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

[Xen-devel] [PATCH v2 10/10] x86: Handle new asynchronous exit qualification



Using EPT to translate PT output addresses introduces the possibility of
taking events on PT output reads and writes. Event possibilities include
EPT violations, EPT misconfigurations, PML log-full VM exits, and APIC
access VM exits.
EPT violations:
 a. Intel PT buffer is a MMIO address in guest. Actually, it can be a
    MMIO address (SDM 35.2.6.1), but in order do not affect other
    passthrough/emulate device in guest. Ferbid use MMIO addr at present.
 b. Intel PT buffer is a RAM non-writable address. Don't need emulate
    and inject a #GP to guest.
 c. EPT table entry write protect for Live Migration. Do nothing and
    handled as usual.
EPT misconfiguration:
 Nothing to do.
PML log-full VM exits:
 Intel PT trace output a new page, this behavior will be recorded to
 PML page may cause PML log-FULL VM-exit. Nothing to do.
APIC access VM exits:
 PT output region shouldn't have overlap with 4KB APIC MMIO region as
 defined by the IA32_APIC_BASE (SDM 35.2.6.4) but no error for this
 case in hardware. Crash guest in hypervisor.

Signed-off-by: Luwei Kang <luwei.kang@xxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c            | 8 ++++++--
 xen/arch/x86/hvm/vmx/vmx.c        | 5 +++++
 xen/include/asm-x86/hvm/vmx/vmx.h | 8 +++++---
 xen/include/xen/mm.h              | 1 +
 4 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index c23983c..7782160 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -1712,7 +1712,7 @@ int hvm_hap_nested_page_fault(paddr_t gpa, unsigned long 
gla,
     struct vcpu *curr = current;
     struct domain *currd = curr->domain;
     struct p2m_domain *p2m, *hostp2m;
-    int rc, fall_through = 0, paged = 0;
+    int rc = 0, fall_through = 0, paged = 0;
     int sharing_enomem = 0;
     vm_event_request_t *req_ptr = NULL;
     bool_t ap2m_active, sync = 0;
@@ -1873,7 +1873,11 @@ int hvm_hap_nested_page_fault(paddr_t gpa, unsigned long 
gla,
          (npfec.write_access &&
           (p2m_is_discard_write(p2mt) || (p2mt == p2m_ioreq_server))) )
     {
-        if ( !handle_mmio_with_translation(gla, gpa >> PAGE_SHIFT, npfec) )
+        /* Don't emulate and make guest crash when write to mmio address */
+        if ( npfec.async && (p2mt == p2m_mmio_dm) )
+            goto out_put_gfn;
+
+        if ( npfec.async || !handle_mmio_with_translation(gla, gpa >> 
PAGE_SHIFT, npfec) )
             hvm_inject_hw_exception(TRAP_gp_fault, 0);
         rc = 1;
         goto out_put_gfn;
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index fa1ca0c..d0d00f8 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -3253,6 +3253,7 @@ static void ept_handle_violation(ept_qual_t q, paddr_t 
gpa)
         .write_access = q.write,
         .insn_fetch = q.fetch,
         .present = q.eff_read || q.eff_write || q.eff_exec,
+        .async = q.async,
     };
 
     if ( tb_init_done )
@@ -4027,6 +4028,10 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
         break;
 
     case EXIT_REASON_APIC_ACCESS:
+        __vmread(EXIT_QUALIFICATION, &exit_qualification);
+        if ( exit_qualification & 0x10000 )
+            goto exit_and_crash;
+
         if ( !vmx_handle_eoi_write() && !handle_mmio() )
             hvm_inject_hw_exception(TRAP_gp_fault, 0);
         break;
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h 
b/xen/include/asm-x86/hvm/vmx/vmx.h
index 89619e4..e7c5360 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -620,11 +620,13 @@ void vmx_pi_hooks_deassign(struct domain *d);
 typedef union ept_qual {
     unsigned long raw;
     struct {
-        bool read:1, write:1, fetch:1,
+        unsigned long read:1, write:1, fetch:1,
             eff_read:1, eff_write:1, eff_exec:1, /* eff_user_exec */:1,
             gla_valid:1,
-            gla_fault:1; /* Valid iff gla_valid. */
-        unsigned long /* pad */:55;
+            gla_fault:1, /* Valid iff gla_valid. */
+            :7,
+            async:1; /* Asynchronous to Instruction Execution (e.g. ipt) */
+        unsigned long /* pad */:47;
     };
 } __transparent__ ept_qual_t;
 
diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h
index e928551..1546d4f 100644
--- a/xen/include/xen/mm.h
+++ b/xen/include/xen/mm.h
@@ -228,6 +228,7 @@ struct npfec {
     unsigned int present:1;
     unsigned int gla_valid:1;
     unsigned int kind:2;  /* npfec_kind_t */
+    unsigned int async:1;
 };
 
 /* memflags: */
-- 
1.8.3.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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