xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 1/5] monitor: Rename vm_event_monitor_get_capabilities
@ 2016-06-23 17:07 Tamas K Lengyel
  2016-06-23 17:07 ` [PATCH v6 2/5] monitor: Rename vm_event_monitor_guest_request Tamas K Lengyel
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Tamas K Lengyel @ 2016-06-23 17:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Tamas K Lengyel, Stefano Stabellini, Jan Beulich

The monitor_get_capabilities check actually belongs to the monitor subsystem so
relocating and renaming it to sanitize the code's name and location. Mechanical
patch, no code changes introduced.

Signed-off-by: Tamas K Lengyel <tamas@tklengyel.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Acked-by: Julien Grall <julien.grall@arm.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
---
 xen/arch/x86/monitor.c         |  2 +-
 xen/common/monitor.c           |  5 ++---
 xen/include/asm-arm/monitor.h  | 11 ++++++++++-
 xen/include/asm-arm/vm_event.h |  9 ---------
 xen/include/asm-x86/monitor.h  | 23 +++++++++++++++++++++++
 xen/include/asm-x86/vm_event.h | 23 -----------------------
 6 files changed, 36 insertions(+), 37 deletions(-)

diff --git a/xen/arch/x86/monitor.c b/xen/arch/x86/monitor.c
index afc8537..a271161 100644
--- a/xen/arch/x86/monitor.c
+++ b/xen/arch/x86/monitor.c
@@ -226,7 +226,7 @@ int arch_monitor_domctl_event(struct domain *d,
 
     default:
         /*
-         * Should not be reached unless vm_event_monitor_get_capabilities() is
+         * Should not be reached unless arch_monitor_get_capabilities() is
          * not properly implemented.
          */
         ASSERT_UNREACHABLE();
diff --git a/xen/common/monitor.c b/xen/common/monitor.c
index d950a7c..7c3d1c8 100644
--- a/xen/common/monitor.c
+++ b/xen/common/monitor.c
@@ -24,7 +24,6 @@
 #include <xsm/xsm.h>
 #include <public/domctl.h>
 #include <asm/monitor.h>
-#include <asm/vm_event.h>
 
 int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop)
 {
@@ -48,12 +47,12 @@ int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop)
         if ( unlikely(mop->event > 31) )
             return -EINVAL;
         /* Check if event type is available. */
-        if ( unlikely(!(vm_event_monitor_get_capabilities(d) & (1U << mop->event))) )
+        if ( unlikely(!(arch_monitor_get_capabilities(d) & (1U << mop->event))) )
             return -EOPNOTSUPP;
         break;
 
     case XEN_DOMCTL_MONITOR_OP_GET_CAPABILITIES:
-        mop->event = vm_event_monitor_get_capabilities(d);
+        mop->event = arch_monitor_get_capabilities(d);
         return 0;
 
     default:
diff --git a/xen/include/asm-arm/monitor.h b/xen/include/asm-arm/monitor.h
index 478f5e9..4af707a 100644
--- a/xen/include/asm-arm/monitor.h
+++ b/xen/include/asm-arm/monitor.h
@@ -39,7 +39,7 @@ int arch_monitor_domctl_event(struct domain *d,
     /*
      * No arch-specific monitor vm-events on ARM.
      *
-     * Should not be reached unless vm_event_monitor_get_capabilities() is not
+     * Should not be reached unless arch_monitor_get_capabilities() is not
      * properly implemented.
      */
     ASSERT_UNREACHABLE();
@@ -59,4 +59,13 @@ void arch_monitor_cleanup_domain(struct domain *d)
     /* No arch-specific domain cleanup on ARM. */
 }
 
+static inline uint32_t arch_monitor_get_capabilities(struct domain *d)
+{
+    uint32_t capabilities = 0;
+
+    capabilities = (1U << XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST);
+
+    return capabilities;
+}
+
 #endif /* __ASM_ARM_MONITOR_H__ */
diff --git a/xen/include/asm-arm/vm_event.h b/xen/include/asm-arm/vm_event.h
index 014d9ba..a3fc4ce 100644
--- a/xen/include/asm-arm/vm_event.h
+++ b/xen/include/asm-arm/vm_event.h
@@ -59,13 +59,4 @@ static inline void vm_event_fill_regs(vm_event_request_t *req)
     /* Not supported on ARM. */
 }
 
-static inline uint32_t vm_event_monitor_get_capabilities(struct domain *d)
-{
-    uint32_t capabilities = 0;
-
-    capabilities = (1U << XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST);
-
-    return capabilities;
-}
-
 #endif /* __ASM_ARM_VM_EVENT_H__ */
diff --git a/xen/include/asm-x86/monitor.h b/xen/include/asm-x86/monitor.h
index 84e3a3a..94b6768 100644
--- a/xen/include/asm-x86/monitor.h
+++ b/xen/include/asm-x86/monitor.h
@@ -63,6 +63,29 @@ int arch_monitor_domctl_op(struct domain *d, struct xen_domctl_monitor_op *mop)
     return rc;
 }
 
+static inline uint32_t arch_monitor_get_capabilities(struct domain *d)
+{
+    uint32_t capabilities = 0;
+
+    /*
+     * At the moment only Intel HVM domains are supported. However, event
+     * delivery could be extended to AMD and PV domains.
+     */
+    if ( !is_hvm_domain(d) || !cpu_has_vmx )
+        return capabilities;
+
+    capabilities = (1U << XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG) |
+                   (1U << XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR) |
+                   (1U << XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT) |
+                   (1U << XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST);
+
+    /* Since we know this is on VMX, we can just call the hvm func */
+    if ( hvm_is_singlestep_supported() )
+        capabilities |= (1U << XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP);
+
+    return capabilities;
+}
+
 int arch_monitor_domctl_event(struct domain *d,
                               struct xen_domctl_monitor_op *mop);
 
diff --git a/xen/include/asm-x86/vm_event.h b/xen/include/asm-x86/vm_event.h
index 0470240..026f42e 100644
--- a/xen/include/asm-x86/vm_event.h
+++ b/xen/include/asm-x86/vm_event.h
@@ -44,27 +44,4 @@ void vm_event_set_registers(struct vcpu *v, vm_event_response_t *rsp);
 
 void vm_event_fill_regs(vm_event_request_t *req);
 
-static inline uint32_t vm_event_monitor_get_capabilities(struct domain *d)
-{
-    uint32_t capabilities = 0;
-
-    /*
-     * At the moment only Intel HVM domains are supported. However, event
-     * delivery could be extended to AMD and PV domains.
-     */
-    if ( !is_hvm_domain(d) || !cpu_has_vmx )
-        return capabilities;
-
-    capabilities = (1U << XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG) |
-                   (1U << XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR) |
-                   (1U << XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT) |
-                   (1U << XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST);
-
-    /* Since we know this is on VMX, we can just call the hvm func */
-    if ( hvm_is_singlestep_supported() )
-        capabilities |= (1U << XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP);
-
-    return capabilities;
-}
-
 #endif /* __ASM_X86_VM_EVENT_H__ */
-- 
2.8.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v6 2/5] monitor: Rename vm_event_monitor_guest_request
  2016-06-23 17:07 [PATCH v6 1/5] monitor: Rename vm_event_monitor_get_capabilities Tamas K Lengyel
@ 2016-06-23 17:07 ` Tamas K Lengyel
  2016-06-23 17:07 ` [PATCH v6 3/5] monitor: Rename hvm/event to hvm/monitor Tamas K Lengyel
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Tamas K Lengyel @ 2016-06-23 17:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Tamas K Lengyel, Stefano Stabellini

Mechanical renaming and relocation to the monitor subsystem.

Signed-off-by: Tamas K Lengyel <tamas@tklengyel.com>
Acked-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Julien Grall <julien.grall@arm.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/arm/hvm.c         |  4 ++--
 xen/arch/x86/hvm/hvm.c     |  3 ++-
 xen/common/monitor.c       | 17 +++++++++++++++++
 xen/common/vm_event.c      | 16 ----------------
 xen/include/xen/monitor.h  |  1 +
 xen/include/xen/vm_event.h |  2 --
 6 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/xen/arch/arm/hvm.c b/xen/arch/arm/hvm.c
index c01123a..d999bde 100644
--- a/xen/arch/arm/hvm.c
+++ b/xen/arch/arm/hvm.c
@@ -22,7 +22,7 @@
 #include <xen/errno.h>
 #include <xen/guest_access.h>
 #include <xen/sched.h>
-#include <xen/vm_event.h>
+#include <xen/monitor.h>
 
 #include <xsm/xsm.h>
 
@@ -75,7 +75,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
 
     case HVMOP_guest_request_vm_event:
         if ( guest_handle_is_null(arg) )
-            vm_event_monitor_guest_request();
+            monitor_guest_request();
         else
             rc = -EINVAL;
         break;
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index ffc3395..337a119 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -37,6 +37,7 @@
 #include <xen/mem_access.h>
 #include <xen/rangeset.h>
 #include <xen/vm_event.h>
+#include <xen/monitor.h>
 #include <asm/shadow.h>
 #include <asm/hap.h>
 #include <asm/current.h>
@@ -5753,7 +5754,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
 
     case HVMOP_guest_request_vm_event:
         if ( guest_handle_is_null(arg) )
-            vm_event_monitor_guest_request();
+            monitor_guest_request();
         else
             rc = -EINVAL;
         break;
diff --git a/xen/common/monitor.c b/xen/common/monitor.c
index 7c3d1c8..436214a 100644
--- a/xen/common/monitor.c
+++ b/xen/common/monitor.c
@@ -21,6 +21,7 @@
 
 #include <xen/monitor.h>
 #include <xen/sched.h>
+#include <xen/vm_event.h>
 #include <xsm/xsm.h>
 #include <public/domctl.h>
 #include <asm/monitor.h>
@@ -84,6 +85,22 @@ int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop)
     return 0;
 }
 
+void monitor_guest_request(void)
+{
+    struct vcpu *curr = current;
+    struct domain *d = curr->domain;
+
+    if ( d->monitor.guest_request_enabled )
+    {
+        vm_event_request_t req = {
+            .reason = VM_EVENT_REASON_GUEST_REQUEST,
+            .vcpu_id = curr->vcpu_id,
+        };
+
+        vm_event_monitor_traps(curr, d->monitor.guest_request_sync, &req);
+    }
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 1ba12cb..ca1eced 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -829,22 +829,6 @@ int vm_event_monitor_traps(struct vcpu *v, uint8_t sync,
     return 1;
 }
 
-void vm_event_monitor_guest_request(void)
-{
-    struct vcpu *curr = current;
-    struct domain *d = curr->domain;
-
-    if ( d->monitor.guest_request_enabled )
-    {
-        vm_event_request_t req = {
-            .reason = VM_EVENT_REASON_GUEST_REQUEST,
-            .vcpu_id = curr->vcpu_id,
-        };
-
-        vm_event_monitor_traps(curr, d->monitor.guest_request_sync, &req);
-    }
-}
-
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/xen/monitor.h b/xen/include/xen/monitor.h
index 7015e6d..204d5cc 100644
--- a/xen/include/xen/monitor.h
+++ b/xen/include/xen/monitor.h
@@ -26,5 +26,6 @@ struct domain;
 struct xen_domctl_monitor_op;
 
 int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *op);
+void monitor_guest_request(void);
 
 #endif /* __XEN_MONITOR_H__ */
diff --git a/xen/include/xen/vm_event.h b/xen/include/xen/vm_event.h
index beda9fe..89e6243 100644
--- a/xen/include/xen/vm_event.h
+++ b/xen/include/xen/vm_event.h
@@ -81,8 +81,6 @@ void vm_event_vcpu_unpause(struct vcpu *v);
 int vm_event_monitor_traps(struct vcpu *v, uint8_t sync,
                            vm_event_request_t *req);
 
-void vm_event_monitor_guest_request(void);
-
 #endif /* __VM_EVENT_H__ */
 
 
-- 
2.8.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v6 3/5] monitor: Rename hvm/event to hvm/monitor
  2016-06-23 17:07 [PATCH v6 1/5] monitor: Rename vm_event_monitor_get_capabilities Tamas K Lengyel
  2016-06-23 17:07 ` [PATCH v6 2/5] monitor: Rename vm_event_monitor_guest_request Tamas K Lengyel
