mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
bitkeeper revision 1.1159.258.166 (42a9bca7SPmMRozAfET0WOMKS0VQZA)
Fix and simplify the seg_fixup code. It only needs to handle instructions with GS override. Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
f88b78b9b6
commit
6a3e7b2035
1 file changed
+18
-27
@@ -292,7 +292,7 @@ int gpf_emulate_4gb(struct xen_regs *regs)
|
||||
u32 disp32 = 0;
|
||||
u8 *eip; /* ptr to instruction start */
|
||||
u8 *pb, b; /* ptr into instr. / current instr. byte */
|
||||
unsigned int *pseg = NULL; /* segment for memory operand (NULL=default) */
|
||||
int gs_override = 0;
|
||||
|
||||
/* WARNING: We only work for ring-3 segments. */
|
||||
if ( unlikely(VM86_MODE(regs)) || unlikely(!RING_3(regs)) )
|
||||
@@ -325,30 +325,20 @@ int gpf_emulate_4gb(struct xen_regs *regs)
|
||||
switch ( b )
|
||||
{
|
||||
case 0x67: /* Address-size override */
|
||||
DPRINTK("Unhandleable prefix byte %02x\n", b);
|
||||
goto fixme;
|
||||
case 0x2e: /* CS override */
|
||||
case 0x3e: /* DS override */
|
||||
case 0x26: /* ES override */
|
||||
case 0x64: /* FS override */
|
||||
case 0x36: /* SS override */
|
||||
DPRINTK("Unhandled prefix %02x\n", b);
|
||||
goto fail;
|
||||
case 0x66: /* Operand-size override */
|
||||
case 0xf0: /* LOCK */
|
||||
case 0xf2: /* REPNE/REPNZ */
|
||||
case 0xf3: /* REP/REPE/REPZ */
|
||||
break;
|
||||
case 0x2e: /* CS override */
|
||||
pseg = ®s->cs;
|
||||
break;
|
||||
case 0x3e: /* DS override */
|
||||
pseg = ®s->ds;
|
||||
break;
|
||||
case 0x26: /* ES override */
|
||||
pseg = ®s->es;
|
||||
break;
|
||||
case 0x64: /* FS override */
|
||||
pseg = ®s->fs;
|
||||
break;
|
||||
case 0x65: /* GS override */
|
||||
pseg = ®s->gs;
|
||||
break;
|
||||
case 0x36: /* SS override */
|
||||
pseg = ®s->ss;
|
||||
gs_override = 1;
|
||||
break;
|
||||
default: /* Not a prefix byte */
|
||||
goto done_prefix;
|
||||
@@ -356,6 +346,12 @@ int gpf_emulate_4gb(struct xen_regs *regs)
|
||||
}
|
||||
done_prefix:
|
||||
|
||||
if ( !gs_override )
|
||||
{
|
||||
DPRINTK("Only instructions with GS override\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
decode = insn_decode[b]; /* opcode byte */
|
||||
pb++;
|
||||
if ( decode == 0 )
|
||||
@@ -366,12 +362,13 @@ int gpf_emulate_4gb(struct xen_regs *regs)
|
||||
|
||||
if ( !(decode & HAS_MODRM) )
|
||||
{
|
||||
/* Must be a <disp32>, or bail. */
|
||||
if ( (decode & 7) != 4 )
|
||||
goto fail;
|
||||
|
||||
if ( get_user(offset, (u32 *)pb) )
|
||||
{
|
||||
DPRINTK("Fault while extracting <disp8>.\n");
|
||||
DPRINTK("Fault while extracting <disp32>.\n");
|
||||
goto page_fault;
|
||||
}
|
||||
pb += 4;
|
||||
@@ -409,8 +406,6 @@ int gpf_emulate_4gb(struct xen_regs *regs)
|
||||
switch ( modrm >> 6 )
|
||||
{
|
||||
case 0:
|
||||
if ( pseg == NULL )
|
||||
pseg = ®s->ds;
|
||||
disp32 = 0;
|
||||
if ( rm == 5 ) /* disp32 rather than (EBP) */
|
||||
{
|
||||
@@ -425,8 +420,6 @@ int gpf_emulate_4gb(struct xen_regs *regs)
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if ( pseg == NULL ) /* NB. EBP defaults to SS */
|
||||
pseg = (rm == 5) ? ®s->ss : ®s->ds;
|
||||
if ( get_user(disp8, pb) )
|
||||
{
|
||||
DPRINTK("Fault while extracting <disp8>.\n");
|
||||
@@ -437,8 +430,6 @@ int gpf_emulate_4gb(struct xen_regs *regs)
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if ( pseg == NULL ) /* NB. EBP defaults to SS */
|
||||
pseg = (rm == 5) ? ®s->ss : ®s->ds;
|
||||
if ( get_user(disp32, (u32 *)pb) )
|
||||
{
|
||||
DPRINTK("Fault while extracting <disp8>.\n");
|
||||
@@ -457,7 +448,7 @@ int gpf_emulate_4gb(struct xen_regs *regs)
|
||||
offset += *(u32 *)memreg;
|
||||
|
||||
skip_modrm:
|
||||
if ( !fixup_seg((u16)(*pseg), offset) )
|
||||
if ( !fixup_seg((u16)regs->gs, offset) )
|
||||
goto fail;
|
||||
|
||||
/* Success! */
|
||||
|
||||