From mboxrd@z Thu Jan 1 00:00:00 1970 From: Scott Parish Subject: Re: PAE xen + linux kernel boots ... Date: Sun, 1 May 2005 08:12:07 +0000 Message-ID: <20050501081207.GF16883@us.ibm.com> References: <20050425172624.GB22076@bytesex> <87ll74o29m.fsf@bytesex.org> <20050430090117.GC16883@us.ibm.com> <20050430095123.GE16883@us.ibm.com> <882ab72161e92b3470da1a3ce14b7a3b@cl.cam.ac.uk> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="jy6Sn24JjFx/iggw" Return-path: Content-Disposition: inline In-Reply-To: <882ab72161e92b3470da1a3ce14b7a3b@cl.cam.ac.uk> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: Keir Fraser Cc: Gerd Knorr , xen-devel@lists.xensource.com, Scott Parish List-Id: xen-devel@lists.xenproject.org --jy6Sn24JjFx/iggw Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sat, Apr 30, 2005 at 11:54:06AM +0100, Keir Fraser wrote: > > On 30 Apr 2005, at 10:51, Scott Parish wrote: > > >Switch to xen, which is going to emulate some instructions and fake > >the writing. We eventually end up in ptwr_emulated_update(), who among > >other things, tries to copy the full l1_pgentry_t (64bits), but from > >the 4 byte offset, that is the 4 high bytes and then 4 bytes of > >undefined memory that may even be in another page. > > There's code in the 32-bit ptwr_emulated_update() to turn a sub-pte > access into a full-pte access. Either this is missing/broken in the > 64-bit version, or the emulator is broken and passing the wrong > operand size. The bitshifting stuff in ptwr_emulated_update() had some problems, although its possible that it somehow worked for whatever cases it was needed for before. Adding a physaddr_t, and fixing the bitshifting took care of the problem. While i was at it, i wired up support for cmpxchg8b emulation under PAE, and then tried to use set_pte_atomic(). That didn't quite do the trick, but killing the machine_to_physical() conversion in pte_val() got things working. I was getting to dom0 prompt under the pae 5th patch release, testing my patches under the 6th, the kernel fell apart in very late boot. Haven't looked into this just yet. sRp -- Scott Parish --jy6Sn24JjFx/iggw Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="ptwr-em-up.diff" 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. */ --jy6Sn24JjFx/iggw Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="bez-m2p.diff" --- include/asm-xen/asm-i386/page.h.orig 2005-05-01 07:08:44.000000000 +0000 +++ include/asm-xen/asm-i386/page.h 2005-05-01 07:21:09.000000000 +0000 @@ -92,18 +92,7 @@ typedef struct { unsigned long long pgpr (((_x)&1) ? ((pgd_t) {phys_to_machine(_x)}) : ((pgd_t) {(_x)})); }) #define __pmd(x) ({ unsigned long long _x = (x); \ (((_x)&1) ? ((pmd_t) {phys_to_machine(_x)}) : ((pmd_t) {(_x)})); }) -static inline unsigned long long pte_val(pte_t x) -{ - unsigned long long ret; - - if (x.pte_low) { - ret = x.pte_low | (unsigned long long)x.pte_high << 32; - ret = machine_to_phys(ret) | 1; - } else { - ret = 0; - } - return ret; -} +#define pte_val(x) ((x).pte_low | (unsigned long long)(x).pte_high << 32) static inline unsigned long long pmd_val(pmd_t x) { unsigned long long ret = x.pmd; --jy6Sn24JjFx/iggw Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --jy6Sn24JjFx/iggw--