# HG changeset patch # User Ian Campbell # Date 1213025142 -3600 # Node ID a332c718c1b6fad787bf2a93a0c172719ffa3119 # Parent db466cd3412c0c383b1a4a9f4a1952baa9ad42bc Allow older PAE Linux guests to access entire compat m2p. Older PAE guests (prior to xen-unstable.hg 8924:229c602a075a, Feb 2006, this includes some vendor's kernel in the field) use a limit of 0xf6800000 on their code and data segments (i.e. up to the end of the read-only m2p table). Newer kernels use a limit of 4G and rely on the hypervisor to clamp to the actual maximum allowed. 32on64 mode takes advantage of this to allow a larger m2p than would fit in the PAEonPAE sized hole. This means that PAE guests with the hardcoded low limit cannot run on top of a 64 bit hypervisor on a host machine which has more than 16G of RAM. Fix this by extending any code or data segment which ends above the start of the hypervisor hole for that guest. Signed-off-by: Ian Campbell diff -r db466cd3412c -r a332c718c1b6 xen/arch/x86/x86_64/mm.c --- a/xen/arch/x86/x86_64/mm.c Mon Jun 09 15:06:26 2008 +0100 +++ b/xen/arch/x86/x86_64/mm.c Mon Jun 09 16:25:42 2008 +0100 @@ -402,8 +402,34 @@ int check_descriptor(const struct domain /* All code and data segments are okay. No base/limit checking. */ if ( (b & _SEGMENT_S) ) { - if ( is_pv_32bit_domain(dom) && (b & _SEGMENT_L) ) - goto bad; + if ( is_pv_32bit_domain(dom) ) + { + unsigned long base, limit; + + if ( b & _SEGMENT_L ) + goto bad; + + /* + * Older PAE Linux guests use segments which are limited to + * 0xf6800000. Extend these to allow access to the larger read-only + * M2P table available in 32on64 mode. + */ + base = (b&(0xff<<24)) | ((b&0xff)<<16) | (a>>16); + + limit = (b&0xf0000) | (a&0xffff); + limit++; /* We add one because limit is inclusive. */ + + if ( (b & _SEGMENT_G) ) + limit <<= 12; + + if ( base == 0 && limit > HYPERVISOR_COMPAT_VIRT_START(dom) && limit < 0x100000000UL ) + { + a |= 0x0000ffff; + b |= 0x000f0000; + } + + } + goto good; }