ia64/xen-unstable

changeset 6609:151da8f5d5f2

Handle page overlapping copies.

Signed-Off-By: Leendert van Doorn <leendert@watson.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Sep 02 17:53:04 2005 +0000 (2005-09-02)
parents b715a9f4dba0
children 7557c46a9edf
files xen/arch/x86/vmx.c xen/include/asm-x86/vmx.h
line diff
     1.1 --- a/xen/arch/x86/vmx.c	Fri Sep 02 17:52:37 2005 +0000
     1.2 +++ b/xen/arch/x86/vmx.c	Fri Sep 02 17:53:04 2005 +0000
     1.3 @@ -699,29 +699,34 @@ static void vmx_io_instruction(struct cp
     1.4      vmx_wait_io();
     1.5  }
     1.6  
     1.7 -enum { COPY_IN = 0, COPY_OUT };
     1.8 -
     1.9 -static inline int
    1.10 +int
    1.11  vmx_copy(void *buf, unsigned long laddr, int size, int dir)
    1.12  {
    1.13 +    unsigned long mfn;
    1.14      char *addr;
    1.15 -    unsigned long mfn;
    1.16 +    int count;
    1.17  
    1.18 -    if ( (size + (laddr & (PAGE_SIZE - 1))) >= PAGE_SIZE )
    1.19 -    {
    1.20 -    	printf("vmx_copy exceeds page boundary\n");
    1.21 -        return 0;
    1.22 +    while (size > 0) {
    1.23 +	count = PAGE_SIZE - (laddr & ~PAGE_MASK);
    1.24 +	if (count > size)
    1.25 +	    count = size;
    1.26 +
    1.27 +	mfn = get_mfn_from_pfn(laddr >> PAGE_SHIFT);
    1.28 +	/* XXX check whether laddr is valid */
    1.29 +	addr = (char *)map_domain_page(mfn) + (laddr & ~PAGE_MASK);
    1.30 +
    1.31 +	if (dir == VMX_COPY_IN)
    1.32 +	    memcpy(buf, addr, count);
    1.33 +	else
    1.34 +	    memcpy(addr, buf, count);
    1.35 +
    1.36 +	unmap_domain_page(addr);
    1.37 +
    1.38 +	laddr += count;
    1.39 +	buf += count;
    1.40 +	size -= count;
    1.41      }
    1.42  
    1.43 -    mfn = get_mfn_from_pfn(laddr >> PAGE_SHIFT);
    1.44 -    addr = (char *)map_domain_page(mfn) + (laddr & ~PAGE_MASK);
    1.45 -
    1.46 -    if (dir == COPY_IN)
    1.47 -	    memcpy(buf, addr, size);
    1.48 -    else
    1.49 -	    memcpy(addr, buf, size);
    1.50 -
    1.51 -    unmap_domain_page(addr);
    1.52      return 1;
    1.53  }
    1.54  
    1.55 @@ -908,7 +913,7 @@ vmx_assist(struct vcpu *d, int mode)
    1.56      u32 cp;
    1.57  
    1.58      /* make sure vmxassist exists (this is not an error) */
    1.59 -    if (!vmx_copy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), COPY_IN))
    1.60 +    if (!vmx_copy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), VMX_COPY_IN))
    1.61      	return 0;
    1.62      if (magic != VMXASSIST_MAGIC)
    1.63      	return 0;
    1.64 @@ -922,20 +927,20 @@ vmx_assist(struct vcpu *d, int mode)
    1.65       */
    1.66      case VMX_ASSIST_INVOKE:
    1.67  	/* save the old context */
    1.68 -	if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), COPY_IN))
    1.69 +	if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), VMX_COPY_IN))
    1.70      	    goto error;
    1.71  	if (cp != 0) {
    1.72      	    if (!vmx_world_save(d, &c))
    1.73  		goto error;
    1.74 -	    if (!vmx_copy(&c, cp, sizeof(c), COPY_OUT))
    1.75 +	    if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_OUT))
    1.76  		goto error;
    1.77  	}
    1.78  
    1.79  	/* restore the new context, this should activate vmxassist */
    1.80 -	if (!vmx_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), COPY_IN))
    1.81 +	if (!vmx_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), VMX_COPY_IN))
    1.82  	    goto error;
    1.83  	if (cp != 0) {
    1.84 -            if (!vmx_copy(&c, cp, sizeof(c), COPY_IN))
    1.85 +            if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_IN))
    1.86  		goto error;
    1.87      	    if (!vmx_world_restore(d, &c))
    1.88  		goto error;
    1.89 @@ -949,10 +954,10 @@ vmx_assist(struct vcpu *d, int mode)
    1.90       */
    1.91      case VMX_ASSIST_RESTORE:
    1.92  	/* save the old context */
    1.93 -	if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), COPY_IN))
    1.94 +	if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), VMX_COPY_IN))
    1.95      	    goto error;
    1.96  	if (cp != 0) {
    1.97 -            if (!vmx_copy(&c, cp, sizeof(c), COPY_IN))
    1.98 +            if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_IN))
    1.99  		goto error;
   1.100      	    if (!vmx_world_restore(d, &c))
   1.101  		goto error;
     2.1 --- a/xen/include/asm-x86/vmx.h	Fri Sep 02 17:52:37 2005 +0000
     2.2 +++ b/xen/include/asm-x86/vmx.h	Fri Sep 02 17:53:04 2005 +0000
     2.3 @@ -471,4 +471,7 @@ static inline int iopacket_port(struct d
     2.4  void load_cpu_user_regs(struct cpu_user_regs *regs);
     2.5  void store_cpu_user_regs(struct cpu_user_regs *regs);
     2.6  
     2.7 +enum { VMX_COPY_IN = 0, VMX_COPY_OUT };
     2.8 +int vmx_copy(void *buf, unsigned long laddr, int size, int dir);
     2.9 +
    2.10  #endif /* __ASM_X86_VMX_H__ */