debuggers.hg

annotate xen/arch/x86/x86_32/seg_fixup.c @ 3674:fb875591fd72

bitkeeper revision 1.1159.223.63 (42028527-fv-d9BM0_LRp8UKGP19gQ)

Fix NMI deferral.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Thu Feb 03 20:10:15 2005 +0000 (2005-02-03)
parents 983a02b6959a
children 7a4e8660d4f4 58658b628754
rev   line source
kaf24@2704 1 /******************************************************************************
kaf24@2704 2 * arch/x86/x86_32/seg_fixup.c
kaf24@2704 3 *
kaf24@2704 4 * Support for -ve accesses to pseudo-4GB segments.
kaf24@2704 5 *
kaf24@2704 6 * Copyright (c) 2004, K A Fraser
kaf24@2704 7 *
kaf24@2704 8 * This program is free software; you can redistribute it and/or modify
kaf24@2704 9 * it under the terms of the GNU General Public License as published by
kaf24@2704 10 * the Free Software Foundation; either version 2 of the License, or
kaf24@2704 11 * (at your option) any later version.
kaf24@2704 12 *
kaf24@2704 13 * This program is distributed in the hope that it will be useful,
kaf24@2704 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
kaf24@2704 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kaf24@2704 16 * GNU General Public License for more details.
kaf24@2704 17 *
kaf24@2704 18 * You should have received a copy of the GNU General Public License
kaf24@2704 19 * along with this program; if not, write to the Free Software
kaf24@2704 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
kaf24@2704 21 */
kaf24@2704 22
kaf24@2704 23 #include <xen/config.h>
kaf24@2704 24 #include <xen/init.h>
kaf24@2704 25 #include <xen/sched.h>
kaf24@2704 26 #include <xen/lib.h>
kaf24@2704 27 #include <xen/errno.h>
kaf24@2704 28 #include <xen/mm.h>
kaf24@2704 29 #include <xen/perfc.h>
kaf24@2704 30 #include <asm/processor.h>
kaf24@2704 31
kaf24@2704 32 /* Make the scary benign errors go away. */
kaf24@2704 33 #undef DPRINTK
kaf24@2704 34 #define DPRINTK(_f, _a...) ((void)0)
kaf24@2704 35
kaf24@2704 36 /* General instruction properties. */
kaf24@2704 37 #define INSN_SUFFIX_BYTES (7)
kaf24@2704 38 #define OPCODE_BYTE (1<<4)
kaf24@2704 39 #define HAS_MODRM (1<<5)
kaf24@2704 40
kaf24@2704 41 /* Short forms for the table. */
kaf24@2704 42 #define X 0 /* invalid for some random reason */
kaf24@2704 43 #define O OPCODE_BYTE
kaf24@2704 44 #define M HAS_MODRM
kaf24@2704 45
kaf24@2704 46 static unsigned char insn_decode[256] = {
kaf24@2704 47 /* 0x00 - 0x0F */
kaf24@2704 48 O|M, O|M, O|M, O|M, X, X, X, X,
kaf24@2704 49 O|M, O|M, O|M, O|M, X, X, X, X,
kaf24@2704 50 /* 0x10 - 0x1F */
kaf24@2704 51 O|M, O|M, O|M, O|M, X, X, X, X,
kaf24@2704 52 O|M, O|M, O|M, O|M, X, X, X, X,
kaf24@2704 53 /* 0x20 - 0x2F */
kaf24@2704 54 O|M, O|M, O|M, O|M, X, X, X, X,
kaf24@2704 55 O|M, O|M, O|M, O|M, X, X, X, X,
kaf24@2704 56 /* 0x30 - 0x3F */
kaf24@2704 57 O|M, O|M, O|M, O|M, X, X, X, X,
kaf24@2704 58 O|M, O|M, O|M, O|M, X, X, X, X,
kaf24@2704 59 /* 0x40 - 0x4F */
kaf24@2704 60 X, X, X, X, X, X, X, X,
kaf24@2704 61 X, X, X, X, X, X, X, X,
kaf24@2704 62 /* 0x50 - 0x5F */
kaf24@2704 63 X, X, X, X, X, X, X, X,
kaf24@2704 64 X, X, X, X, X, X, X, X,
kaf24@2704 65 /* 0x60 - 0x6F */
kaf24@2704 66 X, X, X, X, X, X, X, X,
kaf24@2704 67 X, O|M|4, X, O|M|1, X, X, X, X,
kaf24@2704 68 /* 0x70 - 0x7F */
kaf24@2704 69 X, X, X, X, X, X, X, X,
kaf24@2704 70 X, X, X, X, X, X, X, X,
kaf24@2704 71 /* 0x80 - 0x8F */
kaf24@2704 72 O|M|1, O|M|4, O|M|1, O|M|1, O|M, O|M, O|M, O|M,
kaf24@2704 73 O|M, O|M, O|M, O|M, O|M, O|M, O|M, X,
kaf24@2704 74 /* 0x90 - 0x9F */
kaf24@2704 75 X, X, X, X, X, X, X, X,
kaf24@2704 76 X, X, X, X, X, X, X, X,
kaf24@2704 77 /* 0xA0 - 0xAF */
kaf24@3464 78 O|4, O|4, O|4, O|4, X, X, X, X,
kaf24@2704 79 X, X, X, X, X, X, X, X,
kaf24@2704 80 /* 0xB0 - 0xBF */
kaf24@2704 81 X, X, X, X, X, X, X, X,
kaf24@2704 82 X, X, X, X, X, X, X, X,
kaf24@2704 83 /* 0xC0 - 0xCF */
kaf24@2704 84 O|M|1, O|M|1, X, X, X, X, O|M|1, O|M|4,
kaf24@2704 85 X, X, X, X, X, X, X, X,
kaf24@2704 86 /* 0xD0 - 0xDF */
kaf24@2704 87 O|M, O|M, O|M, O|M, X, X, X, X,
kaf24@2704 88 X, X, X, X, X, X, X, X,
kaf24@2704 89 /* 0xE0 - 0xEF */
kaf24@2704 90 X, X, X, X, X, X, X, X,
kaf24@2704 91 X, X, X, X, X, X, X, X,
kaf24@2704 92 /* 0xF0 - 0xFF */
kaf24@2704 93 X, X, X, X, X, X, X, X,
kaf24@2704 94 X, X, X, X, X, X, O|M, O|M
kaf24@2704 95 };
kaf24@2704 96
kaf24@2704 97 /*
kaf24@2704 98 * Obtain the base and limit associated with the given segment selector.
kaf24@2704 99 * The selector must identify a 32-bit code or data segment. Any segment that
kaf24@2704 100 * appears to be truncated to not overlap with Xen is assumed to be a truncated
kaf24@2704 101 * 4GB segment, and the returned limit reflects this.
kaf24@2704 102 * @seg (IN) : Segment selector to decode.
kaf24@2704 103 * @base (OUT): Decoded linear base address.
kaf24@2704 104 * @limit (OUT): Decoded segment limit, in bytes. 0 == unlimited (4GB).
kaf24@2704 105 */
kaf24@2704 106 int get_baselimit(u16 seg, unsigned long *base, unsigned long *limit)
kaf24@2704 107 {
kaf24@2704 108 struct domain *d = current;
kaf24@2704 109 unsigned long *table, a, b;
kaf24@2704 110 int ldt = !!(seg & 4);
kaf24@2704 111 int idx = (seg >> 3) & 8191;
kaf24@2704 112
kaf24@2704 113 /* Get base and check limit. */
kaf24@2704 114 if ( ldt )
kaf24@2704 115 {
kaf24@2704 116 table = (unsigned long *)LDT_VIRT_START;
kaf24@2704 117 if ( idx >= d->mm.ldt_ents )
kaf24@2704 118 goto fail;
kaf24@2704 119 }
kaf24@2704 120 else /* gdt */
kaf24@2704 121 {
kaf24@2704 122 table = (unsigned long *)GET_GDT_ADDRESS(d);
kaf24@2704 123 if ( idx >= GET_GDT_ENTRIES(d) )
kaf24@2704 124 goto fail;
kaf24@2704 125 }
kaf24@2704 126
kaf24@2704 127 /* Grab the segment descriptor. */
kaf24@2704 128 if ( __get_user(a, &table[2*idx+0]) ||
kaf24@2704 129 __get_user(b, &table[2*idx+1]) )
kaf24@2704 130 goto fail; /* Barking up the wrong tree. Decode needs a page fault.*/
kaf24@2704 131
kaf24@2704 132 /* We only parse 32-bit code and data segments. */
kaf24@2704 133 if ( (b & (_SEGMENT_P|_SEGMENT_S|_SEGMENT_DB)) !=
kaf24@2704 134 (_SEGMENT_P|_SEGMENT_S|_SEGMENT_DB) )
kaf24@2704 135 goto fail;
kaf24@2704 136
kaf24@2704 137 /* Decode base and limit. */
kaf24@2704 138 *base = (b&(0xff<<24)) | ((b&0xff)<<16) | (a>>16);
kaf24@2704 139 *limit = ((b & 0xf0000) | (a & 0x0ffff)) + 1;
kaf24@2704 140 if ( (b & _SEGMENT_G) )
kaf24@2704 141 *limit <<= 12;
kaf24@2704 142
kaf24@2704 143 /*
kaf24@2704 144 * Anything that looks like a truncated segment we assume ought really
kaf24@2704 145 * to be a 4GB segment. DANGER!
kaf24@2704 146 */
kaf24@2704 147 if ( (PAGE_OFFSET - (*base + *limit)) < PAGE_SIZE )
kaf24@2704 148 *limit = 0;
kaf24@2704 149
kaf24@2704 150 return 1;
kaf24@2704 151
kaf24@2704 152 fail:
kaf24@2704 153 return 0;
kaf24@2704 154 }
kaf24@2704 155
kaf24@2704 156 /* Turn a segment+offset into a linear address. */
kaf24@2704 157 int linearise_address(u16 seg, unsigned long off, unsigned long *linear)
kaf24@2704 158 {
kaf24@2704 159 unsigned long base, limit;
kaf24@2704 160
kaf24@2704 161 if ( !get_baselimit(seg, &base, &limit) )
kaf24@2704 162 return 0;
kaf24@2704 163
kaf24@2704 164 if ( off > (limit-1) )
kaf24@2704 165 return 0;
kaf24@2704 166
kaf24@2704 167 *linear = base + off;
kaf24@2704 168
kaf24@2704 169 return 1;
kaf24@2704 170 }
kaf24@2704 171
mafetter@3155 172 int fixup_seg(u16 seg, unsigned long offset)
kaf24@2704 173 {
kaf24@2704 174 struct domain *d = current;
kaf24@2704 175 unsigned long *table, a, b, base, limit;
kaf24@2704 176 int ldt = !!(seg & 4);
kaf24@2704 177 int idx = (seg >> 3) & 8191;
kaf24@2704 178
kaf24@2704 179 /* Get base and check limit. */
kaf24@2704 180 if ( ldt )
kaf24@2704 181 {
kaf24@2704 182 table = (unsigned long *)LDT_VIRT_START;
kaf24@2704 183 if ( idx >= d->mm.ldt_ents )
kaf24@2704 184 {
kaf24@3449 185 DPRINTK("Segment %04x out of LDT range (%ld)\n",
kaf24@2704 186 seg, d->mm.ldt_ents);
kaf24@2704 187 goto fail;
kaf24@2704 188 }
kaf24@2704 189 }
kaf24@2704 190 else /* gdt */
kaf24@2704 191 {
kaf24@2704 192 table = (unsigned long *)GET_GDT_ADDRESS(d);
kaf24@2704 193 if ( idx >= GET_GDT_ENTRIES(d) )
kaf24@2704 194 {
kaf24@2704 195 DPRINTK("Segment %04x out of GDT range (%d)\n",
kaf24@2704 196 seg, GET_GDT_ENTRIES(d));
kaf24@2704 197 goto fail;
kaf24@2704 198 }
kaf24@2704 199 }
kaf24@2704 200
kaf24@2704 201 /* Grab the segment descriptor. */
kaf24@2704 202 if ( __get_user(a, &table[2*idx+0]) ||
kaf24@2704 203 __get_user(b, &table[2*idx+1]) )
kaf24@2704 204 {
kaf24@2704 205 DPRINTK("Fault while reading segment %04x\n", seg);
kaf24@2704 206 goto fail; /* Barking up the wrong tree. Decode needs a page fault.*/
kaf24@2704 207 }
kaf24@2704 208
kaf24@2704 209 /* We only parse 32-bit page-granularity non-privileged data segments. */
kaf24@2704 210 if ( (b & (_SEGMENT_P|_SEGMENT_S|_SEGMENT_DB|
mafetter@3155 211 _SEGMENT_G|_SEGMENT_CODE|_SEGMENT_DPL)) !=
kaf24@2704 212 (_SEGMENT_P|_SEGMENT_S|_SEGMENT_DB|_SEGMENT_G|_SEGMENT_DPL) )
kaf24@2704 213 {
kaf24@2704 214 DPRINTK("Bad segment %08lx:%08lx\n", a, b);
kaf24@2704 215 goto fail;
kaf24@2704 216 }
kaf24@2704 217
kaf24@2704 218 /* Decode base and limit. */
kaf24@2704 219 base = (b&(0xff<<24)) | ((b&0xff)<<16) | (a>>16);
kaf24@2704 220 limit = (((b & 0xf0000) | (a & 0x0ffff)) + 1) << 12;
kaf24@2704 221
mafetter@3155 222 if ( b & _SEGMENT_EC )
kaf24@2704 223 {
kaf24@2704 224 /* Expands-down: All the way to zero? Assume 4GB if so. */
mafetter@3155 225 if ( ((base + limit) < PAGE_SIZE) && (offset <= limit) )
kaf24@2704 226 {
kaf24@2704 227 /* Flip to expands-up. */
kaf24@3137 228 limit = PAGE_OFFSET - base;
kaf24@2704 229 goto flip;
kaf24@2704 230 }
kaf24@2704 231 }
kaf24@2704 232 else
kaf24@2704 233 {
kaf24@3449 234 /* Expands-up: All the way to Xen space? Assume 4GB if so. */
mafetter@3155 235 if ( ((PAGE_OFFSET - (base + limit)) < PAGE_SIZE) &&
kaf24@3449 236 (offset > limit) )
kaf24@2704 237 {
kaf24@2704 238 /* Flip to expands-down. */
kaf24@3137 239 limit = -(base & PAGE_MASK);
kaf24@2704 240 goto flip;
kaf24@2704 241 }
kaf24@2704 242 }
kaf24@2704 243
kaf24@3449 244 DPRINTK("None of the above! (%08lx:%08lx, %08lx, %08lx, %08lx)\n",
kaf24@3449 245 a, b, base, limit, base+limit);
kaf24@2704 246
kaf24@2704 247 fail:
kaf24@2704 248 return 0;
kaf24@2704 249
kaf24@2704 250 flip:
kaf24@3137 251 limit = (limit >> 12) - 1;
kaf24@2704 252 a &= ~0x0ffff; a |= limit & 0x0ffff;
kaf24@2704 253 b &= ~0xf0000; b |= limit & 0xf0000;
mafetter@3155 254 b ^= _SEGMENT_EC; /* grows-up <-> grows-down */
kaf24@2704 255 /* NB. These can't fault. Checked readable above; must also be writable. */
kaf24@2704 256 table[2*idx+0] = a;
kaf24@2704 257 table[2*idx+1] = b;
kaf24@2704 258 return 1;
kaf24@2704 259 }
kaf24@2704 260
kaf24@2704 261 /* Decode Reg field of a ModRM byte: return a pointer into a register block. */
ach61@2843 262 void *decode_reg(struct xen_regs *regs, u8 b)
kaf24@2704 263 {
kaf24@2704 264 switch ( b & 7 )
kaf24@2704 265 {
kaf24@2704 266 case 0: return &regs->eax;
kaf24@2704 267 case 1: return &regs->ecx;
kaf24@2704 268 case 2: return &regs->edx;
kaf24@2704 269 case 3: return &regs->ebx;
kaf24@2704 270 case 4: return &regs->esp;
kaf24@2704 271 case 5: return &regs->ebp;
kaf24@2704 272 case 6: return &regs->esi;
kaf24@2704 273 case 7: return &regs->edi;
kaf24@2704 274 }
kaf24@2704 275
kaf24@2704 276 return NULL;
kaf24@2704 277 }
kaf24@2704 278
kaf24@2704 279 /*
kaf24@2704 280 * Called from the general-protection fault handler to attempt to decode
kaf24@3462 281 * and emulate an instruction that depends on 4GB segments.
kaf24@2704 282 */
ach61@2843 283 int gpf_emulate_4gb(struct xen_regs *regs)
kaf24@2704 284 {
kaf24@2704 285 struct domain *d = current;
kaf24@2704 286 trap_info_t *ti;
kaf24@3081 287 struct trap_bounce *tb;
kaf24@2704 288 u8 modrm, mod, reg, rm, decode;
kaf24@2704 289 void *memreg, *regreg;
kaf24@2704 290 unsigned long offset;
kaf24@2704 291 u8 disp8;
kaf24@2704 292 u32 disp32 = 0;
kaf24@2704 293 u8 *eip; /* ptr to instruction start */
kaf24@2704 294 u8 *pb, b; /* ptr into instr. / current instr. byte */
kaf24@2704 295 unsigned int *pseg = NULL; /* segment for memory operand (NULL=default) */
kaf24@2704 296
kaf24@2704 297 /* WARNING: We only work for ring-3 segments. */
kaf24@3207 298 if ( unlikely(VM86_MODE(regs)) || unlikely(!RING_3(regs)) )
kaf24@2704 299 {
kaf24@2956 300 DPRINTK("Taken fault at bad CS %04x\n", regs->cs);
kaf24@2704 301 goto fail;
kaf24@2704 302 }
kaf24@2704 303
kaf24@2956 304 if ( !linearise_address((u16)regs->cs, regs->eip, (unsigned long *)&eip) )
kaf24@2704 305 {
kaf24@3449 306 DPRINTK("Cannot linearise %04x:%08x\n", regs->cs, regs->eip);
kaf24@2704 307 goto fail;
kaf24@2704 308 }
kaf24@2704 309
kaf24@2704 310 /* Parse prefix bytes. We're basically looking for segment override. */
kaf24@2704 311 for ( pb = eip; ; pb++ )
kaf24@2704 312 {
kaf24@2704 313 if ( get_user(b, pb) )
kaf24@2704 314 {
kaf24@2704 315 DPRINTK("Fault while accessing byte %d of instruction\n", pb-eip);
kaf24@3462 316 goto page_fault;
kaf24@2704 317 }
kaf24@2704 318
mafetter@3155 319 if ( (pb - eip) >= 15 )
mafetter@3155 320 {
mafetter@3155 321 DPRINTK("Too many instruction prefixes for a legal instruction\n");
mafetter@3155 322 goto fail;
mafetter@3155 323 }
mafetter@3155 324
kaf24@2704 325 switch ( b )
kaf24@2704 326 {
kaf24@2704 327 case 0x67: /* Address-size override */
kaf24@2704 328 DPRINTK("Unhandleable prefix byte %02x\n", b);
kaf24@2704 329 goto fixme;
kaf24@2704 330 case 0x66: /* Operand-size override */
mafetter@3155 331 case 0xf0: /* LOCK */
mafetter@3155 332 case 0xf2: /* REPNE/REPNZ */
mafetter@3155 333 case 0xf3: /* REP/REPE/REPZ */
kaf24@3449 334 break;
kaf24@2704 335 case 0x2e: /* CS override */
kaf24@2956 336 pseg = &regs->cs;
kaf24@3449 337 break;
kaf24@2704 338 case 0x3e: /* DS override */
kaf24@2956 339 pseg = &regs->ds;
kaf24@3449 340 break;
kaf24@2704 341 case 0x26: /* ES override */
kaf24@2956 342 pseg = &regs->es;
kaf24@3449 343 break;
kaf24@2704 344 case 0x64: /* FS override */
kaf24@2956 345 pseg = &regs->fs;
kaf24@3449 346 break;
kaf24@2704 347 case 0x65: /* GS override */
kaf24@2956 348 pseg = &regs->gs;
kaf24@3449 349 break;
kaf24@2704 350 case 0x36: /* SS override */
kaf24@2956 351 pseg = &regs->ss;
kaf24@3449 352 break;
kaf24@2704 353 default: /* Not a prefix byte */
kaf24@2704 354 goto done_prefix;
kaf24@2704 355 }
kaf24@2704 356 }
kaf24@2704 357 done_prefix:
kaf24@2704 358
kaf24@2704 359 decode = insn_decode[b]; /* opcode byte */
kaf24@2704 360 pb++;
kaf24@2704 361 if ( decode == 0 )
kaf24@2704 362 {
kaf24@2704 363 DPRINTK("Unsupported opcode %02x\n", b);
kaf24@2704 364 goto fail;
kaf24@2704 365 }
kaf24@2704 366
kaf24@2704 367 if ( !(decode & HAS_MODRM) )
kaf24@2704 368 {
kaf24@3464 369 if ( (decode & 7) != 4 )
kaf24@3464 370 goto fail;
kaf24@3464 371
kaf24@3464 372 if ( get_user(offset, (u32 *)pb) )
kaf24@2704 373 {
kaf24@3464 374 DPRINTK("Fault while extracting <disp8>.\n");
kaf24@3464 375 goto page_fault;
kaf24@2704 376 }
kaf24@3464 377 pb += 4;
kaf24@3464 378
kaf24@3464 379 goto skip_modrm;
kaf24@2704 380 }
kaf24@2704 381
kaf24@2704 382 /*
kaf24@2704 383 * Mod/RM processing.
kaf24@2704 384 */
kaf24@2704 385
kaf24@2704 386 if ( get_user(modrm, pb) )
kaf24@2704 387 {
kaf24@2704 388 DPRINTK("Fault while extracting modrm byte\n");
kaf24@3462 389 goto page_fault;
kaf24@2704 390 }
kaf24@2704 391
kaf24@2704 392 pb++;
kaf24@2704 393
kaf24@2704 394 mod = (modrm >> 6) & 3;
kaf24@2704 395 reg = (modrm >> 3) & 7;
kaf24@2704 396 rm = (modrm >> 0) & 7;
kaf24@2704 397
kaf24@2704 398 if ( rm == 4 )
kaf24@2704 399 {
kaf24@2704 400 DPRINTK("FIXME: Add decoding for the SIB byte.\n");
kaf24@2704 401 goto fixme;
kaf24@2704 402 }
kaf24@2704 403
kaf24@2704 404 /* Decode Reg and R/M fields. */
kaf24@2704 405 regreg = decode_reg(regs, reg);
kaf24@2704 406 memreg = decode_reg(regs, rm);
kaf24@2704 407
kaf24@2704 408 /* Decode Mod field. */
kaf24@2704 409 switch ( modrm >> 6 )
kaf24@2704 410 {
kaf24@2704 411 case 0:
kaf24@2704 412 if ( pseg == NULL )
kaf24@2956 413 pseg = &regs->ds;
kaf24@2704 414 disp32 = 0;
kaf24@2704 415 if ( rm == 5 ) /* disp32 rather than (EBP) */
kaf24@2704 416 {
kaf24@2704 417 memreg = NULL;
kaf24@2704 418 if ( get_user(disp32, (u32 *)pb) )
kaf24@2704 419 {
kaf24@2704 420 DPRINTK("Fault while extracting <disp8>.\n");
kaf24@3462 421 goto page_fault;
kaf24@2704 422 }
kaf24@2704 423 pb += 4;
kaf24@2704 424 }
kaf24@2704 425 break;
kaf24@2704 426
kaf24@2704 427 case 1:
kaf24@2704 428 if ( pseg == NULL ) /* NB. EBP defaults to SS */
kaf24@2956 429 pseg = (rm == 5) ? &regs->ss : &regs->ds;
kaf24@2704 430 if ( get_user(disp8, pb) )
kaf24@2704 431 {
kaf24@2704 432 DPRINTK("Fault while extracting <disp8>.\n");
kaf24@3462 433 goto page_fault;
kaf24@2704 434 }
kaf24@2704 435 pb++;
kaf24@2704 436 disp32 = (disp8 & 0x80) ? (disp8 | ~0xff) : disp8;;
kaf24@2704 437 break;
kaf24@2704 438
kaf24@2704 439 case 2:
kaf24@2704 440 if ( pseg == NULL ) /* NB. EBP defaults to SS */
kaf24@2956 441 pseg = (rm == 5) ? &regs->ss : &regs->ds;
kaf24@2704 442 if ( get_user(disp32, (u32 *)pb) )
kaf24@2704 443 {
kaf24@2704 444 DPRINTK("Fault while extracting <disp8>.\n");
kaf24@3462 445 goto page_fault;
kaf24@2704 446 }
kaf24@2704 447 pb += 4;
kaf24@2704 448 break;
kaf24@2704 449
kaf24@2704 450 case 3:
kaf24@2704 451 DPRINTK("Not a memory operand!\n");
kaf24@2704 452 goto fail;
kaf24@2704 453 }
kaf24@2704 454
kaf24@2704 455 offset = disp32;
kaf24@2704 456 if ( memreg != NULL )
kaf24@2704 457 offset += *(u32 *)memreg;
kaf24@2704 458
kaf24@2704 459 skip_modrm:
mafetter@3155 460 if ( !fixup_seg((u16)(*pseg), offset) )
kaf24@2704 461 goto fail;
kaf24@2704 462
kaf24@2704 463 /* Success! */
kaf24@2704 464 perfc_incrc(seg_fixups);
kaf24@2704 465
kaf24@2704 466 /* If requested, give a callback on otherwise unused vector 15. */
kaf24@2704 467 if ( VM_ASSIST(d, VMASST_TYPE_4gb_segments_notify) )
kaf24@2704 468 {
kaf24@2704 469 ti = &d->thread.traps[15];
kaf24@3081 470 tb = &d->thread.trap_bounce;
kaf24@3127 471 tb->flags = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE;
kaf24@3081 472 tb->error_code = pb - eip;
kaf24@3081 473 tb->cs = ti->cs;
kaf24@3081 474 tb->eip = ti->address;
kaf24@2704 475 if ( TI_GET_IF(ti) )
kaf24@2704 476 d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
kaf24@2704 477 }
kaf24@2704 478
kaf24@3462 479 return EXCRET_fault_fixed;
kaf24@2704 480
kaf24@2704 481 fixme:
kaf24@2704 482 DPRINTK("Undecodable instruction %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
kaf24@3449 483 "caused GPF(0) at %04x:%08x\n",
kaf24@2704 484 eip[0], eip[1], eip[2], eip[3],
kaf24@2704 485 eip[4], eip[5], eip[6], eip[7],
kaf24@2956 486 regs->cs, regs->eip);
kaf24@2704 487 fail:
kaf24@2704 488 return 0;
kaf24@3462 489
kaf24@3462 490 page_fault:
kaf24@3462 491 propagate_page_fault((unsigned long)pb, 4);
kaf24@3462 492 return EXCRET_fault_fixed;
kaf24@2704 493 }