@ 2016-06-23 17:07 ` Tamas K Lengyel
  2016-06-23 17:07 ` [PATCH v6 4/5] vm_event: clear up return value of vm_event_monitor_traps Tamas K Lengyel
  2016-06-23 17:07 ` [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events Tamas K Lengyel
  3 siblings, 0 replies; 14+ messages in thread
From: Tamas K Lengyel @ 2016-06-23 17:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Tamas K Lengyel, Jun Nakajima

Mechanical renaming to better describe that the code in hvm/event is part of
the monitor subsystem.

Signed-off-by: Tamas K Lengyel <tamas@tklengyel.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
Acked-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jun Nakajima <jun.nakajima@intel.com>
---
 xen/arch/x86/hvm/Makefile                      |  2 +-
 xen/arch/x86/hvm/hvm.c                         | 12 +++++------
 xen/arch/x86/hvm/{event.c => monitor.c}        | 17 ++++++++-------
 xen/arch/x86/hvm/vmx/vmx.c                     | 13 +++++------
 xen/include/asm-x86/hvm/{event.h => monitor.h} | 30 +++++++++++++-------------
 5 files changed, 38 insertions(+), 36 deletions(-)
 rename xen/arch/x86/hvm/{event.c => monitor.c} (88%)
 rename xen/include/asm-x86/hvm/{event.h => monitor.h} (59%)

diff --git a/xen/arch/x86/hvm/Makefile b/xen/arch/x86/hvm/Makefile
index 8bc55a9..f750d13 100644
--- a/xen/arch/x86/hvm/Makefile
+++ b/xen/arch/x86/hvm/Makefile
@@ -3,7 +3,6 @@ subdir-y += vmx
 
 obj-y += asid.o
 obj-y += emulate.o
-obj-y += event.o
 obj-y += hpet.o
 obj-y += hvm.o
 obj-y += i8254.o
@@ -11,6 +10,7 @@ obj-y += intercept.o
 obj-y += io.o
 obj-y += ioreq.o
 obj-y += irq.o
+obj-y += monitor.o
 obj-y += mtrr.o
 obj-y += nestedhvm.o
 obj-y += pmtimer.o
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 337a119..ef18949 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -60,7 +60,7 @@
 #include <asm/hvm/cacheattr.h>
 #include <asm/hvm/trace.h>
 #include <asm/hvm/nestedhvm.h>
-#include <asm/hvm/event.h>
+#include <asm/hvm/monitor.h>
 #include <asm/hvm/ioreq.h>
 #include <asm/hvm/vmx/vmx.h>
 #include <asm/altp2m.h>
@@ -1961,7 +1961,7 @@ int hvm_handle_xsetbv(u32 index, u64 new_bv)
 {
     int rc;
 
-    hvm_event_crX(XCR0, new_bv, current->arch.xcr0);
+    hvm_monitor_crX(XCR0, new_bv, current->arch.xcr0);
 
     rc = handle_xsetbv(index, new_bv);
     if ( rc )
@@ -2197,7 +2197,7 @@ int hvm_set_cr0(unsigned long value, bool_t may_defer)
     {
         ASSERT(v->arch.vm_event);
 
-        if ( hvm_event_crX(CR0, value, old_value) )
+        if ( hvm_monitor_crX(CR0, value, old_value) )
         {
             /* The actual write will occur in hvm_do_resume(), if permitted. */
             v->arch.vm_event->write_data.do_write.cr0 = 1;
@@ -2299,7 +2299,7 @@ int hvm_set_cr3(unsigned long value, bool_t may_defer)
     {
         ASSERT(v->arch.vm_event);
 
-        if ( hvm_event_crX(CR3, value, old) )
+        if ( hvm_monitor_crX(CR3, value, old) )
         {
             /* The actual write will occur in hvm_do_resume(), if permitted. */
             v->arch.vm_event->write_data.do_write.cr3 = 1;
@@ -2379,7 +2379,7 @@ int hvm_set_cr4(unsigned long value, bool_t may_defer)
     {
         ASSERT(v->arch.vm_event);
 
-        if ( hvm_event_crX(CR4, value, old_cr) )
+        if ( hvm_monitor_crX(CR4, value, old_cr) )
         {
             /* The actual write will occur in hvm_do_resume(), if permitted. */
             v->arch.vm_event->write_data.do_write.cr4 = 1;
@@ -3765,7 +3765,7 @@ int hvm_msr_write_intercept(unsigned int msr, uint64_t msr_content,
         v->arch.vm_event->write_data.msr = msr;
         v->arch.vm_event->write_data.value = msr_content;
 
-        hvm_event_msr(msr, msr_content);
+        hvm_monitor_msr(msr, msr_content);
         return X86EMUL_OKAY;
     }
 
diff --git a/xen/arch/x86/hvm/event.c b/xen/arch/x86/hvm/monitor.c
similarity index 88%
rename from xen/arch/x86/hvm/event.c
rename to xen/arch/x86/hvm/monitor.c
index 8fdb6f5..f0ab33a 100644
--- a/xen/arch/x86/hvm/event.c
+++ b/xen/arch/x86/hvm/monitor.c
@@ -1,5 +1,5 @@
 /*
- * arch/x86/hvm/event.c
+ * arch/x86/hvm/monitor.c
  *
  * Arch-specific hardware virtual machine event abstractions.
  *
@@ -7,6 +7,7 @@
  * Copyright (c) 2005, International Business Machines Corporation.
  * Copyright (c) 2008, Citrix Systems, Inc.
  * Copyright (c) 2016, Bitdefender S.R.L.
+ * Copyright (c) 2016, Tamas K Lengyel (tamas@tklengyel.com)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -22,12 +23,12 @@
  */
 
 #include <xen/vm_event.h>
-#include <asm/hvm/event.h>
+#include <asm/hvm/monitor.h>
 #include <asm/monitor.h>
 #include <asm/vm_event.h>
 #include <public/vm_event.h>
 
-bool_t hvm_event_cr(unsigned int index, unsigned long value, unsigned long old)
+bool_t hvm_monitor_cr(unsigned int index, unsigned long value, unsigned long old)
 {
     struct vcpu *curr = current;
     struct arch_domain *ad = &curr->domain->arch;
@@ -54,7 +55,7 @@ bool_t hvm_event_cr(unsigned int index, unsigned long value, unsigned long old)
     return 0;
 }
 
-void hvm_event_msr(unsigned int msr, uint64_t value)
+void hvm_monitor_msr(unsigned int msr, uint64_t value)
 {
     struct vcpu *curr = current;
 
@@ -86,8 +87,8 @@ static inline unsigned long gfn_of_rip(unsigned long rip)
     return paging_gva_to_gfn(curr, sreg.base + rip, &pfec);
 }
 
-int hvm_event_breakpoint(unsigned long rip,
-                         enum hvm_event_breakpoint_type type)
+int hvm_monitor_breakpoint(unsigned long rip,
+                           enum hvm_monitor_breakpoint_type type)
 {
     struct vcpu *curr = current;
     struct arch_domain *ad = &curr->domain->arch;
@@ -95,14 +96,14 @@ int hvm_event_breakpoint(unsigned long rip,
 
     switch ( type )
     {
-    case HVM_EVENT_SOFTWARE_BREAKPOINT:
+    case HVM_MONITOR_SOFTWARE_BREAKPOINT:
         if ( !ad->monitor.software_breakpoint_enabled )
             return 0;
         req.reason = VM_EVENT_REASON_SOFTWARE_BREAKPOINT;
         req.u.software_breakpoint.gfn = gfn_of_rip(rip);
         break;
 
-    case HVM_EVENT_SINGLESTEP_BREAKPOINT:
+    case HVM_MONITOR_SINGLESTEP_BREAKPOINT:
         if ( !ad->monitor.singlestep_enabled )
             return 0;
         req.reason = VM_EVENT_REASON_SINGLESTEP;
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 4edf283..a56926c 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -50,7 +50,7 @@
 #include <asm/hvm/vpt.h>
 #include <public/hvm/save.h>
 #include <asm/hvm/trace.h>
-#include <asm/hvm/event.h>
+#include <asm/hvm/monitor.h>
 #include <asm/xenoprof.h>
 #include <asm/debugger.h>
 #include <asm/apic.h>
@@ -2473,10 +2473,10 @@ static int vmx_cr_access(unsigned long exit_qualification)
 
         /*
          * Special case unlikely to be interesting to a
-         * VM_EVENT_FLAG_DENY-capable application, so the hvm_event_crX()
+         * VM_EVENT_FLAG_DENY-capable application, so the hvm_monitor_crX()
          * return value is ignored for now.
          */
-        hvm_event_crX(CR0, value, old);
+        hvm_monitor_crX(CR0, value, old);
         curr->arch.hvm_vcpu.guest_cr[0] = value;
         vmx_update_guest_cr(curr, 0);
         HVMTRACE_0D(CLTS);
@@ -3389,8 +3389,8 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
             }
             else {
                 int handled =
-                        hvm_event_breakpoint(regs->eip,
-                                             HVM_EVENT_SOFTWARE_BREAKPOINT);
+                      hvm_monitor_breakpoint(regs->eip,
+                                             HVM_MONITOR_SOFTWARE_BREAKPOINT);
 
                 if ( handled < 0 ) 
                 {
@@ -3717,7 +3717,8 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
         vmx_update_cpu_exec_control(v);
         if ( v->arch.hvm_vcpu.single_step )
         {
-            hvm_event_breakpoint(regs->eip, HVM_EVENT_SINGLESTEP_BREAKPOINT);
+            hvm_monitor_breakpoint(regs->eip,
+                                   HVM_MONITOR_SINGLESTEP_BREAKPOINT);
             if ( v->domain->debugger_attached )
                 domain_pause_for_debugger();
         }
diff --git a/xen/include/asm-x86/hvm/event.h b/xen/include/asm-x86/hvm/monitor.h
similarity index 59%
rename from xen/include/asm-x86/hvm/event.h
rename to xen/include/asm-x86/hvm/monitor.h
index 03f7fee..55d435e 100644
--- a/xen/include/asm-x86/hvm/event.h
+++ b/xen/include/asm-x86/hvm/monitor.h
@@ -1,7 +1,7 @@
 /*
- * include/asm-x86/hvm/event.h
+ * include/asm-x86/hvm/monitor.h
  *
- * Arch-specific hardware virtual machine event abstractions.
+ * Arch-specific hardware virtual machine monitor abstractions.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -16,17 +16,17 @@
  * this program; If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __ASM_X86_HVM_EVENT_H__
-#define __ASM_X86_HVM_EVENT_H__
+#ifndef __ASM_X86_HVM_MONITOR_H__
+#define __ASM_X86_HVM_MONITOR_H__
 
 #include <xen/sched.h>
 #include <xen/paging.h>
 #include <public/vm_event.h>
 
-enum hvm_event_breakpoint_type
+enum hvm_monitor_breakpoint_type
 {
-    HVM_EVENT_SOFTWARE_BREAKPOINT,
-    HVM_EVENT_SINGLESTEP_BREAKPOINT,
+    HVM_MONITOR_SOFTWARE_BREAKPOINT,
+    HVM_MONITOR_SINGLESTEP_BREAKPOINT,
 };
 
 /*
@@ -34,15 +34,15 @@ enum hvm_event_breakpoint_type
  * The event might not fire if the client has subscribed to it in onchangeonly
  * mode, hence the bool_t return type for control register write events.
  */
-bool_t hvm_event_cr(unsigned int index, unsigned long value,
-                    unsigned long old);
-#define hvm_event_crX(cr, new, old) \
-    hvm_event_cr(VM_EVENT_X86_##cr, new, old)
-void hvm_event_msr(unsigned int msr, uint64_t value);
-int hvm_event_breakpoint(unsigned long rip,
-                         enum hvm_event_breakpoint_type type);
+bool_t hvm_monitor_cr(unsigned int index, unsigned long value,
+                      unsigned long old);
+#define hvm_monitor_crX(cr, new, old) \
+                        hvm_monitor_cr(VM_EVENT_X86_##cr, new, old)
+void hvm_monitor_msr(unsigned int msr, uint64_t value);
+int hvm_monitor_breakpoint(unsigned long rip,
+                           enum hvm_monitor_breakpoint_type type);
 
-#endif /* __ASM_X86_HVM_EVENT_H__ */
+#endif /* __ASM_X86_HVM_MONITOR_H__ */
 
 /*
  * Local variables:
-- 
2.8.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v6 4/5] vm_event: clear up return value of vm_event_monitor_traps
  2016-06-23 17:07 [PATCH v6 1/5] monitor: Rename vm_event_monitor_get_capabilities Tamas K Lengyel
  2016-06-23 17:07 ` [PATCH v6 2/5] monitor: Rename vm_event_monitor_guest_request Tamas K Lengyel
  2016-06-23 17:07 ` [PATCH v6 3/5] monitor: Rename hvm/event to hvm/monitor Tamas K Lengyel
@ 2016-06-23 17:07 ` Tamas K Lengyel
  2016-06-24 10:59   ` Tian, Kevin
  2016-06-23 17:07 ` [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events Tamas K Lengyel
  3 siblings, 1 reply; 14+ messages in thread
From: Tamas K Lengyel @ 2016-06-23 17:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Kevin Tian, Tamas K Lengyel, Jun Nakajima

The return value has not been clearly defined, with the function
never returning 0 which seemingly indicated a condition where the
guest should crash.

In this patch we define -rc as error condition where a subscriber is
present but an error prevented the notification from being sent;
0 where there is no subscriber or the notification was sent and the vCPU
is not paused (i.e. safe to continue execution as normal); and 1 where the
notification was sent with the vCPU paused and we are waiting for a
response.

Signed-off-by: Tamas K Lengyel <tamas@tklengyel.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
---
Cc: Jun Nakajima <jun.nakajima@intel.com>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>

v6: Remove unnecessary else clause in vmx
---
 xen/arch/x86/hvm/monitor.c | 4 ++--
 xen/arch/x86/hvm/vmx/vmx.c | 6 +++---
 xen/common/vm_event.c      | 5 +++--
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/xen/arch/x86/hvm/monitor.c b/xen/arch/x86/hvm/monitor.c
index f0ab33a..472926c 100644
--- a/xen/arch/x86/hvm/monitor.c
+++ b/xen/arch/x86/hvm/monitor.c
@@ -48,8 +48,8 @@ bool_t hvm_monitor_cr(unsigned int index, unsigned long value, unsigned long old
             .u.write_ctrlreg.old_value = old
         };
 
-        vm_event_monitor_traps(curr, sync, &req);
-        return 1;
+        if ( vm_event_monitor_traps(curr, sync, &req) >= 0 )
+            return 1;
     }
 
     return 0;
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index a56926c..03fcba7 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -3388,11 +3388,11 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
                 break;
             }
             else {
-                int handled =
+                int rc =
                       hvm_monitor_breakpoint(regs->eip,
                                              HVM_MONITOR_SOFTWARE_BREAKPOINT);
 
-                if ( handled < 0 ) 
+                if ( !rc )
                 {
                     struct hvm_trap trap = {
                         .vector = TRAP_int3,
@@ -3406,7 +3406,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
                     hvm_inject_trap(&trap);
                     break;
                 }
-                else if ( handled )
+                if ( rc > 0 )
                     break;
             }
 
diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index ca1eced..b303180 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -806,7 +806,7 @@ int vm_event_monitor_traps(struct vcpu *v, uint8_t sync,
          * If there was no ring to handle the event, then
          * simply continue executing normally.
          */
-        return 1;
+        return 0;
     default:
         return rc;
     };
@@ -815,6 +815,7 @@ int vm_event_monitor_traps(struct vcpu *v, uint8_t sync,
     {
         req->flags |= VM_EVENT_FLAG_VCPU_PAUSED;
         vm_event_vcpu_pause(v);
+        rc = 1;
     }
 
     if ( altp2m_active(d) )
@@ -826,7 +827,7 @@ int vm_event_monitor_traps(struct vcpu *v, uint8_t sync,
     vm_event_fill_regs(req);
     vm_event_put_request(d, &d->vm_event->monitor, req);
 
-    return 1;
+    return rc;
 }
 
 /*
-- 
2.8.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events
  2016-06-23 17:07 [PATCH v6 1/5] monitor: Rename vm_event_monitor_get_capabilities Tamas K Lengyel
                   ` (2 preceding siblings ...)
  2016-06-23 17:07 ` [PATCH v6 4/5] vm_event: clear up return value of vm_event_monitor_traps Tamas K Lengyel
@ 2016-06-23 17:07 ` Tamas K Lengyel
  2016-06-24  7:14   ` Jan Beulich
                     ` (2 more replies)
  3 siblings, 3 replies; 14+ messages in thread
From: Tamas K Lengyel @ 2016-06-23 17:07 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Tamas K Lengyel, Wei Liu, Jun Nakajima,
	Razvan Cojocaru, Andrew Cooper, Ian Jackson, Jan Beulich

Since in-guest debug exceptions are now unconditionally trapped to Xen, adding
a hook for vm_event subscribers to tap into this new always-on guest event. We
rename along the way hvm_event_breakpoint_type to hvm_event_type to better
match the various events that can be passed with it. We also introduce the
necessary monitor_op domctl's to enable subscribing to the events.

This patch also provides monitor subscribers to int3 events proper access
to the instruction length necessary for accurate event-reinjection. Without
this subscribers manually have to evaluate if the int3 instruction has any
prefix attached which would change the instruction length.

Signed-off-by: Tamas K Lengyel <tamas@tklengyel.com>
---
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Razvan Cojocaru <rcojocaru@bitdefender.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jun Nakajima <jun.nakajima@intel.com>
Cc: Kevin Tian <kevin.tian@intel.com>

v6: Add comment describing rc condition values for the monitor call
v5: Transmit the proper insn_length for int3 events as well to fix
     the current bug with prefixed int3 instructions.
---
 tools/libxc/include/xenctrl.h       |  3 +-
 tools/libxc/xc_monitor.c            | 25 +++++++++++++++
 tools/tests/xen-access/xen-access.c | 63 ++++++++++++++++++++++++++++++++-----
 xen/arch/x86/hvm/monitor.c          | 21 +++++++++++--
 xen/arch/x86/hvm/vmx/vmx.c          | 55 +++++++++++++++++++++++++-------
 xen/arch/x86/monitor.c              | 16 ++++++++++
 xen/include/asm-x86/domain.h        |  2 ++
 xen/include/asm-x86/hvm/monitor.h   |  7 +++--
 xen/include/asm-x86/monitor.h       |  3 +-
 xen/include/public/domctl.h         |  6 ++++
 xen/include/public/vm_event.h       | 14 +++++++--
 11 files changed, 186 insertions(+), 29 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 4f5d954..4a85b4a 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2165,7 +2165,8 @@ int xc_monitor_software_breakpoint(xc_interface *xch, domid_t domain_id,
                                    bool enable);
 int xc_monitor_guest_request(xc_interface *xch, domid_t domain_id,
                              bool enable, bool sync);
-
+int xc_monitor_debug_exceptions(xc_interface *xch, domid_t domain_id,
+                                bool enable, bool sync);
 /**
  * This function enables / disables emulation for each REP for a
  * REP-compatible instruction.
diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c
index 78131b2..264992c 100644
--- a/tools/libxc/xc_monitor.c
+++ b/tools/libxc/xc_monitor.c
@@ -156,3 +156,28 @@ int xc_monitor_emulate_each_rep(xc_interface *xch, domid_t domain_id,
 
     return do_domctl(xch, &domctl);
 }
+
+int xc_monitor_debug_exceptions(xc_interface *xch, domid_t domain_id,
+                                bool enable, bool sync)
+{
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_monitor_op;
+    domctl.domain = domain_id;
+    domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
+                                    : XEN_DOMCTL_MONITOR_OP_DISABLE;
+    domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION;
+    domctl.u.monitor_op.u.debug_exception.sync = sync;
+
+    return do_domctl(xch, &domctl);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c
index f26e723..e615476 100644
--- a/tools/tests/xen-access/xen-access.c
+++ b/tools/tests/xen-access/xen-access.c
@@ -53,6 +53,10 @@
 #define ERROR(a, b...) fprintf(stderr, a "\n", ## b)
 #define PERROR(a, b...) fprintf(stderr, a ": %s\n", ## b, strerror(errno))
 
+/* From xen/include/asm-x86/processor.h */
+#define X86_TRAP_DEBUG  1
+#define X86_TRAP_INT3   3
+
 typedef struct vm_event {
     domid_t domain_id;
     xenevtchn_handle *xce_handle;
@@ -333,7 +337,7 @@ void usage(char* progname)
 {
     fprintf(stderr, "Usage: %s [-m] <domain_id> write|exec", progname);
 #if defined(__i386__) || defined(__x86_64__)
-            fprintf(stderr, "|breakpoint|altp2m_write|altp2m_exec");
+            fprintf(stderr, "|breakpoint|altp2m_write|altp2m_exec|debug");
 #endif
             fprintf(stderr,
             "\n"
@@ -354,10 +358,12 @@ int main(int argc, char *argv[])
     xc_interface *xch;
     xenmem_access_t default_access = XENMEM_access_rwx;
     xenmem_access_t after_first_access = XENMEM_access_rwx;
+    int memaccess = 0;
     int required = 0;
     int breakpoint = 0;
     int shutting_down = 0;
     int altp2m = 0;
+    int debug = 0;
     uint16_t altp2m_view_id = 0;
 
     char* progname = argv[0];
@@ -391,11 +397,13 @@ int main(int argc, char *argv[])
     {
         default_access = XENMEM_access_rx;
         after_first_access = XENMEM_access_rwx;
+        memaccess = 1;
     }
     else if ( !strcmp(argv[0], "exec") )
     {
         default_access = XENMEM_access_rw;
         after_first_access = XENMEM_access_rwx;
+        memaccess = 1;
     }
 #if defined(__i386__) || defined(__x86_64__)
     else if ( !strcmp(argv[0], "breakpoint") )
@@ -406,11 +414,17 @@ int main(int argc, char *argv[])
     {
         default_access = XENMEM_access_rx;
         altp2m = 1;
+        memaccess = 1;
     }
     else if ( !strcmp(argv[0], "altp2m_exec") )
     {
         default_access = XENMEM_access_rw;
         altp2m = 1;
+        memaccess = 1;
+    }
+    else if ( !strcmp(argv[0], "debug") )
+    {
+        debug = 1;
     }
 #endif
     else
@@ -446,7 +460,7 @@ int main(int argc, char *argv[])
     }
 
     /* With altp2m we just create a new, restricted view of the memory */
-    if ( altp2m )
+    if ( memaccess && altp2m )
     {
         xen_pfn_t gfn = 0;
         unsigned long perm_set = 0;
@@ -493,7 +507,7 @@ int main(int argc, char *argv[])
         }
     }
 
-    if ( !altp2m )
+    if ( memaccess && !altp2m )
     {
         /* Set the default access type and convert all pages to it */
         rc = xc_set_mem_access(xch, domain_id, default_access, ~0ull, 0);
@@ -524,6 +538,16 @@ int main(int argc, char *argv[])
         }
     }
 
+    if ( debug )
+    {
+        rc = xc_monitor_debug_exceptions(xch, domain_id, 1, 1);
+        if ( rc < 0 )
+        {
+            ERROR("Error %d setting debug exception listener with vm_event\n", rc);
+            goto exit;
+        }
+    }
+
     /* Wait for access */
     for (;;)
     {
@@ -534,6 +558,8 @@ int main(int argc, char *argv[])
 
             if ( breakpoint )
                 rc = xc_monitor_software_breakpoint(xch, domain_id, 0);
+            if ( debug )
+                rc = xc_monitor_debug_exceptions(xch, domain_id, 0, 0);
 
             if ( altp2m )
             {
@@ -635,22 +661,22 @@ int main(int argc, char *argv[])
                 rsp.u.mem_access = req.u.mem_access;
                 break;
             case VM_EVENT_REASON_SOFTWARE_BREAKPOINT:
-                printf("Breakpoint: rip=%016"PRIx64", gfn=%"PRIx64" (vcpu %d)\n",
+                printf("Breakpoint: rip=%016"PRIx64" gfn=%"PRIx64" (vcpu %d)\n",
                        req.data.regs.x86.rip,
                        req.u.software_breakpoint.gfn,
                        req.vcpu_id);
 
                 /* Reinject */
-                rc = xc_hvm_inject_trap(
-                    xch, domain_id, req.vcpu_id, 3,
-                    HVMOP_TRAP_sw_exc, -1, 0, 0);
+                rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id,
+                                        X86_TRAP_INT3,
+                                        req.u.software_breakpoint.type, -1,
+                                        req.u.software_breakpoint.insn_length, 0);
                 if (rc < 0)
                 {
                     ERROR("Error %d injecting breakpoint\n", rc);
                     interrupted = -1;
                     continue;
                 }
-
                 break;
             case VM_EVENT_REASON_SINGLESTEP:
                 printf("Singlestep: rip=%016"PRIx64", vcpu %d, altp2m %u\n",
@@ -669,6 +695,27 @@ int main(int argc, char *argv[])
                 rsp.flags |= VM_EVENT_FLAG_TOGGLE_SINGLESTEP;
 
                 break;
+            case VM_EVENT_REASON_DEBUG_EXCEPTION:
+                printf("Debug exception: rip=%016"PRIx64", vcpu %d. Type: %u. Length: %u\n",
+                       req.data.regs.x86.rip,
+                       req.vcpu_id,
+                       req.u.debug_exception.type,
+                       req.u.debug_exception.insn_length);
+
+                /* Reinject */
+                rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id,
+                                        X86_TRAP_DEBUG,
+                                        req.u.debug_exception.type, -1,
+                                        req.u.debug_exception.insn_length,
+                                        req.data.regs.x86.cr2);
+                if (rc < 0)
+                {
+                    ERROR("Error %d injecting breakpoint\n", rc);
+                    interrupted = -1;
+                    continue;
+                }
+
+                break;
             default:
                 fprintf(stderr, "UNKNOWN REASON CODE %d\n", req.reason);
             }
diff --git a/xen/arch/x86/hvm/monitor.c b/xen/arch/x86/hvm/monitor.c
index 472926c..bbe5952 100644
--- a/xen/arch/x86/hvm/monitor.c
+++ b/xen/arch/x86/hvm/monitor.c
@@ -87,12 +87,13 @@ static inline unsigned long gfn_of_rip(unsigned long rip)
     return paging_gva_to_gfn(curr, sreg.base + rip, &pfec);
 }
 
-int hvm_monitor_breakpoint(unsigned long rip,
-                           enum hvm_monitor_breakpoint_type type)
+int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type,
+                      unsigned long trap_type, unsigned long insn_length)
 {
     struct vcpu *curr = current;
     struct arch_domain *ad = &curr->domain->arch;
     vm_event_request_t req = {};
+    bool_t sync;
 
     switch ( type )
     {
@@ -101,6 +102,9 @@ int hvm_monitor_breakpoint(unsigned long rip,
             return 0;
         req.reason = VM_EVENT_REASON_SOFTWARE_BREAKPOINT;
         req.u.software_breakpoint.gfn = gfn_of_rip(rip);
+        req.u.software_breakpoint.type = trap_type;
+        req.u.software_breakpoint.insn_length = insn_length;
+        sync = 1;
         break;
 
     case HVM_MONITOR_SINGLESTEP_BREAKPOINT:
@@ -108,6 +112,17 @@ int hvm_monitor_breakpoint(unsigned long rip,
             return 0;
         req.reason = VM_EVENT_REASON_SINGLESTEP;
         req.u.singlestep.gfn = gfn_of_rip(rip);
+        sync = 1;
+        break;
+
+    case HVM_MONITOR_DEBUG_EXCEPTION:
+        if ( !ad->monitor.debug_exception_enabled )
+            return 0;
+        req.reason = VM_EVENT_REASON_DEBUG_EXCEPTION;
+        req.u.debug_exception.gfn = gfn_of_rip(rip);
+        req.u.debug_exception.type = trap_type;
+        req.u.debug_exception.insn_length = insn_length;
+        sync = !!ad->monitor.debug_exception_sync;
         break;
 
     default:
@@ -116,7 +131,7 @@ int hvm_monitor_breakpoint(unsigned long rip,
 
     req.vcpu_id = curr->vcpu_id;
 
-    return vm_event_monitor_traps(curr, 1, &req);
+    return vm_event_monitor_traps(curr, sync, &req);
 }
 
 /*
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 03fcba7..4b69ca6 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -3373,10 +3373,39 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
             HVMTRACE_1D(TRAP_DEBUG, exit_qualification);
             write_debugreg(6, exit_qualification | DR_STATUS_RESERVED_ONE);
             if ( !v->domain->debugger_attached )
-                vmx_propagate_intr(intr_info);
+            {
+                unsigned long insn_len = 0;
+                int rc;
+                unsigned long trap_type = MASK_EXTR(intr_info,
+                                                    INTR_INFO_INTR_TYPE_MASK);
+
+                if ( trap_type >= X86_EVENTTYPE_SW_INTERRUPT )
+                    __vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len);
+
+                rc = hvm_monitor_debug(regs->eip,
+                                       HVM_MONITOR_DEBUG_EXCEPTION,
+                                       trap_type, insn_len);
+
+                /*
+                 * !rc  continue normally
+                 * rc > paused waiting for response, work here is done
+                 * rc < error, fall-through to exit_and_crash
+                 */
+                if ( !rc )
+                {
+                    vmx_propagate_intr(intr_info);
+                    break;
+                }
+                if ( rc > 0 )
+                    break;
+            }
             else
+            {
                 domain_pause_for_debugger();
-            break;
+                break;
+            }
+
+            goto exit_and_crash;
         case TRAP_int3: 
         {
             HVMTRACE_1D(TRAP, vector);
@@ -3388,9 +3417,14 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
                 break;
             }
             else {
-                int rc =
-                      hvm_monitor_breakpoint(regs->eip,
-                                             HVM_MONITOR_SOFTWARE_BREAKPOINT);
+                unsigned long insn_len;
+                int rc;
+
+                __vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len);
+                rc = hvm_monitor_debug(regs->eip,
+                                       HVM_MONITOR_SOFTWARE_BREAKPOINT,
+                                       X86_EVENTTYPE_SW_EXCEPTION,
+                                       insn_len);
 
                 if ( !rc )
                 {
@@ -3398,11 +3432,8 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
                         .vector = TRAP_int3,
                         .type = X86_EVENTTYPE_SW_EXCEPTION,
                         .error_code = HVM_DELIVER_NO_ERROR_CODE,
+                        .insn_len = insn_len
                     };
-                    unsigned long insn_len;
-
-                    __vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len);
-                    trap.insn_len = insn_len;
                     hvm_inject_trap(&trap);
                     break;
                 }
@@ -3717,8 +3748,10 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
         vmx_update_cpu_exec_control(v);
         if ( v->arch.hvm_vcpu.single_step )
         {
-            hvm_monitor_breakpoint(regs->eip,
-                                   HVM_MONITOR_SINGLESTEP_BREAKPOINT);
+            hvm_monitor_debug(regs->eip,
+                              HVM_MONITOR_SINGLESTEP_BREAKPOINT,
+                              0, 0);
+
             if ( v->domain->debugger_attached )
                 domain_pause_for_debugger();
         }
diff --git a/xen/arch/x86/monitor.c b/xen/arch/x86/monitor.c
index a271161..205df41 100644
--- a/xen/arch/x86/monitor.c
+++ b/xen/arch/x86/monitor.c
@@ -224,6 +224,22 @@ int arch_monitor_domctl_event(struct domain *d,
         break;
     }
 
+    case XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION:
+    {
+        bool_t old_status = ad->monitor.debug_exception_enabled;
+
+        if ( unlikely(old_status == requested_status) )
+            return -EEXIST;
+
+        domain_pause(d);
+        ad->monitor.debug_exception_enabled = requested_status;
+        ad->monitor.debug_exception_sync = requested_status ?
+                                            mop->u.debug_exception.sync :
+                                            0;
+        domain_unpause(d);
+        break;
+    }
+
     default:
         /*
          * Should not be reached unless arch_monitor_get_capabilities() is
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 7c27f9e..8f64ae9 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -403,6 +403,8 @@ struct arch_domain
         unsigned int write_ctrlreg_onchangeonly  : 4;
         unsigned int singlestep_enabled          : 1;
         unsigned int software_breakpoint_enabled : 1;
+        unsigned int debug_exception_enabled     : 1;
+        unsigned int debug_exception_sync        : 1;
         struct monitor_msr_bitmap *msr_bitmap;
     } monitor;
 
diff --git a/xen/include/asm-x86/hvm/monitor.h b/xen/include/asm-x86/hvm/monitor.h
index 55d435e..8b0f119 100644
--- a/xen/include/asm-x86/hvm/monitor.h
+++ b/xen/include/asm-x86/hvm/monitor.h
@@ -23,10 +23,11 @@
 #include <xen/paging.h>
 #include <public/vm_event.h>
 
-enum hvm_monitor_breakpoint_type
+enum hvm_monitor_debug_type
 {
     HVM_MONITOR_SOFTWARE_BREAKPOINT,
     HVM_MONITOR_SINGLESTEP_BREAKPOINT,
+    HVM_MONITOR_DEBUG_EXCEPTION,
 };
 
 /*
@@ -39,8 +40,8 @@ bool_t hvm_monitor_cr(unsigned int index, unsigned long value,
 #define hvm_monitor_crX(cr, new, old) \
                         hvm_monitor_cr(VM_EVENT_X86_##cr, new, old)
 void hvm_monitor_msr(unsigned int msr, uint64_t value);
-int hvm_monitor_breakpoint(unsigned long rip,
-                           enum hvm_monitor_breakpoint_type type);
+int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type,
+                      unsigned long trap_type, unsigned long insn_length);
 
 #endif /* __ASM_X86_HVM_MONITOR_H__ */
 
diff --git a/xen/include/asm-x86/monitor.h b/xen/include/asm-x86/monitor.h
index 94b6768..a9db3c0 100644
--- a/xen/include/asm-x86/monitor.h
+++ b/xen/include/asm-x86/monitor.h
@@ -77,7 +77,8 @@ static inline uint32_t arch_monitor_get_capabilities(struct domain *d)
     capabilities = (1U << XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG) |
                    (1U << XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR) |
                    (1U << XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT) |
-                   (1U << XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST);
+                   (1U << XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST) |
+                   (1U << XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION);
 
     /* Since we know this is on VMX, we can just call the hvm func */
     if ( hvm_is_singlestep_supported() )
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 7be3924..30020ba 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -1080,6 +1080,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_psr_cmt_op_t);
 #define XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP            2
 #define XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT   3
 #define XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST         4
+#define XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION       5
 
 struct xen_domctl_monitor_op {
     uint32_t op; /* XEN_DOMCTL_MONITOR_OP_* */
@@ -1114,6 +1115,11 @@ struct xen_domctl_monitor_op {
             /* Pause vCPU until response */
             uint8_t sync;
         } guest_request;
+
+        struct {
+            /* Pause vCPU until response */
+            uint8_t sync;
+        } debug_exception;
     } u;
 };
 typedef struct xen_domctl_monitor_op xen_domctl_monitor_op_t;
