aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/hvm
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-02-05 12:16:28 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-02-05 12:16:28 +0000
commit1bb7e0437bb0b3cda7eb47caaac9516d5bb1970a (patch)
treedd271d4129cfa10ec8567c7f507caf77ac2684c4 /xen/common/hvm
parent38651997ed10ad12c9dc9aebe04217fd0dd76bb6 (diff)
downloadxen-1bb7e0437bb0b3cda7eb47caaac9516d5bb1970a.tar.gz
xen-1bb7e0437bb0b3cda7eb47caaac9516d5bb1970a.tar.bz2
xen-1bb7e0437bb0b3cda7eb47caaac9516d5bb1970a.zip
Add a new domctl to get a single record from the HVM save context
Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
Diffstat (limited to 'xen/common/hvm')
-rw-r--r--xen/common/hvm/save.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/xen/common/hvm/save.c b/xen/common/hvm/save.c
index cb3cf66885..66876e6a1c 100644
--- a/xen/common/hvm/save.c
+++ b/xen/common/hvm/save.c
@@ -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)
{