[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-riscv] [PATCH v1 2/8] target/riscv: Trigger interrupt on MIP updat
From: |
Alistair Francis |
Subject: |
[Qemu-riscv] [PATCH v1 2/8] target/riscv: Trigger interrupt on MIP update asynchronously |
Date: |
Sat, 20 Apr 2019 02:26:54 +0000 |
The requirement of holding the iothread_mutex is burdersome when
swapping the background and foreground registers in the Hypervisor
extension. To avoid the requrirement let's set the interrupt
asynchronously.
Signed-off-by: Alistair Francis <address@hidden>
---
target/riscv/cpu_helper.c | 33 +++++++++++++++++++++++++++------
target/riscv/csr.c | 2 --
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index b17f169681..582d58aad9 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -82,10 +82,31 @@ int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t
interrupts)
}
}
-/* iothread_mutex must be held */
+struct CpuAsyncInfo {
+ uint32_t new_mip;
+};
+
+static void riscv_cpu_update_mip_irqs_async(CPUState *target_cpu_state,
+ run_on_cpu_data data)
+{
+ CPURISCVState *env = &RISCV_CPU(target_cpu_state)->env;
+ RISCVCPU *cpu = riscv_env_get_cpu(env);
+ struct CpuAsyncInfo *info = (struct CpuAsyncInfo *) data.host_ptr;
+
+ if (info->new_mip) {
+ cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+ } else {
+ cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+ }
+
+ g_free(info);
+}
+
uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
{
CPURISCVState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
+ struct CpuAsyncInfo *info;
uint32_t old, new, cmp = atomic_read(&env->mip);
do {
@@ -94,11 +115,11 @@ uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t
mask, uint32_t value)
cmp = atomic_cmpxchg(&env->mip, old, new);
} while (old != cmp);
- if (new) {
- cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
- } else {
- cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
- }
+ info = g_new(struct CpuAsyncInfo, 1);
+ info->new_mip = new;
+
+ async_run_on_cpu(cs, riscv_cpu_update_mip_irqs_async,
+ RUN_ON_CPU_HOST_PTR(info));
return old;
}
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e1d91b6c60..f9d8d150e0 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -555,9 +555,7 @@ static int rmw_mip(CPURISCVState *env, int csrno,
target_ulong *ret_value,
uint32_t old_mip;
if (mask) {
- qemu_mutex_lock_iothread();
old_mip = riscv_cpu_update_mip(cpu, mask, (new_value & mask));
- qemu_mutex_unlock_iothread();
} else {
old_mip = atomic_read(&env->mip);
}
--
2.21.0
- [Qemu-riscv] [PATCH v1 0/8] RISC-V: Add some prep patches for the Hypervisor, Alistair Francis, 2019/04/19
- [Qemu-riscv] [PATCH v1 1/8] target/riscv: Mark privilege level 2 as reserved, Alistair Francis, 2019/04/19
- [Qemu-riscv] [PATCH v1 2/8] target/riscv: Trigger interrupt on MIP update asynchronously,
Alistair Francis <=
- [Qemu-riscv] [PATCH v1 3/8] target/riscv: Improve the scause logic, Alistair Francis, 2019/04/19
- [Qemu-riscv] [PATCH v1 5/8] target/riscv: Allow setting mstatus virtulisation bits, Alistair Francis, 2019/04/19
- [Qemu-riscv] [PATCH v1 4/8] target/riscv: Add the MPV and MTL mstatus bits, Alistair Francis, 2019/04/19
- [Qemu-riscv] [PATCH v1 6/8] target/riscv: Add Hypervisor CSR macros, Alistair Francis, 2019/04/19
- [Qemu-riscv] [PATCH v1 7/8] target/riscv: Add the HSTATUS register masks, Alistair Francis, 2019/04/19
- [Qemu-riscv] [PATCH v1 8/8] target/riscv: Add the HGATP register masks, Alistair Francis, 2019/04/19