diff --git a/xen/include/public/vm_event.h b/xen/include/public/vm_event.h
index 9270d52..68bddfb 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 0x00000001
+#define VM_EVENT_INTERFACE_VERSION 0x00000002
 
 #if defined(__XEN__) || defined(__XEN_TOOLS__)
 
@@ -119,6 +119,8 @@
 #define VM_EVENT_REASON_SINGLESTEP              7
 /* An event has been requested via HVMOP_guest_request_vm_event. */
 #define VM_EVENT_REASON_GUEST_REQUEST           8
+/* A debug exception was caught */
+#define VM_EVENT_REASON_DEBUG_EXCEPTION         9
 
 /* Supported values for the vm_event_write_ctrlreg index. */
 #define VM_EVENT_X86_CR0    0
@@ -203,8 +205,15 @@ struct vm_event_write_ctrlreg {
     uint64_t old_value;
 };
 
+struct vm_event_singlestep {
+    uint64_t gfn;
+};
+
 struct vm_event_debug {
     uint64_t gfn;
+    uint32_t insn_length;
+    uint8_t type;        /* HVMOP_TRAP_* */
+    uint8_t _pad[3];
 };
 
 struct vm_event_mov_to_msr {
@@ -247,8 +256,9 @@ typedef struct vm_event_st {
         struct vm_event_mem_access            mem_access;
         struct vm_event_write_ctrlreg         write_ctrlreg;
         struct vm_event_mov_to_msr            mov_to_msr;
+        struct vm_event_singlestep            singlestep;
         struct vm_event_debug                 software_breakpoint;
-        struct vm_event_debug                 singlestep;
+        struct vm_event_debug                 debug_exception;
     } u;
 
     union {
-- 
2.8.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events
  2016-06-23 17:07 ` [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events Tamas K Lengyel
@ 2016-06-24  7:14   ` Jan Beulich
  2016-06-24  7:56   ` Razvan Cojocaru
  2016-06-24 11:20   ` Tian, Kevin
  2 siblings, 0 replies; 14+ messages in thread
From: Jan Beulich @ 2016-06-24  7:14 UTC (permalink / raw)
  To: Tamas K Lengyel
  Cc: Kevin Tian, Wei Liu, Razvan Cojocaru, Andrew Cooper, Ian Jackson,
	Jun Nakajima, xen-devel

>>> On 23.06.16 at 19:07, <tamas@tklengyel.com> wrote:
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -3373,10 +3373,39 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
>              HVMTRACE_1D(TRAP_DEBUG, exit_qualification);
>              write_debugreg(6, exit_qualification | DR_STATUS_RESERVED_ONE);
>              if ( !v->domain->debugger_attached )
> -                vmx_propagate_intr(intr_info);
> +            {
> +                unsigned long insn_len = 0;
> +                int rc;
> +                unsigned long trap_type = MASK_EXTR(intr_info,
> +                                                    INTR_INFO_INTR_TYPE_MASK);
> +
> +                if ( trap_type >= X86_EVENTTYPE_SW_INTERRUPT )
> +                    __vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len);
> +
> +                rc = hvm_monitor_debug(regs->eip,
> +                                       HVM_MONITOR_DEBUG_EXCEPTION,
> +                                       trap_type, insn_len);
> +
> +                /*
> +                 * !rc  continue normally
> +                 * rc > paused waiting for response, work here is done
> +                 * rc < error, fall-through to exit_and_crash
> +                 */
> +                if ( !rc )
> +                {
> +                    vmx_propagate_intr(intr_info);
> +                    break;
> +                }
> +                if ( rc > 0 )
> +                    break;
> +            }
>              else
> +            {
>                  domain_pause_for_debugger();
> -            break;
> +                break;
> +            }
> +
> +            goto exit_and_crash;

I continue to think this is sub-optimal structuring (at once needlessly
making the patch larger), but it'll be the VMX maintainers to judge.

For the few pieces it is relevant for:
Acked-by: Jan Beulich <jbeulich@suse.com>

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events
  2016-06-23 17:07 ` [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events Tamas K Lengyel
  2016-06-24  7:14   ` Jan Beulich
@ 2016-06-24  7:56   ` Razvan Cojocaru
  2016-06-24 18:48     ` Tamas K Lengyel
  2016-06-24 11:20   ` Tian, Kevin
  2 siblings, 1 reply; 14+ messages in thread
From: Razvan Cojocaru @ 2016-06-24  7:56 UTC (permalink / raw)
  To: Tamas K Lengyel, xen-devel
  Cc: Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper, Ian Jackson,
	Jun Nakajima

On 06/23/2016 08:07 PM, Tamas K Lengyel wrote:
> Since in-guest debug exceptions are now unconditionally trapped to Xen, adding
> a hook for vm_event subscribers to tap into this new always-on guest event. We
> rename along the way hvm_event_breakpoint_type to hvm_event_type to better
> match the various events that can be passed with it. We also introduce the
> necessary monitor_op domctl's to enable subscribing to the events.
> 
> This patch also provides monitor subscribers to int3 events proper access
> to the instruction length necessary for accurate event-reinjection. Without
> this subscribers manually have to evaluate if the int3 instruction has any
> prefix attached which would change the instruction length.
> 
> Signed-off-by: Tamas K Lengyel <tamas@tklengyel.com>
> ---
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Razvan Cojocaru <rcojocaru@bitdefender.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Jun Nakajima <jun.nakajima@intel.com>
> Cc: Kevin Tian <kevin.tian@intel.com>
> 
> v6: Add comment describing rc condition values for the monitor call
> v5: Transmit the proper insn_length for int3 events as well to fix
>      the current bug with prefixed int3 instructions.
> ---
>  tools/libxc/include/xenctrl.h       |  3 +-
>  tools/libxc/xc_monitor.c            | 25 +++++++++++++++
>  tools/tests/xen-access/xen-access.c | 63 ++++++++++++++++++++++++++++++++-----
>  xen/arch/x86/hvm/monitor.c          | 21 +++++++++++--
>  xen/arch/x86/hvm/vmx/vmx.c          | 55 +++++++++++++++++++++++++-------
>  xen/arch/x86/monitor.c              | 16 ++++++++++
>  xen/include/asm-x86/domain.h        |  2 ++
>  xen/include/asm-x86/hvm/monitor.h   |  7 +++--
>  xen/include/asm-x86/monitor.h       |  3 +-
>  xen/include/public/domctl.h         |  6 ++++
>  xen/include/public/vm_event.h       | 14 +++++++--
>  11 files changed, 186 insertions(+), 29 deletions(-)
> 
> diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
> index 4f5d954..4a85b4a 100644
> --- a/tools/libxc/include/xenctrl.h
> +++ b/tools/libxc/include/xenctrl.h
> @@ -2165,7 +2165,8 @@ int xc_monitor_software_breakpoint(xc_interface *xch, domid_t domain_id,
>                                     bool enable);
>  int xc_monitor_guest_request(xc_interface *xch, domid_t domain_id,
>                               bool enable, bool sync);
> -
> +int xc_monitor_debug_exceptions(xc_interface *xch, domid_t domain_id,
> +                                bool enable, bool sync);
>  /**
>   * This function enables / disables emulation for each REP for a
>   * REP-compatible instruction.
> diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c
> index 78131b2..264992c 100644
> --- a/tools/libxc/xc_monitor.c
> +++ b/tools/libxc/xc_monitor.c
> @@ -156,3 +156,28 @@ int xc_monitor_emulate_each_rep(xc_interface *xch, domid_t domain_id,
>  
>      return do_domctl(xch, &domctl);
>  }
> +
> +int xc_monitor_debug_exceptions(xc_interface *xch, domid_t domain_id,
> +                                bool enable, bool sync)
> +{
> +    DECLARE_DOMCTL;
> +
> +    domctl.cmd = XEN_DOMCTL_monitor_op;
> +    domctl.domain = domain_id;
> +    domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE
> +                                    : XEN_DOMCTL_MONITOR_OP_DISABLE;
> +    domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION;
> +    domctl.u.monitor_op.u.debug_exception.sync = sync;
> +
> +    return do_domctl(xch, &domctl);
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c
> index f26e723..e615476 100644
> --- a/tools/tests/xen-access/xen-access.c
> +++ b/tools/tests/xen-access/xen-access.c
> @@ -53,6 +53,10 @@
>  #define ERROR(a, b...) fprintf(stderr, a "\n", ## b)
>  #define PERROR(a, b...) fprintf(stderr, a ": %s\n", ## b, strerror(errno))
>  
> +/* From xen/include/asm-x86/processor.h */
> +#define X86_TRAP_DEBUG  1
> +#define X86_TRAP_INT3   3
> +
>  typedef struct vm_event {
>      domid_t domain_id;
>      xenevtchn_handle *xce_handle;
> @@ -333,7 +337,7 @@ void usage(char* progname)
>  {
>      fprintf(stderr, "Usage: %s [-m] <domain_id> write|exec", progname);
>  #if defined(__i386__) || defined(__x86_64__)
> -            fprintf(stderr, "|breakpoint|altp2m_write|altp2m_exec");
> +            fprintf(stderr, "|breakpoint|altp2m_write|altp2m_exec|debug");
>  #endif
>              fprintf(stderr,
>              "\n"
> @@ -354,10 +358,12 @@ int main(int argc, char *argv[])
>      xc_interface *xch;
>      xenmem_access_t default_access = XENMEM_access_rwx;
>      xenmem_access_t after_first_access = XENMEM_access_rwx;
> +    int memaccess = 0;
>      int required = 0;
>      int breakpoint = 0;
>      int shutting_down = 0;
>      int altp2m = 0;
> +    int debug = 0;
>      uint16_t altp2m_view_id = 0;
>  
>      char* progname = argv[0];
> @@ -391,11 +397,13 @@ int main(int argc, char *argv[])
>      {
>          default_access = XENMEM_access_rx;
>          after_first_access = XENMEM_access_rwx;
> +        memaccess = 1;
>      }
>      else if ( !strcmp(argv[0], "exec") )
>      {
>          default_access = XENMEM_access_rw;
>          after_first_access = XENMEM_access_rwx;
> +        memaccess = 1;
>      }
>  #if defined(__i386__) || defined(__x86_64__)
>      else if ( !strcmp(argv[0], "breakpoint") )
> @@ -406,11 +414,17 @@ int main(int argc, char *argv[])
>      {
>          default_access = XENMEM_access_rx;
>          altp2m = 1;
> +        memaccess = 1;
>      }
>      else if ( !strcmp(argv[0], "altp2m_exec") )
>      {
>          default_access = XENMEM_access_rw;
>          altp2m = 1;
> +        memaccess = 1;
> +    }
> +    else if ( !strcmp(argv[0], "debug") )
> +    {
> +        debug = 1;
>      }
>  #endif
>      else
> @@ -446,7 +460,7 @@ int main(int argc, char *argv[])
>      }
>  
>      /* With altp2m we just create a new, restricted view of the memory */
> -    if ( altp2m )
> +    if ( memaccess && altp2m )
>      {
>          xen_pfn_t gfn = 0;
>          unsigned long perm_set = 0;
> @@ -493,7 +507,7 @@ int main(int argc, char *argv[])
>          }
>      }
>  
> -    if ( !altp2m )
> +    if ( memaccess && !altp2m )
>      {
>          /* Set the default access type and convert all pages to it */
>          rc = xc_set_mem_access(xch, domain_id, default_access, ~0ull, 0);
> @@ -524,6 +538,16 @@ int main(int argc, char *argv[])
>          }
>      }
>  
> +    if ( debug )
> +    {
> +        rc = xc_monitor_debug_exceptions(xch, domain_id, 1, 1);
> +        if ( rc < 0 )
> +        {
> +            ERROR("Error %d setting debug exception listener with vm_event\n", rc);
> +            goto exit;
> +        }
> +    }
> +
>      /* Wait for access */
>      for (;;)
>      {
> @@ -534,6 +558,8 @@ int main(int argc, char *argv[])
>  
>              if ( breakpoint )
>                  rc = xc_monitor_software_breakpoint(xch, domain_id, 0);
> +            if ( debug )
> +                rc = xc_monitor_debug_exceptions(xch, domain_id, 0, 0);
>  
>              if ( altp2m )
>              {
> @@ -635,22 +661,22 @@ int main(int argc, char *argv[])
>                  rsp.u.mem_access = req.u.mem_access;
>                  break;
>              case VM_EVENT_REASON_SOFTWARE_BREAKPOINT:
> -                printf("Breakpoint: rip=%016"PRIx64", gfn=%"PRIx64" (vcpu %d)\n",
> +                printf("Breakpoint: rip=%016"PRIx64" gfn=%"PRIx64" (vcpu %d)\n",

You seem to have removed the comma here (',') after the first "PRIx64",
but ...

>                         req.data.regs.x86.rip,
>                         req.u.software_breakpoint.gfn,
>                         req.vcpu_id);
>  
>                  /* Reinject */
> -                rc = xc_hvm_inject_trap(
> -                    xch, domain_id, req.vcpu_id, 3,
> -                    HVMOP_TRAP_sw_exc, -1, 0, 0);
> +                rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id,
> +                                        X86_TRAP_INT3,
> +                                        req.u.software_breakpoint.type, -1,
> +                                        req.u.software_breakpoint.insn_length, 0);
>                  if (rc < 0)
>                  {
>                      ERROR("Error %d injecting breakpoint\n", rc);
>                      interrupted = -1;
>                      continue;
>                  }
> -
>                  break;
>              case VM_EVENT_REASON_SINGLESTEP:
>                  printf("Singlestep: rip=%016"PRIx64", vcpu %d, altp2m %u\n",
> @@ -669,6 +695,27 @@ int main(int argc, char *argv[])
>                  rsp.flags |= VM_EVENT_FLAG_TOGGLE_SINGLESTEP;
>  
>                  break;
> +            case VM_EVENT_REASON_DEBUG_EXCEPTION:
> +                printf("Debug exception: rip=%016"PRIx64", vcpu %d. Type: %u. Length: %u\n",

... this newly added line uses the old style (with a comma after the
first "PRIx64"). Minor issue maybe, I just don't understand why the
first modification was made.

> +                       req.data.regs.x86.rip,
> +                       req.vcpu_id,
> +                       req.u.debug_exception.type,
> +                       req.u.debug_exception.insn_length);
> +
> +                /* Reinject */
> +                rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id,
> +                                        X86_TRAP_DEBUG,
> +                                        req.u.debug_exception.type, -1,
> +                                        req.u.debug_exception.insn_length,
> +                                        req.data.regs.x86.cr2);
> +                if (rc < 0)
> +                {
> +                    ERROR("Error %d injecting breakpoint\n", rc);
> +                    interrupted = -1;
> +                    continue;
> +                }
> +
> +                break;
>              default:
>                  fprintf(stderr, "UNKNOWN REASON CODE %d\n", req.reason);
>              }
> diff --git a/xen/arch/x86/hvm/monitor.c b/xen/arch/x86/hvm/monitor.c
> index 472926c..bbe5952 100644
> --- a/xen/arch/x86/hvm/monitor.c
> +++ b/xen/arch/x86/hvm/monitor.c
> @@ -87,12 +87,13 @@ static inline unsigned long gfn_of_rip(unsigned long rip)
>      return paging_gva_to_gfn(curr, sreg.base + rip, &pfec);
>  }
>  
> -int hvm_monitor_breakpoint(unsigned long rip,
> -                           enum hvm_monitor_breakpoint_type type)
> +int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type,
> +                      unsigned long trap_type, unsigned long insn_length)
>  {
>      struct vcpu *curr = current;
>      struct arch_domain *ad = &curr->domain->arch;
>      vm_event_request_t req = {};
> +    bool_t sync;
>  
>      switch ( type )
>      {
> @@ -101,6 +102,9 @@ int hvm_monitor_breakpoint(unsigned long rip,
>              return 0;
>          req.reason = VM_EVENT_REASON_SOFTWARE_BREAKPOINT;
>          req.u.software_breakpoint.gfn = gfn_of_rip(rip);
> +        req.u.software_breakpoint.type = trap_type;
> +        req.u.software_breakpoint.insn_length = insn_length;
> +        sync = 1;
>          break;
>  
>      case HVM_MONITOR_SINGLESTEP_BREAKPOINT:
> @@ -108,6 +112,17 @@ int hvm_monitor_breakpoint(unsigned long rip,
>              return 0;
>          req.reason = VM_EVENT_REASON_SINGLESTEP;
>          req.u.singlestep.gfn = gfn_of_rip(rip);
> +        sync = 1;
> +        break;
> +
> +    case HVM_MONITOR_DEBUG_EXCEPTION:
> +        if ( !ad->monitor.debug_exception_enabled )
> +            return 0;
> +        req.reason = VM_EVENT_REASON_DEBUG_EXCEPTION;
> +        req.u.debug_exception.gfn = gfn_of_rip(rip);
> +        req.u.debug_exception.type = trap_type;
> +        req.u.debug_exception.insn_length = insn_length;
> +        sync = !!ad->monitor.debug_exception_sync;
>          break;
>  
>      default:
> @@ -116,7 +131,7 @@ int hvm_monitor_breakpoint(unsigned long rip,
>  
>      req.vcpu_id = curr->vcpu_id;
>  
> -    return vm_event_monitor_traps(curr, 1, &req);
> +    return vm_event_monitor_traps(curr, sync, &req);


What would be a basic use-case for this event to be sent without pausing
the VCPU (i.e. with sync != 1)?


Thanks,
Razvan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 4/5] vm_event: clear up return value of vm_event_monitor_traps
  2016-06-23 17:07 ` [PATCH v6 4/5] vm_event: clear up return value of vm_event_monitor_traps Tamas K Lengyel
@ 2016-06-24 10:59   ` Tian, Kevin
  0 siblings, 0 replies; 14+ messages in thread
From: Tian, Kevin @ 2016-06-24 10:59 UTC (permalink / raw)
  To: Tamas K Lengyel, xen-devel; +Cc: Andrew Cooper, Nakajima, Jun

> From: Tamas K Lengyel [mailto:tamas@tklengyel.com]
> Sent: Friday, June 24, 2016 1:07 AM
> 
> The return value has not been clearly defined, with the function
> never returning 0 which seemingly indicated a condition where the
> guest should crash.
> 
> In this patch we define -rc as error condition where a subscriber is
> present but an error prevented the notification from being sent;
> 0 where there is no subscriber or the notification was sent and the vCPU
> is not paused (i.e. safe to continue execution as normal); and 1 where the
> notification was sent with the vCPU paused and we are waiting for a
> response.
> 
> Signed-off-by: Tamas K Lengyel <tamas@tklengyel.com>
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> Acked-by: Razvan Cojocaru <rcojocaru@bitdefender.com>

Sorry I should ack this new version:

Acked-by: Kevin Tian <kevin.tian@intel.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events
  2016-06-23 17:07 ` [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events Tamas K Lengyel
  2016-06-24  7:14   ` Jan Beulich
  2016-06-24  7:56   ` Razvan Cojocaru
@ 2016-06-24 11:20   ` Tian, Kevin
  2016-06-24 11:24     ` Jan Beulich
  2 siblings, 1 reply; 14+ messages in thread
From: Tian, Kevin @ 2016-06-24 11:20 UTC (permalink / raw)
  To: Tamas K Lengyel, xen-devel
  Cc: Wei Liu, Jan Beulich, Razvan Cojocaru, Andrew Cooper,
	Ian Jackson, Nakajima, Jun

> From: Tamas K Lengyel [mailto:tamas@tklengyel.com]
> Sent: Friday, June 24, 2016 1:07 AM
> 
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index 03fcba7..4b69ca6 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -3373,10 +3373,39 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
>              HVMTRACE_1D(TRAP_DEBUG, exit_qualification);
>              write_debugreg(6, exit_qualification | DR_STATUS_RESERVED_ONE);
>              if ( !v->domain->debugger_attached )
> -                vmx_propagate_intr(intr_info);
> +            {
> +                unsigned long insn_len = 0;
> +                int rc;
> +                unsigned long trap_type = MASK_EXTR(intr_info,
> +                                                    INTR_INFO_INTR_TYPE_MASK);
> +
> +                if ( trap_type >= X86_EVENTTYPE_SW_INTERRUPT )
> +                    __vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len);
> +
> +                rc = hvm_monitor_debug(regs->eip,
> +                                       HVM_MONITOR_DEBUG_EXCEPTION,
> +                                       trap_type, insn_len);
> +
> +                /*
> +                 * !rc  continue normally
> +                 * rc > paused waiting for response, work here is done

Did you mean "rc > 0, vcpu is paused and waiting for response..."? Please
make the comment clear to understand.

> +                 * rc < error, fall-through to exit_and_crash
> +                 */
> +                if ( !rc )
> +                {
> +                    vmx_propagate_intr(intr_info);
> +                    break;
> +                }
> +                if ( rc > 0 )
> +                    break;
> +            }
>              else
> +            {
>                  domain_pause_for_debugger();
> -            break;
> +                break;
> +            }
> +
> +            goto exit_and_crash;

Putting goto as the last line within a 'case' looks a bit strange. What
about putting goto directly under a "if ( rc < 0 )" check earlier?

		if ( !rc )
			...
		if ( rc < 0 )
			goto exit_and_crash;
	}
	else
		domain_pause_for_debugger();
	break;

