aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Chtchetkine <vchtchetkine@google.com>2011-09-27 11:21:12 -0700
committerVladimir Chtchetkine <vchtchetkine@google.com>2011-09-27 11:21:12 -0700
commitc3b969ab0c049efd7a699fe4dacc659b7ceb30bb (patch)
treef8870796444d969209f6fb4acb0cd1b41bae5c06
parentd852f06bb611557c3a6e0aa81400ccff0d3c7c1a (diff)
downloadexternal_qemu-c3b969ab0c049efd7a699fe4dacc659b7ceb30bb.zip
external_qemu-c3b969ab0c049efd7a699fe4dacc659b7ceb30bb.tar.gz
external_qemu-c3b969ab0c049efd7a699fe4dacc659b7ceb30bb.tar.bz2
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
-rw-r--r--hw/goldfish_pipe.c19
1 files changed, 17 insertions, 2 deletions
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);