mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
x86/hvm: allow guest_request vm_events coming from userspace
In some introspection usecases, an in-guest agent needs to communicate with the external introspection agent. An existing mechanism is HVMOP_guest_request_vm_event, but this is restricted to kernel usecases like all other hypercalls. Introduce a mechanism whereby the introspection agent can whitelist the use of HVMOP_guest_request_vm_event directly from userspace. Signed-off-by: Alexandru Isaila <aisaila@bitdefender.com> Acked-by: Wei Liu <wei.liu2@citrix.com> Acked-by: Jan Beulich <jbeulich@suse.com> Acked-by: Tamas K Lengyel <tamas@tklengyel.com>
This commit is contained in:
1 parent
69d99d1b22
commit
7c4dc5dbdf
8 files changed
+31
-11
No files matched your search
@@ -2022,7 +2022,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;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
#include <xen/sched.h>
|
||||
#include <public/domctl.h>
|
||||
|
||||
static inline
|
||||
void arch_monitor_allow_userspace(struct domain *d, bool allow_userspace)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
int arch_monitor_domctl_op(struct domain *d, struct xen_domctl_monitor_op *mop)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -32,6 +32,12 @@ struct monitor_msr_bitmap {
|
||||
DECLARE_BITMAP(high, 8192);
|
||||
};
|
||||
|
||||
static inline
|
||||
void arch_monitor_allow_userspace(struct domain *d, bool 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)
|
||||
{
|
||||
|
||||
@@ -1128,6 +1128,7 @@ struct xen_domctl_monitor_op {
|
||||
struct {
|
||||
/* Pause vCPU until response */
|
||||
uint8_t sync;
|
||||
uint8_t allow_userspace;
|
||||
} guest_request;
|
||||
|
||||
struct {
|
||||
|
||||