Thanks
Kevin

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events
  2016-06-24 11:20   ` Tian, Kevin
@ 2016-06-24 11:24     ` Jan Beulich
  2016-06-24 16:29       ` Tamas K Lengyel
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Beulich @ 2016-06-24 11:24 UTC (permalink / raw)
  To: Kevin Tian, Tamas K Lengyel
  Cc: Wei Liu, Razvan Cojocaru, Andrew Cooper, Ian Jackson,
	Jun Nakajima, xen-devel

>>> On 24.06.16 at 13:20, <kevin.tian@intel.com> wrote:
>>  From: Tamas K Lengyel [mailto:tamas@tklengyel.com]
>> Sent: Friday, June 24, 2016 1:07 AM
>> 
>> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
>> index 03fcba7..4b69ca6 100644
>> --- a/xen/arch/x86/hvm/vmx/vmx.c
>> +++ b/xen/arch/x86/hvm/vmx/vmx.c
>> @@ -3373,10 +3373,39 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
>>              HVMTRACE_1D(TRAP_DEBUG, exit_qualification);
>>              write_debugreg(6, exit_qualification | DR_STATUS_RESERVED_ONE);
>>              if ( !v->domain->debugger_attached )
>> -                vmx_propagate_intr(intr_info);
>> +            {
>> +                unsigned long insn_len = 0;
>> +                int rc;
>> +                unsigned long trap_type = MASK_EXTR(intr_info,
>> +                                                    INTR_INFO_INTR_TYPE_MASK);
>> +
>> +                if ( trap_type >= X86_EVENTTYPE_SW_INTERRUPT )
>> +                    __vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len);
>> +
>> +                rc = hvm_monitor_debug(regs->eip,
>> +                                       HVM_MONITOR_DEBUG_EXCEPTION,
>> +                                       trap_type, insn_len);
>> +
>> +                /*
>> +                 * !rc  continue normally
>> +                 * rc > paused waiting for response, work here is done
> 
> Did you mean "rc > 0, vcpu is paused and waiting for response..."? Please
> make the comment clear to understand.
> 
>> +                 * rc < error, fall-through to exit_and_crash
>> +                 */
>> +                if ( !rc )
>> +                {
>> +                    vmx_propagate_intr(intr_info);
>> +                    break;
>> +                }
>> +                if ( rc > 0 )
>> +                    break;
>> +            }
>>              else
>> +            {
>>                  domain_pause_for_debugger();
>> -            break;
>> +                break;
>> +            }
>> +
>> +            goto exit_and_crash;
> 
> Putting goto as the last line within a 'case' looks a bit strange. What
> about putting goto directly under a "if ( rc < 0 )" check earlier?
> 
> 		if ( !rc )
> 			...
> 		if ( rc < 0 )
> 			goto exit_and_crash;
> 	}
> 	else
> 		domain_pause_for_debugger();
> 	break;

Thanks, Kevin - indeed that's exactly what I had asked for already
on the previous iteration.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events
  2016-06-24 11:24     ` Jan Beulich
