* [PULL 0/4] target/avr patch queue
@ 2022-09-01 5:48 Richard Henderson
2022-09-01 5:48 ` [PULL 1/4] target/avr: Support probe argument to tlb_fill Richard Henderson
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Richard Henderson @ 2022-09-01 5:48 UTC (permalink / raw)
To: qemu-devel
The following changes since commit e93ded1bf6c94ab95015b33e188bc8b0b0c32670:
Merge tag 'testing-pull-request-2022-08-30' of https://gitlab.com/thuth/qemu into staging (2022-08-31 18:19:03 -0400)
are available in the Git repository at:
https://gitlab.com/rth7680/qemu.git tags/pull-avr-20220901
for you to fetch changes up to 36027c70974fef1392e6c73dfb94c3f94f0930bc:
target/avr: Disable interrupts when env->skip set (2022-09-01 06:42:21 +0100)
----------------------------------------------------------------
Fix avr_cpu_tlb_fill use of probe argument
Fix skip instructions being separated from the next insn (#1118)
----------------------------------------------------------------
Richard Henderson (4):
target/avr: Support probe argument to tlb_fill
target/avr: Call avr_cpu_do_interrupt directly
target/avr: Only execute one interrupt at a time
target/avr: Disable interrupts when env->skip set
target/avr/helper.c | 69 +++++++++++++++++++++++++++++++-------------------
target/avr/translate.c | 26 ++++++++++++++++---
2 files changed, 65 insertions(+), 30 deletions(-)
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PULL 1/4] target/avr: Support probe argument to tlb_fill
2022-09-01 5:48 [PULL 0/4] target/avr patch queue Richard Henderson
@ 2022-09-01 5:48 ` Richard Henderson
2022-09-01 5:48 ` [PULL 2/4] target/avr: Call avr_cpu_do_interrupt directly Richard Henderson
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2022-09-01 5:48 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé
While there are no target-specific nonfaulting probes,
generic code may grow some uses at some point.
Note that the attrs argument was incorrect -- it should have
been MEMTXATTRS_UNSPECIFIED. Just use the simpler interface.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/avr/helper.c | 46 ++++++++++++++++++++++++++++-----------------
1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/target/avr/helper.c b/target/avr/helper.c
index db76452f9a..82284f8997 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -102,38 +102,50 @@ bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr)
{
- int prot = 0;
- MemTxAttrs attrs = {};
+ int prot, page_size = TARGET_PAGE_SIZE;
uint32_t paddr;
address &= TARGET_PAGE_MASK;
if (mmu_idx == MMU_CODE_IDX) {
- /* access to code in flash */
+ /* Access to code in flash. */
paddr = OFFSET_CODE + address;
prot = PAGE_READ | PAGE_EXEC;
- if (paddr + TARGET_PAGE_SIZE > OFFSET_DATA) {
+ if (paddr >= OFFSET_DATA) {
+ /*
+ * This should not be possible via any architectural operations.
+ * There is certainly not an exception that we can deliver.
+ * Accept probing that might come from generic code.
+ */
+ if (probe) {
+ return false;
+ }
error_report("execution left flash memory");
abort();
}
- } else if (address < NUMBER_OF_CPU_REGISTERS + NUMBER_OF_IO_REGISTERS) {
- /*
- * access to CPU registers, exit and rebuilt this TB to use full access
- * incase it touches specially handled registers like SREG or SP
- */
- AVRCPU *cpu = AVR_CPU(cs);
- CPUAVRState *env = &cpu->env;
- env->fullacc = 1;
- cpu_loop_exit_restore(cs, retaddr);
} else {
- /* access to memory. nothing special */
+ /* Access to memory. */
paddr = OFFSET_DATA + address;
prot = PAGE_READ | PAGE_WRITE;
+ if (address < NUMBER_OF_CPU_REGISTERS + NUMBER_OF_IO_REGISTERS) {
+ /*
+ * Access to CPU registers, exit and rebuilt this TB to use
+ * full access in case it touches specially handled registers
+ * like SREG or SP. For probing, set page_size = 1, in order
+ * to force tlb_fill to be called for the next access.
+ */
+ if (probe) {
+ page_size = 1;
+ } else {
+ AVRCPU *cpu = AVR_CPU(cs);
+ CPUAVRState *env = &cpu->env;
+ env->fullacc = 1;
+ cpu_loop_exit_restore(cs, retaddr);
+ }
+ }
}
- tlb_set_page_with_attrs(cs, address, paddr, attrs, prot,
- mmu_idx, TARGET_PAGE_SIZE);
-
+ tlb_set_page(cs, address, paddr, prot, mmu_idx, page_size);
return true;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PULL 2/4] target/avr: Call avr_cpu_do_interrupt directly
2022-09-01 5:48 [PULL 0/4] target/avr patch queue Richard Henderson
2022-09-01 5:48 ` [PULL 1/4] target/avr: Support probe argument to tlb_fill Richard Henderson
@ 2022-09-01 5:48 ` Richard Henderson
2022-09-01 5:48 ` [PULL 3/4] target/avr: Only execute one interrupt at a time Richard Henderson
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2022-09-01 5:48 UTC (permalink / raw)
To: qemu-devel; +Cc: Michael Rolnik, Philippe Mathieu-Daudé
There is no need to go through cc->tcg_ops when
we know what value that must have.
Reviewed-by: Michael Rolnik <mrolnik@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/avr/helper.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/target/avr/helper.c b/target/avr/helper.c
index 82284f8997..9614ccf3e4 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -29,14 +29,13 @@
bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
bool ret = false;
- CPUClass *cc = CPU_GET_CLASS(cs);
AVRCPU *cpu = AVR_CPU(cs);
CPUAVRState *env = &cpu->env;
if (interrupt_request & CPU_INTERRUPT_RESET) {
if (cpu_interrupts_enabled(env)) {
cs->exception_index = EXCP_RESET;
- cc->tcg_ops->do_interrupt(cs);
+ avr_cpu_do_interrupt(cs);
cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
@@ -47,7 +46,7 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
int index = ctz32(env->intsrc);
cs->exception_index = EXCP_INT(index);
- cc->tcg_ops->do_interrupt(cs);
+ avr_cpu_do_interrupt(cs);
env->intsrc &= env->intsrc - 1; /* clear the interrupt */
if (!env->intsrc) {
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PULL 3/4] target/avr: Only execute one interrupt at a time
2022-09-01 5:48 [PULL 0/4] target/avr patch queue Richard Henderson
2022-09-01 5:48 ` [PULL 1/4] target/avr: Support probe argument to tlb_fill Richard Henderson
2022-09-01 5:48 ` [PULL 2/4] target/avr: Call avr_cpu_do_interrupt directly Richard Henderson
@ 2022-09-01 5:48 ` Richard Henderson
2022-09-01 5:48 ` [PULL 4/4] target/avr: Disable interrupts when env->skip set Richard Henderson
2022-09-02 17:20 ` [PULL 0/4] target/avr patch queue Stefan Hajnoczi
4 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2022-09-01 5:48 UTC (permalink / raw)
To: qemu-devel; +Cc: Michael Rolnik, Philippe Mathieu-Daudé
We cannot deliver two interrupts simultaneously;
the first interrupt handler must execute first.
Reviewed-by: Michael Rolnik <mrolnik@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/avr/helper.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/target/avr/helper.c b/target/avr/helper.c
index 9614ccf3e4..34f1cbffb2 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -28,7 +28,6 @@
bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
- bool ret = false;
AVRCPU *cpu = AVR_CPU(cs);
CPUAVRState *env = &cpu->env;
@@ -38,8 +37,7 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
avr_cpu_do_interrupt(cs);
cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
-
- ret = true;
+ return true;
}
}
if (interrupt_request & CPU_INTERRUPT_HARD) {
@@ -52,11 +50,10 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
if (!env->intsrc) {
cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
}
-
- ret = true;
+ return true;
}
}
- return ret;
+ return false;
}
void avr_cpu_do_interrupt(CPUState *cs)
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PULL 4/4] target/avr: Disable interrupts when env->skip set
2022-09-01 5:48 [PULL 0/4] target/avr patch queue Richard Henderson
` (2 preceding siblings ...)
2022-09-01 5:48 ` [PULL 3/4] target/avr: Only execute one interrupt at a time Richard Henderson
@ 2022-09-01 5:48 ` Richard Henderson
2022-09-02 17:20 ` [PULL 0/4] target/avr patch queue Stefan Hajnoczi
4 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2022-09-01 5:48 UTC (permalink / raw)
To: qemu-devel; +Cc: Michael Rolnik, Philippe Mathieu-Daudé
This bit is not saved across interrupts, so we must
delay delivering the interrupt until the skip has
been processed.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1118
Reviewed-by: Michael Rolnik <mrolnik@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/avr/helper.c | 9 +++++++++
target/avr/translate.c | 26 ++++++++++++++++++++++----
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/target/avr/helper.c b/target/avr/helper.c
index 34f1cbffb2..156dde4e92 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -31,6 +31,15 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
AVRCPU *cpu = AVR_CPU(cs);
CPUAVRState *env = &cpu->env;
+ /*
+ * We cannot separate a skip from the next instruction,
+ * as the skip would not be preserved across the interrupt.
+ * Separating the two insn normally only happens at page boundaries.
+ */
+ if (env->skip) {
+ return false;
+ }
+
if (interrupt_request & CPU_INTERRUPT_RESET) {
if (cpu_interrupts_enabled(env)) {
cs->exception_index = EXCP_RESET;
diff --git a/target/avr/translate.c b/target/avr/translate.c
index dc9c3d6bcc..026753c963 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2971,8 +2971,18 @@ static void avr_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
if (skip_label) {
canonicalize_skip(ctx);
gen_set_label(skip_label);
- if (ctx->base.is_jmp == DISAS_NORETURN) {
+
+ switch (ctx->base.is_jmp) {
+ case DISAS_NORETURN:
ctx->base.is_jmp = DISAS_CHAIN;
+ break;
+ case DISAS_NEXT:
+ if (ctx->base.tb->flags & TB_FLAGS_SKIP) {
+ ctx->base.is_jmp = DISAS_TOO_MANY;
+ }
+ break;
+ default:
+ break;
}
}
@@ -2989,6 +2999,11 @@ static void avr_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
bool nonconst_skip = canonicalize_skip(ctx);
+ /*
+ * Because we disable interrupts while env->skip is set,
+ * we must return to the main loop to re-evaluate afterward.
+ */
+ bool force_exit = ctx->base.tb->flags & TB_FLAGS_SKIP;
switch (ctx->base.is_jmp) {
case DISAS_NORETURN:
@@ -2997,7 +3012,7 @@ static void avr_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
case DISAS_NEXT:
case DISAS_TOO_MANY:
case DISAS_CHAIN:
- if (!nonconst_skip) {
+ if (!nonconst_skip && !force_exit) {
/* Note gen_goto_tb checks singlestep. */
gen_goto_tb(ctx, 1, ctx->npc);
break;
@@ -3005,8 +3020,11 @@ static void avr_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
tcg_gen_movi_tl(cpu_pc, ctx->npc);
/* fall through */
case DISAS_LOOKUP:
- tcg_gen_lookup_and_goto_ptr();
- break;
+ if (!force_exit) {
+ tcg_gen_lookup_and_goto_ptr();
+ break;
+ }
+ /* fall through */
case DISAS_EXIT:
tcg_gen_exit_tb(NULL, 0);
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PULL 1/4] target/avr: Support probe argument to tlb_fill
2022-09-01 6:51 [PULL 00/20] tcg " Richard Henderson
@ 2022-09-01 6:51 ` Richard Henderson
0 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2022-09-01 6:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé
While there are no target-specific nonfaulting probes,
generic code may grow some uses at some point.
Note that the attrs argument was incorrect -- it should have
been MEMTXATTRS_UNSPECIFIED. Just use the simpler interface.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/avr/helper.c | 46 ++++++++++++++++++++++++++++-----------------
1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/target/avr/helper.c b/target/avr/helper.c
index db76452f9a..82284f8997 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -102,38 +102,50 @@ bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr)
{
- int prot = 0;
- MemTxAttrs attrs = {};
+ int prot, page_size = TARGET_PAGE_SIZE;
uint32_t paddr;
address &= TARGET_PAGE_MASK;
if (mmu_idx == MMU_CODE_IDX) {
- /* access to code in flash */
+ /* Access to code in flash. */
paddr = OFFSET_CODE + address;
prot = PAGE_READ | PAGE_EXEC;
- if (paddr + TARGET_PAGE_SIZE > OFFSET_DATA) {
+ if (paddr >= OFFSET_DATA) {
+ /*
+ * This should not be possible via any architectural operations.
+ * There is certainly not an exception that we can deliver.
+ * Accept probing that might come from generic code.
+ */
+ if (probe) {
+ return false;
+ }
error_report("execution left flash memory");
abort();
}
- } else if (address < NUMBER_OF_CPU_REGISTERS + NUMBER_OF_IO_REGISTERS) {
- /*
- * access to CPU registers, exit and rebuilt this TB to use full access
- * incase it touches specially handled registers like SREG or SP
- */
- AVRCPU *cpu = AVR_CPU(cs);
- CPUAVRState *env = &cpu->env;
- env->fullacc = 1;
- cpu_loop_exit_restore(cs, retaddr);
} else {
- /* access to memory. nothing special */
+ /* Access to memory. */
paddr = OFFSET_DATA + address;
prot = PAGE_READ | PAGE_WRITE;
+ if (address < NUMBER_OF_CPU_REGISTERS + NUMBER_OF_IO_REGISTERS) {
+ /*
+ * Access to CPU registers, exit and rebuilt this TB to use
+ * full access in case it touches specially handled registers
+ * like SREG or SP. For probing, set page_size = 1, in order
+ * to force tlb_fill to be called for the next access.
+ */
+ if (probe) {
+ page_size = 1;
+ } else {
+ AVRCPU *cpu = AVR_CPU(cs);
+ CPUAVRState *env = &cpu->env;
+ env->fullacc = 1;
+ cpu_loop_exit_restore(cs, retaddr);
+ }
+ }
}
- tlb_set_page_with_attrs(cs, address, paddr, attrs, prot,
- mmu_idx, TARGET_PAGE_SIZE);
-
+ tlb_set_page(cs, address, paddr, prot, mmu_idx, page_size);
return true;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PULL 0/4] target/avr patch queue
2022-09-01 5:48 [PULL 0/4] target/avr patch queue Richard Henderson
` (3 preceding siblings ...)
2022-09-01 5:48 ` [PULL 4/4] target/avr: Disable interrupts when env->skip set Richard Henderson
@ 2022-09-02 17:20 ` Stefan Hajnoczi
4 siblings, 0 replies; 7+ messages in thread
From: Stefan Hajnoczi @ 2022-09-02 17:20 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 115 bytes --]
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/7.2 for any user-visible changes.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-09-05 11:43 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-01 5:48 [PULL 0/4] target/avr patch queue Richard Henderson
2022-09-01 5:48 ` [PULL 1/4] target/avr: Support probe argument to tlb_fill Richard Henderson
2022-09-01 5:48 ` [PULL 2/4] target/avr: Call avr_cpu_do_interrupt directly Richard Henderson
2022-09-01 5:48 ` [PULL 3/4] target/avr: Only execute one interrupt at a time Richard Henderson
2022-09-01 5:48 ` [PULL 4/4] target/avr: Disable interrupts when env->skip set Richard Henderson
2022-09-02 17:20 ` [PULL 0/4] target/avr patch queue Stefan Hajnoczi
-- strict thread matches above, loose matches on Subject: below --
2022-09-01 6:51 [PULL 00/20] tcg " Richard Henderson
2022-09-01 6:51 ` [PULL 1/4] target/avr: Support probe argument to tlb_fill Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).