cpu-kvm, arch-x86: flush TLB after syscalls (#411)
Modified the x86 KVM-in-SE syscall handler to flush the TLB following each syscall, in case the page table has been modified. This is done by reloading the value in %cr3. Doing this requires an intermediate GPR, which we store in a new scratch buffer following the syscall code at address `syscallDataBuf`. GitHub issue: https://github.com/gem5/gem5/issues/409
This commit is contained in:
@@ -483,13 +483,35 @@ X86_64Process::initState()
|
||||
physProxy.writeBlob(idtPhysAddr + 0xE0, &PFGate, sizeof(PFGate));
|
||||
|
||||
/* System call handler */
|
||||
// First, we write to the MMIO m5ops range (0xffffc90000007000)
|
||||
// to trap out of the VM back into gem5 to emulate the system
|
||||
// call. Upon re-entering the VM, we need to flush the TLB in
|
||||
// case the system call modified existing page mappings (e.g.,
|
||||
// munmap, mremap, brk). To do this, we can simply read/write
|
||||
// cr3; however, doing so requires saving the value to an
|
||||
// intermediate GPR (%rax, in this case). We save/restore the
|
||||
// value of %rax in the scratch region syscallDataBuf.
|
||||
const Addr syscallDataBuf = syscallCodeVirtAddr + 0x100;
|
||||
uint8_t syscallBlob[] = {
|
||||
// mov %rax, (0xffffc90000007000)
|
||||
0x48, 0xa3, 0x00, 0x70, 0x00,
|
||||
0x00, 0x00, 0xc9, 0xff, 0xff,
|
||||
// mov %rax, (syscallDataBuf)
|
||||
0x48, 0xa3, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// mov %cr3, %rax
|
||||
0x0f, 0x20, 0xd8,
|
||||
// mov %rax, %cr3
|
||||
0x0f, 0x22, 0xd8,
|
||||
// mov (syscallDataBuf), %rax
|
||||
0x48, 0xa1, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// sysret
|
||||
0x48, 0x0f, 0x07
|
||||
};
|
||||
assert(syscallDataBuf >= syscallCodePhysAddr + sizeof syscallBlob);
|
||||
std::memcpy(&syscallBlob[12], &syscallDataBuf, sizeof syscallDataBuf);
|
||||
std::memcpy(&syscallBlob[28], &syscallDataBuf, sizeof syscallDataBuf);
|
||||
|
||||
physProxy.writeBlob(syscallCodePhysAddr,
|
||||
syscallBlob, sizeof(syscallBlob));
|
||||
|
||||
Reference in New Issue
Block a user