# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1233836228 0
# Node ID 2358b9fcd51b376c5f1f641a34e1bf3cd427b55d
# Parent 7eb8b094a207267a40a7cf34754b10f12d54e6af
libxc support for the new partial-HVM-save domctl.
This includes making the pagetable walker in xc_pagetab.c behave
correctly for 32-bit and 64-bit HVM guests.
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
---
tools/libxc/xc_domain.c | 32 ++++++++++++++++++++++++++++++++
tools/libxc/xc_pagetab.c | 36 ++++++++++++++----------------------
tools/libxc/xenctrl.h | 19 +++++++++++++++++++
3 files changed, 65 insertions(+), 22 deletions(-)
diff -r 7eb8b094a207 -r 2358b9fcd51b tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Thu Feb 05 12:16:53 2009 +0000
+++ b/tools/libxc/xc_domain.c Thu Feb 05 12:17:08 2009 +0000
@@ -269,6 +269,38 @@ int xc_domain_hvm_getcontext(int xc_hand
unlock_pages(ctxt_buf, size);
return (ret < 0 ? -1 : domctl.u.hvmcontext.size);
+}
+
+/* Get just one element of the HVM guest context.
+ * size must be >= HVM_SAVE_LENGTH(type) */
+int xc_domain_hvm_getcontext_partial(int xc_handle,
+ uint32_t domid,
+ uint16_t typecode,
+ uint16_t instance,
+ void *ctxt_buf,
+ uint32_t size)
+{
+ int ret;
+ DECLARE_DOMCTL;
+
+ if ( !ctxt_buf )
+ return -EINVAL;
+
+ domctl.cmd = XEN_DOMCTL_gethvmcontext_partial;
+ domctl.domain = (domid_t) domid;
+ domctl.u.hvmcontext_partial.type = typecode;
+ domctl.u.hvmcontext_partial.instance = instance;
+ set_xen_guest_handle(domctl.u.hvmcontext_partial.buffer, ctxt_buf);
+
+ if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
+ return ret;
+
+ ret = do_domctl(xc_handle, &domctl);
+
+ if ( ctxt_buf )
+ unlock_pages(ctxt_buf, size);
+
+ return ret ? -1 : 0;
}
/* set info to hvm guest for restore */
diff -r 7eb8b094a207 -r 2358b9fcd51b tools/libxc/xc_pagetab.c
--- a/tools/libxc/xc_pagetab.c Thu Feb 05 12:16:53 2009 +0000
+++ b/tools/libxc/xc_pagetab.c Thu Feb 05 12:17:08 2009 +0000
@@ -4,50 +4,42 @@
* Function to translate virtual to physical addresses.
*/
#include "xc_private.h"
+#include <xen/hvm/save.h>
#define CR0_PG 0x80000000
#define CR4_PAE 0x20
#define PTE_PSE 0x80
+#define EFER_LMA 0x400
+
unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
int vcpu, unsigned long long virt)
{
xc_dominfo_t dominfo;
- vcpu_guest_context_any_t ctx;
uint64_t paddr, mask, pte = 0;
int size, level, pt_levels = 2;
void *map;
if (xc_domain_getinfo(xc_handle, dom, 1, &dominfo) != 1
- || dominfo.domid != dom
- || xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0)
+ || dominfo.domid != dom)
return 0;
/* What kind of paging are we dealing with? */
if (dominfo.hvm) {
- unsigned long cr0, cr3, cr4;
- xen_capabilities_info_t xen_caps = "";
- if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0)
+ struct hvm_hw_cpu ctx;
+ if (xc_domain_hvm_getcontext_partial(xc_handle, dom,
+ HVM_SAVE_CODE(CPU), vcpu,
+ &ctx, sizeof ctx) != 0)
return 0;
- /* HVM context records are always host-sized */
- if (strstr(xen_caps, "xen-3.0-x86_64")) {
- cr0 = ctx.x64.ctrlreg[0];
- cr3 = ctx.x64.ctrlreg[3];
- cr4 = ctx.x64.ctrlreg[4];
- } else {
- cr0 = ctx.x32.ctrlreg[0];
- cr3 = ctx.x32.ctrlreg[3];
- cr4 = ctx.x32.ctrlreg[4];
- }
- if (!(cr0 & CR0_PG))
+ if (!(ctx.cr0 & CR0_PG))
return virt;
- if (0 /* XXX how to get EFER.LMA? */)
- pt_levels = 4;
- else
- pt_levels = (cr4 & CR4_PAE) ? 3 : 2;
- paddr = cr3 & ((pt_levels == 3) ? ~0x1full : ~0xfffull);
+ pt_levels = (ctx.msr_efer&EFER_LMA) ? 4 : (ctx.cr4&CR4_PAE) ? 3 : 2;
+ paddr = ctx.cr3 & ((pt_levels == 3) ? ~0x1full : ~0xfffull);
} else {
DECLARE_DOMCTL;
+ vcpu_guest_context_any_t ctx;
+ if (xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0)
+ return 0;
domctl.domain = dom;
domctl.cmd = XEN_DOMCTL_get_address_size;
if ( do_domctl(xc_handle, &domctl) != 0 )
diff -r 7eb8b094a207 -r 2358b9fcd51b tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Thu Feb 05 12:16:53 2009 +0000
+++ b/tools/libxc/xenctrl.h Thu Feb 05 12:17:08 2009 +0000
@@ -375,6 +375,25 @@ int xc_domain_hvm_getcontext(int xc_hand
uint8_t *ctxt_buf,
uint32_t size);
+
+/**
+ * This function returns one element of the context of a hvm domain
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain to get information from
+ * @parm typecode which type of elemnt required
+ * @parm instance which instance of the type
+ * @parm ctxt_buf a pointer to a structure to store the execution context of
+ * the hvm domain
+ * @parm size the size of ctxt_buf (must be >= HVM_SAVE_LENGTH(typecode))
+ * @return 0 on success, -1 on failure
+ */
+int xc_domain_hvm_getcontext_partial(int xc_handle,
+ uint32_t domid,
+ uint16_t typecode,
+ uint16_t instance,
+ void *ctxt_buf,
+ uint32_t size);
+
/**
* This function will set the context for hvm domain
*
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|