@ 2016-06-24 16:29       ` Tamas K Lengyel
  2016-06-27  7:08         ` Jan Beulich
  0 siblings, 1 reply; 14+ messages in thread
From: Tamas K Lengyel @ 2016-06-24 16:29 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Kevin Tian, Wei Liu, Razvan Cojocaru, Andrew Cooper, Ian Jackson,
	Jun Nakajima, xen-devel

On Fri, Jun 24, 2016 at 5:24 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 24.06.16 at 13:20, <kevin.tian@intel.com> wrote:
>>>  From: Tamas K Lengyel [mailto:tamas@tklengyel.com]
>>> Sent: Friday, June 24, 2016 1:07 AM
>>>
>>> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
>>> index 03fcba7..4b69ca6 100644
>>> --- a/xen/arch/x86/hvm/vmx/vmx.c
>>> +++ b/xen/arch/x86/hvm/vmx/vmx.c
>>> @@ -3373,10 +3373,39 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
>>>              HVMTRACE_1D(TRAP_DEBUG, exit_qualification);
>>>              write_debugreg(6, exit_qualification | DR_STATUS_RESERVED_ONE);
>>>              if ( !v->domain->debugger_attached )
>>> -                vmx_propagate_intr(intr_info);
>>> +            {
>>> +                unsigned long insn_len = 0;
>>> +                int rc;
>>> +                unsigned long trap_type = MASK_EXTR(intr_info,
>>> +                                                    INTR_INFO_INTR_TYPE_MASK);
>>> +
>>> +                if ( trap_type >= X86_EVENTTYPE_SW_INTERRUPT )
>>> +                    __vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len);
>>> +
>>> +                rc = hvm_monitor_debug(regs->eip,
>>> +                                       HVM_MONITOR_DEBUG_EXCEPTION,
>>> +                                       trap_type, insn_len);
>>> +
>>> +                /*
>>> +                 * !rc  continue normally
>>> +                 * rc > paused waiting for response, work here is done
>>
>> Did you mean "rc > 0, vcpu is paused and waiting for response..."? Please
>> make the comment clear to understand.

Yes, sure.

>>
>>> +                 * rc < error, fall-through to exit_and_crash
>>> +                 */
>>> +                if ( !rc )
>>> +                {
>>> +                    vmx_propagate_intr(intr_info);
>>> +                    break;
>>> +                }
>>> +                if ( rc > 0 )
>>> +                    break;
>>> +            }
>>>              else
>>> +            {
>>>                  domain_pause_for_debugger();
>>> -            break;
>>> +                break;
>>> +            }
>>> +
>>> +            goto exit_and_crash;
>>
>> Putting goto as the last line within a 'case' looks a bit strange. What
>> about putting goto directly under a "if ( rc < 0 )" check earlier?
>>
>>               if ( !rc )
>>                       ...
>>               if ( rc < 0 )
>>                       goto exit_and_crash;
>>       }
>>       else
>>               domain_pause_for_debugger();
>>       break;
>
> Thanks, Kevin - indeed that's exactly what I had asked for already
> on the previous iteration.
>

