ia64/xen-unstable

changeset 12569:cdd9e366aa59

[HVM] Unaligned write to a PTE is a good indication the
page is no longer a page table.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Nov 24 14:37:45 2006 +0000 (2006-11-24)
parents a1441f389dc1
children 074b4b34e049
files xen/arch/x86/mm/shadow/multi.c
line diff
     1.1 --- a/xen/arch/x86/mm/shadow/multi.c	Fri Nov 24 14:05:59 2006 +0000
     1.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Fri Nov 24 14:37:45 2006 +0000
     1.3 @@ -3823,13 +3823,10 @@ static inline void * emulate_map_dest(st
     1.4          v->arch.shadow.propagate_fault = 1;
     1.5          return NULL;
     1.6      }
     1.7 -    
     1.8 -    if ( !valid_mfn(mfn) )
     1.9 -    {
    1.10 -        /* Attempted a write to a bad gfn.  This should never happen:
    1.11 -         * after all, we're here because this write is to a page table. */
    1.12 -        BUG();
    1.13 -    }
    1.14 +
    1.15 +    /* Attempted a write to a bad gfn? This should never happen:
    1.16 +     * after all, we're here because this write is to a page table. */
    1.17 +    BUG_ON(!valid_mfn(mfn));
    1.18  
    1.19      ASSERT(sh_mfn_is_a_page_table(mfn));
    1.20      *mfnp = mfn;
    1.21 @@ -3840,27 +3837,26 @@ int
    1.22  sh_x86_emulate_write(struct vcpu *v, unsigned long vaddr, void *src,
    1.23                        u32 bytes, struct x86_emulate_ctxt *ctxt)
    1.24  {
    1.25 +    mfn_t mfn;
    1.26 +    void *addr;
    1.27 +
    1.28 +    if ( vaddr & (bytes-1) )
    1.29 +        return X86EMUL_UNHANDLEABLE;
    1.30 +
    1.31      ASSERT(shadow_lock_is_acquired(v->domain));
    1.32 -    while ( bytes > 0 )
    1.33 -    {
    1.34 -        mfn_t mfn;
    1.35 -        int bytes_on_page;
    1.36 -        void *addr;
    1.37 -
    1.38 -        bytes_on_page = PAGE_SIZE - (vaddr & ~PAGE_MASK);
    1.39 -        if ( bytes_on_page > bytes )
    1.40 -            bytes_on_page = bytes;
    1.41 -
    1.42 -        if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
    1.43 -            return X86EMUL_PROPAGATE_FAULT;
    1.44 -        memcpy(addr, src, bytes_on_page);
    1.45 -        shadow_validate_guest_pt_write(v, mfn, addr, bytes_on_page);
    1.46 -        bytes -= bytes_on_page;
    1.47 -        /* If we are writing zeros to this page, might want to unshadow */
    1.48 -        if ( likely(bytes_on_page >= 4) && (*(u32 *)addr == 0) )
    1.49 -            check_for_early_unshadow(v, mfn);
    1.50 -        sh_unmap_domain_page(addr);
    1.51 -    }
    1.52 +    ASSERT(((vaddr & ~PAGE_MASK) + bytes) <= PAGE_SIZE);
    1.53 +
    1.54 +    if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
    1.55 +        return X86EMUL_PROPAGATE_FAULT;
    1.56 +
    1.57 +    memcpy(addr, src, bytes);
    1.58 +    shadow_validate_guest_pt_write(v, mfn, addr, bytes);
    1.59 +
    1.60 +    /* If we are writing zeros to this page, might want to unshadow */
    1.61 +    if ( likely(bytes >= 4) && (*(u32 *)addr == 0) )
    1.62 +        check_for_early_unshadow(v, mfn);
    1.63 +
    1.64 +    sh_unmap_domain_page(addr);
    1.65      shadow_audit_tables(v);
    1.66      return X86EMUL_CONTINUE;
    1.67  }
    1.68 @@ -3876,12 +3872,15 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
    1.69      int rv = X86EMUL_CONTINUE;
    1.70  
    1.71      ASSERT(shadow_lock_is_acquired(v->domain));
    1.72 -    ASSERT(bytes <= sizeof (unsigned long));
    1.73 +    ASSERT(bytes <= sizeof(unsigned long));
    1.74 +
    1.75 +    if ( vaddr & (bytes-1) )
    1.76 +        return X86EMUL_UNHANDLEABLE;
    1.77  
    1.78      if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
    1.79          return X86EMUL_PROPAGATE_FAULT;
    1.80  
    1.81 -    switch (bytes) 
    1.82 +    switch ( bytes )
    1.83      {
    1.84      case 1: prev = cmpxchg(((u8 *)addr), old, new);  break;
    1.85      case 2: prev = cmpxchg(((u16 *)addr), old, new); break;
    1.86 @@ -3892,7 +3891,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
    1.87          prev = ~old;
    1.88      }
    1.89  
    1.90 -    if ( (prev == old)  )
    1.91 +    if ( prev == old )
    1.92          shadow_validate_guest_pt_write(v, mfn, addr, bytes);
    1.93      else
    1.94          rv = X86EMUL_CMPXCHG_FAILED;
    1.95 @@ -3923,6 +3922,9 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
    1.96  
    1.97      ASSERT(shadow_lock_is_acquired(v->domain));
    1.98  
    1.99 +    if ( vaddr & 7 )
   1.100 +        return X86EMUL_UNHANDLEABLE;
   1.101 +
   1.102      if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
   1.103          return X86EMUL_PROPAGATE_FAULT;
   1.104  
   1.105 @@ -3930,7 +3932,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
   1.106      new = (((u64) new_hi) << 32) | (u64) new_lo;
   1.107      prev = cmpxchg(((u64 *)addr), old, new);
   1.108  
   1.109 -    if ( (prev == old)  )
   1.110 +    if ( prev == old )
   1.111          shadow_validate_guest_pt_write(v, mfn, addr, 8);
   1.112      else
   1.113          rv = X86EMUL_CMPXCHG_FAILED;