# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1192097456 -32400 # Node ID 6f9435bb6a195a52cb43799b82cc24cdc7a298f3 # Parent 9009a8f49f11378d562a4aed005b17f136a773c0 implement set/gethvmcontext hypercall PATCHNAME: implement_set_get_hvmcontext_hypercall Signed-off-by: Isaku Yamahata diff -r 9009a8f49f11 -r 6f9435bb6a19 xen/arch/ia64/xen/dom0_ops.c --- a/xen/arch/ia64/xen/dom0_ops.c Thu Oct 11 20:10:30 2007 +0900 +++ b/xen/arch/ia64/xen/dom0_ops.c Thu Oct 11 19:10:56 2007 +0900 @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include #define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) @@ -217,6 +220,109 @@ long arch_do_domctl(xen_domctl_t *op, XE } break; + case XEN_DOMCTL_sethvmcontext: + { + struct hvm_domain_context c; + struct domain *d; + + c.cur = 0; + c.size = op->u.hvmcontext.size; + c.data = NULL; + + ret = -ESRCH; + if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL ) + break; + +#ifdef CONFIG_X86 + ret = xsm_hvmcontext(d, op->cmd); + if ( ret ) + goto sethvmcontext_out; +#endif /* CONFIG_X86 */ + + ret = -EINVAL; + if ( !is_hvm_domain(d) ) + goto sethvmcontext_out; + + ret = -ENOMEM; + if ( (c.data = xmalloc_bytes(c.size)) == NULL ) + goto sethvmcontext_out; + + ret = -EFAULT; + if ( copy_from_guest(c.data, op->u.hvmcontext.buffer, c.size) != 0) + goto sethvmcontext_out; + + domain_pause(d); + ret = hvm_load(d, &c); + domain_unpause(d); + + sethvmcontext_out: + if ( c.data != NULL ) + xfree(c.data); + + rcu_unlock_domain(d); + } + break; + + case XEN_DOMCTL_gethvmcontext: + { + struct hvm_domain_context c; + struct domain *d; + + ret = -ESRCH; + if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL ) + break; + +#ifdef CONFIG_X86 + ret = xsm_hvmcontext(d, op->cmd); + if ( ret ) + goto gethvmcontext_out; +#endif /* CONFIG_X86 */ + + ret = -EINVAL; + if ( !is_hvm_domain(d) ) + goto gethvmcontext_out; + + c.cur = 0; + c.size = hvm_save_size(d); + c.data = NULL; + + if ( guest_handle_is_null(op->u.hvmcontext.buffer) ) + { + /* Client is querying for the correct buffer size */ + op->u.hvmcontext.size = c.size; + ret = 0; + goto gethvmcontext_out; + } + + /* Check that the client has a big enough buffer */ + ret = -ENOSPC; + if ( op->u.hvmcontext.size < c.size ) + goto gethvmcontext_out; + + /* Allocate our own marshalling buffer */ + ret = -ENOMEM; + if ( (c.data = xmalloc_bytes(c.size)) == NULL ) + goto gethvmcontext_out; + + domain_pause(d); + ret = hvm_save(d, &c); + domain_unpause(d); + + op->u.hvmcontext.size = c.cur; + if ( copy_to_guest(op->u.hvmcontext.buffer, c.data, c.size) != 0 ) + ret = -EFAULT; + + gethvmcontext_out: + if ( copy_to_guest(u_domctl, op, 1) ) + ret = -EFAULT; + + if ( c.data != NULL ) + xfree(c.data); + + rcu_unlock_domain(d); + } + break; + default: printk("arch_do_domctl: unrecognized domctl: %d!!!\n",op->cmd); ret = -ENOSYS;