|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 3/5] xen/vm_event: Support for guest-requested events
Added support for a new class of vm_events: VM_EVENT_REASON_REQUEST,
sent via HVMOP_request_vm_event. The guest can request that a
generic vm_event (containing only the vm_event-filled guest registers
as information) be sent to userspace by setting up the correct
registers and doing a VMCALL. For example, for a 64-bit guest, this
means: EAX = 34 (hvmop), EBX = 24 (HVMOP_request_vm_event).
Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx>
---
tools/libxc/include/xenctrl.h | 2 ++
tools/libxc/xc_monitor.c | 15 +++++++++++++++
xen/arch/x86/hvm/event.c | 14 ++++++++++++++
xen/arch/x86/hvm/hvm.c | 4 ++++
xen/arch/x86/monitor.c | 16 ++++++++++++++++
xen/include/asm-x86/domain.h | 32 +++++++++++++++++---------------
xen/include/asm-x86/hvm/event.h | 1 +
xen/include/public/domctl.h | 6 ++++++
xen/include/public/hvm/hvm_op.h | 4 ++++
xen/include/public/vm_event.h | 2 ++
10 files changed, 81 insertions(+), 15 deletions(-)
diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 1aa4f87..17a0bc8 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2339,6 +2339,8 @@ int xc_monitor_software_breakpoint(xc_interface *xch,
domid_t domain_id,
bool enable);
int xc_monitor_xsetbv(xc_interface *xch, domid_t domain_id, bool enable,
bool sync);
+int xc_monitor_requested(xc_interface *xch, domid_t domain_id, bool enable,
+ bool sync);
/***
* Memory sharing operations.
diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c
index aec2f4a..5d8f4f8 100644
--- a/tools/libxc/xc_monitor.c
+++ b/tools/libxc/xc_monitor.c
@@ -150,3 +150,18 @@ int xc_monitor_xsetbv(xc_interface *xch, domid_t
domain_id, bool enable,
return do_domctl(xch, &domctl);
}
+
+int xc_monitor_requested(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_REQUEST;
+ domctl.u.monitor_op.u.request.sync = sync;
+
+ return do_domctl(xch, &domctl);
+}
diff --git a/xen/arch/x86/hvm/event.c b/xen/arch/x86/hvm/event.c
index 5b869c8..b72ccbf 100644
--- a/xen/arch/x86/hvm/event.c
+++ b/xen/arch/x86/hvm/event.c
@@ -167,6 +167,20 @@ void hvm_event_xsetbv(unsigned long xcr, uint64_t value)
hvm_event_traps(currad->monitor.xsetbv_sync, &req);
}
+void hvm_event_requested(void)
+{
+ struct vcpu *curr = current;
+ struct arch_domain *currad = ¤t->domain->arch;
+
+ vm_event_request_t req = {
+ .reason = VM_EVENT_REASON_REQUEST,
+ .vcpu_id = curr->vcpu_id,
+ };
+
+ if ( currad->monitor.request_enabled )
+ hvm_event_traps(currad->monitor.request_sync, &req);
+}
+
int hvm_event_int3(unsigned long gla)
{
int rc = 0;
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 86f9885..8ad03c6 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -6267,6 +6267,10 @@ long do_hvm_op(unsigned long op,
XEN_GUEST_HANDLE_PARAM(void) arg)
break;
}
+ case HVMOP_request_vm_event:
+ hvm_event_requested();
+ break;
+
default:
{
gdprintk(XENLOG_DEBUG, "Bad HVM op %ld.\n", op);
diff --git a/xen/arch/x86/monitor.c b/xen/arch/x86/monitor.c
index 6823a84..5176149 100644
--- a/xen/arch/x86/monitor.c
+++ b/xen/arch/x86/monitor.c
@@ -194,6 +194,22 @@ int monitor_domctl(struct domain *d, struct
xen_domctl_monitor_op *mop)
break;
}
+ case XEN_DOMCTL_MONITOR_EVENT_REQUEST:
+ {
+ bool_t status = ad->monitor.request_enabled;
+
+ rc = status_check(mop, status);
+ if ( rc )
+ return rc;
+
+ ad->monitor.request_sync = mop->u.request.sync;
+
+ domain_pause(d);
+ ad->monitor.request_enabled = !status;
+ domain_unpause(d);
+ break;
+ }
+
default:
return -EOPNOTSUPP;
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 2b89182..682ccc5 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -342,21 +342,23 @@ struct arch_domain
/* Monitor options */
struct {
- uint16_t mov_to_cr0_enabled : 1;
- uint16_t mov_to_cr0_sync : 1;
- uint16_t mov_to_cr0_onchangeonly : 1;
- uint16_t mov_to_cr3_enabled : 1;
- uint16_t mov_to_cr3_sync : 1;
- uint16_t mov_to_cr3_onchangeonly : 1;
- uint16_t mov_to_cr4_enabled : 1;
- uint16_t mov_to_cr4_sync : 1;
- uint16_t mov_to_cr4_onchangeonly : 1;
- uint16_t mov_to_msr_enabled : 1;
- uint16_t mov_to_msr_extended : 1;
- uint16_t singlestep_enabled : 1;
- uint16_t software_breakpoint_enabled : 1;
- uint16_t xsetbv_enabled : 1;
- uint16_t xsetbv_sync : 1;
+ uint32_t mov_to_cr0_enabled : 1;
+ uint32_t mov_to_cr0_sync : 1;
+ uint32_t mov_to_cr0_onchangeonly : 1;
+ uint32_t mov_to_cr3_enabled : 1;
+ uint32_t mov_to_cr3_sync : 1;
+ uint32_t mov_to_cr3_onchangeonly : 1;
+ uint32_t mov_to_cr4_enabled : 1;
+ uint32_t mov_to_cr4_sync : 1;
+ uint32_t mov_to_cr4_onchangeonly : 1;
+ uint32_t mov_to_msr_enabled : 1;
+ uint32_t mov_to_msr_extended : 1;
+ uint32_t singlestep_enabled : 1;
+ uint32_t software_breakpoint_enabled : 1;
+ uint32_t xsetbv_enabled : 1;
+ uint32_t xsetbv_sync : 1;
+ uint32_t request_enabled : 1;
+ uint32_t request_sync : 1;
} monitor;
/* Mem_access emulation control */
diff --git a/xen/include/asm-x86/hvm/event.h b/xen/include/asm-x86/hvm/event.h
index b2cf3bc..ca63055 100644
--- a/xen/include/asm-x86/hvm/event.h
+++ b/xen/include/asm-x86/hvm/event.h
@@ -24,6 +24,7 @@ void hvm_event_cr3(unsigned long value, unsigned long old);
void hvm_event_cr4(unsigned long value, unsigned long old);
void hvm_event_msr(unsigned int msr, uint64_t value);
void hvm_event_xsetbv(unsigned long xcr, uint64_t value);
+void hvm_event_requested(void);
/* Called for current VCPU: returns -1 if no listener */
int hvm_event_int3(unsigned long gla);
int hvm_event_single_step(unsigned long gla);
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index b866e33..a627360 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -1019,6 +1019,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_psr_cmt_op_t);
#define XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP 4
#define XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT 5
#define XEN_DOMCTL_MONITOR_EVENT_XSETBV 6
+#define XEN_DOMCTL_MONITOR_EVENT_REQUEST 7
struct xen_domctl_monitor_op {
uint32_t op; /* XEN_DOMCTL_MONITOR_OP_* */
@@ -1044,6 +1045,11 @@ struct xen_domctl_monitor_op {
/* Pause vCPU until response */
uint8_t sync;
} xsetbv;
+
+ struct {
+ /* Pause vCPU until response */
+ uint8_t sync;
+ } request;
} u;
};
typedef struct xen_domctl__op xen_domctl_monitor_op_t;
diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h
index cde3571..cb5168a 100644
--- a/xen/include/public/hvm/hvm_op.h
+++ b/xen/include/public/hvm/hvm_op.h
@@ -389,6 +389,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_evtchn_upcall_vector_t);
#endif /* defined(__i386__) || defined(__x86_64__) */
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
+#define HVMOP_request_vm_event 24
+#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
+
#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
/*
diff --git a/xen/include/public/vm_event.h b/xen/include/public/vm_event.h
index bce3e3e..2913a85 100644
--- a/xen/include/public/vm_event.h
+++ b/xen/include/public/vm_event.h
@@ -74,6 +74,8 @@
#define VM_EVENT_REASON_SINGLESTEP 9
/* An XCR was updated. */
#define VM_EVENT_REASON_XSETBV 10
+/* An event has been requested via HVMOP_request_vm_event. */
+#define VM_EVENT_REASON_REQUEST 11
/*
* Using a custom struct (not hvm_hw_cpu) so as to not fill
--
1.7.9.5
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |