hvm_save_one: return correct data

It is possible that hvm_sr_handlers[typecode].save does not use all
the provided room.  Also it can use variable sized records.  In both
cases, using:

   instance * hvm_sr_handlers[typecode].size

does not select the correct instance.  Add code to search for the
correct instance.

Signed-off-by: Don Slutz <dslutz@verizon.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
master commit: e019c606f5
master date: 2014-01-08 09:15:03 +0100
This commit is contained in:
Don Slutz authored and Jan Beulich committed 2014-01-10 11:13:00 +01:00
1 parent 409a207354
commit 670d64aed0
1 file changed
+24 -10
+24 -10
View File
@@ -98,9 +98,6 @@ int hvm_save_one(struct domain *d, uint16_t typecode, uint16_t instance,
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 )
@@ -112,13 +109,30 @@ int hvm_save_one(struct domain *d, uint16_t typecode, uint16_t instance,
d->domain_id, 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;
else
{
uint32_t off;
const struct hvm_save_descriptor *desc;
rv = -EBADSLT;
for ( off = 0; off < (ctxt.cur - sizeof(*desc)); off += desc->length )
{
desc = (void *)(ctxt.data + off);
/* Move past header */
off += sizeof(*desc);
if ( instance == desc->instance )
{
uint32_t copy_length = desc->length;
if ( off + copy_length > ctxt.cur )
copy_length = ctxt.cur - off;
rv = 0;
if ( copy_to_guest(handle, ctxt.data + off, copy_length) )
rv = -EFAULT;
break;
}
}
}
xfree(ctxt.data);
return rv;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.