I'm OK with adding the rc < 0 case, it's just that the fall-through
style is already used for handling the int3 events for example. Should
I fix that too while I'm at it so the code is consistent?

Tamas

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events
  2016-06-24  7:56   ` Razvan Cojocaru
@ 2016-06-24 18:48     ` Tamas K Lengyel
  2016-06-24 19:49       ` Razvan Cojocaru
  0 siblings, 1 reply; 14+ messages in thread
From: Tamas K Lengyel @ 2016-06-24 18:48 UTC (permalink / raw)
  To: Razvan Cojocaru
  Cc: Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper, Ian Jackson,
	Jun Nakajima, Xen-devel

>>              {
>> @@ -635,22 +661,22 @@ int main(int argc, char *argv[])
>>                  rsp.u.mem_access = req.u.mem_access;
>>                  break;
>>              case VM_EVENT_REASON_SOFTWARE_BREAKPOINT:
>> -                printf("Breakpoint: rip=%016"PRIx64", gfn=%"PRIx64" (vcpu %d)\n",
>> +                printf("Breakpoint: rip=%016"PRIx64" gfn=%"PRIx64" (vcpu %d)\n",
>
> You seem to have removed the comma here (',') after the first "PRIx64",
> but ...
>
>>                         req.data.regs.x86.rip,
>>                         req.u.software_breakpoint.gfn,
>>                         req.vcpu_id);
>>
>>                  /* Reinject */
>> -                rc = xc_hvm_inject_trap(
>> -                    xch, domain_id, req.vcpu_id, 3,
>> -                    HVMOP_TRAP_sw_exc, -1, 0, 0);
>> +                rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id,
>> +                                        X86_TRAP_INT3,
>> +                                        req.u.software_breakpoint.type, -1,
>> +                                        req.u.software_breakpoint.insn_length, 0);
>>                  if (rc < 0)
>>                  {
>>                      ERROR("Error %d injecting breakpoint\n", rc);
>>                      interrupted = -1;
>>                      continue;
>>                  }
>> -
>>                  break;
>>              case VM_EVENT_REASON_SINGLESTEP:
>>                  printf("Singlestep: rip=%016"PRIx64", vcpu %d, altp2m %u\n",
>> @@ -669,6 +695,27 @@ int main(int argc, char *argv[])
>>                  rsp.flags |= VM_EVENT_FLAG_TOGGLE_SINGLESTEP;
>>
>>                  break;
>> +            case VM_EVENT_REASON_DEBUG_EXCEPTION:
>> +                printf("Debug exception: rip=%016"PRIx64", vcpu %d. Type: %u. Length: %u\n",
>
> ... this newly added line uses the old style (with a comma after the
> first "PRIx64"). Minor issue maybe, I just don't understand why the
> first modification was made.

Yea, for no reason. Will add the comma back above.

>
>> +                       req.data.regs.x86.rip,
>> +                       req.vcpu_id,
>> +                       req.u.debug_exception.type,
>> +                       req.u.debug_exception.insn_length);
>> +
>> +                /* Reinject */
>> +                rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id,
>> +                                        X86_TRAP_DEBUG,
>> +                                        req.u.debug_exception.type, -1,
>> +                                        req.u.debug_exception.insn_length,
>> +                                        req.data.regs.x86.cr2);
>> +                if (rc < 0)
>> +                {
>> +                    ERROR("Error %d injecting breakpoint\n", rc);
>> +                    interrupted = -1;
>> +                    continue;
>> +                }
>> +
>> +                break;
>>              default:
>>                  fprintf(stderr, "UNKNOWN REASON CODE %d\n", req.reason);
>>              }
>> diff --git a/xen/arch/x86/hvm/monitor.c b/xen/arch/x86/hvm/monitor.c
>> index 472926c..bbe5952 100644
>> --- a/xen/arch/x86/hvm/monitor.c
>> +++ b/xen/arch/x86/hvm/monitor.c
>> @@ -87,12 +87,13 @@ static inline unsigned long gfn_of_rip(unsigned long rip)
>>      return paging_gva_to_gfn(curr, sreg.base + rip, &pfec);
>>  }
>>
>> -int hvm_monitor_breakpoint(unsigned long rip,
>> -                           enum hvm_monitor_breakpoint_type type)
>> +int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type,
>> +                      unsigned long trap_type, unsigned long insn_length)
>>  {
>>      struct vcpu *curr = current;
>>      struct arch_domain *ad = &curr->domain->arch;
>>      vm_event_request_t req = {};
>> +    bool_t sync;
>>
>>      switch ( type )
>>      {
>> @@ -101,6 +102,9 @@ int hvm_monitor_breakpoint(unsigned long rip,
>>              return 0;
>>          req.reason = VM_EVENT_REASON_SOFTWARE_BREAKPOINT;
>>          req.u.software_breakpoint.gfn = gfn_of_rip(rip);
>> +        req.u.software_breakpoint.type = trap_type;
>> +        req.u.software_breakpoint.insn_length = insn_length;
>> +        sync = 1;
>>          break;
>>
>>      case HVM_MONITOR_SINGLESTEP_BREAKPOINT:
>> @@ -108,6 +112,17 @@ int hvm_monitor_breakpoint(unsigned long rip,
>>              return 0;
>>          req.reason = VM_EVENT_REASON_SINGLESTEP;
>>          req.u.singlestep.gfn = gfn_of_rip(rip);
>> +        sync = 1;
>> +        break;
>> +
>> +    case HVM_MONITOR_DEBUG_EXCEPTION:
>> +        if ( !ad->monitor.debug_exception_enabled )
>> +            return 0;
>> +        req.reason = VM_EVENT_REASON_DEBUG_EXCEPTION;
>> +        req.u.debug_exception.gfn = gfn_of_rip(rip);
>> +        req.u.debug_exception.type = trap_type;
>> +        req.u.debug_exception.insn_length = insn_length;
>> +        sync = !!ad->monitor.debug_exception_sync;
>>          break;
>>
>>      default:
>> @@ -116,7 +131,7 @@ int hvm_monitor_breakpoint(unsigned long rip,
>>
>>      req.vcpu_id = curr->vcpu_id;
>>
>> -    return vm_event_monitor_traps(curr, 1, &req);
>> +    return vm_event_monitor_traps(curr, sync, &req);
>
>
> What would be a basic use-case for this event to be sent without pausing
> the VCPU (i.e. with sync != 1)?

If you wish to passively monitor the occurrences of debug events in
the guest you can use the !sync option. That will make Xen
automatically reinject the event as it would normally but will send
you a notification. I don't have a particular use for this but since
Xen already had all the necessary wiring ready for it so we might as
well make it available as an option, similar to the other !sync
events.

Tamas

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events
  2016-06-24 18:48     ` Tamas K Lengyel
