@@ -2021,7 +2021,7 @@ int xc_monitor_software_breakpoint(xc_interface *xch, domid_t domain_id,
int xc_monitor_descriptor_access(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);
+ bool enable, bool sync, bool allow_userspace);
int xc_monitor_debug_exceptions(xc_interface *xch, domid_t domain_id,
bool enable, bool sync);
int xc_monitor_cpuid(xc_interface *xch, domid_t domain_id, bool enable);
@@ -147,7 +147,7 @@ int xc_monitor_descriptor_access(xc_interface *xch, domid_t domain_id,
}
int xc_monitor_guest_request(xc_interface *xch, domid_t domain_id, bool enable,
- bool sync)
+ bool sync, bool allow_userspace)
{
DECLARE_DOMCTL;
@@ -157,6 +157,7 @@ int xc_monitor_guest_request(xc_interface *xch, domid_t domain_id, bool enable,
: XEN_DOMCTL_MONITOR_OP_DISABLE;
domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST;
domctl.u.monitor_op.u.guest_request.sync = sync;
+ domctl.u.monitor_op.u.guest_request.allow_userspace = enable ? allow_userspace : false;
return do_domctl(xch, &domctl);
}
@@ -155,6 +155,11 @@ int hvm_hypercall(struct cpu_user_regs *regs)
/* Fallthrough to permission check. */
case 4:
case 2:
+ if ( currd->arch.monitor.guest_request_userspace_enabled &&
+ eax == __HYPERVISOR_hvm_op &&
+ (mode == 8 ? regs->rdi : regs->ebx) == HVMOP_guest_request_vm_event )
+ break;
+
if ( unlikely(hvm_get_cpl(curr)) )
{
default:
@@ -75,6 +75,7 @@ int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop)
domain_pause(d);
d->monitor.guest_request_sync = mop->u.guest_request.sync;
d->monitor.guest_request_enabled = requested_status;
+ arch_monitor_allow_userspace(d, mop->u.guest_request.allow_userspace);
domain_unpause(d);
break;
}
@@ -26,6 +26,12 @@
#include <public/domctl.h>
static inline
+void arch_monitor_allow_userspace(struct domain *d, uint8_t allow_userspace)
+{
+ return;
+}
+
+static inline
int arch_monitor_domctl_op(struct domain *d, struct xen_domctl_monitor_op *mop)
{
/* No arch-specific monitor ops on ARM. */
@@ -396,15 +396,16 @@ struct arch_domain
/* Arch-specific monitor options */
struct {
- unsigned int write_ctrlreg_enabled : 4;
- unsigned int write_ctrlreg_sync : 4;
- 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;
- unsigned int cpuid_enabled : 1;
- unsigned int descriptor_access_enabled : 1;
+ unsigned int write_ctrlreg_enabled : 4;
+ unsigned int write_ctrlreg_sync : 4;
+ 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;
+ unsigned int cpuid_enabled : 1;
+ unsigned int descriptor_access_enabled : 1;
+ unsigned int guest_request_userspace_enabled : 1;
struct monitor_msr_bitmap *msr_bitmap;
uint64_t write_ctrlreg_mask[4];
} monitor;
@@ -33,6 +33,12 @@ struct monitor_msr_bitmap {
};
static inline
+void arch_monitor_allow_userspace(struct domain *d, uint8_t allow_userspace)
+{
+ d->arch.monitor.guest_request_userspace_enabled = allow_userspace;
+}
+
+static inline
int arch_monitor_domctl_op(struct domain *d, struct xen_domctl_monitor_op *mop)
{
int rc = 0;
@@ -1124,6 +1124,7 @@ struct xen_domctl_monitor_op {
struct {
/* Pause vCPU until response */
uint8_t sync;
+ uint8_t allow_userspace;
} guest_request;
struct {