From: Andrii Anisov <andrii.anisov@gmail.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>,
Andrii Anisov <andrii_anisov@epam.com>,
Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
George Dunlap <George.Dunlap@eu.citrix.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Ian Jackson <ian.jackson@eu.citrix.com>, Tim Deegan <tim@xen.org>,
Julien Grall <julien.grall@arm.com>,
Jan Beulich <jbeulich@suse.com>,
xen-devel@lists.xenproject.org, Wei Liu <wei.liu2@citrix.com>
Subject: [Xen-devel] [PATCH RFC 2] [DO NOT APPLY] introduce VCPUOP_register_runstate_phys_memory_area hypercall
Date: Fri, 24 May 2019 21:12:54 +0300 [thread overview]
Message-ID: <1558721577-13958-1-git-send-email-andrii.anisov@gmail.com> (raw)
Message-ID: <20190524181254.VPl8JBIM1874IEPRRijv3aAUQ24wn_iozxbx_IXcbwU@z> (raw)
From: Andrii Anisov <andrii_anisov@epam.com>
An RFC version of the runstate registration with phys address.
Runstate area access is implemented with mapping on each update once for
all accesses.
Signed-off-by: Andrii Anisov <andrii_anisov@epam.com>
---
xen/arch/arm/domain.c | 63 ++++++++++++++++++++++++++---
xen/common/domain.c | 101 ++++++++++++++++++++++++++++++++++++++++++++--
xen/include/public/vcpu.h | 15 +++++++
xen/include/xen/sched.h | 28 +++++++++----
4 files changed, 190 insertions(+), 17 deletions(-)
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index a9f7ff5..04c4cff 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -274,17 +274,15 @@ static void ctxt_switch_to(struct vcpu *n)
virt_timer_restore(n);
}
-/* Update per-VCPU guest runstate shared memory area (if registered). */
-static void update_runstate_area(struct vcpu *v)
+static void update_runstate_by_gvaddr(struct vcpu *v)
{
void __user *guest_handle = NULL;
- if ( guest_handle_is_null(runstate_guest(v)) )
- return;
+ ASSERT(!guest_handle_is_null(runstate_guest_virt(v)));
if ( VM_ASSIST(v->domain, runstate_update_flag) )
{
- guest_handle = &v->runstate_guest.p->state_entry_time + 1;
+ guest_handle = &v->runstate_guest.virt.p->state_entry_time + 1;
guest_handle--;
v->runstate.state_entry_time |= XEN_RUNSTATE_UPDATE;
__raw_copy_to_guest(guest_handle,
@@ -292,7 +290,7 @@ static void update_runstate_area(struct vcpu *v)
smp_wmb();
}
- __copy_to_guest(runstate_guest(v), &v->runstate, 1);
+ __copy_to_guest(runstate_guest_virt(v), &v->runstate, 1);
if ( guest_handle )
{
@@ -303,6 +301,58 @@ static void update_runstate_area(struct vcpu *v)
}
}
+extern int map_runstate_area(struct vcpu *v, struct vcpu_runstate_info **area);
+extern void unmap_runstate_area(struct vcpu_runstate_info *area);
+
+static void update_runstate_by_gpaddr(struct vcpu *v)
+{
+ struct vcpu_runstate_info *runstate;
+
+ if ( map_runstate_area(v, &runstate) )
+ return;
+
+ if ( VM_ASSIST(v->domain, runstate_update_flag) )
+ {
+ runstate->state_entry_time |= XEN_RUNSTATE_UPDATE;
+ smp_wmb();
+ v->runstate.state_entry_time |= XEN_RUNSTATE_UPDATE;
+ }
+
+ memcpy(runstate, &v->runstate, sizeof(v->runstate));
+
+ if ( VM_ASSIST(v->domain, runstate_update_flag) )
+ {
+ runstate->state_entry_time &= ~XEN_RUNSTATE_UPDATE;
+ smp_wmb();
+ v->runstate.state_entry_time &= ~XEN_RUNSTATE_UPDATE;
+ }
+
+ unmap_runstate_area(runstate);
+}
+
+/* Update per-VCPU guest runstate shared memory area (if registered). */
+static void update_runstate_area(struct vcpu *v)
+{
+ if ( xchg(&v->runstate_in_use, 1) )
+ return;
+
+ switch ( v->runstate_guest_type )
+ {
+ case RUNSTATE_NONE:
+ break;
+
+ case RUNSTATE_VADDR:
+ update_runstate_by_gvaddr(v);
+ break;
+
+ case RUNSTATE_PADDR:
+ update_runstate_by_gpaddr(v);
+ break;
+ }
+
+ xchg(&v->runstate_in_use, 0);
+}
+
static void schedule_tail(struct vcpu *prev)
{
ctxt_switch_from(prev);
@@ -998,6 +1048,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/common/domain.c b/xen/common/domain.c
index 32bca8d..f167a68 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -700,6 +700,68 @@ int rcu_lock_live_remote_domain_by_id(domid_t dom, struct domain **d)
return 0;
}
+void unmap_runstate_area(struct vcpu_runstate_info *area)
+{
+ mfn_t mfn;
+
+ ASSERT(area != NULL);
+
+ mfn = _mfn(domain_page_map_to_mfn(area));
+
+ unmap_domain_page_global((void *)
+ ((unsigned long)area &
+ PAGE_MASK));
+
+ put_page_and_type(mfn_to_page(mfn));
+}
+
+int map_runstate_area(struct vcpu *v, struct vcpu_runstate_info **area)
+{
+ unsigned long offset = v->runstate_guest.phys & ~PAGE_MASK;
+ gfn_t gfn = gaddr_to_gfn(v->runstate_guest.phys);
+ struct domain *d = v->domain;
+ void *mapping;
+ struct page_info *page;
+ size_t size = sizeof(struct vcpu_runstate_info);
+
+ if ( offset > (PAGE_SIZE - size) )
+ return -EINVAL;
+
+ page = get_page_from_gfn(d, gfn_x(gfn), NULL, P2M_ALLOC);
+ if ( !page )
+ return -EINVAL;
+
+ if ( !get_page_type(page, PGT_writable_page) )
+ {
+ put_page(page);
+ return -EINVAL;
+ }
+
+ mapping = __map_domain_page_global(page);
+
+ if ( mapping == NULL )
+ {
+ put_page_and_type(page);
+ return -ENOMEM;
+ }
+
+ *area = mapping + offset;
+
+ return 0;
+}
+
+static void discard_runstate_area(struct vcpu *v)
+{
+ v->runstate_guest_type = RUNSTATE_NONE;
+}
+
+static void discard_runstate_area_locked(struct vcpu *v)
+{
+ while ( xchg(&v->runstate_in_use, 1) );
+ discard_runstate_area(v);
+ xchg(&v->runstate_in_use, 0);
+}
+
int domain_kill(struct domain *d)
{
int rc = 0;
@@ -738,7 +800,10 @@ int domain_kill(struct domain *d)
if ( cpupool_move_domain(d, cpupool0) )
return -ERESTART;
for_each_vcpu ( d, v )
+ {
+ discard_runstate_area_locked(v);
unmap_vcpu_info(v);
+ }
d->is_dying = DOMDYING_dead;
/* Mem event cleanup has to go here because the rings
* have to be put before we call put_domain. */
@@ -1192,7 +1257,7 @@ int domain_soft_reset(struct domain *d)
for_each_vcpu ( d, v )
{
- set_xen_guest_handle(runstate_guest(v), NULL);
+ discard_runstate_area_locked(v);
unmap_vcpu_info(v);
}
@@ -1520,18 +1585,46 @@ long do_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg)
break;
rc = 0;
- runstate_guest(v) = area.addr.h;
+
+ while( xchg(&v->runstate_in_use, 1) == 0);
+
+ discard_runstate_area(v);
+
+ runstate_guest_virt(v) = area.addr.h;
+ v->runstate_guest_type = RUNSTATE_VADDR;
if ( v == current )
{
- __copy_to_guest(runstate_guest(v), &v->runstate, 1);
+ __copy_to_guest(runstate_guest_virt(v), &v->runstate, 1);
}
else
{
vcpu_runstate_get(v, &runstate);
- __copy_to_guest(runstate_guest(v), &runstate, 1);
+ __copy_to_guest(runstate_guest_virt(v), &runstate, 1);
}
+ xchg(&v->runstate_in_use, 0);
+
+ break;
+ }
+
+ case VCPUOP_register_runstate_phys_memory_area:
+ {
+ struct vcpu_register_runstate_memory_area area;
+
+ rc = -EFAULT;
+ if ( copy_from_guest(&area, arg, 1) )
+ break;
+
+ while( xchg(&v->runstate_in_use, 1) == 0);
+
+ discard_runstate_area(v);
+ v->runstate_guest.phys = area.addr.p;
+ v->runstate_guest_type = RUNSTATE_PADDR;
+
+ xchg(&v->runstate_in_use, 0);
+ rc = 0;
+
break;
}
diff --git a/xen/include/public/vcpu.h b/xen/include/public/vcpu.h
index 3623af9..d7da4a3 100644
--- a/xen/include/public/vcpu.h
+++ b/xen/include/public/vcpu.h
@@ -235,6 +235,21 @@ 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..8ac597b 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -163,17 +163,31 @@ 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;
+
+ unsigned long runstate_in_use;
+
+ union
+ {
#ifndef CONFIG_COMPAT
-# define runstate_guest(v) ((v)->runstate_guest)
- XEN_GUEST_HANDLE(vcpu_runstate_info_t) runstate_guest; /* guest address */
+# define runstate_guest_virt(v) ((v)->runstate_guest.virt)
+ XEN_GUEST_HANDLE(vcpu_runstate_info_t) virt; /* guest address */
#else
-# define runstate_guest(v) ((v)->runstate_guest.native)
- union {
- XEN_GUEST_HANDLE(vcpu_runstate_info_t) native;
- XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t) compat;
- } runstate_guest; /* guest address */
+# define runstate_guest_virt(v) ((v)->runstate_guest.virt.native)
+ union {
+ XEN_GUEST_HANDLE(vcpu_runstate_info_t) native;
+ XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t) compat;
+ } virt; /* guest address */
#endif
+ paddr_t phys;
+ } runstate_guest;
+
/* last time when vCPU is scheduled out */
uint64_t last_run_time;
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next reply other threads:[~2019-05-24 18:13 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-24 18:12 Andrii Anisov [this message]
2019-05-24 18:12 ` [Xen-devel] [PATCH RFC 2] [DO NOT APPLY] introduce VCPUOP_register_runstate_phys_memory_area hypercall Andrii Anisov
2019-05-24 18:12 ` [PATCH v3] Introduce runstate area registration with phys address Andrii Anisov
2019-05-24 18:12 ` [Xen-devel] " Andrii Anisov
2019-05-24 18:12 ` [PATCH v3] xen: introduce VCPUOP_register_runstate_phys_memory_area hypercall Andrii Anisov
2019-05-24 18:12 ` [Xen-devel] " Andrii Anisov
2019-06-07 14:23 ` Jan Beulich
2019-06-10 11:44 ` Julien Grall
2019-06-11 9:10 ` Jan Beulich
2019-06-11 10:22 ` Andrii Anisov
2019-06-11 12:12 ` Julien Grall
2019-06-11 12:26 ` Andrii Anisov
2019-06-11 12:32 ` Julien Grall
2019-06-11 12:40 ` Andrii Anisov
2019-06-13 12:21 ` Andrii Anisov
2019-06-13 12:39 ` Jan Beulich
2019-06-13 12:32 ` Andrii Anisov
2019-06-13 12:41 ` Jan Beulich
2019-06-13 12:48 ` Julien Grall
2019-06-13 12:58 ` Jan Beulich
2019-06-13 13:14 ` Julien Grall
2019-06-13 13:40 ` Jan Beulich
2019-06-13 14:41 ` Julien Grall
2019-06-14 14:36 ` Andrii Anisov
2019-06-14 14:39 ` Julien Grall
2019-06-14 15:11 ` Andrii Anisov
2019-06-14 15:24 ` Julien Grall
2019-06-14 16:11 ` Andrii Anisov
2019-06-14 16:20 ` Julien Grall
2019-06-14 16:25 ` Andrii Anisov
2019-06-17 6:27 ` Jan Beulich
2019-06-14 15:42 ` Jan Beulich
2019-06-14 16:23 ` Andrii Anisov
2019-06-17 6:28 ` Jan Beulich
2019-06-18 15:32 ` Andrii Anisov
2019-06-18 15:44 ` Jan Beulich
2019-06-11 16:09 ` Andrii Anisov
2019-06-12 7:27 ` Jan Beulich
2019-06-13 12:17 ` Andrii Anisov
2019-06-13 12:36 ` Jan Beulich
2019-06-11 16:13 ` Andrii Anisov
2019-05-24 18:12 ` [PATCH RFC 1] [DO NOT APPLY] " Andrii Anisov
2019-05-24 18:12 ` [Xen-devel] " Andrii Anisov
2019-05-28 8:59 ` [PATCH RFC 2] " Julien Grall
2019-05-28 8:59 ` [Xen-devel] " Julien Grall
2019-05-28 9:17 ` Andrii Anisov
2019-05-28 9:17 ` [Xen-devel] " Andrii Anisov
2019-05-28 9:23 ` Julien Grall
2019-05-28 9:23 ` [Xen-devel] " Julien Grall
2019-05-28 9:36 ` Andrii Anisov
2019-05-28 9:36 ` [Xen-devel] " Andrii Anisov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1558721577-13958-1-git-send-email-andrii.anisov@gmail.com \
--to=andrii.anisov@gmail.com \
--cc=George.Dunlap@eu.citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=andrii_anisov@epam.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=julien.grall@arm.com \
--cc=konrad.wilk@oracle.com \
--cc=sstabellini@kernel.org \
--cc=tim@xen.org \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).