From c3b969ab0c049efd7a699fe4dacc659b7ceb30bb Mon Sep 17 00:00:00 2001 From: Vladimir Chtchetkine Date: Tue, 27 Sep 2011 11:21:12 -0700 Subject: Fix QEMU pipe on KVM The issue was that CPU registers (CR3 in particular) in QEMU were out of sync with KVM at the time when virtual address to physical address translation was performed. This caused translation failure, and the subsequent crash. The fix was to explicitly sync QEMU registers with KVM registers just before calling VA->PA translation. Change-Id: I1ff4ed2cfddd77e6889bb645f08db442f119049a --- hw/goldfish_pipe.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/goldfish_pipe.c b/hw/goldfish_pipe.c index 2227093..5a00247 100644 --- a/hw/goldfish_pipe.c +++ b/hw/goldfish_pipe.c @@ -14,6 +14,9 @@ #include "hw/goldfish_pipe.h" #include "hw/goldfish_device.h" #include "qemu-timer.h" +#ifdef TARGET_I386 +#include "kvm.h" +#endif #define DEBUG 0 @@ -875,7 +878,13 @@ pipeDevice_doCommand( PipeDevice* dev, uint32_t command ) GoldfishPipeBuffer buffer; uint32_t address = dev->address; uint32_t page = address & TARGET_PAGE_MASK; - target_phys_addr_t phys = cpu_get_phys_page_debug(env, page); + target_phys_addr_t phys; +#ifdef TARGET_I386 + if(kvm_enabled()) { + cpu_synchronize_state(env, 0); + } +#endif + phys = cpu_get_phys_page_debug(env, page); buffer.data = qemu_get_ram_ptr(phys) + (address - page); buffer.size = dev->size; dev->status = pipe->funcs->recvBuffers(pipe->opaque, &buffer, 1); @@ -889,7 +898,13 @@ pipeDevice_doCommand( PipeDevice* dev, uint32_t command ) GoldfishPipeBuffer buffer; uint32_t address = dev->address; uint32_t page = address & TARGET_PAGE_MASK; - target_phys_addr_t phys = cpu_get_phys_page_debug(env, page); + target_phys_addr_t phys; +#ifdef TARGET_I386 + if(kvm_enabled()) { + cpu_synchronize_state(env, 0); + } +#endif + phys = cpu_get_phys_page_debug(env, page); buffer.data = qemu_get_ram_ptr(phys) + (address - page); buffer.size = dev->size; dev->status = pipe->funcs->sendBuffers(pipe->opaque, &buffer, 1); -- cgit v1.1