This lets us pass the whole 4GB address space down to the "guest". Recent versions of Linux use addresses above 0xfe000000 for the stack when running 32-bit programs in 64-bit mode, and this breaks if we leave the EPT identity map at the default address (0xfe000000). Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- api/identity.cc | 18 +++++++----------- api/kvmxx.cc | 5 +++++ api/kvmxx.hh | 1 + 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/api/identity.cc b/api/identity.cc index a178f3a..2e7987f 100644 --- a/api/identity.cc +++ b/api/identity.cc @@ -20,7 +20,7 @@ hole::hole(void* address, size_t size) vm::vm(kvm::vm& vm, mem_map& mmap, hole h) { - posix_memalign(&tss, 4096, 3 * 4096); + posix_memalign(&tss, 4096, 4 * 4096); if (!tss) { throw errno_exception(errno); } @@ -28,31 +28,27 @@ vm::vm(kvm::vm& vm, mem_map& mmap, hole h) uint64_t hole_gpa = reinterpret_cast<uintptr_t>(h.address); char* hole_hva = static_cast<char*>(h.address); uint64_t tss_addr = reinterpret_cast<uintptr_t>(tss); - uint64_t tss_end = tss_addr + 3 * 4096; + uint64_t tss_end = tss_addr + 4 * 4096; uint64_t hole_end = hole_gpa + h.size; - uint64_t top = 0xfe000000UL; - if (hole_end > top) { - puts("unlucky memory map :("); - throw std::exception(); - } if (hole_gpa < tss_addr) { if (hole_gpa) { _slots.push_back(mem_slot_ptr(new mem_slot(mmap, 0, hole_gpa, NULL))); } _slots.push_back(mem_slot_ptr(new mem_slot(mmap, hole_end, tss_addr - hole_end, hole_hva + h.size))); - _slots.push_back(mem_slot_ptr(new mem_slot(mmap, tss_end, (uint32_t)top - tss_end, - (char*)tss + 3 * 4096))); + _slots.push_back(mem_slot_ptr(new mem_slot(mmap, tss_end, (uint32_t)-tss_end, + (char*)tss + 4 * 4096))); } else { _slots.push_back(mem_slot_ptr(new mem_slot(mmap, 0, tss_addr, NULL))); _slots.push_back(mem_slot_ptr(new mem_slot(mmap, tss_end, hole_gpa - tss_end, - (char*)tss + 3 * 4096))); - _slots.push_back(mem_slot_ptr(new mem_slot(mmap, hole_end, (uint32_t)top - hole_end, + (char*)tss + 4 * 4096))); + _slots.push_back(mem_slot_ptr(new mem_slot(mmap, hole_end, (uint32_t)-hole_end, hole_hva + h.size))); } vm.set_tss_addr(tss_addr); + vm.set_ept_identity_map_addr(tss_addr + 3 * 4096); } vm::~vm() diff --git a/api/kvmxx.cc b/api/kvmxx.cc index 1df6f38..313902e 100644 --- a/api/kvmxx.cc +++ b/api/kvmxx.cc @@ -176,6 +176,11 @@ void vm::set_tss_addr(uint32_t addr) _fd.ioctl(KVM_SET_TSS_ADDR, addr); } +void vm::set_ept_identity_map_addr(uint64_t addr) +{ + _fd.ioctlp(KVM_SET_IDENTITY_MAP_ADDR, &addr); +} + system::system(std::string device_node) : _fd(device_node, O_RDWR) { diff --git a/api/kvmxx.hh b/api/kvmxx.hh index 1dcb41d..e39bd5b 100644 --- a/api/kvmxx.hh +++ b/api/kvmxx.hh @@ -61,6 +61,7 @@ public: uint32_t flags = 0); void get_dirty_log(int slot, void *log); void set_tss_addr(uint32_t addr); + void set_ept_identity_map_addr(uint64_t addr); system& sys() { return _system; } private: system& _system; -- 1.8.3.1