@ 2016-06-24 19:49       ` Razvan Cojocaru
  0 siblings, 0 replies; 14+ messages in thread
From: Razvan Cojocaru @ 2016-06-24 19:49 UTC (permalink / raw)
  To: Tamas K Lengyel
  Cc: Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper, Ian Jackson,
	Jun Nakajima, Xen-devel

On 06/24/16 21:48, Tamas K Lengyel wrote:
>>>              {
>>> @@ -635,22 +661,22 @@ int main(int argc, char *argv[])
>>>                  rsp.u.mem_access = req.u.mem_access;
>>>                  break;
>>>              case VM_EVENT_REASON_SOFTWARE_BREAKPOINT:
>>> -                printf("Breakpoint: rip=%016"PRIx64", gfn=%"PRIx64" (vcpu %d)\n",
>>> +                printf("Breakpoint: rip=%016"PRIx64" gfn=%"PRIx64" (vcpu %d)\n",
>>
>> You seem to have removed the comma here (',') after the first "PRIx64",
>> but ...
>>
>>>                         req.data.regs.x86.rip,
>>>                         req.u.software_breakpoint.gfn,
>>>                         req.vcpu_id);
>>>
>>>                  /* Reinject */
>>> -                rc = xc_hvm_inject_trap(
>>> -                    xch, domain_id, req.vcpu_id, 3,
>>> -                    HVMOP_TRAP_sw_exc, -1, 0, 0);
>>> +                rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id,
>>> +                                        X86_TRAP_INT3,
>>> +                                        req.u.software_breakpoint.type, -1,
>>> +                                        req.u.software_breakpoint.insn_length, 0);
>>>                  if (rc < 0)
>>>                  {
>>>                      ERROR("Error %d injecting breakpoint\n", rc);
>>>                      interrupted = -1;
>>>                      continue;
>>>                  }
>>> -
>>>                  break;
>>>              case VM_EVENT_REASON_SINGLESTEP:
>>>                  printf("Singlestep: rip=%016"PRIx64", vcpu %d, altp2m %u\n",
>>> @@ -669,6 +695,27 @@ int main(int argc, char *argv[])
>>>                  rsp.flags |= VM_EVENT_FLAG_TOGGLE_SINGLESTEP;
>>>
>>>                  break;
>>> +            case VM_EVENT_REASON_DEBUG_EXCEPTION:
>>> +                printf("Debug exception: rip=%016"PRIx64", vcpu %d. Type: %u. Length: %u\n",
>>
>> ... this newly added line uses the old style (with a comma after the
>> first "PRIx64"). Minor issue maybe, I just don't understand why the
>> first modification was made.
> 
> Yea, for no reason. Will add the comma back above.
> 
>>
>>> +                       req.data.regs.x86.rip,
>>> +                       req.vcpu_id,
>>> +                       req.u.debug_exception.type,
>>> +                       req.u.debug_exception.insn_length);
>>> +
>>> +                /* Reinject */
>>> +                rc = xc_hvm_inject_trap(xch, domain_id, req.vcpu_id,
>>> +                                        X86_TRAP_DEBUG,
>>> +                                        req.u.debug_exception.type, -1,
>>> +                                        req.u.debug_exception.insn_length,
>>> +                                        req.data.regs.x86.cr2);
>>> +                if (rc < 0)
>>> +                {
>>> +                    ERROR("Error %d injecting breakpoint\n", rc);
>>> +                    interrupted = -1;
>>> +                    continue;
>>> +                }
>>> +
>>> +                break;
>>>              default:
>>>                  fprintf(stderr, "UNKNOWN REASON CODE %d\n", req.reason);
>>>              }
>>> diff --git a/xen/arch/x86/hvm/monitor.c b/xen/arch/x86/hvm/monitor.c
>>> index 472926c..bbe5952 100644
>>> --- a/xen/arch/x86/hvm/monitor.c
>>> +++ b/xen/arch/x86/hvm/monitor.c
>>> @@ -87,12 +87,13 @@ static inline unsigned long gfn_of_rip(unsigned long rip)
>>>      return paging_gva_to_gfn(curr, sreg.base + rip, &pfec);
>>>  }
>>>
>>> -int hvm_monitor_breakpoint(unsigned long rip,
>>> -                           enum hvm_monitor_breakpoint_type type)
>>> +int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type,
>>> +                      unsigned long trap_type, unsigned long insn_length)
>>>  {
>>>      struct vcpu *curr = current;
>>>      struct arch_domain *ad = &curr->domain->arch;
>>>      vm_event_request_t req = {};
>>> +    bool_t sync;
>>>
>>>      switch ( type )
>>>      {
>>> @@ -101,6 +102,9 @@ int hvm_monitor_breakpoint(unsigned long rip,
>>>              return 0;
>>>          req.reason = VM_EVENT_REASON_SOFTWARE_BREAKPOINT;
>>>          req.u.software_breakpoint.gfn = gfn_of_rip(rip);
>>> +        req.u.software_breakpoint.type = trap_type;
>>> +        req.u.software_breakpoint.insn_length = insn_length;
>>> +        sync = 1;
>>>          break;
>>>
>>>      case HVM_MONITOR_SINGLESTEP_BREAKPOINT:
>>> @@ -108,6 +112,17 @@ int hvm_monitor_breakpoint(unsigned long rip,
>>>              return 0;
>>>          req.reason = VM_EVENT_REASON_SINGLESTEP;
>>>          req.u.singlestep.gfn = gfn_of_rip(rip);
>>> +        sync = 1;
>>> +        break;
>>> +
>>> +    case HVM_MONITOR_DEBUG_EXCEPTION:
>>> +        if ( !ad->monitor.debug_exception_enabled )
>>> +            return 0;
>>> +        req.reason = VM_EVENT_REASON_DEBUG_EXCEPTION;
>>> +        req.u.debug_exception.gfn = gfn_of_rip(rip);
>>> +        req.u.debug_exception.type = trap_type;
>>> +        req.u.debug_exception.insn_length = insn_length;
>>> +        sync = !!ad->monitor.debug_exception_sync;
>>>          break;
>>>
>>>      default:
>>> @@ -116,7 +131,7 @@ int hvm_monitor_breakpoint(unsigned long rip,
>>>
>>>      req.vcpu_id = curr->vcpu_id;
>>>
>>> -    return vm_event_monitor_traps(curr, 1, &req);
>>> +    return vm_event_monitor_traps(curr, sync, &req);
>>
>>
>> What would be a basic use-case for this event to be sent without pausing
>> the VCPU (i.e. with sync != 1)?
> 
> If you wish to passively monitor the occurrences of debug events in
> the guest you can use the !sync option. That will make Xen
> automatically reinject the event as it would normally but will send
> you a notification. I don't have a particular use for this but since
> Xen already had all the necessary wiring ready for it so we might as
> well make it available as an option, similar to the other !sync
> events.

Fair enough, thanks for the explanation.


Thanks,
Razvan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events
  2016-06-24 16:29       ` Tamas K Lengyel
