1 /* 2 * x86 segmentation related helpers: 3 * TSS, interrupts, system calls, jumps and call/task gates, descriptors 4 * 5 * Copyright (c) 2003 Fabrice Bellard 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "qemu/osdep.h" 22 #include "cpu.h" 23 #include "qemu/log.h" 24 #include "exec/helper-proto.h" 25 #include "exec/exec-all.h" 26 #include "exec/cpu_ldst.h" 27 #include "exec/log.h" 28 #include "helper-tcg.h" 29 #include "seg_helper.h" 30 #include "access.h" 31 32 #ifdef TARGET_X86_64 33 #define SET_ESP(val, sp_mask) \ 34 do { \ 35 if ((sp_mask) == 0xffff) { \ 36 env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | \ 37 ((val) & 0xffff); \ 38 } else if ((sp_mask) == 0xffffffffLL) { \ 39 env->regs[R_ESP] = (uint32_t)(val); \ 40 } else { \ 41 env->regs[R_ESP] = (val); \ 42 } \ 43 } while (0) 44 #else 45 #define SET_ESP(val, sp_mask) \ 46 do { \ 47 env->regs[R_ESP] = (env->regs[R_ESP] & ~(sp_mask)) | \ 48 ((val) & (sp_mask)); \ 49 } while (0) 50 #endif 51 52 /* XXX: use mmu_index to have proper DPL support */ 53 typedef struct StackAccess 54 { 55 CPUX86State *env; 56 uintptr_t ra; 57 target_ulong ss_base; 58 target_ulong sp; 59 target_ulong sp_mask; 60 int mmu_index; 61 } StackAccess; 62 63 static void pushw(StackAccess *sa, uint16_t val) 64 { 65 sa->sp -= 2; 66 cpu_stw_mmuidx_ra(sa->env, sa->ss_base + (sa->sp & sa->sp_mask), 67 val, sa->mmu_index, sa->ra); 68 } 69 70 static void pushl(StackAccess *sa, uint32_t val) 71 { 72 sa->sp -= 4; 73 cpu_stl_mmuidx_ra(sa->env, sa->ss_base + (sa->sp & sa->sp_mask), 74 val, sa->mmu_index, sa->ra); 75 } 76 77 static uint16_t popw(StackAccess *sa) 78 { 79 uint16_t ret = cpu_lduw_mmuidx_ra(sa->env, 80 sa->ss_base + (sa->sp & sa->sp_mask), 81 sa->mmu_index, sa->ra); 82 sa->sp += 2; 83 return ret; 84 } 85 86 static uint32_t popl(StackAccess *sa) 87 { 88 uint32_t ret = cpu_ldl_mmuidx_ra(sa->env, 89 sa->ss_base + (sa->sp & sa->sp_mask), 90 sa->mmu_index, sa->ra); 91 sa->sp += 4; 92 return ret; 93 } 94 95 int get_pg_mode(CPUX86State *env) 96 { 97 int pg_mode = 0; 98 if (!(env->cr[0] & CR0_PG_MASK)) { 99 return 0; 100 } 101 if (env->cr[0] & CR0_WP_MASK) { 102 pg_mode |= PG_MODE_WP; 103 } 104 if (env->cr[4] & CR4_PAE_MASK) { 105 pg_mode |= PG_MODE_PAE; 106 if (env->efer & MSR_EFER_NXE) { 107 pg_mode |= PG_MODE_NXE; 108 } 109 } 110 if (env->cr[4] & CR4_PSE_MASK) { 111 pg_mode |= PG_MODE_PSE; 112 } 113 if (env->cr[4] & CR4_SMEP_MASK) { 114 pg_mode |= PG_MODE_SMEP; 115 } 116 if (env->hflags & HF_LMA_MASK) { 117 pg_mode |= PG_MODE_LMA; 118 if (env->cr[4] & CR4_PKE_MASK) { 119 pg_mode |= PG_MODE_PKE; 120 } 121 if (env->cr[4] & CR4_PKS_MASK) { 122 pg_mode |= PG_MODE_PKS; 123 } 124 if (env->cr[4] & CR4_LA57_MASK) { 125 pg_mode |= PG_MODE_LA57; 126 } 127 } 128 return pg_mode; 129 } 130 131 /* return non zero if error */ 132 static inline int load_segment_ra(CPUX86State *env, uint32_t *e1_ptr, 133 uint32_t *e2_ptr, int selector, 134 uintptr_t retaddr) 135 { 136 SegmentCache *dt; 137 int index; 138 target_ulong ptr; 139 140 if (selector & 0x4) { 141 dt = &env->ldt; 142 } else { 143 dt = &env->gdt; 144 } 145 index = selector & ~7; 146 if ((index + 7) > dt->limit) { 147 return -1; 148 } 149 ptr = dt->base + index; 150 *e1_ptr = cpu_ldl_kernel_ra(env, ptr, retaddr); 151 *e2_ptr = cpu_ldl_kernel_ra(env, ptr + 4, retaddr); 152 return 0; 153 } 154 155 static inline int load_segment(CPUX86State *env, uint32_t *e1_ptr, 156 uint32_t *e2_ptr, int selector) 157 { 158 return load_segment_ra(env, e1_ptr, e2_ptr, selector, 0); 159 } 160 161 static inline unsigned int get_seg_limit(uint32_t e1, uint32_t e2) 162 { 163 unsigned int limit; 164 165 limit = (e1 & 0xffff) | (e2 & 0x000f0000); 166 if (e2 & DESC_G_MASK) { 167 limit = (limit << 12) | 0xfff; 168 } 169 return limit; 170 } 171 172 static inline uint32_t get_seg_base(uint32_t e1, uint32_t e2) 173 { 174 return (e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000); 175 } 176 177 static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, 178 uint32_t e2) 179 { 180 sc->base = get_seg_base(e1, e2); 181 sc->limit = get_seg_limit(e1, e2); 182 sc->flags = e2; 183 } 184 185 /* init the segment cache in vm86 mode. */ 186 static inline void load_seg_vm(CPUX86State *env, int seg, int selector) 187 { 188 selector &= 0xffff; 189 190 cpu_x86_load_seg_cache(env, seg, selector, (selector << 4), 0xffff, 191 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | 192 DESC_A_MASK | (3 << DESC_DPL_SHIFT)); 193 } 194 195 static inline void get_ss_esp_from_tss(CPUX86State *env, uint32_t *ss_ptr, 196 uint32_t *esp_ptr, int dpl, 197 uintptr_t retaddr) 198 { 199 X86CPU *cpu = env_archcpu(env); 200 int type, index, shift; 201 202 #if 0 203 { 204 int i; 205 printf("TR: base=%p limit=%x\n", env->tr.base, env->tr.limit); 206 for (i = 0; i < env->tr.limit; i++) { 207 printf("%02x ", env->tr.base[i]); 208 if ((i & 7) == 7) { 209 printf("\n"); 210 } 211 } 212 printf("\n"); 213 } 214 #endif 215 216 if (!(env->tr.flags & DESC_P_MASK)) { 217 cpu_abort(CPU(cpu), "invalid tss"); 218 } 219 type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf; 220 if ((type & 7) != 1) { 221 cpu_abort(CPU(cpu), "invalid tss type"); 222 } 223 shift = type >> 3; 224 index = (dpl * 4 + 2) << shift; 225 if (index + (4 << shift) - 1 > env->tr.limit) { 226 raise_exception_err_ra(env, EXCP0A_TSS, env->tr.selector & 0xfffc, retaddr); 227 } 228 if (shift == 0) { 229 *esp_ptr = cpu_lduw_kernel_ra(env, env->tr.base + index, retaddr); 230 *ss_ptr = cpu_lduw_kernel_ra(env, env->tr.base + index + 2, retaddr); 231 } else { 232 *esp_ptr = cpu_ldl_kernel_ra(env, env->tr.base + index, retaddr); 233 *ss_ptr = cpu_lduw_kernel_ra(env, env->tr.base + index + 4, retaddr); 234 } 235 } 236 237 static void tss_load_seg(CPUX86State *env, X86Seg seg_reg, int selector, 238 int cpl, uintptr_t retaddr) 239 { 240 uint32_t e1, e2; 241 int rpl, dpl; 242 243 if ((selector & 0xfffc) != 0) { 244 if (load_segment_ra(env, &e1, &e2, selector, retaddr) != 0) { 245 raise_exception_err_ra(env, EXCP0A_TSS, selector & 0xfffc, retaddr); 246 } 247 if (!(e2 & DESC_S_MASK)) { 248 raise_exception_err_ra(env, EXCP0A_TSS, selector & 0xfffc, retaddr); 249 } 250 rpl = selector & 3; 251 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 252 if (seg_reg == R_CS) { 253 if (!(e2 & DESC_CS_MASK)) { 254 raise_exception_err_ra(env, EXCP0A_TSS, selector & 0xfffc, retaddr); 255 } 256 if (dpl != rpl) { 257 raise_exception_err_ra(env, EXCP0A_TSS, selector & 0xfffc, retaddr); 258 } 259 } else if (seg_reg == R_SS) { 260 /* SS must be writable data */ 261 if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) { 262 raise_exception_err_ra(env, EXCP0A_TSS, selector & 0xfffc, retaddr); 263 } 264 if (dpl != cpl || dpl != rpl) { 265 raise_exception_err_ra(env, EXCP0A_TSS, selector & 0xfffc, retaddr); 266 } 267 } else { 268 /* not readable code */ 269 if ((e2 & DESC_CS_MASK) && !(e2 & DESC_R_MASK)) { 270 raise_exception_err_ra(env, EXCP0A_TSS, selector & 0xfffc, retaddr); 271 } 272 /* if data or non conforming code, checks the rights */ 273 if (((e2 >> DESC_TYPE_SHIFT) & 0xf) < 12) { 274 if (dpl < cpl || dpl < rpl) { 275 raise_exception_err_ra(env, EXCP0A_TSS, selector & 0xfffc, retaddr); 276 } 277 } 278 } 279 if (!(e2 & DESC_P_MASK)) { 280 raise_exception_err_ra(env, EXCP0B_NOSEG, selector & 0xfffc, retaddr); 281 } 282 cpu_x86_load_seg_cache(env, seg_reg, selector, 283 get_seg_base(e1, e2), 284 get_seg_limit(e1, e2), 285 e2); 286 } else { 287 if (seg_reg == R_SS || seg_reg == R_CS) { 288 raise_exception_err_ra(env, EXCP0A_TSS, selector & 0xfffc, retaddr); 289 } 290 } 291 } 292 293 static void tss_set_busy(CPUX86State *env, int tss_selector, bool value, 294 uintptr_t retaddr) 295 { 296 target_ulong ptr = env->gdt.base + (tss_selector & ~7); 297 uint32_t e2 = cpu_ldl_kernel_ra(env, ptr + 4, retaddr); 298 299 if (value) { 300 e2 |= DESC_TSS_BUSY_MASK; 301 } else { 302 e2 &= ~DESC_TSS_BUSY_MASK; 303 } 304 305 cpu_stl_kernel_ra(env, ptr + 4, e2, retaddr); 306 } 307 308 #define SWITCH_TSS_JMP 0 309 #define SWITCH_TSS_IRET 1 310 #define SWITCH_TSS_CALL 2 311 312 /* return 0 if switching to a 16-bit selector */ 313 static int switch_tss_ra(CPUX86State *env, int tss_selector, 314 uint32_t e1, uint32_t e2, int source, 315 uint32_t next_eip, uintptr_t retaddr) 316 { 317 int tss_limit, tss_limit_max, type, old_tss_limit_max, old_type, i; 318 target_ulong tss_base; 319 uint32_t new_regs[8], new_segs[6]; 320 uint32_t new_eflags, new_eip, new_cr3, new_ldt, new_trap; 321 uint32_t old_eflags, eflags_mask; 322 SegmentCache *dt; 323 int mmu_index, index; 324 target_ulong ptr; 325 X86Access old, new; 326 327 type = (e2 >> DESC_TYPE_SHIFT) & 0xf; 328 LOG_PCALL("switch_tss: sel=0x%04x type=%d src=%d\n", tss_selector, type, 329 source); 330 331 /* if task gate, we read the TSS segment and we load it */ 332 if (type == 5) { 333 if (!(e2 & DESC_P_MASK)) { 334 raise_exception_err_ra(env, EXCP0B_NOSEG, tss_selector & 0xfffc, retaddr); 335 } 336 tss_selector = e1 >> 16; 337 if (tss_selector & 4) { 338 raise_exception_err_ra(env, EXCP0A_TSS, tss_selector & 0xfffc, retaddr); 339 } 340 if (load_segment_ra(env, &e1, &e2, tss_selector, retaddr) != 0) { 341 raise_exception_err_ra(env, EXCP0D_GPF, tss_selector & 0xfffc, retaddr); 342 } 343 if (e2 & DESC_S_MASK) { 344 raise_exception_err_ra(env, EXCP0D_GPF, tss_selector & 0xfffc, retaddr); 345 } 346 type = (e2 >> DESC_TYPE_SHIFT) & 0xf; 347 if ((type & 7) != 1) { 348 raise_exception_err_ra(env, EXCP0D_GPF, tss_selector & 0xfffc, retaddr); 349 } 350 } 351 352 if (!(e2 & DESC_P_MASK)) { 353 raise_exception_err_ra(env, EXCP0B_NOSEG, tss_selector & 0xfffc, retaddr); 354 } 355 356 if (type & 8) { 357 tss_limit_max = 103; 358 } else { 359 tss_limit_max = 43; 360 } 361 tss_limit = get_seg_limit(e1, e2); 362 tss_base = get_seg_base(e1, e2); 363 if ((tss_selector & 4) != 0 || 364 tss_limit < tss_limit_max) { 365 raise_exception_err_ra(env, EXCP0A_TSS, tss_selector & 0xfffc, retaddr); 366 } 367 old_type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf; 368 if (old_type & 8) { 369 old_tss_limit_max = 103; 370 } else { 371 old_tss_limit_max = 43; 372 } 373 374 /* new TSS must be busy iff the source is an IRET instruction */ 375 if (!!(e2 & DESC_TSS_BUSY_MASK) != (source == SWITCH_TSS_IRET)) { 376 raise_exception_err_ra(env, EXCP0A_TSS, tss_selector & 0xfffc, retaddr); 377 } 378 379 /* X86Access avoids memory exceptions during the task switch */ 380 mmu_index = cpu_mmu_index_kernel(env); 381 access_prepare_mmu(&old, env, env->tr.base, old_tss_limit_max, 382 MMU_DATA_STORE, mmu_index, retaddr); 383 384 if (source == SWITCH_TSS_CALL) { 385 /* Probe for future write of parent task */ 386 probe_access(env, tss_base, 2, MMU_DATA_STORE, 387 mmu_index, retaddr); 388 } 389 access_prepare_mmu(&new, env, tss_base, tss_limit, 390 MMU_DATA_LOAD, mmu_index, retaddr); 391 392 /* save the current state in the old TSS */ 393 old_eflags = cpu_compute_eflags(env); 394 if (old_type & 8) { 395 /* 32 bit */ 396 access_stl(&old, env->tr.base + 0x20, next_eip); 397 access_stl(&old, env->tr.base + 0x24, old_eflags); 398 access_stl(&old, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]); 399 access_stl(&old, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]); 400 access_stl(&old, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]); 401 access_stl(&old, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]); 402 access_stl(&old, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]); 403 access_stl(&old, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]); 404 access_stl(&old, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]); 405 access_stl(&old, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI]); 406 for (i = 0; i < 6; i++) { 407 access_stw(&old, env->tr.base + (0x48 + i * 4), 408 env->segs[i].selector); 409 } 410 } else { 411 /* 16 bit */ 412 access_stw(&old, env->tr.base + 0x0e, next_eip); 413 access_stw(&old, env->tr.base + 0x10, old_eflags); 414 access_stw(&old, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]); 415 access_stw(&old, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]); 416 access_stw(&old, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]); 417 access_stw(&old, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]); 418 access_stw(&old, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]); 419 access_stw(&old, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]); 420 access_stw(&old, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]); 421 access_stw(&old, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI]); 422 for (i = 0; i < 4; i++) { 423 access_stw(&old, env->tr.base + (0x22 + i * 2), 424 env->segs[i].selector); 425 } 426 } 427 428 /* read all the registers from the new TSS */ 429 if (type & 8) { 430 /* 32 bit */ 431 new_cr3 = access_ldl(&new, tss_base + 0x1c); 432 new_eip = access_ldl(&new, tss_base + 0x20); 433 new_eflags = access_ldl(&new, tss_base + 0x24); 434 for (i = 0; i < 8; i++) { 435 new_regs[i] = access_ldl(&new, tss_base + (0x28 + i * 4)); 436 } 437 for (i = 0; i < 6; i++) { 438 new_segs[i] = access_ldw(&new, tss_base + (0x48 + i * 4)); 439 } 440 new_ldt = access_ldw(&new, tss_base + 0x60); 441 new_trap = access_ldl(&new, tss_base + 0x64); 442 } else { 443 /* 16 bit */ 444 new_cr3 = 0; 445 new_eip = access_ldw(&new, tss_base + 0x0e); 446 new_eflags = access_ldw(&new, tss_base + 0x10); 447 for (i = 0; i < 8; i++) { 448 new_regs[i] = access_ldw(&new, tss_base + (0x12 + i * 2)); 449 } 450 for (i = 0; i < 4; i++) { 451 new_segs[i] = access_ldw(&new, tss_base + (0x22 + i * 2)); 452 } 453 new_ldt = access_ldw(&new, tss_base + 0x2a); 454 new_segs[R_FS] = 0; 455 new_segs[R_GS] = 0; 456 new_trap = 0; 457 } 458 /* XXX: avoid a compiler warning, see 459 http://support.amd.com/us/Processor_TechDocs/24593.pdf 460 chapters 12.2.5 and 13.2.4 on how to implement TSS Trap bit */ 461 (void)new_trap; 462 463 /* clear busy bit (it is restartable) */ 464 if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) { 465 tss_set_busy(env, env->tr.selector, 0, retaddr); 466 } 467 468 if (source == SWITCH_TSS_IRET) { 469 old_eflags &= ~NT_MASK; 470 if (old_type & 8) { 471 access_stl(&old, env->tr.base + 0x24, old_eflags); 472 } else { 473 access_stw(&old, env->tr.base + 0x10, old_eflags); 474 } 475 } 476 477 if (source == SWITCH_TSS_CALL) { 478 /* 479 * Thanks to the probe_access above, we know the first two 480 * bytes addressed by &new are writable too. 481 */ 482 access_stw(&new, tss_base, env->tr.selector); 483 new_eflags |= NT_MASK; 484 } 485 486 /* set busy bit */ 487 if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_CALL) { 488 tss_set_busy(env, tss_selector, 1, retaddr); 489 } 490 491 /* set the new CPU state */ 492 493 /* now if an exception occurs, it will occur in the next task context */ 494 495 env->cr[0] |= CR0_TS_MASK; 496 env->hflags |= HF_TS_MASK; 497 env->tr.selector = tss_selector; 498 env->tr.base = tss_base; 499 env->tr.limit = tss_limit; 500 env->tr.flags = e2 & ~DESC_TSS_BUSY_MASK; 501 502 if ((type & 8) && (env->cr[0] & CR0_PG_MASK)) { 503 cpu_x86_update_cr3(env, new_cr3); 504 } 505 506 /* load all registers without an exception, then reload them with 507 possible exception */ 508 env->eip = new_eip; 509 eflags_mask = TF_MASK | AC_MASK | ID_MASK | 510 IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK; 511 if (type & 8) { 512 cpu_load_eflags(env, new_eflags, eflags_mask); 513 for (i = 0; i < 8; i++) { 514 env->regs[i] = new_regs[i]; 515 } 516 } else { 517 cpu_load_eflags(env, new_eflags, eflags_mask & 0xffff); 518 for (i = 0; i < 8; i++) { 519 env->regs[i] = (env->regs[i] & 0xffff0000) | new_regs[i]; 520 } 521 } 522 if (new_eflags & VM_MASK) { 523 for (i = 0; i < 6; i++) { 524 load_seg_vm(env, i, new_segs[i]); 525 } 526 } else { 527 /* first just selectors as the rest may trigger exceptions */ 528 for (i = 0; i < 6; i++) { 529 cpu_x86_load_seg_cache(env, i, new_segs[i], 0, 0, 0); 530 } 531 } 532 533 env->ldt.selector = new_ldt & ~4; 534 env->ldt.base = 0; 535 env->ldt.limit = 0; 536 env->ldt.flags = 0; 537 538 /* load the LDT */ 539 if (new_ldt & 4) { 540 raise_exception_err_ra(env, EXCP0A_TSS, new_ldt & 0xfffc, retaddr); 541 } 542 543 if ((new_ldt & 0xfffc) != 0) { 544 dt = &env->gdt; 545 index = new_ldt & ~7; 546 if ((index + 7) > dt->limit) { 547 raise_exception_err_ra(env, EXCP0A_TSS, new_ldt & 0xfffc, retaddr); 548 } 549 ptr = dt->base + index; 550 e1 = cpu_ldl_kernel_ra(env, ptr, retaddr); 551 e2 = cpu_ldl_kernel_ra(env, ptr + 4, retaddr); 552 if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) { 553 raise_exception_err_ra(env, EXCP0A_TSS, new_ldt & 0xfffc, retaddr); 554 } 555 if (!(e2 & DESC_P_MASK)) { 556 raise_exception_err_ra(env, EXCP0A_TSS, new_ldt & 0xfffc, retaddr); 557 } 558 load_seg_cache_raw_dt(&env->ldt, e1, e2); 559 } 560 561 /* load the segments */ 562 if (!(new_eflags & VM_MASK)) { 563 int cpl = new_segs[R_CS] & 3; 564 tss_load_seg(env, R_CS, new_segs[R_CS], cpl, retaddr); 565 tss_load_seg(env, R_SS, new_segs[R_SS], cpl, retaddr); 566 tss_load_seg(env, R_ES, new_segs[R_ES], cpl, retaddr); 567 tss_load_seg(env, R_DS, new_segs[R_DS], cpl, retaddr); 568 tss_load_seg(env, R_FS, new_segs[R_FS], cpl, retaddr); 569 tss_load_seg(env, R_GS, new_segs[R_GS], cpl, retaddr); 570 } 571 572 /* check that env->eip is in the CS segment limits */ 573 if (new_eip > env->segs[R_CS].limit) { 574 /* XXX: different exception if CALL? */ 575 raise_exception_err_ra(env, EXCP0D_GPF, 0, retaddr); 576 } 577 578 #ifndef CONFIG_USER_ONLY 579 /* reset local breakpoints */ 580 if (env->dr[7] & DR7_LOCAL_BP_MASK) { 581 cpu_x86_update_dr7(env, env->dr[7] & ~DR7_LOCAL_BP_MASK); 582 } 583 #endif 584 return type >> 3; 585 } 586 587 static int switch_tss(CPUX86State *env, int tss_selector, 588 uint32_t e1, uint32_t e2, int source, 589 uint32_t next_eip) 590 { 591 return switch_tss_ra(env, tss_selector, e1, e2, source, next_eip, 0); 592 } 593 594 static inline unsigned int get_sp_mask(unsigned int e2) 595 { 596 #ifdef TARGET_X86_64 597 if (e2 & DESC_L_MASK) { 598 return 0; 599 } else 600 #endif 601 if (e2 & DESC_B_MASK) { 602 return 0xffffffff; 603 } else { 604 return 0xffff; 605 } 606 } 607 608 static int exception_is_fault(int intno) 609 { 610 switch (intno) { 611 /* 612 * #DB can be both fault- and trap-like, but it never sets RF=1 613 * in the RFLAGS value pushed on the stack. 614 */ 615 case EXCP01_DB: 616 case EXCP03_INT3: 617 case EXCP04_INTO: 618 case EXCP08_DBLE: 619 case EXCP12_MCHK: 620 return 0; 621 } 622 /* Everything else including reserved exception is a fault. */ 623 return 1; 624 } 625 626 int exception_has_error_code(int intno) 627 { 628 switch (intno) { 629 case 8: 630 case 10: 631 case 11: 632 case 12: 633 case 13: 634 case 14: 635 case 17: 636 return 1; 637 } 638 return 0; 639 } 640 641 /* protected mode interrupt */ 642 static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, 643 int error_code, unsigned int next_eip, 644 int is_hw) 645 { 646 SegmentCache *dt; 647 target_ulong ptr; 648 int type, dpl, selector, ss_dpl, cpl; 649 int has_error_code, new_stack, shift; 650 uint32_t e1, e2, offset, ss = 0, ss_e1 = 0, ss_e2 = 0; 651 uint32_t old_eip, eflags; 652 int vm86 = env->eflags & VM_MASK; 653 StackAccess sa; 654 bool set_rf; 655 656 has_error_code = 0; 657 if (!is_int && !is_hw) { 658 has_error_code = exception_has_error_code(intno); 659 } 660 if (is_int) { 661 old_eip = next_eip; 662 set_rf = false; 663 } else { 664 old_eip = env->eip; 665 set_rf = exception_is_fault(intno); 666 } 667 668 dt = &env->idt; 669 if (intno * 8 + 7 > dt->limit) { 670 raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); 671 } 672 ptr = dt->base + intno * 8; 673 e1 = cpu_ldl_kernel(env, ptr); 674 e2 = cpu_ldl_kernel(env, ptr + 4); 675 /* check gate type */ 676 type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; 677 switch (type) { 678 case 5: /* task gate */ 679 case 6: /* 286 interrupt gate */ 680 case 7: /* 286 trap gate */ 681 case 14: /* 386 interrupt gate */ 682 case 15: /* 386 trap gate */ 683 break; 684 default: 685 raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); 686 break; 687 } 688 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 689 cpl = env->hflags & HF_CPL_MASK; 690 /* check privilege if software int */ 691 if (is_int && dpl < cpl) { 692 raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); 693 } 694 695 sa.env = env; 696 sa.ra = 0; 697 sa.mmu_index = cpu_mmu_index_kernel(env); 698 699 if (type == 5) { 700 /* task gate */ 701 /* must do that check here to return the correct error code */ 702 if (!(e2 & DESC_P_MASK)) { 703 raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2); 704 } 705 shift = switch_tss(env, intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip); 706 if (has_error_code) { 707 /* push the error code */ 708 if (env->segs[R_SS].flags & DESC_B_MASK) { 709 sa.sp_mask = 0xffffffff; 710 } else { 711 sa.sp_mask = 0xffff; 712 } 713 sa.sp = env->regs[R_ESP]; 714 sa.ss_base = env->segs[R_SS].base; 715 if (shift) { 716 pushl(&sa, error_code); 717 } else { 718 pushw(&sa, error_code); 719 } 720 SET_ESP(sa.sp, sa.sp_mask); 721 } 722 return; 723 } 724 725 /* Otherwise, trap or interrupt gate */ 726 727 /* check valid bit */ 728 if (!(e2 & DESC_P_MASK)) { 729 raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2); 730 } 731 selector = e1 >> 16; 732 offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff); 733 if ((selector & 0xfffc) == 0) { 734 raise_exception_err(env, EXCP0D_GPF, 0); 735 } 736 if (load_segment(env, &e1, &e2, selector) != 0) { 737 raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); 738 } 739 if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) { 740 raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); 741 } 742 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 743 if (dpl > cpl) { 744 raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); 745 } 746 if (!(e2 & DESC_P_MASK)) { 747 raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc); 748 } 749 if (e2 & DESC_C_MASK) { 750 dpl = cpl; 751 } 752 if (dpl < cpl) { 753 /* to inner privilege */ 754 uint32_t esp; 755 get_ss_esp_from_tss(env, &ss, &esp, dpl, 0); 756 if ((ss & 0xfffc) == 0) { 757 raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); 758 } 759 if ((ss & 3) != dpl) { 760 raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); 761 } 762 if (load_segment(env, &ss_e1, &ss_e2, ss) != 0) { 763 raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); 764 } 765 ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; 766 if (ss_dpl != dpl) { 767 raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); 768 } 769 if (!(ss_e2 & DESC_S_MASK) || 770 (ss_e2 & DESC_CS_MASK) || 771 !(ss_e2 & DESC_W_MASK)) { 772 raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); 773 } 774 if (!(ss_e2 & DESC_P_MASK)) { 775 raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); 776 } 777 new_stack = 1; 778 sa.sp = esp; 779 sa.sp_mask = get_sp_mask(ss_e2); 780 sa.ss_base = get_seg_base(ss_e1, ss_e2); 781 } else { 782 /* to same privilege */ 783 if (vm86) { 784 raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); 785 } 786 new_stack = 0; 787 sa.sp = env->regs[R_ESP]; 788 sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); 789 sa.ss_base = env->segs[R_SS].base; 790 } 791 792 shift = type >> 3; 793 794 #if 0 795 /* XXX: check that enough room is available */ 796 push_size = 6 + (new_stack << 2) + (has_error_code << 1); 797 if (vm86) { 798 push_size += 8; 799 } 800 push_size <<= shift; 801 #endif 802 eflags = cpu_compute_eflags(env); 803 /* 804 * AMD states that code breakpoint #DBs clear RF=0, Intel leaves it 805 * as is. AMD behavior could be implemented in check_hw_breakpoints(). 806 */ 807 if (set_rf) { 808 eflags |= RF_MASK; 809 } 810 811 if (shift == 1) { 812 if (new_stack) { 813 if (vm86) { 814 pushl(&sa, env->segs[R_GS].selector); 815 pushl(&sa, env->segs[R_FS].selector); 816 pushl(&sa, env->segs[R_DS].selector); 817 pushl(&sa, env->segs[R_ES].selector); 818 } 819 pushl(&sa, env->segs[R_SS].selector); 820 pushl(&sa, env->regs[R_ESP]); 821 } 822 pushl(&sa, eflags); 823 pushl(&sa, env->segs[R_CS].selector); 824 pushl(&sa, old_eip); 825 if (has_error_code) { 826 pushl(&sa, error_code); 827 } 828 } else { 829 if (new_stack) { 830 if (vm86) { 831 pushw(&sa, env->segs[R_GS].selector); 832 pushw(&sa, env->segs[R_FS].selector); 833 pushw(&sa, env->segs[R_DS].selector); 834 pushw(&sa, env->segs[R_ES].selector); 835 } 836 pushw(&sa, env->segs[R_SS].selector); 837 pushw(&sa, env->regs[R_ESP]); 838 } 839 pushw(&sa, eflags); 840 pushw(&sa, env->segs[R_CS].selector); 841 pushw(&sa, old_eip); 842 if (has_error_code) { 843 pushw(&sa, error_code); 844 } 845 } 846 847 /* interrupt gate clear IF mask */ 848 if ((type & 1) == 0) { 849 env->eflags &= ~IF_MASK; 850 } 851 env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK); 852 853 if (new_stack) { 854 if (vm86) { 855 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0); 856 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0, 0); 857 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0, 0); 858 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0, 0); 859 } 860 ss = (ss & ~3) | dpl; 861 cpu_x86_load_seg_cache(env, R_SS, ss, sa.ss_base, 862 get_seg_limit(ss_e1, ss_e2), ss_e2); 863 } 864 SET_ESP(sa.sp, sa.sp_mask); 865 866 selector = (selector & ~3) | dpl; 867 cpu_x86_load_seg_cache(env, R_CS, selector, 868 get_seg_base(e1, e2), 869 get_seg_limit(e1, e2), 870 e2); 871 env->eip = offset; 872 } 873 874 #ifdef TARGET_X86_64 875 876 static void pushq(StackAccess *sa, uint64_t val) 877 { 878 sa->sp -= 8; 879 cpu_stq_mmuidx_ra(sa->env, sa->sp, val, sa->mmu_index, sa->ra); 880 } 881 882 static uint64_t popq(StackAccess *sa) 883 { 884 uint64_t ret = cpu_ldq_mmuidx_ra(sa->env, sa->sp, sa->mmu_index, sa->ra); 885 sa->sp += 8; 886 return ret; 887 } 888 889 static inline target_ulong get_rsp_from_tss(CPUX86State *env, int level) 890 { 891 X86CPU *cpu = env_archcpu(env); 892 int index, pg_mode; 893 target_ulong rsp; 894 int32_t sext; 895 896 #if 0 897 printf("TR: base=" TARGET_FMT_lx " limit=%x\n", 898 env->tr.base, env->tr.limit); 899 #endif 900 901 if (!(env->tr.flags & DESC_P_MASK)) { 902 cpu_abort(CPU(cpu), "invalid tss"); 903 } 904 index = 8 * level + 4; 905 if ((index + 7) > env->tr.limit) { 906 raise_exception_err(env, EXCP0A_TSS, env->tr.selector & 0xfffc); 907 } 908 909 rsp = cpu_ldq_kernel(env, env->tr.base + index); 910 911 /* test virtual address sign extension */ 912 pg_mode = get_pg_mode(env); 913 sext = (int64_t)rsp >> (pg_mode & PG_MODE_LA57 ? 56 : 47); 914 if (sext != 0 && sext != -1) { 915 raise_exception_err(env, EXCP0C_STACK, 0); 916 } 917 918 return rsp; 919 } 920 921 /* 64 bit interrupt */ 922 static void do_interrupt64(CPUX86State *env, int intno, int is_int, 923 int error_code, target_ulong next_eip, int is_hw) 924 { 925 SegmentCache *dt; 926 target_ulong ptr; 927 int type, dpl, selector, cpl, ist; 928 int has_error_code, new_stack; 929 uint32_t e1, e2, e3, eflags; 930 target_ulong old_eip, offset; 931 bool set_rf; 932 StackAccess sa; 933 934 has_error_code = 0; 935 if (!is_int && !is_hw) { 936 has_error_code = exception_has_error_code(intno); 937 } 938 if (is_int) { 939 old_eip = next_eip; 940 set_rf = false; 941 } else { 942 old_eip = env->eip; 943 set_rf = exception_is_fault(intno); 944 } 945 946 dt = &env->idt; 947 if (intno * 16 + 15 > dt->limit) { 948 raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); 949 } 950 ptr = dt->base + intno * 16; 951 e1 = cpu_ldl_kernel(env, ptr); 952 e2 = cpu_ldl_kernel(env, ptr + 4); 953 e3 = cpu_ldl_kernel(env, ptr + 8); 954 /* check gate type */ 955 type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; 956 switch (type) { 957 case 14: /* 386 interrupt gate */ 958 case 15: /* 386 trap gate */ 959 break; 960 default: 961 raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); 962 break; 963 } 964 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 965 cpl = env->hflags & HF_CPL_MASK; 966 /* check privilege if software int */ 967 if (is_int && dpl < cpl) { 968 raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); 969 } 970 /* check valid bit */ 971 if (!(e2 & DESC_P_MASK)) { 972 raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2); 973 } 974 selector = e1 >> 16; 975 offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff); 976 ist = e2 & 7; 977 if ((selector & 0xfffc) == 0) { 978 raise_exception_err(env, EXCP0D_GPF, 0); 979 } 980 981 if (load_segment(env, &e1, &e2, selector) != 0) { 982 raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); 983 } 984 if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) { 985 raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); 986 } 987 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 988 if (dpl > cpl) { 989 raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); 990 } 991 if (!(e2 & DESC_P_MASK)) { 992 raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc); 993 } 994 if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK)) { 995 raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); 996 } 997 if (e2 & DESC_C_MASK) { 998 dpl = cpl; 999 } 1000 1001 sa.env = env; 1002 sa.ra = 0; 1003 sa.mmu_index = cpu_mmu_index_kernel(env); 1004 sa.sp_mask = -1; 1005 sa.ss_base = 0; 1006 if (dpl < cpl || ist != 0) { 1007 /* to inner privilege */ 1008 new_stack = 1; 1009 sa.sp = get_rsp_from_tss(env, ist != 0 ? ist + 3 : dpl); 1010 } else { 1011 /* to same privilege */ 1012 if (env->eflags & VM_MASK) { 1013 raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); 1014 } 1015 new_stack = 0; 1016 sa.sp = env->regs[R_ESP]; 1017 } 1018 sa.sp &= ~0xfLL; /* align stack */ 1019 1020 /* See do_interrupt_protected. */ 1021 eflags = cpu_compute_eflags(env); 1022 if (set_rf) { 1023 eflags |= RF_MASK; 1024 } 1025 1026 pushq(&sa, env->segs[R_SS].selector); 1027 pushq(&sa, env->regs[R_ESP]); 1028 pushq(&sa, eflags); 1029 pushq(&sa, env->segs[R_CS].selector); 1030 pushq(&sa, old_eip); 1031 if (has_error_code) { 1032 pushq(&sa, error_code); 1033 } 1034 1035 /* interrupt gate clear IF mask */ 1036 if ((type & 1) == 0) { 1037 env->eflags &= ~IF_MASK; 1038 } 1039 env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK); 1040 1041 if (new_stack) { 1042 uint32_t ss = 0 | dpl; /* SS = NULL selector with RPL = new CPL */ 1043 cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, dpl << DESC_DPL_SHIFT); 1044 } 1045 env->regs[R_ESP] = sa.sp; 1046 1047 selector = (selector & ~3) | dpl; 1048 cpu_x86_load_seg_cache(env, R_CS, selector, 1049 get_seg_base(e1, e2), 1050 get_seg_limit(e1, e2), 1051 e2); 1052 env->eip = offset; 1053 } 1054 #endif /* TARGET_X86_64 */ 1055 1056 void helper_sysret(CPUX86State *env, int dflag) 1057 { 1058 int cpl, selector; 1059 1060 if (!(env->efer & MSR_EFER_SCE)) { 1061 raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); 1062 } 1063 cpl = env->hflags & HF_CPL_MASK; 1064 if (!(env->cr[0] & CR0_PE_MASK) || cpl != 0) { 1065 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 1066 } 1067 selector = (env->star >> 48) & 0xffff; 1068 #ifdef TARGET_X86_64 1069 if (env->hflags & HF_LMA_MASK) { 1070 cpu_load_eflags(env, (uint32_t)(env->regs[11]), TF_MASK | AC_MASK 1071 | ID_MASK | IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | 1072 NT_MASK); 1073 if (dflag == 2) { 1074 cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3, 1075 0, 0xffffffff, 1076 DESC_G_MASK | DESC_P_MASK | 1077 DESC_S_MASK | (3 << DESC_DPL_SHIFT) | 1078 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | 1079 DESC_L_MASK); 1080 env->eip = env->regs[R_ECX]; 1081 } else { 1082 cpu_x86_load_seg_cache(env, R_CS, selector | 3, 1083 0, 0xffffffff, 1084 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 1085 DESC_S_MASK | (3 << DESC_DPL_SHIFT) | 1086 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); 1087 env->eip = (uint32_t)env->regs[R_ECX]; 1088 } 1089 cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3, 1090 0, 0xffffffff, 1091 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 1092 DESC_S_MASK | (3 << DESC_DPL_SHIFT) | 1093 DESC_W_MASK | DESC_A_MASK); 1094 } else 1095 #endif 1096 { 1097 env->eflags |= IF_MASK; 1098 cpu_x86_load_seg_cache(env, R_CS, selector | 3, 1099 0, 0xffffffff, 1100 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 1101 DESC_S_MASK | (3 << DESC_DPL_SHIFT) | 1102 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); 1103 env->eip = (uint32_t)env->regs[R_ECX]; 1104 cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3, 1105 0, 0xffffffff, 1106 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 1107 DESC_S_MASK | (3 << DESC_DPL_SHIFT) | 1108 DESC_W_MASK | DESC_A_MASK); 1109 } 1110 } 1111 1112 /* real mode interrupt */ 1113 static void do_interrupt_real(CPUX86State *env, int intno, int is_int, 1114 int error_code, unsigned int next_eip) 1115 { 1116 SegmentCache *dt; 1117 target_ulong ptr; 1118 int selector; 1119 uint32_t offset; 1120 uint32_t old_cs, old_eip; 1121 StackAccess sa; 1122 1123 /* real mode (simpler!) */ 1124 dt = &env->idt; 1125 if (intno * 4 + 3 > dt->limit) { 1126 raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); 1127 } 1128 ptr = dt->base + intno * 4; 1129 offset = cpu_lduw_kernel(env, ptr); 1130 selector = cpu_lduw_kernel(env, ptr + 2); 1131 1132 sa.env = env; 1133 sa.ra = 0; 1134 sa.sp = env->regs[R_ESP]; 1135 sa.sp_mask = 0xffff; 1136 sa.ss_base = env->segs[R_SS].base; 1137 sa.mmu_index = cpu_mmu_index_kernel(env); 1138 1139 if (is_int) { 1140 old_eip = next_eip; 1141 } else { 1142 old_eip = env->eip; 1143 } 1144 old_cs = env->segs[R_CS].selector; 1145 /* XXX: use SS segment size? */ 1146 pushw(&sa, cpu_compute_eflags(env)); 1147 pushw(&sa, old_cs); 1148 pushw(&sa, old_eip); 1149 1150 /* update processor state */ 1151 SET_ESP(sa.sp, sa.sp_mask); 1152 env->eip = offset; 1153 env->segs[R_CS].selector = selector; 1154 env->segs[R_CS].base = (selector << 4); 1155 env->eflags &= ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK); 1156 } 1157 1158 /* 1159 * Begin execution of an interruption. is_int is TRUE if coming from 1160 * the int instruction. next_eip is the env->eip value AFTER the interrupt 1161 * instruction. It is only relevant if is_int is TRUE. 1162 */ 1163 void do_interrupt_all(X86CPU *cpu, int intno, int is_int, 1164 int error_code, target_ulong next_eip, int is_hw) 1165 { 1166 CPUX86State *env = &cpu->env; 1167 1168 if (qemu_loglevel_mask(CPU_LOG_INT)) { 1169 if ((env->cr[0] & CR0_PE_MASK)) { 1170 static int count; 1171 1172 qemu_log("%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx 1173 " pc=" TARGET_FMT_lx " SP=%04x:" TARGET_FMT_lx, 1174 count, intno, error_code, is_int, 1175 env->hflags & HF_CPL_MASK, 1176 env->segs[R_CS].selector, env->eip, 1177 (int)env->segs[R_CS].base + env->eip, 1178 env->segs[R_SS].selector, env->regs[R_ESP]); 1179 if (intno == 0x0e) { 1180 qemu_log(" CR2=" TARGET_FMT_lx, env->cr[2]); 1181 } else { 1182 qemu_log(" env->regs[R_EAX]=" TARGET_FMT_lx, env->regs[R_EAX]); 1183 } 1184 qemu_log("\n"); 1185 log_cpu_state(CPU(cpu), CPU_DUMP_CCOP); 1186 #if 0 1187 { 1188 int i; 1189 target_ulong ptr; 1190 1191 qemu_log(" code="); 1192 ptr = env->segs[R_CS].base + env->eip; 1193 for (i = 0; i < 16; i++) { 1194 qemu_log(" %02x", ldub(ptr + i)); 1195 } 1196 qemu_log("\n"); 1197 } 1198 #endif 1199 count++; 1200 } 1201 } 1202 if (env->cr[0] & CR0_PE_MASK) { 1203 #if !defined(CONFIG_USER_ONLY) 1204 if (env->hflags & HF_GUEST_MASK) { 1205 handle_even_inj(env, intno, is_int, error_code, is_hw, 0); 1206 } 1207 #endif 1208 #ifdef TARGET_X86_64 1209 if (env->hflags & HF_LMA_MASK) { 1210 do_interrupt64(env, intno, is_int, error_code, next_eip, is_hw); 1211 } else 1212 #endif 1213 { 1214 do_interrupt_protected(env, intno, is_int, error_code, next_eip, 1215 is_hw); 1216 } 1217 } else { 1218 #if !defined(CONFIG_USER_ONLY) 1219 if (env->hflags & HF_GUEST_MASK) { 1220 handle_even_inj(env, intno, is_int, error_code, is_hw, 1); 1221 } 1222 #endif 1223 do_interrupt_real(env, intno, is_int, error_code, next_eip); 1224 } 1225 1226 #if !defined(CONFIG_USER_ONLY) 1227 if (env->hflags & HF_GUEST_MASK) { 1228 CPUState *cs = CPU(cpu); 1229 uint32_t event_inj = x86_ldl_phys(cs, env->vm_vmcb + 1230 offsetof(struct vmcb, 1231 control.event_inj)); 1232 1233 x86_stl_phys(cs, 1234 env->vm_vmcb + offsetof(struct vmcb, control.event_inj), 1235 event_inj & ~SVM_EVTINJ_VALID); 1236 } 1237 #endif 1238 } 1239 1240 void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw) 1241 { 1242 do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw); 1243 } 1244 1245 void helper_lldt(CPUX86State *env, int selector) 1246 { 1247 SegmentCache *dt; 1248 uint32_t e1, e2; 1249 int index, entry_limit; 1250 target_ulong ptr; 1251 1252 selector &= 0xffff; 1253 if ((selector & 0xfffc) == 0) { 1254 /* XXX: NULL selector case: invalid LDT */ 1255 env->ldt.base = 0; 1256 env->ldt.limit = 0; 1257 } else { 1258 if (selector & 0x4) { 1259 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1260 } 1261 dt = &env->gdt; 1262 index = selector & ~7; 1263 #ifdef TARGET_X86_64 1264 if (env->hflags & HF_LMA_MASK) { 1265 entry_limit = 15; 1266 } else 1267 #endif 1268 { 1269 entry_limit = 7; 1270 } 1271 if ((index + entry_limit) > dt->limit) { 1272 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1273 } 1274 ptr = dt->base + index; 1275 e1 = cpu_ldl_kernel_ra(env, ptr, GETPC()); 1276 e2 = cpu_ldl_kernel_ra(env, ptr + 4, GETPC()); 1277 if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) { 1278 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1279 } 1280 if (!(e2 & DESC_P_MASK)) { 1281 raise_exception_err_ra(env, EXCP0B_NOSEG, selector & 0xfffc, GETPC()); 1282 } 1283 #ifdef TARGET_X86_64 1284 if (env->hflags & HF_LMA_MASK) { 1285 uint32_t e3; 1286 1287 e3 = cpu_ldl_kernel_ra(env, ptr + 8, GETPC()); 1288 load_seg_cache_raw_dt(&env->ldt, e1, e2); 1289 env->ldt.base |= (target_ulong)e3 << 32; 1290 } else 1291 #endif 1292 { 1293 load_seg_cache_raw_dt(&env->ldt, e1, e2); 1294 } 1295 } 1296 env->ldt.selector = selector; 1297 } 1298 1299 void helper_ltr(CPUX86State *env, int selector) 1300 { 1301 SegmentCache *dt; 1302 uint32_t e1, e2; 1303 int index, type, entry_limit; 1304 target_ulong ptr; 1305 1306 selector &= 0xffff; 1307 if ((selector & 0xfffc) == 0) { 1308 /* NULL selector case: invalid TR */ 1309 env->tr.base = 0; 1310 env->tr.limit = 0; 1311 env->tr.flags = 0; 1312 } else { 1313 if (selector & 0x4) { 1314 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1315 } 1316 dt = &env->gdt; 1317 index = selector & ~7; 1318 #ifdef TARGET_X86_64 1319 if (env->hflags & HF_LMA_MASK) { 1320 entry_limit = 15; 1321 } else 1322 #endif 1323 { 1324 entry_limit = 7; 1325 } 1326 if ((index + entry_limit) > dt->limit) { 1327 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1328 } 1329 ptr = dt->base + index; 1330 e1 = cpu_ldl_kernel_ra(env, ptr, GETPC()); 1331 e2 = cpu_ldl_kernel_ra(env, ptr + 4, GETPC()); 1332 type = (e2 >> DESC_TYPE_SHIFT) & 0xf; 1333 if ((e2 & DESC_S_MASK) || 1334 (type != 1 && type != 9)) { 1335 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1336 } 1337 if (!(e2 & DESC_P_MASK)) { 1338 raise_exception_err_ra(env, EXCP0B_NOSEG, selector & 0xfffc, GETPC()); 1339 } 1340 #ifdef TARGET_X86_64 1341 if (env->hflags & HF_LMA_MASK) { 1342 uint32_t e3, e4; 1343 1344 e3 = cpu_ldl_kernel_ra(env, ptr + 8, GETPC()); 1345 e4 = cpu_ldl_kernel_ra(env, ptr + 12, GETPC()); 1346 if ((e4 >> DESC_TYPE_SHIFT) & 0xf) { 1347 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1348 } 1349 load_seg_cache_raw_dt(&env->tr, e1, e2); 1350 env->tr.base |= (target_ulong)e3 << 32; 1351 } else 1352 #endif 1353 { 1354 load_seg_cache_raw_dt(&env->tr, e1, e2); 1355 } 1356 e2 |= DESC_TSS_BUSY_MASK; 1357 cpu_stl_kernel_ra(env, ptr + 4, e2, GETPC()); 1358 } 1359 env->tr.selector = selector; 1360 } 1361 1362 /* only works if protected mode and not VM86. seg_reg must be != R_CS */ 1363 void helper_load_seg(CPUX86State *env, int seg_reg, int selector) 1364 { 1365 uint32_t e1, e2; 1366 int cpl, dpl, rpl; 1367 SegmentCache *dt; 1368 int index; 1369 target_ulong ptr; 1370 1371 selector &= 0xffff; 1372 cpl = env->hflags & HF_CPL_MASK; 1373 if ((selector & 0xfffc) == 0) { 1374 /* null selector case */ 1375 if (seg_reg == R_SS 1376 #ifdef TARGET_X86_64 1377 && (!(env->hflags & HF_CS64_MASK) || cpl == 3) 1378 #endif 1379 ) { 1380 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 1381 } 1382 cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0); 1383 } else { 1384 1385 if (selector & 0x4) { 1386 dt = &env->ldt; 1387 } else { 1388 dt = &env->gdt; 1389 } 1390 index = selector & ~7; 1391 if ((index + 7) > dt->limit) { 1392 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1393 } 1394 ptr = dt->base + index; 1395 e1 = cpu_ldl_kernel_ra(env, ptr, GETPC()); 1396 e2 = cpu_ldl_kernel_ra(env, ptr + 4, GETPC()); 1397 1398 if (!(e2 & DESC_S_MASK)) { 1399 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1400 } 1401 rpl = selector & 3; 1402 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 1403 if (seg_reg == R_SS) { 1404 /* must be writable segment */ 1405 if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) { 1406 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1407 } 1408 if (rpl != cpl || dpl != cpl) { 1409 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1410 } 1411 } else { 1412 /* must be readable segment */ 1413 if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) { 1414 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1415 } 1416 1417 if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) { 1418 /* if not conforming code, test rights */ 1419 if (dpl < cpl || dpl < rpl) { 1420 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1421 } 1422 } 1423 } 1424 1425 if (!(e2 & DESC_P_MASK)) { 1426 if (seg_reg == R_SS) { 1427 raise_exception_err_ra(env, EXCP0C_STACK, selector & 0xfffc, GETPC()); 1428 } else { 1429 raise_exception_err_ra(env, EXCP0B_NOSEG, selector & 0xfffc, GETPC()); 1430 } 1431 } 1432 1433 /* set the access bit if not already set */ 1434 if (!(e2 & DESC_A_MASK)) { 1435 e2 |= DESC_A_MASK; 1436 cpu_stl_kernel_ra(env, ptr + 4, e2, GETPC()); 1437 } 1438 1439 cpu_x86_load_seg_cache(env, seg_reg, selector, 1440 get_seg_base(e1, e2), 1441 get_seg_limit(e1, e2), 1442 e2); 1443 #if 0 1444 qemu_log("load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx flags=%08x\n", 1445 selector, (unsigned long)sc->base, sc->limit, sc->flags); 1446 #endif 1447 } 1448 } 1449 1450 /* protected mode jump */ 1451 void helper_ljmp_protected(CPUX86State *env, int new_cs, target_ulong new_eip, 1452 target_ulong next_eip) 1453 { 1454 int gate_cs, type; 1455 uint32_t e1, e2, cpl, dpl, rpl, limit; 1456 1457 if ((new_cs & 0xfffc) == 0) { 1458 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 1459 } 1460 if (load_segment_ra(env, &e1, &e2, new_cs, GETPC()) != 0) { 1461 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1462 } 1463 cpl = env->hflags & HF_CPL_MASK; 1464 if (e2 & DESC_S_MASK) { 1465 if (!(e2 & DESC_CS_MASK)) { 1466 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1467 } 1468 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 1469 if (e2 & DESC_C_MASK) { 1470 /* conforming code segment */ 1471 if (dpl > cpl) { 1472 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1473 } 1474 } else { 1475 /* non conforming code segment */ 1476 rpl = new_cs & 3; 1477 if (rpl > cpl) { 1478 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1479 } 1480 if (dpl != cpl) { 1481 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1482 } 1483 } 1484 if (!(e2 & DESC_P_MASK)) { 1485 raise_exception_err_ra(env, EXCP0B_NOSEG, new_cs & 0xfffc, GETPC()); 1486 } 1487 limit = get_seg_limit(e1, e2); 1488 if (new_eip > limit && 1489 (!(env->hflags & HF_LMA_MASK) || !(e2 & DESC_L_MASK))) { 1490 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 1491 } 1492 cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, 1493 get_seg_base(e1, e2), limit, e2); 1494 env->eip = new_eip; 1495 } else { 1496 /* jump to call or task gate */ 1497 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 1498 rpl = new_cs & 3; 1499 cpl = env->hflags & HF_CPL_MASK; 1500 type = (e2 >> DESC_TYPE_SHIFT) & 0xf; 1501 1502 #ifdef TARGET_X86_64 1503 if (env->efer & MSR_EFER_LMA) { 1504 if (type != 12) { 1505 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1506 } 1507 } 1508 #endif 1509 switch (type) { 1510 case 1: /* 286 TSS */ 1511 case 9: /* 386 TSS */ 1512 case 5: /* task gate */ 1513 if (dpl < cpl || dpl < rpl) { 1514 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1515 } 1516 switch_tss_ra(env, new_cs, e1, e2, SWITCH_TSS_JMP, next_eip, GETPC()); 1517 break; 1518 case 4: /* 286 call gate */ 1519 case 12: /* 386 call gate */ 1520 if ((dpl < cpl) || (dpl < rpl)) { 1521 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1522 } 1523 if (!(e2 & DESC_P_MASK)) { 1524 raise_exception_err_ra(env, EXCP0B_NOSEG, new_cs & 0xfffc, GETPC()); 1525 } 1526 gate_cs = e1 >> 16; 1527 new_eip = (e1 & 0xffff); 1528 if (type == 12) { 1529 new_eip |= (e2 & 0xffff0000); 1530 } 1531 1532 #ifdef TARGET_X86_64 1533 if (env->efer & MSR_EFER_LMA) { 1534 /* load the upper 8 bytes of the 64-bit call gate */ 1535 if (load_segment_ra(env, &e1, &e2, new_cs + 8, GETPC())) { 1536 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, 1537 GETPC()); 1538 } 1539 type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; 1540 if (type != 0) { 1541 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, 1542 GETPC()); 1543 } 1544 new_eip |= ((target_ulong)e1) << 32; 1545 } 1546 #endif 1547 1548 if (load_segment_ra(env, &e1, &e2, gate_cs, GETPC()) != 0) { 1549 raise_exception_err_ra(env, EXCP0D_GPF, gate_cs & 0xfffc, GETPC()); 1550 } 1551 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 1552 /* must be code segment */ 1553 if (((e2 & (DESC_S_MASK | DESC_CS_MASK)) != 1554 (DESC_S_MASK | DESC_CS_MASK))) { 1555 raise_exception_err_ra(env, EXCP0D_GPF, gate_cs & 0xfffc, GETPC()); 1556 } 1557 if (((e2 & DESC_C_MASK) && (dpl > cpl)) || 1558 (!(e2 & DESC_C_MASK) && (dpl != cpl))) { 1559 raise_exception_err_ra(env, EXCP0D_GPF, gate_cs & 0xfffc, GETPC()); 1560 } 1561 #ifdef TARGET_X86_64 1562 if (env->efer & MSR_EFER_LMA) { 1563 if (!(e2 & DESC_L_MASK)) { 1564 raise_exception_err_ra(env, EXCP0D_GPF, gate_cs & 0xfffc, GETPC()); 1565 } 1566 if (e2 & DESC_B_MASK) { 1567 raise_exception_err_ra(env, EXCP0D_GPF, gate_cs & 0xfffc, GETPC()); 1568 } 1569 } 1570 #endif 1571 if (!(e2 & DESC_P_MASK)) { 1572 raise_exception_err_ra(env, EXCP0D_GPF, gate_cs & 0xfffc, GETPC()); 1573 } 1574 limit = get_seg_limit(e1, e2); 1575 if (new_eip > limit && 1576 (!(env->hflags & HF_LMA_MASK) || !(e2 & DESC_L_MASK))) { 1577 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 1578 } 1579 cpu_x86_load_seg_cache(env, R_CS, (gate_cs & 0xfffc) | cpl, 1580 get_seg_base(e1, e2), limit, e2); 1581 env->eip = new_eip; 1582 break; 1583 default: 1584 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1585 break; 1586 } 1587 } 1588 } 1589 1590 /* real mode call */ 1591 void helper_lcall_real(CPUX86State *env, uint32_t new_cs, uint32_t new_eip, 1592 int shift, uint32_t next_eip) 1593 { 1594 StackAccess sa; 1595 1596 sa.env = env; 1597 sa.ra = GETPC(); 1598 sa.sp = env->regs[R_ESP]; 1599 sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); 1600 sa.ss_base = env->segs[R_SS].base; 1601 sa.mmu_index = cpu_mmu_index_kernel(env); 1602 1603 if (shift) { 1604 pushl(&sa, env->segs[R_CS].selector); 1605 pushl(&sa, next_eip); 1606 } else { 1607 pushw(&sa, env->segs[R_CS].selector); 1608 pushw(&sa, next_eip); 1609 } 1610 1611 SET_ESP(sa.sp, sa.sp_mask); 1612 env->eip = new_eip; 1613 env->segs[R_CS].selector = new_cs; 1614 env->segs[R_CS].base = (new_cs << 4); 1615 } 1616 1617 /* protected mode call */ 1618 void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, 1619 int shift, target_ulong next_eip) 1620 { 1621 int new_stack, i; 1622 uint32_t e1, e2, cpl, dpl, rpl, selector, param_count; 1623 uint32_t ss = 0, ss_e1 = 0, ss_e2 = 0, type, ss_dpl; 1624 uint32_t val, limit, old_sp_mask; 1625 target_ulong old_ssp, offset; 1626 StackAccess sa; 1627 1628 LOG_PCALL("lcall %04x:" TARGET_FMT_lx " s=%d\n", new_cs, new_eip, shift); 1629 LOG_PCALL_STATE(env_cpu(env)); 1630 if ((new_cs & 0xfffc) == 0) { 1631 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 1632 } 1633 if (load_segment_ra(env, &e1, &e2, new_cs, GETPC()) != 0) { 1634 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1635 } 1636 cpl = env->hflags & HF_CPL_MASK; 1637 LOG_PCALL("desc=%08x:%08x\n", e1, e2); 1638 1639 sa.env = env; 1640 sa.ra = GETPC(); 1641 sa.mmu_index = cpu_mmu_index_kernel(env); 1642 1643 if (e2 & DESC_S_MASK) { 1644 if (!(e2 & DESC_CS_MASK)) { 1645 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1646 } 1647 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 1648 if (e2 & DESC_C_MASK) { 1649 /* conforming code segment */ 1650 if (dpl > cpl) { 1651 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1652 } 1653 } else { 1654 /* non conforming code segment */ 1655 rpl = new_cs & 3; 1656 if (rpl > cpl) { 1657 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1658 } 1659 if (dpl != cpl) { 1660 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1661 } 1662 } 1663 if (!(e2 & DESC_P_MASK)) { 1664 raise_exception_err_ra(env, EXCP0B_NOSEG, new_cs & 0xfffc, GETPC()); 1665 } 1666 1667 #ifdef TARGET_X86_64 1668 /* XXX: check 16/32 bit cases in long mode */ 1669 if (shift == 2) { 1670 /* 64 bit case */ 1671 sa.sp = env->regs[R_ESP]; 1672 sa.sp_mask = -1; 1673 sa.ss_base = 0; 1674 pushq(&sa, env->segs[R_CS].selector); 1675 pushq(&sa, next_eip); 1676 /* from this point, not restartable */ 1677 env->regs[R_ESP] = sa.sp; 1678 cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, 1679 get_seg_base(e1, e2), 1680 get_seg_limit(e1, e2), e2); 1681 env->eip = new_eip; 1682 } else 1683 #endif 1684 { 1685 sa.sp = env->regs[R_ESP]; 1686 sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); 1687 sa.ss_base = env->segs[R_SS].base; 1688 if (shift) { 1689 pushl(&sa, env->segs[R_CS].selector); 1690 pushl(&sa, next_eip); 1691 } else { 1692 pushw(&sa, env->segs[R_CS].selector); 1693 pushw(&sa, next_eip); 1694 } 1695 1696 limit = get_seg_limit(e1, e2); 1697 if (new_eip > limit) { 1698 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1699 } 1700 /* from this point, not restartable */ 1701 SET_ESP(sa.sp, sa.sp_mask); 1702 cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, 1703 get_seg_base(e1, e2), limit, e2); 1704 env->eip = new_eip; 1705 } 1706 } else { 1707 /* check gate type */ 1708 type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; 1709 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 1710 rpl = new_cs & 3; 1711 1712 #ifdef TARGET_X86_64 1713 if (env->efer & MSR_EFER_LMA) { 1714 if (type != 12) { 1715 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1716 } 1717 } 1718 #endif 1719 1720 switch (type) { 1721 case 1: /* available 286 TSS */ 1722 case 9: /* available 386 TSS */ 1723 case 5: /* task gate */ 1724 if (dpl < cpl || dpl < rpl) { 1725 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1726 } 1727 switch_tss_ra(env, new_cs, e1, e2, SWITCH_TSS_CALL, next_eip, GETPC()); 1728 return; 1729 case 4: /* 286 call gate */ 1730 case 12: /* 386 call gate */ 1731 break; 1732 default: 1733 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1734 break; 1735 } 1736 shift = type >> 3; 1737 1738 if (dpl < cpl || dpl < rpl) { 1739 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); 1740 } 1741 /* check valid bit */ 1742 if (!(e2 & DESC_P_MASK)) { 1743 raise_exception_err_ra(env, EXCP0B_NOSEG, new_cs & 0xfffc, GETPC()); 1744 } 1745 selector = e1 >> 16; 1746 param_count = e2 & 0x1f; 1747 offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff); 1748 #ifdef TARGET_X86_64 1749 if (env->efer & MSR_EFER_LMA) { 1750 /* load the upper 8 bytes of the 64-bit call gate */ 1751 if (load_segment_ra(env, &e1, &e2, new_cs + 8, GETPC())) { 1752 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, 1753 GETPC()); 1754 } 1755 type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; 1756 if (type != 0) { 1757 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, 1758 GETPC()); 1759 } 1760 offset |= ((target_ulong)e1) << 32; 1761 } 1762 #endif 1763 if ((selector & 0xfffc) == 0) { 1764 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 1765 } 1766 1767 if (load_segment_ra(env, &e1, &e2, selector, GETPC()) != 0) { 1768 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1769 } 1770 if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) { 1771 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1772 } 1773 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 1774 if (dpl > cpl) { 1775 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1776 } 1777 #ifdef TARGET_X86_64 1778 if (env->efer & MSR_EFER_LMA) { 1779 if (!(e2 & DESC_L_MASK)) { 1780 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1781 } 1782 if (e2 & DESC_B_MASK) { 1783 raise_exception_err_ra(env, EXCP0D_GPF, selector & 0xfffc, GETPC()); 1784 } 1785 shift++; 1786 } 1787 #endif 1788 if (!(e2 & DESC_P_MASK)) { 1789 raise_exception_err_ra(env, EXCP0B_NOSEG, selector & 0xfffc, GETPC()); 1790 } 1791 1792 if (!(e2 & DESC_C_MASK) && dpl < cpl) { 1793 /* to inner privilege */ 1794 #ifdef TARGET_X86_64 1795 if (shift == 2) { 1796 ss = dpl; /* SS = NULL selector with RPL = new CPL */ 1797 new_stack = 1; 1798 sa.sp = get_rsp_from_tss(env, dpl); 1799 sa.sp_mask = -1; 1800 sa.ss_base = 0; /* SS base is always zero in IA-32e mode */ 1801 LOG_PCALL("new ss:rsp=%04x:%016llx env->regs[R_ESP]=" 1802 TARGET_FMT_lx "\n", ss, sa.sp, env->regs[R_ESP]); 1803 } else 1804 #endif 1805 { 1806 uint32_t sp32; 1807 get_ss_esp_from_tss(env, &ss, &sp32, dpl, GETPC()); 1808 LOG_PCALL("new ss:esp=%04x:%08x param_count=%d env->regs[R_ESP]=" 1809 TARGET_FMT_lx "\n", ss, sp32, param_count, 1810 env->regs[R_ESP]); 1811 if ((ss & 0xfffc) == 0) { 1812 raise_exception_err_ra(env, EXCP0A_TSS, ss & 0xfffc, GETPC()); 1813 } 1814 if ((ss & 3) != dpl) { 1815 raise_exception_err_ra(env, EXCP0A_TSS, ss & 0xfffc, GETPC()); 1816 } 1817 if (load_segment_ra(env, &ss_e1, &ss_e2, ss, GETPC()) != 0) { 1818 raise_exception_err_ra(env, EXCP0A_TSS, ss & 0xfffc, GETPC()); 1819 } 1820 ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; 1821 if (ss_dpl != dpl) { 1822 raise_exception_err_ra(env, EXCP0A_TSS, ss & 0xfffc, GETPC()); 1823 } 1824 if (!(ss_e2 & DESC_S_MASK) || 1825 (ss_e2 & DESC_CS_MASK) || 1826 !(ss_e2 & DESC_W_MASK)) { 1827 raise_exception_err_ra(env, EXCP0A_TSS, ss & 0xfffc, GETPC()); 1828 } 1829 if (!(ss_e2 & DESC_P_MASK)) { 1830 raise_exception_err_ra(env, EXCP0A_TSS, ss & 0xfffc, GETPC()); 1831 } 1832 1833 sa.sp = sp32; 1834 sa.sp_mask = get_sp_mask(ss_e2); 1835 sa.ss_base = get_seg_base(ss_e1, ss_e2); 1836 } 1837 1838 /* push_size = ((param_count * 2) + 8) << shift; */ 1839 old_sp_mask = get_sp_mask(env->segs[R_SS].flags); 1840 old_ssp = env->segs[R_SS].base; 1841 1842 #ifdef TARGET_X86_64 1843 if (shift == 2) { 1844 /* XXX: verify if new stack address is canonical */ 1845 pushq(&sa, env->segs[R_SS].selector); 1846 pushq(&sa, env->regs[R_ESP]); 1847 /* parameters aren't supported for 64-bit call gates */ 1848 } else 1849 #endif 1850 if (shift == 1) { 1851 pushl(&sa, env->segs[R_SS].selector); 1852 pushl(&sa, env->regs[R_ESP]); 1853 for (i = param_count - 1; i >= 0; i--) { 1854 val = cpu_ldl_data_ra(env, 1855 old_ssp + ((env->regs[R_ESP] + i * 4) & old_sp_mask), 1856 GETPC()); 1857 pushl(&sa, val); 1858 } 1859 } else { 1860 pushw(&sa, env->segs[R_SS].selector); 1861 pushw(&sa, env->regs[R_ESP]); 1862 for (i = param_count - 1; i >= 0; i--) { 1863 val = cpu_lduw_data_ra(env, 1864 old_ssp + ((env->regs[R_ESP] + i * 2) & old_sp_mask), 1865 GETPC()); 1866 pushw(&sa, val); 1867 } 1868 } 1869 new_stack = 1; 1870 } else { 1871 /* to same privilege */ 1872 sa.sp = env->regs[R_ESP]; 1873 sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); 1874 sa.ss_base = env->segs[R_SS].base; 1875 /* push_size = (4 << shift); */ 1876 new_stack = 0; 1877 } 1878 1879 #ifdef TARGET_X86_64 1880 if (shift == 2) { 1881 pushq(&sa, env->segs[R_CS].selector); 1882 pushq(&sa, next_eip); 1883 } else 1884 #endif 1885 if (shift == 1) { 1886 pushl(&sa, env->segs[R_CS].selector); 1887 pushl(&sa, next_eip); 1888 } else { 1889 pushw(&sa, env->segs[R_CS].selector); 1890 pushw(&sa, next_eip); 1891 } 1892 1893 /* from this point, not restartable */ 1894 1895 if (new_stack) { 1896 #ifdef TARGET_X86_64 1897 if (shift == 2) { 1898 cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0); 1899 } else 1900 #endif 1901 { 1902 ss = (ss & ~3) | dpl; 1903 cpu_x86_load_seg_cache(env, R_SS, ss, 1904 sa.ss_base, 1905 get_seg_limit(ss_e1, ss_e2), 1906 ss_e2); 1907 } 1908 } 1909 1910 selector = (selector & ~3) | dpl; 1911 cpu_x86_load_seg_cache(env, R_CS, selector, 1912 get_seg_base(e1, e2), 1913 get_seg_limit(e1, e2), 1914 e2); 1915 SET_ESP(sa.sp, sa.sp_mask); 1916 env->eip = offset; 1917 } 1918 } 1919 1920 /* real and vm86 mode iret */ 1921 void helper_iret_real(CPUX86State *env, int shift) 1922 { 1923 uint32_t new_cs, new_eip, new_eflags; 1924 int eflags_mask; 1925 StackAccess sa; 1926 1927 sa.env = env; 1928 sa.ra = GETPC(); 1929 sa.mmu_index = x86_mmu_index_pl(env, 0); 1930 sa.sp_mask = 0xffff; /* XXXX: use SS segment size? */ 1931 sa.sp = env->regs[R_ESP]; 1932 sa.ss_base = env->segs[R_SS].base; 1933 1934 if (shift == 1) { 1935 /* 32 bits */ 1936 new_eip = popl(&sa); 1937 new_cs = popl(&sa) & 0xffff; 1938 new_eflags = popl(&sa); 1939 } else { 1940 /* 16 bits */ 1941 new_eip = popw(&sa); 1942 new_cs = popw(&sa); 1943 new_eflags = popw(&sa); 1944 } 1945 SET_ESP(sa.sp, sa.sp_mask); 1946 env->segs[R_CS].selector = new_cs; 1947 env->segs[R_CS].base = (new_cs << 4); 1948 env->eip = new_eip; 1949 if (env->eflags & VM_MASK) { 1950 eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | RF_MASK | 1951 NT_MASK; 1952 } else { 1953 eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK | 1954 RF_MASK | NT_MASK; 1955 } 1956 if (shift == 0) { 1957 eflags_mask &= 0xffff; 1958 } 1959 cpu_load_eflags(env, new_eflags, eflags_mask); 1960 env->hflags2 &= ~HF2_NMI_MASK; 1961 } 1962 1963 static inline void validate_seg(CPUX86State *env, X86Seg seg_reg, int cpl) 1964 { 1965 int dpl; 1966 uint32_t e2; 1967 1968 /* XXX: on x86_64, we do not want to nullify FS and GS because 1969 they may still contain a valid base. I would be interested to 1970 know how a real x86_64 CPU behaves */ 1971 if ((seg_reg == R_FS || seg_reg == R_GS) && 1972 (env->segs[seg_reg].selector & 0xfffc) == 0) { 1973 return; 1974 } 1975 1976 e2 = env->segs[seg_reg].flags; 1977 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 1978 if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) { 1979 /* data or non conforming code segment */ 1980 if (dpl < cpl) { 1981 cpu_x86_load_seg_cache(env, seg_reg, 0, 1982 env->segs[seg_reg].base, 1983 env->segs[seg_reg].limit, 1984 env->segs[seg_reg].flags & ~DESC_P_MASK); 1985 } 1986 } 1987 } 1988 1989 /* protected mode iret */ 1990 static inline void helper_ret_protected(CPUX86State *env, int shift, 1991 int is_iret, int addend, 1992 uintptr_t retaddr) 1993 { 1994 uint32_t new_cs, new_eflags, new_ss; 1995 uint32_t new_es, new_ds, new_fs, new_gs; 1996 uint32_t e1, e2, ss_e1, ss_e2; 1997 int cpl, dpl, rpl, eflags_mask, iopl; 1998 target_ulong new_eip, new_esp; 1999 StackAccess sa; 2000 2001 cpl = env->hflags & HF_CPL_MASK; 2002 2003 sa.env = env; 2004 sa.ra = retaddr; 2005 sa.mmu_index = x86_mmu_index_pl(env, cpl); 2006 2007 #ifdef TARGET_X86_64 2008 if (shift == 2) { 2009 sa.sp_mask = -1; 2010 } else 2011 #endif 2012 { 2013 sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); 2014 } 2015 sa.sp = env->regs[R_ESP]; 2016 sa.ss_base = env->segs[R_SS].base; 2017 new_eflags = 0; /* avoid warning */ 2018 #ifdef TARGET_X86_64 2019 if (shift == 2) { 2020 new_eip = popq(&sa); 2021 new_cs = popq(&sa) & 0xffff; 2022 if (is_iret) { 2023 new_eflags = popq(&sa); 2024 } 2025 } else 2026 #endif 2027 { 2028 if (shift == 1) { 2029 /* 32 bits */ 2030 new_eip = popl(&sa); 2031 new_cs = popl(&sa) & 0xffff; 2032 if (is_iret) { 2033 new_eflags = popl(&sa); 2034 if (new_eflags & VM_MASK) { 2035 goto return_to_vm86; 2036 } 2037 } 2038 } else { 2039 /* 16 bits */ 2040 new_eip = popw(&sa); 2041 new_cs = popw(&sa); 2042 if (is_iret) { 2043 new_eflags = popw(&sa); 2044 } 2045 } 2046 } 2047 LOG_PCALL("lret new %04x:" TARGET_FMT_lx " s=%d addend=0x%x\n", 2048 new_cs, new_eip, shift, addend); 2049 LOG_PCALL_STATE(env_cpu(env)); 2050 if ((new_cs & 0xfffc) == 0) { 2051 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, retaddr); 2052 } 2053 if (load_segment_ra(env, &e1, &e2, new_cs, retaddr) != 0) { 2054 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, retaddr); 2055 } 2056 if (!(e2 & DESC_S_MASK) || 2057 !(e2 & DESC_CS_MASK)) { 2058 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, retaddr); 2059 } 2060 rpl = new_cs & 3; 2061 if (rpl < cpl) { 2062 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, retaddr); 2063 } 2064 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 2065 if (e2 & DESC_C_MASK) { 2066 if (dpl > rpl) { 2067 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, retaddr); 2068 } 2069 } else { 2070 if (dpl != rpl) { 2071 raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, retaddr); 2072 } 2073 } 2074 if (!(e2 & DESC_P_MASK)) { 2075 raise_exception_err_ra(env, EXCP0B_NOSEG, new_cs & 0xfffc, retaddr); 2076 } 2077 2078 sa.sp += addend; 2079 if (rpl == cpl && (!(env->hflags & HF_CS64_MASK) || 2080 ((env->hflags & HF_CS64_MASK) && !is_iret))) { 2081 /* return to same privilege level */ 2082 cpu_x86_load_seg_cache(env, R_CS, new_cs, 2083 get_seg_base(e1, e2), 2084 get_seg_limit(e1, e2), 2085 e2); 2086 } else { 2087 /* return to different privilege level */ 2088 #ifdef TARGET_X86_64 2089 if (shift == 2) { 2090 new_esp = popq(&sa); 2091 new_ss = popq(&sa) & 0xffff; 2092 } else 2093 #endif 2094 { 2095 if (shift == 1) { 2096 /* 32 bits */ 2097 new_esp = popl(&sa); 2098 new_ss = popl(&sa) & 0xffff; 2099 } else { 2100 /* 16 bits */ 2101 new_esp = popw(&sa); 2102 new_ss = popw(&sa); 2103 } 2104 } 2105 LOG_PCALL("new ss:esp=%04x:" TARGET_FMT_lx "\n", 2106 new_ss, new_esp); 2107 if ((new_ss & 0xfffc) == 0) { 2108 #ifdef TARGET_X86_64 2109 /* NULL ss is allowed in long mode if cpl != 3 */ 2110 /* XXX: test CS64? */ 2111 if ((env->hflags & HF_LMA_MASK) && rpl != 3) { 2112 cpu_x86_load_seg_cache(env, R_SS, new_ss, 2113 0, 0xffffffff, 2114 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 2115 DESC_S_MASK | (rpl << DESC_DPL_SHIFT) | 2116 DESC_W_MASK | DESC_A_MASK); 2117 ss_e2 = DESC_B_MASK; /* XXX: should not be needed? */ 2118 } else 2119 #endif 2120 { 2121 raise_exception_err_ra(env, EXCP0D_GPF, 0, retaddr); 2122 } 2123 } else { 2124 if ((new_ss & 3) != rpl) { 2125 raise_exception_err_ra(env, EXCP0D_GPF, new_ss & 0xfffc, retaddr); 2126 } 2127 if (load_segment_ra(env, &ss_e1, &ss_e2, new_ss, retaddr) != 0) { 2128 raise_exception_err_ra(env, EXCP0D_GPF, new_ss & 0xfffc, retaddr); 2129 } 2130 if (!(ss_e2 & DESC_S_MASK) || 2131 (ss_e2 & DESC_CS_MASK) || 2132 !(ss_e2 & DESC_W_MASK)) { 2133 raise_exception_err_ra(env, EXCP0D_GPF, new_ss & 0xfffc, retaddr); 2134 } 2135 dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; 2136 if (dpl != rpl) { 2137 raise_exception_err_ra(env, EXCP0D_GPF, new_ss & 0xfffc, retaddr); 2138 } 2139 if (!(ss_e2 & DESC_P_MASK)) { 2140 raise_exception_err_ra(env, EXCP0B_NOSEG, new_ss & 0xfffc, retaddr); 2141 } 2142 cpu_x86_load_seg_cache(env, R_SS, new_ss, 2143 get_seg_base(ss_e1, ss_e2), 2144 get_seg_limit(ss_e1, ss_e2), 2145 ss_e2); 2146 } 2147 2148 cpu_x86_load_seg_cache(env, R_CS, new_cs, 2149 get_seg_base(e1, e2), 2150 get_seg_limit(e1, e2), 2151 e2); 2152 sa.sp = new_esp; 2153 #ifdef TARGET_X86_64 2154 if (env->hflags & HF_CS64_MASK) { 2155 sa.sp_mask = -1; 2156 } else 2157 #endif 2158 { 2159 sa.sp_mask = get_sp_mask(ss_e2); 2160 } 2161 2162 /* validate data segments */ 2163 validate_seg(env, R_ES, rpl); 2164 validate_seg(env, R_DS, rpl); 2165 validate_seg(env, R_FS, rpl); 2166 validate_seg(env, R_GS, rpl); 2167 2168 sa.sp += addend; 2169 } 2170 SET_ESP(sa.sp, sa.sp_mask); 2171 env->eip = new_eip; 2172 if (is_iret) { 2173 /* NOTE: 'cpl' is the _old_ CPL */ 2174 eflags_mask = TF_MASK | AC_MASK | ID_MASK | RF_MASK | NT_MASK; 2175 if (cpl == 0) { 2176 eflags_mask |= IOPL_MASK; 2177 } 2178 iopl = (env->eflags >> IOPL_SHIFT) & 3; 2179 if (cpl <= iopl) { 2180 eflags_mask |= IF_MASK; 2181 } 2182 if (shift == 0) { 2183 eflags_mask &= 0xffff; 2184 } 2185 cpu_load_eflags(env, new_eflags, eflags_mask); 2186 } 2187 return; 2188 2189 return_to_vm86: 2190 new_esp = popl(&sa); 2191 new_ss = popl(&sa); 2192 new_es = popl(&sa); 2193 new_ds = popl(&sa); 2194 new_fs = popl(&sa); 2195 new_gs = popl(&sa); 2196 2197 /* modify processor state */ 2198 cpu_load_eflags(env, new_eflags, TF_MASK | AC_MASK | ID_MASK | 2199 IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK | 2200 VIP_MASK); 2201 load_seg_vm(env, R_CS, new_cs & 0xffff); 2202 load_seg_vm(env, R_SS, new_ss & 0xffff); 2203 load_seg_vm(env, R_ES, new_es & 0xffff); 2204 load_seg_vm(env, R_DS, new_ds & 0xffff); 2205 load_seg_vm(env, R_FS, new_fs & 0xffff); 2206 load_seg_vm(env, R_GS, new_gs & 0xffff); 2207 2208 env->eip = new_eip & 0xffff; 2209 env->regs[R_ESP] = new_esp; 2210 } 2211 2212 void helper_iret_protected(CPUX86State *env, int shift, int next_eip) 2213 { 2214 int tss_selector, type; 2215 uint32_t e1, e2; 2216 2217 /* specific case for TSS */ 2218 if (env->eflags & NT_MASK) { 2219 #ifdef TARGET_X86_64 2220 if (env->hflags & HF_LMA_MASK) { 2221 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 2222 } 2223 #endif 2224 tss_selector = cpu_lduw_kernel_ra(env, env->tr.base + 0, GETPC()); 2225 if (tss_selector & 4) { 2226 raise_exception_err_ra(env, EXCP0A_TSS, tss_selector & 0xfffc, GETPC()); 2227 } 2228 if (load_segment_ra(env, &e1, &e2, tss_selector, GETPC()) != 0) { 2229 raise_exception_err_ra(env, EXCP0A_TSS, tss_selector & 0xfffc, GETPC()); 2230 } 2231 type = (e2 >> DESC_TYPE_SHIFT) & 0x17; 2232 /* NOTE: we check both segment and busy TSS */ 2233 if (type != 3) { 2234 raise_exception_err_ra(env, EXCP0A_TSS, tss_selector & 0xfffc, GETPC()); 2235 } 2236 switch_tss_ra(env, tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip, GETPC()); 2237 } else { 2238 helper_ret_protected(env, shift, 1, 0, GETPC()); 2239 } 2240 env->hflags2 &= ~HF2_NMI_MASK; 2241 } 2242 2243 void helper_lret_protected(CPUX86State *env, int shift, int addend) 2244 { 2245 helper_ret_protected(env, shift, 0, addend, GETPC()); 2246 } 2247 2248 void helper_sysenter(CPUX86State *env) 2249 { 2250 if (env->sysenter_cs == 0) { 2251 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 2252 } 2253 env->eflags &= ~(VM_MASK | IF_MASK | RF_MASK); 2254 2255 #ifdef TARGET_X86_64 2256 if (env->hflags & HF_LMA_MASK) { 2257 cpu_x86_load_seg_cache(env, R_CS, env->sysenter_cs & 0xfffc, 2258 0, 0xffffffff, 2259 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 2260 DESC_S_MASK | 2261 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | 2262 DESC_L_MASK); 2263 } else 2264 #endif 2265 { 2266 cpu_x86_load_seg_cache(env, R_CS, env->sysenter_cs & 0xfffc, 2267 0, 0xffffffff, 2268 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 2269 DESC_S_MASK | 2270 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); 2271 } 2272 cpu_x86_load_seg_cache(env, R_SS, (env->sysenter_cs + 8) & 0xfffc, 2273 0, 0xffffffff, 2274 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 2275 DESC_S_MASK | 2276 DESC_W_MASK | DESC_A_MASK); 2277 env->regs[R_ESP] = env->sysenter_esp; 2278 env->eip = env->sysenter_eip; 2279 } 2280 2281 void helper_sysexit(CPUX86State *env, int dflag) 2282 { 2283 int cpl; 2284 2285 cpl = env->hflags & HF_CPL_MASK; 2286 if (env->sysenter_cs == 0 || cpl != 0) { 2287 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 2288 } 2289 #ifdef TARGET_X86_64 2290 if (dflag == 2) { 2291 cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 32) & 0xfffc) | 2292 3, 0, 0xffffffff, 2293 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 2294 DESC_S_MASK | (3 << DESC_DPL_SHIFT) | 2295 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | 2296 DESC_L_MASK); 2297 cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 40) & 0xfffc) | 2298 3, 0, 0xffffffff, 2299 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 2300 DESC_S_MASK | (3 << DESC_DPL_SHIFT) | 2301 DESC_W_MASK | DESC_A_MASK); 2302 } else 2303 #endif 2304 { 2305 cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 16) & 0xfffc) | 2306 3, 0, 0xffffffff, 2307 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 2308 DESC_S_MASK | (3 << DESC_DPL_SHIFT) | 2309 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); 2310 cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 24) & 0xfffc) | 2311 3, 0, 0xffffffff, 2312 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | 2313 DESC_S_MASK | (3 << DESC_DPL_SHIFT) | 2314 DESC_W_MASK | DESC_A_MASK); 2315 } 2316 env->regs[R_ESP] = env->regs[R_ECX]; 2317 env->eip = env->regs[R_EDX]; 2318 } 2319 2320 target_ulong helper_lsl(CPUX86State *env, target_ulong selector1) 2321 { 2322 unsigned int limit; 2323 uint32_t e1, e2, selector; 2324 int rpl, dpl, cpl, type; 2325 2326 selector = selector1 & 0xffff; 2327 assert(CC_OP == CC_OP_EFLAGS); 2328 if ((selector & 0xfffc) == 0) { 2329 goto fail; 2330 } 2331 if (load_segment_ra(env, &e1, &e2, selector, GETPC()) != 0) { 2332 goto fail; 2333 } 2334 rpl = selector & 3; 2335 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 2336 cpl = env->hflags & HF_CPL_MASK; 2337 if (e2 & DESC_S_MASK) { 2338 if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) { 2339 /* conforming */ 2340 } else { 2341 if (dpl < cpl || dpl < rpl) { 2342 goto fail; 2343 } 2344 } 2345 } else { 2346 type = (e2 >> DESC_TYPE_SHIFT) & 0xf; 2347 switch (type) { 2348 case 1: 2349 case 2: 2350 case 3: 2351 case 9: 2352 case 11: 2353 break; 2354 default: 2355 goto fail; 2356 } 2357 if (dpl < cpl || dpl < rpl) { 2358 fail: 2359 CC_SRC &= ~CC_Z; 2360 return 0; 2361 } 2362 } 2363 limit = get_seg_limit(e1, e2); 2364 CC_SRC |= CC_Z; 2365 return limit; 2366 } 2367 2368 target_ulong helper_lar(CPUX86State *env, target_ulong selector1) 2369 { 2370 uint32_t e1, e2, selector; 2371 int rpl, dpl, cpl, type; 2372 2373 selector = selector1 & 0xffff; 2374 assert(CC_OP == CC_OP_EFLAGS); 2375 if ((selector & 0xfffc) == 0) { 2376 goto fail; 2377 } 2378 if (load_segment_ra(env, &e1, &e2, selector, GETPC()) != 0) { 2379 goto fail; 2380 } 2381 rpl = selector & 3; 2382 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 2383 cpl = env->hflags & HF_CPL_MASK; 2384 if (e2 & DESC_S_MASK) { 2385 if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) { 2386 /* conforming */ 2387 } else { 2388 if (dpl < cpl || dpl < rpl) { 2389 goto fail; 2390 } 2391 } 2392 } else { 2393 type = (e2 >> DESC_TYPE_SHIFT) & 0xf; 2394 switch (type) { 2395 case 1: 2396 case 2: 2397 case 3: 2398 case 4: 2399 case 5: 2400 case 9: 2401 case 11: 2402 case 12: 2403 break; 2404 default: 2405 goto fail; 2406 } 2407 if (dpl < cpl || dpl < rpl) { 2408 fail: 2409 CC_SRC &= ~CC_Z; 2410 return 0; 2411 } 2412 } 2413 CC_SRC |= CC_Z; 2414 return e2 & 0x00f0ff00; 2415 } 2416 2417 void helper_verr(CPUX86State *env, target_ulong selector1) 2418 { 2419 uint32_t e1, e2, eflags, selector; 2420 int rpl, dpl, cpl; 2421 2422 selector = selector1 & 0xffff; 2423 eflags = cpu_cc_compute_all(env) | CC_Z; 2424 if ((selector & 0xfffc) == 0) { 2425 goto fail; 2426 } 2427 if (load_segment_ra(env, &e1, &e2, selector, GETPC()) != 0) { 2428 goto fail; 2429 } 2430 if (!(e2 & DESC_S_MASK)) { 2431 goto fail; 2432 } 2433 rpl = selector & 3; 2434 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 2435 cpl = env->hflags & HF_CPL_MASK; 2436 if (e2 & DESC_CS_MASK) { 2437 if (!(e2 & DESC_R_MASK)) { 2438 goto fail; 2439 } 2440 if (!(e2 & DESC_C_MASK)) { 2441 if (dpl < cpl || dpl < rpl) { 2442 goto fail; 2443 } 2444 } 2445 } else { 2446 if (dpl < cpl || dpl < rpl) { 2447 fail: 2448 eflags &= ~CC_Z; 2449 } 2450 } 2451 CC_SRC = eflags; 2452 CC_OP = CC_OP_EFLAGS; 2453 } 2454 2455 void helper_verw(CPUX86State *env, target_ulong selector1) 2456 { 2457 uint32_t e1, e2, eflags, selector; 2458 int rpl, dpl, cpl; 2459 2460 selector = selector1 & 0xffff; 2461 eflags = cpu_cc_compute_all(env) | CC_Z; 2462 if ((selector & 0xfffc) == 0) { 2463 goto fail; 2464 } 2465 if (load_segment_ra(env, &e1, &e2, selector, GETPC()) != 0) { 2466 goto fail; 2467 } 2468 if (!(e2 & DESC_S_MASK)) { 2469 goto fail; 2470 } 2471 rpl = selector & 3; 2472 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 2473 cpl = env->hflags & HF_CPL_MASK; 2474 if (e2 & DESC_CS_MASK) { 2475 goto fail; 2476 } else { 2477 if (dpl < cpl || dpl < rpl) { 2478 goto fail; 2479 } 2480 if (!(e2 & DESC_W_MASK)) { 2481 fail: 2482 eflags &= ~CC_Z; 2483 } 2484 } 2485 CC_SRC = eflags; 2486 CC_OP = CC_OP_EFLAGS; 2487 } 2488