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.k...@intel.com>
---
 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@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Reply via email to