ia64/xen-unstable

changeset 5267:6c89d5f8c629

bitkeeper revision 1.1633 (429ebf697h76hFAG0kPyIQgpATAdnw)

[PATCH] vmx-mmio-2pages.patch

Handle the case where the MMIO instruction crosses a page boundary.

Signed-off-by: Arun Sharma <arun.sharma@intel.com>
author arun.sharma@intel.com[kaf24]
date Thu Jun 02 08:12:25 2005 +0000 (2005-06-02)
parents 5bb481c21157
children 061fa5a23248
files xen/arch/x86/vmx_platform.c
line diff
     1.1 --- a/xen/arch/x86/vmx_platform.c	Thu Jun 02 08:10:58 2005 +0000
     1.2 +++ b/xen/arch/x86/vmx_platform.c	Thu Jun 02 08:12:25 2005 +0000
     1.3 @@ -406,35 +406,49 @@ static int vmx_decode(const unsigned cha
     1.4      return DECODE_failure;
     1.5  }
     1.6  
     1.7 -int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip, int inst_len)
     1.8 +int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
     1.9 +                         int inst_len)
    1.10  {
    1.11      l1_pgentry_t gpte;
    1.12      unsigned long mfn;
    1.13      unsigned long ma;
    1.14      unsigned char * inst_start;
    1.15 +    int remaining = 0;
    1.16          
    1.17      if (inst_len > MAX_INST_LEN || inst_len <= 0) {
    1.18          return 0;
    1.19      }
    1.20  
    1.21 -    if ((guest_eip & PAGE_MASK) == ((guest_eip + inst_len) & PAGE_MASK)) {
    1.22 -        if (vmx_paging_enabled(current)) {
    1.23 -                gpte = gva_to_gpte(guest_eip);
    1.24 -                mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
    1.25 -        } else {
    1.26 -                mfn = phys_to_machine_mapping(guest_eip >> PAGE_SHIFT);
    1.27 +    if (vmx_paging_enabled(current)) {
    1.28 +        gpte = gva_to_gpte(guest_eip);
    1.29 +        mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
    1.30 +        /* Does this cross a page boundary ? */
    1.31 +        if ((guest_eip & PAGE_MASK) != ((guest_eip + inst_len) & PAGE_MASK)) {
    1.32 +            remaining = (guest_eip + inst_len) & ~PAGE_MASK;
    1.33 +            inst_len -= remaining;
    1.34          }
    1.35 -        ma = (mfn << PAGE_SHIFT) | (guest_eip & (PAGE_SIZE - 1));
    1.36 +
    1.37 +    } else {
    1.38 +        mfn = phys_to_machine_mapping(guest_eip >> PAGE_SHIFT);
    1.39 +    }
    1.40 +    ma = (mfn << PAGE_SHIFT) | (guest_eip & (PAGE_SIZE - 1));
    1.41 +    inst_start = (unsigned char *)map_domain_mem(ma);
    1.42 +                
    1.43 +    memcpy((char *)buf, inst_start, inst_len);
    1.44 +    unmap_domain_mem(inst_start);
    1.45 +
    1.46 +    if (remaining) {
    1.47 +        gpte = gva_to_gpte(guest_eip+inst_len+remaining);
    1.48 +        mfn = phys_to_machine_mapping(l1e_get_pfn(gpte));
    1.49 +
    1.50 +        ma = (mfn << PAGE_SHIFT);
    1.51          inst_start = (unsigned char *)map_domain_mem(ma);
    1.52                  
    1.53 -        memcpy((char *)buf, inst_start, inst_len);
    1.54 +        memcpy((char *)buf+inst_len, inst_start, remaining);
    1.55          unmap_domain_mem(inst_start);
    1.56 -    } else {
    1.57 -        // Todo: In two page frames
    1.58 -        BUG();
    1.59 +
    1.60      }
    1.61 -        
    1.62 -    return inst_len;
    1.63 +    return inst_len+remaining;
    1.64  }
    1.65  
    1.66  static void init_instruction(struct instruction *mmio_inst)