[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging] x86/vm_event: transfer nested p2m base info



commit d581cf8839417b73f02d8b6f79cf33e9903933db
Author:     Tamas K Lengyel <tamas@xxxxxxxxxxxxx>
AuthorDate: Sun Jan 3 11:41:17 2021 -0700
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Tue Jan 5 23:00:27 2021 +0000

    x86/vm_event: transfer nested p2m base info
    
    Required to introspect events originating from nested VMs.
    
    Signed-off-by: Tamas K Lengyel <tamas@xxxxxxxxxxxxx>
    Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/hvm/monitor.c    | 32 ++++++++++++++++++++++++++++++--
 xen/include/public/vm_event.h | 17 ++++++++++++++++-
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/hvm/monitor.c b/xen/arch/x86/hvm/monitor.c
index e4a09964a0..b44a1e1dfe 100644
--- a/xen/arch/x86/hvm/monitor.c
+++ b/xen/arch/x86/hvm/monitor.c
@@ -26,6 +26,7 @@
 #include <xen/mem_access.h>
 #include <xen/monitor.h>
 #include <asm/hvm/monitor.h>
+#include <asm/hvm/nestedhvm.h>
 #include <asm/altp2m.h>
 #include <asm/monitor.h>
 #include <asm/p2m.h>
@@ -33,6 +34,15 @@
 #include <asm/vm_event.h>
 #include <public/vm_event.h>
 
+static void set_npt_base(struct vcpu *v, vm_event_request_t *req)
+{
+    if ( nestedhvm_enabled(v->domain) && nestedhvm_vcpu_in_guestmode(v) )
+    {
+        req->flags |= VM_EVENT_FLAG_NESTED_P2M;
+        req->data.regs.x86.npt_base = nhvm_vcpu_p2m_base(v);
+    }
+}
+
 bool hvm_monitor_cr(unsigned int index, unsigned long value, unsigned long old)
 {
     struct vcpu *curr = current;
@@ -53,6 +63,8 @@ bool hvm_monitor_cr(unsigned int index, unsigned long value, 
unsigned long old)
             .u.write_ctrlreg.old_value = old
         };
 
+        set_npt_base(curr, &req);
+
         return monitor_traps(curr, sync, &req) >= 0 &&
                curr->domain->arch.monitor.control_register_values;
     }
@@ -73,6 +85,8 @@ bool hvm_monitor_emul_unimplemented(void)
         .vcpu_id  = curr->vcpu_id,
     };
 
+    set_npt_base(curr, &req);
+
     return curr->domain->arch.monitor.emul_unimplemented_enabled &&
         monitor_traps(curr, true, &req) == 1;
 }
@@ -92,6 +106,8 @@ bool hvm_monitor_msr(unsigned int msr, uint64_t new_value, 
uint64_t old_value)
             .u.mov_to_msr.old_value = old_value
         };
 
+        set_npt_base(curr, &req);
+
         return monitor_traps(curr, 1, &req) >= 0 &&
                curr->domain->arch.monitor.control_register_values;
     }
@@ -103,6 +119,7 @@ void hvm_monitor_descriptor_access(uint64_t exit_info,
                                    uint64_t vmx_exit_qualification,
                                    uint8_t descriptor, bool is_write)
 {
+    struct vcpu *curr = current;
     vm_event_request_t req = {
         .reason = VM_EVENT_REASON_DESCRIPTOR_ACCESS,
         .u.desc_access.descriptor = descriptor,
@@ -115,7 +132,9 @@ void hvm_monitor_descriptor_access(uint64_t exit_info,
         req.u.desc_access.arch.vmx.exit_qualification = vmx_exit_qualification;
     }
 
-    monitor_traps(current, true, &req);
+    set_npt_base(curr, &req);
+
+    monitor_traps(curr, true, &req);
 }
 
 static inline unsigned long gfn_of_rip(unsigned long rip)
@@ -189,6 +208,8 @@ int hvm_monitor_debug(unsigned long rip, enum 
hvm_monitor_debug_type type,
         return -EOPNOTSUPP;
     }
 
+    set_npt_base(curr, &req);
+
     return monitor_traps(curr, sync, &req);
 }
 
@@ -207,12 +228,15 @@ int hvm_monitor_cpuid(unsigned long insn_length, unsigned 
int leaf,
     req.u.cpuid.leaf = leaf;
     req.u.cpuid.subleaf = subleaf;
 
+    set_npt_base(curr, &req);
+
     return monitor_traps(curr, 1, &req);
 }
 
 void hvm_monitor_interrupt(unsigned int vector, unsigned int type,
                            unsigned int err, uint64_t cr2)
 {
+    struct vcpu *curr = current;
     vm_event_request_t req = {
         .reason = VM_EVENT_REASON_INTERRUPT,
         .u.interrupt.x86.vector = vector,
@@ -221,7 +245,9 @@ void hvm_monitor_interrupt(unsigned int vector, unsigned 
int type,
         .u.interrupt.x86.cr2 = cr2,
     };
 
-    monitor_traps(current, 1, &req);
+    set_npt_base(curr, &req);
+
+    monitor_traps(curr, 1, &req);
 }
 
 /*
@@ -297,6 +323,8 @@ bool hvm_monitor_check_p2m(unsigned long gla, gfn_t gfn, 
uint32_t pfec,
     req.u.mem_access.gla = gla;
     req.u.mem_access.offset = gpa & ~PAGE_MASK;
 
+    set_npt_base(curr, &req);
+
     return monitor_traps(curr, true, &req) >= 0;
 }
 
diff --git a/xen/include/public/vm_event.h b/xen/include/public/vm_event.h
index fdd3ad8a30..141ea024a3 100644
--- a/xen/include/public/vm_event.h
+++ b/xen/include/public/vm_event.h
@@ -29,7 +29,7 @@
 
 #include "xen.h"
 
-#define VM_EVENT_INTERFACE_VERSION 0x00000006
+#define VM_EVENT_INTERFACE_VERSION 0x00000007
 
 #if defined(__XEN__) || defined(__XEN_TOOLS__)
 
@@ -119,6 +119,10 @@
  * which singlestep gets automatically disabled.
  */
 #define VM_EVENT_FLAG_FAST_SINGLESTEP    (1 << 11)
+/*
+ * Set if the event comes from a nested VM and thus npt_base is valid.
+ */
+#define VM_EVENT_FLAG_NESTED_P2M         (1 << 12)
 
 /*
  * Reasons for the vm event request
@@ -208,6 +212,17 @@ struct vm_event_regs_x86 {
     uint64_t msr_star;
     uint64_t msr_lstar;
     uint64_t gdtr_base;
+
+    /*
+     * When VM_EVENT_FLAG_NESTED_P2M is set, this event comes from a nested
+     * VM.  npt_base is the guest physical address of the L1 hypervisors
+     * EPT/NPT tables for the nested guest.
+     *
+     * All bits outside of architectural address ranges are reserved for
+     * future metadata.
+     */
+    uint64_t npt_base;
+
     uint32_t cs_base;
     uint32_t ss_base;
     uint32_t ds_base;
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.