ia64/xen-unstable

changeset 2184:d7b517eaf176

bitkeeper revision 1.1159.17.9 (4119cbc9Y38CPLUDM54OzSqxL0xnfw)

Disable binary-rewriting while fixing it for FC2.
author kaf24@scramble.cl.cam.ac.uk
date Wed Aug 11 07:33:29 2004 +0000 (2004-08-11)
parents 8651fa465906
children eeb76f67d3d3 83a98ae048ea 0dd06fdaffd4
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:28:29 2004 +0000
     1.2 +++ b/linux-2.6.7-xen-sparse/arch/xen/kernel/fixup.c	Wed Aug 11 07:33:29 2004 +0000
     1.3 @@ -205,7 +205,7 @@ asmlinkage void do_fixup_4gb_segment(str
     1.4  {
     1.5      static unsigned int fixup_idx = 0;
     1.6      unsigned int fi;
     1.7 -    int save_indirect_reg, hash, rel_idx;
     1.8 +    int save_indirect_reg, hash;
     1.9      unsigned int insn_len = (unsigned int)error_code, new_insn_len;
    1.10      unsigned char b[20], modrm, mod, reg, rm, patch[PATCH_LEN], opcode, decode;
    1.11      unsigned long eip = regs->eip - insn_len;
    1.12 @@ -339,8 +339,15 @@ asmlinkage void do_fixup_4gb_segment(str
    1.13      if ( save_indirect_reg )
    1.14          fixup_buf[fi++] = 0x58 + rm;
    1.15  
    1.16 -    while ( insn_len < PATCH_LEN )
    1.17 +    for ( ; ; )
    1.18      {
    1.19 +        if ( insn_len >= PATCH_LEN )
    1.20 +        {
    1.21 +            /* ret */
    1.22 +            fixup_buf[fi++] = 0xc3;
    1.23 +            break;
    1.24 +        }
    1.25 +
    1.26          /* Bail if can't decode the following instruction. */
    1.27          if ( unlikely((new_insn_len =
    1.28                         get_insn_len(&b[insn_len], &opcode, &decode)) == 0) )
    1.29 @@ -349,38 +356,59 @@ asmlinkage void do_fixup_4gb_segment(str
    1.30              return;
    1.31          }
    1.32  
    1.33 -        /* We track one 8-bit relative offset for patching later. */
    1.34          if ( (decode & CODE_MASK) == JMP )
    1.35          {
    1.36 -            rel_idx = insn_len;
    1.37 -            while ( (fixup_buf[fi++] = b[rel_idx++]) != opcode )
    1.38 -                continue;
    1.39 +            return;
    1.40 +
    1.41 +            memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len - 1);
    1.42 +            fi += new_insn_len - 1;
    1.43              
    1.44              /* Patch the 8-bit relative offset. */
    1.45 -            int idx = fe->fixup_idx + relbyte_idx + 6 + 4/**/;
    1.46 -            if ( save_indirect_reg )
    1.47 -                idx += 2;
    1.48 -            fixup_buf[idx] = fi - (idx + 1);
    1.49 +            fixup_buf[fi++] = 1;
    1.50 +
    1.51 +            insn_len += new_insn_len;
    1.52 +            ASSERT(insn_len >= PATCH_LEN);
    1.53          
    1.54 +            /* ret */
    1.55 +            fixup_buf[fi++] = 0xc3;
    1.56 +
    1.57              /* jmp <rel32> */
    1.58              fixup_buf[fi++] = 0xe9;
    1.59              fi += 4;
    1.60              *(unsigned long *)&fixup_buf[fi-4] = 
    1.61 -                (eip + relbyte_idx + 1 + (long)(char)b[relbyte_idx]) - 
    1.62 +                (eip + insn_len + (long)(char)b[insn_len-1]) - 
    1.63                  (FIXUP_BUF_USER + fi);
    1.64 +            
    1.65 +            break;
    1.66          }
    1.67          else if ( opcode == 0xe9 )
    1.68          {
    1.69 -            rel_idx = insn_len;
    1.70 -            while ( (fixup_buf[fi++] = b[rel_idx++]) != opcode )
    1.71 -                continue;
    1.72 +            return;
    1.73 +
    1.74 +            memcpy(&fixup_buf[fi], &b[insn_len], new_insn_len - 4);
    1.75 +            fi += new_insn_len - 4;
    1.76              
    1.77 +            insn_len += new_insn_len;
    1.78 +            ASSERT(insn_len >= PATCH_LEN);
    1.79 +        
    1.80              /* Patch the 32-bit relative offset. */
    1.81 -            int idx = fe->fixup_idx + relword_idx + 6 + 4/**/;
    1.82 -            if ( save_indirect_reg )
    1.83 -                idx += 2;
    1.84 -            *(unsigned long *)&fixup_buf[idx] +=
    1.85 -                (eip + relword_idx) - (FIXUP_BUF_USER + idx);
    1.86 +            fi += 4;
    1.87 +            *(unsigned long *)&fixup_buf[fi-4] = 
    1.88 +                (eip + insn_len + *(long *)&b[insn_len-4]) - 
    1.89 +                (FIXUP_BUF_USER + fi);
    1.90 +
    1.91 +            /* ret */
    1.92 +            fixup_buf[fi++] = 0xc3;
    1.93 +
    1.94 +            break;
    1.95 +        }
    1.96 +        else if ( (decode & CODE_MASK) == PUSH )
    1.97 +        {
    1.98 +            return;
    1.99 +        }
   1.100 +        else if ( (decode & CODE_MASK) == POP )
   1.101 +        {
   1.102 +            return;
   1.103          }
   1.104          else
   1.105          {
   1.106 @@ -395,12 +423,8 @@ asmlinkage void do_fixup_4gb_segment(str
   1.107              return;
   1.108          }
   1.109  
   1.110 -        /* The instructions together must be no smaller than 'jmp <disp32>'. */
   1.111 -        if ( insn_len >= PATCH_LEN )
   1.112 -            break;
   1.113 -
   1.114          /* Can't have a RET in the middle of a patch sequence. */
   1.115 -        if ( opcode == 0xc4 )
   1.116 +        if ( (opcode == 0xc4) && (insn_len < PATCH_LEN) )
   1.117          {
   1.118              DPRINTK("RET in middle of patch seq!\n");
   1.119              return;
   1.120 @@ -423,18 +447,23 @@ asmlinkage void do_fixup_4gb_segment(str
   1.121      fe->next = fixup_hash[hash];
   1.122      fixup_hash[hash] = fe;
   1.123  
   1.124 -
   1.125 -    /* jmp <rel32> */
   1.126 -    fixup_buf[fi++] = 0xe9;
   1.127 -    fi += 4;
   1.128 -    *(unsigned long *)&fixup_buf[fi-4] = 
   1.129 -        (eip + insn_len) - (FIXUP_BUF_USER + fi);
   1.130 -
   1.131      /* Commit the patch. */
   1.132      fixup_idx = fi;
   1.133  
   1.134 -#if 0
   1.135 -    if ( fe->fixup_idx == 4122 )
   1.136 + do_the_patch:
   1.137 +#if 1
   1.138 +    /* Create the patching instruction in a temporary buffer. */
   1.139 +    patch[0] = 0x67;
   1.140 +    patch[1] = 0xff;
   1.141 +    patch[2] = 0x16; /* call <r/m16> */
   1.142 +    *(u16 *)&patch[3] = FIXUP_BUF_USER + fe->fixup_idx;
   1.143 +#else
   1.144 +    patch[0] = 0x9a;
   1.145 +    *(u32 *)&patch[1] = FIXUP_BUF_USER + fe->fixup_idx + 4;
   1.146 +    *(u16 *)&patch[5] = __USER_CS;
   1.147 +#endif
   1.148 +
   1.149 +#if 1
   1.150      {
   1.151          int iii;
   1.152          printk(KERN_ALERT "EIP == %08lx; USER_EIP == %08lx\n",
   1.153 @@ -442,24 +471,27 @@ asmlinkage void do_fixup_4gb_segment(str
   1.154          printk(KERN_ALERT " .byte ");
   1.155          for ( iii = 0; iii < insn_len; iii++ )
   1.156              printk("0x%02x,", b[iii]);
   1.157 -        printk("\n");
   1.158 +        printk("!!\n");
   1.159          printk(KERN_ALERT " .byte ");
   1.160          for ( iii = fe->fixup_idx; iii < fi; iii++ )
   1.161 -            printk("0x%02x,", fixup_buf[iii]);
   1.162 -        printk("\n");
   1.163 +            printk("0x%02x,", (unsigned char)fixup_buf[iii]);
   1.164 +        printk("!!\n");
   1.165          printk(KERN_ALERT " .byte ");
   1.166 -        for ( iii = fe->fixup_idx; iii < fi; iii++ )
   1.167 -            printk("0x%02x,", ((char *)FIXUP_BUF_USER)[iii]);
   1.168 -        printk("\n");
   1.169 +        for ( iii = 0; iii < 7; iii++ )
   1.170 +            printk("0x%02x,", (unsigned char)patch[iii]);
   1.171 +        printk("!!\n");
   1.172      }
   1.173  #endif
   1.174  
   1.175 - do_the_patch:
   1.176 -    /* Create the patching instruction in a temporary buffer. */
   1.177 -    patch[0] = 0x67;
   1.178 -    patch[1] = 0xff;
   1.179 -    patch[2] = 0x26; /* call <r/m16> */
   1.180 -    *(u16 *)&patch[3] = FIXUP_BUF_USER + fe->fixup_idx;
   1.181 +    if ( put_user(eip + insn_len, (unsigned long *)regs->esp - 1) != 0 )
   1.182 +    {
   1.183 +        DPRINTK("Failed to place return address on user stack.");
   1.184 +        return;
   1.185 +    }
   1.186 +
   1.187 +    /* Success! Return to user land to execute 2nd insn of the pair. */
   1.188 +    regs->esp -= 4;
   1.189 +    regs->eip = FIXUP_BUF_USER + fe->return_idx;
   1.190  
   1.191      /* [SMP] Need to pause other threads while patching. */
   1.192      pgd = pgd_offset(current->mm, eip);
   1.193 @@ -469,8 +501,6 @@ asmlinkage void do_fixup_4gb_segment(str
   1.194      memcpy((char *)veip + (eip & ~PAGE_MASK), patch, PATCH_LEN);
   1.195      kunmap(pte_page(*pte));
   1.196  
   1.197 -    /* Success! Return to user land to execute 2nd insn of the pair. */
   1.198 -    regs->eip = FIXUP_BUF_USER + fe->return_idx;
   1.199      return;
   1.200  }
   1.201  
   1.202 @@ -482,7 +512,7 @@ static int __init fixup_init(void)
   1.203      struct page *_pages[1<<FIXUP_BUF_ORDER], **pages=_pages;
   1.204      int i;
   1.205  
   1.206 -    if ( nosegfixup )
   1.207 +    /*if ( nosegfixup )*/
   1.208          return 0;
   1.209  
   1.210      HYPERVISOR_vm_assist(VMASST_CMD_enable,