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