Handle page overlapping copies. (patches are against current xen-vt-testing tree) Signed-Off-By: Leendert van Doorn <leendert@watson.ibm.com> diff -r 04ca47c298b5 xen/arch/x86/vmx.c --- a/xen/arch/x86/vmx.c Thu Sep 1 21:30:51 2005 +++ b/xen/arch/x86/vmx.c Fri Sep 2 08:39:08 2005 @@ -699,29 +699,34 @@ vmx_wait_io(); } -enum { COPY_IN = 0, COPY_OUT }; - -static inline int +int vmx_copy(void *buf, unsigned long laddr, int size, int dir) { + unsigned long mfn; char *addr; - unsigned long mfn; - - if ( (size + (laddr & (PAGE_SIZE - 1))) >= PAGE_SIZE ) - { - printf("vmx_copy exceeds page boundary\n"); - return 0; - } - - mfn = get_mfn_from_pfn(laddr >> PAGE_SHIFT); - addr = (char *)map_domain_page(mfn) + (laddr & ~PAGE_MASK); - - if (dir == COPY_IN) - memcpy(buf, addr, size); - else - memcpy(addr, buf, size); - - unmap_domain_page(addr); + int count; + + while (size > 0) { + count = PAGE_SIZE - (laddr & ~PAGE_MASK); + if (count > size) + count = size; + + mfn = get_mfn_from_pfn(laddr >> PAGE_SHIFT); + /* XXX check whether laddr is valid */ + addr = (char *)map_domain_page(mfn) + (laddr & ~PAGE_MASK); + + if (dir == VMX_COPY_IN) + memcpy(buf, addr, count); + else + memcpy(addr, buf, count); + + unmap_domain_page(addr); + + laddr += count; + buf += count; + size -= count; + } + return 1; } @@ -908,7 +913,7 @@ u32 cp; /* make sure vmxassist exists (this is not an error) */ - if (!vmx_copy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), COPY_IN)) + if (!vmx_copy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), VMX_COPY_IN)) return 0; if (magic != VMXASSIST_MAGIC) return 0; @@ -922,20 +927,20 @@ */ case VMX_ASSIST_INVOKE: /* save the old context */ - if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), COPY_IN)) + if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), VMX_COPY_IN)) goto error; if (cp != 0) { if (!vmx_world_save(d, &c)) goto error; - if (!vmx_copy(&c, cp, sizeof(c), COPY_OUT)) + if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_OUT)) goto error; } /* restore the new context, this should activate vmxassist */ - if (!vmx_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), COPY_IN)) + if (!vmx_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), VMX_COPY_IN)) goto error; if (cp != 0) { - if (!vmx_copy(&c, cp, sizeof(c), COPY_IN)) + if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_IN)) goto error; if (!vmx_world_restore(d, &c)) goto error; @@ -949,10 +954,10 @@ */ case VMX_ASSIST_RESTORE: /* save the old context */ - if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), COPY_IN)) + if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), VMX_COPY_IN)) goto error; if (cp != 0) { - if (!vmx_copy(&c, cp, sizeof(c), COPY_IN)) + if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_IN)) goto error; if (!vmx_world_restore(d, &c)) goto error; diff -r 04ca47c298b5 xen/include/asm-x86/vmx.h --- a/xen/include/asm-x86/vmx.h Thu Sep 1 21:30:51 2005 +++ b/xen/include/asm-x86/vmx.h Fri Sep 2 08:39:08 2005 @@ -471,4 +471,7 @@ void load_cpu_user_regs(struct cpu_user_regs *regs); void store_cpu_user_regs(struct cpu_user_regs *regs); +enum { VMX_COPY_IN = 0, VMX_COPY_OUT }; +int vmx_copy(void *buf, unsigned long laddr, int size, int dir); + #endif /* __ASM_X86_VMX_H__ */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel