Re: [PATCH v2] hvf: arm: Ignore cache operations on MMIO

2021-11-02 Thread Richard Henderson

On 11/2/21 6:42 AM, Peter Maydell wrote:

On Tue, 2 Nov 2021 at 10:01, Richard Henderson
 wrote:


On 11/1/21 3:35 PM, Peter Maydell wrote:

On Mon, 1 Nov 2021 at 19:28, Richard Henderson
 wrote:


On 10/26/21 3:12 AM, Alexander Graf wrote:

Apple's Hypervisor.Framework forwards cache operations as MMIO traps
into user space. For MMIO however, these have no meaning: There is no
cache attached to them.

So let's just treat cache data exits as nops.

This fixes OpenBSD booting as guest.

Signed-off-by: Alexander Graf 
Reported-by: AJ Barris 
Reference: https://github.com/utmapp/UTM/issues/3197
---
target/arm/hvf/hvf.c | 7 +++
1 file changed, 7 insertions(+)


Thanks, applied to target-arm.next


...did you see my email saying I think we also need
to test S1PTW ?


That arrived afterward.


Thinking it over later, I wouldn't be opposed to taking this
patch now and adding the S1PTW second -- I think we're
currently going to do the wrong thing for the "page tables
not in RAM case anyway", so you could regard it as a
separate bug fix.


Heh.  I was thinking the something similar, after I dequeued the patch.  That this fixes a 
problem emulating a well-behaved guest, and that the s1ptw hole is "merely" a problem vs 
an ill-behaved guest hitting the following assert.


Well, I've sent off the PR without this included, so I guess this should be the first cab 
off the rank for the next set.


I'm quite happy to hand the target-arm.next baton back to you.  ;-)

r~



[PULL 31/60] target/nios2: Implement nios2_cpu_record_sigsegv

2021-11-02 Thread Richard Henderson
Because the linux-user kuser page handling is currently implemented
by detecting magic addresses in the unnamed 0xaa trap, we cannot
simply remove nios2_cpu_tlb_fill and rely on the fallback code.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/nios2/cpu.h| 6 ++
 target/nios2/cpu.c| 6 --
 target/nios2/helper.c | 7 ---
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index a80587338a..1a69ed7a49 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -218,9 +218,15 @@ static inline int cpu_mmu_index(CPUNios2State *env, bool 
ifetch)
   MMU_SUPERVISOR_IDX;
 }
 
+#ifdef CONFIG_USER_ONLY
+void nios2_cpu_record_sigsegv(CPUState *cpu, vaddr addr,
+  MMUAccessType access_type,
+  bool maperr, uintptr_t ra);
+#else
 bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MMUAccessType access_type, int mmu_idx,
 bool probe, uintptr_t retaddr);
+#endif
 
 static inline int cpu_interrupts_enabled(CPUNios2State *env)
 {
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index 58ecd27d75..4cade61e93 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -216,9 +216,11 @@ static const struct SysemuCPUOps nios2_sysemu_ops = {
 
 static const struct TCGCPUOps nios2_tcg_ops = {
 .initialize = nios2_tcg_init,
-.tlb_fill = nios2_cpu_tlb_fill,
 
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+.record_sigsegv = nios2_cpu_record_sigsegv,
+#else
+.tlb_fill = nios2_cpu_tlb_fill,
 .cpu_exec_interrupt = nios2_cpu_exec_interrupt,
 .do_interrupt = nios2_cpu_do_interrupt,
 .do_unaligned_access = nios2_cpu_do_unaligned_access,
diff --git a/target/nios2/helper.c b/target/nios2/helper.c
index 53be8398e9..e5c98650e1 100644
--- a/target/nios2/helper.c
+++ b/target/nios2/helper.c
@@ -38,10 +38,11 @@ void nios2_cpu_do_interrupt(CPUState *cs)
 env->regs[R_EA] = env->regs[R_PC] + 4;
 }
 
-bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-MMUAccessType access_type, int mmu_idx,
-bool probe, uintptr_t retaddr)
+void nios2_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+  MMUAccessType access_type,
+  bool maperr, uintptr_t retaddr)
 {
+/* FIXME: Disentangle kuser page from linux-user sigsegv handling. */
 cs->exception_index = 0xaa;
 cpu_loop_exit_restore(cs, retaddr);
 }
-- 
2.25.1




[PULL 50/60] target/ppc: Restrict ppc_cpu_do_unaligned_access to sysemu

2021-11-02 Thread Richard Henderson
This is not used by, nor required by, user-only.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/ppc/internal.h| 8 +++-
 target/ppc/excp_helper.c | 8 +++-
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index 339974b7d8..6aa9484f34 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -211,11 +211,6 @@ void helper_compute_fprf_float16(CPUPPCState *env, float16 
arg);
 void helper_compute_fprf_float32(CPUPPCState *env, float32 arg);
 void helper_compute_fprf_float128(CPUPPCState *env, float128 arg);
 
-/* Raise a data fault alignment exception for the specified virtual address */
-void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
- MMUAccessType access_type, int mmu_idx,
- uintptr_t retaddr) QEMU_NORETURN;
-
 /* translate.c */
 
 int ppc_fixup_cpu(PowerPCCPU *cpu);
@@ -291,6 +286,9 @@ void ppc_cpu_record_sigsegv(CPUState *cs, vaddr addr,
 bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
   MMUAccessType access_type, int mmu_idx,
   bool probe, uintptr_t retaddr);
+void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
+ MMUAccessType access_type, int mmu_idx,
+ uintptr_t retaddr) QEMU_NORETURN;
 #endif
 
 #endif /* PPC_INTERNAL_H */
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index e568a54536..17607adbe4 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1454,11 +1454,8 @@ void helper_book3s_msgsndp(CPUPPCState *env, 
target_ulong rb)
 
 book3s_msgsnd_common(pir, PPC_INTERRUPT_DOORBELL);
 }
-#endif
-#endif /* CONFIG_TCG */
-#endif
+#endif /* TARGET_PPC64 */
 
-#ifdef CONFIG_TCG
 void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
  MMUAccessType access_type,
  int mmu_idx, uintptr_t retaddr)
@@ -1483,4 +1480,5 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr 
vaddr,
 env->error_code = 0;
 cpu_loop_exit_restore(cs, retaddr);
 }
-#endif
+#endif /* CONFIG_TCG */
+#endif /* !CONFIG_USER_ONLY */
-- 
2.25.1




[PULL 41/60] accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu

2021-11-02 Thread Richard Henderson
We have replaced tlb_fill with record_sigsegv for user mode.
Move the declaration to restrict it to system emulation.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/hw/core/tcg-cpu-ops.h | 22 ++
 linux-user/signal.c   |  3 ---
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index 41718b695b..8eadd404c8 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -35,18 +35,6 @@ struct TCGCPUOps {
 void (*cpu_exec_enter)(CPUState *cpu);
 /** @cpu_exec_exit: Callback for cpu_exec cleanup */
 void (*cpu_exec_exit)(CPUState *cpu);
-/**
- * @tlb_fill: Handle a softmmu tlb miss or user-only address fault
- *
- * For system mode, if the access is valid, call tlb_set_page
- * and return true; if the access is invalid, and probe is
- * true, return false; otherwise raise an exception and do
- * not return.  For user-only mode, always raise an exception
- * and do not return.
- */
-bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
 /** @debug_excp_handler: Callback for handling debug exceptions */
 void (*debug_excp_handler)(CPUState *cpu);
 
@@ -68,6 +56,16 @@ struct TCGCPUOps {
 #ifdef CONFIG_SOFTMMU
 /** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
 bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
+/**
+ * @tlb_fill: Handle a softmmu tlb miss
+ *
+ * If the access is valid, call tlb_set_page and return true;
+ * if the access is invalid and probe is true, return false;
+ * otherwise raise an exception and do not return.
+ */
+bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
 /**
  * @do_transaction_failed: Callback for handling failed memory transactions
  * (ie bus faults or external aborts; not MMU faults)
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 135983747d..9d60abc038 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -697,9 +697,6 @@ void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
 
 if (tcg_ops->record_sigsegv) {
 tcg_ops->record_sigsegv(cpu, addr, access_type, maperr, ra);
-} else if (tcg_ops->tlb_fill) {
-tcg_ops->tlb_fill(cpu, addr, 0, access_type, MMU_USER_IDX, false, ra);
-g_assert_not_reached();
 }
 
 force_sig_fault(TARGET_SIGSEGV,
-- 
2.25.1




[PULL 57/60] accel/tcg: Report unaligned atomics for user-only

2021-11-02 Thread Richard Henderson
Use the new cpu_loop_exit_sigbus for atomic_mmu_lookup, which
has access to complete alignment info from the TCGMemOpIdx arg.

Reviewed-by: Warner Losh 
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 accel/tcg/user-exec.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index c4f69908e9..1ee64f01fc 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -474,11 +474,22 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
MemOpIdx oi, int size, int prot,
uintptr_t retaddr)
 {
+MemOp mop = get_memop(oi);
+int a_bits = get_alignment_bits(mop);
+void *ret;
+
+/* Enforce guest required alignment.  */
+if (unlikely(addr & ((1 << a_bits) - 1))) {
+MMUAccessType t = prot == PAGE_READ ? MMU_DATA_LOAD : MMU_DATA_STORE;
+cpu_loop_exit_sigbus(env_cpu(env), addr, t, retaddr);
+}
+
 /* Enforce qemu required alignment.  */
 if (unlikely(addr & (size - 1))) {
 cpu_loop_exit_atomic(env_cpu(env), retaddr);
 }
-void *ret = g2h(env_cpu(env), addr);
+
+ret = g2h(env_cpu(env), addr);
 set_helper_retaddr(retaddr);
 return ret;
 }
-- 
2.25.1




[PULL 49/60] target/ppc: Set fault address in ppc_cpu_do_unaligned_access

2021-11-02 Thread Richard Henderson
We ought to have been recording the virtual address for reporting
to the guest trap handler.

Cc: qemu-...@nongnu.org
Reviewed-by: Warner Losh 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/ppc/excp_helper.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 88a8de4b80..e568a54536 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1465,6 +1465,20 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr 
vaddr,
 {
 CPUPPCState *env = cs->env_ptr;
 
+switch (env->mmu_model) {
+case POWERPC_MMU_SOFT_4xx:
+case POWERPC_MMU_SOFT_4xx_Z:
+env->spr[SPR_40x_DEAR] = vaddr;
+break;
+case POWERPC_MMU_BOOKE:
+case POWERPC_MMU_BOOKE206:
+env->spr[SPR_BOOKE_DEAR] = vaddr;
+break;
+default:
+env->spr[SPR_DAR] = vaddr;
+break;
+}
+
 cs->exception_index = POWERPC_EXCP_ALIGN;
 env->error_code = 0;
 cpu_loop_exit_restore(cs, retaddr);
-- 
2.25.1




[PULL 46/60] linux-user/hppa: Remove EXCP_UNALIGN handling

2021-11-02 Thread Richard Henderson
We will raise SIGBUS directly from cpu_loop_exit_sigbus.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/hppa/cpu_loop.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index e0a62deeb9..375576c8f0 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -144,13 +144,6 @@ void cpu_loop(CPUHPPAState *env)
 env->iaoq_f = env->gr[31];
 env->iaoq_b = env->gr[31] + 4;
 break;
-case EXCP_UNALIGN:
-info.si_signo = TARGET_SIGBUS;
-info.si_errno = 0;
-info.si_code = 0;
-info._sifields._sigfault._addr = env->cr[CR_IOR];
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
 case EXCP_ILL:
 case EXCP_PRIV_OPR:
 case EXCP_PRIV_REG:
-- 
2.25.1




[PULL 54/60] target/sparc: Remove DEBUG_UNALIGNED

2021-11-02 Thread Richard Henderson
The printf should have been qemu_log_mask, the parameters
themselves no longer compile, and because this is placed
before unwinding the PC is actively wrong.

We get better (and correct) logging on the other side of
raising the exception, in sparc_cpu_do_interrupt.

Reviewed-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/sparc/ldst_helper.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
index bbf3601cb1..0549b6adf1 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -27,7 +27,6 @@
 
 //#define DEBUG_MMU
 //#define DEBUG_MXCC
-//#define DEBUG_UNALIGNED
 //#define DEBUG_UNASSIGNED
 //#define DEBUG_ASI
 //#define DEBUG_CACHE_CONTROL
@@ -364,10 +363,6 @@ static void do_check_align(CPUSPARCState *env, 
target_ulong addr,
uint32_t align, uintptr_t ra)
 {
 if (addr & align) {
-#ifdef DEBUG_UNALIGNED
-printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
-   "\n", addr, env->pc);
-#endif
 cpu_raise_exception_ra(env, TT_UNALIGNED, ra);
 }
 }
@@ -1968,10 +1963,6 @@ void QEMU_NORETURN 
sparc_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
 SPARCCPU *cpu = SPARC_CPU(cs);
 CPUSPARCState *env = >env;
 
-#ifdef DEBUG_UNALIGNED
-printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
-   "\n", addr, env->pc);
-#endif
 cpu_raise_exception_ra(env, TT_UNALIGNED, retaddr);
 }
 #endif
-- 
2.25.1




[PULL 37/60] target/s390x: Implement s390_cpu_record_sigsegv

2021-11-02 Thread Richard Henderson
Move the masking of the address from cpu_loop into
s390_cpu_record_sigsegv -- this is governed by hw, not linux.
This does mean we have to raise our own exception, rather
than return to the fallback.

Use maperr to choose between PGM_PROTECTION and PGM_ADDRESSING.
Use the appropriate si_code for each in cpu_loop.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/s390x/s390x-internal.h  | 13 ++---
 linux-user/s390x/cpu_loop.c| 13 ++---
 target/s390x/cpu.c |  6 --
 target/s390x/tcg/excp_helper.c | 18 +++---
 4 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/target/s390x/s390x-internal.h b/target/s390x/s390x-internal.h
index 27d4a03ca1..163aa4f94a 100644
--- a/target/s390x/s390x-internal.h
+++ b/target/s390x/s390x-internal.h
@@ -270,13 +270,20 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 void s390x_cpu_debug_excp_handler(CPUState *cs);
 void s390_cpu_do_interrupt(CPUState *cpu);
 bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
-bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr);
 void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type, int mmu_idx,
uintptr_t retaddr) QEMU_NORETURN;
 
+#ifdef CONFIG_USER_ONLY
+void s390_cpu_record_sigsegv(CPUState *cs, vaddr address,
+ MMUAccessType access_type,
+ bool maperr, uintptr_t retaddr);
+#else
+bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
+#endif
+
 
 /* fpu_helper.c */
 uint32_t set_cc_nz_f32(float32 v);
diff --git a/linux-user/s390x/cpu_loop.c b/linux-user/s390x/cpu_loop.c
index 69b69981f6..d089c8417e 100644
--- a/linux-user/s390x/cpu_loop.c
+++ b/linux-user/s390x/cpu_loop.c
@@ -24,8 +24,6 @@
 #include "cpu_loop-common.h"
 #include "signal-common.h"
 
-/* s390x masks the fault address it reports in si_addr for SIGSEGV and SIGBUS 
*/
-#define S390X_FAIL_ADDR_MASK -4096LL
 
 static int get_pgm_data_si_code(int dxc_code)
 {
@@ -111,12 +109,13 @@ void cpu_loop(CPUS390XState *env)
 n = TARGET_ILL_ILLOPC;
 goto do_signal_pc;
 case PGM_PROTECTION:
+force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_ACCERR,
+env->__excp_addr);
+break;
 case PGM_ADDRESSING:
-sig = TARGET_SIGSEGV;
-/* XXX: check env->error_code */
-n = TARGET_SEGV_MAPERR;
-addr = env->__excp_addr & S390X_FAIL_ADDR_MASK;
-goto do_signal;
+force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR,
+env->__excp_addr);
+break;
 case PGM_EXECUTE:
 case PGM_SPECIFICATION:
 case PGM_SPECIAL_OP:
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 7b7b05f1d3..593dda75c4 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -266,9 +266,11 @@ static void s390_cpu_reset_full(DeviceState *dev)
 
 static const struct TCGCPUOps s390_tcg_ops = {
 .initialize = s390x_translate_init,
-.tlb_fill = s390_cpu_tlb_fill,
 
-#if !defined(CONFIG_USER_ONLY)
+#ifdef CONFIG_USER_ONLY
+.record_sigsegv = s390_cpu_record_sigsegv,
+#else
+.tlb_fill = s390_cpu_tlb_fill,
 .cpu_exec_interrupt = s390_cpu_exec_interrupt,
 .do_interrupt = s390_cpu_do_interrupt,
 .debug_excp_handler = s390x_cpu_debug_excp_handler,
diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c
index 3d6662a53c..b923d080fc 100644
--- a/target/s390x/tcg/excp_helper.c
+++ b/target/s390x/tcg/excp_helper.c
@@ -89,16 +89,20 @@ void s390_cpu_do_interrupt(CPUState *cs)
 cs->exception_index = -1;
 }
 
-bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr)
+void s390_cpu_record_sigsegv(CPUState *cs, vaddr address,
+ MMUAccessType access_type,
+ bool maperr, uintptr_t retaddr)
 {
 S390CPU *cpu = S390_CPU(cs);
 
-trigger_pgm_exception(>env, PGM_ADDRESSING);
-/* On real machines this value is dropped into LowMem.  Since this
-   is userland, simply put this someplace that cpu_loop can find it.  */
-cpu->env.__excp_addr = address;
+trigger_pgm_exception(>env, maperr ? PGM_ADDRESSING : PGM_PROTECTION);
+/*
+ * On real machines this value is dropped into LowMem. Since this
+ * is userland, simply put this someplace that cpu_loop can find it.
+ * S390 only gives the page of the fault, 

[PULL 42/60] hw/core: Add TCGCPUOps.record_sigbus

2021-11-02 Thread Richard Henderson
Add a new user-only interface for updating cpu state before
raising a signal.  This will take the place of do_unaligned_access
for user-only and should result in less boilerplate for each guest.

Reviewed-by: Warner Losh 
Signed-off-by: Richard Henderson 
---
 include/hw/core/tcg-cpu-ops.h | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index 8eadd404c8..e13898553a 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -135,6 +135,29 @@ struct TCGCPUOps {
 void (*record_sigsegv)(CPUState *cpu, vaddr addr,
MMUAccessType access_type,
bool maperr, uintptr_t ra);
+/**
+ * record_sigbus:
+ * @cpu: cpu context
+ * @addr: misaligned guest address
+ * @access_type: access was read/write/execute
+ * @ra: host pc for unwinding
+ *
+ * We are about to raise SIGBUS with si_code BUS_ADRALN,
+ * and si_addr set for @addr.  Record anything further needed
+ * for the signal ucontext_t.
+ *
+ * If the emulated kernel does not provide the signal handler with
+ * anything besides the user context registers, and the siginfo_t,
+ * then this hook need do nothing and may be omitted.
+ * Otherwise, record the data and return; the caller will raise
+ * the signal, unwind the cpu state, and return to the main loop.
+ *
+ * If it is simpler to re-use the sysemu do_unaligned_access code,
+ * @ra is provided so that a "normal" cpu exception can be raised.
+ * In this case, the signal must be raised by the architecture cpu_loop.
+ */
+void (*record_sigbus)(CPUState *cpu, vaddr addr,
+  MMUAccessType access_type, uintptr_t ra);
 #endif /* CONFIG_SOFTMMU */
 #endif /* NEED_CPU_H */
 
-- 
2.25.1




[PULL 30/60] target/mips: Make mips_cpu_tlb_fill sysemu only

2021-11-02 Thread Richard Henderson
The fallback code in cpu_loop_exit_sigsegv is sufficient
for mips linux-user.

This means we can remove tcg/user/tlb_helper.c entirely.
Remove the code from cpu_loop that raised SIGSEGV.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/mips/tcg/tcg-internal.h|  7 ++--
 linux-user/mips/cpu_loop.c| 11 --
 target/mips/cpu.c |  2 +-
 target/mips/tcg/user/tlb_helper.c | 59 ---
 target/mips/tcg/meson.build   |  3 --
 target/mips/tcg/user/meson.build  |  3 --
 6 files changed, 5 insertions(+), 80 deletions(-)
 delete mode 100644 target/mips/tcg/user/tlb_helper.c
 delete mode 100644 target/mips/tcg/user/meson.build

diff --git a/target/mips/tcg/tcg-internal.h b/target/mips/tcg/tcg-internal.h
index bad3deb611..466768aec4 100644
--- a/target/mips/tcg/tcg-internal.h
+++ b/target/mips/tcg/tcg-internal.h
@@ -18,9 +18,6 @@
 void mips_tcg_init(void);
 
 void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb);
-bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr);
 void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
   MMUAccessType access_type, int mmu_idx,
   uintptr_t retaddr) QEMU_NORETURN;
@@ -60,6 +57,10 @@ void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr 
physaddr,
 MemTxResult response, uintptr_t retaddr);
 void cpu_mips_tlb_flush(CPUMIPSState *env);
 
+bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
+
 #endif /* !CONFIG_USER_ONLY */
 
 #endif
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index cb03fb066b..b735c99a24 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -158,17 +158,6 @@ done_syscall:
 }
 env->active_tc.gpr[2] = ret;
 break;
-case EXCP_TLBL:
-case EXCP_TLBS:
-case EXCP_AdEL:
-case EXCP_AdES:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->CP0_BadVAddr;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
 case EXCP_CpU:
 case EXCP_RI:
 info.si_signo = TARGET_SIGILL;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 00e0c55d0e..4aae23934b 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -539,9 +539,9 @@ static const struct SysemuCPUOps mips_sysemu_ops = {
 static const struct TCGCPUOps mips_tcg_ops = {
 .initialize = mips_tcg_init,
 .synchronize_from_tb = mips_cpu_synchronize_from_tb,
-.tlb_fill = mips_cpu_tlb_fill,
 
 #if !defined(CONFIG_USER_ONLY)
+.tlb_fill = mips_cpu_tlb_fill,
 .cpu_exec_interrupt = mips_cpu_exec_interrupt,
 .do_interrupt = mips_cpu_do_interrupt,
 .do_transaction_failed = mips_cpu_do_transaction_failed,
diff --git a/target/mips/tcg/user/tlb_helper.c 
b/target/mips/tcg/user/tlb_helper.c
deleted file mode 100644
index 210c6d529e..00
--- a/target/mips/tcg/user/tlb_helper.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * MIPS TLB (Translation lookaside buffer) helpers.
- *
- *  Copyright (c) 2004-2005 Jocelyn Mayer
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see .
- */
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "internal.h"
-
-static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
-MMUAccessType access_type)
-{
-CPUState *cs = env_cpu(env);
-
-env->error_code = 0;
-if (access_type == MMU_INST_FETCH) {
-env->error_code |= EXCP_INST_NOTAVAIL;
-}
-
-/* Reference to kernel address from user mode or supervisor mode */
-/* Reference to supervisor address from user mode */
-if (access_type == MMU_DATA_STORE) {
-cs->exception_index = EXCP_AdES;
-} else {
-cs->exception_index = EXCP_AdEL;
-}
-
-/* Raise exception */
-

[PULL 48/60] target/ppc: Move SPR_DSISR setting to powerpc_excp

2021-11-02 Thread Richard Henderson
By doing this while sending the exception, we will have already
done the unwinding, which makes the ppc_cpu_do_unaligned_access
code a bit cleaner.

Update the comment about the expected instruction format.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/ppc/excp_helper.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index b7d1767920..88a8de4b80 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -454,13 +454,15 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 break;
 }
 case POWERPC_EXCP_ALIGN: /* Alignment exception  */
-/* Get rS/rD and rA from faulting opcode */
 /*
- * Note: the opcode fields will not be set properly for a
- * direct store load/store, but nobody cares as nobody
- * actually uses direct store segments.
+ * Get rS/rD and rA from faulting opcode.
+ * Note: We will only invoke ALIGN for atomic operations,
+ * so all instructions are X-form.
  */
-env->spr[SPR_DSISR] |= (env->error_code & 0x03FF) >> 16;
+{
+uint32_t insn = cpu_ldl_code(env, env->nip);
+env->spr[SPR_DSISR] |= (insn & 0x03FF) >> 16;
+}
 break;
 case POWERPC_EXCP_PROGRAM:   /* Program exception*/
 switch (env->error_code & ~0xF) {
@@ -1462,14 +1464,9 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr 
vaddr,
  int mmu_idx, uintptr_t retaddr)
 {
 CPUPPCState *env = cs->env_ptr;
-uint32_t insn;
-
-/* Restore state and reload the insn we executed, for filling in DSISR.  */
-cpu_restore_state(cs, retaddr, true);
-insn = cpu_ldl_code(env, env->nip);
 
 cs->exception_index = POWERPC_EXCP_ALIGN;
-env->error_code = insn & 0x03FF;
-cpu_loop_exit(cs);
+env->error_code = 0;
+cpu_loop_exit_restore(cs, retaddr);
 }
 #endif
-- 
2.25.1




[PULL 44/60] target/alpha: Implement alpha_cpu_record_sigbus

2021-11-02 Thread Richard Henderson
Record trap_arg{0,1,2} for the linux-user signal frame.

Raise SIGBUS directly from cpu_loop_exit_sigbus, which means
we can remove the code for EXCP_UNALIGN in cpu_loop.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/alpha/cpu.h  |  8 +---
 linux-user/alpha/cpu_loop.c |  7 ---
 target/alpha/cpu.c  |  1 +
 target/alpha/mem_helper.c   | 30 ++
 4 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index d49cc36d07..afd975c878 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -282,9 +282,6 @@ void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
-   MMUAccessType access_type, int mmu_idx,
-   uintptr_t retaddr) QEMU_NORETURN;
 
 #define cpu_list alpha_cpu_list
 
@@ -451,10 +448,15 @@ void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, 
uint64_t val);
 void alpha_cpu_record_sigsegv(CPUState *cs, vaddr address,
   MMUAccessType access_type,
   bool maperr, uintptr_t retaddr);
+void alpha_cpu_record_sigbus(CPUState *cs, vaddr address,
+ MMUAccessType access_type, uintptr_t retaddr);
 #else
 bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MMUAccessType access_type, int mmu_idx,
 bool probe, uintptr_t retaddr);
+void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
+   MMUAccessType access_type, int mmu_idx,
+   uintptr_t retaddr) QEMU_NORETURN;
 void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
  vaddr addr, unsigned size,
  MMUAccessType access_type,
diff --git a/linux-user/alpha/cpu_loop.c b/linux-user/alpha/cpu_loop.c
index 4cc8e0a55c..4029849d5c 100644
--- a/linux-user/alpha/cpu_loop.c
+++ b/linux-user/alpha/cpu_loop.c
@@ -54,13 +54,6 @@ void cpu_loop(CPUAlphaState *env)
 fprintf(stderr, "External interrupt. Exit\n");
 exit(EXIT_FAILURE);
 break;
-case EXCP_UNALIGN:
-info.si_signo = TARGET_SIGBUS;
-info.si_errno = 0;
-info.si_code = TARGET_BUS_ADRALN;
-info._sifields._sigfault._addr = env->trap_arg0;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
 case EXCP_OPCDEC:
 do_sigill:
 info.si_signo = TARGET_SIGILL;
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 69f32c3078..a8990d401b 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -221,6 +221,7 @@ static const struct TCGCPUOps alpha_tcg_ops = {
 
 #ifdef CONFIG_USER_ONLY
 .record_sigsegv = alpha_cpu_record_sigsegv,
+.record_sigbus = alpha_cpu_record_sigbus,
 #else
 .tlb_fill = alpha_cpu_tlb_fill,
 .cpu_exec_interrupt = alpha_cpu_exec_interrupt,
diff --git a/target/alpha/mem_helper.c b/target/alpha/mem_helper.c
index 75e72bc337..47283a0612 100644
--- a/target/alpha/mem_helper.c
+++ b/target/alpha/mem_helper.c
@@ -23,18 +23,12 @@
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 
-/* Softmmu support */
-#ifndef CONFIG_USER_ONLY
-void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
-   MMUAccessType access_type,
-   int mmu_idx, uintptr_t retaddr)
+static void do_unaligned_access(CPUAlphaState *env, vaddr addr, uintptr_t 
retaddr)
 {
-AlphaCPU *cpu = ALPHA_CPU(cs);
-CPUAlphaState *env = >env;
 uint64_t pc;
 uint32_t insn;
 
-cpu_restore_state(cs, retaddr, true);
+cpu_restore_state(env_cpu(env), retaddr, true);
 
 pc = env->pc;
 insn = cpu_ldl_code(env, pc);
@@ -42,6 +36,26 @@ void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
 env->trap_arg0 = addr;
 env->trap_arg1 = insn >> 26;/* opcode */
 env->trap_arg2 = (insn >> 21) & 31; /* dest regno */
+}
+
+#ifdef CONFIG_USER_ONLY
+void alpha_cpu_record_sigbus(CPUState *cs, vaddr addr,
+ MMUAccessType access_type, uintptr_t retaddr)
+{
+AlphaCPU *cpu = ALPHA_CPU(cs);
+CPUAlphaState *env = >env;
+
+do_unaligned_access(env, addr, retaddr);
+}
+#else
+void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
+   MMUAccessType access_type,
+   int mmu_idx, uintptr_t retaddr)
+{
+AlphaCPU *cpu = ALPHA_CPU(cs);
+CPUAlphaState *env = >env;
+
+do_unaligned_access(env, 

[PULL 40/60] target/xtensa: Make xtensa_cpu_tlb_fill sysemu only

2021-11-02 Thread Richard Henderson
The fallback code in cpu_loop_exit_sigsegv is sufficient
for xtensa linux-user.

Remove the code from cpu_loop that raised SIGSEGV.

Acked-by: Max Filippov 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/xtensa/cpu.h  |  2 +-
 linux-user/xtensa/cpu_loop.c |  9 -
 target/xtensa/cpu.c  |  2 +-
 target/xtensa/helper.c   | 22 +-
 4 files changed, 3 insertions(+), 32 deletions(-)

diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index f9a510ca46..02143f2f77 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -563,10 +563,10 @@ struct XtensaCPU {
 };
 
 
+#ifndef CONFIG_USER_ONLY
 bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
  MMUAccessType access_type, int mmu_idx,
  bool probe, uintptr_t retaddr);
-#ifndef CONFIG_USER_ONLY
 void xtensa_cpu_do_interrupt(CPUState *cpu);
 bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr 
addr,
diff --git a/linux-user/xtensa/cpu_loop.c b/linux-user/xtensa/cpu_loop.c
index 622afbcd34..a83490ab35 100644
--- a/linux-user/xtensa/cpu_loop.c
+++ b/linux-user/xtensa/cpu_loop.c
@@ -226,15 +226,6 @@ void cpu_loop(CPUXtensaState *env)
 queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
 break;
 
-case LOAD_PROHIBITED_CAUSE:
-case STORE_PROHIBITED_CAUSE:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = TARGET_SEGV_ACCERR;
-info._sifields._sigfault._addr = env->sregs[EXCVADDR];
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
-
 default:
 fprintf(stderr, "exccause = %d\n", env->sregs[EXCCAUSE]);
 g_assert_not_reached();
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index c1cbd03595..224f723236 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -192,10 +192,10 @@ static const struct SysemuCPUOps xtensa_sysemu_ops = {
 
 static const struct TCGCPUOps xtensa_tcg_ops = {
 .initialize = xtensa_translate_init,
-.tlb_fill = xtensa_cpu_tlb_fill,
 .debug_excp_handler = xtensa_breakpoint_handler,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = xtensa_cpu_tlb_fill,
 .cpu_exec_interrupt = xtensa_cpu_exec_interrupt,
 .do_interrupt = xtensa_cpu_do_interrupt,
 .do_transaction_failed = xtensa_cpu_do_transaction_failed,
diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c
index f18ab383fd..29d216ec1b 100644
--- a/target/xtensa/helper.c
+++ b/target/xtensa/helper.c
@@ -242,27 +242,7 @@ void xtensa_cpu_list(void)
 }
 }
 
-#ifdef CONFIG_USER_ONLY
-
-bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
-XtensaCPU *cpu = XTENSA_CPU(cs);
-CPUXtensaState *env = >env;
-
-qemu_log_mask(CPU_LOG_INT,
-  "%s: rw = %d, address = 0x%08" VADDR_PRIx ", size = %d\n",
-  __func__, access_type, address, size);
-env->sregs[EXCVADDR] = address;
-env->sregs[EXCCAUSE] = (access_type == MMU_DATA_STORE ?
-STORE_PROHIBITED_CAUSE : LOAD_PROHIBITED_CAUSE);
-cs->exception_index = EXC_USER;
-cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else /* !CONFIG_USER_ONLY */
-
+#ifndef CONFIG_USER_ONLY
 void xtensa_cpu_do_unaligned_access(CPUState *cs,
 vaddr addr, MMUAccessType access_type,
 int mmu_idx, uintptr_t retaddr)
-- 
2.25.1




[PULL 26/60] target/hppa: Make hppa_cpu_tlb_fill sysemu only

2021-11-02 Thread Richard Henderson
The fallback code in cpu_loop_exit_sigsegv is sufficient
for hppa linux-user.

Remove the code from cpu_loop that raised SIGSEGV.
This makes all of the code in mem_helper.c sysemu only,
so remove the ifdefs and move the file to hppa_softmmu_ss.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h  |  2 +-
 linux-user/hppa/cpu_loop.c | 16 
 target/hppa/cpu.c  |  2 +-
 target/hppa/mem_helper.c   | 15 ---
 target/hppa/meson.build|  6 --
 5 files changed, 6 insertions(+), 35 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index d3cb7a279f..294fd7297f 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -323,10 +323,10 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr);
 int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
+#ifndef CONFIG_USER_ONLY
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
-#ifndef CONFIG_USER_ONLY
 void hppa_cpu_do_interrupt(CPUState *cpu);
 bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
 int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index 81607a9b27..e0a62deeb9 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -144,22 +144,6 @@ void cpu_loop(CPUHPPAState *env)
 env->iaoq_f = env->gr[31];
 env->iaoq_b = env->gr[31] + 4;
 break;
-case EXCP_ITLB_MISS:
-case EXCP_DTLB_MISS:
-case EXCP_NA_ITLB_MISS:
-case EXCP_NA_DTLB_MISS:
-case EXCP_IMP:
-case EXCP_DMP:
-case EXCP_DMB:
-case EXCP_PAGE_REF:
-case EXCP_DMAR:
-case EXCP_DMPI:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = TARGET_SEGV_ACCERR;
-info._sifields._sigfault._addr = env->cr[CR_IOR];
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
 case EXCP_UNALIGN:
 info.si_signo = TARGET_SIGBUS;
 info.si_errno = 0;
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 89cba9d7a2..23eb254228 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -145,9 +145,9 @@ static const struct SysemuCPUOps hppa_sysemu_ops = {
 static const struct TCGCPUOps hppa_tcg_ops = {
 .initialize = hppa_translate_init,
 .synchronize_from_tb = hppa_cpu_synchronize_from_tb,
-.tlb_fill = hppa_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = hppa_cpu_tlb_fill,
 .cpu_exec_interrupt = hppa_cpu_exec_interrupt,
 .do_interrupt = hppa_cpu_do_interrupt,
 .do_unaligned_access = hppa_cpu_do_unaligned_access,
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index afc5b56c3e..bf07445cd1 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -24,20 +24,6 @@
 #include "hw/core/cpu.h"
 #include "trace.h"
 
-#ifdef CONFIG_USER_ONLY
-bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr)
-{
-HPPACPU *cpu = HPPA_CPU(cs);
-
-/* ??? Test between data page fault and data memory protection trap,
-   which would affect si_code.  */
-cs->exception_index = EXCP_DMP;
-cpu->env.cr[CR_IOR] = address;
-cpu_loop_exit_restore(cs, retaddr);
-}
-#else
 static hppa_tlb_entry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
 {
 int i;
@@ -392,4 +378,3 @@ int hppa_artype_for_page(CPUHPPAState *env, target_ulong 
vaddr)
 hppa_tlb_entry *ent = hppa_find_tlb(env, vaddr);
 return ent ? ent->ar_type : -1;
 }
-#endif /* CONFIG_USER_ONLY */
diff --git a/target/hppa/meson.build b/target/hppa/meson.build
index 8a7ff82efc..021e42a2d0 100644
--- a/target/hppa/meson.build
+++ b/target/hppa/meson.build
@@ -7,13 +7,15 @@ hppa_ss.add(files(
   'gdbstub.c',
   'helper.c',
   'int_helper.c',
-  'mem_helper.c',
   'op_helper.c',
   'translate.c',
 ))
 
 hppa_softmmu_ss = ss.source_set()
-hppa_softmmu_ss.add(files('machine.c'))
+hppa_softmmu_ss.add(files(
+  'machine.c',
+  'mem_helper.c',
+))
 
 target_arch += {'hppa': hppa_ss}
 target_softmmu_arch += {'hppa': hppa_softmmu_ss}
-- 
2.25.1




[PULL 39/60] target/sparc: Make sparc_cpu_tlb_fill sysemu only

2021-11-02 Thread Richard Henderson
The fallback code in cpu_loop_exit_sigsegv is sufficient
for sparc linux-user.

This makes all of the code in mmu_helper.c sysemu only, so remove
the ifdefs and move the file to sparc_softmmu_ss.  Remove the code
from cpu_loop that handled TT_DFAULT and TT_TFAULT.

Cc: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/sparc/cpu_loop.c | 25 -
 target/sparc/cpu.c  |  2 +-
 target/sparc/mmu_helper.c   | 25 -
 target/sparc/meson.build|  2 +-
 4 files changed, 2 insertions(+), 52 deletions(-)

diff --git a/linux-user/sparc/cpu_loop.c b/linux-user/sparc/cpu_loop.c
index ad29b4eb6a..0ba65e431c 100644
--- a/linux-user/sparc/cpu_loop.c
+++ b/linux-user/sparc/cpu_loop.c
@@ -219,17 +219,6 @@ void cpu_loop (CPUSPARCState *env)
 case TT_WIN_UNF: /* window underflow */
 restore_window(env);
 break;
-case TT_TFAULT:
-case TT_DFAULT:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->mmuregs[4];
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-}
-break;
 #else
 case TT_SPILL: /* window overflow */
 save_window(env);
@@ -237,20 +226,6 @@ void cpu_loop (CPUSPARCState *env)
 case TT_FILL: /* window underflow */
 restore_window(env);
 break;
-case TT_TFAULT:
-case TT_DFAULT:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-if (trapnr == TT_DFAULT)
-info._sifields._sigfault._addr = env->dmmu.mmuregs[4];
-else
-info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-}
-break;
 #ifndef TARGET_ABI32
 case 0x16e:
 flush_windows(env);
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 21dd27796d..55268ed2a1 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -865,9 +865,9 @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
 static const struct TCGCPUOps sparc_tcg_ops = {
 .initialize = sparc_tcg_init,
 .synchronize_from_tb = sparc_cpu_synchronize_from_tb,
-.tlb_fill = sparc_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = sparc_cpu_tlb_fill,
 .cpu_exec_interrupt = sparc_cpu_exec_interrupt,
 .do_interrupt = sparc_cpu_do_interrupt,
 .do_transaction_failed = sparc_cpu_do_transaction_failed,
diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index a44473a1c7..2ad47391d0 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -25,30 +25,6 @@
 
 /* Sparc MMU emulation */
 
-#if defined(CONFIG_USER_ONLY)
-
-bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-MMUAccessType access_type, int mmu_idx,
-bool probe, uintptr_t retaddr)
-{
-SPARCCPU *cpu = SPARC_CPU(cs);
-CPUSPARCState *env = >env;
-
-if (access_type == MMU_INST_FETCH) {
-cs->exception_index = TT_TFAULT;
-} else {
-cs->exception_index = TT_DFAULT;
-#ifdef TARGET_SPARC64
-env->dmmu.mmuregs[4] = address;
-#else
-env->mmuregs[4] = address;
-#endif
-}
-cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else
-
 #ifndef TARGET_SPARC64
 /*
  * Sparc V8 Reference MMU (SRMMU)
@@ -926,4 +902,3 @@ hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 }
 return phys_addr;
 }
-#endif
diff --git a/target/sparc/meson.build b/target/sparc/meson.build
index a3638b9503..a801802ee2 100644
--- a/target/sparc/meson.build
+++ b/target/sparc/meson.build
@@ -6,7 +6,6 @@ sparc_ss.add(files(
   'gdbstub.c',
   'helper.c',
   'ldst_helper.c',
-  'mmu_helper.c',
   'translate.c',
   'win_helper.c',
 ))
@@ -16,6 +15,7 @@ sparc_ss.add(when: 'TARGET_SPARC64', if_true: 
files('int64_helper.c', 'vis_helpe
 sparc_softmmu_ss = ss.source_set()
 sparc_softmmu_ss.add(files(
   'machine.c',
+  'mmu_helper.c',
   'monitor.c',
 ))
 
-- 
2.25.1




[PULL 24/60] target/cris: Make cris_cpu_tlb_fill sysemu only

2021-11-02 Thread Richard Henderson
The fallback code in cpu_loop_exit_sigsegv is sufficient
for cris linux-user.

Remove the code from cpu_loop that handled the unnamed 0xaa exception.
This makes all of the code in helper.c sysemu only, so remove the
ifdefs and move the file to cris_softmmu_ss.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/cris/cpu.h  |  8 
 linux-user/cris/cpu_loop.c | 10 --
 target/cris/cpu.c  |  4 ++--
 target/cris/helper.c   | 18 --
 target/cris/meson.build|  7 +--
 5 files changed, 11 insertions(+), 36 deletions(-)

diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index 6603565f83..b445b194ea 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -189,6 +189,10 @@ extern const VMStateDescription vmstate_cris_cpu;
 void cris_cpu_do_interrupt(CPUState *cpu);
 void crisv10_cpu_do_interrupt(CPUState *cpu);
 bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
+
+bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
 #endif
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);
@@ -251,10 +255,6 @@ static inline int cpu_mmu_index (CPUCRISState *env, bool 
ifetch)
return !!(env->pregs[PR_CCS] & U_FLAG);
 }
 
-bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr);
-
 /* Support function regs.  */
 #define SFR_RW_GC_CFG  0][0
 #define SFR_RW_MM_CFG  env->pregs[PR_SRS]][0
diff --git a/linux-user/cris/cpu_loop.c b/linux-user/cris/cpu_loop.c
index b9085619c4..0d5d268609 100644
--- a/linux-user/cris/cpu_loop.c
+++ b/linux-user/cris/cpu_loop.c
@@ -37,16 +37,6 @@ void cpu_loop(CPUCRISState *env)
 process_queued_cpu_work(cs);
 
 switch (trapnr) {
-case 0xaa:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->pregs[PR_EDA];
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-}
-break;
 case EXCP_INTERRUPT:
   /* just indicate that signals should be handled asap */
   break;
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index c2e7483f5b..ed6c781342 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -205,9 +205,9 @@ static const struct SysemuCPUOps cris_sysemu_ops = {
 
 static const struct TCGCPUOps crisv10_tcg_ops = {
 .initialize = cris_initialize_crisv10_tcg,
-.tlb_fill = cris_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = cris_cpu_tlb_fill,
 .cpu_exec_interrupt = cris_cpu_exec_interrupt,
 .do_interrupt = crisv10_cpu_do_interrupt,
 #endif /* !CONFIG_USER_ONLY */
@@ -215,9 +215,9 @@ static const struct TCGCPUOps crisv10_tcg_ops = {
 
 static const struct TCGCPUOps crisv32_tcg_ops = {
 .initialize = cris_initialize_tcg,
-.tlb_fill = cris_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = cris_cpu_tlb_fill,
 .cpu_exec_interrupt = cris_cpu_exec_interrupt,
 .do_interrupt = cris_cpu_do_interrupt,
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 36926faf32..a0d6ecdcd3 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -39,22 +39,6 @@
 #define D_LOG(...) do { } while (0)
 #endif
 
-#if defined(CONFIG_USER_ONLY)
-
-bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr)
-{
-CRISCPU *cpu = CRIS_CPU(cs);
-
-cs->exception_index = 0xaa;
-cpu->env.pregs[PR_EDA] = address;
-cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else /* !CONFIG_USER_ONLY */
-
-
 static void cris_shift_ccs(CPUCRISState *env)
 {
 uint32_t ccs;
@@ -304,5 +288,3 @@ bool cris_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 
 return ret;
 }
-
-#endif /* !CONFIG_USER_ONLY */
diff --git a/target/cris/meson.build b/target/cris/meson.build
index 67c3793c85..c1e326d950 100644
--- a/target/cris/meson.build
+++ b/target/cris/meson.build
@@ -2,13 +2,16 @@ cris_ss = ss.source_set()
 cris_ss.add(files(
   'cpu.c',
   'gdbstub.c',
-  'helper.c',
   'op_helper.c',
   'translate.c',
 ))
 
 cris_softmmu_ss = ss.source_set()
-cris_softmmu_ss.add(files('mmu.c', 'machine.c'))
+cris_softmmu_ss.add(files(
+  'helper.c',
+  'machine.c',
+  'mmu.c',
+))
 
 target_arch += {'cris': cris_ss}
 target_softmmu_arch += {'cris': cris_softmmu_ss}
-- 
2.25.1




[PULL 25/60] target/hexagon: Remove hexagon_cpu_tlb_fill

2021-11-02 Thread Richard Henderson
The fallback code in cpu_loop_exit_sigsegv is sufficient
for hexagon linux-user.

Remove the code from cpu_loop that raises SIGSEGV.

Reviewed-by: Taylor Simpson 
Signed-off-by: Richard Henderson 
---
 linux-user/hexagon/cpu_loop.c | 24 +---
 target/hexagon/cpu.c  | 23 ---
 2 files changed, 1 insertion(+), 46 deletions(-)

diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
index bee2a9e4ea..6b24cbaba9 100644
--- a/linux-user/hexagon/cpu_loop.c
+++ b/linux-user/hexagon/cpu_loop.c
@@ -28,8 +28,7 @@
 void cpu_loop(CPUHexagonState *env)
 {
 CPUState *cs = env_cpu(env);
-int trapnr, signum, sigcode;
-target_ulong sigaddr;
+int trapnr;
 target_ulong syscallnum;
 target_ulong ret;
 
@@ -39,10 +38,6 @@ void cpu_loop(CPUHexagonState *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-signum = 0;
-sigcode = 0;
-sigaddr = 0;
-
 switch (trapnr) {
 case EXCP_INTERRUPT:
 /* just indicate that signals should be handled asap */
@@ -65,12 +60,6 @@ void cpu_loop(CPUHexagonState *env)
 env->gpr[0] = ret;
 }
 break;
-case HEX_EXCP_FETCH_NO_UPAGE:
-case HEX_EXCP_PRIV_NO_UREAD:
-case HEX_EXCP_PRIV_NO_UWRITE:
-signum = TARGET_SIGSEGV;
-sigcode = TARGET_SEGV_MAPERR;
-break;
 case EXCP_ATOMIC:
 cpu_exec_step_atomic(cs);
 break;
@@ -79,17 +68,6 @@ void cpu_loop(CPUHexagonState *env)
  trapnr);
 exit(EXIT_FAILURE);
 }
-
-if (signum) {
-target_siginfo_t info = {
-.si_signo = signum,
-.si_errno = 0,
-.si_code = sigcode,
-._sifields._sigfault._addr = sigaddr
-};
-queue_signal(env, info.si_signo, QEMU_SI_KILL, );
-}
-
 process_pending_signals(env);
 }
 }
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 3338365c16..160a46a3d5 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -245,34 +245,11 @@ static void hexagon_cpu_init(Object *obj)
 qdev_property_add_static(DEVICE(obj), _lldb_stack_adjust_property);
 }
 
-static bool hexagon_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
-#ifdef CONFIG_USER_ONLY
-switch (access_type) {
-case MMU_INST_FETCH:
-cs->exception_index = HEX_EXCP_FETCH_NO_UPAGE;
-break;
-case MMU_DATA_LOAD:
-cs->exception_index = HEX_EXCP_PRIV_NO_UREAD;
-break;
-case MMU_DATA_STORE:
-cs->exception_index = HEX_EXCP_PRIV_NO_UWRITE;
-break;
-}
-cpu_loop_exit_restore(cs, retaddr);
-#else
-#error System mode not implemented for Hexagon
-#endif
-}
-
 #include "hw/core/tcg-cpu-ops.h"
 
 static const struct TCGCPUOps hexagon_tcg_ops = {
 .initialize = hexagon_translate_init,
 .synchronize_from_tb = hexagon_cpu_synchronize_from_tb,
-.tlb_fill = hexagon_tlb_fill,
 };
 
 static void hexagon_cpu_class_init(ObjectClass *c, void *data)
-- 
2.25.1




[PULL 43/60] linux-user: Add cpu_loop_exit_sigbus

2021-11-02 Thread Richard Henderson
This is a new interface to be provided by the os emulator for
raising SIGBUS on fault.  Use the new record_sigbus target hook.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/exec/exec-all.h | 14 ++
 linux-user/signal.c | 14 ++
 2 files changed, 28 insertions(+)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index f74578500c..6bb2a0f7ec 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -700,6 +700,20 @@ void QEMU_NORETURN cpu_loop_exit_sigsegv(CPUState *cpu, 
target_ulong addr,
  MMUAccessType access_type,
  bool maperr, uintptr_t ra);
 
+/**
+ * cpu_loop_exit_sigbus:
+ * @cpu: the cpu context
+ * @addr: the guest address of the alignment fault
+ * @access_type: access was read/write/execute
+ * @ra: host pc for unwinding
+ *
+ * Use the TCGCPUOps hook to record cpu state, do guest operating system
+ * specific things to raise SIGBUS, and jump to the main cpu loop.
+ */
+void QEMU_NORETURN cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
+MMUAccessType access_type,
+uintptr_t ra);
+
 #else
 static inline void mmap_lock(void) {}
 static inline void mmap_unlock(void) {}
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 9d60abc038..df2c8678d0 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -706,6 +706,20 @@ void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong 
addr,
 cpu_loop_exit_restore(cpu, ra);
 }
 
+void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
+  MMUAccessType access_type, uintptr_t ra)
+{
+const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
+
+if (tcg_ops->record_sigbus) {
+tcg_ops->record_sigbus(cpu, addr, access_type, ra);
+}
+
+force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, addr);
+cpu->exception_index = EXCP_INTERRUPT;
+cpu_loop_exit_restore(cpu, ra);
+}
+
 /* abort execution with signal */
 static void QEMU_NORETURN dump_core_and_abort(int target_sig)
 {
-- 
2.25.1




[PULL 18/60] linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER

2021-11-02 Thread Richard Henderson
Now that all of the linux-user hosts have been converted
to host-signal.h, drop the compatibility code.

Reviewed by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/exec/exec-all.h | 12 
 linux-user/signal.c | 14 --
 2 files changed, 26 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 5f94d799aa..5dd663c153 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -685,18 +685,6 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool 
is_write);
 bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
  uintptr_t host_pc, abi_ptr guest_addr);
 
-/**
- * cpu_signal_handler
- * @signum: host signal number
- * @pinfo: host siginfo_t
- * @puc: host ucontext_t
- *
- * To be called from the SIGBUS and SIGSEGV signal handler to inform the
- * virtual cpu of exceptions.  Returns true if the signal was handled by
- * the virtual CPU.
- */
-int cpu_signal_handler(int signum, void *pinfo, void *puc);
-
 #else
 static inline void mmap_lock(void) {}
 static inline void mmap_unlock(void) {}
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 6900acb122..b816678ba5 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -780,17 +780,6 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
 ucontext_t *uc = puc;
 struct emulated_sigtable *k;
 int guest_sig;
-
-#ifdef HOST_SIGNAL_PLACEHOLDER
-/* the CPU emulator uses some host signals to detect exceptions,
-   we forward to it some signals */
-if ((host_sig == SIGSEGV || host_sig == SIGBUS)
-&& info->si_code > 0) {
-if (cpu_signal_handler(host_sig, info, puc)) {
-return;
-}
-}
-#else
 uintptr_t pc = 0;
 bool sync_sig = false;
 
@@ -850,7 +839,6 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
 
 sync_sig = true;
 }
-#endif
 
 /* get target signal number */
 guest_sig = host_to_target_signal(host_sig);
@@ -865,7 +853,6 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
 k->pending = guest_sig;
 ts->signal_pending = 1;
 
-#ifndef HOST_SIGNAL_PLACEHOLDER
 /*
  * For synchronous signals, unwind the cpu state to the faulting
  * insn and then exit back to the main loop so that the signal
@@ -875,7 +862,6 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
 cpu->exception_index = EXCP_INTERRUPT;
 cpu_loop_exit_restore(cpu, pc);
 }
-#endif
 
 rewind_if_in_safe_syscall(puc);
 
-- 
2.25.1




[PULL 33/60] target/openrisc: Make openrisc_cpu_tlb_fill sysemu only

2021-11-02 Thread Richard Henderson
The fallback code in cpu_loop_exit_sigsegv is sufficient for
openrisc linux-user.

This makes all of the code in mmu.c sysemu only, so remove
the ifdefs and move the file to openrisc_softmmu_ss.
Remove the code from cpu_loop that handled EXCP_DPF.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/openrisc/cpu.h  | 7 ---
 linux-user/openrisc/cpu_loop.c | 8 
 target/openrisc/cpu.c  | 2 +-
 target/openrisc/mmu.c  | 9 -
 target/openrisc/meson.build| 2 +-
 5 files changed, 6 insertions(+), 22 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 187a4a114e..ee069b080c 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -317,14 +317,15 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, 
vaddr addr);
 int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void openrisc_translate_init(void);
-bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr);
 int print_insn_or1k(bfd_vma addr, disassemble_info *info);
 
 #define cpu_list cpu_openrisc_list
 
 #ifndef CONFIG_USER_ONLY
+bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
+
 extern const VMStateDescription vmstate_openrisc_cpu;
 
 void openrisc_cpu_do_interrupt(CPUState *cpu);
diff --git a/linux-user/openrisc/cpu_loop.c b/linux-user/openrisc/cpu_loop.c
index 10b7147f68..3cfdbbf037 100644
--- a/linux-user/openrisc/cpu_loop.c
+++ b/linux-user/openrisc/cpu_loop.c
@@ -54,14 +54,6 @@ void cpu_loop(CPUOpenRISCState *env)
 cpu_set_gpr(env, 11, ret);
 }
 break;
-case EXCP_DPF:
-case EXCP_IPF:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->pc;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
 case EXCP_ALIGN:
 info.si_signo = TARGET_SIGBUS;
 info.si_errno = 0;
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 27cb04152f..dfbafc5236 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -186,9 +186,9 @@ static const struct SysemuCPUOps openrisc_sysemu_ops = {
 
 static const struct TCGCPUOps openrisc_tcg_ops = {
 .initialize = openrisc_translate_init,
-.tlb_fill = openrisc_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = openrisc_cpu_tlb_fill,
 .cpu_exec_interrupt = openrisc_cpu_exec_interrupt,
 .do_interrupt = openrisc_cpu_do_interrupt,
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index 94df8c7bef..e561ef245b 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -23,11 +23,8 @@
 #include "exec/exec-all.h"
 #include "exec/gdbstub.h"
 #include "qemu/host-utils.h"
-#ifndef CONFIG_USER_ONLY
 #include "hw/loader.h"
-#endif
 
-#ifndef CONFIG_USER_ONLY
 static inline void get_phys_nommu(hwaddr *phys_addr, int *prot,
   target_ulong address)
 {
@@ -94,7 +91,6 @@ static int get_phys_mmu(OpenRISCCPU *cpu, hwaddr *phys_addr, 
int *prot,
 return need & PAGE_EXEC ? EXCP_ITLBMISS : EXCP_DTLBMISS;
 }
 }
-#endif
 
 static void raise_mmu_exception(OpenRISCCPU *cpu, target_ulong address,
 int exception)
@@ -112,8 +108,6 @@ bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr addr, int 
size,
 {
 OpenRISCCPU *cpu = OPENRISC_CPU(cs);
 int excp = EXCP_DPF;
-
-#ifndef CONFIG_USER_ONLY
 int prot;
 hwaddr phys_addr;
 
@@ -138,13 +132,11 @@ bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr addr, int 
size,
 if (probe) {
 return false;
 }
-#endif
 
 raise_mmu_exception(cpu, addr, excp);
 cpu_loop_exit_restore(cs, retaddr);
 }
 
-#ifndef CONFIG_USER_ONLY
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
 OpenRISCCPU *cpu = OPENRISC_CPU(cs);
@@ -177,4 +169,3 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 return phys_addr;
 }
 }
-#endif
diff --git a/target/openrisc/meson.build b/target/openrisc/meson.build
index e445dec4a0..84322086ec 100644
--- a/target/openrisc/meson.build
+++ b/target/openrisc/meson.build
@@ -10,7 +10,6 @@ openrisc_ss.add(files(
   'fpu_helper.c',
   'gdbstub.c',
   'interrupt_helper.c',
-  'mmu.c',
   'sys_helper.c',
   'translate.c',
 ))
@@ -19,6 +18,7 @@ openrisc_softmmu_ss = ss.source_set()
 openrisc_softmmu_ss.add(files(
   'interrupt.c',
   'machine.c',
+  'mmu.c',
 ))
 
 target_arch += {'openrisc': openrisc_ss}
-- 
2.25.1




[PULL 29/60] target/microblaze: Make mb_cpu_tlb_fill sysemu only

2021-11-02 Thread Richard Henderson
The fallback code in cpu_loop_exit_sigsegv is sufficient
for microblaze linux-user.

Remove the code from cpu_loop that handled the unnamed 0xaa exception.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Edgar E. Iglesias 
Signed-off-by: Richard Henderson 
---
 target/microblaze/cpu.h  |  8 
 linux-user/microblaze/cpu_loop.c | 10 --
 target/microblaze/cpu.c  |  2 +-
 target/microblaze/helper.c   | 13 +
 4 files changed, 6 insertions(+), 27 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index b7a848bbae..e9cd0b88de 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -394,10 +394,6 @@ void mb_tcg_init(void);
 #define MMU_USER_IDX2
 /* See NB_MMU_MODES further up the file.  */
 
-bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
-
 typedef CPUMBState CPUArchState;
 typedef MicroBlazeCPU ArchCPU;
 
@@ -415,6 +411,10 @@ static inline void cpu_get_tb_cpu_state(CPUMBState *env, 
target_ulong *pc,
 }
 
 #if !defined(CONFIG_USER_ONLY)
+bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
+
 void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
unsigned size, MMUAccessType access_type,
int mmu_idx, MemTxAttrs attrs,
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index 5eb93f..a94467dd2d 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -37,16 +37,6 @@ void cpu_loop(CPUMBState *env)
 process_queued_cpu_work(cs);
 
 switch (trapnr) {
-case 0xaa:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = 0;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-}
-break;
 case EXCP_INTERRUPT:
   /* just indicate that signals should be handled asap */
   break;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 15db277925..b9c888b87e 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -365,9 +365,9 @@ static const struct SysemuCPUOps mb_sysemu_ops = {
 static const struct TCGCPUOps mb_tcg_ops = {
 .initialize = mb_tcg_init,
 .synchronize_from_tb = mb_cpu_synchronize_from_tb,
-.tlb_fill = mb_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = mb_cpu_tlb_fill,
 .cpu_exec_interrupt = mb_cpu_exec_interrupt,
 .do_interrupt = mb_cpu_do_interrupt,
 .do_transaction_failed = mb_cpu_transaction_failed,
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index dd2aecd1d5..a607fe68e5 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -24,18 +24,7 @@
 #include "qemu/host-utils.h"
 #include "exec/log.h"
 
-#if defined(CONFIG_USER_ONLY)
-
-bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
-cs->exception_index = 0xaa;
-cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else /* !CONFIG_USER_ONLY */
-
+#ifndef CONFIG_USER_ONLY
 static bool mb_cpu_access_is_secure(MicroBlazeCPU *cpu,
 MMUAccessType access_type)
 {
-- 
2.25.1




[PULL 28/60] target/m68k: Make m68k_cpu_tlb_fill sysemu only

2021-11-02 Thread Richard Henderson
The fallback code in cpu_loop_exit_sigsegv is sufficient
for m68k linux-user.

Remove the code from cpu_loop that handled EXCP_ACCESS.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/m68k/cpu_loop.c | 10 --
 target/m68k/cpu.c  |  2 +-
 target/m68k/helper.c   |  6 +-
 3 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c
index ebf32be78f..790bd558c3 100644
--- a/linux-user/m68k/cpu_loop.c
+++ b/linux-user/m68k/cpu_loop.c
@@ -90,16 +90,6 @@ void cpu_loop(CPUM68KState *env)
 case EXCP_INTERRUPT:
 /* just indicate that signals should be handled asap */
 break;
-case EXCP_ACCESS:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->mmu.ar;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-}
-break;
 case EXCP_DEBUG:
 info.si_signo = TARGET_SIGTRAP;
 info.si_errno = 0;
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 66d22d1189..c7aeb7da9c 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -515,9 +515,9 @@ static const struct SysemuCPUOps m68k_sysemu_ops = {
 
 static const struct TCGCPUOps m68k_tcg_ops = {
 .initialize = m68k_tcg_init,
-.tlb_fill = m68k_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = m68k_cpu_tlb_fill,
 .cpu_exec_interrupt = m68k_cpu_exec_interrupt,
 .do_interrupt = m68k_cpu_do_interrupt,
 .do_transaction_failed = m68k_cpu_transaction_failed,
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 137a3e1a3d..5728e48585 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -978,16 +978,12 @@ void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t 
vector)
 }
 }
 
-#endif
-
 bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType qemu_access_type, int mmu_idx,
bool probe, uintptr_t retaddr)
 {
 M68kCPU *cpu = M68K_CPU(cs);
 CPUM68KState *env = >env;
-
-#ifndef CONFIG_USER_ONLY
 hwaddr physical;
 int prot;
 int access_type;
@@ -1051,12 +1047,12 @@ bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 if (!(access_type & ACCESS_STORE)) {
 env->mmu.ssw |= M68K_RW_040;
 }
-#endif
 
 cs->exception_index = EXCP_ACCESS;
 env->mmu.ar = address;
 cpu_loop_exit_restore(cs, retaddr);
 }
+#endif /* !CONFIG_USER_ONLY */
 
 uint32_t HELPER(bitrev)(uint32_t x)
 {
-- 
2.25.1




[PULL 16/60] target/arm: Fixup comment re handle_cpu_signal

2021-11-02 Thread Richard Henderson
The named function no longer exists.
Refer to host_signal_handler instead.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/arm/sve_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index dab5f1d1cd..07be55b7e1 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -6118,7 +6118,7 @@ DO_LDN_2(4, dd, MO_64)
  * linux-user/ in its get_user/put_user macros.
  *
  * TODO: Construct some helpers, written in assembly, that interact with
- * handle_cpu_signal to produce memory ops which can properly report errors
+ * host_signal_handler to produce memory ops which can properly report errors
  * without racing.
  */
 
-- 
2.25.1




[PULL 20/60] linux-user: Add cpu_loop_exit_sigsegv

2021-11-02 Thread Richard Henderson
This is a new interface to be provided by the os emulator for
raising SIGSEGV on fault.  Use the new record_sigsegv target hook.

Reviewed by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/exec/exec-all.h | 15 +++
 accel/tcg/user-exec.c   | 33 ++---
 linux-user/signal.c | 30 ++
 3 files changed, 55 insertions(+), 23 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 5dd663c153..f74578500c 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -685,6 +685,21 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool 
is_write);
 bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
  uintptr_t host_pc, abi_ptr guest_addr);
 
+/**
+ * cpu_loop_exit_sigsegv:
+ * @cpu: the cpu context
+ * @addr: the guest address of the fault
+ * @access_type: access was read/write/execute
+ * @maperr: true for invalid page, false for permission fault
+ * @ra: host pc for unwinding
+ *
+ * Use the TCGCPUOps hook to record cpu state, do guest operating system
+ * specific things to raise SIGSEGV, and jump to the main cpu loop.
+ */
+void QEMU_NORETURN cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
+ MMUAccessType access_type,
+ bool maperr, uintptr_t ra);
+
 #else
 static inline void mmap_lock(void) {}
 static inline void mmap_unlock(void) {}
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index a0cba61e83..c4f69908e9 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -141,35 +141,38 @@ static int probe_access_internal(CPUArchState *env, 
target_ulong addr,
  int fault_size, MMUAccessType access_type,
  bool nonfault, uintptr_t ra)
 {
-int flags;
+int acc_flag;
+bool maperr;
 
 switch (access_type) {
 case MMU_DATA_STORE:
-flags = PAGE_WRITE;
+acc_flag = PAGE_WRITE_ORG;
 break;
 case MMU_DATA_LOAD:
-flags = PAGE_READ;
+acc_flag = PAGE_READ;
 break;
 case MMU_INST_FETCH:
-flags = PAGE_EXEC;
+acc_flag = PAGE_EXEC;
 break;
 default:
 g_assert_not_reached();
 }
 
-if (!guest_addr_valid_untagged(addr) ||
-page_check_range(addr, 1, flags) < 0) {
-if (nonfault) {
-return TLB_INVALID_MASK;
-} else {
-CPUState *cpu = env_cpu(env);
-CPUClass *cc = CPU_GET_CLASS(cpu);
-cc->tcg_ops->tlb_fill(cpu, addr, fault_size, access_type,
-  MMU_USER_IDX, false, ra);
-g_assert_not_reached();
+if (guest_addr_valid_untagged(addr)) {
+int page_flags = page_get_flags(addr);
+if (page_flags & acc_flag) {
+return 0; /* success */
 }
+maperr = !(page_flags & PAGE_VALID);
+} else {
+maperr = true;
 }
-return 0;
+
+if (nonfault) {
+return TLB_INVALID_MASK;
+}
+
+cpu_loop_exit_sigsegv(env_cpu(env), addr, access_type, maperr, ra);
 }
 
 int probe_access_flags(CPUArchState *env, target_ulong addr,
diff --git a/linux-user/signal.c b/linux-user/signal.c
index b816678ba5..135983747d 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -688,9 +688,27 @@ void force_sigsegv(int oldsig)
 }
 force_sig(TARGET_SIGSEGV);
 }
-
 #endif
 
+void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
+   MMUAccessType access_type, bool maperr, uintptr_t 
ra)
+{
+const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
+
+if (tcg_ops->record_sigsegv) {
+tcg_ops->record_sigsegv(cpu, addr, access_type, maperr, ra);
+} else if (tcg_ops->tlb_fill) {
+tcg_ops->tlb_fill(cpu, addr, 0, access_type, MMU_USER_IDX, false, ra);
+g_assert_not_reached();
+}
+
+force_sig_fault(TARGET_SIGSEGV,
+maperr ? TARGET_SEGV_MAPERR : TARGET_SEGV_ACCERR,
+addr);
+cpu->exception_index = EXCP_INTERRUPT;
+cpu_loop_exit_restore(cpu, ra);
+}
+
 /* abort execution with signal */
 static void QEMU_NORETURN dump_core_and_abort(int target_sig)
 {
@@ -806,7 +824,7 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
 access_type = adjust_signal_pc(, is_write);
 
 if (host_sig == SIGSEGV) {
-const struct TCGCPUOps *tcg_ops;
+bool maperr = true;
 
 if (info->si_code == SEGV_ACCERR && h2g_valid(host_addr)) {
 /* If this was a write to a TB protected page, restart. */
@@ -821,18 +839,14 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
  * which means that we may get ACCERR when we want MAPERR.
  */
 if 

[PULL 23/60] target/arm: Implement arm_cpu_record_sigsegv

2021-11-02 Thread Richard Henderson
Because of the complexity of setting ESR, continue to use
arm_deliver_fault.  This means we cannot remove the code
within cpu_loop that decodes EXCP_DATA_ABORT and
EXCP_PREFETCH_ABORT.

But using the new hook means that we don't have to do the
page_get_flags check manually, and we'll be able to restrict
the tlb_fill hook to sysemu later.

Reviewed-by: Warner Losh 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/internals.h  |  6 ++
 target/arm/cpu.c|  6 --
 target/arm/cpu_tcg.c|  6 --
 target/arm/tlb_helper.c | 36 +++-
 4 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 3612107ab2..5a7aaf0f51 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -544,9 +544,15 @@ static inline bool arm_extabort_type(MemTxResult result)
 return result != MEMTX_DECODE_ERROR;
 }
 
+#ifdef CONFIG_USER_ONLY
+void arm_cpu_record_sigsegv(CPUState *cpu, vaddr addr,
+MMUAccessType access_type,
+bool maperr, uintptr_t ra);
+#else
 bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
   MMUAccessType access_type, int mmu_idx,
   bool probe, uintptr_t retaddr);
+#endif
 
 static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx)
 {
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 641a8c2d3d..7a18a58ca0 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2031,10 +2031,12 @@ static const struct SysemuCPUOps arm_sysemu_ops = {
 static const struct TCGCPUOps arm_tcg_ops = {
 .initialize = arm_translate_init,
 .synchronize_from_tb = arm_cpu_synchronize_from_tb,
-.tlb_fill = arm_cpu_tlb_fill,
 .debug_excp_handler = arm_debug_excp_handler,
 
-#if !defined(CONFIG_USER_ONLY)
+#ifdef CONFIG_USER_ONLY
+.record_sigsegv = arm_cpu_record_sigsegv,
+#else
+.tlb_fill = arm_cpu_tlb_fill,
 .cpu_exec_interrupt = arm_cpu_exec_interrupt,
 .do_interrupt = arm_cpu_do_interrupt,
 .do_transaction_failed = arm_cpu_do_transaction_failed,
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 0d5adccf1a..7b3bea2fbb 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -898,10 +898,12 @@ static void pxa270c5_initfn(Object *obj)
 static const struct TCGCPUOps arm_v7m_tcg_ops = {
 .initialize = arm_translate_init,
 .synchronize_from_tb = arm_cpu_synchronize_from_tb,
-.tlb_fill = arm_cpu_tlb_fill,
 .debug_excp_handler = arm_debug_excp_handler,
 
-#if !defined(CONFIG_USER_ONLY)
+#ifdef CONFIG_USER_ONLY
+.record_sigsegv = arm_cpu_record_sigsegv,
+#else
+.tlb_fill = arm_cpu_tlb_fill,
 .cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
 .do_interrupt = arm_v7m_cpu_do_interrupt,
 .do_transaction_failed = arm_cpu_do_transaction_failed,
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
index 3107f9823e..dc5860180f 100644
--- a/target/arm/tlb_helper.c
+++ b/target/arm/tlb_helper.c
@@ -147,28 +147,12 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr 
physaddr,
 arm_deliver_fault(cpu, addr, access_type, mmu_idx, );
 }
 
-#endif /* !defined(CONFIG_USER_ONLY) */
-
 bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
   MMUAccessType access_type, int mmu_idx,
   bool probe, uintptr_t retaddr)
 {
 ARMCPU *cpu = ARM_CPU(cs);
 ARMMMUFaultInfo fi = {};
-
-#ifdef CONFIG_USER_ONLY
-int flags = page_get_flags(useronly_clean_ptr(address));
-if (flags & PAGE_VALID) {
-fi.type = ARMFault_Permission;
-} else {
-fi.type = ARMFault_Translation;
-}
-fi.level = 3;
-
-/* now we have a real cpu fault */
-cpu_restore_state(cs, retaddr, true);
-arm_deliver_fault(cpu, address, access_type, mmu_idx, );
-#else
 hwaddr phys_addr;
 target_ulong page_size;
 int prot, ret;
@@ -210,5 +194,23 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 cpu_restore_state(cs, retaddr, true);
 arm_deliver_fault(cpu, address, access_type, mmu_idx, );
 }
-#endif
 }
+#else
+void arm_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+MMUAccessType access_type,
+bool maperr, uintptr_t ra)
+{
+ARMMMUFaultInfo fi = {
+.type = maperr ? ARMFault_Translation : ARMFault_Permission,
+.level = 3,
+};
+ARMCPU *cpu = ARM_CPU(cs);
+
+/*
+ * We report both ESR and FAR to signal handlers.
+ * For now, it's easiest to deliver the fault normally.
+ */
+cpu_restore_state(cs, ra, true);
+arm_deliver_fault(cpu, addr, access_type, MMU_USER_IDX, );
+}
+#endif /* !defined(CONFIG_USER_ONLY) */
-- 
2.25.1




[PULL 34/60] target/ppc: Implement ppc_cpu_record_sigsegv

2021-11-02 Thread Richard Henderson
Record DAR, DSISR, and exception_index.  That last means
that we must exit to cpu_loop ourselves, instead of letting
exception_index being overwritten.

This is exactly what the user-mode ppc_cpu_tlb_fill does,
so simply rename it as ppc_cpu_record_sigsegv.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/ppc/cpu.h  |  3 ---
 target/ppc/internal.h |  9 +
 target/ppc/cpu_init.c |  6 --
 target/ppc/user_only_helper.c | 15 +++
 4 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 0472ec9154..e946da5f3a 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1302,9 +1302,6 @@ extern const VMStateDescription vmstate_ppc_cpu;
 
 /*/
 void ppc_translate_init(void);
-bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-  MMUAccessType access_type, int mmu_idx,
-  bool probe, uintptr_t retaddr);
 
 #if !defined(CONFIG_USER_ONLY)
 void ppc_store_sdr1(CPUPPCState *env, target_ulong value);
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index 55284369f5..339974b7d8 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -283,5 +283,14 @@ static inline void pte_invalidate(target_ulong *pte0)
 #define PTE_PTEM_MASK 0x7FBF
 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
 
+#ifdef CONFIG_USER_ONLY
+void ppc_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+MMUAccessType access_type,
+bool maperr, uintptr_t ra);
+#else
+bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+  MMUAccessType access_type, int mmu_idx,
+  bool probe, uintptr_t retaddr);
+#endif
 
 #endif /* PPC_INTERNAL_H */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 65545ba9ca..1c7a7b4b38 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -9014,9 +9014,11 @@ static const struct SysemuCPUOps ppc_sysemu_ops = {
 
 static const struct TCGCPUOps ppc_tcg_ops = {
   .initialize = ppc_translate_init,
-  .tlb_fill = ppc_cpu_tlb_fill,
 
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+  .record_sigsegv = ppc_cpu_record_sigsegv,
+#else
+  .tlb_fill = ppc_cpu_tlb_fill,
   .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
   .do_interrupt = ppc_cpu_do_interrupt,
   .cpu_exec_enter = ppc_cpu_exec_enter,
diff --git a/target/ppc/user_only_helper.c b/target/ppc/user_only_helper.c
index aa3f867596..7ff76f7a06 100644
--- a/target/ppc/user_only_helper.c
+++ b/target/ppc/user_only_helper.c
@@ -21,16 +21,23 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/exec-all.h"
+#include "internal.h"
 
-
-bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-  MMUAccessType access_type, int mmu_idx,
-  bool probe, uintptr_t retaddr)
+void ppc_cpu_record_sigsegv(CPUState *cs, vaddr address,
+MMUAccessType access_type,
+bool maperr, uintptr_t retaddr)
 {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
 CPUPPCState *env = >env;
 int exception, error_code;
 
+/*
+ * Both DSISR and the "trap number" (exception vector offset,
+ * looked up from exception_index) are present in the linux-user
+ * signal frame.
+ * FIXME: we don't actually populate the trap number properly.
+ * It would be easiest to fill in an env->trap value now.
+ */
 if (access_type == MMU_INST_FETCH) {
 exception = POWERPC_EXCP_ISI;
 error_code = 0x4000;
-- 
2.25.1




[PULL 21/60] target/alpha: Implement alpha_cpu_record_sigsegv

2021-11-02 Thread Richard Henderson
Record trap_arg{0,1,2} for the linux-user signal frame.

Fill in the stores to trap_arg{1,2} that were missing
from the previous user-only alpha_cpu_tlb_fill function.
Use maperr to simplify computation of trap_arg1.

Remove the code for EXCP_MMFAULT from cpu_loop, as
that part is now handled by cpu_loop_exit_sigsegv.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/alpha/cpu.h  | 13 +
 linux-user/alpha/cpu_loop.c |  8 
 target/alpha/cpu.c  |  6 --
 target/alpha/helper.c   | 39 -
 4 files changed, 47 insertions(+), 19 deletions(-)

diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index 772828cc26..d49cc36d07 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -439,9 +439,6 @@ void alpha_translate_init(void);
 #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU
 
 void alpha_cpu_list(void);
-bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-MMUAccessType access_type, int mmu_idx,
-bool probe, uintptr_t retaddr);
 void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
 void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
 
@@ -449,7 +446,15 @@ uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env);
 void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val);
 uint64_t cpu_alpha_load_gr(CPUAlphaState *env, unsigned reg);
 void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val);
-#ifndef CONFIG_USER_ONLY
+
+#ifdef CONFIG_USER_ONLY
+void alpha_cpu_record_sigsegv(CPUState *cs, vaddr address,
+  MMUAccessType access_type,
+  bool maperr, uintptr_t retaddr);
+#else
+bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr);
 void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
  vaddr addr, unsigned size,
  MMUAccessType access_type,
diff --git a/linux-user/alpha/cpu_loop.c b/linux-user/alpha/cpu_loop.c
index 1b00a81385..4cc8e0a55c 100644
--- a/linux-user/alpha/cpu_loop.c
+++ b/linux-user/alpha/cpu_loop.c
@@ -54,14 +54,6 @@ void cpu_loop(CPUAlphaState *env)
 fprintf(stderr, "External interrupt. Exit\n");
 exit(EXIT_FAILURE);
 break;
-case EXCP_MMFAULT:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
-? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
-info._sifields._sigfault._addr = env->trap_arg0;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
 case EXCP_UNALIGN:
 info.si_signo = TARGET_SIGBUS;
 info.si_errno = 0;
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 93e16a2ffb..69f32c3078 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -218,9 +218,11 @@ static const struct SysemuCPUOps alpha_sysemu_ops = {
 
 static const struct TCGCPUOps alpha_tcg_ops = {
 .initialize = alpha_translate_init,
-.tlb_fill = alpha_cpu_tlb_fill,
 
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+.record_sigsegv = alpha_cpu_record_sigsegv,
+#else
+.tlb_fill = alpha_cpu_tlb_fill,
 .cpu_exec_interrupt = alpha_cpu_exec_interrupt,
 .do_interrupt = alpha_cpu_do_interrupt,
 .do_transaction_failed = alpha_cpu_do_transaction_failed,
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index 81550d9e2f..b7e7f73b15 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -120,15 +120,44 @@ void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, 
uint64_t val)
 }
 
 #if defined(CONFIG_USER_ONLY)
-bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-MMUAccessType access_type, int mmu_idx,
-bool probe, uintptr_t retaddr)
+void alpha_cpu_record_sigsegv(CPUState *cs, vaddr address,
+  MMUAccessType access_type,
+  bool maperr, uintptr_t retaddr)
 {
 AlphaCPU *cpu = ALPHA_CPU(cs);
+target_ulong mmcsr, cause;
 
-cs->exception_index = EXCP_MMFAULT;
+/* Assuming !maperr, infer the missing protection. */
+switch (access_type) {
+case MMU_DATA_LOAD:
+mmcsr = MM_K_FOR;
+cause = 0;
+break;
+case MMU_DATA_STORE:
+mmcsr = MM_K_FOW;
+cause = 1;
+break;
+case MMU_INST_FETCH:
+mmcsr = MM_K_FOE;
+cause = -1;
+break;
+default:
+g_assert_not_reached();
+}
+if (maperr) {
+if (address < BIT_ULL(TARGET_VIRT_ADDR_SPACE_BITS - 1)) {
+/* Userspace address, therefore page not mapped. */
+mmcsr = MM_K_TNV;
+  

[PULL 17/60] linux-user/host/riscv: Improve host_signal_write

2021-11-02 Thread Richard Henderson
Do not read 4 bytes before we determine the size of the insn.
Simplify triple switches in favor of checking major opcodes.
Include the missing cases of compact fsd and fsdsp.

Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 linux-user/host/riscv/host-signal.h | 83 ++---
 1 file changed, 28 insertions(+), 55 deletions(-)

diff --git a/linux-user/host/riscv/host-signal.h 
b/linux-user/host/riscv/host-signal.h
index df145b1527..3b168cb58b 100644
--- a/linux-user/host/riscv/host-signal.h
+++ b/linux-user/host/riscv/host-signal.h
@@ -18,65 +18,38 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
 
 static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
 {
-uint32_t insn = *(uint32_t *)host_signal_pc(uc);
-
 /*
- * Detect store by reading the instruction at the program
- * counter. Note: we currently only generate 32-bit
- * instructions so we thus only detect 32-bit stores
+ * Detect store by reading the instruction at the program counter.
+ * Do not read more than 16 bits, because we have not yet determined
+ * the size of the instruction.
  */
-switch (((insn >> 0) & 0b11)) {
-case 3:
-switch (((insn >> 2) & 0b1)) {
-case 8:
-switch (((insn >> 12) & 0b111)) {
-case 0: /* sb */
-case 1: /* sh */
-case 2: /* sw */
-case 3: /* sd */
-case 4: /* sq */
-return true;
-default:
-break;
-}
-break;
-case 9:
-switch (((insn >> 12) & 0b111)) {
-case 2: /* fsw */
-case 3: /* fsd */
-case 4: /* fsq */
-return true;
-default:
-break;
-}
-break;
-default:
-break;
-}
+const uint16_t *pinsn = (const uint16_t *)host_signal_pc(uc);
+uint16_t insn = pinsn[0];
+
+/* 16-bit instructions */
+switch (insn & 0xe003) {
+case 0xa000: /* c.fsd */
+case 0xc000: /* c.sw */
+case 0xe000: /* c.sd (rv64) / c.fsw (rv32) */
+case 0xa002: /* c.fsdsp */
+case 0xc002: /* c.swsp */
+case 0xe002: /* c.sdsp (rv64) / c.fswsp (rv32) */
+return true;
 }
 
-/* Check for compressed instructions */
-switch (((insn >> 13) & 0b111)) {
-case 7:
-switch (insn & 0b11) {
-case 0: /*c.sd */
-case 2: /* c.sdsp */
-return true;
-default:
-break;
-}
-break;
-case 6:
-switch (insn & 0b11) {
-case 0: /* c.sw */
-case 3: /* c.swsp */
-return true;
-default:
-break;
-}
-break;
-default:
-break;
+/* 32-bit instructions, major opcodes */
+switch (insn & 0x7f) {
+case 0x23: /* store */
+case 0x27: /* store-fp */
+return true;
+case 0x2f: /* amo */
+/*
+ * The AMO function code is in bits 25-31, unread as yet.
+ * The AMO functions are LR (read), SC (write), and the
+ * rest are all read-modify-write.
+ */
+insn = pinsn[1];
+return (insn >> 11) != 2; /* LR */
 }
 
 return false;
-- 
2.25.1




[PULL 09/60] linux-user/host/alpha: Populate host_signal.h

2021-11-02 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/host/alpha/host-signal.h | 42 +
 accel/tcg/user-exec.c   | 31 +
 2 files changed, 43 insertions(+), 30 deletions(-)
 create mode 100644 linux-user/host/alpha/host-signal.h

diff --git a/linux-user/host/alpha/host-signal.h 
b/linux-user/host/alpha/host-signal.h
new file mode 100644
index 00..e080be412f
--- /dev/null
+++ b/linux-user/host/alpha/host-signal.h
@@ -0,0 +1,42 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef ALPHA_HOST_SIGNAL_H
+#define ALPHA_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.sc_pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+uint32_t *pc = (uint32_t *)host_signal_pc(uc);
+uint32_t insn = *pc;
+
+/* XXX: need kernel patch to get write flag faster */
+switch (insn >> 26) {
+case 0x0d: /* stw */
+case 0x0e: /* stb */
+case 0x0f: /* stq_u */
+case 0x24: /* stf */
+case 0x25: /* stg */
+case 0x26: /* sts */
+case 0x27: /* stt */
+case 0x2c: /* stl */
+case 0x2d: /* stq */
+case 0x2e: /* stl_c */
+case 0x2f: /* stq_c */
+return true;
+}
+return false;
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 5a0a65fa46..e9b6eb696f 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -253,36 +253,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__alpha__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-ucontext_t *uc = puc;
-uint32_t *pc = uc->uc_mcontext.sc_pc;
-uint32_t insn = *pc;
-int is_write = 0;
-
-/* XXX: need kernel patch to get write flag faster */
-switch (insn >> 26) {
-case 0x0d: /* stw */
-case 0x0e: /* stb */
-case 0x0f: /* stq_u */
-case 0x24: /* stf */
-case 0x25: /* stg */
-case 0x26: /* sts */
-case 0x27: /* stt */
-case 0x2c: /* stl */
-case 0x2d: /* stq */
-case 0x2e: /* stl_c */
-case 0x2f: /* stq_c */
-is_write = 1;
-}
-
-return handle_cpu_signal(pc, info, is_write, >uc_sigmask);
-}
-#elif defined(__sparc__)
+#if defined(__sparc__)
 
 int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
-- 
2.25.1




[PULL 38/60] target/sh4: Make sh4_cpu_tlb_fill sysemu only

2021-11-02 Thread Richard Henderson
The fallback code in cpu_loop_exit_sigsegv is sufficient
for sh4 linux-user.

Remove the code from cpu_loop that raised SIGSEGV.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/sh4/cpu.h  | 6 +++---
 linux-user/sh4/cpu_loop.c | 8 
 target/sh4/cpu.c  | 2 +-
 target/sh4/helper.c   | 9 +
 4 files changed, 5 insertions(+), 20 deletions(-)

diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index dc81406646..4cfb109f56 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -213,12 +213,12 @@ void superh_cpu_do_unaligned_access(CPUState *cpu, vaddr 
addr,
 uintptr_t retaddr) QEMU_NORETURN;
 
 void sh4_translate_init(void);
+void sh4_cpu_list(void);
+
+#if !defined(CONFIG_USER_ONLY)
 bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
  MMUAccessType access_type, int mmu_idx,
  bool probe, uintptr_t retaddr);
-
-void sh4_cpu_list(void);
-#if !defined(CONFIG_USER_ONLY)
 void superh_cpu_do_interrupt(CPUState *cpu);
 bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void cpu_sh4_invalidate_tlb(CPUSH4State *s);
diff --git a/linux-user/sh4/cpu_loop.c b/linux-user/sh4/cpu_loop.c
index 65b8972e3c..ac9b01840c 100644
--- a/linux-user/sh4/cpu_loop.c
+++ b/linux-user/sh4/cpu_loop.c
@@ -65,14 +65,6 @@ void cpu_loop(CPUSH4State *env)
 info.si_code = TARGET_TRAP_BRKPT;
 queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
 break;
-case 0xa0:
-case 0xc0:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->tea;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
 case EXCP_ATOMIC:
 cpu_exec_step_atomic(cs);
 arch_interrupt = false;
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 2047742d03..06b2691dc4 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -236,9 +236,9 @@ static const struct SysemuCPUOps sh4_sysemu_ops = {
 static const struct TCGCPUOps superh_tcg_ops = {
 .initialize = sh4_translate_init,
 .synchronize_from_tb = superh_cpu_synchronize_from_tb,
-.tlb_fill = superh_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = superh_cpu_tlb_fill,
 .cpu_exec_interrupt = superh_cpu_exec_interrupt,
 .do_interrupt = superh_cpu_do_interrupt,
 .do_unaligned_access = superh_cpu_do_unaligned_access,
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 53cb9c3b63..6a620e36fc 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -796,8 +796,6 @@ bool superh_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 return false;
 }
 
-#endif /* !CONFIG_USER_ONLY */
-
 bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
  MMUAccessType access_type, int mmu_idx,
  bool probe, uintptr_t retaddr)
@@ -806,11 +804,6 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 CPUSH4State *env = >env;
 int ret;
 
-#ifdef CONFIG_USER_ONLY
-ret = (access_type == MMU_DATA_STORE ? MMU_DTLB_VIOLATION_WRITE :
-   access_type == MMU_INST_FETCH ? MMU_ITLB_VIOLATION :
-   MMU_DTLB_VIOLATION_READ);
-#else
 target_ulong physical;
 int prot;
 
@@ -829,7 +822,6 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 if (ret != MMU_DTLB_MULTIPLE && ret != MMU_ITLB_MULTIPLE) {
 env->pteh = (env->pteh & PTEH_ASID_MASK) | (address & PTEH_VPN_MASK);
 }
-#endif
 
 env->tea = address;
 switch (ret) {
@@ -868,3 +860,4 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 cpu_loop_exit_restore(cs, retaddr);
 }
+#endif /* !CONFIG_USER_ONLY */
-- 
2.25.1




[PULL 13/60] linux-user/host/s390: Populate host_signal.h

2021-11-02 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.

Reviewed-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/host/s390/host-signal.h  | 94 -
 linux-user/host/s390x/host-signal.h |  2 +-
 accel/tcg/user-exec.c   | 88 +--
 3 files changed, 95 insertions(+), 89 deletions(-)

diff --git a/linux-user/host/s390/host-signal.h 
b/linux-user/host/s390/host-signal.h
index f4b4d65031..26990e4893 100644
--- a/linux-user/host/s390/host-signal.h
+++ b/linux-user/host/s390/host-signal.h
@@ -1 +1,93 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef S390_HOST_SIGNAL_H
+#define S390_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.psw.addr;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+uint16_t *pinsn = (uint16_t *)host_signal_pc(uc);
+
+/*
+ * ??? On linux, the non-rt signal handler has 4 (!) arguments instead
+ * of the normal 2 arguments.  The 4th argument contains the "Translation-
+ * Exception Identification for DAT Exceptions" from the hardware (aka
+ * "int_parm_long"), which does in fact contain the is_write value.
+ * The rt signal handler, as far as I can tell, does not give this value
+ * at all.  Not that we could get to it from here even if it were.
+ * So fall back to parsing instructions.  Treat read-modify-write ones as
+ * writes, which is not fully correct, but for tracking self-modifying code
+ * this is better than treating them as reads.  Checking si_addr page flags
+ * might be a viable improvement, albeit a racy one.
+ */
+/* ??? This is not even close to complete.  */
+switch (pinsn[0] >> 8) {
+case 0x50: /* ST */
+case 0x42: /* STC */
+case 0x40: /* STH */
+case 0xba: /* CS */
+case 0xbb: /* CDS */
+return true;
+case 0xc4: /* RIL format insns */
+switch (pinsn[0] & 0xf) {
+case 0xf: /* STRL */
+case 0xb: /* STGRL */
+case 0x7: /* STHRL */
+return true;
+}
+break;
+case 0xc8: /* SSF format insns */
+switch (pinsn[0] & 0xf) {
+case 0x2: /* CSST */
+return true;
+}
+break;
+case 0xe3: /* RXY format insns */
+switch (pinsn[2] & 0xff) {
+case 0x50: /* STY */
+case 0x24: /* STG */
+case 0x72: /* STCY */
+case 0x70: /* STHY */
+case 0x8e: /* STPQ */
+case 0x3f: /* STRVH */
+case 0x3e: /* STRV */
+case 0x2f: /* STRVG */
+return true;
+}
+break;
+case 0xeb: /* RSY format insns */
+switch (pinsn[2] & 0xff) {
+case 0x14: /* CSY */
+case 0x30: /* CSG */
+case 0x31: /* CDSY */
+case 0x3e: /* CDSG */
+case 0xe4: /* LANG */
+case 0xe6: /* LAOG */
+case 0xe7: /* LAXG */
+case 0xe8: /* LAAG */
+case 0xea: /* LAALG */
+case 0xf4: /* LAN */
+case 0xf6: /* LAO */
+case 0xf7: /* LAX */
+case 0xfa: /* LAAL */
+case 0xf8: /* LAA */
+return true;
+}
+break;
+}
+return false;
+}
+
+#endif
diff --git a/linux-user/host/s390x/host-signal.h 
b/linux-user/host/s390x/host-signal.h
index f4b4d65031..0e83f9358d 100644
--- a/linux-user/host/s390x/host-signal.h
+++ b/linux-user/host/s390x/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../s390/host-signal.h"
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 5cdbfab35b..f18f3b2a5c 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -253,93 +253,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__s390__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-ucontext_t *uc = puc;
-unsigned long pc;
-uint16_t *pinsn;
-int is_write = 0;
-
-pc = uc->uc_mcontext.psw.addr;
-
-/*
- * ??? On linux, the non-rt signal handler has 4 (!) arguments instead
- * of the normal 2 arguments.  The 4th argument contains the "Translation-
- * Exception Identification for DAT Exceptions" from the hardware (aka
- * "int_parm_long"), which does in fact contain the is_write value.
- * The rt signal handler, as far as I can tell, does not give this value
- * at all.  Not that we could get to it from here even if it were.
- * So fall back to parsing instructions.  Treat read-modify-write 

[PULL 12/60] linux-user/host/aarch64: Populate host_signal.h

2021-11-02 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Reviewed-by: Warner Losh 
Signed-off-by: Richard Henderson 
---
 linux-user/host/aarch64/host-signal.h | 75 -
 accel/tcg/user-exec.c | 94 +--
 2 files changed, 75 insertions(+), 94 deletions(-)

diff --git a/linux-user/host/aarch64/host-signal.h 
b/linux-user/host/aarch64/host-signal.h
index f4b4d65031..0c0b08383a 100644
--- a/linux-user/host/aarch64/host-signal.h
+++ b/linux-user/host/aarch64/host-signal.h
@@ -1 +1,74 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef AARCH64_HOST_SIGNAL_H
+#define AARCH64_HOST_SIGNAL_H
+
+/* Pre-3.16 kernel headers don't have these, so provide fallback definitions */
+#ifndef ESR_MAGIC
+#define ESR_MAGIC 0x45535201
+struct esr_context {
+struct _aarch64_ctx head;
+uint64_t esr;
+};
+#endif
+
+static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)
+{
+return (struct _aarch64_ctx *)>uc_mcontext.__reserved;
+}
+
+static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)
+{
+return (struct _aarch64_ctx *)((char *)hdr + hdr->size);
+}
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+struct _aarch64_ctx *hdr;
+uint32_t insn;
+
+/* Find the esr_context, which has the WnR bit in it */
+for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {
+if (hdr->magic == ESR_MAGIC) {
+struct esr_context const *ec = (struct esr_context const *)hdr;
+uint64_t esr = ec->esr;
+
+/* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR bit */
+return extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
+}
+}
+
+/*
+ * Fall back to parsing instructions; will only be needed
+ * for really ancient (pre-3.16) kernels.
+ */
+insn = *(uint32_t *)host_signal_pc(uc);
+
+return (insn & 0xbfff) == 0x0c00   /* C3.3.1 */
+|| (insn & 0xbfe0) == 0x0c80   /* C3.3.2 */
+|| (insn & 0xbfdf) == 0x0d00   /* C3.3.3 */
+|| (insn & 0xbfc0) == 0x0d80   /* C3.3.4 */
+|| (insn & 0x3f40) == 0x0800   /* C3.3.6 */
+|| (insn & 0x3bc0) == 0x3900   /* C3.3.13 */
+|| (insn & 0x3fc0) == 0x3d80   /* ... 128bit */
+/* Ignore bits 10, 11 & 21, controlling indexing.  */
+|| (insn & 0x3bc0) == 0x3800   /* C3.3.8-12 */
+|| (insn & 0x3fe0) == 0x3c80   /* ... 128bit */
+/* Ignore bits 23 & 24, controlling indexing.  */
+|| (insn & 0x3a40) == 0x2800; /* C3.3.7,14-16 */
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index fabc8855a9..5cdbfab35b 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -253,99 +253,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__aarch64__)
-
-#if defined(__NetBSD__)
-
-#include 
-#include 
-
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
-{
-ucontext_t *uc = puc;
-siginfo_t *si = pinfo;
-unsigned long pc;
-int is_write;
-uint32_t esr;
-
-pc = uc->uc_mcontext.__gregs[_REG_PC];
-esr = si->si_trap;
-
-/*
- * siginfo_t::si_trap is the ESR value, for data aborts ESR.EC
- * is 0b10010x: then bit 6 is the WnR bit
- */
-is_write = extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
-return handle_cpu_signal(pc, si, is_write, >uc_sigmask);
-}
-
-#else
-
-#ifndef ESR_MAGIC
-/* Pre-3.16 kernel headers don't have these, so provide fallback definitions */
-#define ESR_MAGIC 0x45535201
-struct esr_context {
-struct _aarch64_ctx head;
-uint64_t esr;
-};
-#endif
-
-static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)
-{
-return (struct _aarch64_ctx *)>uc_mcontext.__reserved;
-}
-
-static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)
-{
-return (struct _aarch64_ctx *)((char *)hdr + hdr->size);
-}
-
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
-{
-siginfo_t *info = pinfo;
-ucontext_t *uc = puc;
-uintptr_t pc = uc->uc_mcontext.pc;
-bool is_write;
-struct _aarch64_ctx *hdr;
-struct esr_context const *esrctx = NULL;
-
-/* Find the esr_context, which has the WnR bit in it */
-for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {
-if (hdr->magic == ESR_MAGIC) {
-esrctx = (struct esr_context const 

[PULL 11/60] linux-user/host/arm: Populate host_signal.h

2021-11-02 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/host/arm/host-signal.h | 31 -
 accel/tcg/user-exec.c | 45 +--
 2 files changed, 31 insertions(+), 45 deletions(-)

diff --git a/linux-user/host/arm/host-signal.h 
b/linux-user/host/arm/host-signal.h
index f4b4d65031..efb165c0c5 100644
--- a/linux-user/host/arm/host-signal.h
+++ b/linux-user/host/arm/host-signal.h
@@ -1 +1,30 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef ARM_HOST_SIGNAL_H
+#define ARM_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.arm_pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+/*
+ * In the FSR, bit 11 is WnR, assuming a v6 or
+ * later processor.  On v5 we will always report
+ * this as a read, which will fail later.
+ */
+uint32_t fsr = uc->uc_mcontext.error_code;
+return extract32(fsr, 11, 1);
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 694eff7f04..fabc8855a9 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -253,50 +253,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__arm__)
-
-#if defined(__NetBSD__)
-#include 
-#include 
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-#if defined(__NetBSD__)
-ucontext_t *uc = puc;
-siginfo_t *si = pinfo;
-#else
-ucontext_t *uc = puc;
-#endif
-unsigned long pc;
-uint32_t fsr;
-int is_write;
-
-#if defined(__NetBSD__)
-pc = uc->uc_mcontext.__gregs[_REG_R15];
-#elif defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && 
__GLIBC_MINOR__ <= 3))
-pc = uc->uc_mcontext.gregs[R15];
-#else
-pc = uc->uc_mcontext.arm_pc;
-#endif
-
-#ifdef __NetBSD__
-fsr = si->si_trap;
-#else
-fsr = uc->uc_mcontext.error_code;
-#endif
-/*
- * In the FSR, bit 11 is WnR, assuming a v6 or
- * later processor.  On v5 we will always report
- * this as a read, which will fail later.
- */
-is_write = extract32(fsr, 11, 1);
-return handle_cpu_signal(pc, info, is_write, >uc_sigmask);
-}
-
-#elif defined(__aarch64__)
+#if defined(__aarch64__)
 
 #if defined(__NetBSD__)
 
-- 
2.25.1




[PULL 36/60] target/s390x: Use probe_access_flags in s390_probe_access

2021-11-02 Thread Richard Henderson
Not sure why the user-only code wasn't rewritten to use
probe_access_flags at the same time that the sysemu code
was converted.  For the purpose of user-only, this is an
exact replacement.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/s390x/tcg/mem_helper.c | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
index 17e3f83641..362a30d99e 100644
--- a/target/s390x/tcg/mem_helper.c
+++ b/target/s390x/tcg/mem_helper.c
@@ -141,20 +141,12 @@ static int s390_probe_access(CPUArchState *env, 
target_ulong addr, int size,
  MMUAccessType access_type, int mmu_idx,
  bool nonfault, void **phost, uintptr_t ra)
 {
+#if defined(CONFIG_USER_ONLY)
+return probe_access_flags(env, addr, access_type, mmu_idx,
+  nonfault, phost, ra);
+#else
 int flags;
 
-#if defined(CONFIG_USER_ONLY)
-flags = page_get_flags(addr);
-if (!(flags & (access_type == MMU_DATA_LOAD ?  PAGE_READ : 
PAGE_WRITE_ORG))) {
-env->__excp_addr = addr;
-flags = (flags & PAGE_VALID) ? PGM_PROTECTION : PGM_ADDRESSING;
-if (nonfault) {
-return flags;
-}
-tcg_s390_program_interrupt(env, flags, ra);
-}
-*phost = g2h(env_cpu(env), addr);
-#else
 /*
  * For !CONFIG_USER_ONLY, we cannot rely on TLB_INVALID_MASK or haddr==NULL
  * to detect if there was an exception during tlb_fill().
@@ -173,8 +165,8 @@ static int s390_probe_access(CPUArchState *env, 
target_ulong addr, int size,
  (access_type == MMU_DATA_STORE
   ? BP_MEM_WRITE : BP_MEM_READ), ra);
 }
-#endif
 return 0;
+#endif
 }
 
 static int access_prepare_nf(S390Access *access, CPUS390XState *env,
-- 
2.25.1




[PULL 08/60] linux-user/host/ppc: Populate host_signal.h

2021-11-02 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Reviewed-by: Warner Losh 
Signed-off-by: Richard Henderson 
---
 linux-user/host/ppc/host-signal.h   | 26 +-
 linux-user/host/ppc64/host-signal.h |  2 +-
 accel/tcg/user-exec.c   | 79 +
 3 files changed, 27 insertions(+), 80 deletions(-)

diff --git a/linux-user/host/ppc/host-signal.h 
b/linux-user/host/ppc/host-signal.h
index f4b4d65031..a491c413dc 100644
--- a/linux-user/host/ppc/host-signal.h
+++ b/linux-user/host/ppc/host-signal.h
@@ -1 +1,25 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef PPC_HOST_SIGNAL_H
+#define PPC_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.regs->nip;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+return uc->uc_mcontext.regs->trap != 0x400
+&& (uc->uc_mcontext.regs->dsisr & 0x0200);
+}
+
+#endif
diff --git a/linux-user/host/ppc64/host-signal.h 
b/linux-user/host/ppc64/host-signal.h
index f4b4d65031..a353c22a90 100644
--- a/linux-user/host/ppc64/host-signal.h
+++ b/linux-user/host/ppc64/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../ppc/host-signal.h"
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index b121e6c2e9..5a0a65fa46 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -253,84 +253,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(_ARCH_PPC)
-
-/***
- * signal context platform-specific definitions
- * From Wine
- */
-#ifdef linux
-/* All Registers access - only for local access */
-#define REG_sig(reg_name, context)  \
-((context)->uc_mcontext.regs->reg_name)
-/* Gpr Registers access  */
-#define GPR_sig(reg_num, context)  REG_sig(gpr[reg_num], context)
-/* Program counter */
-#define IAR_sig(context)   REG_sig(nip, context)
-/* Machine State Register (Supervisor) */
-#define MSR_sig(context)   REG_sig(msr, context)
-/* Count register */
-#define CTR_sig(context)   REG_sig(ctr, context)
-/* User's integer exception register */
-#define XER_sig(context)   REG_sig(xer, context)
-/* Link register */
-#define LR_sig(context)REG_sig(link, context)
-/* Condition register */
-#define CR_sig(context)REG_sig(ccr, context)
-
-/* Float Registers access  */
-#define FLOAT_sig(reg_num, context) \
-(((double *)((char *)((context)->uc_mcontext.regs + 48 * 4)))[reg_num])
-#define FPSCR_sig(context) \
-(*(int *)((char *)((context)->uc_mcontext.regs + (48 + 32 * 2) * 4)))
-/* Exception Registers access */
-#define DAR_sig(context)   REG_sig(dar, context)
-#define DSISR_sig(context) REG_sig(dsisr, context)
-#define TRAP_sig(context)  REG_sig(trap, context)
-#endif /* linux */
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#include 
-#define IAR_sig(context)   ((context)->uc_mcontext.mc_srr0)
-#define MSR_sig(context)   ((context)->uc_mcontext.mc_srr1)
-#define CTR_sig(context)   ((context)->uc_mcontext.mc_ctr)
-#define XER_sig(context)   ((context)->uc_mcontext.mc_xer)
-#define LR_sig(context)((context)->uc_mcontext.mc_lr)
-#define CR_sig(context)((context)->uc_mcontext.mc_cr)
-/* Exception Registers access */
-#define DAR_sig(context)   ((context)->uc_mcontext.mc_dar)
-#define DSISR_sig(context) ((context)->uc_mcontext.mc_dsisr)
-#define TRAP_sig(context)  ((context)->uc_mcontext.mc_exc)
-#endif /* __FreeBSD__|| __FreeBSD_kernel__ */
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-ucontext_t *uc = puc;
-#else
-ucontext_t *uc = puc;
-#endif
-unsigned long pc;
-int is_write;
-
-pc = IAR_sig(uc);
-is_write = 0;
-#if 0
-/* ppc 4xx case */
-if (DSISR_sig(uc) & 0x0080) {
-is_write = 1;
-}
-#else
-if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x0200)) {
-is_write = 1;
-}
-#endif
-return handle_cpu_signal(pc, info, is_write, >uc_sigmask);
-}
-
-#elif defined(__alpha__)
+#if defined(__alpha__)
 
 int cpu_signal_handler(int host_signum, void 

[PULL 35/60] target/riscv: Make riscv_cpu_tlb_fill sysemu only

2021-11-02 Thread Richard Henderson
The fallback code in cpu_loop_exit_sigsegv is sufficient
for riscv linux-user.

Remove the code from cpu_loop that raised SIGSEGV.

Reviewed-by: Warner Losh 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/riscv/cpu_loop.c |  7 ---
 target/riscv/cpu.c  |  2 +-
 target/riscv/cpu_helper.c   | 21 +
 3 files changed, 2 insertions(+), 28 deletions(-)

diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index e5bb6d908a..b301dac802 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -87,13 +87,6 @@ void cpu_loop(CPURISCVState *env)
 sigcode = TARGET_TRAP_BRKPT;
 sigaddr = env->pc;
 break;
-case RISCV_EXCP_INST_PAGE_FAULT:
-case RISCV_EXCP_LOAD_PAGE_FAULT:
-case RISCV_EXCP_STORE_PAGE_FAULT:
-signum = TARGET_SIGSEGV;
-sigcode = TARGET_SEGV_MAPERR;
-sigaddr = env->badaddr;
-break;
 case RISCV_EXCP_SEMIHOST:
 env->gpr[xA0] = do_common_semihosting(cs);
 env->pc += 4;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7d53125dbc..f812998123 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -694,9 +694,9 @@ static const struct SysemuCPUOps riscv_sysemu_ops = {
 static const struct TCGCPUOps riscv_tcg_ops = {
 .initialize = riscv_translate_init,
 .synchronize_from_tb = riscv_cpu_synchronize_from_tb,
-.tlb_fill = riscv_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = riscv_cpu_tlb_fill,
 .cpu_exec_interrupt = riscv_cpu_exec_interrupt,
 .do_interrupt = riscv_cpu_do_interrupt,
 .do_transaction_failed = riscv_cpu_do_transaction_failed,
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index f30ff672f8..9eeed38c7e 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -814,7 +814,6 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
 riscv_cpu_two_stage_lookup(mmu_idx);
 riscv_raise_exception(env, cs->exception_index, retaddr);
 }
-#endif /* !CONFIG_USER_ONLY */
 
 bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MMUAccessType access_type, int mmu_idx,
@@ -822,7 +821,6 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
-#ifndef CONFIG_USER_ONLY
 vaddr im_address;
 hwaddr pa = 0;
 int prot, prot2, prot_pmp;
@@ -954,25 +952,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 
 return true;
-
-#else
-switch (access_type) {
-case MMU_INST_FETCH:
-cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
-break;
-case MMU_DATA_LOAD:
-cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
-break;
-case MMU_DATA_STORE:
-cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
-break;
-default:
-g_assert_not_reached();
-}
-env->badaddr = address;
-cpu_loop_exit_restore(cs, retaddr);
-#endif
 }
+#endif /* !CONFIG_USER_ONLY */
 
 /*
  * Handle Traps
-- 
2.25.1




[PULL 05/60] configure: Merge riscv32 and riscv64 host architectures

2021-11-02 Thread Richard Henderson
The existing code for safe-syscall.inc.S will compile
without change for riscv32 and riscv64.  We may also
drop the meson.build stanza that merges them for tcg/.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 configure |  8 ++--
 meson.build   |  4 +---
 linux-user/host/{riscv64 => riscv}/hostdep.h  |  4 ++--
 linux-user/host/riscv32/hostdep.h | 11 ---
 linux-user/host/{riscv64 => riscv}/safe-syscall.inc.S |  0
 5 files changed, 5 insertions(+), 22 deletions(-)
 rename linux-user/host/{riscv64 => riscv}/hostdep.h (94%)
 delete mode 100644 linux-user/host/riscv32/hostdep.h
 rename linux-user/host/{riscv64 => riscv}/safe-syscall.inc.S (100%)

diff --git a/configure b/configure
index 039467c04b..d57ad58342 100755
--- a/configure
+++ b/configure
@@ -570,11 +570,7 @@ elif check_define __s390__ ; then
 cpu="s390"
   fi
 elif check_define __riscv ; then
-  if check_define _LP64 ; then
-cpu="riscv64"
-  else
-cpu="riscv32"
-  fi
+  cpu="riscv"
 elif check_define __arm__ ; then
   cpu="arm"
 elif check_define __aarch64__ ; then
@@ -587,7 +583,7 @@ ARCH=
 # Normalise host CPU name and set ARCH.
 # Note that this case should only have supported host CPUs, not guests.
 case "$cpu" in
-  ppc|ppc64|s390x|sparc64|x32|riscv32|riscv64)
+  ppc|ppc64|s390x|sparc64|x32|riscv)
   ;;
   ppc64le)
 ARCH="ppc64"
diff --git a/meson.build b/meson.build
index 2c5b53cbe2..90e3e85f20 100644
--- a/meson.build
+++ b/meson.build
@@ -55,7 +55,7 @@ have_block = have_system or have_tools
 python = import('python').find_installation()
 
 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 
'sunos', 'linux']
-supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 
'x86_64',
+supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
   'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
 
 cpu = host_machine.cpu_family()
@@ -351,8 +351,6 @@ if not get_option('tcg').disabled()
 tcg_arch = 'i386'
   elif config_host['ARCH'] == 'ppc64'
 tcg_arch = 'ppc'
-  elif config_host['ARCH'] in ['riscv32', 'riscv64']
-tcg_arch = 'riscv'
   endif
   add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / 
tcg_arch,
 language: ['c', 'cpp', 'objc'])
diff --git a/linux-user/host/riscv64/hostdep.h b/linux-user/host/riscv/hostdep.h
similarity index 94%
rename from linux-user/host/riscv64/hostdep.h
rename to linux-user/host/riscv/hostdep.h
index 865f0fb9ff..2ba07456ae 100644
--- a/linux-user/host/riscv64/hostdep.h
+++ b/linux-user/host/riscv/hostdep.h
@@ -5,8 +5,8 @@
  * See the COPYING file in the top-level directory.
  */
 
-#ifndef RISCV64_HOSTDEP_H
-#define RISCV64_HOSTDEP_H
+#ifndef RISCV_HOSTDEP_H
+#define RISCV_HOSTDEP_H
 
 /* We have a safe-syscall.inc.S */
 #define HAVE_SAFE_SYSCALL
diff --git a/linux-user/host/riscv32/hostdep.h 
b/linux-user/host/riscv32/hostdep.h
deleted file mode 100644
index adf9edbf2d..00
--- a/linux-user/host/riscv32/hostdep.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef RISCV32_HOSTDEP_H
-#define RISCV32_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/riscv64/safe-syscall.inc.S 
b/linux-user/host/riscv/safe-syscall.inc.S
similarity index 100%
rename from linux-user/host/riscv64/safe-syscall.inc.S
rename to linux-user/host/riscv/safe-syscall.inc.S
-- 
2.25.1




[PULL 10/60] linux-user/host/sparc: Populate host_signal.h

2021-11-02 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.
Drop the Solaris code as completely unused.

Reviewed-by: Warner Losh 
Signed-off-by: Richard Henderson 
---
 linux-user/host/sparc/host-signal.h   | 55 +++-
 linux-user/host/sparc64/host-signal.h |  2 +-
 accel/tcg/user-exec.c | 62 +--
 3 files changed, 56 insertions(+), 63 deletions(-)

diff --git a/linux-user/host/sparc/host-signal.h 
b/linux-user/host/sparc/host-signal.h
index f4b4d65031..5e71d33f8e 100644
--- a/linux-user/host/sparc/host-signal.h
+++ b/linux-user/host/sparc/host-signal.h
@@ -1 +1,54 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef SPARC_HOST_SIGNAL_H
+#define SPARC_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+#ifdef __arch64__
+return uc->uc_mcontext.mc_gregs[MC_PC];
+#else
+return uc->uc_mcontext.gregs[REG_PC];
+#endif
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+uint32_t insn = *(uint32_t *)host_signal_pc(uc);
+
+if ((insn >> 30) == 3) {
+switch ((insn >> 19) & 0x3f) {
+case 0x05: /* stb */
+case 0x15: /* stba */
+case 0x06: /* sth */
+case 0x16: /* stha */
+case 0x04: /* st */
+case 0x14: /* sta */
+case 0x07: /* std */
+case 0x17: /* stda */
+case 0x0e: /* stx */
+case 0x1e: /* stxa */
+case 0x24: /* stf */
+case 0x34: /* stfa */
+case 0x27: /* stdf */
+case 0x37: /* stdfa */
+case 0x26: /* stqf */
+case 0x36: /* stqfa */
+case 0x25: /* stfsr */
+case 0x3c: /* casa */
+case 0x3e: /* casxa */
+return true;
+}
+}
+return false;
+}
+
+#endif
diff --git a/linux-user/host/sparc64/host-signal.h 
b/linux-user/host/sparc64/host-signal.h
index f4b4d65031..1191fe2d40 100644
--- a/linux-user/host/sparc64/host-signal.h
+++ b/linux-user/host/sparc64/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../sparc/host-signal.h"
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index e9b6eb696f..694eff7f04 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -253,67 +253,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__sparc__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-int is_write;
-uint32_t insn;
-#if !defined(__arch64__) || defined(CONFIG_SOLARIS)
-uint32_t *regs = (uint32_t *)(info + 1);
-void *sigmask = (regs + 20);
-/* XXX: is there a standard glibc define ? */
-unsigned long pc = regs[1];
-#else
-#ifdef __linux__
-struct sigcontext *sc = puc;
-unsigned long pc = sc->sigc_regs.tpc;
-void *sigmask = (void *)sc->sigc_mask;
-#elif defined(__OpenBSD__)
-struct sigcontext *uc = puc;
-unsigned long pc = uc->sc_pc;
-void *sigmask = (void *)(long)uc->sc_mask;
-#elif defined(__NetBSD__)
-ucontext_t *uc = puc;
-unsigned long pc = _UC_MACHINE_PC(uc);
-void *sigmask = (void *)>uc_sigmask;
-#endif
-#endif
-
-/* XXX: need kernel patch to get write flag faster */
-is_write = 0;
-insn = *(uint32_t *)pc;
-if ((insn >> 30) == 3) {
-switch ((insn >> 19) & 0x3f) {
-case 0x05: /* stb */
-case 0x15: /* stba */
-case 0x06: /* sth */
-case 0x16: /* stha */
-case 0x04: /* st */
-case 0x14: /* sta */
-case 0x07: /* std */
-case 0x17: /* stda */
-case 0x0e: /* stx */
-case 0x1e: /* stxa */
-case 0x24: /* stf */
-case 0x34: /* stfa */
-case 0x27: /* stdf */
-case 0x37: /* stdfa */
-case 0x26: /* stqf */
-case 0x36: /* stqfa */
-case 0x25: /* stfsr */
-case 0x3c: /* casa */
-case 0x3e: /* casxa */
-is_write = 1;
-break;
-}
-}
-return handle_cpu_signal(pc, info, is_write, sigmask);
-}
-
-#elif defined(__arm__)
+#if defined(__arm__)
 
 #if defined(__NetBSD__)
 #include 
-- 
2.25.1




[PULL 00/60] accel/tcg patch queue

2021-11-02 Thread Richard Henderson
The following changes since commit dd61b91c080cdfba1360a5ea1e4693fffb3445b0:

  Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-10-29' into 
staging (2021-10-29 19:42:36 -0700)

are available in the Git repository at:

  https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20211102

for you to fetch changes up to 742f07628c0a0bd847b47ee0a0b20c44531e0ba5:

  linux-user: Handle BUS_ADRALN in host_signal_handler (2021-11-02 07:00:52 
-0400)


- Split out host signal handing from accel/tcg/user-exec.c
  to linux-user/host/arch/host-signal.h
- Replace TCGCPUOps.tlb_fill with TCGCPUOps.record_sigsegv for user-only
- Add TCGCPUOps.record_sigbus for user-only
- Remove a lot of target-specific cpu_loop handling for signals,
  now accomplished with generic code.


Richard Henderson (60):
  accel/tcg: Split out adjust_signal_pc
  accel/tcg: Move clear_helper_retaddr to cpu loop
  accel/tcg: Split out handle_sigsegv_accerr_write
  accel/tcg: Fold cpu_exit_tb_from_sighandler into caller
  configure: Merge riscv32 and riscv64 host architectures
  linux-user: Reorg handling for SIGSEGV
  linux-user/host/x86: Populate host_signal.h
  linux-user/host/ppc: Populate host_signal.h
  linux-user/host/alpha: Populate host_signal.h
  linux-user/host/sparc: Populate host_signal.h
  linux-user/host/arm: Populate host_signal.h
  linux-user/host/aarch64: Populate host_signal.h
  linux-user/host/s390: Populate host_signal.h
  linux-user/host/mips: Populate host_signal.h
  linux-user/host/riscv: Populate host_signal.h
  target/arm: Fixup comment re handle_cpu_signal
  linux-user/host/riscv: Improve host_signal_write
  linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER
  hw/core: Add TCGCPUOps.record_sigsegv
  linux-user: Add cpu_loop_exit_sigsegv
  target/alpha: Implement alpha_cpu_record_sigsegv
  target/arm: Use cpu_loop_exit_sigsegv for mte tag lookup
  target/arm: Implement arm_cpu_record_sigsegv
  target/cris: Make cris_cpu_tlb_fill sysemu only
  target/hexagon: Remove hexagon_cpu_tlb_fill
  target/hppa: Make hppa_cpu_tlb_fill sysemu only
  target/i386: Implement x86_cpu_record_sigsegv
  target/m68k: Make m68k_cpu_tlb_fill sysemu only
  target/microblaze: Make mb_cpu_tlb_fill sysemu only
  target/mips: Make mips_cpu_tlb_fill sysemu only
  target/nios2: Implement nios2_cpu_record_sigsegv
  linux-user/openrisc: Abort for EXCP_RANGE, EXCP_FPE
  target/openrisc: Make openrisc_cpu_tlb_fill sysemu only
  target/ppc: Implement ppc_cpu_record_sigsegv
  target/riscv: Make riscv_cpu_tlb_fill sysemu only
  target/s390x: Use probe_access_flags in s390_probe_access
  target/s390x: Implement s390_cpu_record_sigsegv
  target/sh4: Make sh4_cpu_tlb_fill sysemu only
  target/sparc: Make sparc_cpu_tlb_fill sysemu only
  target/xtensa: Make xtensa_cpu_tlb_fill sysemu only
  accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu
  hw/core: Add TCGCPUOps.record_sigbus
  linux-user: Add cpu_loop_exit_sigbus
  target/alpha: Implement alpha_cpu_record_sigbus
  target/arm: Implement arm_cpu_record_sigbus
  linux-user/hppa: Remove EXCP_UNALIGN handling
  target/microblaze: Do not set MO_ALIGN for user-only
  target/ppc: Move SPR_DSISR setting to powerpc_excp
  target/ppc: Set fault address in ppc_cpu_do_unaligned_access
  target/ppc: Restrict ppc_cpu_do_unaligned_access to sysemu
  linux-user/ppc: Remove POWERPC_EXCP_ALIGN handling
  target/s390x: Implement s390x_cpu_record_sigbus
  target/sh4: Set fault address in superh_cpu_do_unaligned_access
  target/sparc: Remove DEBUG_UNALIGNED
  target/sparc: Split out build_sfsr
  target/sparc: Set fault address in sparc_cpu_do_unaligned_access
  accel/tcg: Report unaligned atomics for user-only
  accel/tcg: Report unaligned load/store for user-only
  tcg: Add helper_unaligned_{ld,st} for user-only sigbus
  linux-user: Handle BUS_ADRALN in host_signal_handler

 configure  |   8 +-
 meson.build|   4 +-
 include/exec/exec-all.h|  55 +-
 include/hw/core/tcg-cpu-ops.h  |  71 +-
 include/tcg/tcg-ldst.h |   5 +
 linux-user/host/aarch64/host-signal.h  |  74 ++
 linux-user/host/alpha/host-signal.h|  42 +
 linux-user/host/arm/host-signal.h  |  30 +
 linux-user/host/i386/host-signal.h |  25 +
 linux-user/host/mips/host-signal.h |  62 ++
 linux-user/host/ppc/host-signal.h  |  25 +
 linux-user/host/ppc64/host-signal.h|   1 +
 linux-user/host/riscv/host-signal.h|  58 ++
 linux-user

[PULL 27/60] target/i386: Implement x86_cpu_record_sigsegv

2021-11-02 Thread Richard Henderson
Record cr2, error_code, and exception_index.  That last means
that we must exit to cpu_loop ourselves, instead of letting
exception_index being overwritten.

Use the maperr parameter to properly set PG_ERROR_P_MASK.

Reviewed by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/i386/tcg/helper-tcg.h   |  6 ++
 target/i386/tcg/tcg-cpu.c  |  3 ++-
 target/i386/tcg/user/excp_helper.c | 23 +--
 3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index 60ca09e95e..0a4401e917 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -43,9 +43,15 @@ bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
 #endif
 
 /* helper.c */
+#ifdef CONFIG_USER_ONLY
+void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+MMUAccessType access_type,
+bool maperr, uintptr_t ra);
+#else
 bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
   MMUAccessType access_type, int mmu_idx,
   bool probe, uintptr_t retaddr);
+#endif
 
 void breakpoint_handler(CPUState *cs);
 
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
index 3ecfae34cb..6fdfdf9598 100644
--- a/target/i386/tcg/tcg-cpu.c
+++ b/target/i386/tcg/tcg-cpu.c
@@ -72,10 +72,11 @@ static const struct TCGCPUOps x86_tcg_ops = {
 .synchronize_from_tb = x86_cpu_synchronize_from_tb,
 .cpu_exec_enter = x86_cpu_exec_enter,
 .cpu_exec_exit = x86_cpu_exec_exit,
-.tlb_fill = x86_cpu_tlb_fill,
 #ifdef CONFIG_USER_ONLY
 .fake_user_interrupt = x86_cpu_do_interrupt,
+.record_sigsegv = x86_cpu_record_sigsegv,
 #else
+.tlb_fill = x86_cpu_tlb_fill,
 .do_interrupt = x86_cpu_do_interrupt,
 .cpu_exec_interrupt = x86_cpu_exec_interrupt,
 .debug_excp_handler = breakpoint_handler,
diff --git a/target/i386/tcg/user/excp_helper.c 
b/target/i386/tcg/user/excp_helper.c
index a89b5228fd..cd507e2a1b 100644
--- a/target/i386/tcg/user/excp_helper.c
+++ b/target/i386/tcg/user/excp_helper.c
@@ -22,18 +22,29 @@
 #include "exec/exec-all.h"
 #include "tcg/helper-tcg.h"
 
-bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
-  MMUAccessType access_type, int mmu_idx,
-  bool probe, uintptr_t retaddr)
+void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+MMUAccessType access_type,
+bool maperr, uintptr_t ra)
 {
 X86CPU *cpu = X86_CPU(cs);
 CPUX86State *env = >env;
 
+/*
+ * The error_code that hw reports as part of the exception frame
+ * is copied to linux sigcontext.err.  The exception_index is
+ * copied to linux sigcontext.trapno.  Short of inventing a new
+ * place to store the trapno, we cannot let our caller raise the
+ * signal and set exception_index to EXCP_INTERRUPT.
+ */
 env->cr[2] = addr;
-env->error_code = (access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT;
-env->error_code |= PG_ERROR_U_MASK;
+env->error_code = ((access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT)
+| (maperr ? 0 : PG_ERROR_P_MASK)
+| PG_ERROR_U_MASK;
 cs->exception_index = EXCP0E_PAGE;
+
+/* Disable do_interrupt_user. */
 env->exception_is_int = 0;
 env->exception_next_eip = -1;
-cpu_loop_exit_restore(cs, retaddr);
+
+cpu_loop_exit_restore(cs, ra);
 }
-- 
2.25.1




[PULL 07/60] linux-user/host/x86: Populate host_signal.h

2021-11-02 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Reviewed-by: Warner Losh 
Signed-off-by: Richard Henderson 
---
 linux-user/host/i386/host-signal.h   |  26 -
 linux-user/host/x32/host-signal.h|   2 +-
 linux-user/host/x86_64/host-signal.h |  25 -
 accel/tcg/user-exec.c| 136 +--
 4 files changed, 51 insertions(+), 138 deletions(-)

diff --git a/linux-user/host/i386/host-signal.h 
b/linux-user/host/i386/host-signal.h
index f4b4d65031..4c8eef99ce 100644
--- a/linux-user/host/i386/host-signal.h
+++ b/linux-user/host/i386/host-signal.h
@@ -1 +1,25 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef I386_HOST_SIGNAL_H
+#define I386_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.gregs[REG_EIP];
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
+&& (uc->uc_mcontext.gregs[REG_ERR] & 0x2);
+}
+
+#endif
diff --git a/linux-user/host/x32/host-signal.h 
b/linux-user/host/x32/host-signal.h
index f4b4d65031..26800591d3 100644
--- a/linux-user/host/x32/host-signal.h
+++ b/linux-user/host/x32/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../x86_64/host-signal.h"
diff --git a/linux-user/host/x86_64/host-signal.h 
b/linux-user/host/x86_64/host-signal.h
index f4b4d65031..883d2fcf65 100644
--- a/linux-user/host/x86_64/host-signal.h
+++ b/linux-user/host/x86_64/host-signal.h
@@ -1 +1,24 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef X86_64_HOST_SIGNAL_H
+#define X86_64_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.gregs[REG_RIP];
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
+&& (uc->uc_mcontext.gregs[REG_ERR] & 0x2);
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index b1183aa4b3..b121e6c2e9 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -29,19 +29,6 @@
 #include "trace/trace-root.h"
 #include "internal.h"
 
-#undef EAX
-#undef ECX
-#undef EDX
-#undef EBX
-#undef ESP
-#undef EBP
-#undef ESI
-#undef EDI
-#undef EIP
-#ifdef __linux__
-#include 
-#endif
-
 __thread uintptr_t helper_retaddr;
 
 //#define DEBUG_SIGNAL
@@ -266,123 +253,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__i386__)
-
-#if defined(__NetBSD__)
-#include 
-#include 
-
-#define EIP_sig(context) ((context)->uc_mcontext.__gregs[_REG_EIP])
-#define TRAP_sig(context)((context)->uc_mcontext.__gregs[_REG_TRAPNO])
-#define ERROR_sig(context)   ((context)->uc_mcontext.__gregs[_REG_ERR])
-#define MASK_sig(context)((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP  T_PAGEFLT
-#elif defined(__FreeBSD__) || defined(__DragonFly__)
-#include 
-#include 
-
-#define EIP_sig(context)  (*((unsigned long *)&(context)->uc_mcontext.mc_eip))
-#define TRAP_sig(context)((context)->uc_mcontext.mc_trapno)
-#define ERROR_sig(context)   ((context)->uc_mcontext.mc_err)
-#define MASK_sig(context)((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP  T_PAGEFLT
-#elif defined(__OpenBSD__)
-#include 
-#define EIP_sig(context) ((context)->sc_eip)
-#define TRAP_sig(context)((context)->sc_trapno)
-#define ERROR_sig(context)   ((context)->sc_err)
-#define MASK_sig(context)((context)->sc_mask)
-#define PAGE_FAULT_TRAP  T_PAGEFLT
-#else
-#define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP])
-#define TRAP_sig(context)((context)->uc_mcontext.gregs[REG_TRAPNO])
-#define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
-#define MASK_sig(context)((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP  0xe
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
-ucontext_t *uc = puc;
-#elif defined(__OpenBSD__)
-struct sigcontext *uc = puc;
-#else
-ucontext_t *uc = puc;
-#endif
-unsigned long pc;
-int trapno;
-
-#ifndef REG_EIP
-/* for glibc 2.1 */
-#define REG_EIPEIP
-#define REG_ERRERR
-#define REG_TRAPNO TRAPNO
-#endif
-pc = EIP_sig(uc);
-

[PULL 03/60] accel/tcg: Split out handle_sigsegv_accerr_write

2021-11-02 Thread Richard Henderson
This is the major portion of handle_cpu_signal which is specific
to tcg, handling the page protections for the translations.
Most of the rest will migrate to linux-user/ shortly.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
v2: Pass guest address to handle_sigsegv_accerr_write.
---
 include/exec/exec-all.h |  12 +
 accel/tcg/user-exec.c   | 101 
 2 files changed, 72 insertions(+), 41 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index e54f8e5d65..5f94d799aa 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -673,6 +673,18 @@ static inline tb_page_addr_t 
get_page_addr_code_hostp(CPUArchState *env,
  */
 MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write);
 
+/**
+ * handle_sigsegv_accerr_write:
+ * @cpu: the cpu context
+ * @old_set: the sigset_t from the signal ucontext_t
+ * @host_pc: the host pc, adjusted for the signal
+ * @host_addr: the host address of the fault
+ *
+ * Return true if the write fault has been handled, and should be re-tried.
+ */
+bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
+ uintptr_t host_pc, abi_ptr guest_addr);
+
 /**
  * cpu_signal_handler
  * @signum: host signal number
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 3f3e793b7b..b83f8d12f4 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -114,6 +114,52 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool 
is_write)
 return is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
 }
 
+/**
+ * handle_sigsegv_accerr_write:
+ * @cpu: the cpu context
+ * @old_set: the sigset_t from the signal ucontext_t
+ * @host_pc: the host pc, adjusted for the signal
+ * @guest_addr: the guest address of the fault
+ *
+ * Return true if the write fault has been handled, and should be re-tried.
+ *
+ * Note that it is important that we don't call page_unprotect() unless
+ * this is really a "write to nonwriteable page" fault, because
+ * page_unprotect() assumes that if it is called for an access to
+ * a page that's writeable this means we had two threads racing and
+ * another thread got there first and already made the page writeable;
+ * so we will retry the access. If we were to call page_unprotect()
+ * for some other kind of fault that should really be passed to the
+ * guest, we'd end up in an infinite loop of retrying the faulting access.
+ */
+bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
+ uintptr_t host_pc, abi_ptr guest_addr)
+{
+switch (page_unprotect(guest_addr, host_pc)) {
+case 0:
+/*
+ * Fault not caused by a page marked unwritable to protect
+ * cached translations, must be the guest binary's problem.
+ */
+return false;
+case 1:
+/*
+ * Fault caused by protection of cached translation; TBs
+ * invalidated, so resume execution.
+ */
+return true;
+case 2:
+/*
+ * Fault caused by protection of cached translation, and the
+ * currently executing TB was modified and must be exited immediately.
+ */
+cpu_exit_tb_from_sighandler(cpu, old_set);
+/* NORETURN */
+default:
+g_assert_not_reached();
+}
+}
+
 /*
  * 'pc' is the host PC at which the exception was raised.
  * 'address' is the effective address of the memory exception.
@@ -125,8 +171,9 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
 {
 CPUState *cpu = current_cpu;
 CPUClass *cc;
-unsigned long address = (unsigned long)info->si_addr;
+unsigned long host_addr = (unsigned long)info->si_addr;
 MMUAccessType access_type = adjust_signal_pc(, is_write);
+abi_ptr guest_addr;
 
 /* For synchronous signals we expect to be coming from the vCPU
  * thread (so current_cpu should be valid) and either from running
@@ -143,49 +190,21 @@ static inline int handle_cpu_signal(uintptr_t pc, 
siginfo_t *info,
 
 #if defined(DEBUG_SIGNAL)
 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
-   pc, address, is_write, *(unsigned long *)old_set);
+   pc, host_addr, is_write, *(unsigned long *)old_set);
 #endif
-/* XXX: locking issue */
-/* Note that it is important that we don't call page_unprotect() unless
- * this is really a "write to nonwriteable page" fault, because
- * page_unprotect() assumes that if it is called for an access to
- * a page that's writeable this means we had two threads racing and
- * another thread got there first and already made the page writeable;
- * so we will retry the access. If we were to call page_unprotect()
- * for some other kind of fault that should really be passed to the
- * guest, we'd end up in an infinite loop of retrying the faulting
- * access.
- */
-if (is_write && 

[PULL 06/60] linux-user: Reorg handling for SIGSEGV

2021-11-02 Thread Richard Henderson
Add stub host-signal.h for all linux-user hosts.
Add new code replacing cpu_signal_handler.
Full migration will happen one host at a time.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 linux-user/host/aarch64/host-signal.h |   1 +
 linux-user/host/arm/host-signal.h |   1 +
 linux-user/host/i386/host-signal.h|   1 +
 linux-user/host/mips/host-signal.h|   1 +
 linux-user/host/ppc/host-signal.h |   1 +
 linux-user/host/ppc64/host-signal.h   |   1 +
 linux-user/host/riscv/host-signal.h   |   1 +
 linux-user/host/s390/host-signal.h|   1 +
 linux-user/host/s390x/host-signal.h   |   1 +
 linux-user/host/sparc/host-signal.h   |   1 +
 linux-user/host/sparc64/host-signal.h |   1 +
 linux-user/host/x32/host-signal.h |   1 +
 linux-user/host/x86_64/host-signal.h  |   1 +
 linux-user/signal.c   | 109 ++
 14 files changed, 106 insertions(+), 16 deletions(-)
 create mode 100644 linux-user/host/aarch64/host-signal.h
 create mode 100644 linux-user/host/arm/host-signal.h
 create mode 100644 linux-user/host/i386/host-signal.h
 create mode 100644 linux-user/host/mips/host-signal.h
 create mode 100644 linux-user/host/ppc/host-signal.h
 create mode 100644 linux-user/host/ppc64/host-signal.h
 create mode 100644 linux-user/host/riscv/host-signal.h
 create mode 100644 linux-user/host/s390/host-signal.h
 create mode 100644 linux-user/host/s390x/host-signal.h
 create mode 100644 linux-user/host/sparc/host-signal.h
 create mode 100644 linux-user/host/sparc64/host-signal.h
 create mode 100644 linux-user/host/x32/host-signal.h
 create mode 100644 linux-user/host/x86_64/host-signal.h

diff --git a/linux-user/host/aarch64/host-signal.h 
b/linux-user/host/aarch64/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/aarch64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/arm/host-signal.h 
b/linux-user/host/arm/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/arm/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/i386/host-signal.h 
b/linux-user/host/i386/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/i386/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/mips/host-signal.h 
b/linux-user/host/mips/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/mips/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/ppc/host-signal.h 
b/linux-user/host/ppc/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/ppc/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/ppc64/host-signal.h 
b/linux-user/host/ppc64/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/ppc64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/riscv/host-signal.h 
b/linux-user/host/riscv/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/riscv/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/s390/host-signal.h 
b/linux-user/host/s390/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/s390/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/s390x/host-signal.h 
b/linux-user/host/s390x/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/s390x/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/sparc/host-signal.h 
b/linux-user/host/sparc/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/sparc/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/sparc64/host-signal.h 
b/linux-user/host/sparc64/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/sparc64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/x32/host-signal.h 
b/linux-user/host/x32/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/x32/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/x86_64/host-signal.h 
b/linux-user/host/x86_64/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/x86_64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 14d8fdfde1..6900acb122 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ 

[PULL 22/60] target/arm: Use cpu_loop_exit_sigsegv for mte tag lookup

2021-11-02 Thread Richard Henderson
Use the new os interface for raising the exception,
rather than calling arm_cpu_tlb_fill directly.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/arm/mte_helper.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 724175210b..e09b7e46a2 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -84,10 +84,8 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int 
ptr_mmu_idx,
 uintptr_t index;
 
 if (!(flags & (ptr_access == MMU_DATA_STORE ? PAGE_WRITE_ORG : 
PAGE_READ))) {
-/* SIGSEGV */
-arm_cpu_tlb_fill(env_cpu(env), ptr, ptr_size, ptr_access,
- ptr_mmu_idx, false, ra);
-g_assert_not_reached();
+cpu_loop_exit_sigsegv(env_cpu(env), ptr, ptr_access,
+  !(flags & PAGE_VALID), ra);
 }
 
 /* Require both MAP_ANON and PROT_MTE for the page. */
-- 
2.25.1




[PULL 04/60] accel/tcg: Fold cpu_exit_tb_from_sighandler into caller

2021-11-02 Thread Richard Henderson
Remove the comment about siglongjmp.  We do use sigsetjmp
in the main cpu loop, but we do not save the signal mask
as most exits from the cpu loop do not require them.

Reviewed-by: Warner Losh 
Signed-off-by: Richard Henderson 
---
 accel/tcg/user-exec.c | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index b83f8d12f4..b1183aa4b3 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -46,17 +46,6 @@ __thread uintptr_t helper_retaddr;
 
 //#define DEBUG_SIGNAL
 
-/* exit the current TB from a signal handler. The host registers are
-   restored in a state compatible with the CPU emulator
- */
-static void QEMU_NORETURN cpu_exit_tb_from_sighandler(CPUState *cpu,
-  sigset_t *old_set)
-{
-/* XXX: use siglongjmp ? */
-sigprocmask(SIG_SETMASK, old_set, NULL);
-cpu_loop_exit_noexc(cpu);
-}
-
 /*
  * Adjust the pc to pass to cpu_restore_state; return the memop type.
  */
@@ -153,7 +142,8 @@ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t 
*old_set,
  * Fault caused by protection of cached translation, and the
  * currently executing TB was modified and must be exited immediately.
  */
-cpu_exit_tb_from_sighandler(cpu, old_set);
+sigprocmask(SIG_SETMASK, old_set, NULL);
+cpu_loop_exit_noexc(cpu);
 /* NORETURN */
 default:
 g_assert_not_reached();
-- 
2.25.1




[PULL 11/12] target/arm: Use tcg_constant_i32() in gen_rev16()

2021-11-02 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

Since the mask is a constant value, use tcg_constant_i32()
instead of a TCG temporary.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211029231834.2476117-6-f4...@amsat.org>
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 52ba562c96..98f5925928 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -388,13 +388,12 @@ static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
 void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
 {
 TCGv_i32 tmp = tcg_temp_new_i32();
-TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
+TCGv_i32 mask = tcg_constant_i32(0x00ff00ff);
 tcg_gen_shri_i32(tmp, var, 8);
 tcg_gen_and_i32(tmp, tmp, mask);
 tcg_gen_and_i32(var, var, mask);
 tcg_gen_shli_i32(var, var, 8);
 tcg_gen_or_i32(dest, var, tmp);
-tcg_temp_free_i32(mask);
 tcg_temp_free_i32(tmp);
 }
 
-- 
2.25.1




[PULL 02/60] accel/tcg: Move clear_helper_retaddr to cpu loop

2021-11-02 Thread Richard Henderson
Currently there are only two places that require we reset this
value before exiting to the main loop, but that will change.

Reviewed-by: Warner Losh 
Signed-off-by: Richard Henderson 
---
 accel/tcg/cpu-exec.c  | 3 ++-
 accel/tcg/user-exec.c | 2 --
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index c9764c1325..bba4672632 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -462,6 +462,7 @@ void cpu_exec_step_atomic(CPUState *cpu)
  * memory.
  */
 #ifndef CONFIG_SOFTMMU
+clear_helper_retaddr();
 tcg_debug_assert(!have_mmap_lock());
 #endif
 if (qemu_mutex_iothread_locked()) {
@@ -471,7 +472,6 @@ void cpu_exec_step_atomic(CPUState *cpu)
 qemu_plugin_disable_mem_helpers(cpu);
 }
 
-
 /*
  * As we start the exclusive region before codegen we must still
  * be in the region if we longjump out of either the codegen or
@@ -916,6 +916,7 @@ int cpu_exec(CPUState *cpu)
 #endif
 
 #ifndef CONFIG_SOFTMMU
+clear_helper_retaddr();
 tcg_debug_assert(!have_mmap_lock());
 #endif
 if (qemu_mutex_iothread_locked()) {
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index c02d509ec6..3f3e793b7b 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -175,7 +175,6 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
  * currently executing TB was modified and must be exited
  * immediately.  Clear helper_retaddr for next execution.
  */
-clear_helper_retaddr();
 cpu_exit_tb_from_sighandler(cpu, old_set);
 /* NORETURN */
 
@@ -193,7 +192,6 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
  * an exception.  Undo signal and retaddr state prior to longjmp.
  */
 sigprocmask(SIG_SETMASK, old_set, NULL);
-clear_helper_retaddr();
 
 cc = CPU_GET_CLASS(cpu);
 cc->tcg_ops->tlb_fill(cpu, address, 0, access_type,
-- 
2.25.1




[PULL 15/60] linux-user/host/riscv: Populate host_signal.h

2021-11-02 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.

Reviewed-by: Warner Losh 
Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 linux-user/host/riscv/host-signal.h |  86 +-
 accel/tcg/user-exec.c   | 134 
 2 files changed, 85 insertions(+), 135 deletions(-)

diff --git a/linux-user/host/riscv/host-signal.h 
b/linux-user/host/riscv/host-signal.h
index f4b4d65031..df145b1527 100644
--- a/linux-user/host/riscv/host-signal.h
+++ b/linux-user/host/riscv/host-signal.h
@@ -1 +1,85 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef RISCV_HOST_SIGNAL_H
+#define RISCV_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.__gregs[REG_PC];
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+uint32_t insn = *(uint32_t *)host_signal_pc(uc);
+
+/*
+ * Detect store by reading the instruction at the program
+ * counter. Note: we currently only generate 32-bit
+ * instructions so we thus only detect 32-bit stores
+ */
+switch (((insn >> 0) & 0b11)) {
+case 3:
+switch (((insn >> 2) & 0b1)) {
+case 8:
+switch (((insn >> 12) & 0b111)) {
+case 0: /* sb */
+case 1: /* sh */
+case 2: /* sw */
+case 3: /* sd */
+case 4: /* sq */
+return true;
+default:
+break;
+}
+break;
+case 9:
+switch (((insn >> 12) & 0b111)) {
+case 2: /* fsw */
+case 3: /* fsd */
+case 4: /* fsq */
+return true;
+default:
+break;
+}
+break;
+default:
+break;
+}
+}
+
+/* Check for compressed instructions */
+switch (((insn >> 13) & 0b111)) {
+case 7:
+switch (insn & 0b11) {
+case 0: /*c.sd */
+case 2: /* c.sdsp */
+return true;
+default:
+break;
+}
+break;
+case 6:
+switch (insn & 0b11) {
+case 0: /* c.sw */
+case 3: /* c.swsp */
+return true;
+default:
+break;
+}
+break;
+default:
+break;
+}
+
+return false;
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 44c83acba5..a0cba61e83 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -137,64 +137,6 @@ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t 
*old_set,
 }
 }
 
-/*
- * 'pc' is the host PC at which the exception was raised.
- * 'address' is the effective address of the memory exception.
- * 'is_write' is 1 if a write caused the exception and otherwise 0.
- * 'old_set' is the signal set which should be restored.
- */
-static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
-int is_write, sigset_t *old_set)
-{
-CPUState *cpu = current_cpu;
-CPUClass *cc;
-unsigned long host_addr = (unsigned long)info->si_addr;
-MMUAccessType access_type = adjust_signal_pc(, is_write);
-abi_ptr guest_addr;
-
-/* For synchronous signals we expect to be coming from the vCPU
- * thread (so current_cpu should be valid) and either from running
- * code or during translation which can fault as we cross pages.
- *
- * If neither is true then something has gone wrong and we should
- * abort rather than try and restart the vCPU execution.
- */
-if (!cpu || !cpu->running) {
-printf("qemu:%s received signal outside vCPU context @ pc=0x%"
-   PRIxPTR "\n",  __func__, pc);
-abort();
-}
-
-#if defined(DEBUG_SIGNAL)
-printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
-   pc, host_addr, is_write, *(unsigned long *)old_set);
-#endif
-
-/* Convert forcefully to guest address space, invalid addresses
-   are still valid segv ones */
-guest_addr = h2g_nocheck(host_addr);
-
-/* XXX: locking issue */
-if (is_write &&
-info->si_signo == SIGSEGV &&
-info->si_code == SEGV_ACCERR &&
-h2g_valid(host_addr) &&
-handle_sigsegv_accerr_write(cpu, old_set, pc, guest_addr)) {
-return 1;
-}
-
-/*
- * There is no way the target can handle this other than raising
- * an exception.  Undo signal and retaddr state prior to longjmp.
- */
-sigprocmask(SIG_SETMASK, old_set, NULL);
-
-cc = CPU_GET_CLASS(cpu);
-cc->tcg_ops->tlb_fill(cpu, guest_addr, 0, access_type,
-  

[PULL 12/12] hw/arm/virt: Rename default_bus_bypass_iommu

2021-11-02 Thread Richard Henderson
From: Jean-Philippe Brucker 

Since commit d8fb7d0969d5 ("vl: switch -M parsing to keyval"), machine
parameter definitions cannot use underscores, because keyval_dashify()
transforms them to dashes and the parser doesn't find the parameter.

This affects option default_bus_bypass_iommu which was introduced in the
same release:

$ qemu-system-aarch64 -M virt,default_bus_bypass_iommu=on
qemu-system-aarch64: Property 'virt-6.1-machine.default-bus-bypass-iommu' not 
found

Rename the parameter to "default-bus-bypass-iommu". Passing
"default_bus_bypass_iommu" is still valid since the underscore are
transformed automatically.

Fixes: 6d7a85483a06 ("hw/arm/virt: Add default_bus_bypass_iommu machine option")
Signed-off-by: Jean-Philippe Brucker 
Tested-by: Eric Auger 
Reviewed-by: Eric Auger 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211026093733.2144161-1-jean-phili...@linaro.org>
Signed-off-by: Richard Henderson 
---
 hw/arm/virt.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index ca433adb5b..369552ad45 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2737,10 +2737,10 @@ static void virt_machine_class_init(ObjectClass *oc, 
void *data)
   "Set the IOMMU type. "
   "Valid values are none and smmuv3");
 
-object_class_property_add_bool(oc, "default_bus_bypass_iommu",
+object_class_property_add_bool(oc, "default-bus-bypass-iommu",
virt_get_default_bus_bypass_iommu,
virt_set_default_bus_bypass_iommu);
-object_class_property_set_description(oc, "default_bus_bypass_iommu",
+object_class_property_set_description(oc, "default-bus-bypass-iommu",
   "Set on/off to enable/disable "
   "bypass_iommu for default root bus");
 
-- 
2.25.1




[PULL 09/12] target/arm: Use the constant variant of store_cpu_field() when possible

2021-11-02 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

When using a constant variable, we can replace the store_cpu_field()
call by store_cpu_field_constant() which avoid using TCG temporaries.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211029231834.2476117-4-f4...@amsat.org>
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 21 ++---
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 083a6d6ed7..52ba562c96 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -364,8 +364,7 @@ void clear_eci_state(DisasContext *s)
  * multiple insn executes.
  */
 if (s->eci) {
-TCGv_i32 tmp = tcg_const_i32(0);
-store_cpu_field(tmp, condexec_bits);
+store_cpu_field_constant(0, condexec_bits);
 s->eci = 0;
 }
 }
@@ -740,9 +739,8 @@ void gen_set_condexec(DisasContext *s)
 {
 if (s->condexec_mask) {
 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
-TCGv_i32 tmp = tcg_temp_new_i32();
-tcg_gen_movi_i32(tmp, val);
-store_cpu_field(tmp, condexec_bits);
+
+store_cpu_field_constant(val, condexec_bits);
 }
 }
 
@@ -8362,8 +8360,6 @@ static bool trans_BL(DisasContext *s, arg_i *a)
 
 static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
 {
-TCGv_i32 tmp;
-
 /*
  * BLX  would be useless on M-profile; the encoding space
  * is used for other insns from v8.1M onward, and UNDEFs before that.
@@ -8377,8 +8373,7 @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
 return false;
 }
 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
-tmp = tcg_const_i32(!s->thumb);
-store_cpu_field(tmp, thumb);
+store_cpu_field_constant(!s->thumb, thumb);
 gen_jmp(s, (read_pc(s) & ~3) + a->imm);
 return true;
 }
@@ -8677,7 +8672,6 @@ static bool trans_LCTP(DisasContext *s, arg_LCTP *a)
  * doesn't cache branch information, all we need to do is reset
  * FPSCR.LTPSIZE to 4.
  */
-TCGv_i32 ltpsize;
 
 if (!dc_isar_feature(aa32_lob, s) ||
 !dc_isar_feature(aa32_mve, s)) {
@@ -8688,8 +8682,7 @@ static bool trans_LCTP(DisasContext *s, arg_LCTP *a)
 return true;
 }
 
-ltpsize = tcg_const_i32(4);
-store_cpu_field(ltpsize, v7m.ltpsize);
+store_cpu_field_constant(4, v7m.ltpsize);
 return true;
 }
 
@@ -9487,9 +9480,7 @@ static void arm_tr_tb_start(DisasContextBase *dcbase, 
CPUState *cpu)
 /* Reset the conditional execution bits immediately. This avoids
complications trying to do it at the end of the block.  */
 if (dc->condexec_mask || dc->condexec_cond) {
-TCGv_i32 tmp = tcg_temp_new_i32();
-tcg_gen_movi_i32(tmp, 0);
-store_cpu_field(tmp, condexec_bits);
+store_cpu_field_constant(0, condexec_bits);
 }
 }
 
-- 
2.25.1




[PULL 01/60] accel/tcg: Split out adjust_signal_pc

2021-11-02 Thread Richard Henderson
Split out a function to adjust the raw signal pc into a
value that could be passed to cpu_restore_state.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
v2: Adjust pc in place; return MMUAccessType.
---
 include/exec/exec-all.h | 10 ++
 accel/tcg/user-exec.c   | 41 +
 2 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 9d5987ba04..e54f8e5d65 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -663,6 +663,16 @@ static inline tb_page_addr_t 
get_page_addr_code_hostp(CPUArchState *env,
 return addr;
 }
 
+/**
+ * adjust_signal_pc:
+ * @pc: raw pc from the host signal ucontext_t.
+ * @is_write: host memory operation was write, or read-modify-write.
+ *
+ * Alter @pc as required for unwinding.  Return the type of the
+ * guest memory access -- host reads may be for guest execution.
+ */
+MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write);
+
 /**
  * cpu_signal_handler
  * @signum: host signal number
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index e6bb29b42d..c02d509ec6 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -57,18 +57,11 @@ static void QEMU_NORETURN 
cpu_exit_tb_from_sighandler(CPUState *cpu,
 cpu_loop_exit_noexc(cpu);
 }
 
-/* 'pc' is the host PC at which the exception was raised. 'address' is
-   the effective address of the memory exception. 'is_write' is 1 if a
-   write caused the exception and otherwise 0'. 'old_set' is the
-   signal set which should be restored */
-static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
-int is_write, sigset_t *old_set)
+/*
+ * Adjust the pc to pass to cpu_restore_state; return the memop type.
+ */
+MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write)
 {
-CPUState *cpu = current_cpu;
-CPUClass *cc;
-unsigned long address = (unsigned long)info->si_addr;
-MMUAccessType access_type = is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
-
 switch (helper_retaddr) {
 default:
 /*
@@ -77,7 +70,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
  * pointer into the generated code that will unwind to the
  * correct guest pc.
  */
-pc = helper_retaddr;
+*pc = helper_retaddr;
 break;
 
 case 0:
@@ -97,7 +90,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
  * Therefore, adjust to compensate for what will be done later
  * by cpu_restore_state_from_tb.
  */
-pc += GETPC_ADJ;
+*pc += GETPC_ADJ;
 break;
 
 case 1:
@@ -113,12 +106,28 @@ static inline int handle_cpu_signal(uintptr_t pc, 
siginfo_t *info,
  *
  * Like tb_gen_code, release the memory lock before cpu_loop_exit.
  */
-pc = 0;
-access_type = MMU_INST_FETCH;
 mmap_unlock();
-break;
+*pc = 0;
+return MMU_INST_FETCH;
 }
 
+return is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
+}
+
+/*
+ * 'pc' is the host PC at which the exception was raised.
+ * 'address' is the effective address of the memory exception.
+ * 'is_write' is 1 if a write caused the exception and otherwise 0.
+ * 'old_set' is the signal set which should be restored.
+ */
+static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
+int is_write, sigset_t *old_set)
+{
+CPUState *cpu = current_cpu;
+CPUClass *cc;
+unsigned long address = (unsigned long)info->si_addr;
+MMUAccessType access_type = adjust_signal_pc(, is_write);
+
 /* For synchronous signals we expect to be coming from the vCPU
  * thread (so current_cpu should be valid) and either from running
  * code or during translation which can fault as we cross pages.
-- 
2.25.1




[PULL 07/12] target/arm: Use tcg_constant_i32() in op_smlad()

2021-11-02 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

Avoid using a TCG temporary for a read-only constant.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211029231834.2476117-2-f4...@amsat.org>
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index d6af5b1b03..083a6d6ed7 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -7849,10 +7849,9 @@ static bool op_smlad(DisasContext *s, arg_ *a, bool 
m_swap, bool sub)
 t3 = tcg_temp_new_i32();
 tcg_gen_sari_i32(t3, t1, 31);
 qf = load_cpu_field(QF);
-one = tcg_const_i32(1);
+one = tcg_constant_i32(1);
 tcg_gen_movcond_i32(TCG_COND_NE, qf, t2, t3, one, qf);
 store_cpu_field(qf, QF);
-tcg_temp_free_i32(one);
 tcg_temp_free_i32(t3);
 tcg_temp_free_i32(t2);
 }
-- 
2.25.1




[PULL 19/60] hw/core: Add TCGCPUOps.record_sigsegv

2021-11-02 Thread Richard Henderson
Add a new user-only interface for updating cpu state before
raising a signal.  This will replace tlb_fill for user-only
and should result in less boilerplate for each guest.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/hw/core/tcg-cpu-ops.h | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index 6cbe17f2e6..41718b695b 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -111,6 +111,32 @@ struct TCGCPUOps {
  */
 bool (*io_recompile_replay_branch)(CPUState *cpu,
const TranslationBlock *tb);
+#else
+/**
+ * record_sigsegv:
+ * @cpu: cpu context
+ * @addr: faulting guest address
+ * @access_type: access was read/write/execute
+ * @maperr: true for invalid page, false for permission fault
+ * @ra: host pc for unwinding
+ *
+ * We are about to raise SIGSEGV with si_code set for @maperr,
+ * and si_addr set for @addr.  Record anything further needed
+ * for the signal ucontext_t.
+ *
+ * If the emulated kernel does not provide anything to the signal
+ * handler with anything besides the user context registers, and
+ * the siginfo_t, then this hook need do nothing and may be omitted.
+ * Otherwise, record the data and return; the caller will raise
+ * the signal, unwind the cpu state, and return to the main loop.
+ *
+ * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided
+ * so that a "normal" cpu exception can be raised.  In this case,
+ * the signal must be raised by the architecture cpu_loop.
+ */
+void (*record_sigsegv)(CPUState *cpu, vaddr addr,
+   MMUAccessType access_type,
+   bool maperr, uintptr_t ra);
 #endif /* CONFIG_SOFTMMU */
 #endif /* NEED_CPU_H */
 
-- 
2.25.1




[PULL 08/12] target/arm: Introduce store_cpu_field_constant() helper

2021-11-02 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

Similarly to the store_cpu_field() helper which takes a TCG
temporary, store its value to the CPUState, introduce the
store_cpu_field_constant() helper which store a constant to
CPUState (without using any TCG temporary).

Suggested-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211029231834.2476117-3-f4...@amsat.org>
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a32.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
index 88f15df60e..17af8dc95a 100644
--- a/target/arm/translate-a32.h
+++ b/target/arm/translate-a32.h
@@ -70,6 +70,9 @@ static inline void store_cpu_offset(TCGv_i32 var, int offset)
 #define store_cpu_field(var, name) \
 store_cpu_offset(var, offsetof(CPUARMState, name))
 
+#define store_cpu_field_constant(val, name) \
+tcg_gen_st_i32(tcg_constant_i32(val), cpu_env, offsetof(CPUARMState, name))
+
 /* Create a new temporary and set it to the value of a CPU register.  */
 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
 {
-- 
2.25.1




[PULL 10/12] target/arm: Use tcg_constant_i64() in do_sat_addsub_64()

2021-11-02 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

The immediate value used for comparison is constant and
read-only. Move it to the constant pool. This frees a
TCG temporary for unsigned saturation opcodes.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20211029231834.2476117-5-f4...@amsat.org>
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index bc91a64171..76b5fe9f31 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1943,20 +1943,20 @@ static void do_sat_addsub_32(TCGv_i64 reg, TCGv_i64 
val, bool u, bool d)
 static void do_sat_addsub_64(TCGv_i64 reg, TCGv_i64 val, bool u, bool d)
 {
 TCGv_i64 t0 = tcg_temp_new_i64();
-TCGv_i64 t1 = tcg_temp_new_i64();
 TCGv_i64 t2;
 
 if (u) {
 if (d) {
 tcg_gen_sub_i64(t0, reg, val);
-tcg_gen_movi_i64(t1, 0);
-tcg_gen_movcond_i64(TCG_COND_LTU, reg, reg, val, t1, t0);
+t2 = tcg_constant_i64(0);
+tcg_gen_movcond_i64(TCG_COND_LTU, reg, reg, val, t2, t0);
 } else {
 tcg_gen_add_i64(t0, reg, val);
-tcg_gen_movi_i64(t1, -1);
-tcg_gen_movcond_i64(TCG_COND_LTU, reg, t0, reg, t1, t0);
+t2 = tcg_constant_i64(-1);
+tcg_gen_movcond_i64(TCG_COND_LTU, reg, t0, reg, t2, t0);
 }
 } else {
+TCGv_i64 t1 = tcg_temp_new_i64();
 if (d) {
 /* Detect signed overflow for subtraction.  */
 tcg_gen_xor_i64(t0, reg, val);
@@ -1966,7 +1966,7 @@ static void do_sat_addsub_64(TCGv_i64 reg, TCGv_i64 val, 
bool u, bool d)
 
 /* Bound the result.  */
 tcg_gen_movi_i64(reg, INT64_MIN);
-t2 = tcg_const_i64(0);
+t2 = tcg_constant_i64(0);
 tcg_gen_movcond_i64(TCG_COND_LT, reg, t0, t2, reg, t1);
 } else {
 /* Detect signed overflow for addition.  */
@@ -1977,13 +1977,12 @@ static void do_sat_addsub_64(TCGv_i64 reg, TCGv_i64 
val, bool u, bool d)
 
 /* Bound the result.  */
 tcg_gen_movi_i64(t1, INT64_MAX);
-t2 = tcg_const_i64(0);
+t2 = tcg_constant_i64(0);
 tcg_gen_movcond_i64(TCG_COND_LT, reg, t0, t2, t1, reg);
 }
-tcg_temp_free_i64(t2);
+tcg_temp_free_i64(t1);
 }
 tcg_temp_free_i64(t0);
-tcg_temp_free_i64(t1);
 }
 
 /* Similarly with a vector and a scalar operand.  */
-- 
2.25.1




[PULL 03/12] hw/arm: Attach MMC to quanta-gbs-bmc

2021-11-02 Thread Richard Henderson
From: Shengtan Mao 

Signed-off-by: Shengtan Mao 
Signed-off-by: Hao Wu 
Reviewed-by: Hao Wu 
Reviewed-by: Tyrone Ting 
Reviewed-by: Peter Maydell 
Message-Id: <20211008002628.1958285-4-wuhao...@google.com>
Signed-off-by: Richard Henderson 
---
 hw/arm/npcm7xx_boards.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index a656169f61..dec7d16ae5 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -27,6 +27,9 @@
 #include "qemu-common.h"
 #include "qemu/datadir.h"
 #include "qemu/units.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/block-backend.h"
 
 #define NPCM750_EVB_POWER_ON_STRAPS 0x1ff7
 #define QUANTA_GSJ_POWER_ON_STRAPS 0x1fff
@@ -81,6 +84,22 @@ static void npcm7xx_connect_dram(NPCM7xxState *soc, 
MemoryRegion *dram)
  _abort);
 }
 
+static void sdhci_attach_drive(SDHCIState *sdhci)
+{
+DriveInfo *di = drive_get_next(IF_SD);
+BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
+
+BusState *bus = qdev_get_child_bus(DEVICE(sdhci), "sd-bus");
+if (bus == NULL) {
+error_report("No SD bus found in SOC object");
+exit(1);
+}
+
+DeviceState *carddev = qdev_new(TYPE_SD_CARD);
+qdev_prop_set_drive_err(carddev, "drive", blk, _fatal);
+qdev_realize_and_unref(carddev, bus, _fatal);
+}
+
 static NPCM7xxState *npcm7xx_create_soc(MachineState *machine,
 uint32_t hw_straps)
 {
@@ -355,6 +374,7 @@ static void quanta_gbs_init(MachineState *machine)
   drive_get(IF_MTD, 0, 0));
 
 quanta_gbs_i2c_init(soc);
+sdhci_attach_drive(>mmc.sdhci);
 npcm7xx_load_kernel(machine, soc);
 }
 
-- 
2.25.1




[PULL 04/12] tests/qtest/libqos: add SDHCI commands

2021-11-02 Thread Richard Henderson
From: Shengtan Mao 

Signed-off-by: Shengtan Mao 
Signed-off-by: Hao Wu 
Reviewed-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Tyrone Ting 
Reviewed-by: Peter Maydell 
Message-Id: <20211008002628.1958285-5-wuhao...@google.com>
Signed-off-by: Richard Henderson 
---
 tests/qtest/libqos/sdhci-cmd.h |  70 
 tests/qtest/libqos/sdhci-cmd.c | 116 +
 tests/qtest/libqos/meson.build |   1 +
 3 files changed, 187 insertions(+)
 create mode 100644 tests/qtest/libqos/sdhci-cmd.h
 create mode 100644 tests/qtest/libqos/sdhci-cmd.c

diff --git a/tests/qtest/libqos/sdhci-cmd.h b/tests/qtest/libqos/sdhci-cmd.h
new file mode 100644
index 00..64763c5a2a
--- /dev/null
+++ b/tests/qtest/libqos/sdhci-cmd.h
@@ -0,0 +1,70 @@
+/*
+ * MMC Host Controller Commands
+ *
+ * Copyright (c) 2021 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "libqtest.h"
+
+/* more details at hw/sd/sdhci-internal.h */
+#define SDHC_BLKSIZE 0x04
+#define SDHC_BLKCNT 0x06
+#define SDHC_ARGUMENT 0x08
+#define SDHC_TRNMOD 0x0C
+#define SDHC_CMDREG 0x0E
+#define SDHC_BDATA 0x20
+#define SDHC_PRNSTS 0x24
+#define SDHC_BLKGAP 0x2A
+#define SDHC_CLKCON 0x2C
+#define SDHC_SWRST 0x2F
+#define SDHC_CAPAB 0x40
+#define SDHC_MAXCURR 0x48
+#define SDHC_HCVER 0xFE
+
+/* TRNSMOD Reg */
+#define SDHC_TRNS_BLK_CNT_EN 0x0002
+#define SDHC_TRNS_READ 0x0010
+#define SDHC_TRNS_WRITE 0x
+#define SDHC_TRNS_MULTI 0x0020
+
+/* CMD Reg */
+#define SDHC_CMD_DATA_PRESENT (1 << 5)
+#define SDHC_ALL_SEND_CID (2 << 8)
+#define SDHC_SEND_RELATIVE_ADDR (3 << 8)
+#define SDHC_SELECT_DESELECT_CARD (7 << 8)
+#define SDHC_SEND_CSD (9 << 8)
+#define SDHC_STOP_TRANSMISSION (12 << 8)
+#define SDHC_READ_MULTIPLE_BLOCK (18 << 8)
+#define SDHC_WRITE_MULTIPLE_BLOCK (25 << 8)
+#define SDHC_APP_CMD (55 << 8)
+
+/* SWRST Reg */
+#define SDHC_RESET_ALL 0x01
+
+/* CLKCTRL Reg */
+#define SDHC_CLOCK_INT_EN 0x0001
+#define SDHC_CLOCK_INT_STABLE 0x0002
+#define SDHC_CLOCK_SDCLK_EN (1 << 2)
+
+/* Set registers needed to send commands to SD */
+void sdhci_cmd_regs(QTestState *qts, uint64_t base_addr, uint16_t blksize,
+uint16_t blkcnt, uint32_t argument, uint16_t trnmod,
+uint16_t cmdreg);
+
+/* Read at most 1 block of SD using non-DMA  */
+ssize_t sdhci_read_cmd(QTestState *qts, uint64_t base_addr, char *msg,
+   size_t count);
+
+/* Write at most 1 block of SD using non-DMA  */
+void sdhci_write_cmd(QTestState *qts, uint64_t base_addr, const char *msg,
+ size_t count, size_t blksize);
diff --git a/tests/qtest/libqos/sdhci-cmd.c b/tests/qtest/libqos/sdhci-cmd.c
new file mode 100644
index 00..2d9e518341
--- /dev/null
+++ b/tests/qtest/libqos/sdhci-cmd.c
@@ -0,0 +1,116 @@
+/*
+ * MMC Host Controller Commands
+ *
+ * Copyright (c) 2021 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "sdhci-cmd.h"
+#include "libqtest.h"
+
+static ssize_t read_fifo(QTestState *qts, uint64_t reg, char *msg, size_t 
count)
+{
+uint32_t mask = 0xff;
+size_t index = 0;
+uint32_t msg_frag;
+int size;
+while (index < count) {
+size = count - index;
+if (size > 4) {
+size = 4;
+}
+msg_frag = qtest_readl(qts, reg);
+while (size > 0) {
+msg[index] = msg_frag & mask;
+if (msg[index++] == 0) {
+return index;
+}
+msg_frag >>= 8;
+--size;
+}
+}
+return index;
+}
+
+static void write_fifo(QTestState *qts, uint64_t reg, const char *msg,
+   size_t count)
+{
+size_t index = 0;
+uint32_t msg_frag;
+int size;
+int frag_i;
+while (index < count) {
+size = count - index;
+if (size > 4) {
+size = 4;
+}
+msg_frag = 0;
+frag_i = 0;
+while (frag_i < size) {
+msg_frag |= ((uint32_t)msg[index++]) << (frag_i * 8);
+++frag_i;

[PULL 06/12] target/arm: Advertise MVE to gdb when present

2021-11-02 Thread Richard Henderson
From: Peter Maydell 

Cortex-M CPUs with MVE should advertise this fact to gdb, using the
org.gnu.gdb.arm.m-profile-mve XML feature, which defines the VPR
register.  Presence of this feature also tells gdb to create
pseudo-registers Q0..Q7, so we do not need to tell gdb about them
separately.

Note that unless you have a very recent GDB that includes this fix:
http://patches-tcwg.linaro.org/patch/58133/ gdb will mis-print the
individual fields of the VPR register as zero (but showing the whole
thing as hex, eg with "print /x $vpr" will give the correct value).

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20211101160814.5103-1-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 configs/targets/aarch64-softmmu.mak  |  2 +-
 configs/targets/arm-linux-user.mak   |  2 +-
 configs/targets/arm-softmmu.mak  |  2 +-
 configs/targets/armeb-linux-user.mak |  2 +-
 target/arm/gdbstub.c | 25 +
 gdb-xml/arm-m-profile-mve.xml| 19 +++
 6 files changed, 48 insertions(+), 4 deletions(-)
 create mode 100644 gdb-xml/arm-m-profile-mve.xml

diff --git a/configs/targets/aarch64-softmmu.mak 
b/configs/targets/aarch64-softmmu.mak
index 13d40b55e6..d489e6da83 100644
--- a/configs/targets/aarch64-softmmu.mak
+++ b/configs/targets/aarch64-softmmu.mak
@@ -1,5 +1,5 @@
 TARGET_ARCH=aarch64
 TARGET_BASE_ARCH=arm
 TARGET_SUPPORTS_MTTCG=y
-TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml 
gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml 
gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml
+TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml 
gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml 
gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml 
gdb-xml/arm-m-profile-mve.xml
 TARGET_NEED_FDT=y
diff --git a/configs/targets/arm-linux-user.mak 
b/configs/targets/arm-linux-user.mak
index acecc339e3..3e10d6b15d 100644
--- a/configs/targets/arm-linux-user.mak
+++ b/configs/targets/arm-linux-user.mak
@@ -1,6 +1,6 @@
 TARGET_ARCH=arm
 TARGET_SYSTBL_ABI=common,oabi
 TARGET_SYSTBL=syscall.tbl
-TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml 
gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml 
gdb-xml/arm-m-profile.xml
+TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml 
gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml 
gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml
 TARGET_HAS_BFLT=y
 CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
diff --git a/configs/targets/arm-softmmu.mak b/configs/targets/arm-softmmu.mak
index f6c95ba07a..92c8349b96 100644
--- a/configs/targets/arm-softmmu.mak
+++ b/configs/targets/arm-softmmu.mak
@@ -1,4 +1,4 @@
 TARGET_ARCH=arm
 TARGET_SUPPORTS_MTTCG=y
-TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml 
gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml 
gdb-xml/arm-m-profile.xml
+TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml 
gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml 
gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml
 TARGET_NEED_FDT=y
diff --git a/configs/targets/armeb-linux-user.mak 
b/configs/targets/armeb-linux-user.mak
index 662c73d8fb..f81e5bf1fe 100644
--- a/configs/targets/armeb-linux-user.mak
+++ b/configs/targets/armeb-linux-user.mak
@@ -2,6 +2,6 @@ TARGET_ARCH=arm
 TARGET_SYSTBL_ABI=common,oabi
 TARGET_SYSTBL=syscall.tbl
 TARGET_WORDS_BIGENDIAN=y
-TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml 
gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml 
gdb-xml/arm-m-profile.xml
+TARGET_XML_FILES= gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml 
gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml 
gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml
 TARGET_HAS_BFLT=y
 CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
index e0dcb33e32..134da0d0ae 100644
--- a/target/arm/gdbstub.c
+++ b/target/arm/gdbstub.c
@@ -199,6 +199,27 @@ static int vfp_gdb_set_sysreg(CPUARMState *env, uint8_t 
*buf, int reg)
 return 0;
 }
 
+static int mve_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
+{
+switch (reg) {
+case 0:
+return gdb_get_reg32(buf, env->v7m.vpr);
+default:
+return 0;
+}
+}
+
+static int mve_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
+{
+switch (reg) {
+case 0:
+env->v7m.vpr = ldl_p(buf);
+return 4;
+default:
+return 0;
+}
+}
+
 /**
  * arm_get/set_gdb_*: get/set a gdb register
  * @env: the CPU state
@@ -468,6 +489,10 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
  2, "arm-vfp-sysregs.xml", 0);
 }
 }
+if (cpu_isar_feature(aa32_mve, cpu)) {
+gdb_register_coprocessor(cs, mve_gdb_get_reg, 

[PULL 00/12] target/arm patch queue

2021-11-02 Thread Richard Henderson
The following changes since commit dd61b91c080cdfba1360a5ea1e4693fffb3445b0:

  Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-10-29' into 
staging (2021-10-29 19:42:36 -0700)

are available in the Git repository at:

  https://gitlab.com/rth7680/qemu.git tags/pull-arm-20211102

for you to fetch changes up to 1d3e21e25399367714518d389f3cbc956d27dddf:

  hw/arm/virt: Rename default_bus_bypass_iommu (2021-11-01 13:45:26 -0400)


Add nuvoton sd module for NPCM7XX
Add gdb-xml for MVE
More uses of tcg_constant_* in target/arm
Fix parameter naming for default-bus-bypass-iommu


Jean-Philippe Brucker (1):
  hw/arm/virt: Rename default_bus_bypass_iommu

Peter Maydell (1):
  target/arm: Advertise MVE to gdb when present

Philippe Mathieu-Daudé (5):
  target/arm: Use tcg_constant_i32() in op_smlad()
  target/arm: Introduce store_cpu_field_constant() helper
  target/arm: Use the constant variant of store_cpu_field() when possible
  target/arm: Use tcg_constant_i64() in do_sat_addsub_64()
  target/arm: Use tcg_constant_i32() in gen_rev16()

Shengtan Mao (5):
  hw/sd: add nuvoton MMC
  hw/arm: Add Nuvoton SD module to board
  hw/arm: Attach MMC to quanta-gbs-bmc
  tests/qtest/libqos: add SDHCI commands
  tests/qtest: add qtests for npcm7xx sdhci

 configs/targets/aarch64-softmmu.mak  |   2 +-
 configs/targets/arm-linux-user.mak   |   2 +-
 configs/targets/arm-softmmu.mak  |   2 +-
 configs/targets/armeb-linux-user.mak |   2 +-
 include/hw/arm/npcm7xx.h |   2 +
 include/hw/sd/npcm7xx_sdhci.h|  65 +++
 target/arm/translate-a32.h   |   3 +
 tests/qtest/libqos/sdhci-cmd.h   |  70 
 hw/arm/npcm7xx.c |  12 +-
 hw/arm/npcm7xx_boards.c  |  20 
 hw/arm/virt.c|   4 +-
 hw/sd/npcm7xx_sdhci.c| 182 ++
 target/arm/gdbstub.c |  25 +
 target/arm/translate-sve.c   |  17 ++-
 target/arm/translate.c   |  27 ++---
 tests/qtest/libqos/sdhci-cmd.c   | 116 +++
 tests/qtest/npcm7xx_sdhci-test.c | 209 +++
 gdb-xml/arm-m-profile-mve.xml|  19 
 hw/sd/meson.build|   1 +
 tests/qtest/libqos/meson.build   |   1 +
 tests/qtest/meson.build  |   1 +
 21 files changed, 747 insertions(+), 35 deletions(-)
 create mode 100644 include/hw/sd/npcm7xx_sdhci.h
 create mode 100644 tests/qtest/libqos/sdhci-cmd.h
 create mode 100644 hw/sd/npcm7xx_sdhci.c
 create mode 100644 tests/qtest/libqos/sdhci-cmd.c
 create mode 100644 tests/qtest/npcm7xx_sdhci-test.c
 create mode 100644 gdb-xml/arm-m-profile-mve.xml



[PULL 05/12] tests/qtest: add qtests for npcm7xx sdhci

2021-11-02 Thread Richard Henderson
From: Shengtan Mao 

Signed-off-by: Shengtan Mao 
Signed-off-by: Hao Wu 
Reviewed-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Tyrone Ting 
Reviewed-by: Peter Maydell 
Message-Id: <20211008002628.1958285-6-wuhao...@google.com>
Signed-off-by: Richard Henderson 
---
 tests/qtest/npcm7xx_sdhci-test.c | 209 +++
 tests/qtest/meson.build  |   1 +
 2 files changed, 210 insertions(+)
 create mode 100644 tests/qtest/npcm7xx_sdhci-test.c

diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c
new file mode 100644
index 00..a6732f657d
--- /dev/null
+++ b/tests/qtest/npcm7xx_sdhci-test.c
@@ -0,0 +1,209 @@
+/*
+ * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller
+ *
+ * Copyright (c) 2021 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sd/npcm7xx_sdhci.h"
+
+#include "libqos/libqtest.h"
+#include "libqtest-single.h"
+#include "libqos/sdhci-cmd.h"
+
+#define NPCM7XX_MMC_BA 0xF0842000
+#define NPCM7XX_BLK_SIZE 512
+#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30)
+
+static char *sd_path;
+
+static QTestState *setup_sd_card(void)
+{
+QTestState *qts = qtest_initf(
+"-machine quanta-gbs-bmc "
+"-device sd-card,drive=drive0 "
+"-drive id=drive0,if=none,file=%s,format=raw,auto-read-only=off",
+sd_path);
+
+qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_SWRST, SDHC_RESET_ALL);
+qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_CLKCON,
+ SDHC_CLOCK_SDCLK_EN | SDHC_CLOCK_INT_STABLE |
+ SDHC_CLOCK_INT_EN);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_APP_CMD);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x4120, 0, (41 << 8));
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_ALL_SEND_CID);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_SEND_RELATIVE_ADDR);
+sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x4567, 0,
+   SDHC_SELECT_DESELECT_CARD);
+
+return qts;
+}
+
+static void write_sdread(QTestState *qts, const char *msg)
+{
+size_t len = strlen(msg);
+char *rmsg = g_malloc(len);
+
+/* write message to sd */
+int fd = open(sd_path, O_WRONLY);
+int ret;
+
+g_assert(fd > 0);
+ret = write(fd, msg, len);
+g_assert(ret == len);
+ret = close(fd);
+g_assert(ret == 0);
+
+/* read message using sdhci */
+ret = sdhci_read_cmd(qts, NPCM7XX_MMC_BA, rmsg, len);
+g_assert(ret == len);
+g_assert(!strcmp(rmsg, msg));
+
+free(rmsg);
+}
+
+/* Check MMC can read values from sd */
+static void test_read_sd(void)
+{
+QTestState *qts = setup_sd_card();
+
+write_sdread(qts, "hello world");
+write_sdread(qts, "goodbye");
+
+qtest_quit(qts);
+}
+
+static void sdwrite_read(QTestState *qts, const char *msg)
+{
+size_t len = strlen(msg);
+char *rmsg = g_malloc(len);
+
+/* write message using sdhci */
+sdhci_write_cmd(qts, NPCM7XX_MMC_BA, msg, len, NPCM7XX_BLK_SIZE);
+
+/* read message from sd */
+int fd = open(sd_path, O_RDONLY);
+int ret;
+
+g_assert(fd > 0);
+ret = read(fd, rmsg, len);
+g_assert(ret == len);
+ret = close(fd);
+g_assert(ret == 0);
+
+g_assert(!strcmp(rmsg, msg));
+
+free(rmsg);
+}
+
+/* Check MMC can write values to sd */
+static void test_write_sd(void)
+{
+QTestState *qts = setup_sd_card();
+
+sdwrite_read(qts, "hello world");
+sdwrite_read(qts, "goodbye");
+
+qtest_quit(qts);
+}
+
+/* Check SDHCI has correct default values. */
+static void test_reset(void)
+{
+QTestState *qts = qtest_init("-machine quanta-gbs-bmc");
+
+uint64_t addr = NPCM7XX_MMC_BA;
+uint64_t end_addr = addr + 0x100;
+uint16_t prstvals_resets[] = {NPCM7XX_PRSTVALS_0_RESET,
+  NPCM7XX_PRSTVALS_1_RESET,
+  0,
+  NPCM7XX_PRSTVALS_3_RESET,
+  0,
+  0};
+int i;
+uint32_t mask;
+while (addr < end_addr) {
+switch (addr - NPCM7XX_MMC_BA) {
+case SDHC_PRNSTS:
+/* ignores bits 20 to 24: they are changed when reading registers 
*/
+mask = 0x1f0;
+g_assert_cmphex(qtest_readl(qts, addr) | mask, ==,
+NPCM7XX_PRSNTS_RESET | mask);
+addr += 4;
+break;
+case SDHC_BLKGAP:
+g_assert_cmphex(qtest_readb(qts, addr), ==, 

[PULL 02/12] hw/arm: Add Nuvoton SD module to board

2021-11-02 Thread Richard Henderson
From: Shengtan Mao 

Signed-off-by: Shengtan Mao 
Signed-off-by: Hao Wu 
Reviewed-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Tyrone Ting 
Reviewed-by: Peter Maydell 
Message-Id: <20211008002628.1958285-3-wuhao...@google.com>
Signed-off-by: Richard Henderson 
---
 include/hw/arm/npcm7xx.h |  2 ++
 hw/arm/npcm7xx.c | 12 +++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 61ecc57ab9..ce593235d9 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -35,6 +35,7 @@
 #include "hw/usb/hcd-ehci.h"
 #include "hw/usb/hcd-ohci.h"
 #include "target/arm/cpu.h"
+#include "hw/sd/npcm7xx_sdhci.h"
 
 #define NPCM7XX_MAX_NUM_CPUS(2)
 
@@ -103,6 +104,7 @@ typedef struct NPCM7xxState {
 OHCISysBusState ohci;
 NPCM7xxFIUState fiu[2];
 NPCM7xxEMCState emc[2];
+NPCM7xxSDHCIState   mmc;
 } NPCM7xxState;
 
 #define TYPE_NPCM7XX"npcm7xx"
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 2ab0080e0b..878c2208e0 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -63,6 +63,8 @@
 #define NPCM7XX_ROM_BA  (0x)
 #define NPCM7XX_ROM_SZ  (64 * KiB)
 
+/* SDHCI Modules */
+#define NPCM7XX_MMC_BA  (0xf0842000)
 
 /* Clock configuration values to be fixed up when bypassing bootloader */
 
@@ -83,6 +85,7 @@ enum NPCM7xxInterrupt {
 NPCM7XX_UART3_IRQ,
 NPCM7XX_EMC1RX_IRQ  = 15,
 NPCM7XX_EMC1TX_IRQ,
+NPCM7XX_MMC_IRQ = 26,
 NPCM7XX_TIMER0_IRQ  = 32,   /* Timer Module 0 */
 NPCM7XX_TIMER1_IRQ,
 NPCM7XX_TIMER2_IRQ,
@@ -443,6 +446,8 @@ static void npcm7xx_init(Object *obj)
 for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
 object_initialize_child(obj, "emc[*]", >emc[i], TYPE_NPCM7XX_EMC);
 }
+
+object_initialize_child(obj, "mmc", >mmc, TYPE_NPCM7XX_SDHCI);
 }
 
 static void npcm7xx_realize(DeviceState *dev, Error **errp)
@@ -707,6 +712,12 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
_abort);
 memory_region_add_subregion(get_system_memory(), NPCM7XX_ROM_BA, >irom);
 
+/* SDHCI */
+sysbus_realize(SYS_BUS_DEVICE(>mmc), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(>mmc), 0, NPCM7XX_MMC_BA);
+sysbus_connect_irq(SYS_BUS_DEVICE(>mmc), 0,
+npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
+
 create_unimplemented_device("npcm7xx.shm",  0xc0001000,   4 * KiB);
 create_unimplemented_device("npcm7xx.vdmx", 0xe080,   4 * KiB);
 create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * KiB);
@@ -736,7 +747,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.usbd[8]",  0xf0838000,   4 * KiB);
 create_unimplemented_device("npcm7xx.usbd[9]",  0xf0839000,   4 * KiB);
 create_unimplemented_device("npcm7xx.sd",   0xf084,   8 * KiB);
-create_unimplemented_device("npcm7xx.mmc",  0xf0842000,   8 * KiB);
 create_unimplemented_device("npcm7xx.pcimbx",   0xf0848000, 512 * KiB);
 create_unimplemented_device("npcm7xx.aes",  0xf0858000,   4 * KiB);
 create_unimplemented_device("npcm7xx.des",  0xf0859000,   4 * KiB);
-- 
2.25.1




[PULL 01/12] hw/sd: add nuvoton MMC

2021-11-02 Thread Richard Henderson
From: Shengtan Mao 

Signed-off-by: Shengtan Mao 
Signed-off-by: Hao Wu 
Reviewed-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Tyrone Ting 
Reviewed-by: Peter Maydell 
Message-Id: <20211008002628.1958285-2-wuhao...@google.com>
[rth: Fix typos of "nonexistent"]
Signed-off-by: Richard Henderson 
---
 include/hw/sd/npcm7xx_sdhci.h |  65 
 hw/sd/npcm7xx_sdhci.c | 182 ++
 hw/sd/meson.build |   1 +
 3 files changed, 248 insertions(+)
 create mode 100644 include/hw/sd/npcm7xx_sdhci.h
 create mode 100644 hw/sd/npcm7xx_sdhci.c

diff --git a/include/hw/sd/npcm7xx_sdhci.h b/include/hw/sd/npcm7xx_sdhci.h
new file mode 100644
index 00..d728f0a40d
--- /dev/null
+++ b/include/hw/sd/npcm7xx_sdhci.h
@@ -0,0 +1,65 @@
+/*
+ * NPCM7xx SD-3.0 / eMMC-4.51 Host Controller
+ *
+ * Copyright (c) 2021 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef NPCM7XX_SDHCI_H
+#define NPCM7XX_SDHCI_H
+
+#include "hw/sd/sdhci.h"
+#include "qom/object.h"
+
+#define TYPE_NPCM7XX_SDHCI "npcm7xx.sdhci"
+#define NPCM7XX_PRSTVALS_SIZE 6
+#define NPCM7XX_PRSTVALS 0x60
+#define NPCM7XX_PRSTVALS_0 0x0
+#define NPCM7XX_PRSTVALS_1 0x2
+#define NPCM7XX_PRSTVALS_2 0x4
+#define NPCM7XX_PRSTVALS_3 0x6
+#define NPCM7XX_PRSTVALS_4 0x8
+#define NPCM7XX_PRSTVALS_5 0xA
+#define NPCM7XX_BOOTTOCTRL 0x10
+#define NPCM7XX_SDHCI_REGSIZE 0x20
+
+#define NPCM7XX_PRSNTS_RESET 0x04A0
+#define NPCM7XX_BLKGAP_RESET 0x80
+#define NPCM7XX_CAPAB_RESET 0x0100200161EE0399
+#define NPCM7XX_MAXCURR_RESET 0x0005
+#define NPCM7XX_HCVER_RESET 0x1002
+
+#define NPCM7XX_PRSTVALS_0_RESET 0x0040
+#define NPCM7XX_PRSTVALS_1_RESET 0x0001
+#define NPCM7XX_PRSTVALS_3_RESET 0x0001
+
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxSDHCIState, NPCM7XX_SDHCI)
+
+typedef struct NPCM7xxRegs {
+/* Preset Values Register Field, read-only */
+uint16_t prstvals[NPCM7XX_PRSTVALS_SIZE];
+/* Boot Timeout Control Register, read-write */
+uint32_t boottoctrl;
+} NPCM7xxRegisters;
+
+typedef struct NPCM7xxSDHCIState {
+SysBusDevice parent;
+
+MemoryRegion container;
+MemoryRegion iomem;
+BusState *bus;
+NPCM7xxRegisters regs;
+
+SDHCIState sdhci;
+} NPCM7xxSDHCIState;
+
+#endif /* NPCM7XX_SDHCI_H */
diff --git a/hw/sd/npcm7xx_sdhci.c b/hw/sd/npcm7xx_sdhci.c
new file mode 100644
index 00..ef503365df
--- /dev/null
+++ b/hw/sd/npcm7xx_sdhci.c
@@ -0,0 +1,182 @@
+/*
+ * NPCM7xx SD-3.0 / eMMC-4.51 Host Controller
+ *
+ * Copyright (c) 2021 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/sd/npcm7xx_sdhci.h"
+#include "migration/vmstate.h"
+#include "sdhci-internal.h"
+#include "qemu/log.h"
+
+static uint64_t npcm7xx_sdhci_read(void *opaque, hwaddr addr, unsigned int 
size)
+{
+NPCM7xxSDHCIState *s = opaque;
+uint64_t val = 0;
+
+switch (addr) {
+case NPCM7XX_PRSTVALS_0:
+case NPCM7XX_PRSTVALS_1:
+case NPCM7XX_PRSTVALS_2:
+case NPCM7XX_PRSTVALS_3:
+case NPCM7XX_PRSTVALS_4:
+case NPCM7XX_PRSTVALS_5:
+val = s->regs.prstvals[(addr - NPCM7XX_PRSTVALS_0) / 2];
+break;
+case NPCM7XX_BOOTTOCTRL:
+val = s->regs.boottoctrl;
+break;
+default:
+qemu_log_mask(LOG_GUEST_ERROR, "SDHCI read of nonexistent reg: 0x%02"
+  HWADDR_PRIx, addr);
+break;
+}
+
+return val;
+}
+
+static void npcm7xx_sdhci_write(void *opaque, hwaddr addr, uint64_t val,
+unsigned int size)
+{
+NPCM7xxSDHCIState *s = opaque;
+
+switch (addr) {
+case NPCM7XX_BOOTTOCTRL:
+s->regs.boottoctrl = val;
+break;
+default:
+qemu_log_mask(LOG_GUEST_ERROR, "SDHCI write of nonexistent reg: 0x%02"
+  HWADDR_PRIx, addr);
+break;
+}
+}
+
+static bool npcm7xx_sdhci_check_mem_op(void *opaque, hwaddr addr,
+   unsigned size, bool is_write,
+   MemTxAttrs attrs)
+{

[PATCH v2] meson.build: Allow to disable OSS again

2021-11-02 Thread Thomas Huth
If sys/soundcard.h is available, it is currently not possible to
disable OSS with the --disable-oss or --without-default-features
configure switches. Improve the check in meson.build to fix this.

Fixes: 87430d5b13 ("configure, meson: move audio driver detection to Meson")
Signed-off-by: Thomas Huth 
---
 v2: Only ever look for OSS if we also have system emulation enabled

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 6dec5dd5cc..2848917602 100644
--- a/meson.build
+++ b/meson.build
@@ -915,7 +915,7 @@ if liblzfse.found() and not cc.links('''
 endif
 
 oss = not_found
-if not get_option('oss').auto() or have_system
+if have_system and not get_option('oss').disabled()
   if not cc.has_header('sys/soundcard.h')
 # not found
   elif targetos == 'netbsd'
-- 
2.27.0




Re: [PATCH 0/3] SEV: fixes for -kernel launch with incompatible OVMF

2021-11-02 Thread Brijesh Singh
Hi Dov,

Overall the patch looks good, only question I have is that now we are
enforce qemu to hash the kernel, initrd and cmdline unconditionally for
any of the SEV guest launches. This requires anyone wanting to
calculating the expected measurement need to account for it. Should we
make the hash page build optional ?

I am thinking this more for the SEV-SNP guest. As you may be aware that
with SEV-SNP the attestation is performed by the guest, and its possible
for the launch flow to pass 512-bits of host_data that gets included in
the report. If a user wants to do the hash'e checks for the SNP then
they can pass a hash of kernel, initrd and cmdline through a
launch_finish.ID_BLOCK.host_data and does not require a special hash
page. This it will simplify the expected hash calculation. Adding a
special page requires a validation of that page. All the prevalidated
page need to be excluded by guest BIOS page validation flow to avoid the
double validation. The hash page is populated only when we pass -kernel
and it will be tricky to communicate this information to the guest BIOS
so that it can skip the validation.

Thoughts ?

thanks

On 11/1/21 5:21 AM, Dov Murik wrote:
> Tom Lendacky and Brijesh Singh reported two issues with launching SEV
> guests with the -kernel QEMU option when an old [1] or wrongly configured [2]
> OVMF images are used.
>
> The fixes in patches 1 and 2 allow such guests to boot by skipping the
> kernel/initrd/cmdline hashes addition to the initial guest memory (and
> warning the user).
>
> Patch 3 is a refactoring of parts of the same function
> sev_add_kernel_loader_hashes() to calculate all padding sizes at
> compile-time.  This patch is not required to fix the issues above, but
> is suggested as an improvement (no functional change intended).
>
> Note that launch measurement security is not harmed by these fixes: a
> Guest Owner that wants to use measured Linux boot with -kernel, must use
> (and measure) an OVMF image that designates a proper hashes table area,
> and that verifies those hashes when loading the binaries from QEMU via
> fw_cfg.
>
> The old OVMFs which don't publish the hashes table GUID or don't reserve
> a valid area for it in MEMFD cannot support these hashes verification in
> any case (for measured boot with -kernel).
>
>
> [1] 
> https://lore.kernel.org/qemu-devel/3b9d10d9-5d9c-da52-f18c-cd93c1931...@amd.com/
> [2] 
> https://lore.kernel.org/qemu-devel/001dd81a-282d-c307-a657-e228480d4...@amd.com/
>
> Dov Murik (3):
>   sev/i386: Allow launching with -kernel if no OVMF hashes table found
>   sev/i386: Warn if using -kernel with invalid OVMF hashes table area
>   sev/i386: Perform padding calculations at compile-time
>
>  target/i386/sev.c | 34 +++---
>  1 file changed, 23 insertions(+), 11 deletions(-)
>
>
> base-commit: af531756d25541a1b3b3d9a14e72e7fedd941a2e



Re: [RFC PATCH 07/15] job-driver.h: add helper functions

2021-11-02 Thread Vladimir Sementsov-Ogievskiy

29.10.2021 19:39, Emanuele Giuseppe Esposito wrote:

These functions will be useful when job_lock is globally applied,
as they will allow drivers to access the job struct fields
without worrying about the job lock.

Now that we are done with the job API header split, update also
the comments in blockjob.c (and move them in job.c).

Signed-off-by: Emanuele Giuseppe Esposito 
---
  include/qemu/job-driver.h |  21 +++
  blockjob.c|  20 ---
  job.c | 116 +-
  3 files changed, 135 insertions(+), 22 deletions(-)

diff --git a/include/qemu/job-driver.h b/include/qemu/job-driver.h
index 1efd196da8..19ae5ce8f0 100644
--- a/include/qemu/job-driver.h
+++ b/include/qemu/job-driver.h
@@ -149,4 +149,25 @@ void job_early_fail(Job *job);
  /** Moves the @job from RUNNING to READY */
  void job_transition_to_ready(Job *job);
  
+/** Enters the @job if it is not paused */

+void job_enter_not_paused(Job *job);
+
+/** returns @job->ret */
+bool job_has_failed(Job *job);
+
+/** Returns the @job->status */
+JobStatus job_get_status(Job *job);
+
+/** Returns the @job->pause_count */
+int job_get_pause_count(Job *job);
+
+/** Returns @job->paused */
+bool job_get_paused(Job *job);
+
+/** Returns @job->busy */
+bool job_get_busy(Job *job);
+
+/** Return true if @job not paused and not cancelled */
+bool job_not_paused_nor_cancelled(Job *job);
+
  #endif /* JOB_DRIVER_H */
diff --git a/blockjob.c b/blockjob.c
index 4982f6a2b5..53c1e9c406 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -36,21 +36,6 @@
  #include "qemu/main-loop.h"
  #include "qemu/timer.h"
  
-/*

- * The block job API is composed of two categories of functions.
- *
- * The first includes functions used by the monitor.  The monitor is
- * peculiar in that it accesses the block job list with block_job_get, and
- * therefore needs consistency across block_job_get and the actual operation
- * (e.g. block_job_set_speed).  The consistency is achieved with
- * aio_context_acquire/release.  These functions are declared in blockjob.h.
- *
- * The second includes functions used by the block job drivers and sometimes
- * by the core block layer.  These do not care about locking, because the
- * whole coroutine runs under the AioContext lock, and are declared in
- * blockjob_int.h.
- */
-
  static bool is_block_job(Job *job)
  {
  return job_type(job) == JOB_TYPE_BACKUP ||
@@ -433,11 +418,6 @@ static void block_job_event_ready(Notifier *n, void 
*opaque)
  }
  
  
-/*

- * API for block job drivers and the block layer.  These functions are
- * declared in blockjob_int.h.
- */
-
  void *block_job_create(const char *job_id, const BlockJobDriver *driver,
 JobTxn *txn, BlockDriverState *bs, uint64_t perm,
 uint64_t shared_perm, int64_t speed, int flags,
diff --git a/job.c b/job.c
index b66d59b746..db7ad79745 100644
--- a/job.c
+++ b/job.c
@@ -32,6 +32,23 @@
  #include "trace/trace-root.h"
  #include "qapi/qapi-events-job.h"
  
+/*

+ * The job API is composed of two categories of functions.
+ *
+ * The first includes functions used by the monitor.  The monitor is
+ * peculiar in that it accesses the block job list with job_get, and
+ * therefore needs consistency across job_get and the actual operation
+ * (e.g. job_user_cancel). To achieve this consistency, the caller
+ * calls job_lock/job_unlock itself around the whole operation.
+ * These functions are declared in job-monitor.h.
+ *
+ *
+ * The second includes functions used by the block job drivers and sometimes
+ * by the core block layer. These delegate the locking to the callee instead,
+ * and are declared in job-driver.h.
+ */
+
+
  /* job_mutex protects the jobs list, but also makes the job API thread-safe. 
*/
  static QemuMutex job_mutex;
  
@@ -213,18 +230,94 @@ const char *job_type_str(const Job *job)

  return JobType_str(job_type(job));
  }
  
-bool job_is_cancelled(Job *job)

+JobStatus job_get_status(Job *job)
+{
+JobStatus status;
+job_lock();
+status = job->status;
+job_unlock();
+return status;
+}


Didn't you consider implementing a kind of QEMU_LOCK_GUARD() / 
WITH_QEMU_LOCK_GUARD context manager? This will simplify these helpers a lot, 
to just two line functions, like:

JobStatute job_get_status(Job *job)
{
   JOB_LOCK_GUARD();
   return status;
}



--
Best regards,
Vladimir



Re: [PATCH v2 0/4] hw/usb/vt82c686-uhci-pci: Use ISA instead of PCI interrupts

2021-11-02 Thread BALATON Zoltan

Hello,

On Mon, 25 Oct 2021, Philippe Mathieu-Daudé wrote:

On 10/25/21 13:33, BALATON Zoltan wrote:

This is the same as posted before just omitting the two patches that
are optimisations by caching the func0 and avoiding QOM casts which
could not be measured to have an effect but these reamaining patches
are still needed to fix USB interrupts on pegasos2

Gerd, could you please take them?

Regards,

BALATON Zoltan (4):
  usb/uhci: Misc clean up
  usb/uhci: Disallow user creating a vt82c686-uhci-pci device
  usb/uhci: Replace pci_set_irq with qemu_set_irq
  hw/usb/vt82c686-uhci-pci: Use ISA instead of PCI interrupts


Thanks, series applied to mips-next tree.


According to https://wiki.qemu.org/Planning/6.2 freeze starts today and I 
haven't yet seen a pull request with this series. Is it still to come? (As 
it is fixing a bug with USB IRQ it may be OK before hard freeze but to be 
safe I'm asking now to avoid missing a release and having to wait months 
to get it merged).


Thank you,
BALATON Zoltan

Re: [RFC PATCH 08/15] job.c: minor adjustments in preparation to job-driver

2021-11-02 Thread Vladimir Sementsov-Ogievskiy

