direct-io.hg

changeset 2188:83a98ae048ea

bitkeeper revision 1.1159.17.10 (411a5552Ocw2woXgBOLvoZ2_WALTDg)

Binary rewriting now works with Fedora Core 2.
author kaf24@scramble.cl.cam.ac.uk
date Wed Aug 11 17:20:18 2004 +0000 (2004-08-11)
parents d7b517eaf176
children 8927b36dfcc0
files linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c
line diff
     1.1 --- a/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c	Wed Aug 11 07:33:29 2004 +0000
     1.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c	Wed Aug 11 17:20:18 2004 +0000
     1.3 @@ -32,7 +32,7 @@
     1.4  #include <asm/pgtable.h>
     1.5  #include <asm/uaccess.h>
     1.6  
     1.7 -#if 1
     1.8 +#if 0
     1.9  #define ASSERT(_p) \
    1.10      if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
    1.11      __LINE__, __FILE__); *(int*)0=0; }
    1.12 @@ -44,14 +44,13 @@
    1.13  #define DPRINTK(_f, _a...) ((void)0)
    1.14  #endif
    1.15  
    1.16 -static char            *fixup_buf;
    1.17 +static unsigned char *fixup_buf;
    1.18  #define FIXUP_BUF_USER  PAGE_SIZE
    1.19  #define FIXUP_BUF_ORDER 1
    1.20  #define FIXUP_BUF_SIZE  (PAGE_SIZE<<FIXUP_BUF_ORDER)
    1.21  #define PATCH_LEN       5
    1.22  
    1.23  struct fixup_entry {
    1.24 -    unsigned long  patch_addr; /* XXX */
    1.25      unsigned char  patched_code[20];
    1.26      unsigned short patched_code_len;
    1.27      unsigned short fixup_idx;
    1.28 @@ -77,9 +76,9 @@ static inline int FIXUP_HASH(char *b)
    1.29  
    1.30  /* Helpful codes for the main decode routine. */
    1.31  #define CODE_MASK         (3<<6)
    1.32 -#define PUSH              (0<<6) /* PUSH onto stack */
    1.33 -#define POP               (1<<6) /* POP from stack */
    1.34 -#define JMP               (2<<6) /* 8-bit relative JMP */
    1.35 +#define PUSH              (1<<6) /* PUSH onto stack */
    1.36 +#define POP               (2<<6) /* POP from stack */
    1.37 +#define JMP               (3<<6) /* 8-bit relative JMP */
    1.38  
    1.39  /* Short forms for the table. */
    1.40  #define X  0 /* invalid for some random reason */
    1.41 @@ -117,7 +116,7 @@ static unsigned char insn_decode[256] = 
    1.42      O|M|1, O|M|4, O|M|1, O|M|1, O|M, O|M, O|M, O|M,
    1.43      O|M, O|M, O|M, O|M, O|M, O|M, O|M, O|M|POP, 
    1.44      /* 0x90 - 0x9F */
    1.45 -    O, O, O, O, O, O, O, O,
    1.46 +    O, O, O, O, S, O, O, O,
    1.47      O, O, X, O, O, O, O, O,
    1.48      /* 0xA0 - 0xAF */
    1.49      O|1, O|4, O|1, O|4, O, O, O, O,
    1.50 @@ -139,9 +138,9 @@ static unsigned char insn_decode[256] = 
    1.51      O, O, O, O, O, O, O|M, X
    1.52  };
    1.53  
    1.54 -static unsigned int get_insn_len(unsigned char *insn, 
    1.55 -                                 unsigned char *p_opcode,
    1.56 -                                 unsigned char *p_decode)
    1.57 +static unsigned int parse_insn(unsigned char *insn, 
    1.58 +                               unsigned char *p_opcode,
    1.59 +                               unsigned char *p_decode)
    1.60  {
    1.61      unsigned char b, d, *pb, mod, rm;
    1.62  
    1.63 @@ -159,10 +158,7 @@ static unsigned int get_insn_len(unsigne
    1.64  
    1.65      /* 2. Ensure we have a valid opcode byte. */
    1.66      if ( !(d & OPCODE_BYTE) )
    1.67 -    {
    1.68 -        printk(KERN_ALERT " *** %02x %02x %02x\n", pb[0], pb[1], pb[2]);
    1.69          return 0;
    1.70 -    }
    1.71  
    1.72      /* 3. Process Mod/RM if there is one. */
    1.73      if ( d & HAS_MODRM )
    1.74 @@ -188,10 +184,11 @@ static unsigned int get_insn_len(unsigne
    1.75          }
    1.76      }
    1.77  
    1.78 -    /* 4. All done. Result is all byte sstepped over, plus any immediates. */
    1.79 +    /* 4. All done. Result is all bytes stepped over, plus any immediates. */
    1.80      return ((pb - insn) + 1 + (d & INSN_SUFFIX_BYTES));
    1.81  }
    1.82  
    1.83 +/* Bitmap of faulting instructions that we can handle. */
    1.84  static unsigned char handleable_code[32] = {
    1.85      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1.86      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1.87 @@ -201,13 +198,25 @@ static unsigned char handleable_code[32]
    1.88      0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1.89  };
    1.90  
    1.91 +/* Bitmap of opcodes that use a register operand specified by Mod/RM. */
    1.92 +static unsigned char opcode_uses_reg[32] = {
    1.93 +    /* 0x00 - 0x3F */
    1.94 +    0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
    1.95 +    /* 0x40 - 0x7F */
    1.96 +    0x00, 0x00, 0x00, 0x00, 0x0C, 0x0A, 0x00, 0x00,
    1.97 +    /* 0x80 - 0xBF */
    1.98 +    0xF0, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    1.99 +    /* 0xC0 - 0xFF */
   1.100 +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   1.101 +};
   1.102 +
   1.103  asmlinkage void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
   1.104  {
   1.105      static unsigned int fixup_idx = 0;
   1.106      unsigned int fi;
   1.107 -    int save_indirect_reg, hash;
   1.108 +    int save_indirect_reg, hash, i;
   1.109      unsigned int insn_len = (unsigned int)error_code, new_insn_len;
   1.110 -    unsigned char b[20], modrm, mod, reg, rm, patch[PATCH_LEN], opcode, decode;
   1.111 +    unsigned char b[20], modrm, mod, reg, rm, sib, patch[20], opcode, decode;
   1.112      unsigned long eip = regs->eip - insn_len;
   1.113      struct fixup_entry *fe;
   1.114      pte_t *pte;
   1.115 @@ -227,20 +236,14 @@ asmlinkage void do_fixup_4gb_segment(str
   1.116          DPRINTK("User executing out of kernel space?!");
   1.117          return;
   1.118      }
   1.119 -    
   1.120 -    if ( unlikely(((eip ^ (eip+PATCH_LEN)) & PAGE_MASK) != 0) )
   1.121 -    {
   1.122 -        DPRINTK("Patch instruction would straddle a page boundary.");
   1.123 -        return;
   1.124 -    }
   1.125  
   1.126      /*
   1.127 -     * Check that the page to be patched is part of a read-only VMA. This 
   1.128 +     * Check that the page to be patched is part of a private VMA. This 
   1.129       * means that our patch will never erroneously get flushed to disc.
   1.130       */
   1.131      if ( eip > (FIXUP_BUF_USER + FIXUP_BUF_SIZE) ) /* don't check fixup area */
   1.132      {
   1.133 -        /* [SMP] Need to the mmap_sem semaphore. */
   1.134 +        /* [SMP] Need to grab the mmap_sem semaphore. */
   1.135          struct vm_area_struct *vma = find_vma(current->mm, eip);
   1.136          if ( (vma == NULL) || (vma->vm_flags & VM_MAYSHARE) )
   1.137          {
   1.138 @@ -255,19 +258,16 @@ asmlinkage void do_fixup_4gb_segment(str
   1.139          return;
   1.140      }
   1.141  
   1.142 -    /* Already created a fixup for this address and code sequence? */
   1.143 +    /* Already created a fixup for this code sequence? */
   1.144      hash = FIXUP_HASH(b);
   1.145 -    for ( fe = fixup_hash[hash];
   1.146 -          fe != NULL; fe = fe->next )
   1.147 +    for ( fe = fixup_hash[hash]; fe != NULL; fe = fe->next )
   1.148      {
   1.149 -        if ( eip != fe->patch_addr )
   1.150 -            continue; /* XXX */
   1.151          if ( memcmp(fe->patched_code, b, fe->patched_code_len) == 0 )
   1.152              goto do_the_patch;
   1.153      }
   1.154  
   1.155      /* Guaranteed enough room to patch? */
   1.156 -    if ( unlikely((fi = fixup_idx) > (FIXUP_BUF_SIZE-32)) )
   1.157 +    if ( unlikely((fi = fixup_idx) > (FIXUP_BUF_SIZE-64)) )
   1.158      {
   1.159          static int printed = 0;
   1.160          if ( !printed )
   1.161 @@ -324,6 +324,9 @@ asmlinkage void do_fixup_4gb_segment(str
   1.162      if ( save_indirect_reg )
   1.163          fixup_buf[fi++] = 0x50 + rm;
   1.164  
   1.165 +    /* pushf */
   1.166 +    fixup_buf[fi++] = 0x9c;
   1.167 +
   1.168      /* add %gs:0,<r32> */
   1.169      fixup_buf[fi++] = 0x65;
   1.170      fixup_buf[fi++] = 0x03;
   1.171 @@ -331,6 +334,9 @@ asmlinkage void do_fixup_4gb_segment(str
   1.172      *(unsigned long *)&fixup_buf[fi] = 0;
   1.173      fi += 4;
   1.174  
   1.175 +    /* popf */
   1.176 +    fixup_buf[fi++] = 0x9d;
   1.177 +
   1.178      /* Relocate the faulting instruction, minus the GS override. */
   1.179      memcpy(&fixup_buf[fi], &b[1], error_code - 1);
   1.180      fi += error_code - 1;
   1.181 @@ -350,7 +356,7 @@ asmlinkage void do_fixup_4gb_segment(str
   1.182  
   1.183          /* Bail if can't decode the following instruction. */
   1.184          if ( unlikely((new_insn_len =
   1.185 -                       get_insn_len(&b[insn_len], &opcode, &decode)) == 0) )
   1.186 +                       parse_insn(&b[insn_len], &opcode, &decode)) == 0) )
   1.187          {
   1.188              DPRINTK("Could not decode following instruction.");
   1.189              return;
   1.190 @@ -358,63 +364,183 @@ asmlinkage void do_fixup_4gb_segment(str
   1.191  
   1.192          if ( (decode & CODE_MASK) == JMP )
   1.193          {
   1.194 -            return;
   1.195 +            long off;
   1.196  
   1.197              memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len - 1);
   1.198              fi += new_insn_len - 1;
   1.199              
   1.200              /* Patch the 8-bit relative offset. */
   1.201              fixup_buf[fi++] = 1;
   1.202 -
   1.203 +            
   1.204              insn_len += new_insn_len;
   1.205              ASSERT(insn_len >= PATCH_LEN);
   1.206          
   1.207              /* ret */
   1.208              fixup_buf[fi++] = 0xc3;
   1.209  
   1.210 -            /* jmp <rel32> */
   1.211 -            fixup_buf[fi++] = 0xe9;
   1.212 -            fi += 4;
   1.213 -            *(unsigned long *)&fixup_buf[fi-4] = 
   1.214 -                (eip + insn_len + (long)(char)b[insn_len-1]) - 
   1.215 -                (FIXUP_BUF_USER + fi);
   1.216 -            
   1.217 +            /* pushf */
   1.218 +            fixup_buf[fi++] = 0x9c;
   1.219 +
   1.220 +            off = (insn_len - PATCH_LEN) + (long)(char)b[insn_len-1];
   1.221 +            if ( unlikely(off > 127) )
   1.222 +            {
   1.223 +                /* add <imm32>,4(%esp) */
   1.224 +                fixup_buf[fi++] = 0x81;
   1.225 +                fixup_buf[fi++] = 0x44;
   1.226 +                fixup_buf[fi++] = 0x24;
   1.227 +                fixup_buf[fi++] = 0x04;
   1.228 +                fi += 4;
   1.229 +                *(long *)&fixup_buf[fi-4] = off;
   1.230 +            }
   1.231 +            else
   1.232 +            {
   1.233 +                /* add <imm8>,4(%esp) [sign-extended] */
   1.234 +                fixup_buf[fi++] = 0x83;
   1.235 +                fixup_buf[fi++] = 0x44;
   1.236 +                fixup_buf[fi++] = 0x24;
   1.237 +                fixup_buf[fi++] = 0x04;
   1.238 +                fixup_buf[fi++] = (char)(off & 0xff);
   1.239 +            }
   1.240 +
   1.241 +            /* popf */
   1.242 +            fixup_buf[fi++] = 0x9d;
   1.243 +
   1.244 +            /* ret */
   1.245 +            fixup_buf[fi++] = 0xc3;
   1.246 +
   1.247              break;
   1.248          }
   1.249 -        else if ( opcode == 0xe9 )
   1.250 +        else if ( opcode == 0xe9 ) /* jmp <rel32> */
   1.251          {
   1.252 -            return;
   1.253 -
   1.254 -            memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len - 4);
   1.255 -            fi += new_insn_len - 4;
   1.256 -            
   1.257              insn_len += new_insn_len;
   1.258              ASSERT(insn_len >= PATCH_LEN);
   1.259          
   1.260 -            /* Patch the 32-bit relative offset. */
   1.261 +            /* pushf */
   1.262 +            fixup_buf[fi++] = 0x9c;
   1.263 +
   1.264 +            /* add <imm32>,4(%esp) */
   1.265 +            fixup_buf[fi++] = 0x81;
   1.266 +            fixup_buf[fi++] = 0x44;
   1.267 +            fixup_buf[fi++] = 0x24;
   1.268 +            fixup_buf[fi++] = 0x04;
   1.269              fi += 4;
   1.270 -            *(unsigned long *)&fixup_buf[fi-4] = 
   1.271 -                (eip + insn_len + *(long *)&b[insn_len-4]) - 
   1.272 -                (FIXUP_BUF_USER + fi);
   1.273 +            *(long *)&fixup_buf[fi-4] = 
   1.274 +                (insn_len - PATCH_LEN) + *(long *)&b[insn_len-4];
   1.275 +
   1.276 +            /* popf */
   1.277 +            fixup_buf[fi++] = 0x9d;
   1.278  
   1.279              /* ret */
   1.280              fixup_buf[fi++] = 0xc3;
   1.281  
   1.282              break;
   1.283          }
   1.284 -        else if ( (decode & CODE_MASK) == PUSH )
   1.285 +        else if ( opcode == 0xc3 ) /* ret */
   1.286          {
   1.287 -            return;
   1.288 -        }
   1.289 -        else if ( (decode & CODE_MASK) == POP )
   1.290 -        {
   1.291 -            return;
   1.292 +            /* pop -4(%esp) [doesn't affect EFLAGS] */
   1.293 +            fixup_buf[fi++] = 0x8f;
   1.294 +            fixup_buf[fi++] = 0x44;
   1.295 +            fixup_buf[fi++] = 0x24;
   1.296 +            fixup_buf[fi++] = 0xfc;
   1.297          }
   1.298          else
   1.299          {
   1.300 -            /* Relocate the instruction verbatim. */
   1.301 -            memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len);
   1.302 -            fi += new_insn_len;
   1.303 +            int stack_addon = 4;
   1.304 +
   1.305 +            if ( (decode & CODE_MASK) == PUSH )
   1.306 +            {
   1.307 +                stack_addon = 8;
   1.308 +                /* push (%esp) */
   1.309 +                fixup_buf[fi++] = 0xff;
   1.310 +                fixup_buf[fi++] = 0x34;
   1.311 +                fixup_buf[fi++] = 0x24;
   1.312 +            }
   1.313 +            else if ( (decode & CODE_MASK) == POP )
   1.314 +            {
   1.315 +                stack_addon = 8;
   1.316 +                /* push 4(%esp) */
   1.317 +                fixup_buf[fi++] = 0xff;
   1.318 +                fixup_buf[fi++] = 0x74;
   1.319 +                fixup_buf[fi++] = 0x24;
   1.320 +                fixup_buf[fi++] = 0x04;
   1.321 +            }
   1.322 +
   1.323 +            /* Check for EA calculations involving ESP, and skip return addr */
   1.324 +            if ( decode & HAS_MODRM )
   1.325 +            {
   1.326 +                do { new_insn_len--; }
   1.327 +                while ( (fixup_buf[fi++] = b[insn_len++]) != opcode );
   1.328 +
   1.329 +                modrm = fixup_buf[fi++] = b[insn_len++];
   1.330 +                new_insn_len--;
   1.331 +                mod   = (modrm >> 6) & 3;
   1.332 +                reg   = (modrm >> 3) & 7;
   1.333 +                rm    = (modrm >> 0) & 7;
   1.334 +
   1.335 +                if ( (reg == 4) &&
   1.336 +                     test_bit(opcode, (unsigned long *)opcode_uses_reg) )
   1.337 +                {
   1.338 +                    DPRINTK("Data movement to ESP unsupported.");
   1.339 +                    return;
   1.340 +                }
   1.341 +
   1.342 +                if ( rm == 4 )
   1.343 +                {
   1.344 +                    if ( mod == 3 )
   1.345 +                    {
   1.346 +                        DPRINTK("Data movement to ESP is unsupported.");
   1.347 +                        return;
   1.348 +                    }
   1.349 +
   1.350 +                    sib = fixup_buf[fi++] = b[insn_len++];
   1.351 +                    new_insn_len--;
   1.352 +                    if ( (sib & 7) == 4 )
   1.353 +                    {
   1.354 +                        switch ( mod )
   1.355 +                        {
   1.356 +                        case 0:
   1.357 +                            mod = 1;
   1.358 +                            fixup_buf[fi-2] |= 0x40;
   1.359 +                            fixup_buf[fi++] = stack_addon;
   1.360 +                            break;
   1.361 +                        case 1:
   1.362 +                            fixup_buf[fi++] = b[insn_len++] + stack_addon;
   1.363 +                            new_insn_len--;
   1.364 +                            break;
   1.365 +                        case 2:
   1.366 +                            *(long *)&fixup_buf[fi] = 
   1.367 +                                *(long *)&b[insn_len] + stack_addon;
   1.368 +                            fi += 4;
   1.369 +                            insn_len += 4;
   1.370 +                            new_insn_len -= 4;
   1.371 +                            break;
   1.372 +                        }
   1.373 +                    }
   1.374 +                }
   1.375 +            }
   1.376 +
   1.377 +            /* Relocate the (remainder of) the instruction. */
   1.378 +            if ( new_insn_len != 0 )
   1.379 +            {
   1.380 +                memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len);
   1.381 +                fi += new_insn_len;
   1.382 +            }
   1.383 +
   1.384 +            if ( (decode & CODE_MASK) == PUSH )
   1.385 +            {
   1.386 +                /* pop 4(%esp) */
   1.387 +                fixup_buf[fi++] = 0x8f;
   1.388 +                fixup_buf[fi++] = 0x44;
   1.389 +                fixup_buf[fi++] = 0x24;
   1.390 +                fixup_buf[fi++] = 0x04;
   1.391 +            }
   1.392 +            else if ( (decode & CODE_MASK) == POP )
   1.393 +            {
   1.394 +                /* pop (%esp) */
   1.395 +                fixup_buf[fi++] = 0x8f;
   1.396 +                fixup_buf[fi++] = 0x04;
   1.397 +                fixup_buf[fi++] = 0x24;
   1.398 +            }
   1.399          }
   1.400  
   1.401          if ( (insn_len += new_insn_len) > 20 )
   1.402 @@ -424,7 +550,7 @@ asmlinkage void do_fixup_4gb_segment(str
   1.403          }
   1.404  
   1.405          /* Can't have a RET in the middle of a patch sequence. */
   1.406 -        if ( (opcode == 0xc4) && (insn_len < PATCH_LEN) )
   1.407 +        if ( (opcode == 0xc3) && (insn_len < PATCH_LEN) )
   1.408          {
   1.409              DPRINTK("RET in middle of patch seq!\n");
   1.410              return;
   1.411 @@ -438,12 +564,11 @@ asmlinkage void do_fixup_4gb_segment(str
   1.412          DPRINTK("Not enough memory to allocate a fixup_entry.");
   1.413          return;
   1.414      }
   1.415 -    fe->patch_addr = eip; /* XXX */
   1.416      fe->patched_code_len = insn_len;
   1.417      memcpy(fe->patched_code, b, insn_len);
   1.418      fe->fixup_idx = fixup_idx;
   1.419      fe->return_idx = 
   1.420 -        fixup_idx + error_code + 6 + 4/**/ + (save_indirect_reg ? 2 : 0);
   1.421 +        fixup_idx + error_code + (save_indirect_reg ? 14 : 12);
   1.422      fe->next = fixup_hash[hash];
   1.423      fixup_hash[hash] = fe;
   1.424  
   1.425 @@ -451,39 +576,22 @@ asmlinkage void do_fixup_4gb_segment(str
   1.426      fixup_idx = fi;
   1.427  
   1.428   do_the_patch:
   1.429 -#if 1
   1.430 -    /* Create the patching instruction in a temporary buffer. */
   1.431 +
   1.432 +    if ( unlikely(((eip ^ (eip + fe->patched_code_len)) & PAGE_MASK) != 0) )
   1.433 +    {
   1.434 +        DPRINTK("Patch instruction would straddle a page boundary.");
   1.435 +        return;
   1.436 +    }
   1.437 +
   1.438 +    /* Create the patching instructions in a temporary buffer. */
   1.439      patch[0] = 0x67;
   1.440      patch[1] = 0xff;
   1.441      patch[2] = 0x16; /* call <r/m16> */
   1.442      *(u16 *)&patch[3] = FIXUP_BUF_USER + fe->fixup_idx;
   1.443 -#else
   1.444 -    patch[0] = 0x9a;
   1.445 -    *(u32 *)&patch[1] = FIXUP_BUF_USER + fe->fixup_idx + 4;
   1.446 -    *(u16 *)&patch[5] = __USER_CS;
   1.447 -#endif
   1.448 +    for ( i = 5; i < fe->patched_code_len; i++ )
   1.449 +        patch[i] = 0x90; /* nop */
   1.450  
   1.451 -#if 1
   1.452 -    {
   1.453 -        int iii;
   1.454 -        printk(KERN_ALERT "EIP == %08lx; USER_EIP == %08lx\n",
   1.455 -               eip, FIXUP_BUF_USER + fe->fixup_idx);
   1.456 -        printk(KERN_ALERT " .byte ");
   1.457 -        for ( iii = 0; iii < insn_len; iii++ )
   1.458 -            printk("0x%02x,", b[iii]);
   1.459 -        printk("!!\n");
   1.460 -        printk(KERN_ALERT " .byte ");
   1.461 -        for ( iii = fe->fixup_idx; iii < fi; iii++ )
   1.462 -            printk("0x%02x,", (unsigned char)fixup_buf[iii]);
   1.463 -        printk("!!\n");
   1.464 -        printk(KERN_ALERT " .byte ");
   1.465 -        for ( iii = 0; iii < 7; iii++ )
   1.466 -            printk("0x%02x,", (unsigned char)patch[iii]);
   1.467 -        printk("!!\n");
   1.468 -    }
   1.469 -#endif
   1.470 -
   1.471 -    if ( put_user(eip + insn_len, (unsigned long *)regs->esp - 1) != 0 )
   1.472 +    if ( put_user(eip + PATCH_LEN, (unsigned long *)regs->esp - 1) != 0 )
   1.473      {
   1.474          DPRINTK("Failed to place return address on user stack.");
   1.475          return;
   1.476 @@ -498,7 +606,7 @@ asmlinkage void do_fixup_4gb_segment(str
   1.477      pmd = pmd_offset(pgd, eip);
   1.478      pte = pte_offset_kernel(pmd, eip);
   1.479      veip = kmap(pte_page(*pte));
   1.480 -    memcpy((char *)veip + (eip & ~PAGE_MASK), patch, PATCH_LEN);
   1.481 +    memcpy((char *)veip + (eip & ~PAGE_MASK), patch, fe->patched_code_len);
   1.482      kunmap(pte_page(*pte));
   1.483  
   1.484      return;
   1.485 @@ -512,7 +620,7 @@ static int __init fixup_init(void)
   1.486      struct page *_pages[1<<FIXUP_BUF_ORDER], **pages=_pages;
   1.487      int i;
   1.488  
   1.489 -    /*if ( nosegfixup )*/
   1.490 +    if ( nosegfixup )
   1.491          return 0;
   1.492  
   1.493      HYPERVISOR_vm_assist(VMASST_CMD_enable,