Revision 2c17449b target-i386/svm_helper.c

b/target-i386/svm_helper.c
105 105
    unsigned int flags;
106 106

  
107 107
    sc->selector = lduw_phys(addr + offsetof(struct vmcb_seg, selector));
108
    sc->base = ldq_phys(addr + offsetof(struct vmcb_seg, base));
108
    sc->base = ldq_phys(cs->as, addr + offsetof(struct vmcb_seg, base));
109 109
    sc->limit = ldl_phys(cs->as, addr + offsetof(struct vmcb_seg, limit));
110 110
    flags = lduw_phys(addr + offsetof(struct vmcb_seg, attrib));
111 111
    sc->flags = ((flags & 0xff) << 8) | ((flags & 0x0f00) << 12);
......
178 178

  
179 179
    /* load the interception bitmaps so we do not need to access the
180 180
       vmcb in svm mode */
181
    env->intercept = ldq_phys(env->vm_vmcb + offsetof(struct vmcb,
181
    env->intercept = ldq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
182 182
                                                      control.intercept));
183 183
    env->intercept_cr_read = lduw_phys(env->vm_vmcb +
184 184
                                       offsetof(struct vmcb,
......
200 200
    /* enable intercepts */
201 201
    env->hflags |= HF_SVMI_MASK;
202 202

  
203
    env->tsc_offset = ldq_phys(env->vm_vmcb +
203
    env->tsc_offset = ldq_phys(cs->as, env->vm_vmcb +
204 204
                               offsetof(struct vmcb, control.tsc_offset));
205 205

  
206
    env->gdt.base  = ldq_phys(env->vm_vmcb + offsetof(struct vmcb,
206
    env->gdt.base  = ldq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
207 207
                                                      save.gdtr.base));
208 208
    env->gdt.limit = ldl_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
209 209
                                                      save.gdtr.limit));
210 210

  
211
    env->idt.base  = ldq_phys(env->vm_vmcb + offsetof(struct vmcb,
211
    env->idt.base  = ldq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
212 212
                                                      save.idtr.base));
213 213
    env->idt.limit = ldl_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
214 214
                                                      save.idtr.limit));
......
216 216
    /* clear exit_info_2 so we behave like the real hardware */
217 217
    stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0);
218 218

  
219
    cpu_x86_update_cr0(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb,
219
    cpu_x86_update_cr0(env, ldq_phys(cs->as,
220
                                     env->vm_vmcb + offsetof(struct vmcb,
220 221
                                                             save.cr0)));
221
    cpu_x86_update_cr4(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb,
222
    cpu_x86_update_cr4(env, ldq_phys(cs->as,
223
                                     env->vm_vmcb + offsetof(struct vmcb,
222 224
                                                             save.cr4)));
223
    cpu_x86_update_cr3(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb,
225
    cpu_x86_update_cr3(env, ldq_phys(cs->as,
226
                                     env->vm_vmcb + offsetof(struct vmcb,
224 227
                                                             save.cr3)));
225
    env->cr[2] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr2));
228
    env->cr[2] = ldq_phys(cs->as,
229
                          env->vm_vmcb + offsetof(struct vmcb, save.cr2));
226 230
    int_ctl = ldl_phys(cs->as,
227 231
                       env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
228 232
    env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
......
235 239
    }
236 240

  
237 241
    cpu_load_efer(env,
238
                  ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.efer)));
242
                  ldq_phys(cs->as,
243
                           env->vm_vmcb + offsetof(struct vmcb, save.efer)));
239 244
    env->eflags = 0;
240
    cpu_load_eflags(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb,
245
    cpu_load_eflags(env, ldq_phys(cs->as,
246
                                  env->vm_vmcb + offsetof(struct vmcb,
241 247
                                                          save.rflags)),
242 248
                    ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
243 249
    CC_OP = CC_OP_EFLAGS;
......
251 257
    svm_load_seg_cache(env, env->vm_vmcb + offsetof(struct vmcb, save.ds),
252 258
                       R_DS);
253 259

  
254
    env->eip = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip));
255

  
256
    env->regs[R_ESP] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp));
257
    env->regs[R_EAX] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax));
258
    env->dr[7] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7));
259
    env->dr[6] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6));
