[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/2 for-4.12] xen: introduce VCPUOP_register_runstate_phys_memory_area hypercall
From: Andrii Anisov <andrii_anisov@xxxxxxxx> The hypercall employs the same vcpu_register_runstate_memory_area structure for the interface, but requires registered area to not cross a page boundary. Signed-off-by: Andrii Anisov <andrii_anisov@xxxxxxxx> --- xen/arch/arm/domain.c | 39 ++++++++++++++++++--------------- xen/arch/x86/domain.c | 55 ++++++++++++++++++++++++++--------------------- xen/common/domain.c | 7 ++++++ xen/include/public/vcpu.h | 16 ++++++++++++++ xen/include/xen/sched.h | 7 ++++++ 5 files changed, 83 insertions(+), 41 deletions(-) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 6dc633e..ec9bdbd 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -277,29 +277,33 @@ static void ctxt_switch_to(struct vcpu *n) /* Update per-VCPU guest runstate shared memory area (if registered). */ static void update_runstate_area(struct vcpu *v) { - void __user *guest_handle = NULL; - if ( guest_handle_is_null(runstate_guest(v)) ) return; - if ( VM_ASSIST(v->domain, runstate_update_flag) ) + if ( v->runstate_guest_type == RUNSTATE_VADDR ) { - guest_handle = &v->runstate_guest.p->state_entry_time + 1; - guest_handle--; - v->runstate.state_entry_time |= XEN_RUNSTATE_UPDATE; - __raw_copy_to_guest(guest_handle, - (void *)(&v->runstate.state_entry_time + 1) - 1, 1); - smp_wmb(); - } + void __user *guest_handle = NULL; + if ( VM_ASSIST(v->domain, runstate_update_flag) ) + { + guest_handle = &v->runstate_guest.p->state_entry_time + 1; + guest_handle--; + v->runstate.state_entry_time |= XEN_RUNSTATE_UPDATE; + __raw_copy_to_guest(guest_handle, + (void *)(&v->runstate.state_entry_time + 1) - 1, + 1); + smp_wmb(); + } - __copy_to_guest(runstate_guest(v), &v->runstate, 1); + __copy_to_guest(runstate_guest(v), &v->runstate, 1); - if ( guest_handle ) - { - v->runstate.state_entry_time &= ~XEN_RUNSTATE_UPDATE; - smp_wmb(); - __raw_copy_to_guest(guest_handle, - (void *)(&v->runstate.state_entry_time + 1) - 1, 1); + if ( guest_handle ) + { + v->runstate.state_entry_time &= ~XEN_RUNSTATE_UPDATE; + smp_wmb(); + __raw_copy_to_guest(guest_handle, + (void *)(&v->runstate.state_entry_time + 1) - 1, + 1); + } } } @@ -998,6 +1002,7 @@ long do_arm_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) a { case VCPUOP_register_vcpu_info: case VCPUOP_register_runstate_memory_area: + case VCPUOP_register_runstate_phys_memory_area: return do_vcpu_op(cmd, vcpuid, arg); default: return -EINVAL; diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index b5febd6..2acffba 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1614,36 +1614,43 @@ bool update_runstate_area(struct vcpu *v) update_guest_memory_policy(v, &policy); - if ( VM_ASSIST(v->domain, runstate_update_flag) ) + if ( v->runstate_guest_type == RUNSTATE_VADDR ) { - guest_handle = has_32bit_shinfo(v->domain) - ? &v->runstate_guest.compat.p->state_entry_time + 1 - : &v->runstate_guest.native.p->state_entry_time + 1; - guest_handle--; - v->runstate.state_entry_time |= XEN_RUNSTATE_UPDATE; - __raw_copy_to_guest(guest_handle, - (void *)(&v->runstate.state_entry_time + 1) - 1, 1); - smp_wmb(); - } + if ( VM_ASSIST(v->domain, runstate_update_flag) ) + { + guest_handle = has_32bit_shinfo(v->domain) + ? &v->runstate_guest.compat.p->state_entry_time + 1 + : &v->runstate_guest.native.p->state_entry_time + 1; + guest_handle--; + v->runstate.state_entry_time |= XEN_RUNSTATE_UPDATE; + __raw_copy_to_guest(guest_handle, + (void *)(&v->runstate.state_entry_time + 1) - 1, 1); + smp_wmb(); + } - if ( has_32bit_shinfo(v->domain) ) - { - struct compat_vcpu_runstate_info info; + if ( has_32bit_shinfo(v->domain) ) + { + struct compat_vcpu_runstate_info info; - XLAT_vcpu_runstate_info(&info, &v->runstate); - __copy_to_guest(v->runstate_guest.compat, &info, 1); - rc = true; + XLAT_vcpu_runstate_info(&info, &v->runstate); + __copy_to_guest(v->runstate_guest.compat, &info, 1); + rc = true; + } + else + rc = __copy_to_guest(runstate_guest(v), &v->runstate, 1) != + sizeof(v->runstate); + + if ( guest_handle ) + { + v->runstate.state_entry_time &= ~XEN_RUNSTATE_UPDATE; + smp_wmb(); + __raw_copy_to_guest(guest_handle, + (void *)(&v->runstate.state_entry_time + 1) - 1, 1); + } } else - rc = __copy_to_guest(runstate_guest(v), &v->runstate, 1) != - sizeof(v->runstate); - - if ( guest_handle ) { - v->runstate.state_entry_time &= ~XEN_RUNSTATE_UPDATE; - smp_wmb(); - __raw_copy_to_guest(guest_handle, - (void *)(&v->runstate.state_entry_time + 1) - 1, 1); + rc = true; } update_guest_memory_policy(v, &policy); diff --git a/xen/common/domain.c b/xen/common/domain.c index 32bca8d..2c83ede 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -1521,6 +1521,7 @@ long do_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg) rc = 0; runstate_guest(v) = area.addr.h; + v->runstate_guest_type = RUNSTATE_VADDR; if ( v == current ) { @@ -1535,6 +1536,12 @@ long do_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg) break; } + case VCPUOP_register_runstate_phys_memory_area: + { + rc = -ENOSYS; + break; + } + #ifdef VCPU_TRAP_NMI case VCPUOP_send_nmi: if ( !guest_handle_is_null(arg) ) diff --git a/xen/include/public/vcpu.h b/xen/include/public/vcpu.h index 3623af9..0722892 100644 --- a/xen/include/public/vcpu.h +++ b/xen/include/public/vcpu.h @@ -235,6 +235,22 @@ struct vcpu_register_time_memory_area { typedef struct vcpu_register_time_memory_area vcpu_register_time_memory_area_t; DEFINE_XEN_GUEST_HANDLE(vcpu_register_time_memory_area_t); +/* + * Register a shared memory area from which the guest may obtain its own + * runstate information without needing to execute a hypercall. + * Notes: + * 1. The registered address must be guest's physical address. + * 2. The registered runstate area should not cross page boundary. + * 3. Only one shared area may be registered per VCPU. The shared area is + * updated by the hypervisor each time the VCPU is scheduled. Thus + * runstate.state will always be RUNSTATE_running and + * runstate.state_entry_time will indicate the system time at which the + * VCPU was last scheduled to run. + * @extra_arg == pointer to vcpu_register_runstate_memory_area structure. + */ +#define VCPUOP_register_runstate_phys_memory_area 14 + + #endif /* __XEN_PUBLIC_VCPU_H__ */ /* diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index edee52d..9ea76ec 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -163,6 +163,13 @@ struct vcpu void *sched_priv; /* scheduler-specific data */ struct vcpu_runstate_info runstate; + + enum { + RUNSTATE_NONE = 0, + RUNSTATE_PADDR = 1, + RUNSTATE_VADDR = 2, + } runstate_guest_type; + #ifndef CONFIG_COMPAT # define runstate_guest(v) ((v)->runstate_guest) XEN_GUEST_HANDLE(vcpu_runstate_info_t) runstate_guest; /* guest address */ -- 2.7.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |