# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1233836188 0
# Node ID 1dfcb2444c6e0c0ff0e2809f4ac4ee4adda72fa6
# Parent 8303bd33d0304ed4f4edc94960c874eabad60563
Add a new domctl to get a single record from the HVM save context
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
---
xen/arch/x86/domctl.c | 28 +++++++++++++++++++++++++
xen/common/hvm/save.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
xen/include/public/domctl.h | 12 +++++++++++
xen/include/xen/hvm/save.h | 2 +
xen/xsm/flask/hooks.c | 1
5 files changed, 91 insertions(+)
diff -r 8303bd33d030 -r 1dfcb2444c6e xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Thu Feb 05 12:14:09 2009 +0000
+++ b/xen/arch/x86/domctl.c Thu Feb 05 12:16:28 2009 +0000
@@ -417,6 +417,34 @@ long arch_do_domctl(
}
break;
+ case XEN_DOMCTL_gethvmcontext_partial:
+ {
+ struct domain *d;
+
+ ret = -ESRCH;
+ if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
+ break;
+
+ ret = xsm_hvmcontext(d, domctl->cmd);
+ if ( ret )
+ goto gethvmcontext_partial_out;
+
+ ret = -EINVAL;
+ if ( !is_hvm_domain(d) )
+ goto gethvmcontext_partial_out;
+
+ domain_pause(d);
+ ret = hvm_save_one(d, domctl->u.hvmcontext_partial.type,
+ domctl->u.hvmcontext_partial.instance,
+ domctl->u.hvmcontext_partial.buffer);
+ domain_unpause(d);
+
+ gethvmcontext_partial_out:
+ rcu_unlock_domain(d);
+ }
+ break;
+
+
case XEN_DOMCTL_set_address_size:
{
struct domain *d;
diff -r 8303bd33d030 -r 1dfcb2444c6e xen/common/hvm/save.c
--- a/xen/common/hvm/save.c Thu Feb 05 12:14:09 2009 +0000
+++ b/xen/common/hvm/save.c Thu Feb 05 12:16:28 2009 +0000
@@ -26,6 +26,7 @@
#include <xen/version.h>
#include <public/version.h>
#include <xen/sched.h>
+#include <xen/guest_access.h>
#include <asm/hvm/support.h>
@@ -75,6 +76,53 @@ size_t hvm_save_size(struct domain *d)
return sz;
}
+/* Extract a single instance of a save record, by marshalling all
+ * records of that type and copying out the one we need. */
+int hvm_save_one(struct domain *d, uint16_t typecode, uint16_t instance,
+ XEN_GUEST_HANDLE_64(uint8) handle)
+{
+ int rv = 0;
+ size_t sz = 0;
+ struct vcpu *v;
+ hvm_domain_context_t ctxt = { 0, };
+
+ if ( d->is_dying
+ || typecode > HVM_SAVE_CODE_MAX
+ || hvm_sr_handlers[typecode].size < sizeof(struct hvm_save_descriptor)
+ || hvm_sr_handlers[typecode].save == NULL )
+ return -EINVAL;
+
+ if ( hvm_sr_handlers[typecode].kind == HVMSR_PER_VCPU )
+ for_each_vcpu(d, v)
+ sz += hvm_sr_handlers[typecode].size;
+ else
+ sz = hvm_sr_handlers[typecode].size;
+
+ if ( (instance + 1) * hvm_sr_handlers[typecode].size > sz )
+ return -EINVAL;
+
+ ctxt.size = sz;
+ ctxt.data = xmalloc_bytes(sz);
+ if ( !ctxt.data )
+ return -ENOMEM;
+
+ if ( hvm_sr_handlers[typecode].save(d, &ctxt) != 0 )
+ {
+ gdprintk(XENLOG_ERR,
+ "HVM save: failed to save type %"PRIu16"\n", typecode);
+ rv = -EFAULT;
+ }
+ else if ( copy_to_guest(handle,
+ ctxt.data
+ + (instance * hvm_sr_handlers[typecode].size)
+ + sizeof (struct hvm_save_descriptor),
+ hvm_sr_handlers[typecode].size
+ - sizeof (struct hvm_save_descriptor)) )
+ rv = -EFAULT;
+
+ xfree(ctxt.data);
+ return rv;
+}
int hvm_save(struct domain *d, hvm_domain_context_t *h)
{
diff -r 8303bd33d030 -r 1dfcb2444c6e xen/include/public/domctl.h
--- a/xen/include/public/domctl.h Thu Feb 05 12:14:09 2009 +0000
+++ b/xen/include/public/domctl.h Thu Feb 05 12:16:28 2009 +0000
@@ -630,6 +630,17 @@ typedef struct xen_domctl_debug_op xen_d
typedef struct xen_domctl_debug_op xen_domctl_debug_op_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_debug_op_t);
+/*
+ * Request a particular record from the HVM context
+ */
+#define XEN_DOMCTL_gethvmcontext_partial 55
+typedef struct xen_domctl_hvmcontext_partial {
+ uint32_t type; /* IN: Type of record required */
+ uint32_t instance; /* IN: Instance of that type */
+ XEN_GUEST_HANDLE_64(uint8) buffer; /* OUT: buffer to write record into */
+} xen_domctl_hvmcontext_partial_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_partial_t);
+
struct xen_domctl {
uint32_t cmd;
@@ -658,6 +669,7 @@ struct xen_domctl {
struct xen_domctl_settimeoffset settimeoffset;
struct xen_domctl_real_mode_area real_mode_area;
struct xen_domctl_hvmcontext hvmcontext;
+ struct xen_domctl_hvmcontext_partial hvmcontext_partial;
struct xen_domctl_address_size address_size;
struct xen_domctl_sendtrigger sendtrigger;
struct xen_domctl_get_device_group get_device_group;
diff -r 8303bd33d030 -r 1dfcb2444c6e xen/include/xen/hvm/save.h
--- a/xen/include/xen/hvm/save.h Thu Feb 05 12:14:09 2009 +0000
+++ b/xen/include/xen/hvm/save.h Thu Feb 05 12:16:28 2009 +0000
@@ -152,6 +152,8 @@ __initcall(__hvm_register_##_x##_save_an
/* Entry points for saving and restoring HVM domain state */
size_t hvm_save_size(struct domain *d);
int hvm_save(struct domain *d, hvm_domain_context_t *h);
+int hvm_save_one(struct domain *d, uint16_t typecode, uint16_t instance,
+ XEN_GUEST_HANDLE_64(uint8) handle);
int hvm_load(struct domain *d, hvm_domain_context_t *h);
/* Arch-specific definitions. */
diff -r 8303bd33d030 -r 1dfcb2444c6e xen/xsm/flask/hooks.c
--- a/xen/xsm/flask/hooks.c Thu Feb 05 12:14:09 2009 +0000
+++ b/xen/xsm/flask/hooks.c Thu Feb 05 12:16:28 2009 +0000
@@ -820,6 +820,7 @@ static int flask_hvmcontext(struct domai
perm = HVM__SETHVMC;
break;
case XEN_DOMCTL_gethvmcontext:
+ case XEN_DOMCTL_gethvmcontext_partial:
perm = HVM__GETHVMC;
break;
default:
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|