ia64/xen-unstable

changeset 2094:8e0d9e45c5f7

bitkeeper revision 1.1154 (4112b45dWwkFmdda2Kbef4LU3kxWcw)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/xeno
author kaf24@scramble.cl.cam.ac.uk
date Thu Aug 05 22:27:41 2004 +0000 (2004-08-05)
parents b6d46f6caea5 e8ef06e458e1
children b6006dac0b1a
files linux-2.4.26-xen-sparse/arch/xen/kernel/traps.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c linux-2.6.7-xen-sparse/arch/xen/kernel/evtchn.c linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h
line diff
     1.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/traps.c	Thu Aug 05 16:40:56 2004 +0000
     1.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/traps.c	Thu Aug 05 22:27:41 2004 +0000
     1.3 @@ -449,8 +449,8 @@ void math_error(void *eip)
     1.4  		default:
     1.5  			break;
     1.6  		case 0x001: /* Invalid Op */
     1.7 -		case 0x040: /* Stack Fault */
     1.8 -		case 0x240: /* Stack Fault | Direction */
     1.9 +		case 0x041: /* Stack Fault */
    1.10 +		case 0x241: /* Stack Fault | Direction */
    1.11  			info.si_code = FPE_FLTINV;
    1.12  			break;
    1.13  		case 0x002: /* Denormalize */
     2.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c	Thu Aug 05 16:40:56 2004 +0000
     2.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/setup.c	Thu Aug 05 22:27:41 2004 +0000
     2.3 @@ -137,8 +137,10 @@ static struct resource data_resource = {
     2.4   * page as soon as fixmap is up and running.
     2.5   */
     2.6  shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
     2.7 +EXPORT_SYMBOL(HYPERVISOR_shared_info);
     2.8  
     2.9  unsigned long *phys_to_machine_mapping;
    2.10 +EXPORT_SYMBOL(phys_to_machine_mapping);
    2.11  
    2.12  multicall_entry_t multicall_list[8];
    2.13  int nr_multicall_ents = 0;
     3.1 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c	Thu Aug 05 16:40:56 2004 +0000
     3.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/traps.c	Thu Aug 05 22:27:41 2004 +0000
     3.3 @@ -722,8 +722,8 @@ void math_error(void *eip)
     3.4  		default:
     3.5  			break;
     3.6  		case 0x001: /* Invalid Op */
     3.7 -		case 0x040: /* Stack Fault XXX? */
     3.8 -		case 0x240: /* Stack Fault | Direction XXX? */
     3.9 +		case 0x041: /* Stack Fault */
    3.10 +		case 0x241: /* Stack Fault | Direction */
    3.11  			info.si_code = FPE_FLTINV;
    3.12  			/* Should we clear the SF or let user space do it ???? */
    3.13  			break;
     4.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/evtchn.c	Thu Aug 05 16:40:56 2004 +0000
     4.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/evtchn.c	Thu Aug 05 22:27:41 2004 +0000
     4.3 @@ -7,6 +7,7 @@
     4.4   */
     4.5  
     4.6  #include <linux/config.h>
     4.7 +#include <linux/module.h>
     4.8  #include <linux/irq.h>
     4.9  #include <linux/interrupt.h>
    4.10  #include <linux/sched.h>
    4.11 @@ -81,7 +82,7 @@ void evtchn_do_upcall(struct pt_regs *re
    4.12  
    4.13      local_irq_restore(flags);
    4.14  }
    4.15 -
    4.16 +EXPORT_SYMBOL(evtchn_do_upcall);
    4.17  
    4.18  static int find_unbound_irq(void)
    4.19  {
     5.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c	Thu Aug 05 16:40:56 2004 +0000
     5.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c	Thu Aug 05 22:27:41 2004 +0000
     5.3 @@ -23,9 +23,400 @@
     5.4   */
     5.5  
     5.6  #include <linux/config.h>
     5.7 +#include <linux/init.h>
     5.8  #include <linux/sched.h>
     5.9  #include <linux/kernel.h>
    5.10 +#include <linux/highmem.h>
    5.11 +#include <asm/fixmap.h>
    5.12 +#include <asm/pgtable.h>
    5.13 +#include <asm/uaccess.h>
    5.14 +
    5.15 +#if 0
    5.16 +#define ASSERT(_p) \
    5.17 +    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
    5.18 +    __LINE__, __FILE__); *(int*)0=0; }
    5.19 +#define DPRINTK(_f, _a...) printk(KERN_ALERT \
    5.20 +                           "(file=%s, line=%d, eip=%08lx) " _f "\n", \
    5.21 +                           __FILE__ , __LINE__ , eip, ## _a )
    5.22 +#else
    5.23 +#define ASSERT(_p) ((void)0)
    5.24 +#define DPRINTK(_f, _a...) ((void)0)
    5.25 +#endif
    5.26 +
    5.27 +struct fixup_entry {
    5.28 +    unsigned long  patch_addr;
    5.29 +    unsigned char  patched_code[20];
    5.30 +    unsigned short patched_code_len;
    5.31 +    unsigned short fixup_idx;
    5.32 +    struct fixup_entry *next;
    5.33 +};
    5.34 +
    5.35 +#define FIXUP_HASHSZ 128
    5.36 +static struct fixup_entry *fixup_hash[FIXUP_HASHSZ];
    5.37 +#define FIXUP_HASH(_a) ((unsigned int)(_a) & (FIXUP_HASHSZ-1))
    5.38 +
    5.39 +#define INSN_SUFFIX_BYTES (7)
    5.40 +#define PREFIX_BYTE       (1<<3)
    5.41 +#define OPCODE_BYTE       (1<<4)  
    5.42 +#define HAS_MODRM         (1<<5)
    5.43 +
    5.44 +#define X  0 /* invalid */
    5.45 +#define P  PREFIX_BYTE
    5.46 +#define O  OPCODE_BYTE
    5.47 +#define M  HAS_MODRM
    5.48 +
    5.49 +static unsigned char insn_decode[256] = {
    5.50 +    /* 0x00 - 0x0F */
    5.51 +    O|M, O|M, O|M, O|M, O|1, O|4, O, O,
    5.52 +    O|M, O|M, O|M, O|M, O|1, O|4, O, X,
    5.53 +    /* 0x10 - 0x1F */
    5.54 +    O|M, O|M, O|M, O|M, O|1, O|4, O, O,
    5.55 +    O|M, O|M, O|M, O|M, O|1, O|4, O, O,
    5.56 +    /* 0x20 - 0x2F */
    5.57 +    O|M, O|M, O|M, O|M, O|1, O|4, P, O,
    5.58 +    O|M, O|M, O|M, O|M, O|1, O|4, P, O,
    5.59 +    /* 0x30 - 0x3F */
    5.60 +    O|M, O|M, O|M, O|M, O|1, O|4, P, O,
    5.61 +    O|M, O|M, O|M, O|M, O|1, O|4, P, O,
    5.62 +    /* 0x40 - 0x4F */
    5.63 +    O, O, O, O, O, O, O, O,
    5.64 +    O, O, O, O, O, O, O, O,
    5.65 +    /* 0x50 - 0x5F */
    5.66 +    O, O, O, O, O, O, O, O,
    5.67 +    O, O, O, O, O, O, O, O,
    5.68 +    /* 0x60 - 0x6F */
    5.69 +    O, O, O|M, O|M, P, P, X, X,
    5.70 +    O|4, O|M|4, O|1, O|M|1, O, O, O, O,
    5.71 +    /* 0x70 - 0x7F */
    5.72 +    O|1, O|1, O|1, O|1, O|1, O|1, O|1, O|1,
    5.73 +    O|1, O|1, O|1, O|1, O|1, O|1, O|1, O|1,
    5.74 +    /* 0x80 - 0x8F */
    5.75 +    O|M|1, O|M|4, O|M|1, O|M|1, O|M, O|M, O|M, O|M,
    5.76 +    O|M, O|M, O|M, O|M, O|M, O|M, O|M, O|M, 
    5.77 +    /* 0x90 - 0x9F */
    5.78 +    O, O, O, O, O, O, O, O,
    5.79 +    O, O, X, O, O, O, O, O,
    5.80 +    /* 0xA0 - 0xAF */
    5.81 +    O|1, O|4, O|1, O|4, O, O, O, O,
    5.82 +    O|1, O|4, O, O, O, O, O, O,
    5.83 +    /* 0xB0 - 0xBF */
    5.84 +    O|1, O|1, O|1, O|1, O|1, O|1, O|1, O|1,
    5.85 +    O|4, O|4, O|4, O|4, O|4, O|4, O|4, O|4,
    5.86 +    /* 0xC0 - 0xCF */
    5.87 +    O|M|1, O|M|1, X, O, X, X, O|M|1, O|M|4,
    5.88 +    X, X, X, X, X, X, X, X,
    5.89 +    /* 0xD0 - 0xDF */
    5.90 +    O|M, O|M, O|M, O|M, O|1, O|1, X, X,
    5.91 +    X, X, X, X, X, X, X, X,
    5.92 +    /* 0xE0 - 0xEF */
    5.93 +    X, X, X, X, X, X, X, X,
    5.94 +    X, X, X, O|1, X, X, X, X,
    5.95 +    /* 0xF0 - 0xFF */
    5.96 +    P, X, P, P, O, O, O|M|1, O|M|4, 
    5.97 +    O, O, O, O, O, O, O|M, O|M
    5.98 +};
    5.99 +
   5.100 +static unsigned int get_insn_len(unsigned char *insn, unsigned char *p_opcode)
   5.101 +{
   5.102 +    unsigned char b, d, *pb, mod, rm;
   5.103 +
   5.104 +    /* 1. Step over the prefix bytes. */
   5.105 +    for ( pb = insn; (pb - insn) < 4; pb++ )
   5.106 +    {
   5.107 +        b = *pb;
   5.108 +        d = insn_decode[b];
   5.109 +        if ( !(d & PREFIX_BYTE) )
   5.110 +            break;
   5.111 +    }
   5.112 +
   5.113 +    *p_opcode = b;
   5.114 +
   5.115 +    /* 2. Ensure we have a valid opcode byte. */
   5.116 +    if ( !(d & OPCODE_BYTE) )
   5.117 +    {
   5.118 +        printk(KERN_ALERT " !!! 0x%02x 0x%02x\n", b, *(pb+1));
   5.119 +        return 0;
   5.120 +    }
   5.121 +
   5.122 +    /* 3. Process Mod/RM if there is one. */
   5.123 +    if ( d & HAS_MODRM )
   5.124 +    {
   5.125 +        b = *(++pb);
   5.126 +        if ( (mod = (b >> 6) & 3) != 3 )
   5.127 +        {           
   5.128 +            if ( (rm = (b >> 0) & 7) == 4 )
   5.129 +                pb += 1; /* SIB byte */
   5.130 +            switch ( mod )
   5.131 +            {
   5.132 +            case 0:
   5.133 +                if ( rm == 5 )
   5.134 +                    pb += 4; /* disp32 */
   5.135 +                break;
   5.136 +            case 1:
   5.137 +                pb += 1; /* disp8 */
   5.138 +                break;
   5.139 +            case 2:
   5.140 +                pb += 4; /* disp32 */
   5.141 +                break;
   5.142 +            }
   5.143 +        }
   5.144 +    }
   5.145 +
   5.146 +    /* 4. All done. Result is all byte sstepped over, plus any immediates. */
   5.147 +    return ((pb - insn) + 1 + (d & INSN_SUFFIX_BYTES));
   5.148 +}
   5.149  
   5.150  asmlinkage void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
   5.151  {
   5.152 +    static unsigned int fixup_idx = 0;
   5.153 +    int relbyte_idx = -1;
   5.154 +    unsigned int insn_len = (unsigned int)error_code, new_insn_len;
   5.155 +    unsigned char b[20], modrm, mod, reg, rm, *fixup_buf, patch[5], opcode;
   5.156 +    unsigned long fixup_buf_user, eip = regs->eip - insn_len;
   5.157 +    struct fixup_entry *fe;
   5.158 +    pte_t *pte;
   5.159 +    pmd_t *pmd;
   5.160 +    pgd_t *pgd;
   5.161 +    void *veip;
   5.162 +
   5.163 +    return; /* XXX */
   5.164 +
   5.165 +    /* Easy check that code segment has base 0, max limit. */
   5.166 +    if ( unlikely(regs->xcs != __USER_CS) )
   5.167 +    {
   5.168 +        DPRINTK("Unexpected CS value.");
   5.169 +        return;
   5.170 +    }
   5.171 +
   5.172 +    if ( unlikely(eip >= (PAGE_OFFSET-32)) )
   5.173 +    {
   5.174 +        DPRINTK("User executing out of kernel space?!");
   5.175 +        return;
   5.176 +    }
   5.177 +
   5.178 +    if ( unlikely(((eip ^ (eip+5)) & PAGE_MASK) != 0) )
   5.179 +    {
   5.180 +        DPRINTK("Patch instruction would straddle a page boundary.");
   5.181 +        return;
   5.182 +    }
   5.183 +
   5.184 +    /* Guaranteed enough room to patch? */
   5.185 +    if ( unlikely(fixup_idx > (PAGE_SIZE-32)) )
   5.186 +    {
   5.187 +        DPRINTK("Out of room in fixup page.");
   5.188 +        return;
   5.189 +    }
   5.190 +
   5.191 +    if ( unlikely(copy_from_user(b, (void *)eip, sizeof(b)) != 0) )
   5.192 +    {
   5.193 +        DPRINTK("Could not read instruction bytes from user space.");
   5.194 +        return;
   5.195 +    }
   5.196 +
   5.197 +    /* Must be 'mov %gs:m32,r32' or 'mov r32,%gs:m32'. */
   5.198 +    if ( (b[0] != 0x65) || ((b[1] != 0x89) && (b[1] != 0x8b)) )
   5.199 +    {
   5.200 +        DPRINTK("No GS override, or not a MOV (%02x %02x).", b[0], b[1]);
   5.201 +        return;
   5.202 +    }
   5.203 +
   5.204 +    modrm = b[2];
   5.205 +    mod   = (modrm >> 6) & 3;
   5.206 +    reg   = (modrm >> 3) & 7;
   5.207 +    rm    = (modrm >> 0) & 7;
   5.208 +
   5.209 +    /* We don't grok SIB bytes. */
   5.210 +    if ( rm == 4 )
   5.211 +    {
   5.212 +        DPRINTK("We don't grok SIB bytes.");
   5.213 +        return;
   5.214 +    }
   5.215 +
   5.216 +    /* Ensure Mod/RM specifies (r32) or disp8(r32). */
   5.217 +    switch ( mod )
   5.218 +    {
   5.219 +    case 0:
   5.220 +        if ( (rm == 5) || unlikely(insn_len != 3) )
   5.221 +        {
   5.222 +            DPRINTK("Unhandleable disp32 EA, or bad insn_len (%d, %d).",
   5.223 +                    rm, insn_len);
   5.224 +            return;
   5.225 +        }
   5.226 +        break;            /* m32 == (r32) */
   5.227 +    case 1:
   5.228 +        if ( unlikely(insn_len != 4) )
   5.229 +        {
   5.230 +            DPRINTK("Bad insn_len (%d).", insn_len);
   5.231 +            return;
   5.232 +        }
   5.233 +        break;            /* m32 == disp8(r32) */
   5.234 +    default:
   5.235 +        DPRINTK("Unhandleable Mod value %d.", mod);
   5.236 +        return;
   5.237 +    }
   5.238 +
   5.239 +    for ( ; ; )
   5.240 +    {
   5.241 +        /* Bail if can't decode the following instruction. */
   5.242 +        if ( unlikely((new_insn_len =
   5.243 +                       get_insn_len(&b[insn_len], &opcode)) == 0) )
   5.244 +        {
   5.245 +            DPRINTK("Could not decode following instruction.");
   5.246 +            return;
   5.247 +        }
   5.248 +
   5.249 +        /* We track one 8-bit relative offset for patching later. */
   5.250 +        if ( ((opcode >= 0x70) && (opcode <= 0x7f)) || (opcode == 0xeb) )
   5.251 +        {
   5.252 +            if ( relbyte_idx != -1 )
   5.253 +            {
   5.254 +                printk(KERN_ALERT "Multiple relative offsets in patch seq!");
   5.255 +                return;
   5.256 +            }
   5.257 +            relbyte_idx = insn_len;
   5.258 +            while ( b[relbyte_idx] != opcode )
   5.259 +                relbyte_idx++;
   5.260 +            relbyte_idx++;
   5.261 +        }
   5.262 +
   5.263 +        if ( (insn_len += new_insn_len) > 20 )
   5.264 +        {
   5.265 +            DPRINTK("Code to patch is too long!");
   5.266 +            return;
   5.267 +        }
   5.268 +
   5.269 +        /* The instructions together must be no smaller than 'jmp <disp32>'. */
   5.270 +        if ( insn_len >= 5 )
   5.271 +            break;
   5.272 +
   5.273 +        /* Can't have a RET in the middle of a patch sequence. */
   5.274 +        if ( (opcode == 0xc4) || (relbyte_idx != -1) )
   5.275 +        {
   5.276 +            printk(KERN_ALERT "RET or rel. off. in middle of patch seq!\n");
   5.277 +            return;
   5.278 +        }
   5.279 +    }
   5.280 +
   5.281 +    fixup_buf = (unsigned char *)fix_to_virt(FIX_4GB_SEGMENT_FIXUP_RW);
   5.282 +    fixup_buf_user = fix_to_virt(FIX_4GB_SEGMENT_FIXUP_RO);
   5.283 +
   5.284 +    /* Already created a fixup for this address and code sequence? */
   5.285 +    for ( fe = fixup_hash[FIXUP_HASH(eip)];
   5.286 +          fe != NULL; fe = fe->next )
   5.287 +    {
   5.288 +        if ( (fe->patch_addr == eip) &&
   5.289 +             (fe->patched_code_len == insn_len) &&
   5.290 +             (memcmp(fe->patched_code, b, insn_len) == 0) )
   5.291 +        {
   5.292 +#if 0
   5.293 +            if ( fe->fixup_idx == 10000 )
   5.294 +                return;
   5.295 +#endif
   5.296 +            goto do_the_patch;
   5.297 +        }
   5.298 +    }
   5.299 +
   5.300 +    /* No existing patch -- create an entry for one. */
   5.301 +    fe = kmalloc(sizeof(struct fixup_entry), GFP_KERNEL);
   5.302 +    if ( unlikely(fe == NULL) )
   5.303 +    {
   5.304 +        DPRINTK("Not enough memory to allocate a fixup_entry.");
   5.305 +        return;
   5.306 +    }
   5.307 +    fe->patch_addr = eip;
   5.308 +    fe->patched_code_len = insn_len;
   5.309 +    memcpy(fe->patched_code, b, insn_len);
   5.310 +    fe->fixup_idx = fixup_idx;
   5.311 +    fe->next = fixup_hash[FIXUP_HASH(eip)];
   5.312 +    fixup_hash[FIXUP_HASH(eip)] = fe;
   5.313 +    
   5.314 +#if 0
   5.315 +    if ( (eip & 0x3f) == 0x38 )
   5.316 +    {
   5.317 +        int i;
   5.318 +        static int ii = 0;
   5.319 +        printk(KERN_ALERT " !!!!!!! %d'th reject\n"KERN_ALERT" .byte ", ++ii);
   5.320 +        for ( i = 0; i < insn_len; i++ )
   5.321 +            printk("0x%02x,", b[i]);
   5.322 +        printk("\n");
   5.323 +        fe->fixup_idx = 10000;
   5.324 +        return;
   5.325 +    }
   5.326 +#endif
   5.327 +
   5.328 +    /* push <r32> */
   5.329 +    if ( reg != rm )
   5.330 +        fixup_buf[fixup_idx++] = 0x50 + rm;
   5.331 +
   5.332 +    /* add %gs:0,<r32> */
   5.333 +    fixup_buf[fixup_idx++] = 0x65;
   5.334 +    fixup_buf[fixup_idx++] = 0x03;
   5.335 +    fixup_buf[fixup_idx++] = 0x05 | (rm << 3);
   5.336 +    *(unsigned long *)&fixup_buf[fixup_idx] = 0;
   5.337 +    fixup_idx += 4;
   5.338 +
   5.339 +    /* First relocated instruction, minus the GS override. */
   5.340 +    memcpy(&fixup_buf[fixup_idx], &b[1], error_code - 1);
   5.341 +    fixup_idx += error_code - 1;
   5.342 +
   5.343 +    /* pop <r32> */
   5.344 +    if ( reg != rm )
   5.345 +        fixup_buf[fixup_idx++] = 0x58 + rm;
   5.346 +
   5.347 +    /* Relocated instructions, minus the initial GS override. */
   5.348 +    memcpy(&fixup_buf[fixup_idx], &b[error_code], insn_len - error_code);
   5.349 +    fixup_idx += insn_len - error_code;
   5.350 +
   5.351 +    /* jmp <rel32> */
   5.352 +    fixup_buf[fixup_idx++] = 0xe9;
   5.353 +    fixup_idx += 4;
   5.354 +    *(unsigned long *)&fixup_buf[fixup_idx-4] = 
   5.355 +        (eip + insn_len) - (fixup_buf_user + fixup_idx);
   5.356 +
   5.357 +    if ( relbyte_idx != -1 )
   5.358 +    {
   5.359 +        /* Patch the 8-bit relative offset. */
   5.360 +        int idx = relbyte_idx + 6;
   5.361 +        if ( reg != rm )
   5.362 +            idx += 2;
   5.363 +        fixup_buf[idx] = fixup_idx - (idx + 1);
   5.364 +        
   5.365 +        /* jmp <rel32> */
   5.366 +        fixup_buf[fixup_idx++] = 0xe9;
   5.367 +        fixup_idx += 4;
   5.368 +        *(unsigned long *)&fixup_buf[fixup_idx-4] = 
   5.369 +            (eip + relbyte_idx + 1 + b[relbyte_idx]) - 
   5.370 +            (fixup_buf_user + fixup_idx);
   5.371 +
   5.372 +    }
   5.373 +
   5.374 + do_the_patch:
   5.375 +    /* Create the patching instruction in a temporary buffer. */
   5.376 +    patch[0] = 0xe9;
   5.377 +    *(unsigned long *)&patch[1] = 
   5.378 +        (fixup_buf_user + fe->fixup_idx) - (eip + 5);
   5.379 +
   5.380 +    pgd = pgd_offset(current->mm, eip);
   5.381 +    pmd = pmd_offset(pgd, eip);
   5.382 +    pte = pte_offset_kernel(pmd, eip);
   5.383 +    veip = kmap(pte_page(*pte));
   5.384 +    memcpy((char *)veip + (eip & ~PAGE_MASK), patch, 5);
   5.385 +    kunmap(pte_page(*pte));
   5.386 +
   5.387 +    /* Success! Return to user land to execute 2nd insn of the pair. */
   5.388 +    regs->eip = fixup_buf_user + fe->fixup_idx + error_code + 6;
   5.389 +    if ( reg != rm )
   5.390 +        regs->eip += 2; /* account for push/pop pair */
   5.391 +    return;
   5.392  }
   5.393 +
   5.394 +static int __init fixup_init(void)
   5.395 +{
   5.396 +    unsigned long page = get_zeroed_page(GFP_ATOMIC);
   5.397 +    __set_fixmap(FIX_4GB_SEGMENT_FIXUP_RO, __pa(page), PAGE_READONLY);
   5.398 +    __set_fixmap(FIX_4GB_SEGMENT_FIXUP_RW, __pa(page), PAGE_KERNEL);
   5.399 +    memset(fixup_hash, 0, sizeof(fixup_hash));
   5.400 +    return 0;
   5.401 +}
   5.402 +
   5.403 +__initcall(fixup_init);
     6.1 --- a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h	Thu Aug 05 16:40:56 2004 +0000
     6.2 +++ b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h	Thu Aug 05 22:27:41 2004 +0000
     6.3 @@ -44,6 +44,8 @@
     6.4  enum fixed_addresses {
     6.5  	FIX_HOLE,
     6.6  	FIX_VSYSCALL,
     6.7 +	FIX_4GB_SEGMENT_FIXUP_RO,
     6.8 +	FIX_4GB_SEGMENT_FIXUP_RW,
     6.9  #ifdef CONFIG_X86_LOCAL_APIC
    6.10  	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
    6.11  #endif
    6.12 @@ -126,8 +128,8 @@ extern void __set_fixmap_ma (enum fixed_
    6.13   * This is the range that is readable by user mode, and things
    6.14   * acting like user mode such as get_user_pages.
    6.15   */
    6.16 -#define FIXADDR_USER_START	(__fix_to_virt(FIX_VSYSCALL))
    6.17 -#define FIXADDR_USER_END	(FIXADDR_USER_START + PAGE_SIZE)
    6.18 +#define FIXADDR_USER_START	(__fix_to_virt(FIX_4GB_SEGMENT_FIXUP_RO))
    6.19 +#define FIXADDR_USER_END	(FIXADDR_USER_START + (2*PAGE_SIZE))
    6.20  
    6.21  
    6.22  extern void __this_fixmap_does_not_exist(void);