29.10.2021 19:39, Emanuele Giuseppe Esposito wrote:

job_event_* functions can be all static, as they are not used
outside job.c

Add also missing notifier initialization for the on_idle
list in job_create().

Signed-off-by: Emanuele Giuseppe Esposito 
---
  job.c | 13 +++--
  1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/job.c b/job.c
index db7ad79745..88d911f2d7 100644
--- a/job.c
+++ b/job.c
@@ -464,6 +464,7 @@ void *job_create(const char *job_id, const JobDriver 
*driver, JobTxn *txn,
  notifier_list_init(>on_finalize_completed);
  notifier_list_init(>on_pending);
  notifier_list_init(>on_ready);
+notifier_list_init(>on_idle);


Is that a bug fix? I think it worth small separate patch.

  
  job_state_transition(job, JOB_STATUS_CREATED);

  aio_timer_init(qemu_get_aio_context(), >sleep_timer,
@@ -527,12 +528,20 @@ void job_progress_increase_remaining(Job *job, uint64_t 
delta)
  progress_increase_remaining(>progress, delta);
  }
  
-void job_event_cancelled(Job *job)

+/**
+ * To be called when a cancelled job is finalised.
+ * Called with job_mutex held.
+ */
+static void job_event_cancelled(Job *job)
  {
  notifier_list_notify(>on_finalize_cancelled, job);
  }
  
-void job_event_completed(Job *job)

+/**
+ * To be called when a successfully completed job is finalised.
+ * Called with job_mutex held.
+ */
+static void job_event_completed(Job *job)
  {
  notifier_list_notify(>on_finalize_completed, job);
  }




--
Best regards,
Vladimir



Re: [PATCH v4 02/22] target/riscv: Implement SGEIP bit in hip and hie CSRs

2021-11-02 Thread Bin Meng
On Tue, Nov 2, 2021 at 6:24 PM Anup Patel  wrote:
>
> On Tue, Nov 2, 2021 at 12:22 PM Bin Meng  wrote:
> >
> > On Tue, Oct 26, 2021 at 2:43 PM Anup Patel  wrote:
> > >
> > > A hypervsior can optionally take guest external interrupts using
> >
> > typo: hypervisor
>
> Okay, I will update.
>
> >
> > > SGEIP bit of hip and hie CSRs.
> > >
> > > Signed-off-by: Anup Patel 
> > > Reviewed-by: Alistair Francis 
> > > ---
> > >  target/riscv/cpu.c  |  3 ++-
> > >  target/riscv/cpu_bits.h |  3 +++
> > >  target/riscv/csr.c  | 18 +++---
> > >  3 files changed, 16 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > > index 788fa0b11c..0460a3972b 100644
> > > --- a/target/riscv/cpu.c
> > > +++ b/target/riscv/cpu.c
> > > @@ -365,6 +365,7 @@ static void riscv_cpu_reset(DeviceState *dev)
> > >  env->mstatus = set_field(env->mstatus, MSTATUS64_UXL, 
> > > env->misa_mxl);
> > >  }
> > >  env->mcause = 0;
> > > +env->miclaim = MIP_SGEIP;
> > >  env->pc = env->resetvec;
> > >  env->two_stage_lookup = false;
> > >  #endif
> > > @@ -598,7 +599,7 @@ static void riscv_cpu_init(Object *obj)
> > >  cpu_set_cpustate_pointers(cpu);
> > >
> > >  #ifndef CONFIG_USER_ONLY
> > > -qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, 12);
> > > +qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, IRQ_LOCAL_MAX);
> > >  #endif /* CONFIG_USER_ONLY */
> > >  }
> > >
> > > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > > index cffcd3a5df..8a5a4cde95 100644
> > > --- a/target/riscv/cpu_bits.h
> > > +++ b/target/riscv/cpu_bits.h
> > > @@ -498,6 +498,8 @@ typedef enum RISCVException {
> > >  #define IRQ_S_EXT  9
> > >  #define IRQ_VS_EXT 10
> > >  #define IRQ_M_EXT  11
> > > +#define IRQ_S_GEXT 12
> > > +#define IRQ_LOCAL_MAX  13
> >
> > The IRQ_LOCAL_MAX should be XLEN long, not 13.
>
> The IRQ_LOCAL_MAX here represents local interrupts
> standardized by the RISC-V privilege spec. This value

The standardardized IRQ number is 16.

> will change only when more local interrupts are
> standardized by the RISC-V privilege spec.

We should leave room for platform / custom IRQ as it is already
defined by the priv spec.

Regards,
Bin



Re: [PATCH 2/2] qtest/am53c974-test: add test for cancelling in-flight requests

2021-11-02 Thread Paolo Bonzini

On 01/11/21 19:35, Mark Cave-Ayland wrote:

Based upon the qtest reproducer posted to Gitlab issue #663 at
https://gitlab.com/qemu-project/qemu/-/issues/663.

Signed-off-by: Mark Cave-Ayland 
---
  tests/qtest/am53c974-test.c | 36 
  1 file changed, 36 insertions(+)

diff --git a/tests/qtest/am53c974-test.c b/tests/qtest/am53c974-test.c
index d996866cd4..9b1e4211bd 100644
--- a/tests/qtest/am53c974-test.c
+++ b/tests/qtest/am53c974-test.c
@@ -189,6 +189,40 @@ static void test_cancelled_request_ok(void)
  qtest_quit(s);
  }
  
+static void test_inflight_cancel_ok(void)

+{
+QTestState *s = qtest_init(
+"-device am53c974,id=scsi "
+"-device scsi-hd,drive=disk0 -drive "
+"id=disk0,if=none,file=null-co://,format=raw -nodefaults");
+qtest_outl(s, 0xcf8, 0x80001000);
+qtest_inw(s, 0xcfc);
+qtest_outl(s, 0xcf8, 0x80001010);
+qtest_outl(s, 0xcfc, 0x);
+qtest_outl(s, 0xcf8, 0x80001010);
+qtest_inl(s, 0xcfc);
+qtest_outl(s, 0xcf8, 0x80001010);
+qtest_outl(s, 0xcfc, 0xc001);
+qtest_outl(s, 0xcf8, 0x80001004);
+qtest_inw(s, 0xcfc);
+qtest_outl(s, 0xcf8, 0x80001004);
+qtest_outw(s, 0xcfc, 0x7);
+qtest_outl(s, 0xcf8, 0x80001004);
+qtest_inw(s, 0xcfc);
+qtest_inb(s, 0xc000);
+qtest_outb(s, 0xc008, 0x8);
+qtest_outw(s, 0xc00b, 0x4100);
+qtest_outb(s, 0xc009, 0x0);
+qtest_outb(s, 0xc009, 0x0);
+qtest_outw(s, 0xc00b, 0xc212);
+qtest_outl(s, 0xc042, 0x2c2c5a88);
+qtest_outw(s, 0xc00b, 0xc212);
+qtest_outw(s, 0xc00b, 0x415a);
+qtest_outl(s, 0xc03f, 0x3060303);
+qtest_outl(s, 0xc00b, 0x5afa9054);
+qtest_quit(s);
+}
+
  int main(int argc, char **argv)
  {
  const char *arch = qtest_get_arch();
@@ -212,6 +246,8 @@ int main(int argc, char **argv)
 test_fifo_underflow_on_write_ok);
  qtest_add_func("am53c974/test_cancelled_request_ok",
 test_cancelled_request_ok);
+qtest_add_func("am53c974/test_inflight_cancel_ok",
+   test_inflight_cancel_ok);
  }
  
  return g_test_run();




Queued both, thanks.

Paolo




Re: [PATCH v2 0/5] hw/arm: Add NPCM7XX Tachometer Device

2021-11-02 Thread Peter Maydell
On Tue, 2 Nov 2021 at 10:03, Richard Henderson
 wrote:
>
> On 11/1/21 1:50 PM, Hao Wu wrote:
> > Is this reply to a wrong thread? I thought it was applied a long time ago.
>
> Probably.

Possibly you meant this 5-patch NPCM7xx series ?
https://patchew.org/QEMU/20211008002628.1958285-1-wuhao...@google.com/
("[PATCH v2 0/5] hw/arm: Add MMC device for NPCM7XX boards")

which has been reviewed and is ready to go in I think.

thanks
-- PMM



Re: [PATCH v2] hvf: arm: Ignore cache operations on MMIO

2021-11-02 Thread Peter Maydell
On Tue, 2 Nov 2021 at 10:01, Richard Henderson
 wrote:
>
> On 11/1/21 3:35 PM, Peter Maydell wrote:
> > On Mon, 1 Nov 2021 at 19:28, Richard Henderson
> >  wrote:
> >>
> >> On 10/26/21 3:12 AM, Alexander Graf wrote:
> >>> Apple's Hypervisor.Framework forwards cache operations as MMIO traps
> >>> into user space. For MMIO however, these have no meaning: There is no
> >>> cache attached to them.
> >>>
> >>> So let's just treat cache data exits as nops.
> >>>
> >>> This fixes OpenBSD booting as guest.
> >>>
> >>> Signed-off-by: Alexander Graf 
> >>> Reported-by: AJ Barris 
> >>> Reference: https://github.com/utmapp/UTM/issues/3197
> >>> ---
> >>>target/arm/hvf/hvf.c | 7 +++
> >>>1 file changed, 7 insertions(+)
> >>
> >> Thanks, applied to target-arm.next
> >
> > ...did you see my email saying I think we also need
> > to test S1PTW ?
>
> That arrived afterward.

Thinking it over later, I wouldn't be opposed to taking this
patch now and adding the S1PTW second -- I think we're
currently going to do the wrong thing for the "page tables
not in RAM case anyway", so you could regard it as a
separate bug fix.

-- PMM



Re: [PATCH v2 3/3] KVM: SVM: add migration support for nested TSC scaling

2021-11-02 Thread Paolo Bonzini

On 01/11/21 14:23, Maxim Levitsky wrote:

Signed-off-by: Maxim Levitsky 
---
  target/i386/cpu.c |  5 +
  target/i386/cpu.h |  4 
  target/i386/kvm/kvm.c | 15 +++
  target/i386/machine.c | 23 +++
  4 files changed, 47 insertions(+)


It's easier to migrate it unconditionally:

diff --git a/target/i386/machine.c b/target/i386/machine.c
index e1138693f3..83c2b91529 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -1286,8 +1286,7 @@ static bool amd_tsc_scale_msr_needed(void *opaque)
 X86CPU *cpu = opaque;
 CPUX86State *env = >env;

