]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add support for Xen hypercalls used by libvmi. Patch from Antony Saba
authorJulian Seward <jseward@acm.org>
Thu, 4 Sep 2014 10:59:50 +0000 (10:59 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 4 Sep 2014 10:59:50 +0000 (10:59 +0000)
(antony.saba@fireeye.com).  First of two patches from #337740.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14453

coregrind/m_syswrap/syswrap-xen.c
include/vki/vki-xen-domctl.h
include/vki/vki-xen-hvm.h
include/vki/vki-xen-memory.h
include/vki/vki-xen-x86.h

index 0ba00d7cb9bc428f68cd9da443020adc7f97c911..f65ba12a4e6b1c4c527848a115ca4591f458b6c9 100644 (file)
@@ -186,7 +186,7 @@ PRE(memory_op)
        PRE_MEM_READ("XENMEM_add_to_physmap gpfn",
                     (Addr)&arg->gpfn, sizeof(arg->gpfn));
        break;
-   };
+   }
 
    case VKI_XENMEM_remove_from_physmap: {
        struct vki_xen_remove_from_physmap *arg =
@@ -195,12 +195,24 @@ PRE(memory_op)
                     (Addr)&arg->domid, sizeof(arg->domid));
        PRE_MEM_READ("XENMEM_remove_from_physmap gpfn",
                     (Addr)&arg->gpfn, sizeof(arg->gpfn));
+       break;
    }
 
    case VKI_XENMEM_get_sharing_freed_pages:
    case VKI_XENMEM_get_sharing_shared_pages:
       break;
 
+   case VKI_XENMEM_access_op: {
+       struct vki_xen_mem_event_op *arg =
+            (struct vki_xen_mem_event_op *)ARG2;
+       PRE_MEM_READ("XENMEM_access_op domid",
+                    (Addr)&arg->domain, sizeof(arg->domain));
+       PRE_MEM_READ("XENMEM_access_op op",
+                    (Addr)&arg->op, sizeof(arg->op));
+       PRE_MEM_READ("XENMEM_access_op gfn",
+                    (Addr)&arg->gfn, sizeof(arg->gfn));
+       break;
+   }
    default:
       bad_subop(tid, layout, arrghs, status, flags,
                 "__HYPERVISOR_memory_op", ARG1);
@@ -619,6 +631,26 @@ PRE(domctl)
                     domctl->u.hvmcontext.size);
        break;
 
+   case VKI_XEN_DOMCTL_gethvmcontext_partial:
+       __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, type);
+       __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, instance);
+       __PRE_XEN_DOMCTL_READ(gethvmcontext_partial, hvmcontext_partial, buffer);
+
+       switch (domctl->u.hvmcontext_partial.type) {
+       case VKI_HVM_SAVE_CODE(CPU):
+           if ( domctl->u.hvmcontext_partial.buffer.p )
+                PRE_MEM_WRITE("XEN_DOMCTL_gethvmcontext_partial *buffer",
+                   (Addr)domctl->u.hvmcontext_partial.buffer.p,
+                   VKI_HVM_SAVE_LENGTH(CPU));
+           break;
+       default:
+           bad_subop(tid, layout, arrghs, status, flags,
+                         "__HYPERVISOR_domctl_gethvmcontext_partial type",
+                         domctl->u.hvmcontext_partial.type);
+           break;
+       }
+       break;
+
    case VKI_XEN_DOMCTL_max_mem:
       PRE_XEN_DOMCTL_READ(max_mem, max_memkb);
       break;
@@ -634,6 +666,12 @@ PRE(domctl)
       __PRE_XEN_DOMCTL_READ(settscinfo, tsc_info, info.elapsed_nsec);
       break;
 
+   case VKI_XEN_DOMCTL_ioport_permission:
+      PRE_XEN_DOMCTL_READ(ioport_permission, first_port);
+      PRE_XEN_DOMCTL_READ(ioport_permission, nr_ports);
+      PRE_XEN_DOMCTL_READ(ioport_permission, allow_access);
+      break;
+
    case VKI_XEN_DOMCTL_hypercall_init:
       PRE_XEN_DOMCTL_READ(hypercall_init, gmfn);
       break;
