[PATCH 7/8] kvm: decode the argument for KVM_{SET, GET}_SREGS ioctl command

Masatake YAMATO yamato at redhat.com
Fri Dec 1 05:45:57 UTC 2017


* kvm.c (kvm_ioctl): Handle KVM_SET_SREGS and KVM_GET_SREGES.
(kvm_ioctl_decode_sregs): New function.
(kvm_ioctl_decode_regs_dtable): New function.
(kvm_ioctl_decode_regs_segment): New function.

Signed-off-by: Masatake YAMATO <yamato at redhat.com>
---
 kvm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/kvm.c b/kvm.c
index 69a8c97a..b0eb1377 100644
--- a/kvm.c
+++ b/kvm.c
@@ -121,6 +121,85 @@ kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code, const kern
 #endif
 }
 
+#ifdef X86_64
+static void
+kvm_ioctl_decode_regs_segment(const char *prefix, struct kvm_segment *segment)
+{
+	tprints(prefix);
+	PRINT_FIELD_X("={", *segment, base);
+	PRINT_FIELD_U(", ", *segment, limit);
+	PRINT_FIELD_U(", ", *segment, selector);
+	PRINT_FIELD_U(", ", *segment, type);
+	PRINT_FIELD_U(", ", *segment, present);
+	PRINT_FIELD_U(", ", *segment, dpl);
+	PRINT_FIELD_U(", ", *segment, db);
+	PRINT_FIELD_U(", ", *segment, s);
+	PRINT_FIELD_U(", ", *segment, l);
+	PRINT_FIELD_U(", ", *segment, g);
+	PRINT_FIELD_U(", ", *segment, avl);
+	tprints("}");
+}
+
+static void
+kvm_ioctl_decode_regs_dtable(const char *prefix, struct kvm_dtable *dtable)
+{
+	tprints(prefix);
+	PRINT_FIELD_X("={", *dtable, base);
+	PRINT_FIELD_U(", ", *dtable, limit);
+	tprints("}");
+}
+#endif
+
+static int
+kvm_ioctl_decode_sregs(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
+{
+	struct kvm_sregs sregs;
+
+#ifdef X86_64
+	if (code == KVM_GET_SREGS && entering(tcp))
+		return 0;
+
+	if (umove(tcp, arg, &sregs) < 0)
+		return RVAL_DECODED;
+
+	tprints(", {");
+	kvm_ioctl_decode_regs_segment("cs", &sregs.cs);
+	if (abbrev(tcp)) {
+		tprints(", ...}");
+		return RVAL_IOCTL_DECODED;
+	}
+
+	kvm_ioctl_decode_regs_segment(", ds", &sregs.ds);
+	kvm_ioctl_decode_regs_segment(", es", &sregs.es);
+	kvm_ioctl_decode_regs_segment(", fs", &sregs.fs);
+	kvm_ioctl_decode_regs_segment(", gs", &sregs.gs);
+	kvm_ioctl_decode_regs_segment(", ss", &sregs.ss);
+	kvm_ioctl_decode_regs_segment(", tr", &sregs.tr);
+	kvm_ioctl_decode_regs_segment(", ldt", &sregs.ldt);
+	kvm_ioctl_decode_regs_dtable(", gdt", &sregs.gdt);
+	kvm_ioctl_decode_regs_dtable(", idt", &sregs.idt);
+	PRINT_FIELD_U(", ", sregs, cr0);
+	PRINT_FIELD_U(", ", sregs, cr2);
+	PRINT_FIELD_U(", ", sregs, cr3);
+	PRINT_FIELD_U(", ", sregs, cr4);
+	PRINT_FIELD_U(", ", sregs, cr8);
+	PRINT_FIELD_U(", ", sregs, efer);
+	PRINT_FIELD_X(", ", sregs, apic_base);
+	tprints(", interrupt_bitmap=[");
+	for (int i = 0; i < (KVM_NR_INTERRUPTS + 63) / 64; i++) {
+		if (i != 0)
+			tprints(", ");
+		tprintf("%" PRI__u64, sregs.interrupt_bitmap[i]);
+	}
+	tprints("]");
+	tprints("}");
+
+	return RVAL_IOCTL_DECODED;
+#else
+	return RVAL_DECODED;
+#endif
+}
+
 int
 kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
 {
@@ -134,6 +213,9 @@ kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t a
 	case KVM_SET_REGS:
 	case KVM_GET_REGS:
 		return kvm_ioctl_decode_regs(tcp, code, arg);
+	case KVM_SET_SREGS:
+	case KVM_GET_SREGS:
+		return kvm_ioctl_decode_sregs(tcp, code, arg);
 
 	/* Commands not taking any arguments. */
 	case KVM_RUN:
-- 
2.13.6





More information about the Strace-devel mailing list