-return env->amd_tsc_scale_msr &&
-   env->amd_tsc_scale_msr != MSR_AMD64_TSC_RATIO_DEFAULT;
+return (env->features[FEAT_SVM] & CPUID_SVM_TSCSCALE);
 }

 static const VMStateDescription amd_tsc_scale_msr_ctrl = {


+if (env->features[FEAT_SVM] & CPUID_SVM_TSCSCALE) {
+env->amd_tsc_scale_msr =  MSR_AMD64_TSC_RATIO_DEFAULT;
+}


and also set it unconditionally here, so that it's always passed 
correctly to KVM.


I queued patches 2 and 3, for (1) I need to think more about migration 
to older QEMU versions.


Paolo




Re: [PATCH v4 02/22] target/riscv: Implement SGEIP bit in hip and hie CSRs

2021-11-02 Thread Anup Patel
On Tue, Nov 2, 2021 at 12:22 PM Bin Meng  wrote:
>
> On Tue, Oct 26, 2021 at 2:43 PM Anup Patel  wrote:
> >
> > A hypervsior can optionally take guest external interrupts using
>
> typo: hypervisor

Okay, I will update.

>
> > SGEIP bit of hip and hie CSRs.
> >
> > Signed-off-by: Anup Patel 
> > Reviewed-by: Alistair Francis 
> > ---
> >  target/riscv/cpu.c  |  3 ++-
> >  target/riscv/cpu_bits.h |  3 +++
> >  target/riscv/csr.c  | 18 +++---
> >  3 files changed, 16 insertions(+), 8 deletions(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 788fa0b11c..0460a3972b 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -365,6 +365,7 @@ static void riscv_cpu_reset(DeviceState *dev)
> >  env->mstatus = set_field(env->mstatus, MSTATUS64_UXL, 
> > env->misa_mxl);
> >  }
> >  env->mcause = 0;
> > +env->miclaim = MIP_SGEIP;
> >  env->pc = env->resetvec;
> >  env->two_stage_lookup = false;
> >  #endif
> > @@ -598,7 +599,7 @@ static void riscv_cpu_init(Object *obj)
> >  cpu_set_cpustate_pointers(cpu);
> >
> >  #ifndef CONFIG_USER_ONLY
> > -qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, 12);
> > +qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, IRQ_LOCAL_MAX);
> >  #endif /* CONFIG_USER_ONLY */
> >  }
> >
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index cffcd3a5df..8a5a4cde95 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > @@ -498,6 +498,8 @@ typedef enum RISCVException {
> >  #define IRQ_S_EXT  9
> >  #define IRQ_VS_EXT 10
> >  #define IRQ_M_EXT  11
> > +#define IRQ_S_GEXT 12
> > +#define IRQ_LOCAL_MAX  13
>
> The IRQ_LOCAL_MAX should be XLEN long, not 13.

The IRQ_LOCAL_MAX here represents local interrupts
standardized by the RISC-V privilege spec. This value
will change only when more local interrupts are
standardized by the RISC-V privilege spec.

>
> >
> >  /* mip masks */
> >  #define MIP_USIP   (1 << IRQ_U_SOFT)
> > @@ -512,6 +514,7 @@ typedef enum RISCVException {
> >  #define MIP_SEIP   (1 << IRQ_S_EXT)
> >  #define MIP_VSEIP  (1 << IRQ_VS_EXT)
> >  #define MIP_MEIP   (1 << IRQ_M_EXT)
> > +#define MIP_SGEIP  (1 << IRQ_S_GEXT)
> >
> >  /* sip masks */
> >  #define SIP_SSIP   MIP_SSIP
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 9dfc9b5eba..9a0a0c0679 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -408,12 +408,13 @@ static RISCVException read_timeh(CPURISCVState *env, 
> > int csrno,
> >  #define M_MODE_INTERRUPTS  (MIP_MSIP | MIP_MTIP | MIP_MEIP)
> >  #define S_MODE_INTERRUPTS  (MIP_SSIP | MIP_STIP | MIP_SEIP)
> >  #define VS_MODE_INTERRUPTS (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)
> > +#define HS_MODE_INTERRUPTS (MIP_SGEIP | VS_MODE_INTERRUPTS)
> >
> >  static const target_ulong delegable_ints = S_MODE_INTERRUPTS |
> > VS_MODE_INTERRUPTS;
> >  static const target_ulong vs_delegable_ints = VS_MODE_INTERRUPTS;
> >  static const target_ulong all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS 
> > |
> > - VS_MODE_INTERRUPTS;
> > + HS_MODE_INTERRUPTS;
> >  #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \
> >   (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \
> >   (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \
> > @@ -673,7 +674,7 @@ static RISCVException write_mideleg(CPURISCVState *env, 
> > int csrno,
> >  {
> >  env->mideleg = (env->mideleg & ~delegable_ints) | (val & 
> > delegable_ints);
> >  if (riscv_has_ext(env, RVH)) {
> > -env->mideleg |= VS_MODE_INTERRUPTS;
> > +env->mideleg |= HS_MODE_INTERRUPTS;
> >  }
> >  return RISCV_EXCP_NONE;
> >  }
> > @@ -689,6 +690,9 @@ static RISCVException write_mie(CPURISCVState *env, int 
> > csrno,
> >  target_ulong val)
> >  {
> >  env->mie = (env->mie & ~all_ints) | (val & all_ints);
> > +if (!riscv_has_ext(env, RVH)) {
> > +env->mie &= ~MIP_SGEIP;
> > +}
> >  return RISCV_EXCP_NONE;
> >  }
> >
> > @@ -984,7 +988,7 @@ static RISCVException rmw_sip(CPURISCVState *env, int 
> > csrno,
> >  }
> >
> >  if (ret_value) {
> > -*ret_value &= env->mideleg;
> > +*ret_value &= env->mideleg & S_MODE_INTERRUPTS;
> >  }
> >  return ret;
> >  }
> > @@ -1102,7 +1106,7 @@ static RISCVException rmw_hvip(CPURISCVState *env, 
> > int csrno,
> >write_mask & hvip_writable_mask);
> >
> >  if (ret_value) {
> > -*ret_value &= hvip_writable_mask;
> > +*ret_value &= VS_MODE_INTERRUPTS;
> >  }
> >  

Re: [PATCH] vhost: Fix last queue index of devices with no cvq

2021-11-02 Thread Eugenio Perez Martin
On Tue, Nov 2, 2021 at 8:04 AM Jason Wang  wrote:
>
> On Tue, Nov 2, 2021 at 2:59 PM Eugenio Perez Martin  
> wrote:
> >
> > On Tue, Nov 2, 2021 at 5:09 AM Jason Wang  wrote:
> > >
> > > On Mon, Nov 1, 2021 at 4:59 PM Eugenio Perez Martin  
> > > wrote:
> > > >
> > > > On Mon, Nov 1, 2021 at 4:34 AM Jason Wang  wrote:
> > > > >
> > > > > On Fri, Oct 29, 2021 at 10:16 PM Eugenio Pérez  
> > > > > wrote:
> > > > > >
> > > > > > The -1 assumes that all devices with no cvq have an spare vq 
> > > > > > allocated
> > > > > > for them, but with no offer of VIRTIO_NET_F_CTRL_VQ. This may not 
> > > > > > be the
> > > > > > case, and the device may have a pair number of queues.
> > > > > >
> > > > > > To fix this, just resort to the lower even number of queues.
> > > > > >
> > > > > > Fixes: 049eb15b5fc9 ("vhost: record the last virtqueue index for 
> > > > > > the virtio device")
> > > > > > Signed-off-by: Eugenio Pérez 
> > > > > > ---
> > > > > >  hw/net/vhost_net.c | 2 +-
> > > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > >
> > > > > > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> > > > > > index 0d888f29a6..edf56a597f 100644
> > > > > > --- a/hw/net/vhost_net.c
> > > > > > +++ b/hw/net/vhost_net.c
> > > > > > @@ -330,7 +330,7 @@ int vhost_net_start(VirtIODevice *dev, 
> > > > > > NetClientState *ncs,
> > > > > >  NetClientState *peer;
> > > > > >
> > > > > >  if (!cvq) {
> > > > > > -last_index -= 1;
> > > > > > +last_index &= ~1ULL;
> > > > > >  }
> > > > >
> > > > > The math here looks correct but we need to fix vhost_vdpa_dev_start() 
> > > > > instead?
> > > > >
> > > > > if (dev->vq_index + dev->nvqs - 1 != dev->last_index) {
> > > > > ...
> > > > > }
> > > > >
> > > >
> > > > If we just do that, devices that offer an odd number of queues but do
> > > > not offer ctrl vq would never enable the last vq pair, isn't it?
> > >
> > > For vq pair, you assume that it's a networking device, so the device
> > > you described here violates the spec.
> > >
> > > >
> > > > Also, I would say that the right place for the solution of this
> > > > problem should not be virtio/vhost-vdpa: This is highly dependent on
> > > > having cvq, and this implies a knowledge about the use of each
> > > > virtqueue. Another kind of device could have an odd number of
> > > > virtqueues naturally, and that (-1) would not work for them, isn't it?
> > >
> > > It actually depends on how multiqueue is modeled for each specific
> > > type of device. They need to initialize the vq_index and nvqs
> > > correctly:
> > >
> > > E.g if we had a device with 3 queues, we could model it with the 
> > > following:
> > >
> > > vhost_dev 1, vq_index = 0, nvqs = 2
> > > vhost_dev 2, vq_index = 2, nvqs = 1
> > >
> > > In this case the last_index should be initialized to 2, then we know
> > > all the vhost_dev is initialized and we can start the hardware.
> > >
> >
> > Right, but in that case, cvq == true, and we never enter the
> > conditional if (!cvq).
> >
> > If cvq is false at that moment, your vhost_dev 2 *must* not exist and
> > the last index will be even, so we must not subtract 1 to last_index.
> > The subtraction is the cause the device never starts.

Clarification: I meant networking here :).

>
> The last_index will be 1, so the device will be started after
> vhost_dev 1 is initialized?
>

In !cvq !mq case, last_index is the number of virtqueues. It is initialized as:

int ... last_index = data_queue_pairs * 2;

and data queue pairs comes from caller function virtio_net_vhost_status:

int queue_pairs = n->multiqueue ? n->max_queue_pairs : 1;

so last_index ends up being 2.

I didn't check a MQ device with !cvq, but I think it will be the same.

Thanks!

> Thanks
>
> >
> > Given all of the above, I think we can skip the conditional entirely.
> >
> > Thanks!
> >
> > > Thanks
> > >
> > > >
> > > > Thanks!
> > > >
> > > > > Thanks
> > > > >
> > > > > >
> > > > > >  if (!k->set_guest_notifiers) {
> > > > > > --
> > > > > > 2.27.0
> > > > > >
> > > > >
> > > >
> > >
> >
>




Re: [RFC PATCH v5 22/26] vhost: Shadow virtqueue buffers forwarding

2021-11-02 Thread Eugenio Perez Martin
On Tue, Nov 2, 2021 at 8:59 AM Jason Wang  wrote:
>
>
> 在 2021/10/30 上午2:35, Eugenio Pérez 写道:
> > Initial version of shadow virtqueue that actually forward buffers. There
> > are no iommu support at the moment, and that will be addressed in future
> > patches of this series. Since all vhost-vdpa devices uses forced IOMMU,
> > this means that SVQ is not usable at this point of the series on any
> > device.
> >
> > For simplicity it only supports modern devices, that expects vring
> > in little endian, with split ring and no event idx or indirect
> > descriptors. Support for them will not be added in this series.
> >
> > It reuses the VirtQueue code for the device part. The driver part is
> > based on Linux's virtio_ring driver, but with stripped functionality
> > and optimizations so it's easier to review. Later commits add simpler
> > ones.
> >
> > However to forwarding buffers have some particular pieces: One of the
> > most unexpected ones is that a guest's buffer can expand through more
> > than one descriptor in SVQ. While this is handled gracefully by qemu's
> > emulated virtio devices, it may cause unexpected SVQ queue full. This
> > patch also solves it checking for this condition at both guest's kicks
> > and device's calls. The code may be more elegant in the future if SVQ
> > code runs in its own iocontext.
> >
> > Note that vhost_vdpa_get_vq_state trust the device to write its status
> > to used_idx at pause(), finishing all in-flight descriptors. This may
> > not be enough for complex devices, but other development like usage of
> > inflight_fd on top of this solution may extend the usage in the future.
> >
> > In particular, SVQ trust it to recover guest's virtqueue at start, and
> > to mark as used the latest descriptors used by the device in the
> > meantime.
> >
> > Signed-off-by: Eugenio Pérez 
> > ---
> >   qapi/net.json  |   5 +-
> >   hw/virtio/vhost-shadow-virtqueue.c | 400 +++--
> >   hw/virtio/vhost-vdpa.c | 144 ++-
> >   3 files changed, 521 insertions(+), 28 deletions(-)
> >
> > diff --git a/qapi/net.json b/qapi/net.json
> > index fca2f6ebca..1c6d3b2179 100644
> > --- a/qapi/net.json
> > +++ b/qapi/net.json
> > @@ -84,12 +84,9 @@
> >   #
> >   # Use vhost shadow virtqueue.
> >   #
> > -# SVQ can just forward notifications between the device and the guest at 
> > this
> > -# moment. This will expand in future changes.
> > -#
> >   # @name: the device name of the VirtIO device
> >   #
> > -# @set: true to use the alternate shadow VQ notifications
> > +# @set: true to use the alternate shadow VQ
> >   #
> >   # Since: 6.2
> >   #
> > diff --git a/hw/virtio/vhost-shadow-virtqueue.c 
> > b/hw/virtio/vhost-shadow-virtqueue.c
> > index cb9ffcb015..ad1b2342be 100644
> > --- a/hw/virtio/vhost-shadow-virtqueue.c
> > +++ b/hw/virtio/vhost-shadow-virtqueue.c
> > @@ -9,6 +9,9 @@
> >
> >   #include "qemu/osdep.h"
> >   #include "hw/virtio/vhost-shadow-virtqueue.h"
> > +#include "hw/virtio/vhost.h"
> > +#include "hw/virtio/virtio-access.h"
> > +
> >   #include "standard-headers/linux/vhost_types.h"
> >
> >   #include "qemu/error-report.h"
> > @@ -45,6 +48,27 @@ typedef struct VhostShadowVirtqueue {
> >
> >   /* Virtio device */
> >   VirtIODevice *vdev;
> > +
> > +/* Map for returning guest's descriptors */
> > +VirtQueueElement **ring_id_maps;
> > +
> > +/* Next VirtQueue element that guest made available */
> > +VirtQueueElement *next_guest_avail_elem;
> > +
> > +/* Next head to expose to device */
> > +uint16_t avail_idx_shadow;
> > +
> > +/* Next free descriptor */
> > +uint16_t free_head;
> > +
> > +/* Last seen used idx */
> > +uint16_t shadow_used_idx;
> > +
> > +/* Next head to consume from device */
> > +uint16_t last_used_idx;
> > +
> > +/* Cache for the exposed notification flag */
> > +bool notification;
> >   } VhostShadowVirtqueue;
> >
> >   /**
> > @@ -56,25 +80,174 @@ const EventNotifier *vhost_svq_get_dev_kick_notifier(
> >   return >hdev_kick;
> >   }
> >
> > -/* If the device is using some of these, SVQ cannot communicate */
> > +/**
> > + * VirtIO transport device feature acknowledge
> > + *
> > + * @dev_features  The device features. If success, the acknowledged 
> > features.
> > + *
> > + * Returns true if SVQ can go with a subset of these, false otherwise.
> > + */
> >   bool vhost_svq_valid_device_features(uint64_t *dev_features)
> >   {
> > -return true;
> > +uint64_t b;
> > +bool r = true;
> > +
> > +for (b = VIRTIO_TRANSPORT_F_START; b <= VIRTIO_TRANSPORT_F_END; ++b) {
> > +switch (b) {
> > +case VIRTIO_F_NOTIFY_ON_EMPTY:
> > +case VIRTIO_F_ANY_LAYOUT:
> > +continue;
> > +
> > +case VIRTIO_F_ACCESS_PLATFORM:
> > +/* SVQ does not know how to translate addresses */
> > +if (*dev_features & BIT_ULL(b)) {
> > +clear_bit(b, dev_features);
> > + 

Re: [RFC PATCH 03/15] job-common.h: categorize fields in struct Job

2021-11-02 Thread Stefan Hajnoczi
On Fri, Oct 29, 2021 at 12:39:02PM -0400, Emanuele Giuseppe Esposito wrote:
> Categorize the fields in struct Job to understand which need
> to be protected by the job muutex and which not.

s/muutex/mutex/

  (__)
  `\--(oo)
||(__) .o( moo-tex )
||w--||

BTW "which ones need ... and which don't" reads more naturally.


signature.asc
Description: PGP signature


Re: [PATCH 03/13] target/riscv: Ignore the pc bits above XLEN

2021-11-02 Thread Richard Henderson

On 11/1/21 6:01 AM, LIU Zhiwei wrote:

The read from PC for translation is in cpu_get_tb_cpu_state, before translation.

Signed-off-by: LIU Zhiwei 
---
  target/riscv/cpu_helper.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 7d0aee6769..eb425d74d2 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -71,7 +71,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
  {
  uint32_t flags = 0;
  
-*pc = env->pc;

+*pc = cpu_get_xl(env) == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
  *cs_base = 0;


Oh, let's not compute cpu_get_xl twice -- currently we do it at the end of the function 
when we store into flags.  Move that as necessary.



r~



Re: [PATCH 02/13] target/riscv: Extend pc for runtime pc write

2021-11-02 Thread Richard Henderson

On 11/1/21 9:48 PM, LIU Zhiwei wrote:


On 2021/11/1 下午6:33, Richard Henderson wrote:

On 11/1/21 6:01 AM, LIU Zhiwei wrote:

In some cases, we must restore the guest PC to the address of the start of
the TB, such as when the instruction counter hit zero. So extend pc register
according to current xlen for these cases.

Signed-off-by: LIU Zhiwei 
---
  target/riscv/cpu.c    | 20 +---
  target/riscv/cpu.h    |  2 ++
  target/riscv/cpu_helper.c |  2 +-
  3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7d53125dbc..7eefd4f6a6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -319,7 +319,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
  {
  RISCVCPU *cpu = RISCV_CPU(cs);
  CPURISCVState *env = >env;
-    env->pc = value;
+
+    if (cpu_get_xl(env) == MXL_RV32) {
+    env->pc = (int32_t)value;
+    } else {
+    env->pc = value;
+    }
  }


Good.


  static void riscv_cpu_synchronize_from_tb(CPUState *cs,
@@ -327,7 +332,12 @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
  {
  RISCVCPU *cpu = RISCV_CPU(cs);
  CPURISCVState *env = >env;
-    env->pc = tb->pc;
+
+    if (cpu_get_xl(env) == MXL_RV32) {
+    env->pc = (int32_t)tb->pc;
+    } else {
+    env->pc = tb->pc;
+    }


Bad, since TB->PC should be extended properly.
Though this waits on a change to cpu_get_tb_cpu_state.


Should the env->pc always hold the sign-extend result? In cpu_get_tb_cpu_state, we just 
truncate to the XLEN bits.


Oops, I mis-read patch 3; I thought that sign-extended.  Hmm.

I guess we need to zero-extend the pc for patch 3, to get the correct result in translate 
when we read from memory.  Therefore we need to sign-extend here to get the correct value 
back in env->pc.


Oh, let's not re-compute cpu_get_xl here, and restore_state_to_opc; it is in

FIELD_EX32(tb->flags, TB_FLAGS, XL)


r~



Re: [RFC PATCH 02/15] job.c: make job_lock/unlock public

2021-11-02 Thread Stefan Hajnoczi
On Fri, Oct 29, 2021 at 12:39:01PM -0400, Emanuele Giuseppe Esposito wrote:
> job mutex will be used to protect the job struct elements and list,
> replacing AioContext locks.
> 
> Right now use a shared lock for all jobs, in order to keep things
> simple. Once the AioContext lock is gone, we can introduce per-job
> locks.
> 
> Signed-off-by: Emanuele Giuseppe Esposito 
> ---
>  include/qemu/job-common.h | 18 ++
>  job.c | 12 +---
>  2 files changed, 23 insertions(+), 7 deletions(-)
> 
> diff --git a/include/qemu/job-common.h b/include/qemu/job-common.h
> index c115028e33..dcc24fba48 100644
> --- a/include/qemu/job-common.h
> +++ b/include/qemu/job-common.h
> @@ -297,4 +297,22 @@ typedef enum JobCreateFlags {
>  JOB_MANUAL_DISMISS = 0x04,
>  } JobCreateFlags;
>  
> +/**
> + * job_lock:
> + *
> + * Take the mutex protecting the list of jobs and their status.
> + * Most functions called by the monitor need to call job_lock
> + * and job_unlock manually.  On the other hand, function called

s/function/functions/

> diff --git a/job.c b/job.c
> index 94b142684f..e003f136f0 100644
> --- a/job.c
> +++ b/job.c
> @@ -32,6 +32,9 @@
>  #include "trace/trace-root.h"
>  #include "qapi/qapi-events-job.h"
>  
> +/* job_mutex protects the jobs list, but also makes the job API thread-safe. 
> */

"but also makes the job API thread-safe" is vague. Are the jobs list and
the Job objects all protected by job_mutex? Stating that would be
clearer.

Otherwise:

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [RFC PATCH 01/15] jobs: add job-common.h

2021-11-02 Thread Stefan Hajnoczi
On Fri, Oct 29, 2021 at 12:39:00PM -0400, Emanuele Giuseppe Esposito wrote:
> job-common.h contains all struct and common function that currently
> are in job.h and will be shared by job-monitor and job-driver in
> the next commits.
> 
> No functional change intended.
> 
> Signed-off-by: Emanuele Giuseppe Esposito 
> ---
>  include/qemu/job-common.h | 300 ++
>  include/qemu/job.h| 271 +-
>  2 files changed, 301 insertions(+), 270 deletions(-)
>  create mode 100644 include/qemu/job-common.h

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [PATCH 00/16] fdt: Make OF_BOARD a boolean option

2021-11-02 Thread Michael Walle
Hi,

> On Thu, 28 Oct 2021 at 05:51, Simon Glass  wrote:
> > On Tue, 26 Oct 2021 at 00:46, Ilias Apalodimas
> >  wrote:

..

> > Linux actually doesn't care if the U-Boot properties are in the tree,
> > so long as we have proper bindings. My point here is we only need
> > either:
> >
> > a. one devicetree, shared with Linux and U-Boot (and TF-A?)
> > b. two devicetrees, one for use in firmware and one for passing to Linux
> >
> > We don't need to separate out the U-Boot properties into a second (or
> > third) devicetree. There just isn't any point.
> 
> Again if we are talking about bindings that are upstream in the spec,
> then we agree.  Depending on the SRAM limitation we can even do (a).
> If the vendor messes up the DT backwards compatibility then we can do
> (b).  If you expect TF-A and FIP to go pick up the special bindings
> U-Boot needs, then we disagree.

*puts developer at board vendor hat on* Sometimes (personally I'd say
usually) it isn't possible to have a backwards compatible tree. Also,
like it or not, in the device tree there *are* configuration options
which are not hardware dependent (eg. internal ethernet connection on
the ls1028a). So a vendor doesn't necessarily need to "mess things up"
to need (b). And as you know, my point is, that this device tree has
to come from the distribution, it must not be compiled in into the
firmware.

I feel like I've repeated this far too many times. Therefore, this
will be my last comment about it and I would really like to see that
this - very real - scenario is treated as a valid use case and will be
supported in your systemready vision.

-michael



Re: [RFC PATCH 00/15] job: replace AioContext lock with job_mutex

2021-11-02 Thread Stefan Hajnoczi
On Fri, Oct 29, 2021 at 12:38:59PM -0400, Emanuele Giuseppe Esposito wrote:
> RFC: not sure if the current patch organization is correct.
> Bisecting in patches in between this serie would cause tests
> to deadlock.

Patch series must be bisectable. It will be necessary to fix this.

Stefan


signature.asc
Description: PGP signature


Re: [PATCH v2 0/5] hw/arm: Add NPCM7XX Tachometer Device

2021-11-02 Thread Richard Henderson

On 11/1/21 1:50 PM, Hao Wu wrote:

Is this reply to a wrong thread? I thought it was applied a long time ago.


Probably.

r~



Thanks,

On Mon, Nov 1, 2021 at 10:33 AM Richard Henderson > wrote:


On Thu, 11 Mar 2021 at 13:11, Hao Wu mailto:wuhao...@google.com>> wrote:
 >
 > This patch set implements the Tachometer (a.k.a Multi Functional 
Timer/MFT)
 > device in NPCM7XX SoC. This device is used by NPCM7XX boards to measure
 > the RPM of PWM fans.
 >
 > To provide the RPM of a certain fan, since RPM = MAX_RPM * 
duty_percentage.
 > We convert the duty output in NPCM7XX PWM module into GPIOs and feed them
 > into the MFT module.
 >
 > The connection of PWM modules and fan modules are derived from their 
specific
 > Linux device trees and coded in hw/arm/npcm7xx_boards.c.
 >
 > We amend the QTest for the PWM module to include verifying the reading 
from
 > the Tachometer is correct.
 >
 > Changes since v1:
 > - Split implementation of device and addition to board file to separate 
patches
 > - Adapt to new Clock API and address conflicts
 > - Use the new clock_ns_to_ticks API to calculate tachometer counts
 >
 > Hao Wu (5):
 >   hw/misc: Add GPIOs for duty in NPCM7xx PWM
 >   hw/misc: Add NPCM7XX MFT Module
 >   hw/arm: Add MFT device to NPCM7xx Soc
 >   hw/arm: Connect PWM fans in NPCM7XX boards
 >   tests/qtest: Test PWM fan RPM using MFT in PWM test
 >
 >  docs/system/arm/nuvoton.rst    |   2 +-
 >  hw/arm/npcm7xx.c               |  45 ++-
 >  hw/arm/npcm7xx_boards.c        |  99 ++
 >  hw/misc/meson.build            |   1 +
 >  hw/misc/npcm7xx_mft.c          | 540 +
 >  hw/misc/npcm7xx_pwm.c          |   4 +
 >  hw/misc/trace-events           |   8 +
 >  include/hw/arm/npcm7xx.h       |  13 +-
 >  include/hw/misc/npcm7xx_mft.h  |  70 +
 >  include/hw/misc/npcm7xx_pwm.h  |   4 +-
 >  tests/qtest/npcm7xx_pwm-test.c | 205 -
 >  11 files changed, 974 insertions(+), 17 deletions(-)
 >  create mode 100644 hw/misc/npcm7xx_mft.c
 >  create mode 100644 include/hw/misc/npcm7xx_mft.h

Thanks, queued to target-arm.next.

r~






Re: [PATCH v2] hvf: arm: Ignore cache operations on MMIO

2021-11-02 Thread Richard Henderson

On 11/1/21 3:35 PM, Peter Maydell wrote:

On Mon, 1 Nov 2021 at 19:28, Richard Henderson
 wrote:


On 10/26/21 3:12 AM, Alexander Graf wrote:

Apple's Hypervisor.Framework forwards cache operations as MMIO traps
into user space. For MMIO however, these have no meaning: There is no
cache attached to them.

So let's just treat cache data exits as nops.

This fixes OpenBSD booting as guest.

Signed-off-by: Alexander Graf 
Reported-by: AJ Barris 
Reference: https://github.com/utmapp/UTM/issues/3197
---
   target/arm/hvf/hvf.c | 7 +++
   1 file changed, 7 insertions(+)


Thanks, applied to target-arm.next


...did you see my email saying I think we also need
to test S1PTW ?


That arrived afterward.

r~



Re: [PULL 00/22] Python patches

2021-11-02 Thread Richard Henderson

On 11/1/21 1:29 PM, John Snow wrote:

The following changes since commit af531756d25541a1b3b3d9a14e72e7fedd941a2e:

   Merge remote-tracking branch 'remotes/philmd/tags/renesas-20211030' into 
staging (2021-10-30 11:31:41 -0700)

are available in the Git repository at:

   https://gitlab.com/jsnow/qemu.git tags/python-pull-request

for you to fetch changes up to 76cd358671e6b8e7c435ec65b1c44200254514a9:

   python, iotests: replace qmp with aqmp (2021-11-01 11:54:59 -0400)


Pull request



John Snow (22):
   iotests/297: Move pylint config into pylintrc
   iotests/297: Split mypy configuration out into mypy.ini
   iotests/297: Add get_files() function
   iotests/297: Create main() function
   iotests/297: Don't rely on distro-specific linter binaries
   iotests/297: Split run_linters apart into run_pylint and run_mypy
   iotests/297: refactor run_[mypy|pylint] as generic execution shim
   iotests/297: Change run_linter() to raise an exception on failure
   iotests/297: update tool availability checks
   iotests/297: split test into sub-cases
   iotests: split linters.py out from 297
   iotests/linters: Add entry point for linting via Python CI
   iotests/linters: Add workaround for mypy bug #9852
   python: Add iotest linters to test suite
   python/machine: remove has_quit argument
   python/machine: Handle QMP errors on close more meticulously
   python/aqmp: Remove scary message
   iotests: Accommodate async QMP Exception classes
   iotests: Conditionally silence certain AQMP errors
   iotests/300: avoid abnormal shutdown race condition
   python/aqmp: Create sync QMP wrapper for iotests
   python, iotests: replace qmp with aqmp

  python/qemu/aqmp/__init__.py  |  12 --
  python/qemu/aqmp/legacy.py| 138 ++
  python/qemu/machine/machine.py|  85 +
  python/tests/iotests-mypy.sh  |   4 +
  python/tests/iotests-pylint.sh|   4 +
  scripts/simplebench/bench_block_job.py|   3 +-
  tests/qemu-iotests/040|   7 +-
  tests/qemu-iotests/218|   2 +-
  tests/qemu-iotests/255|   2 +-
  tests/qemu-iotests/297| 103 +++-
  tests/qemu-iotests/300|  13 +-
  tests/qemu-iotests/iotests.py |  20 +++-
  tests/qemu-iotests/linters.py | 105 
  tests/qemu-iotests/mypy.ini   |  12 ++
  tests/qemu-iotests/pylintrc   |  16 +++
  tests/qemu-iotests/tests/mirror-top-perms |  17 ++-
  16 files changed, 424 insertions(+), 119 deletions(-)
  create mode 100644 python/qemu/aqmp/legacy.py
  create mode 100755 python/tests/iotests-mypy.sh
  create mode 100755 python/tests/iotests-pylint.sh
  create mode 100644 tests/qemu-iotests/linters.py
  create mode 100644 tests/qemu-iotests/mypy.ini


Applied, thanks.

r~




Re: [PATCH 0/5] hw/core: Remove uses of obsolete QERR_ definitions

2021-11-02 Thread Damien Hedde




On 10/30/21 01:01, Philippe Mathieu-Daudé wrote:

QERR_ definitions are obsolete since 2015... Remove their
uses in hw/core/.

Philippe Mathieu-Daudé (5):
   hw/core: Remove use of QERR_UNSUPPORTED
   hw/core: Remove use of QERR_FEATURE_DISABLED
   hw/core: Remove uses of QERR_DEVICE_NO_HOTPLUG
   hw/core: Remove uses of QERR_PROPERTY_VALUE_BAD
   hw/core: Remove uses of QERR_INVALID_PARAMETER_VALUE

  include/qapi/qmp/qerror.h| 6 --
  hw/core/machine-qmp-cmds.c   | 3 ++-
  hw/core/nmi.c| 2 +-
  hw/core/qdev-properties-system.c | 2 +-
  hw/core/qdev-properties.c| 2 +-
  hw/core/qdev.c   | 3 ++-
  monitor/misc.c   | 3 +--
  softmmu/cpus.c   | 3 +--
  softmmu/qdev-monitor.c   | 9 -
  target/i386/cpu.c| 2 +-
  10 files changed, 14 insertions(+), 21 deletions(-)



Hi Philippe,

In my patches you just pulled (patch 9). There is a new 
QERR_INVALID_PARAMETER_VALUE in qdev-monitor.c. Maybe it is worth

fixing it as well.

anyway
Reviewed-by: Damien Hedde 

Thanks,
Damien



Re: [PATCH 4/5] hw/core: Remove uses of QERR_PROPERTY_VALUE_BAD

2021-11-02 Thread Damien Hedde




On 10/30/21 01:01, Philippe Mathieu-Daudé wrote:

QERR_PROPERTY_VALUE_BAD definition is obsolete since 2015 (commit
4629ed1e989, "qerror: Finally unused, clean up"). Replace the two
uses and drop the definition.

Signed-off-by: Philippe Mathieu-Daudé 
---
  include/qapi/qmp/qerror.h | 3 ---
  hw/core/qdev-properties.c | 2 +-
  target/i386/cpu.c | 2 +-
  3 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index f49ae01cdb0..a3f44fc4a1e 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -50,9 +50,6 @@
  #define QERR_PERMISSION_DENIED \
  "Insufficient permission to perform this operation"
  
-#define QERR_PROPERTY_VALUE_BAD \

-"Property '%s.%s' doesn't take value '%s'"
-
  #define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
  "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", maximum: %" 
PRId64 ")"
  
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c

index c34aac6ebc9..dbea4cf8e5e 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -663,7 +663,7 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, 
Object *obj,
  break;
  default:
  case -EINVAL:
-error_setg(errp, QERR_PROPERTY_VALUE_BAD,
+error_setg(errp, "Property '%s.%s' doesn't take value '%s'",
 object_get_typename(obj), name, value);
  break;
  case -ENOENT:
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index fc3ed80ef1e..bc63b80e5bd 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4469,7 +4469,7 @@ static void x86_cpuid_set_vendor(Object *obj, const char 
*value,
  int i;
  
  if (strlen(value) != CPUID_VENDOR_SZ) {

-error_setg(errp, QERR_PROPERTY_VALUE_BAD, "", "vendor", value);
+error_setg(errp, "Property '.vendor' doesn't take value '%s'", value);
  return;
  }
  


Hi,

maybe we can remove the '.' before vendor in this case.

--
Damien



Re: [PULL 1/5] hw/pcie-root-port: Fix hotplug for PCI devices requiring IO

2021-11-02 Thread Marcel Apfelbaum
Hi Daniel,

On Tue, Nov 2, 2021 at 11:24 AM Daniel P. Berrangé 
wrote:

> On Mon, Sep 27, 2021 at 05:49:15AM -0400, Michael S. Tsirkin wrote:
> > On Mon, Sep 27, 2021 at 10:33:42AM +0100, Daniel P. Berrangé wrote:
> > > On Tue, Aug 03, 2021 at 04:52:03PM -0400, Michael S. Tsirkin wrote:
> > > > From: Marcel Apfelbaum 
> > > >
> > > > Q35 has now ACPI hotplug enabled by default for PCI(e) devices.
> > > > As opposed to native PCIe hotplug, guests like Fedora 34
> > > > will not assign IO range to pcie-root-ports not supporting
> > > > native hotplug, resulting into a regression.
> > > >
> > > > Reproduce by:
> > > > qemu-bin -M q35 -device pcie-root-port,id=p1 -monitor stdio
> > > > device_add e1000,bus=p1
> > > > In the Guest OS the respective pcie-root-port will have the IO range
> > > > disabled.
> > > >
> > > > Fix it by setting the "reserve-io" hint capability of the
> > > > pcie-root-ports so the firmware will allocate the IO range instead.
> > > >
> > > > Acked-by: Igor Mammedov 
> > > > Signed-off-by: Marcel Apfelbaum 
> > > > Message-Id: <20210802090057.1709775-1-mar...@redhat.com>
> > > > Reviewed-by: Michael S. Tsirkin 
> > > > Signed-off-by: Michael S. Tsirkin 
> > > > ---
> > > >  hw/pci-bridge/gen_pcie_root_port.c | 5 +
> > > >  1 file changed, 5 insertions(+)
> > >
> > > This change, when combined with the switch to ACPI based hotplug by
> > > default, is responsible for a significant regression in QEMU 6.1.0
> > >
> > > It is no longer possible to have more than 15 pcie-root-port devices
> > > added to a q35 VM in 6.1.0.  Before this I've had as many as 80+
> devices
> > > present before I stopped trying to add more.
> > >
> > >   https://gitlab.com/qemu-project/qemu/-/issues/641
> > >
> > > This regression is significant, because it has broken the out of the
> > > box default configuration that OpenStack uses for booting all VMs.
> > > They add 16 pcie-root-ports by defalt to allow empty slots for device
> > > hotplug under q35 [1].
> >
> >
> > Indeed, oops. Thanks for the report!
>
> We're at soft freeze now and this is still broken in git master.
> I don't recall seeing a fix for this problem on list and no one has
> commented on the bug report.
>
> Is anyone actively working on a fix for this release ?
>

I think Julia (cc-ed) is working on a fix.

Thanks,
Marcel



>
> If not, I'm going to post a patch to revert to PCI native
> hotplug, because this was a significant regression in 6.1 that
> breaks openstack out of the box and we can't leave it broken
> again for 6.2.
>
> Regards,
> Daniel
> --
> |: https://berrange.com  -o-
> https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-
> https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-
> https://www.instagram.com/dberrange :|
>
>


Re: [PATCH v2] hmp: Add shortcut to stop command to match cont

2021-11-02 Thread Daniel P . Berrangé
On Sat, Oct 30, 2021 at 11:49:37AM +0200, BALATON Zoltan wrote:
> Some commands such as quit or cont have one letter alternatives but
> stop is missing that. Add stop|s to match cont|c for consistency and
> convenience.
> 
> Signed-off-by: BALATON Zoltan 
> ---
> c2: Fixed typo in commit title
> 
>  hmp-commands.hx | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Daniel P. Berrangé 


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: [PULL 1/5] hw/pcie-root-port: Fix hotplug for PCI devices requiring IO

2021-11-02 Thread Daniel P . Berrangé
On Mon, Sep 27, 2021 at 05:49:15AM -0400, Michael S. Tsirkin wrote:
> On Mon, Sep 27, 2021 at 10:33:42AM +0100, Daniel P. Berrangé wrote:
> > On Tue, Aug 03, 2021 at 04:52:03PM -0400, Michael S. Tsirkin wrote:
> > > From: Marcel Apfelbaum 
> > > 
> > > Q35 has now ACPI hotplug enabled by default for PCI(e) devices.
> > > As opposed to native PCIe hotplug, guests like Fedora 34
> > > will not assign IO range to pcie-root-ports not supporting
> > > native hotplug, resulting into a regression.
> > > 
> > > Reproduce by:
> > > qemu-bin -M q35 -device pcie-root-port,id=p1 -monitor stdio
> > > device_add e1000,bus=p1
> > > In the Guest OS the respective pcie-root-port will have the IO range
> > > disabled.
> > > 
> > > Fix it by setting the "reserve-io" hint capability of the
> > > pcie-root-ports so the firmware will allocate the IO range instead.
> > > 
> > > Acked-by: Igor Mammedov 
> > > Signed-off-by: Marcel Apfelbaum 
> > > Message-Id: <20210802090057.1709775-1-mar...@redhat.com>
> > > Reviewed-by: Michael S. Tsirkin 
> > > Signed-off-by: Michael S. Tsirkin 
> > > ---
> > >  hw/pci-bridge/gen_pcie_root_port.c | 5 +
> > >  1 file changed, 5 insertions(+)
> > 
> > This change, when combined with the switch to ACPI based hotplug by
> > default, is responsible for a significant regression in QEMU 6.1.0
> > 
> > It is no longer possible to have more than 15 pcie-root-port devices
> > added to a q35 VM in 6.1.0.  Before this I've had as many as 80+ devices
> > present before I stopped trying to add more.
> > 
> >   https://gitlab.com/qemu-project/qemu/-/issues/641
> > 
> > This regression is significant, because it has broken the out of the
> > box default configuration that OpenStack uses for booting all VMs.
> > They add 16 pcie-root-ports by defalt to allow empty slots for device
> > hotplug under q35 [1].
> 
> 
> Indeed, oops. Thanks for the report!

We're at soft freeze now and this is still broken in git master.
I don't recall seeing a fix for this problem on list and no one has
commented on the bug report.

Is anyone actively working on a fix for this release ?

If not, I'm going to post a patch to revert to PCI native
hotplug, because this was a significant regression in 6.1 that
breaks openstack out of the box and we can't leave it broken
again for 6.2.

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: [PATCH v1 1/2] migration: block-dirty-bitmap: add missing qemu_mutex_lock_iothread

2021-11-02 Thread Juan Quintela
Juan Quintela  wrote:
> Emanuele Giuseppe Esposito  wrote:
>> init_dirty_bitmap_migration assumes the iothread lock (BQL)
>> to be held, but instead it isn't.
>>
>> Instead of adding the lock to qemu_savevm_state_setup(),
>> follow the same pattern as the other ->save_setup callbacks
>> and lock+unlock inside dirty_bitmap_save_setup().
>>
>> Signed-off-by: Emanuele Giuseppe Esposito 
>> Reviewed-by: Stefan Hajnoczi 
>
> Reviewed-by: Juan Quintela 

And I realized that this patch is already on the tree, just not through
the migration tree.

Ignore the noise.

Later, Juan.




Re: [PATCH 2/9] qapi: Mark unstable QMP parts with feature 'unstable'

2021-11-02 Thread Kevin Wolf
Am 29.10.2021 um 15:07 hat Eric Blake geschrieben:
> On Mon, Oct 25, 2021 at 07:25:25AM +0200, Markus Armbruster wrote:
> > Add special feature 'unstable' everywhere the name starts with 'x-',
> > except for InputBarrierProperties member x-origin and
> > MemoryBackendProperties member x-use-canonical-path-for-ramblock-id,
> > because these two are actually stable.
> > 
> > Signed-off-by: Markus Armbruster 
> > ---
> > @@ -2495,27 +2508,57 @@
> >  #
> >  # Properties for throttle-group objects.
> >  #
> > -# The options starting with x- are aliases for the same key without x- in
> > -# the @limits object. As indicated by the x- prefix, this is not a stable
> > -# interface and may be removed or changed incompatibly in the future. Use
> > -# @limits for a supported stable interface.
> > -#
> >  # @limits: limits to apply for this throttle group
> >  #
> > +# Features:
> > +# @unstable: All members starting with x- are aliases for the same key
> > +#without x- in the @limits object.  This is not a stable
> > +#interface and may be removed or changed incompatibly in
> > +#the future.  Use @limits for a supported stable
> > +#interface.
> > +#
> >  # Since: 2.11
> >  ##
> >  { 'struct': 'ThrottleGroupProperties',
> >'data': { '*limits': 'ThrottleLimits',
> > -'*x-iops-total' : 'int', '*x-iops-total-max' : 'int',
> 
> > +'*x-iops-total': { 'type': 'int',
> > +   'features': [ 'unstable' ] },
> 
> This struct has been around since 381bd74 (v6.0); but was not listed
> as deprecated at the time.  Do we still need it in 6.2, or have we
> gone enough release cycles with the saner naming without x- that we
> could drop this?  But that is a question independent of this patch.

There is no reason any more to use the x- options, and I think libvirt
never used them anyway.

I actually have a commit in my QAPI object branch that removes these
properties, but I think it still broke some tests.

Anyway, something for a separate patch.

Kevin




Re: [PATCH] nvmm: Fix support for stable version

2021-11-02 Thread Kamil Rytarowski
Reviewed-by: Kamil Rytarowski 

Paolo, could you please merge it?

On 13.10.2021 15:54, nia wrote:
> NVMM user version 1 is the version being shipped with netbsd-9,
> which is the most recent stable branch of NetBSD. This makes it
> possible to use the NVMM accelerator on the most recent NetBSD
> release, 9.2, which lacks nvmm_cpu_stop.
> 
> (CC'ing maintainers)
> 
> Signed-off-by: Nia Alarie 
> ---
>  meson.build |  4 +---
>  target/i386/nvmm/nvmm-all.c | 10 ++
>  2 files changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/meson.build b/meson.build
> index 15ef4d3c41..6e4d9b919a 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -244,9 +244,7 @@ if not get_option('hax').disabled()
>endif
>  endif
>  if targetos == 'netbsd'
> -  if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: 
> get_option('nvmm'))
> -nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
> -  endif
> +  nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
>if nvmm.found()
>  accelerators += 'CONFIG_NVMM'
>endif
> diff --git a/target/i386/nvmm/nvmm-all.c b/target/i386/nvmm/nvmm-all.c
> index a488b00e90..4a10412427 100644
> --- a/target/i386/nvmm/nvmm-all.c
> +++ b/target/i386/nvmm/nvmm-all.c
> @@ -750,7 +750,11 @@ nvmm_vcpu_loop(CPUState *cpu)
>  nvmm_vcpu_pre_run(cpu);
>  
>  if (qatomic_read(>exit_request)) {
> +#if NVMM_USER_VERSION >= 2
>  nvmm_vcpu_stop(vcpu);
> +#else
> +qemu_cpu_kick_self();
> +#endif
>  }
>  
>  /* Read exit_request before the kernel reads the immediate exit flag 
> */
> @@ -767,6 +771,7 @@ nvmm_vcpu_loop(CPUState *cpu)
>  switch (exit->reason) {
>  case NVMM_VCPU_EXIT_NONE:
>  break;
> +#if NVMM_USER_VERSION >= 2
>  case NVMM_VCPU_EXIT_STOPPED:
>  /*
>   * The kernel cleared the immediate exit flag; cpu->exit_request
> @@ -775,6 +780,7 @@ nvmm_vcpu_loop(CPUState *cpu)
>  smp_wmb();
>  qcpu->stop = true;
>  break;
> +#endif
>  case NVMM_VCPU_EXIT_MEMORY:
>  ret = nvmm_handle_mem(mach, vcpu);
>  break;
> @@ -888,8 +894,12 @@ nvmm_ipi_signal(int sigcpu)
>  {
>  if (current_cpu) {
>  struct qemu_vcpu *qcpu = get_qemu_vcpu(current_cpu);
> +#if NVMM_USER_VERSION >= 2
>  struct nvmm_vcpu *vcpu = >vcpu;
>  nvmm_vcpu_stop(vcpu);
> +#else
> +qcpu->stop = true;
> +#endif
>  }
>  }
>  
> 




Re: [PATCH v1 1/2] migration: block-dirty-bitmap: add missing qemu_mutex_lock_iothread

2021-11-02 Thread Juan Quintela
Emanuele Giuseppe Esposito  wrote:
> init_dirty_bitmap_migration assumes the iothread lock (BQL)
> to be held, but instead it isn't.
>
> Instead of adding the lock to qemu_savevm_state_setup(),
> follow the same pattern as the other ->save_setup callbacks
> and lock+unlock inside dirty_bitmap_save_setup().
>
> Signed-off-by: Emanuele Giuseppe Esposito 
> Reviewed-by: Stefan Hajnoczi 

Reviewed-by: Juan Quintela 

queued.




Re: [PATCH 2/2] failover: don't allow to migrate a paused VM that needs PCI unplug

2021-11-02 Thread Juan Quintela
Laurent Vivier  wrote:
> As the guest OS is paused, we will never receive the unplug event
> from the kernel and the migration cannot continue.
>
> Signed-off-by: Laurent Vivier 

Reviewed-by: Juan Quintela 

queued.

I can't think of a better solution.




Re: [PATCH 1/2] migration: provide an error message to migration_cancel()

2021-11-02 Thread Juan Quintela
Laurent Vivier  wrote:
> This avoids to call migrate_get_current() in the caller function
> whereas migration_cancel() already needs the pointer to the current
> migration state.
>
> Signed-off-by: Laurent Vivier 

Reviewed-by: Juan Quintela 

queued.


>  error_setg(, "RAM block '%s' resized during precopy.", 
> rb->idstr);
> -migrate_set_error(migrate_get_current(), err);
> +migration_cancel(err);
>  error_free(err);
> -migration_cancel();

This was already there, but it is ugly, isn't it?

Later, Juan.




Re: [PATCH v2 7/7] hw/arm: Add ID for NPCM7XX SMBus

2021-11-02 Thread Philippe Mathieu-Daudé
+Markus/Eduardo

On 11/1/21 18:33, Peter Maydell wrote:
> On Thu, 21 Oct 2021 at 19:40, Hao Wu  wrote:
>>
>> The ID can be used to indicate SMBus modules when adding
>> dynamic devices to them.
>>
>> Signed-off-by: Hao Wu 
>> ---
>>  hw/arm/npcm7xx.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
>> index 2ab0080e0b..72953d65ef 100644
>> --- a/hw/arm/npcm7xx.c
>> +++ b/hw/arm/npcm7xx.c
>> @@ -421,6 +421,7 @@ static void npcm7xx_init(Object *obj)
>>  for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
>>  object_initialize_child(obj, "smbus[*]", >smbus[i],
>>  TYPE_NPCM7XX_SMBUS);
>> +DEVICE(>smbus[i])->id = g_strdup_printf("smbus[%d]", i);
>>  }
> 
> This one looks weird to me -- I'm pretty sure we shouldn't be messing
> about with the DeviceState id string like that. It's supposed to be
> internal to the QOM/qdev code.

I agree with you, however:

$ git grep -F -- '->id = g_strdup' hw
hw/arm/virt.c:1512:dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
hw/block/xen-block.c:761:drive->id = g_strdup(id);
hw/block/xen-block.c:853:iothread->id = g_strdup(id);
hw/core/machine-qmp-cmds.c:169:m->id =
g_strdup(object_get_canonical_path_component(obj));
hw/mem/pc-dimm.c:244:di->id = g_strdup(dev->id);
hw/pci-bridge/pci_expander_bridge.c:248:bds->id =
g_strdup(dev_name);
hw/ppc/e500.c:1009:dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
hw/s390x/s390-pci-bus.c:1003:dev->id =
g_strdup_printf("auto_%02x:%02x.%01x",
hw/sh4/sh7750.c:819:dev->id = g_strdup("sci");
hw/sh4/sh7750.c:836:dev->id = g_strdup("scif");
hw/virtio/virtio-mem-pci.c:69:vi->id = g_strdup(dev->id);
hw/virtio/virtio-pmem-pci.c:74:vi->id = g_strdup(dev->id);



Re: [PATCH v3 3/3] hw/i386: expose a "smbios-entry-point-type" PC machine property

2021-11-02 Thread Philippe Mathieu-Daudé
On 10/26/21 17:11, Eduardo Habkost wrote:
> The i440fx and Q35 machine types are both hardcoded to use the
> legacy SMBIOS 2.1 (32-bit) entry point. This is a sensible
> conservative choice because SeaBIOS only supports SMBIOS 2.1
> 
> EDK2, however, can also support SMBIOS 3.0 (64-bit) entry points,
> and QEMU already uses this on the ARM virt machine type.
> 
> This adds a property to allow the choice of SMBIOS entry point
> versions For example to opt in to 64-bit SMBIOS entry point:
> 
>$QEMU -machine q35,smbios-entry-point-type=64

It would be nice to have a test for this...

Otherwise,
Reviewed-by: Philippe Mathieu-Daudé 

> Based on a patch submitted by Daniel Berrangé.
> 
> Signed-off-by: Daniel P. Berrangé 
> Signed-off-by: Eduardo Habkost 
> ---
> This is patch was previously submitted at:
> https://lore.kernel.org/qemu-devel/20200908165438.1008942-6-berra...@redhat.com
> 
> Changes from v2:
> * Rename "smbios-ep" to "smbios-entry-point-type"
> 
> Changes from v1:
> * Include qapi-visit-smbios.h instead of qapi-visit-machine.h
> * Commit message fix: s/smbios_ep/smbios-ep/
> ---
>  include/hw/i386/pc.h |  4 
>  hw/i386/pc.c | 26 ++
>  hw/i386/pc_piix.c|  2 +-
>  hw/i386/pc_q35.c |  2 +-
>  4 files changed, 32 insertions(+), 2 deletions(-)




Re: [PATCH v2] failover: specify an alternate MAC address

2021-11-02 Thread Michael S. Tsirkin
On Tue, Nov 02, 2021 at 09:14:51AM +0100, Laurent Vivier wrote:
> On 01/11/2021 10:39, Michael S. Tsirkin wrote:
> > On Wed, Oct 27, 2021 at 11:59:45AM +0200, Laurent Vivier wrote:
> > > If the guest driver doesn't support the STANDBY feature, by default
> > > we keep the virtio-net device and don't hotplug the VFIO device,
> > > but in some cases, user can prefer to use the VFIO device rather
> > > than the virtio-net one. We can't unplug the virtio-net device
> > > (because on migration it is expected on the destination side) but
> > > we can keep both interfaces if the MAC addresses are different
> > > (to have the same MAC address can cause kernel crash with old
> > > kernel). The VFIO device will be unplugged before the migration
> > > like in the normal failover migration but without a failover device.
> > > 
> > > This patch adds a new property to the virtio-net device:
> > > "failover-legacy-mac"
> > > 
> > > If an alternate MAC address is provided with "failover-legacy-mac" and
> > > the STANDBY feature is not supported, both interfaces are plugged
> > > but the standby interface (virtio-net) MAC address is set to the
> > > value provided by the "failover-legacy-mac" parameter.
> > > 
> > > If the STANDBY feature is supported by guest and QEMU, the virtio-net
> > > failover acts as usual.
> > > 
> > > Signed-off-by: Laurent Vivier 
> > 
> > Wait a second. What if config is read before features are set?
> > Are we going to provide a legacy or a new mac?
> We provide the new MAC and at this point the primary device is not plugged.
> 
> When features are set:
> - if STANDBY is set, the primary device is plugged, and secondary
> (virtio-net) uses the new MAC
> - if STANDBY is not set:
> - if legacy MAC is provided:
> the primary device is plugged and legacy MAC is used
> - else
> the primary device is not plugged and new MAC is used.
> 
> > I guess current guests do not do this, but the spec does allow this,
> > and then the mac will apparently change for the guests.
> 
> What I read in virtio 1.0 specs, "3.1.1 Driver requirements: Device
> initialization", is the virtio configuration space (step 7) is is accessed
> after the features are negotiated. I don't think the part in step 4 can
> involve the MAC address, and moreover the config is not read before, but
> during the negotiation (I guess we can see that as the config access is part
> of the negotiation).
> 
> 3.1.1 Driver Requirements: Device Initialization
> 
> The driver MUST follow this sequence to initialize a device:
> 1. Reset the device.
> 2. Set the ACKNOWLEDGE status bit: the guest OS has notice the device.
> 3. Set the DRIVER status bit: the guest OS knows how to drive the device.
> 4. Read device feature bits, and write the subset of feature bits understood
> by the OS and driver to the device. During this step the driver MAY read
> (but MUST NOT write) the device-specific configuration fields to check that
> it can support the device before accepting it.
> 5. Set the FEATURES_OK status bit. The driver MUST NOT accept new feature
> bits after this step.
> 6. Re-read device status to ensure the FEATURES_OK bit is still set:
> otherwise, the device does not support our subset of features and the device
> is unusable.
> 7. Perform device-specific setup, including discovery of virtqueues for the
> device, optional per-bus setup, reading and possibly writing the device’s
> virtio configuration space, and population of virtqueues.
> 8. Set the DRIVER_OK status bit. At this point the device is “live”.

OTOH

Device Requirements: Device Configuration Space
The device MUST allow reading of any device-specific configuration field before 
FEATURES_OK is set by the
driver. This includes fields which are conditional on feature bits, as long as 
those feature bits are offered by the
device.

now, we can maybe make an exception for mac.
But this is something to discuss on the virtio TC mailing list.


> > 
> > It might be cleaner to just add a PRIMARY_MAC feature -
> > would need guest work though ...
> 
> We can't add a new feature: the goal of this patch is to be able to use the
> primary device (VFIO) with kernel that doesn't support STANDBY feature. If
> we can add a feature, to add the STANDBY feature would be a better choice.
> 
> If changing the MAC address is not acceptable we can return to a mix of v1 
> and v2 of my patch:
> 
> "virtio: failover: allow to keep the VFIO device rather than the virtio-net 
> one"
> 
> https://patchew.org/QEMU/20210729191910.317114-1-lviv...@redhat.com/
> 
> that disables the virtio-net driver on the module probe.
> 
> Thanks,
> Laurent




<    1   2   3   4   5   6   >