260
    cpu_x86_set_cpl(env, ldub_phys(env->vm_vmcb + offsetof(struct vmcb,
260
    env->eip = ldq_phys(cs->as,
261
                        env->vm_vmcb + offsetof(struct vmcb, save.rip));
262

  
263
    env->regs[R_ESP] = ldq_phys(cs->as,
264
                                env->vm_vmcb + offsetof(struct vmcb, save.rsp));
265
    env->regs[R_EAX] = ldq_phys(cs->as,
266
                                env->vm_vmcb + offsetof(struct vmcb, save.rax));
267
    env->dr[7] = ldq_phys(cs->as,
268
                          env->vm_vmcb + offsetof(struct vmcb, save.dr7));
269
    env->dr[6] = ldq_phys(cs->as,
270
                          env->vm_vmcb + offsetof(struct vmcb, save.dr6));
271
    cpu_x86_set_cpl(env, ldub_phys(cs->as,
272
                                   env->vm_vmcb + offsetof(struct vmcb,
261 273
                                                           save.cpl)));
262 274

  
263 275
    /* FIXME: guest state consistency checks */
264 276

  
265
    switch (ldub_phys(env->vm_vmcb + offsetof(struct vmcb, control.tlb_ctl))) {
277
    switch (ldub_phys(cs->as,
278
                      env->vm_vmcb + offsetof(struct vmcb, control.tlb_ctl))) {
266 279
    case TLB_CONTROL_DO_NOTHING:
267 280
        break;
268 281
    case TLB_CONTROL_FLUSH_ALL_ASID:
......
339 352

  
340 353
void helper_vmload(CPUX86State *env, int aflag)
341 354
{
355
    CPUState *cs = ENV_GET_CPU(env);
342 356
    target_ulong addr;
343 357

  
344 358
    cpu_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0);
......
351 365

  
352 366
    qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmload! " TARGET_FMT_lx
353 367
                  "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
354
                  addr, ldq_phys(addr + offsetof(struct vmcb,
368
                  addr, ldq_phys(cs->as, addr + offsetof(struct vmcb,
355 369
                                                          save.fs.base)),
356 370
                  env->segs[R_FS].base);
357 371

  
......
361 375
    svm_load_seg(env, addr + offsetof(struct vmcb, save.ldtr), &env->ldt);
362 376

  
363 377
#ifdef TARGET_X86_64
364
    env->kernelgsbase = ldq_phys(addr + offsetof(struct vmcb,
378
    env->kernelgsbase = ldq_phys(cs->as, addr + offsetof(struct vmcb,
365 379
                                                 save.kernel_gs_base));
366
    env->lstar = ldq_phys(addr + offsetof(struct vmcb, save.lstar));
367
    env->cstar = ldq_phys(addr + offsetof(struct vmcb, save.cstar));
368
    env->fmask = ldq_phys(addr + offsetof(struct vmcb, save.sfmask));
380
    env->lstar = ldq_phys(cs->as, addr + offsetof(struct vmcb, save.lstar));
381
    env->cstar = ldq_phys(cs->as, addr + offsetof(struct vmcb, save.cstar));
382
    env->fmask = ldq_phys(cs->as, addr + offsetof(struct vmcb, save.sfmask));
369 383
#endif
370
    env->star = ldq_phys(addr + offsetof(struct vmcb, save.star));
371
    env->sysenter_cs = ldq_phys(addr + offsetof(struct vmcb, save.sysenter_cs));
372
    env->sysenter_esp = ldq_phys(addr + offsetof(struct vmcb,
384
    env->star = ldq_phys(cs->as, addr + offsetof(struct vmcb, save.star));
385
    env->sysenter_cs = ldq_phys(cs->as,
386
                                addr + offsetof(struct vmcb, save.sysenter_cs));
387
    env->sysenter_esp = ldq_phys(cs->as, addr + offsetof(struct vmcb,
373 388
                                                 save.sysenter_esp));
374
    env->sysenter_eip = ldq_phys(addr + offsetof(struct vmcb,
389
    env->sysenter_eip = ldq_phys(cs->as, addr + offsetof(struct vmcb,
375 390
                                                 save.sysenter_eip));
376 391
}
377 392

  
378 393
void helper_vmsave(CPUX86State *env, int aflag)
379 394
{
395
    CPUState *cs = ENV_GET_CPU(env);
380 396
    target_ulong addr;
381 397

  
382 398
    cpu_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0);
......
389 405

  
390 406
    qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmsave! " TARGET_FMT_lx
391 407
                  "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
392
                  addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)),
408
                  addr, ldq_phys(cs->as,
409
                                 addr + offsetof(struct vmcb, save.fs.base)),
393 410
                  env->segs[R_FS].base);
394 411

  
395 412
    svm_save_seg(env, addr + offsetof(struct vmcb, save.fs),
......
455 472
void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type,
456 473
                                      uint64_t param)
457 474
{
475
    CPUState *cs = ENV_GET_CPU(env);
476

  
458 477
    if (likely(!(env->hflags & HF_SVMI_MASK))) {
459 478
        return;
460 479
    }
......
487 506
    case SVM_EXIT_MSR:
488 507
        if (env->intercept & (1ULL << (SVM_EXIT_MSR - SVM_EXIT_INTR))) {
489 508
            /* FIXME: this should be read in at vmrun (faster this way?) */
490
            uint64_t addr = ldq_phys(env->vm_vmcb +
509
            uint64_t addr = ldq_phys(cs->as, env->vm_vmcb +
491 510
                                     offsetof(struct vmcb,
492 511
                                              control.msrpm_base_pa));
493 512
            uint32_t t0, t1;
......
513 532
                t1 = 0;
514 533
                break;
515 534
            }
516
            if (ldub_phys(addr + t1) & ((1 << param) << t0)) {
535
            if (ldub_phys(cs->as, addr + t1) & ((1 << param) << t0)) {
517 536
                helper_vmexit(env, type, param);
518 537
            }
519 538
        }
......
535 554
void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
536 555
                         uint32_t next_eip_addend)
537 556
{
557
    CPUState *cs = ENV_GET_CPU(env);
538 558
    if (env->intercept & (1ULL << (SVM_EXIT_IOIO - SVM_EXIT_INTR))) {
539 559
        /* FIXME: this should be read in at vmrun (faster this way?) */
540
        uint64_t addr = ldq_phys(env->vm_vmcb +
560
        uint64_t addr = ldq_phys(cs->as, env->vm_vmcb +
541 561
                                 offsetof(struct vmcb, control.iopm_base_pa));
542 562
        uint16_t mask = (1 << ((param >> 4) & 7)) - 1;
543 563

  
......
559 579
    qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016"
560 580
                  PRIx64 ", " TARGET_FMT_lx ")!\n",
561 581
                  exit_code, exit_info_1,
562
                  ldq_phys(env->vm_vmcb + offsetof(struct vmcb,
582
                  ldq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb,
563 583
                                                   control.exit_info_2)),
564 584
                  env->eip);
565 585

  
......
625 645
    cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
626 646
    env->tsc_offset = 0;
627 647

  
628
    env->gdt.base  = ldq_phys(env->vm_hsave + offsetof(struct vmcb,
648
    env->gdt.base  = ldq_phys(cs->as, env->vm_hsave + offsetof(struct vmcb,
629 649
                                                       save.gdtr.base));
630 650
    env->gdt.limit = ldl_phys(cs->as, env->vm_hsave + offsetof(struct vmcb,
631 651
                                                       save.gdtr.limit));
632 652

  
633
    env->idt.base  = ldq_phys(env->vm_hsave + offsetof(struct vmcb,
653
    env->idt.base  = ldq_phys(cs->as, env->vm_hsave + offsetof(struct vmcb,
634 654
                                                       save.idtr.base));
635 655
    env->idt.limit = ldl_phys(cs->as, env->vm_hsave + offsetof(struct vmcb,
636 656
                                                       save.idtr.limit));
637 657

  
638
    cpu_x86_update_cr0(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb,
658
    cpu_x86_update_cr0(env, ldq_phys(cs->as,
659
                                     env->vm_hsave + offsetof(struct vmcb,
639 660
                                                              save.cr0)) |
640 661
                       CR0_PE_MASK);
641
    cpu_x86_update_cr4(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb,
662
    cpu_x86_update_cr4(env, ldq_phys(cs->as,
663
                                     env->vm_hsave + offsetof(struct vmcb,
642 664
                                                              save.cr4)));
643
    cpu_x86_update_cr3(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb,
665
    cpu_x86_update_cr3(env, ldq_phys(cs->as,
666
                                     env->vm_hsave + offsetof(struct vmcb,
644 667
                                                              save.cr3)));
645 668
    /* we need to set the efer after the crs so the hidden flags get
646 669
       set properly */
647
    cpu_load_efer(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb,
670
    cpu_load_efer(env, ldq_phys(cs->as, env->vm_hsave + offsetof(struct vmcb,
648 671
                                                         save.efer)));
649 672
    env->eflags = 0;
650
    cpu_load_eflags(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb,
673
    cpu_load_eflags(env, ldq_phys(cs->as,
674
                                  env->vm_hsave + offsetof(struct vmcb,
651 675
                                                           save.rflags)),
652 676
                    ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
653 677
    CC_OP = CC_OP_EFLAGS;
......
661 685
    svm_load_seg_cache(env, env->vm_hsave + offsetof(struct vmcb, save.ds),
662 686
                       R_DS);
663 687

  
664
    env->eip = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip));
665
    env->regs[R_ESP] = ldq_phys(env->vm_hsave +
688
    env->eip = ldq_phys(cs->as,
689
                        env->vm_hsave + offsetof(struct vmcb, save.rip));
690
    env->regs[R_ESP] = ldq_phys(cs->as, env->vm_hsave +
666 691
                                offsetof(struct vmcb, save.rsp));
667
    env->regs[R_EAX] = ldq_phys(env->vm_hsave +
692
    env->regs[R_EAX] = ldq_phys(cs->as, env->vm_hsave +
668 693
                                offsetof(struct vmcb, save.rax));
669 694

  
670
    env->dr[6] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6));
671
    env->dr[7] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7));
695
    env->dr[6] = ldq_phys(cs->as,
696
                          env->vm_hsave + offsetof(struct vmcb, save.dr6));
697
    env->dr[7] = ldq_phys(cs->as,
698
                          env->vm_hsave + offsetof(struct vmcb, save.dr7));
672 699

  
673 700
    /* other setups */
674 701
    cpu_x86_set_cpl(env, 0);

Also available in: Unified diff