diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-02-05 12:16:28 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-02-05 12:16:28 +0000 |
commit | 1bb7e0437bb0b3cda7eb47caaac9516d5bb1970a (patch) | |
tree | dd271d4129cfa10ec8567c7f507caf77ac2684c4 /xen/common/hvm | |
parent | 38651997ed10ad12c9dc9aebe04217fd0dd76bb6 (diff) | |
download | xen-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.c | 48 |
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) { |