[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM][VMX] Fix data copying in transition to/from vmxassist.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 412fc1c1bd7a8ac70dace63b84bcc075c1fb8e0b # Parent 6d5d5b883dfcf60f0b17fcfc31269e43aecd5b0c [HVM][VMX] Fix data copying in transition to/from vmxassist. In vmx_assist, the copy for new/old context and vmx assist magic are all using physical address, while hvm_copy will use the virtual address. This may cause problem when guest jump directly from real mode to paging mode. Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx> Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 81 ++++++++++++++++++++++---------------- xen/arch/x86/hvm/vmx/vmx.c | 14 +++--- xen/include/asm-x86/hvm/support.h | 1 3 files changed, 56 insertions(+), 40 deletions(-) diff -r 6d5d5b883dfc -r 412fc1c1bd7a xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Fri Sep 29 09:29:20 2006 +0100 +++ b/xen/arch/x86/hvm/hvm.c Fri Sep 29 10:30:18 2006 +0100 @@ -389,42 +389,57 @@ void hvm_hlt(unsigned long rflags) } /* - * Copy from/to guest virtual. + * __hvm_copy(): + * @buf = hypervisor buffer + * @addr = guest virtual or physical address to copy to/from + * @size = number of bytes to copy + * @dir = HVM_COPY_IN / HVM_COPY_OUT + * @phy = interpret addr as physical or virtual address? + * Returns TRUE on success. */ +static int __hvm_copy( + void *buf, unsigned long addr, int size, int dir, int phy) +{ + struct vcpu *v = current; + unsigned long mfn; + char *p; + int count; + + while ( size > 0 ) + { + count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), size); + + mfn = phy ? + get_mfn_from_gpfn(addr >> PAGE_SHIFT) : + mfn_x(sh_vcpu_gfn_to_mfn(v, shadow_gva_to_gfn(v, addr))); + if ( mfn == INVALID_MFN ) + return 0; + + p = (char *)map_domain_page(mfn) + (addr & ~PAGE_MASK); + + if ( dir == HVM_COPY_IN ) + memcpy(buf, p, count); + else + memcpy(p, buf, count); + + unmap_domain_page(p); + + addr += count; + buf += count; + size -= count; + } + + return 1; +} + +int hvm_copy_phy(void *buf, unsigned long paddr, int size, int dir) +{ + return __hvm_copy(buf, paddr, size, dir, 1); +} + int hvm_copy(void *buf, unsigned long vaddr, int size, int dir) { - struct vcpu *v = current; - unsigned long gfn; - unsigned long mfn; - char *addr; - int count; - - while (size > 0) { - count = PAGE_SIZE - (vaddr & ~PAGE_MASK); - if (count > size) - count = size; - - gfn = shadow_gva_to_gfn(v, vaddr); - mfn = mfn_x(sh_vcpu_gfn_to_mfn(v, gfn)); - - if (mfn == INVALID_MFN) - return 0; - - addr = (char *)map_domain_page(mfn) + (vaddr & ~PAGE_MASK); - - if (dir == HVM_COPY_IN) - memcpy(buf, addr, count); - else - memcpy(addr, buf, count); - - unmap_domain_page(addr); - - vaddr += count; - buf += count; - size -= count; - } - - return 1; + return __hvm_copy(buf, vaddr, size, dir, 0); } /* diff -r 6d5d5b883dfc -r 412fc1c1bd7a xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Fri Sep 29 09:29:20 2006 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Sep 29 10:30:18 2006 +0100 @@ -1371,7 +1371,7 @@ static int vmx_assist(struct vcpu *v, in u32 cp; /* make sure vmxassist exists (this is not an error) */ - if (!hvm_copy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), HVM_COPY_IN)) + if (!hvm_copy_phy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), HVM_COPY_IN)) return 0; if (magic != VMXASSIST_MAGIC) return 0; @@ -1385,20 +1385,20 @@ static int vmx_assist(struct vcpu *v, in */ case VMX_ASSIST_INVOKE: /* save the old context */ - if (!hvm_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN)) + if (!hvm_copy_phy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN)) goto error; if (cp != 0) { if (!vmx_world_save(v, &c)) goto error; - if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_OUT)) + if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_OUT)) goto error; } /* restore the new context, this should activate vmxassist */ - if (!hvm_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), HVM_COPY_IN)) + if (!hvm_copy_phy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), HVM_COPY_IN)) goto error; if (cp != 0) { - if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_IN)) + if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_IN)) goto error; if (!vmx_world_restore(v, &c)) goto error; @@ -1412,10 +1412,10 @@ static int vmx_assist(struct vcpu *v, in */ case VMX_ASSIST_RESTORE: /* save the old context */ - if (!hvm_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN)) + if (!hvm_copy_phy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN)) goto error; if (cp != 0) { - if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_IN)) + if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_IN)) goto error; if (!vmx_world_restore(v, &c)) goto error; diff -r 6d5d5b883dfc -r 412fc1c1bd7a xen/include/asm-x86/hvm/support.h --- a/xen/include/asm-x86/hvm/support.h Fri Sep 29 09:29:20 2006 +0100 +++ b/xen/include/asm-x86/hvm/support.h Fri Sep 29 10:30:18 2006 +0100 @@ -138,6 +138,7 @@ extern int hvm_enabled; enum { HVM_COPY_IN = 0, HVM_COPY_OUT }; extern int hvm_copy(void *buf, unsigned long vaddr, int size, int dir); +extern int hvm_copy_phy(void *buf, unsigned long vaddr, int size, int dir); extern void hvm_setup_platform(struct domain* d); extern int hvm_mmio_intercept(ioreq_t *p); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |