26
26
#include "config.h"
27
27
#include "cpu-all.h"
30
#include <VBox/vmapi.h>
34
#include <VBox/trpm.h>
39
#include <VBox/dbgf.h>
29
#include <VBox/vmm/rem.h>
30
#include <VBox/vmm/vmapi.h>
31
#include <VBox/vmm/tm.h>
32
#include <VBox/vmm/ssm.h>
33
#include <VBox/vmm/em.h>
34
#include <VBox/vmm/trpm.h>
35
#include <VBox/vmm/iom.h>
36
#include <VBox/vmm/mm.h>
37
#include <VBox/vmm/pgm.h>
38
#include <VBox/vmm/pdm.h>
39
#include <VBox/vmm/dbgf.h>
40
40
#include <VBox/dbg.h>
41
#include <VBox/hwaccm.h>
42
#include <VBox/patm.h>
43
#include <VBox/csam.h>
41
#include <VBox/vmm/hwaccm.h>
42
#include <VBox/vmm/patm.h>
43
#include <VBox/vmm/csam.h>
44
44
#include "REMInternal.h"
45
#include <VBox/vmm/vm.h>
46
46
#include <VBox/param.h>
47
47
#include <VBox/err.h>
367
367
STAM_REG(pVM, &gStatRawCheck, STAMTYPE_PROFILE, "/PROF/REM/RawCheck", STAMUNIT_TICKS_PER_CALL, "Profiling timer scheduling.");
368
368
STAM_REG(pVM, &gStatMemRead, STAMTYPE_PROFILE, "/PROF/REM/MemRead", STAMUNIT_TICKS_PER_CALL, "Profiling memory access.");
369
369
STAM_REG(pVM, &gStatMemWrite, STAMTYPE_PROFILE, "/PROF/REM/MemWrite", STAMUNIT_TICKS_PER_CALL, "Profiling memory access.");
370
STAM_REG(pVM, &gStatHCVirt2GCPhys, STAMTYPE_PROFILE, "/PROF/REM/HCVirt2GCPhys", STAMUNIT_TICKS_PER_CALL, "Profiling memory convertion.");
371
STAM_REG(pVM, &gStatGCPhys2HCVirt, STAMTYPE_PROFILE, "/PROF/REM/GCPhys2HCVirt", STAMUNIT_TICKS_PER_CALL, "Profiling memory convertion.");
370
STAM_REG(pVM, &gStatHCVirt2GCPhys, STAMTYPE_PROFILE, "/PROF/REM/HCVirt2GCPhys", STAMUNIT_TICKS_PER_CALL, "Profiling memory conversion.");
371
STAM_REG(pVM, &gStatGCPhys2HCVirt, STAMTYPE_PROFILE, "/PROF/REM/GCPhys2HCVirt", STAMUNIT_TICKS_PER_CALL, "Profiling memory conversion.");
373
373
STAM_REG(pVM, &gStatCpuGetTSC, STAMTYPE_COUNTER, "/REM/CpuGetTSC", STAMUNIT_OCCURENCES, "cpu_get_tsc calls");
765
765
tlb_flush(&pRem->Env, 1);
768
* Stop ignoring ignornable notifications.
768
* Stop ignoring ignorable notifications.
770
770
ASMAtomicDecU32(&pVM->rem.s.cIgnoreAll);
1231
1231
Ctx.trHid.u32Limit = env->tr.limit;
1232
1232
Ctx.trHid.Attr.u = (env->tr.flags >> 8) & 0xF0FF;
1234
Ctx.ldtr = env->ldt.selector;
1235
Ctx.ldtrHid.u64Base = env->ldt.base;
1236
Ctx.ldtrHid.u32Limit = env->ldt.limit;
1237
Ctx.ldtrHid.Attr.u = (env->ldt.flags >> 8) & 0xF0FF;
1234
1239
Ctx.idtr.cbIdt = env->idt.limit;
1235
1240
Ctx.idtr.pIdt = env->idt.base;
1290
1295
* Here we only support 16 & 32 bits protected mode ring 3 code that has no IO privileges
1291
1296
* or 32 bits protected mode ring 0 code
1293
* The tests are ordered by the likelyhood of being true during normal execution.
1298
* The tests are ordered by the likelihood of being true during normal execution.
1295
1300
if (fFlags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK))
1788
1793
* @remark The caller has to check for important FFs before calling REMR3Run. REMR3State will
1789
1794
* no do this since the majority of the callers don't want any unnecessary of events
1790
* pending that would immediatly interrupt execution.
1795
* pending that would immediately interrupt execution.
1792
1797
REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
2038
2043
if (fHiddenSelRegsValid)
2040
2045
/* The hidden selector registers are valid in the CPU context. */
2041
/** @note QEmu saves the 2nd dword of the descriptor; we should convert the attribute word back! */
2046
/* Note! QEmu saves the 2nd dword of the descriptor; we should convert the attribute word back! */
2043
2048
/* Set current CPL */
2044
2049
cpu_x86_set_cpl(&pVM->rem.s.Env, uCpl);
3511
3516
uint32_t u32 = 0;
3512
3517
int rc = IOMMMIORead((PVM)pvVM, GCPhys, &u32, 1);
3513
3518
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3514
Log2(("remR3MMIOReadU8: GCPhys=%RGp -> %02x\n", GCPhys, u32));
3519
Log2(("remR3MMIOReadU8: GCPhys=%RGp -> %02x\n", (RTGCPHYS)GCPhys, u32));
3521
3526
uint32_t u32 = 0;
3522
3527
int rc = IOMMMIORead((PVM)pvVM, GCPhys, &u32, 2);
3523
3528
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3524
Log2(("remR3MMIOReadU16: GCPhys=%RGp -> %04x\n", GCPhys, u32));
3529
Log2(("remR3MMIOReadU16: GCPhys=%RGp -> %04x\n", (RTGCPHYS)GCPhys, u32));
3531
3536
uint32_t u32 = 0;
3532
3537
int rc = IOMMMIORead((PVM)pvVM, GCPhys, &u32, 4);
3533
3538
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3534
Log2(("remR3MMIOReadU32: GCPhys=%RGp -> %08x\n", GCPhys, u32));
3539
Log2(("remR3MMIOReadU32: GCPhys=%RGp -> %08x\n", (RTGCPHYS)GCPhys, u32));
3539
3544
static void remR3MMIOWriteU8(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3542
Log2(("remR3MMIOWriteU8: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
3547
Log2(("remR3MMIOWriteU8: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3543
3548
rc = IOMMMIOWrite((PVM)pvVM, GCPhys, u32, 1);
3544
3549
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3548
3553
static void remR3MMIOWriteU16(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3551
Log2(("remR3MMIOWriteU16: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
3556
Log2(("remR3MMIOWriteU16: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3552
3557
rc = IOMMMIOWrite((PVM)pvVM, GCPhys, u32, 2);
3553
3558
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3557
3562
static void remR3MMIOWriteU32(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3560
Log2(("remR3MMIOWriteU32: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
3565
Log2(("remR3MMIOWriteU32: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3561
3566
rc = IOMMMIOWrite((PVM)pvVM, GCPhys, u32, 4);
3562
3567
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
3571
3576
static uint32_t remR3HandlerReadU8(void *pvVM, target_phys_addr_t GCPhys)
3574
Log2(("remR3HandlerReadU8: GCPhys=%RGp\n", GCPhys));
3579
Log2(("remR3HandlerReadU8: GCPhys=%RGp\n", (RTGCPHYS)GCPhys));
3575
3580
PGMPhysRead((PVM)pvVM, GCPhys, &u8, sizeof(u8));
3579
3584
static uint32_t remR3HandlerReadU16(void *pvVM, target_phys_addr_t GCPhys)
3582
Log2(("remR3HandlerReadU16: GCPhys=%RGp\n", GCPhys));
3587
Log2(("remR3HandlerReadU16: GCPhys=%RGp\n", (RTGCPHYS)GCPhys));
3583
3588
PGMPhysRead((PVM)pvVM, GCPhys, &u16, sizeof(u16));
3587
3592
static uint32_t remR3HandlerReadU32(void *pvVM, target_phys_addr_t GCPhys)
3590
Log2(("remR3HandlerReadU32: GCPhys=%RGp\n", GCPhys));
3595
Log2(("remR3HandlerReadU32: GCPhys=%RGp\n", (RTGCPHYS)GCPhys));
3591
3596
PGMPhysRead((PVM)pvVM, GCPhys, &u32, sizeof(u32));
3595
3600
static void remR3HandlerWriteU8(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3597
Log2(("remR3HandlerWriteU8: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
3602
Log2(("remR3HandlerWriteU8: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3598
3603
PGMPhysWrite((PVM)pvVM, GCPhys, &u32, sizeof(uint8_t));
3601
3606
static void remR3HandlerWriteU16(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3603
Log2(("remR3HandlerWriteU16: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
3608
Log2(("remR3HandlerWriteU16: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3604
3609
PGMPhysWrite((PVM)pvVM, GCPhys, &u32, sizeof(uint16_t));
3607
3612
static void remR3HandlerWriteU32(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
3609
Log2(("remR3HandlerWriteU32: GCPhys=%RGp u32=%#x\n", GCPhys, u32));
3614
Log2(("remR3HandlerWriteU32: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
3610
3615
PGMPhysWrite((PVM)pvVM, GCPhys, &u32, sizeof(uint32_t));
3721
3726
* Disassemble to log.
3724
rc = DBGFR3DisasInstrCurrentLogInternal(env->pVCpu, pszPrefix);
3730
PVMCPU pVCpu = VMMGetCpu(pVM);
3733
int rc = DBGFR3DisasInstrEx(pVCpu->pVMR3,
3737
DBGF_DISAS_FLAGS_CURRENT_GUEST
3738
| DBGF_DISAS_FLAGS_DEFAULT_MODE
3739
| DBGF_DISAS_FLAGS_HID_SEL_REGS_VALID,
3744
RTStrPrintf(szBuf, sizeof(szBuf), "DBGFR3DisasInstrEx failed with rc=%Rrc\n", rc);
3745
if (pszPrefix && *pszPrefix)
3746
RTLogPrintf("%s-CPU%d: %s\n", pszPrefix, pVCpu->idCpu, szBuf);
3748
RTLogPrintf("CPU%d: %s\n", pVCpu->idCpu, szBuf);
3726
3751
return RT_SUCCESS(rc);
3945
3970
* @param pVM VM Handle.
3946
3971
* @param pVCpuDst The target cpu for this notification.
3947
3972
* TM will not broadcast pending timer events, but use
3948
* a decidated EMT for them. So, only interrupt REM
3973
* a dedicated EMT for them. So, only interrupt REM
3949
3974
* execution if the given CPU is executing in REM.
4139
4164
* In that case we can't call PDMGetInterrupt anymore, because it has already cleared the interrupt
4140
4165
* with the (a)pic.
4142
/** @note We assume we will go directly to the recompiler to handle the pending interrupt! */
4167
/* Note! We assume we will go directly to the recompiler to handle the pending interrupt! */
4143
4168
/** @todo r=bird: In the long run we should just do the interrupt handling in EM/CPUM/TRPM/somewhere and
4144
4169
* if we cannot execute the interrupt handler in raw-mode just reschedule to REM. Once that is done we
4145
4170
* remove this kludge. */
4154
4179
rc = PDMGetInterrupt(env->pVCpu, &u8Interrupt);
4156
LogFlow(("cpu_get_pic_interrupt: u8Interrupt=%d rc=%Rrc\n", u8Interrupt, rc));
4181
LogFlow(("cpu_get_pic_interrupt: u8Interrupt=%d rc=%Rrc pc=%04x:%08llx ~flags=%08llx\n",
4182
u8Interrupt, rc, env->segs[R_CS].selector, (uint64_t)env->eip, (uint64_t)env->eflags));
4157
4183
if (RT_SUCCESS(rc))
4159
4185
if (VMCPU_FF_ISPENDING(env->pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
4167
4193
/* -+- local apic -+- */
4195
#if 0 /* CPUMSetGuestMsr does this now. */
4169
4196
void cpu_set_apic_base(CPUX86State *env, uint64_t val)
4171
4198
int rc = PDMApicSetBase(env->pVM, val);
4172
4199
LogFlow(("cpu_set_apic_base: val=%#llx rc=%Rrc\n", val, rc)); NOREF(rc);
4175
4203
uint64_t cpu_get_apic_base(CPUX86State *env)
4208
uint64_t cpu_apic_rdmsr(CPUX86State *env, uint32_t reg)
4211
int rc = PDMApicReadMSR(env->pVM, 0/* cpu */, reg, &value);
4214
LogFlow(("cpu_apic_rdms returns %#x\n", value));
4217
/** @todo: exception ? */
4218
LogFlow(("cpu_apic_rdms returns 0 (rc=%Rrc)\n", rc));
4222
void cpu_apic_wrmsr(CPUX86State *env, uint32_t reg, uint64_t value)
4224
int rc = PDMApicWriteMSR(env->pVM, 0 /* cpu */, reg, value);
4225
/** @todo: exception if error ? */
4226
LogFlow(("cpu_apic_wrmsr: rc=%Rrc\n", rc)); NOREF(rc);
4229
uint64_t cpu_rdmsr(CPUX86State *env, uint32_t msr)
4232
return CPUMGetGuestMsr(env->pVCpu, msr);
4235
void cpu_wrmsr(CPUX86State *env, uint32_t msr, uint64_t val)
4238
CPUMSetGuestMsr(env->pVCpu, msr, val);
4238
* @retval 0 success.
4239
* @retval -1 failure, raise \#GP(0).
4240
* @param env The cpu state.
4241
* @param idMsr The MSR to read.
4242
* @param puValue Where to return the value.
4244
int cpu_rdmsr(CPUX86State *env, uint32_t idMsr, uint64_t *puValue)
4247
return CPUMQueryGuestMsr(env->pVCpu, idMsr, puValue) == VINF_SUCCESS ? 0 : -1;
4253
* @retval 0 success.
4254
* @retval -1 failure, raise \#GP(0).
4255
* @param env The cpu state.
4256
* @param idMsr The MSR to read.
4257
* @param puValue Where to return the value.
4259
int cpu_wrmsr(CPUX86State *env, uint32_t idMsr, uint64_t uValue)
4262
return CPUMSetGuestMsr(env->pVCpu, idMsr, uValue) == VINF_SUCCESS ? 0 : -1;
4241
4265
/* -+- I/O Ports -+- */
4474
4498
* Aborts the VM.
4476
4500
* @param rc VBox error code.
4477
* @param pszTip Hint about why/when this happend.
4501
* @param pszTip Hint about why/when this happened.
4479
4503
void remAbort(int rc, const char *pszTip)