ia64/xen-unstable

changeset 5430:bd865b72e7ab

bitkeeper revision 1.1705.1.16 (42a9bd07XRRfLC09WWyRiQyCeXgWTQ)

Manual merge.
author kaf24@firebug.cl.cam.ac.uk
date Fri Jun 10 16:17:11 2005 +0000 (2005-06-10)
parents 957e3573240e 58658b628754
children ed8174531c13
files xen/arch/x86/x86_32/seg_fixup.c
line diff
     1.1 --- a/xen/arch/x86/x86_32/seg_fixup.c	Fri Jun 10 15:18:00 2005 +0000
     1.2 +++ b/xen/arch/x86/x86_32/seg_fixup.c	Fri Jun 10 16:17:11 2005 +0000
     1.3 @@ -277,7 +277,7 @@ int gpf_emulate_4gb(struct cpu_user_regs
     1.4      u32           disp32 = 0;
     1.5      u8            *eip;         /* ptr to instruction start */
     1.6      u8            *pb, b;       /* ptr into instr. / current instr. byte */
     1.7 -    u16           *pseg = NULL; /* segment for memory operand (NULL=default) */
     1.8 +    int            gs_override = 0;
     1.9  
    1.10      /* WARNING: We only work for ring-3 segments. */
    1.11      if ( unlikely(VM86_MODE(regs)) || unlikely(!RING_3(regs)) )
    1.12 @@ -310,30 +310,20 @@ int gpf_emulate_4gb(struct cpu_user_regs
    1.13          switch ( b )
    1.14          {
    1.15          case 0x67: /* Address-size override */
    1.16 -            DPRINTK("Unhandleable prefix byte %02x\n", b);
    1.17 -            goto fixme;
    1.18 +        case 0x2e: /* CS override */
    1.19 +        case 0x3e: /* DS override */
    1.20 +        case 0x26: /* ES override */
    1.21 +        case 0x64: /* FS override */
    1.22 +        case 0x36: /* SS override */
    1.23 +            DPRINTK("Unhandled prefix %02x\n", b);
    1.24 +            goto fail;
    1.25          case 0x66: /* Operand-size override */
    1.26          case 0xf0: /* LOCK */
    1.27          case 0xf2: /* REPNE/REPNZ */
    1.28          case 0xf3: /* REP/REPE/REPZ */
    1.29              break;
    1.30 -        case 0x2e: /* CS override */
    1.31 -            pseg = &regs->cs;
    1.32 -            break;
    1.33 -        case 0x3e: /* DS override */
    1.34 -            pseg = &regs->ds;
    1.35 -            break;
    1.36 -        case 0x26: /* ES override */
    1.37 -            pseg = &regs->es;
    1.38 -            break;
    1.39 -        case 0x64: /* FS override */
    1.40 -            pseg = &regs->fs;
    1.41 -            break;
    1.42          case 0x65: /* GS override */
    1.43 -            pseg = &regs->gs;
    1.44 -            break;
    1.45 -        case 0x36: /* SS override */
    1.46 -            pseg = &regs->ss;
    1.47 +            gs_override = 1;
    1.48              break;
    1.49          default: /* Not a prefix byte */
    1.50              goto done_prefix;
    1.51 @@ -341,6 +331,12 @@ int gpf_emulate_4gb(struct cpu_user_regs
    1.52      }
    1.53   done_prefix:
    1.54  
    1.55 +    if ( !gs_override )
    1.56 +    {
    1.57 +        DPRINTK("Only instructions with GS override\n");
    1.58 +        goto fail;
    1.59 +    }
    1.60 +
    1.61      decode = insn_decode[b]; /* opcode byte */
    1.62      pb++;
    1.63      if ( decode == 0 )
    1.64 @@ -351,12 +347,13 @@ int gpf_emulate_4gb(struct cpu_user_regs
    1.65      
    1.66      if ( !(decode & HAS_MODRM) )
    1.67      {
    1.68 +        /* Must be a <disp32>, or bail. */
    1.69          if ( (decode & 7) != 4 )
    1.70              goto fail;
    1.71  
    1.72          if ( get_user(offset, (u32 *)pb) )
    1.73          {
    1.74 -            DPRINTK("Fault while extracting <disp8>.\n");
    1.75 +            DPRINTK("Fault while extracting <disp32>.\n");
    1.76              goto page_fault;
    1.77          }
    1.78          pb += 4;
    1.79 @@ -394,8 +391,6 @@ int gpf_emulate_4gb(struct cpu_user_regs
    1.80      switch ( modrm >> 6 )
    1.81      {
    1.82      case 0:
    1.83 -        if ( pseg == NULL )
    1.84 -            pseg = &regs->ds;
    1.85          disp32 = 0;
    1.86          if ( rm == 5 ) /* disp32 rather than (EBP) */
    1.87          {
    1.88 @@ -410,8 +405,6 @@ int gpf_emulate_4gb(struct cpu_user_regs
    1.89          break;
    1.90  
    1.91      case 1:
    1.92 -        if ( pseg == NULL ) /* NB. EBP defaults to SS */
    1.93 -            pseg = (rm == 5) ? &regs->ss : &regs->ds;
    1.94          if ( get_user(disp8, pb) )
    1.95          {
    1.96              DPRINTK("Fault while extracting <disp8>.\n");
    1.97 @@ -422,8 +415,6 @@ int gpf_emulate_4gb(struct cpu_user_regs
    1.98          break;
    1.99  
   1.100      case 2:
   1.101 -        if ( pseg == NULL ) /* NB. EBP defaults to SS */
   1.102 -            pseg = (rm == 5) ? &regs->ss : &regs->ds;
   1.103          if ( get_user(disp32, (u32 *)pb) )
   1.104          {
   1.105              DPRINTK("Fault while extracting <disp8>.\n");
   1.106 @@ -442,7 +433,7 @@ int gpf_emulate_4gb(struct cpu_user_regs
   1.107          offset += *(u32 *)memreg;
   1.108  
   1.109   skip_modrm:
   1.110 -    if ( !fixup_seg((u16)(*pseg), offset) )
   1.111 +    if ( !fixup_seg((u16)regs->gs, offset) )
   1.112          goto fail;
   1.113  
   1.114      /* Success! */