@@ -773,6 +811,20 @@ PRE(domctl)
       PRE_XEN_DOMCTL_READ(cacheflush, nr_pfns);
       break;
 
+   case VKI_XEN_DOMCTL_set_access_required:
+      PRE_XEN_DOMCTL_READ(access_required, access_required);
+      break;
+
+   case VKI_XEN_DOMCTL_mem_event_op:
+      PRE_XEN_DOMCTL_READ(mem_event_op, op);
+      PRE_XEN_DOMCTL_READ(mem_event_op, mode);
+      break;
+
+   case VKI_XEN_DOMCTL_debug_op:
+      PRE_XEN_DOMCTL_READ(debug_op, op);
+      PRE_XEN_DOMCTL_READ(debug_op, vcpu);
+      break;
+
    default:
       bad_subop(tid, layout, arrghs, status, flags,
                 "__HYPERVISOR_domctl", domctl->cmd);
@@ -827,6 +879,34 @@ PRE(hvm_op)
        PRE_XEN_HVMOP_READ(set_mem_type, first_pfn);
        break;
 
+   case VKI_XEN_HVMOP_set_mem_access:
+       PRE_XEN_HVMOP_READ(set_mem_access, domid);
+       PRE_XEN_HVMOP_READ(set_mem_access, hvmmem_access);
+       PRE_XEN_HVMOP_READ(set_mem_access, first_pfn);
+       /* if default access */
+       if ( ((vki_xen_hvm_set_mem_access_t*)arg)->first_pfn != ~0ULL)
+           PRE_XEN_HVMOP_READ(set_mem_access, nr);
+       break;
+
+   case VKI_XEN_HVMOP_get_mem_access:
+       PRE_XEN_HVMOP_READ(get_mem_access, domid);
+       PRE_XEN_HVMOP_READ(get_mem_access, pfn);
+
+       PRE_MEM_WRITE("XEN_HVMOP_get_mem_access *hvmmem_access",
+                   (Addr)&(((vki_xen_hvm_get_mem_access_t*)arg)->hvmmem_access),
+                   sizeof(vki_uint16_t));
+       break;
+
+   case VKI_XEN_HVMOP_inject_trap:
+       PRE_XEN_HVMOP_READ(inject_trap, domid);
+       PRE_XEN_HVMOP_READ(inject_trap, vcpuid);
+       PRE_XEN_HVMOP_READ(inject_trap, vector);
+       PRE_XEN_HVMOP_READ(inject_trap, type);
+       PRE_XEN_HVMOP_READ(inject_trap, error_code);
+       PRE_XEN_HVMOP_READ(inject_trap, insn_len);
+       PRE_XEN_HVMOP_READ(inject_trap, cr2);
+       break;
+
    default:
       bad_subop(tid, layout, arrghs, status, flags,
                 "__HYPERVISOR_hvm_op", op);
@@ -900,6 +980,7 @@ POST(memory_op)
    case VKI_XENMEM_claim_pages:
    case VKI_XENMEM_maximum_gpfn:
    case VKI_XENMEM_remove_from_physmap:
+   case VKI_XENMEM_access_op:
       /* No outputs */
       break;
    case VKI_XENMEM_increase_reservation:
