|
[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 |