@ 2016-06-27  7:08         ` Jan Beulich
  0 siblings, 0 replies; 14+ messages in thread
From: Jan Beulich @ 2016-06-27  7:08 UTC (permalink / raw)
  To: Tamas K Lengyel
  Cc: Kevin Tian, Wei Liu, Razvan Cojocaru, Andrew Cooper, Ian Jackson,
	Jun Nakajima, xen-devel

>>> On 24.06.16 at 18:29, <tamas@tklengyel.com> wrote:
> On Fri, Jun 24, 2016 at 5:24 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>> On 24.06.16 at 13:20, <kevin.tian@intel.com> wrote:
>>>>  From: Tamas K Lengyel [mailto:tamas@tklengyel.com]
>>>> +                 * rc < error, fall-through to exit_and_crash
>>>> +                 */
>>>> +                if ( !rc )
>>>> +                {
>>>> +                    vmx_propagate_intr(intr_info);
>>>> +                    break;
>>>> +                }
>>>> +                if ( rc > 0 )
>>>> +                    break;
>>>> +            }
>>>>              else
>>>> +            {
>>>>                  domain_pause_for_debugger();
>>>> -            break;
>>>> +                break;
>>>> +            }
>>>> +
>>>> +            goto exit_and_crash;
>>>
>>> Putting goto as the last line within a 'case' looks a bit strange. What
>>> about putting goto directly under a "if ( rc < 0 )" check earlier?
>>>
>>>               if ( !rc )
>>>                       ...
>>>               if ( rc < 0 )
>>>                       goto exit_and_crash;
>>>       }
>>>       else
>>>               domain_pause_for_debugger();
>>>       break;
>>
>> Thanks, Kevin - indeed that's exactly what I had asked for already
>> on the previous iteration.
>>
> 
> I'm OK with adding the rc < 0 case, it's just that the fall-through
> style is already used for handling the int3 events for example. Should
> I fix that too while I'm at it so the code is consistent?

Especially if you did it in a separate patch, I for one would
appreciate that.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-06-27  7:08 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-23 17:07 [PATCH v6 1/5] monitor: Rename vm_event_monitor_get_capabilities Tamas K Lengyel
2016-06-23 17:07 ` [PATCH v6 2/5] monitor: Rename vm_event_monitor_guest_request Tamas K Lengyel
2016-06-23 17:07 ` [PATCH v6 3/5] monitor: Rename hvm/event to hvm/monitor Tamas K Lengyel
2016-06-23 17:07 ` [PATCH v6 4/5] vm_event: clear up return value of vm_event_monitor_traps Tamas K Lengyel
2016-06-24 10:59   ` Tian, Kevin
2016-06-23 17:07 ` [PATCH v6 5/5] x86/vm_event: Add HVM debug exception vm_events Tamas K Lengyel
2016-06-24  7:14   ` Jan Beulich
2016-06-24  7:56   ` Razvan Cojocaru
2016-06-24 18:48     ` Tamas K Lengyel
2016-06-24 19:49       ` Razvan Cojocaru
2016-06-24 11:20   ` Tian, Kevin
2016-06-24 11:24     ` Jan Beulich
2016-06-24 16:29       ` Tamas K Lengyel
2016-06-27  7:08         ` Jan Beulich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).