@@ -1175,6 +1256,7 @@ POST(domctl){
    case VKI_XEN_DOMCTL_max_mem:
    case VKI_XEN_DOMCTL_set_address_size:
    case VKI_XEN_DOMCTL_settscinfo:
+   case VKI_XEN_DOMCTL_ioport_permission:
    case VKI_XEN_DOMCTL_hypercall_init:
    case VKI_XEN_DOMCTL_setvcpuaffinity:
    case VKI_XEN_DOMCTL_setvcpucontext:
@@ -1182,9 +1264,11 @@ POST(domctl){
    case VKI_XEN_DOMCTL_set_cpuid:
    case VKI_XEN_DOMCTL_unpausedomain:
    case VKI_XEN_DOMCTL_sethvmcontext:
+   case VKI_XEN_DOMCTL_debug_op:
    case VKI_XEN_DOMCTL_set_max_evtchn:
    case VKI_XEN_DOMCTL_cacheflush:
    case VKI_XEN_DOMCTL_resumedomain:
+   case VKI_XEN_DOMCTL_set_access_required:
       /* No output fields */
       break;
 
@@ -1221,6 +1305,16 @@ POST(domctl){
                           * domctl->u.hvmcontext.size);
        break;
 
+   case VKI_XEN_DOMCTL_gethvmcontext_partial:
+       switch (domctl->u.hvmcontext_partial.type) {
+       case VKI_HVM_SAVE_CODE(CPU):
+           if ( domctl->u.hvmcontext_partial.buffer.p )
+                POST_MEM_WRITE((Addr)domctl->u.hvmcontext_partial.buffer.p,
+                   VKI_HVM_SAVE_LENGTH(CPU));
+           break;
+       }
+       break;
+
    case VKI_XEN_DOMCTL_scheduler_op:
       if ( domctl->u.scheduler_op.cmd == VKI_XEN_DOMCTL_SCHEDOP_getinfo ) {
          switch(domctl->u.scheduler_op.sched_id) {
@@ -1340,6 +1434,10 @@ POST(domctl){
        default:
            break;
        }
+       break;
+   case VKI_XEN_DOMCTL_mem_event_op:
+       POST_XEN_DOMCTL_WRITE(mem_event_op, port);
+
        break;
    }
 #undef POST_XEN_DOMCTL_WRITE
@@ -1355,19 +1453,25 @@ POST(hvm_op)
       POST_MEM_WRITE((Addr)&((_type*)arg)->_field,      \
                      sizeof(((_type*)arg)->_field))
 #define POST_XEN_HVMOP_WRITE(_hvm_op, _field) \
-      __PRE_XEN_HVMOP_READ(_hvm_op, vki_xen_hvm_ ## _hvm_op ## _t, _field)
+      __POST_XEN_HVMOP_WRITE(_hvm_op, vki_xen_hvm_ ## _hvm_op ## _t, _field)
 
    switch (op) {
    case VKI_XEN_HVMOP_set_param:
    case VKI_XEN_HVMOP_set_isa_irq_level:
    case VKI_XEN_HVMOP_set_pci_link_route:
    case VKI_XEN_HVMOP_set_mem_type:
+   case VKI_XEN_HVMOP_set_mem_access:
+   case VKI_XEN_HVMOP_inject_trap:
       /* No output paramters */
       break;
 
    case VKI_XEN_HVMOP_get_param:
       __POST_XEN_HVMOP_WRITE(get_param, struct vki_xen_hvm_param, value);
       break;
+
+   case VKI_XEN_HVMOP_get_mem_access:
+      POST_XEN_HVMOP_WRITE(get_mem_access, hvmmem_access);
+      break;
    }
 #undef __POST_XEN_HVMOP_WRITE
 #undef POST_XEN_HVMOP_WRITE
index 2f55ce0b948be80acb8170b9f20c79f6130d830f..b5037f202be8b4869776c5c01d5c4aec6767a05a 100644 (file)
@@ -261,6 +261,12 @@ struct vki_xen_domctl_max_vcpus {
     vki_uint32_t max;           /* maximum number of vcpus */
 };
 
+struct vki_xen_domctl_ioport_permission {
+    vki_uint32_t first_port;              /* IN */
+    vki_uint32_t nr_ports;                /* IN */
+    vki_uint8_t  allow_access;            /* IN */
+};
+
 struct vki_xen_domctl_hypercall_init {
     vki_xen_uint64_aligned_t  gmfn;           /* GMFN to be initialised */
 };
@@ -294,6 +300,14 @@ struct vki_xen_domctl_hvmcontext {
 typedef struct vki_xen_domctl_hvmcontext vki_xen_domctl_hvmcontext_t;
 DEFINE_VKI_XEN_GUEST_HANDLE(vki_xen_domctl_hvmcontext_t);
 
+struct vki_xen_domctl_hvmcontext_partial {
+    vki_uint32_t type; /* IN */
+    vki_uint32_t instance; /* IN */
+    VKI_XEN_GUEST_HANDLE_64(vki_uint8) buffer; /* IN/OUT buffer */
+};
+typedef struct vki_xen_domctl_hvmcontext_partial vki_xen_domctl_hvmcontext_partial_t;
+DEFINE_VKI_XEN_GUEST_HANDLE(vki_xen_domctl_hvmcontext_partial_t);
+
 struct vki_xen_domctl_tsc_info {
     VKI_XEN_GUEST_HANDLE_64(vki_xen_guest_tsc_info_t) out_info; /* OUT */
     vki_xen_guest_tsc_info_t info; /* IN */
@@ -310,6 +324,22 @@ struct vki_xen_domctl_address_size {
     vki_uint32_t size;
 };
 
+struct vki_xen_domctl_debug_op {
+    vki_uint32_t op;   /* IN */
+    vki_uint32_t vcpu; /* IN */
+};
+typedef struct vki_xen_domctl_debug_op vki_xen_domctl_debug_op_t;
+
+struct vki_xen_domctl_mem_event_op {
+    vki_uint32_t op; /* IN */
+    vki_uint32_t mode; /* IN */
+    vki_uint32_t port; /* OUT */
+};
+
+struct vki_xen_domctl_set_access_required {
+    vki_uint8_t access_required; /* IN */
+};
+
 struct vki_xen_domctl_set_max_evtchn {
     vki_uint32_t max_port;
 };
@@ -344,7 +374,7 @@ struct vki_xen_domctl {
         //struct vki_xen_domctl_setdebugging      setdebugging;
         //struct vki_xen_domctl_irq_permission    irq_permission;
         //struct vki_xen_domctl_iomem_permission  iomem_permission;
-        //struct vki_xen_domctl_ioport_permission ioport_permission;
+        struct vki_xen_domctl_ioport_permission ioport_permission;
         struct vki_xen_domctl_hypercall_init    hypercall_init;
         //struct vki_xen_domctl_arch_setup        arch_setup;
         struct vki_xen_domctl_settimeoffset     settimeoffset;
@@ -352,7 +382,7 @@ struct vki_xen_domctl {
         struct vki_xen_domctl_tsc_info          tsc_info;
         //struct vki_xen_domctl_real_mode_area    real_mode_area;
         struct vki_xen_domctl_hvmcontext        hvmcontext;
-        //struct vki_xen_domctl_hvmcontext_partial hvmcontext_partial;
+        struct vki_xen_domctl_hvmcontext_partial hvmcontext_partial;
         struct vki_xen_domctl_address_size      address_size;
         //struct vki_xen_domctl_sendtrigger       sendtrigger;
         //struct vki_xen_domctl_get_device_group  get_device_group;
@@ -364,14 +394,14 @@ struct vki_xen_domctl {
         //struct vki_xen_domctl_ext_vcpucontext   ext_vcpucontext;
         //struct vki_xen_domctl_set_target        set_target;
         //struct vki_xen_domctl_subscribe         subscribe;
-        //struct vki_xen_domctl_debug_op          debug_op;
-        //struct vki_xen_domctl_mem_event_op      mem_event_op;
+        struct vki_xen_domctl_debug_op          debug_op;
+        struct vki_xen_domctl_mem_event_op      mem_event_op;
         //struct vki_xen_domctl_mem_sharing_op    mem_sharing_op;
 #if defined(__i386__) || defined(__x86_64__)
         struct vki_xen_domctl_cpuid             cpuid;
         struct vki_xen_domctl_vcpuextstate      vcpuextstate;
 #endif
-        //struct vki_xen_domctl_set_access_required access_required;
+        struct vki_xen_domctl_set_access_required access_required;
         //struct vki_xen_domctl_audit_p2m         audit_p2m;
         //struct vki_xen_domctl_set_virq_handler  set_virq_handler;
         struct vki_xen_domctl_set_max_evtchn    set_max_evtchn;
index 19ccbeb81682c16009e4476b935391063ad47aef..f26e039114472800d1b80d035a27552ec8c1b48d 100644 (file)
@@ -31,10 +31,39 @@ struct vki_xen_hvm_set_mem_type {
     vki_xen_domid_t  domid;
     vki_uint16_t hvmmem_type;
     vki_uint32_t nr;
-    vki_xen_uint64_aligned_t first_pfn;
+    vki_uint64_t first_pfn;
 };
 typedef struct vki_xen_hvm_set_mem_type vki_xen_hvm_set_mem_type_t;
 
+#define VKI_XEN_HVMOP_set_mem_access        12
+struct vki_xen_hvm_set_mem_access {
+    vki_xen_domid_t domid;
+    vki_uint16_t hvmmem_access;
+    vki_uint32_t nr;
+    vki_uint64_t first_pfn;
+};
+typedef struct vki_xen_hvm_set_mem_access vki_xen_hvm_set_mem_access_t;
+
+#define VKI_XEN_HVMOP_get_mem_access        13
+struct vki_xen_hvm_get_mem_access {
+    vki_xen_domid_t domid;
+    vki_uint16_t hvmmem_access; /* OUT */
+    vki_uint64_t pfn;
+};
+typedef struct vki_xen_hvm_get_mem_access vki_xen_hvm_get_mem_access_t;
+
+#define VKI_XEN_HVMOP_inject_trap            14
+struct vki_xen_hvm_inject_trap {
+    vki_xen_domid_t domid;
+    vki_uint32_t vcpuid;
+    vki_uint32_t vector;
+    vki_uint32_t type;
+    vki_uint32_t error_code;
+    vki_uint32_t insn_len;
+    vki_uint64_t cr2;
+};
+typedef struct vki_xen_hvm_inject_trap vki_xen_hvm_inject_trap_t;
+
 #endif // __VKI_XEN_HVM_H
 
 /*--------------------------------------------------------------------*/
index 609e648d9ebe3efdeb6c206dd429c8ce92c9bb4c..2690c60c260e7bc8ca9b53de5d1a5540afcc8b66 100644 (file)
@@ -20,6 +20,7 @@
 #define VKI_XENMEM_get_pod_target       17
 #define VKI_XENMEM_get_sharing_freed_pages    18
 #define VKI_XENMEM_get_sharing_shared_pages   19
+#define VKI_XENMEM_access_op                  21
 #define VKI_XENMEM_claim_pages                24
 
 struct vki_xen_memory_map {
@@ -66,6 +67,13 @@ struct vki_xen_remove_from_physmap {
     vki_xen_pfn_t gpfn;
 };
 
+struct vki_xen_mem_event_op {
+    vki_uint8_t     op;
+    vki_xen_domid_t     domain;
+    vki_uint64_t    buffer;
+    vki_uint64_t    gfn;
+};
+
 #endif // __VKI_XEN_MEMORY_H
 
 /*--------------------------------------------------------------------*/
index 240865b30e2860de7079870be7be97850211f2ab..a2d0fb22ae4334f2eaba41998e8bc8b5c56567f8 100644 (file)
@@ -123,6 +123,126 @@ struct vki_xen_vcpu_guest_context {
 typedef struct vki_xen_vcpu_guest_context vki_xen_vcpu_guest_context_t;
 DEFINE_VKI_XEN_GUEST_HANDLE(vki_xen_vcpu_guest_context_t);
 
+
+/* HVM_SAVE types and declarations for getcontext_partial */
+# define VKI_DECLARE_HVM_SAVE_TYPE(_x, _code, _type)                         \
+    struct __VKI_HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[1];}
+
+#define VKI_HVM_SAVE_TYPE(_x) typeof (((struct __VKI_HVM_SAVE_TYPE_##_x *)(0))->t)
+#define VKI_HVM_SAVE_LENGTH(_x) (sizeof (VKI_HVM_SAVE_TYPE(_x)))
+#define VKI_HVM_SAVE_CODE(_x) (sizeof (((struct __VKI_HVM_SAVE_TYPE_##_x *)(0))->c))
+
+struct vki_hvm_hw_cpu {
+   vki_uint8_t  fpu_regs[512];
+
+   vki_uint64_t rax;
+   vki_uint64_t rbx;
+   vki_uint64_t rcx;
+   vki_uint64_t rdx;
+   vki_uint64_t rbp;
+   vki_uint64_t rsi;
+   vki_uint64_t rdi;
+   vki_uint64_t rsp;
+   vki_uint64_t r8;
+   vki_uint64_t r9;
+   vki_uint64_t r10;
+   vki_uint64_t r11;
+   vki_uint64_t r12;
+   vki_uint64_t r13;
+   vki_uint64_t r14;
+   vki_uint64_t r15;
+
+   vki_uint64_t rip;
+   vki_uint64_t rflags;
+
+   vki_uint64_t cr0;
+   vki_uint64_t cr2;
+   vki_uint64_t cr3;
+   vki_uint64_t cr4;
+
+   vki_uint64_t dr0;
+   vki_uint64_t dr1;
+   vki_uint64_t dr2;
+   vki_uint64_t dr3;
+   vki_uint64_t dr6;
+   vki_uint64_t dr7;
+
+   vki_uint32_t cs_sel;
+   vki_uint32_t ds_sel;
+   vki_uint32_t es_sel;
+   vki_uint32_t fs_sel;
+   vki_uint32_t gs_sel;
+   vki_uint32_t ss_sel;
+   vki_uint32_t tr_sel;
+   vki_uint32_t ldtr_sel;
+
+   vki_uint32_t cs_limit;
+   vki_uint32_t ds_limit;
+   vki_uint32_t es_limit;
+   vki_uint32_t fs_limit;
+   vki_uint32_t gs_limit;
+   vki_uint32_t ss_limit;
+   vki_uint32_t tr_limit;
+   vki_uint32_t ldtr_limit;
+   vki_uint32_t idtr_limit;
+   vki_uint32_t gdtr_limit;
+
+   vki_uint64_t cs_base;
+   vki_uint64_t ds_base;
+   vki_uint64_t es_base;
+   vki_uint64_t fs_base;
+   vki_uint64_t gs_base;
+   vki_uint64_t ss_base;
+   vki_uint64_t tr_base;
+   vki_uint64_t ldtr_base;
+   vki_uint64_t idtr_base;
+   vki_uint64_t gdtr_base;
+
+   vki_uint32_t cs_arbytes;
+   vki_uint32_t ds_arbytes;
+   vki_uint32_t es_arbytes;
+   vki_uint32_t fs_arbytes;
+   vki_uint32_t gs_arbytes;
+   vki_uint32_t ss_arbytes;
+   vki_uint32_t tr_arbytes;
+   vki_uint32_t ldtr_arbytes;
+
+   vki_uint64_t sysenter_cs;
+   vki_uint64_t sysenter_esp;
+   vki_uint64_t sysenter_eip;
+
+    /* msr for em64t */
+   vki_uint64_t shadow_gs;
+
+    /* msr content saved/restored. */
+   vki_uint64_t msr_flags;
+   vki_uint64_t msr_lstar;
+   vki_uint64_t msr_star;
+   vki_uint64_t msr_cstar;
+   vki_uint64_t msr_syscall_mask;
+   vki_uint64_t msr_efer;
+   vki_uint64_t msr_tsc_aux;
+
+    /* guest's idea of what rdtsc() would return */
+   vki_uint64_t tsc;
+
+    /* pending event, if any */
+    union {
+       vki_uint32_t pending_event;
+        struct {
+           vki_uint8_t  pending_vector:8;
+           vki_uint8_t  pending_type:3;
+           vki_uint8_t  pending_error_valid:1;
+           vki_uint32_t pending_reserved:19;
+           vki_uint8_t  pending_valid:1;
+        };
+    };
+    /* error code for pending event */
+   vki_uint32_t error_code;
+};
+
+VKI_DECLARE_HVM_SAVE_TYPE(CPU, 2, struct vki_hvm_hw_cpu);
+
 #endif // __VKI_XEN_H
 
 /*--------------------------------------------------------------------*/