57 lines
2.0 KiB
Diff
57 lines
2.0 KiB
Diff
|
From c42b3aca84c5b1a8be7010e518f526a1798e3790 Mon Sep 17 00:00:00 2001
|
||
|
From: Alexander Graf <agraf@suse.de>
|
||
|
Date: Mon, 25 Jun 2012 19:02:32 +0200
|
||
|
Subject: [PATCH] linux-user: fix segmentation fault passing with g2h(x) != x
|
||
|
|
||
|
When forwarding a segmentation fault into the guest process, we were passing
|
||
|
the host's address directly into the guest process's signal descriptor.
|
||
|
|
||
|
That obviously confused the guest process, since it didn't know what to make
|
||
|
of the (usually 32-bit truncated) address. Passing in g2h(address) makes the
|
||
|
guest process a lot happier.
|
||
|
|
||
|
This fixes java running in arm-linux-user for me.
|
||
|
|
||
|
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||
|
---
|
||
|
user-exec.c | 25 +++++++++++++------------
|
||
|
1 files changed, 13 insertions(+), 12 deletions(-)
|
||
|
|
||
|
diff --git a/user-exec.c b/user-exec.c
|
||
|
index 36d29b4..83d2d44 100644
|
||
|
--- a/user-exec.c
|
||
|
+++ b/user-exec.c
|
||
|
@@ -100,19 +100,20 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
|
||
|
/* Maybe we're still holding the TB fiddling lock? */
|
||
|
spin_unlock_safe(&tb_lock);
|
||
|
|
||
|
- /* XXX: locking issue */
|
||
|
- if (is_write && h2g_valid(address)
|
||
|
- && page_unprotect(h2g(address), pc, puc)) {
|
||
|
- return 1;
|
||
|
- }
|
||
|
+ if (h2g_valid(address)) {
|
||
|
+ /* XXX: locking issue */
|
||
|
+ if (is_write && page_unprotect(h2g(address), pc, puc)) {
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
|
||
|
- /* see if it is an MMU fault */
|
||
|
- ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX);
|
||
|
- if (ret < 0) {
|
||
|
- return 0; /* not an MMU fault */
|
||
|
- }
|
||
|
- if (ret == 0) {
|
||
|
- return 1; /* the MMU fault was handled without causing real CPU fault */
|
||
|
+ /* see if it is an MMU fault */
|
||
|
+ ret = cpu_handle_mmu_fault(env, h2g(address), is_write, MMU_USER_IDX);
|
||
|
+ if (ret < 0) {
|
||
|
+ return 0; /* not an MMU fault */
|
||
|
+ }
|
||
|
+ if (ret == 0) {
|
||
|
+ return 1; /* the MMU fault was handled without causing real CPU fault */
|
||
|
+ }
|
||
|
}
|
||
|
/* now we have a real cpu fault */
|
||
|
tb = tb_find_pc(pc);
|