diff -rN -u -p old-xen-unstable-1/xen/arch/x86/mm.c new-xen-unstable-1/xen/arch/x86/mm.c --- old-xen-unstable-1/xen/arch/x86/mm.c 2005-04-30 08:42:30.000000000 +0000 +++ new-xen-unstable-1/xen/arch/x86/mm.c 2005-05-01 07:24:40.000000000 +0000 @@ -2768,8 +2768,8 @@ void ptwr_flush(struct domain *d, const static int ptwr_emulated_update( unsigned long addr, - unsigned long old, - unsigned long val, + physaddr_t old, + physaddr_t val, unsigned int bytes, unsigned int do_cmpxchg) { @@ -2787,21 +2787,22 @@ static int ptwr_emulated_update( } /* Turn a sub-word access into a full-word access. */ - /* FIXME: needs tweaks for PAE */ - if ( (addr & ((BITS_PER_LONG/8)-1)) != 0 ) + if (bytes != sizeof(physaddr_t)) { int rc; - unsigned long full; - unsigned int mask = addr & ((BITS_PER_LONG/8)-1); + physaddr_t full; + unsigned int offset = addr & (sizeof(physaddr_t)-1); + /* Align address; read full word. */ - addr &= ~((BITS_PER_LONG/8)-1); - if ( (rc = x86_emulate_read_std(addr, &full, BITS_PER_LONG/8)) ) - return rc; + addr &= ~(sizeof(physaddr_t)-1); + if ( (rc = x86_emulate_read_std(addr, (unsigned long *)&full, + sizeof(physaddr_t))) ) + return rc; /* Mask out bits provided by caller. */ - full &= ~((1UL << (bytes*8)) - 1UL) << (mask*8); + full &= ~((((physaddr_t)1 << (bytes*8)) - 1) << (offset*8)); /* Shift the caller value and OR in the missing bits. */ - val &= (1UL << (bytes*8)) - 1UL; - val <<= mask*8; + val &= (((physaddr_t)1 << (bytes*8)) - 1); + val <<= (offset)*8; val |= full; } @@ -2889,11 +2890,29 @@ static int ptwr_emulated_cmpxchg( return ptwr_emulated_update(addr, old, new, bytes, 1); } +#if defined(CONFIG_X86_PAE) +static int ptwr_emulated_cmpxchg8b( + unsigned long addr, + unsigned long old, + unsigned long old_hi, + unsigned long new, + unsigned long new_hi) +{ + return ptwr_emulated_update(addr, + (u64)old_hi << sizeof(old_hi)*8 | old, + (u64)new_hi << sizeof(new_hi)*8 | new, + sizeof(u64), 1); +} +#endif + static struct x86_mem_emulator ptwr_mem_emulator = { .read_std = x86_emulate_read_std, .write_std = x86_emulate_write_std, .read_emulated = x86_emulate_read_std, .write_emulated = ptwr_emulated_write, +#if defined(CONFIG_X86_PAE) + .cmpxchg8b_emulated = ptwr_emulated_cmpxchg8b, +#endif .cmpxchg_emulated = ptwr_emulated_cmpxchg }; diff -rN -u -p old-xen-unstable-1/xen/include/asm-x86/types.h new-xen-unstable-1/xen/include/asm-x86/types.h --- old-xen-unstable-1/xen/include/asm-x86/types.h 2005-04-04 22:03:05.000000000 +0000 +++ new-xen-unstable-1/xen/include/asm-x86/types.h 2005-05-01 01:25:20.000000000 +0000 @@ -44,11 +44,17 @@ typedef signed long long s64; typedef unsigned long long u64; #define BITS_PER_LONG 32 typedef unsigned int size_t; +#if defined(CONFIG_X86_PAE) +typedef u64 physaddr_t; +#else +typedef u32 physaddr_t; +#endif #elif defined(__x86_64__) typedef signed long s64; typedef unsigned long u64; #define BITS_PER_LONG 64 typedef unsigned long size_t; +typedef u64 physaddr_t; #endif /* DMA addresses come in generic and 64-bit flavours. */