1
The following changes since commit e93ded1bf6c94ab95015b33e188bc8b0b0c32670:
1
v2: Fix incorretly resolved rebase conflict in patch 16.
2
v3: Work around clang preprocessor bug in patch 3.
2
3
3
Merge tag 'testing-pull-request-2022-08-30' of https://gitlab.com/thuth/qemu into staging (2022-08-31 18:19:03 -0400)
4
5
r~
6
7
8
The following changes since commit fd28528ece590dc709d1a893fce2ff2f68ddca70:
9
10
Merge tag 'pull-or1k-20220904' of https://github.com/stffrdhrn/qemu into staging (2022-09-05 18:01:02 -0400)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20220901
14
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20220906
8
15
9
for you to fetch changes up to 20011be2e30b8aa8ef1fc258485f00c688703deb:
16
for you to fetch changes up to 00c07344fa245b22e895b363320ba4cd0ec1088a:
10
17
11
target/riscv: Make translator stop before the end of a page (2022-09-01 07:43:08 +0100)
18
target/riscv: Make translator stop before the end of a page (2022-09-06 08:04:26 +0100)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
Respect PROT_EXEC in user-only mode.
21
Respect PROT_EXEC in user-only mode.
15
Fix s390x, i386 and riscv for translations crossing a page.
22
Fix s390x, i386 and riscv for translations crossing a page.
16
23
...
...
diff view generated by jsdifflib
1
We're about to start validating PAGE_EXEC, which means
1
We're about to start validating PAGE_EXEC, which means
2
that we've got to mark the commpage executable. We had
2
that we've got to mark the commpage executable. We had
3
been placing the commpage outside of reserved_va, which
3
been placing the commpage outside of reserved_va, which
4
was incorrect and lead to an abort.
4
was incorrect and lead to an abort.
5
5
6
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
9
---
10
linux-user/arm/target_cpu.h | 4 ++--
10
linux-user/arm/target_cpu.h | 4 ++--
11
linux-user/elfload.c | 6 +++++-
11
linux-user/elfload.c | 6 +++++-
12
2 files changed, 7 insertions(+), 3 deletions(-)
12
2 files changed, 7 insertions(+), 3 deletions(-)
13
13
14
diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
14
diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/arm/target_cpu.h
16
--- a/linux-user/arm/target_cpu.h
17
+++ b/linux-user/arm/target_cpu.h
17
+++ b/linux-user/arm/target_cpu.h
18
@@ -XXX,XX +XXX,XX @@ static inline unsigned long arm_max_reserved_va(CPUState *cs)
18
@@ -XXX,XX +XXX,XX @@ static inline unsigned long arm_max_reserved_va(CPUState *cs)
19
} else {
19
} else {
20
/*
20
/*
21
* We need to be able to map the commpage.
21
* We need to be able to map the commpage.
22
- * See validate_guest_space in linux-user/elfload.c.
22
- * See validate_guest_space in linux-user/elfload.c.
23
+ * See init_guest_commpage in linux-user/elfload.c.
23
+ * See init_guest_commpage in linux-user/elfload.c.
24
*/
24
*/
25
- return 0xffff0000ul;
25
- return 0xffff0000ul;
26
+ return 0xfffffffful;
26
+ return 0xfffffffful;
27
}
27
}
28
}
28
}
29
#define MAX_RESERVED_VA arm_max_reserved_va
29
#define MAX_RESERVED_VA arm_max_reserved_va
30
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
30
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
31
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
32
--- a/linux-user/elfload.c
32
--- a/linux-user/elfload.c
33
+++ b/linux-user/elfload.c
33
+++ b/linux-user/elfload.c
34
@@ -XXX,XX +XXX,XX @@ enum {
34
@@ -XXX,XX +XXX,XX @@ enum {
35
35
36
static bool init_guest_commpage(void)
36
static bool init_guest_commpage(void)
37
{
37
{
38
- void *want = g2h_untagged(HI_COMMPAGE & -qemu_host_page_size);
38
- void *want = g2h_untagged(HI_COMMPAGE & -qemu_host_page_size);
39
+ abi_ptr commpage = HI_COMMPAGE & -qemu_host_page_size;
39
+ abi_ptr commpage = HI_COMMPAGE & -qemu_host_page_size;
40
+ void *want = g2h_untagged(commpage);
40
+ void *want = g2h_untagged(commpage);
41
void *addr = mmap(want, qemu_host_page_size, PROT_READ | PROT_WRITE,
41
void *addr = mmap(want, qemu_host_page_size, PROT_READ | PROT_WRITE,
42
MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
42
MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
43
43
44
@@ -XXX,XX +XXX,XX @@ static bool init_guest_commpage(void)
44
@@ -XXX,XX +XXX,XX @@ static bool init_guest_commpage(void)
45
perror("Protecting guest commpage");
45
perror("Protecting guest commpage");
46
exit(EXIT_FAILURE);
46
exit(EXIT_FAILURE);
47
}
47
}
48
+
48
+
49
+ page_set_flags(commpage, commpage + qemu_host_page_size,
49
+ page_set_flags(commpage, commpage + qemu_host_page_size,
50
+ PAGE_READ | PAGE_EXEC | PAGE_VALID);
50
+ PAGE_READ | PAGE_EXEC | PAGE_VALID);
51
return true;
51
return true;
52
}
52
}
53
53
54
--
54
--
55
2.34.1
55
2.34.1
diff view generated by jsdifflib
Deleted patch
1
While there are no target-specific nonfaulting probes,
2
generic code may grow some uses at some point.
3
1
4
Note that the attrs argument was incorrect -- it should have
5
been MEMTXATTRS_UNSPECIFIED. Just use the simpler interface.
6
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
10
target/avr/helper.c | 46 ++++++++++++++++++++++++++++-----------------
11
1 file changed, 29 insertions(+), 17 deletions(-)
12
13
diff --git a/target/avr/helper.c b/target/avr/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/avr/helper.c
16
+++ b/target/avr/helper.c
17
@@ -XXX,XX +XXX,XX @@ bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
18
MMUAccessType access_type, int mmu_idx,
19
bool probe, uintptr_t retaddr)
20
{
21
- int prot = 0;
22
- MemTxAttrs attrs = {};
23
+ int prot, page_size = TARGET_PAGE_SIZE;
24
uint32_t paddr;
25
26
address &= TARGET_PAGE_MASK;
27
28
if (mmu_idx == MMU_CODE_IDX) {
29
- /* access to code in flash */
30
+ /* Access to code in flash. */
31
paddr = OFFSET_CODE + address;
32
prot = PAGE_READ | PAGE_EXEC;
33
- if (paddr + TARGET_PAGE_SIZE > OFFSET_DATA) {
34
+ if (paddr >= OFFSET_DATA) {
35
+ /*
36
+ * This should not be possible via any architectural operations.
37
+ * There is certainly not an exception that we can deliver.
38
+ * Accept probing that might come from generic code.
39
+ */
40
+ if (probe) {
41
+ return false;
42
+ }
43
error_report("execution left flash memory");
44
abort();
45
}
46
- } else if (address < NUMBER_OF_CPU_REGISTERS + NUMBER_OF_IO_REGISTERS) {
47
- /*
48
- * access to CPU registers, exit and rebuilt this TB to use full access
49
- * incase it touches specially handled registers like SREG or SP
50
- */
51
- AVRCPU *cpu = AVR_CPU(cs);
52
- CPUAVRState *env = &cpu->env;
53
- env->fullacc = 1;
54
- cpu_loop_exit_restore(cs, retaddr);
55
} else {
56
- /* access to memory. nothing special */
57
+ /* Access to memory. */
58
paddr = OFFSET_DATA + address;
59
prot = PAGE_READ | PAGE_WRITE;
60
+ if (address < NUMBER_OF_CPU_REGISTERS + NUMBER_OF_IO_REGISTERS) {
61
+ /*
62
+ * Access to CPU registers, exit and rebuilt this TB to use
63
+ * full access in case it touches specially handled registers
64
+ * like SREG or SP. For probing, set page_size = 1, in order
65
+ * to force tlb_fill to be called for the next access.
66
+ */
67
+ if (probe) {
68
+ page_size = 1;
69
+ } else {
70
+ AVRCPU *cpu = AVR_CPU(cs);
71
+ CPUAVRState *env = &cpu->env;
72
+ env->fullacc = 1;
73
+ cpu_loop_exit_restore(cs, retaddr);
74
+ }
75
+ }
76
}
77
78
- tlb_set_page_with_attrs(cs, address, paddr, attrs, prot,
79
- mmu_idx, TARGET_PAGE_SIZE);
80
-
81
+ tlb_set_page(cs, address, paddr, prot, mmu_idx, page_size);
82
return true;
83
}
84
85
--
86
2.34.1
87
88
diff view generated by jsdifflib
Deleted patch
1
There is no need to go through cc->tcg_ops when
2
we know what value that must have.
3
1
4
Reviewed-by: Michael Rolnik <mrolnik@gmail.com>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/avr/helper.c | 5 ++---
9
1 file changed, 2 insertions(+), 3 deletions(-)
10
11
diff --git a/target/avr/helper.c b/target/avr/helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/avr/helper.c
14
+++ b/target/avr/helper.c
15
@@ -XXX,XX +XXX,XX @@
16
bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
17
{
18
bool ret = false;
19
- CPUClass *cc = CPU_GET_CLASS(cs);
20
AVRCPU *cpu = AVR_CPU(cs);
21
CPUAVRState *env = &cpu->env;
22
23
if (interrupt_request & CPU_INTERRUPT_RESET) {
24
if (cpu_interrupts_enabled(env)) {
25
cs->exception_index = EXCP_RESET;
26
- cc->tcg_ops->do_interrupt(cs);
27
+ avr_cpu_do_interrupt(cs);
28
29
cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
30
31
@@ -XXX,XX +XXX,XX @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
32
if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
33
int index = ctz32(env->intsrc);
34
cs->exception_index = EXCP_INT(index);
35
- cc->tcg_ops->do_interrupt(cs);
36
+ avr_cpu_do_interrupt(cs);
37
38
env->intsrc &= env->intsrc - 1; /* clear the interrupt */
39
if (!env->intsrc) {
40
--
41
2.34.1
42
43
diff view generated by jsdifflib
1
We're about to start validating PAGE_EXEC, which means that we've
1
We're about to start validating PAGE_EXEC, which means that we've
2
got to mark page zero executable. We had been special casing this
2
got to mark page zero executable. We had been special casing this
3
entirely within translate.
3
entirely within translate.
4
4
5
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
5
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
8
---
9
linux-user/elfload.c | 34 +++++++++++++++++++++++++++++++---
9
linux-user/elfload.c | 34 +++++++++++++++++++++++++++++++---
10
1 file changed, 31 insertions(+), 3 deletions(-)
10
1 file changed, 31 insertions(+), 3 deletions(-)
11
11
12
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
12
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/linux-user/elfload.c
14
--- a/linux-user/elfload.c
15
+++ b/linux-user/elfload.c
15
+++ b/linux-user/elfload.c
16
@@ -XXX,XX +XXX,XX @@ static inline void init_thread(struct target_pt_regs *regs,
16
@@ -XXX,XX +XXX,XX @@ static inline void init_thread(struct target_pt_regs *regs,
17
regs->gr[31] = infop->entry;
17
regs->gr[31] = infop->entry;
18
}
18
}
19
19
20
+#define LO_COMMPAGE 0
20
+#define LO_COMMPAGE 0
21
+
21
+
22
+static bool init_guest_commpage(void)
22
+static bool init_guest_commpage(void)
23
+{
23
+{
24
+ void *want = g2h_untagged(LO_COMMPAGE);
24
+ void *want = g2h_untagged(LO_COMMPAGE);
25
+ void *addr = mmap(want, qemu_host_page_size, PROT_NONE,
25
+ void *addr = mmap(want, qemu_host_page_size, PROT_NONE,
26
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
26
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
27
+
27
+
28
+ if (addr == MAP_FAILED) {
28
+ if (addr == MAP_FAILED) {
29
+ perror("Allocating guest commpage");
29
+ perror("Allocating guest commpage");
30
+ exit(EXIT_FAILURE);
30
+ exit(EXIT_FAILURE);
31
+ }
31
+ }
32
+ if (addr != want) {
32
+ if (addr != want) {
33
+ return false;
33
+ return false;
34
+ }
34
+ }
35
+
35
+
36
+ /*
36
+ /*
37
+ * On Linux, page zero is normally marked execute only + gateway.
37
+ * On Linux, page zero is normally marked execute only + gateway.
38
+ * Normal read or write is supposed to fail (thus PROT_NONE above),
38
+ * Normal read or write is supposed to fail (thus PROT_NONE above),
39
+ * but specific offsets have kernel code mapped to raise permissions
39
+ * but specific offsets have kernel code mapped to raise permissions
40
+ * and implement syscalls. Here, simply mark the page executable.
40
+ * and implement syscalls. Here, simply mark the page executable.
41
+ * Special case the entry points during translation (see do_page_zero).
41
+ * Special case the entry points during translation (see do_page_zero).
42
+ */
42
+ */
43
+ page_set_flags(LO_COMMPAGE, LO_COMMPAGE + TARGET_PAGE_SIZE,
43
+ page_set_flags(LO_COMMPAGE, LO_COMMPAGE + TARGET_PAGE_SIZE,
44
+ PAGE_EXEC | PAGE_VALID);
44
+ PAGE_EXEC | PAGE_VALID);
45
+ return true;
45
+ return true;
46
+}
46
+}
47
+
47
+
48
#endif /* TARGET_HPPA */
48
#endif /* TARGET_HPPA */
49
49
50
#ifdef TARGET_XTENSA
50
#ifdef TARGET_XTENSA
51
@@ -XXX,XX +XXX,XX @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
51
@@ -XXX,XX +XXX,XX @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
52
}
52
}
53
53
54
#if defined(HI_COMMPAGE)
54
#if defined(HI_COMMPAGE)
55
-#define LO_COMMPAGE 0
55
-#define LO_COMMPAGE 0
56
+#define LO_COMMPAGE -1
56
+#define LO_COMMPAGE -1
57
#elif defined(LO_COMMPAGE)
57
#elif defined(LO_COMMPAGE)
58
#define HI_COMMPAGE 0
58
#define HI_COMMPAGE 0
59
#else
59
#else
60
#define HI_COMMPAGE 0
60
#define HI_COMMPAGE 0
61
-#define LO_COMMPAGE 0
61
-#define LO_COMMPAGE 0
62
+#define LO_COMMPAGE -1
62
+#define LO_COMMPAGE -1
63
#define init_guest_commpage() true
63
#define init_guest_commpage() true
64
#endif
64
#endif
65
65
66
@@ -XXX,XX +XXX,XX @@ static void pgb_static(const char *image_name, abi_ulong orig_loaddr,
66
@@ -XXX,XX +XXX,XX @@ static void pgb_static(const char *image_name, abi_ulong orig_loaddr,
67
} else {
67
} else {
68
offset = -(HI_COMMPAGE & -align);
68
offset = -(HI_COMMPAGE & -align);
69
}
69
}
70
- } else if (LO_COMMPAGE != 0) {
70
- } else if (LO_COMMPAGE != 0) {
71
+ } else if (LO_COMMPAGE != -1) {
71
+ } else if (LO_COMMPAGE != -1) {
72
loaddr = MIN(loaddr, LO_COMMPAGE & -align);
72
loaddr = MIN(loaddr, LO_COMMPAGE & -align);
73
}
73
}
74
74
75
--
75
--
76
2.34.1
76
2.34.1
diff view generated by jsdifflib
...
...
15
+++ b/linux-user/elfload.c
15
+++ b/linux-user/elfload.c
16
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
16
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
17
(*regs)[26] = tswapreg(env->segs[R_GS].selector & 0xffff);
17
(*regs)[26] = tswapreg(env->segs[R_GS].selector & 0xffff);
18
}
18
}
19
19
20
+#if ULONG_MAX >= TARGET_VSYSCALL_PAGE
20
+#if ULONG_MAX > UINT32_MAX
21
+#define INIT_GUEST_COMMPAGE
21
+#define INIT_GUEST_COMMPAGE
22
+static bool init_guest_commpage(void)
22
+static bool init_guest_commpage(void)
23
+{
23
+{
24
+ /*
24
+ /*
25
+ * The vsyscall page is at a high negative address aka kernel space,
25
+ * The vsyscall page is at a high negative address aka kernel space,
...
...
diff view generated by jsdifflib
Deleted patch
1
We cannot deliver two interrupts simultaneously;
2
the first interrupt handler must execute first.
3
1
4
Reviewed-by: Michael Rolnik <mrolnik@gmail.com>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/avr/helper.c | 9 +++------
9
1 file changed, 3 insertions(+), 6 deletions(-)
10
11
diff --git a/target/avr/helper.c b/target/avr/helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/avr/helper.c
14
+++ b/target/avr/helper.c
15
@@ -XXX,XX +XXX,XX @@
16
17
bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
18
{
19
- bool ret = false;
20
AVRCPU *cpu = AVR_CPU(cs);
21
CPUAVRState *env = &cpu->env;
22
23
@@ -XXX,XX +XXX,XX @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
24
avr_cpu_do_interrupt(cs);
25
26
cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
27
-
28
- ret = true;
29
+ return true;
30
}
31
}
32
if (interrupt_request & CPU_INTERRUPT_HARD) {
33
@@ -XXX,XX +XXX,XX @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
34
if (!env->intsrc) {
35
cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
36
}
37
-
38
- ret = true;
39
+ return true;
40
}
41
}
42
- return ret;
43
+ return false;
44
}
45
46
void avr_cpu_do_interrupt(CPUState *cs)
47
--
48
2.34.1
49
50
diff view generated by jsdifflib
Deleted patch
1
This bit is not saved across interrupts, so we must
2
delay delivering the interrupt until the skip has
3
been processed.
4
1
5
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1118
6
Reviewed-by: Michael Rolnik <mrolnik@gmail.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
10
target/avr/helper.c | 9 +++++++++
11
target/avr/translate.c | 26 ++++++++++++++++++++++----
12
2 files changed, 31 insertions(+), 4 deletions(-)
13
14
diff --git a/target/avr/helper.c b/target/avr/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/avr/helper.c
17
+++ b/target/avr/helper.c
18
@@ -XXX,XX +XXX,XX @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
19
AVRCPU *cpu = AVR_CPU(cs);
20
CPUAVRState *env = &cpu->env;
21
22
+ /*
23
+ * We cannot separate a skip from the next instruction,
24
+ * as the skip would not be preserved across the interrupt.
25
+ * Separating the two insn normally only happens at page boundaries.
26
+ */
27
+ if (env->skip) {
28
+ return false;
29
+ }
30
+
31
if (interrupt_request & CPU_INTERRUPT_RESET) {
32
if (cpu_interrupts_enabled(env)) {
33
cs->exception_index = EXCP_RESET;
34
diff --git a/target/avr/translate.c b/target/avr/translate.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/avr/translate.c
37
+++ b/target/avr/translate.c
38
@@ -XXX,XX +XXX,XX @@ static void avr_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
39
if (skip_label) {
40
canonicalize_skip(ctx);
41
gen_set_label(skip_label);
42
- if (ctx->base.is_jmp == DISAS_NORETURN) {
43
+
44
+ switch (ctx->base.is_jmp) {
45
+ case DISAS_NORETURN:
46
ctx->base.is_jmp = DISAS_CHAIN;
47
+ break;
48
+ case DISAS_NEXT:
49
+ if (ctx->base.tb->flags & TB_FLAGS_SKIP) {
50
+ ctx->base.is_jmp = DISAS_TOO_MANY;
51
+ }
52
+ break;
53
+ default:
54
+ break;
55
}
56
}
57
58
@@ -XXX,XX +XXX,XX @@ static void avr_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
59
{
60
DisasContext *ctx = container_of(dcbase, DisasContext, base);
61
bool nonconst_skip = canonicalize_skip(ctx);
62
+ /*
63
+ * Because we disable interrupts while env->skip is set,
64
+ * we must return to the main loop to re-evaluate afterward.
65
+ */
66
+ bool force_exit = ctx->base.tb->flags & TB_FLAGS_SKIP;
67
68
switch (ctx->base.is_jmp) {
69
case DISAS_NORETURN:
70
@@ -XXX,XX +XXX,XX @@ static void avr_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
71
case DISAS_NEXT:
72
case DISAS_TOO_MANY:
73
case DISAS_CHAIN:
74
- if (!nonconst_skip) {
75
+ if (!nonconst_skip && !force_exit) {
76
/* Note gen_goto_tb checks singlestep. */
77
gen_goto_tb(ctx, 1, ctx->npc);
78
break;
79
@@ -XXX,XX +XXX,XX @@ static void avr_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
80
tcg_gen_movi_tl(cpu_pc, ctx->npc);
81
/* fall through */
82
case DISAS_LOOKUP:
83
- tcg_gen_lookup_and_goto_ptr();
84
- break;
85
+ if (!force_exit) {
86
+ tcg_gen_lookup_and_goto_ptr();
87
+ break;
88
+ }
89
+ /* fall through */
90
case DISAS_EXIT:
91
tcg_gen_exit_tb(NULL, 0);
92
break;
93
--
94
2.34.1
95
96
diff view generated by jsdifflib
1
Map the stack executable if required by default or on demand.
1
Map the stack executable if required by default or on demand.
2
2
3
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
3
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
4
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
4
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
6
---
7
include/elf.h | 1 +
7
include/elf.h | 1 +
8
linux-user/qemu.h | 1 +
8
linux-user/qemu.h | 1 +
9
linux-user/elfload.c | 19 ++++++++++++++++++-
9
linux-user/elfload.c | 19 ++++++++++++++++++-
10
3 files changed, 20 insertions(+), 1 deletion(-)
10
3 files changed, 20 insertions(+), 1 deletion(-)
11
11
12
diff --git a/include/elf.h b/include/elf.h
12
diff --git a/include/elf.h b/include/elf.h
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/elf.h
14
--- a/include/elf.h
15
+++ b/include/elf.h
15
+++ b/include/elf.h
16
@@ -XXX,XX +XXX,XX @@ typedef int64_t Elf64_Sxword;
16
@@ -XXX,XX +XXX,XX @@ typedef int64_t Elf64_Sxword;
17
#define PT_LOPROC 0x70000000
17
#define PT_LOPROC 0x70000000
18
#define PT_HIPROC 0x7fffffff
18
#define PT_HIPROC 0x7fffffff
19
19
20
+#define PT_GNU_STACK (PT_LOOS + 0x474e551)
20
+#define PT_GNU_STACK (PT_LOOS + 0x474e551)
21
#define PT_GNU_PROPERTY (PT_LOOS + 0x474e553)
21
#define PT_GNU_PROPERTY (PT_LOOS + 0x474e553)
22
22
23
#define PT_MIPS_REGINFO 0x70000000
23
#define PT_MIPS_REGINFO 0x70000000
24
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
24
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
25
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
26
--- a/linux-user/qemu.h
26
--- a/linux-user/qemu.h
27
+++ b/linux-user/qemu.h
27
+++ b/linux-user/qemu.h
28
@@ -XXX,XX +XXX,XX @@ struct image_info {
28
@@ -XXX,XX +XXX,XX @@ struct image_info {
29
uint32_t elf_flags;
29
uint32_t elf_flags;
30
int personality;
30
int personality;
31
abi_ulong alignment;
31
abi_ulong alignment;
32
+ bool exec_stack;
32
+ bool exec_stack;
33
33
34
/* Generic semihosting knows about these pointers. */
34
/* Generic semihosting knows about these pointers. */
35
abi_ulong arg_strings; /* strings for argv */
35
abi_ulong arg_strings; /* strings for argv */
36
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
36
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
37
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
38
--- a/linux-user/elfload.c
38
--- a/linux-user/elfload.c
39
+++ b/linux-user/elfload.c
39
+++ b/linux-user/elfload.c
40
@@ -XXX,XX +XXX,XX @@ static bool init_guest_commpage(void)
40
@@ -XXX,XX +XXX,XX @@ static bool init_guest_commpage(void)
41
#define ELF_ARCH EM_386
41
#define ELF_ARCH EM_386
42
42
43
#define ELF_PLATFORM get_elf_platform()
43
#define ELF_PLATFORM get_elf_platform()
44
+#define EXSTACK_DEFAULT true
44
+#define EXSTACK_DEFAULT true
45
45
46
static const char *get_elf_platform(void)
46
static const char *get_elf_platform(void)
47
{
47
{
48
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
48
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
49
49
50
#define ELF_ARCH EM_ARM
50
#define ELF_ARCH EM_ARM
51
#define ELF_CLASS ELFCLASS32
51
#define ELF_CLASS ELFCLASS32
52
+#define EXSTACK_DEFAULT true
52
+#define EXSTACK_DEFAULT true
53
53
54
static inline void init_thread(struct target_pt_regs *regs,
54
static inline void init_thread(struct target_pt_regs *regs,
55
struct image_info *infop)
55
struct image_info *infop)
56
@@ -XXX,XX +XXX,XX @@ static inline void init_thread(struct target_pt_regs *regs,
56
@@ -XXX,XX +XXX,XX @@ static inline void init_thread(struct target_pt_regs *regs,
57
#else
57
#else
58
58
59
#define ELF_CLASS ELFCLASS32
59
#define ELF_CLASS ELFCLASS32
60
+#define EXSTACK_DEFAULT true
60
+#define EXSTACK_DEFAULT true
61
61
62
#endif
62
#endif
63
63
64
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en
64
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en
65
65
66
#define ELF_CLASS ELFCLASS64
66
#define ELF_CLASS ELFCLASS64
67
#define ELF_ARCH EM_LOONGARCH
67
#define ELF_ARCH EM_LOONGARCH
68
+#define EXSTACK_DEFAULT true
68
+#define EXSTACK_DEFAULT true
69
69
70
#define elf_check_arch(x) ((x) == EM_LOONGARCH)
70
#define elf_check_arch(x) ((x) == EM_LOONGARCH)
71
71
72
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
72
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
73
#define ELF_CLASS ELFCLASS32
73
#define ELF_CLASS ELFCLASS32
74
#endif
74
#endif
75
#define ELF_ARCH EM_MIPS
75
#define ELF_ARCH EM_MIPS
76
+#define EXSTACK_DEFAULT true
76
+#define EXSTACK_DEFAULT true
77
77
78
#ifdef TARGET_ABI_MIPSN32
78
#ifdef TARGET_ABI_MIPSN32
79
#define elf_check_abi(x) ((x) & EF_MIPS_ABI2)
79
#define elf_check_abi(x) ((x) & EF_MIPS_ABI2)
80
@@ -XXX,XX +XXX,XX @@ static inline void init_thread(struct target_pt_regs *regs,
80
@@ -XXX,XX +XXX,XX @@ static inline void init_thread(struct target_pt_regs *regs,
81
#define bswaptls(ptr) bswap32s(ptr)
81
#define bswaptls(ptr) bswap32s(ptr)
82
#endif
82
#endif
83
83
84
+#ifndef EXSTACK_DEFAULT
84
+#ifndef EXSTACK_DEFAULT
85
+#define EXSTACK_DEFAULT false
85
+#define EXSTACK_DEFAULT false
86
+#endif
86
+#endif
87
+
87
+
88
#include "elf.h"
88
#include "elf.h"
89
89
90
/* We must delay the following stanzas until after "elf.h". */
90
/* We must delay the following stanzas until after "elf.h". */
91
@@ -XXX,XX +XXX,XX @@ static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
91
@@ -XXX,XX +XXX,XX @@ static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
92
struct image_info *info)
92
struct image_info *info)
93
{
93
{
94
abi_ulong size, error, guard;
94
abi_ulong size, error, guard;
95
+ int prot;
95
+ int prot;
96
96
97
size = guest_stack_size;
97
size = guest_stack_size;
98
if (size < STACK_LOWER_LIMIT) {
98
if (size < STACK_LOWER_LIMIT) {
99
@@ -XXX,XX +XXX,XX @@ static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
99
@@ -XXX,XX +XXX,XX @@ static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
100
guard = qemu_real_host_page_size();
100
guard = qemu_real_host_page_size();
101
}
101
}
102
102
103
- error = target_mmap(0, size + guard, PROT_READ | PROT_WRITE,
103
- error = target_mmap(0, size + guard, PROT_READ | PROT_WRITE,
104
+ prot = PROT_READ | PROT_WRITE;
104
+ prot = PROT_READ | PROT_WRITE;
105
+ if (info->exec_stack) {
105
+ if (info->exec_stack) {
106
+ prot |= PROT_EXEC;
106
+ prot |= PROT_EXEC;
107
+ }
107
+ }
108
+ error = target_mmap(0, size + guard, prot,
108
+ error = target_mmap(0, size + guard, prot,
109
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
109
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
110
if (error == -1) {
110
if (error == -1) {
111
perror("mmap stack");
111
perror("mmap stack");
112
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
112
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
113
*/
113
*/
114
loaddr = -1, hiaddr = 0;
114
loaddr = -1, hiaddr = 0;
115
info->alignment = 0;
115
info->alignment = 0;
116
+ info->exec_stack = EXSTACK_DEFAULT;
116
+ info->exec_stack = EXSTACK_DEFAULT;
117
for (i = 0; i < ehdr->e_phnum; ++i) {
117
for (i = 0; i < ehdr->e_phnum; ++i) {
118
struct elf_phdr *eppnt = phdr + i;
118
struct elf_phdr *eppnt = phdr + i;
119
if (eppnt->p_type == PT_LOAD) {
119
if (eppnt->p_type == PT_LOAD) {
120
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
120
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
121
if (!parse_elf_properties(image_fd, info, eppnt, bprm_buf, &err)) {
121
if (!parse_elf_properties(image_fd, info, eppnt, bprm_buf, &err)) {
122
goto exit_errmsg;
122
goto exit_errmsg;
123
}
123
}
124
+ } else if (eppnt->p_type == PT_GNU_STACK) {
124
+ } else if (eppnt->p_type == PT_GNU_STACK) {
125
+ info->exec_stack = eppnt->p_flags & PF_X;
125
+ info->exec_stack = eppnt->p_flags & PF_X;
126
}
126
}
127
}
127
}
128
128
129
--
129
--
130
2.34.1
130
2.34.1
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
2
2
3
Currently it's possible to execute pages that do not have PAGE_EXEC
3
Currently it's possible to execute pages that do not have PAGE_EXEC
4
if there is an existing translation block. Fix by invalidating TBs
4
if there is an existing translation block. Fix by invalidating TBs
5
that touch the affected pages.
5
that touch the affected pages.
6
6
7
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Message-Id: <20220817150506.592862-2-iii@linux.ibm.com>
8
Message-Id: <20220817150506.592862-2-iii@linux.ibm.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
10
---
11
linux-user/mmap.c | 6 ++++--
11
linux-user/mmap.c | 6 ++++--
12
1 file changed, 4 insertions(+), 2 deletions(-)
12
1 file changed, 4 insertions(+), 2 deletions(-)
13
13
14
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
14
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/mmap.c
16
--- a/linux-user/mmap.c
17
+++ b/linux-user/mmap.c
17
+++ b/linux-user/mmap.c
18
@@ -XXX,XX +XXX,XX @@ int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
18
@@ -XXX,XX +XXX,XX @@ int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
19
goto error;
19
goto error;
20
}
20
}
21
}
21
}
22
+
22
+
23
page_set_flags(start, start + len, page_flags);
23
page_set_flags(start, start + len, page_flags);
24
- mmap_unlock();
24
- mmap_unlock();
25
- return 0;
25
- return 0;
26
+ tb_invalidate_phys_range(start, start + len);
26
+ tb_invalidate_phys_range(start, start + len);
27
+ ret = 0;
27
+ ret = 0;
28
+
28
+
29
error:
29
error:
30
mmap_unlock();
30
mmap_unlock();
31
return ret;
31
return ret;
32
--
32
--
33
2.34.1
33
2.34.1
diff view generated by jsdifflib
1
We're about to start validating PAGE_EXEC, which means
1
We're about to start validating PAGE_EXEC, which means
2
that we've got to put this code into a section that is
2
that we've got to put this code into a section that is
3
both writable and executable.
3
both writable and executable.
4
4
5
Note that this test did not run on hardware beforehand either.
5
Note that this test did not run on hardware beforehand either.
6
6
7
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
10
---
11
tests/tcg/i386/test-i386.c | 2 +-
11
tests/tcg/i386/test-i386.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
13
14
diff --git a/tests/tcg/i386/test-i386.c b/tests/tcg/i386/test-i386.c
14
diff --git a/tests/tcg/i386/test-i386.c b/tests/tcg/i386/test-i386.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/tcg/i386/test-i386.c
16
--- a/tests/tcg/i386/test-i386.c
17
+++ b/tests/tcg/i386/test-i386.c
17
+++ b/tests/tcg/i386/test-i386.c
18
@@ -XXX,XX +XXX,XX @@ uint8_t code[] = {
18
@@ -XXX,XX +XXX,XX @@ uint8_t code[] = {
19
0xc3, /* ret */
19
0xc3, /* ret */
20
};
20
};
21
21
22
-asm(".section \".data\"\n"
22
-asm(".section \".data\"\n"
23
+asm(".section \".data_x\",\"awx\"\n"
23
+asm(".section \".data_x\",\"awx\"\n"
24
"smc_code2:\n"
24
"smc_code2:\n"
25
"movl 4(%esp), %eax\n"
25
"movl 4(%esp), %eax\n"
26
"movl %eax, smc_patch_addr2 + 1\n"
26
"movl %eax, smc_patch_addr2 + 1\n"
27
--
27
--
28
2.34.1
28
2.34.1
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
2
2
3
Introduce a function that checks whether a given address is on the same
3
Introduce a function that checks whether a given address is on the same
4
page as where disassembly started. Having it improves readability of
4
page as where disassembly started. Having it improves readability of
5
the following patches.
5
the following patches.
6
6
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
9
Message-Id: <20220811095534.241224-3-iii@linux.ibm.com>
9
Message-Id: <20220811095534.241224-3-iii@linux.ibm.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
[rth: Make the DisasContextBase parameter const.]
11
[rth: Make the DisasContextBase parameter const.]
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
---
13
---
14
include/exec/translator.h | 10 ++++++++++
14
include/exec/translator.h | 10 ++++++++++
15
1 file changed, 10 insertions(+)
15
1 file changed, 10 insertions(+)
16
16
17
diff --git a/include/exec/translator.h b/include/exec/translator.h
17
diff --git a/include/exec/translator.h b/include/exec/translator.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/translator.h
19
--- a/include/exec/translator.h
20
+++ b/include/exec/translator.h
20
+++ b/include/exec/translator.h
21
@@ -XXX,XX +XXX,XX @@ FOR_EACH_TRANSLATOR_LD(GEN_TRANSLATOR_LD)
21
@@ -XXX,XX +XXX,XX @@ FOR_EACH_TRANSLATOR_LD(GEN_TRANSLATOR_LD)
22
22
23
#undef GEN_TRANSLATOR_LD
23
#undef GEN_TRANSLATOR_LD
24
24
25
+/*
25
+/*
26
+ * Return whether addr is on the same page as where disassembly started.
26
+ * Return whether addr is on the same page as where disassembly started.
27
+ * Translators can use this to enforce the rule that only single-insn
27
+ * Translators can use this to enforce the rule that only single-insn
28
+ * translation blocks are allowed to cross page boundaries.
28
+ * translation blocks are allowed to cross page boundaries.
29
+ */
29
+ */
30
+static inline bool is_same_page(const DisasContextBase *db, target_ulong addr)
30
+static inline bool is_same_page(const DisasContextBase *db, target_ulong addr)
31
+{
31
+{
32
+ return ((addr ^ db->pc_first) & TARGET_PAGE_MASK) == 0;
32
+ return ((addr ^ db->pc_first) & TARGET_PAGE_MASK) == 0;
33
+}
33
+}
34
+
34
+
35
#endif /* EXEC__TRANSLATOR_H */
35
#endif /* EXEC__TRANSLATOR_H */
36
--
36
--
37
2.34.1
37
2.34.1
diff view generated by jsdifflib
1
The current implementation is a no-op, simply returning addr.
1
The current implementation is a no-op, simply returning addr.
2
This is incorrect, because we ought to be checking the page
2
This is incorrect, because we ought to be checking the page
3
permissions for execution.
3
permissions for execution.
4
4
5
Make get_page_addr_code inline for both implementations.
5
Make get_page_addr_code inline for both implementations.
6
6
7
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
11
---
12
include/exec/exec-all.h | 85 ++++++++++++++---------------------------
12
include/exec/exec-all.h | 85 ++++++++++++++---------------------------
13
accel/tcg/cputlb.c | 5 ---
13
accel/tcg/cputlb.c | 5 ---
14
accel/tcg/user-exec.c | 14 +++++++
14
accel/tcg/user-exec.c | 14 +++++++
15
3 files changed, 42 insertions(+), 62 deletions(-)
15
3 files changed, 42 insertions(+), 62 deletions(-)
16
16
17
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
17
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/exec-all.h
19
--- a/include/exec/exec-all.h
20
+++ b/include/exec/exec-all.h
20
+++ b/include/exec/exec-all.h
21
@@ -XXX,XX +XXX,XX @@ struct MemoryRegionSection *iotlb_to_section(CPUState *cpu,
21
@@ -XXX,XX +XXX,XX @@ struct MemoryRegionSection *iotlb_to_section(CPUState *cpu,
22
hwaddr index, MemTxAttrs attrs);
22
hwaddr index, MemTxAttrs attrs);
23
#endif
23
#endif
24
24
25
-#if defined(CONFIG_USER_ONLY)
25
-#if defined(CONFIG_USER_ONLY)
26
-void mmap_lock(void);
26
-void mmap_lock(void);
27
-void mmap_unlock(void);
27
-void mmap_unlock(void);
28
-bool have_mmap_lock(void);
28
-bool have_mmap_lock(void);
29
-
29
-
30
/**
30
/**
31
- * get_page_addr_code() - user-mode version
31
- * get_page_addr_code() - user-mode version
32
+ * get_page_addr_code_hostp()
32
+ * get_page_addr_code_hostp()
33
* @env: CPUArchState
33
* @env: CPUArchState
34
* @addr: guest virtual address of guest code
34
* @addr: guest virtual address of guest code
35
*
35
*
36
- * Returns @addr.
36
- * Returns @addr.
37
+ * See get_page_addr_code() (full-system version) for documentation on the
37
+ * See get_page_addr_code() (full-system version) for documentation on the
38
+ * return value.
38
+ * return value.
39
+ *
39
+ *
40
+ * Sets *@hostp (when @hostp is non-NULL) as follows.
40
+ * Sets *@hostp (when @hostp is non-NULL) as follows.
41
+ * If the return value is -1, sets *@hostp to NULL. Otherwise, sets *@hostp
41
+ * If the return value is -1, sets *@hostp to NULL. Otherwise, sets *@hostp
42
+ * to the host address where @addr's content is kept.
42
+ * to the host address where @addr's content is kept.
43
+ *
43
+ *
44
+ * Note: this function can trigger an exception.
44
+ * Note: this function can trigger an exception.
45
+ */
45
+ */
46
+tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
46
+tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
47
+ void **hostp);
47
+ void **hostp);
48
+
48
+
49
+/**
49
+/**
50
+ * get_page_addr_code()
50
+ * get_page_addr_code()
51
+ * @env: CPUArchState
51
+ * @env: CPUArchState
52
+ * @addr: guest virtual address of guest code
52
+ * @addr: guest virtual address of guest code
53
+ *
53
+ *
54
+ * If we cannot translate and execute from the entire RAM page, or if
54
+ * If we cannot translate and execute from the entire RAM page, or if
55
+ * the region is not backed by RAM, returns -1. Otherwise, returns the
55
+ * the region is not backed by RAM, returns -1. Otherwise, returns the
56
+ * ram_addr_t corresponding to the guest code at @addr.
56
+ * ram_addr_t corresponding to the guest code at @addr.
57
+ *
57
+ *
58
+ * Note: this function can trigger an exception.
58
+ * Note: this function can trigger an exception.
59
*/
59
*/
60
static inline tb_page_addr_t get_page_addr_code(CPUArchState *env,
60
static inline tb_page_addr_t get_page_addr_code(CPUArchState *env,
61
target_ulong addr)
61
target_ulong addr)
62
{
62
{
63
- return addr;
63
- return addr;
64
+ return get_page_addr_code_hostp(env, addr, NULL);
64
+ return get_page_addr_code_hostp(env, addr, NULL);
65
}
65
}
66
66
67
-/**
67
-/**
68
- * get_page_addr_code_hostp() - user-mode version
68
- * get_page_addr_code_hostp() - user-mode version
69
- * @env: CPUArchState
69
- * @env: CPUArchState
70
- * @addr: guest virtual address of guest code
70
- * @addr: guest virtual address of guest code
71
- *
71
- *
72
- * Returns @addr.
72
- * Returns @addr.
73
- *
73
- *
74
- * If @hostp is non-NULL, sets *@hostp to the host address where @addr's content
74
- * If @hostp is non-NULL, sets *@hostp to the host address where @addr's content
75
- * is kept.
75
- * is kept.
76
- */
76
- */
77
-static inline tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env,
77
-static inline tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env,
78
- target_ulong addr,
78
- target_ulong addr,
79
- void **hostp)
79
- void **hostp)
80
-{
80
-{
81
- if (hostp) {
81
- if (hostp) {
82
- *hostp = g2h_untagged(addr);
82
- *hostp = g2h_untagged(addr);
83
- }
83
- }
84
- return addr;
84
- return addr;
85
-}
85
-}
86
+#if defined(CONFIG_USER_ONLY)
86
+#if defined(CONFIG_USER_ONLY)
87
+void mmap_lock(void);
87
+void mmap_lock(void);
88
+void mmap_unlock(void);
88
+void mmap_unlock(void);
89
+bool have_mmap_lock(void);
89
+bool have_mmap_lock(void);
90
90
91
/**
91
/**
92
* adjust_signal_pc:
92
* adjust_signal_pc:
93
@@ -XXX,XX +XXX,XX @@ G_NORETURN void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
93
@@ -XXX,XX +XXX,XX @@ G_NORETURN void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
94
static inline void mmap_lock(void) {}
94
static inline void mmap_lock(void) {}
95
static inline void mmap_unlock(void) {}
95
static inline void mmap_unlock(void) {}
96
96
97
-/**
97
-/**
98
- * get_page_addr_code() - full-system version
98
- * get_page_addr_code() - full-system version
99
- * @env: CPUArchState
99
- * @env: CPUArchState
100
- * @addr: guest virtual address of guest code
100
- * @addr: guest virtual address of guest code
101
- *
101
- *
102
- * If we cannot translate and execute from the entire RAM page, or if
102
- * If we cannot translate and execute from the entire RAM page, or if
103
- * the region is not backed by RAM, returns -1. Otherwise, returns the
103
- * the region is not backed by RAM, returns -1. Otherwise, returns the
104
- * ram_addr_t corresponding to the guest code at @addr.
104
- * ram_addr_t corresponding to the guest code at @addr.
105
- *
105
- *
106
- * Note: this function can trigger an exception.
106
- * Note: this function can trigger an exception.
107
- */
107
- */
108
-tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr);
108
-tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr);
109
-
109
-
110
-/**
110
-/**
111
- * get_page_addr_code_hostp() - full-system version
111
- * get_page_addr_code_hostp() - full-system version
112
- * @env: CPUArchState
112
- * @env: CPUArchState
113
- * @addr: guest virtual address of guest code
113
- * @addr: guest virtual address of guest code
114
- *
114
- *
115
- * See get_page_addr_code() (full-system version) for documentation on the
115
- * See get_page_addr_code() (full-system version) for documentation on the
116
- * return value.
116
- * return value.
117
- *
117
- *
118
- * Sets *@hostp (when @hostp is non-NULL) as follows.
118
- * Sets *@hostp (when @hostp is non-NULL) as follows.
119
- * If the return value is -1, sets *@hostp to NULL. Otherwise, sets *@hostp
119
- * If the return value is -1, sets *@hostp to NULL. Otherwise, sets *@hostp
120
- * to the host address where @addr's content is kept.
120
- * to the host address where @addr's content is kept.
121
- *
121
- *
122
- * Note: this function can trigger an exception.
122
- * Note: this function can trigger an exception.
123
- */
123
- */
124
-tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
124
-tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
125
- void **hostp);
125
- void **hostp);
126
-
126
-
127
void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length);
127
void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length);
128
void tlb_set_dirty(CPUState *cpu, target_ulong vaddr);
128
void tlb_set_dirty(CPUState *cpu, target_ulong vaddr);
129
129
130
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
130
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
131
index XXXXXXX..XXXXXXX 100644
131
index XXXXXXX..XXXXXXX 100644
132
--- a/accel/tcg/cputlb.c
132
--- a/accel/tcg/cputlb.c
133
+++ b/accel/tcg/cputlb.c
133
+++ b/accel/tcg/cputlb.c
134
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
134
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
135
return qemu_ram_addr_from_host_nofail(p);
135
return qemu_ram_addr_from_host_nofail(p);
136
}
136
}
137
137
138
-tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
138
-tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
139
-{
139
-{
140
- return get_page_addr_code_hostp(env, addr, NULL);
140
- return get_page_addr_code_hostp(env, addr, NULL);
141
-}
141
-}
142
-
142
-
143
static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size,
143
static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size,
144
CPUIOTLBEntry *iotlbentry, uintptr_t retaddr)
144
CPUIOTLBEntry *iotlbentry, uintptr_t retaddr)
145
{
145
{
146
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
146
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
147
index XXXXXXX..XXXXXXX 100644
147
index XXXXXXX..XXXXXXX 100644
148
--- a/accel/tcg/user-exec.c
148
--- a/accel/tcg/user-exec.c
149
+++ b/accel/tcg/user-exec.c
149
+++ b/accel/tcg/user-exec.c
150
@@ -XXX,XX +XXX,XX @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
150
@@ -XXX,XX +XXX,XX @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
151
return size ? g2h(env_cpu(env), addr) : NULL;
151
return size ? g2h(env_cpu(env), addr) : NULL;
152
}
152
}
153
153
154
+tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
154
+tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
155
+ void **hostp)
155
+ void **hostp)
156
+{
156
+{
157
+ int flags;
157
+ int flags;
158
+
158
+
159
+ flags = probe_access_internal(env, addr, 1, MMU_INST_FETCH, false, 0);
159
+ flags = probe_access_internal(env, addr, 1, MMU_INST_FETCH, false, 0);
160
+ g_assert(flags == 0);
160
+ g_assert(flags == 0);
161
+
161
+
162
+ if (hostp) {
162
+ if (hostp) {
163
+ *hostp = g2h_untagged(addr);
163
+ *hostp = g2h_untagged(addr);
164
+ }
164
+ }
165
+ return addr;
165
+ return addr;
166
+}
166
+}
167
+
167
+
168
/* The softmmu versions of these helpers are in cputlb.c. */
168
/* The softmmu versions of these helpers are in cputlb.c. */
169
169
170
/*
170
/*
171
--
171
--
172
2.34.1
172
2.34.1
diff view generated by jsdifflib
1
The mmap_lock is held around tb_gen_code. While the comment
1
The mmap_lock is held around tb_gen_code. While the comment
2
is correct that the lock is dropped when tb_gen_code runs out
2
is correct that the lock is dropped when tb_gen_code runs out
3
of memory, the lock is *not* dropped when an exception is
3
of memory, the lock is *not* dropped when an exception is
4
raised reading code for translation.
4
raised reading code for translation.
5
5
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
10
---
11
accel/tcg/cpu-exec.c | 12 ++++++------
11
accel/tcg/cpu-exec.c | 12 ++++++------
12
accel/tcg/user-exec.c | 3 ---
12
accel/tcg/user-exec.c | 3 ---
13
2 files changed, 6 insertions(+), 9 deletions(-)
13
2 files changed, 6 insertions(+), 9 deletions(-)
14
14
15
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
15
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/accel/tcg/cpu-exec.c
17
--- a/accel/tcg/cpu-exec.c
18
+++ b/accel/tcg/cpu-exec.c
18
+++ b/accel/tcg/cpu-exec.c
19
@@ -XXX,XX +XXX,XX @@ void cpu_exec_step_atomic(CPUState *cpu)
19
@@ -XXX,XX +XXX,XX @@ void cpu_exec_step_atomic(CPUState *cpu)
20
cpu_tb_exec(cpu, tb, &tb_exit);
20
cpu_tb_exec(cpu, tb, &tb_exit);
21
cpu_exec_exit(cpu);
21
cpu_exec_exit(cpu);
22
} else {
22
} else {
23
- /*
23
- /*
24
- * The mmap_lock is dropped by tb_gen_code if it runs out of
24
- * The mmap_lock is dropped by tb_gen_code if it runs out of
25
- * memory.
25
- * memory.
26
- */
26
- */
27
#ifndef CONFIG_SOFTMMU
27
#ifndef CONFIG_SOFTMMU
28
clear_helper_retaddr();
28
clear_helper_retaddr();
29
- tcg_debug_assert(!have_mmap_lock());
29
- tcg_debug_assert(!have_mmap_lock());
30
+ if (have_mmap_lock()) {
30
+ if (have_mmap_lock()) {
31
+ mmap_unlock();
31
+ mmap_unlock();
32
+ }
32
+ }
33
#endif
33
#endif
34
if (qemu_mutex_iothread_locked()) {
34
if (qemu_mutex_iothread_locked()) {
35
qemu_mutex_unlock_iothread();
35
qemu_mutex_unlock_iothread();
36
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
36
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
37
37
38
#ifndef CONFIG_SOFTMMU
38
#ifndef CONFIG_SOFTMMU
39
clear_helper_retaddr();
39
clear_helper_retaddr();
40
- tcg_debug_assert(!have_mmap_lock());
40
- tcg_debug_assert(!have_mmap_lock());
41
+ if (have_mmap_lock()) {
41
+ if (have_mmap_lock()) {
42
+ mmap_unlock();
42
+ mmap_unlock();
43
+ }
43
+ }
44
#endif
44
#endif
45
if (qemu_mutex_iothread_locked()) {
45
if (qemu_mutex_iothread_locked()) {
46
qemu_mutex_unlock_iothread();
46
qemu_mutex_unlock_iothread();
47
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
47
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
48
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
49
--- a/accel/tcg/user-exec.c
49
--- a/accel/tcg/user-exec.c
50
+++ b/accel/tcg/user-exec.c
50
+++ b/accel/tcg/user-exec.c
51
@@ -XXX,XX +XXX,XX @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write)
51
@@ -XXX,XX +XXX,XX @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write)
52
* (and if the translator doesn't handle page boundaries correctly
52
* (and if the translator doesn't handle page boundaries correctly
53
* there's little we can do about that here). Therefore, do not
53
* there's little we can do about that here). Therefore, do not
54
* trigger the unwinder.
54
* trigger the unwinder.
55
- *
55
- *
56
- * Like tb_gen_code, release the memory lock before cpu_loop_exit.
56
- * Like tb_gen_code, release the memory lock before cpu_loop_exit.
57
*/
57
*/
58
- mmap_unlock();
58
- mmap_unlock();
59
*pc = 0;
59
*pc = 0;
60
return MMU_INST_FETCH;
60
return MMU_INST_FETCH;
61
}
61
}
62
--
62
--
63
2.34.1
63
2.34.1
diff view generated by jsdifflib
1
The function is not used outside of cpu-exec.c. Move it and
1
The function is not used outside of cpu-exec.c. Move it and
2
its subroutines up in the file, before the first use.
2
its subroutines up in the file, before the first use.
3
3
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
5
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
8
---
9
include/exec/exec-all.h | 3 -
9
include/exec/exec-all.h | 3 -
10
accel/tcg/cpu-exec.c | 122 ++++++++++++++++++++--------------------
10
accel/tcg/cpu-exec.c | 122 ++++++++++++++++++++--------------------
11
2 files changed, 61 insertions(+), 64 deletions(-)
11
2 files changed, 61 insertions(+), 64 deletions(-)
12
12
13
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
13
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/exec/exec-all.h
15
--- a/include/exec/exec-all.h
16
+++ b/include/exec/exec-all.h
16
+++ b/include/exec/exec-all.h
17
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs);
17
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs);
18
#endif
18
#endif
19
void tb_flush(CPUState *cpu);
19
void tb_flush(CPUState *cpu);
20
void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
20
void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
21
-TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
21
-TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
22
- target_ulong cs_base, uint32_t flags,
22
- target_ulong cs_base, uint32_t flags,
23
- uint32_t cflags);
23
- uint32_t cflags);
24
void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr);
24
void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr);
25
25
26
/* GETPC is the true target of the return instruction that we'll execute. */
26
/* GETPC is the true target of the return instruction that we'll execute. */
27
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
27
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
28
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
29
--- a/accel/tcg/cpu-exec.c
29
--- a/accel/tcg/cpu-exec.c
30
+++ b/accel/tcg/cpu-exec.c
30
+++ b/accel/tcg/cpu-exec.c
31
@@ -XXX,XX +XXX,XX @@ uint32_t curr_cflags(CPUState *cpu)
31
@@ -XXX,XX +XXX,XX @@ uint32_t curr_cflags(CPUState *cpu)
32
return cflags;
32
return cflags;
33
}
33
}
34
34
35
+struct tb_desc {
35
+struct tb_desc {
36
+ target_ulong pc;
36
+ target_ulong pc;
37
+ target_ulong cs_base;
37
+ target_ulong cs_base;
38
+ CPUArchState *env;
38
+ CPUArchState *env;
39
+ tb_page_addr_t phys_page1;
39
+ tb_page_addr_t phys_page1;
40
+ uint32_t flags;
40
+ uint32_t flags;
41
+ uint32_t cflags;
41
+ uint32_t cflags;
42
+ uint32_t trace_vcpu_dstate;
42
+ uint32_t trace_vcpu_dstate;
43
+};
43
+};
44
+
44
+
45
+static bool tb_lookup_cmp(const void *p, const void *d)
45
+static bool tb_lookup_cmp(const void *p, const void *d)
46
+{
46
+{
47
+ const TranslationBlock *tb = p;
47
+ const TranslationBlock *tb = p;
48
+ const struct tb_desc *desc = d;
48
+ const struct tb_desc *desc = d;
49
+
49
+
50
+ if (tb->pc == desc->pc &&
50
+ if (tb->pc == desc->pc &&
51
+ tb->page_addr[0] == desc->phys_page1 &&
51
+ tb->page_addr[0] == desc->phys_page1 &&
52
+ tb->cs_base == desc->cs_base &&
52
+ tb->cs_base == desc->cs_base &&
53
+ tb->flags == desc->flags &&
53
+ tb->flags == desc->flags &&
54
+ tb->trace_vcpu_dstate == desc->trace_vcpu_dstate &&
54
+ tb->trace_vcpu_dstate == desc->trace_vcpu_dstate &&
55
+ tb_cflags(tb) == desc->cflags) {
55
+ tb_cflags(tb) == desc->cflags) {
56
+ /* check next page if needed */
56
+ /* check next page if needed */
57
+ if (tb->page_addr[1] == -1) {
57
+ if (tb->page_addr[1] == -1) {
58
+ return true;
58
+ return true;
59
+ } else {
59
+ } else {
60
+ tb_page_addr_t phys_page2;
60
+ tb_page_addr_t phys_page2;
61
+ target_ulong virt_page2;
61
+ target_ulong virt_page2;
62
+
62
+
63
+ virt_page2 = (desc->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
63
+ virt_page2 = (desc->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
64
+ phys_page2 = get_page_addr_code(desc->env, virt_page2);
64
+ phys_page2 = get_page_addr_code(desc->env, virt_page2);
65
+ if (tb->page_addr[1] == phys_page2) {
65
+ if (tb->page_addr[1] == phys_page2) {
66
+ return true;
66
+ return true;
67
+ }
67
+ }
68
+ }
68
+ }
69
+ }
69
+ }
70
+ return false;
70
+ return false;
71
+}
71
+}
72
+
72
+
73
+static TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
73
+static TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
74
+ target_ulong cs_base, uint32_t flags,
74
+ target_ulong cs_base, uint32_t flags,
75
+ uint32_t cflags)
75
+ uint32_t cflags)
76
+{
76
+{
77
+ tb_page_addr_t phys_pc;
77
+ tb_page_addr_t phys_pc;
78
+ struct tb_desc desc;
78
+ struct tb_desc desc;
79
+ uint32_t h;
79
+ uint32_t h;
80
+
80
+
81
+ desc.env = cpu->env_ptr;
81
+ desc.env = cpu->env_ptr;
82
+ desc.cs_base = cs_base;
82
+ desc.cs_base = cs_base;
83
+ desc.flags = flags;
83
+ desc.flags = flags;
84
+ desc.cflags = cflags;
84
+ desc.cflags = cflags;
85
+ desc.trace_vcpu_dstate = *cpu->trace_dstate;
85
+ desc.trace_vcpu_dstate = *cpu->trace_dstate;
86
+ desc.pc = pc;
86
+ desc.pc = pc;
87
+ phys_pc = get_page_addr_code(desc.env, pc);
87
+ phys_pc = get_page_addr_code(desc.env, pc);
88
+ if (phys_pc == -1) {
88
+ if (phys_pc == -1) {
89
+ return NULL;
89
+ return NULL;
90
+ }
90
+ }
91
+ desc.phys_page1 = phys_pc & TARGET_PAGE_MASK;
91
+ desc.phys_page1 = phys_pc & TARGET_PAGE_MASK;
92
+ h = tb_hash_func(phys_pc, pc, flags, cflags, *cpu->trace_dstate);
92
+ h = tb_hash_func(phys_pc, pc, flags, cflags, *cpu->trace_dstate);
93
+ return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
93
+ return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
94
+}
94
+}
95
+
95
+
96
/* Might cause an exception, so have a longjmp destination ready */
96
/* Might cause an exception, so have a longjmp destination ready */
97
static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
97
static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
98
target_ulong cs_base,
98
target_ulong cs_base,
99
@@ -XXX,XX +XXX,XX @@ void cpu_exec_step_atomic(CPUState *cpu)
99
@@ -XXX,XX +XXX,XX @@ void cpu_exec_step_atomic(CPUState *cpu)
100
end_exclusive();
100
end_exclusive();
101
}
101
}
102
102
103
-struct tb_desc {
103
-struct tb_desc {
104
- target_ulong pc;
104
- target_ulong pc;
105
- target_ulong cs_base;
105
- target_ulong cs_base;
106
- CPUArchState *env;
106
- CPUArchState *env;
107
- tb_page_addr_t phys_page1;
107
- tb_page_addr_t phys_page1;
108
- uint32_t flags;
108
- uint32_t flags;
109
- uint32_t cflags;
109
- uint32_t cflags;
110
- uint32_t trace_vcpu_dstate;
110
- uint32_t trace_vcpu_dstate;
111
-};
111
-};
112
-
112
-
113
-static bool tb_lookup_cmp(const void *p, const void *d)
113
-static bool tb_lookup_cmp(const void *p, const void *d)
114
-{
114
-{
115
- const TranslationBlock *tb = p;
115
- const TranslationBlock *tb = p;
116
- const struct tb_desc *desc = d;
116
- const struct tb_desc *desc = d;
117
-
117
-
118
- if (tb->pc == desc->pc &&
118
- if (tb->pc == desc->pc &&
119
- tb->page_addr[0] == desc->phys_page1 &&
119
- tb->page_addr[0] == desc->phys_page1 &&
120
- tb->cs_base == desc->cs_base &&
120
- tb->cs_base == desc->cs_base &&
121
- tb->flags == desc->flags &&
121
- tb->flags == desc->flags &&
122
- tb->trace_vcpu_dstate == desc->trace_vcpu_dstate &&
122
- tb->trace_vcpu_dstate == desc->trace_vcpu_dstate &&
123
- tb_cflags(tb) == desc->cflags) {
123
- tb_cflags(tb) == desc->cflags) {
124
- /* check next page if needed */
124
- /* check next page if needed */
125
- if (tb->page_addr[1] == -1) {
125
- if (tb->page_addr[1] == -1) {
126
- return true;
126
- return true;
127
- } else {
127
- } else {
128
- tb_page_addr_t phys_page2;
128
- tb_page_addr_t phys_page2;
129
- target_ulong virt_page2;
129
- target_ulong virt_page2;
130
-
130
-
131
- virt_page2 = (desc->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
131
- virt_page2 = (desc->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
132
- phys_page2 = get_page_addr_code(desc->env, virt_page2);
132
- phys_page2 = get_page_addr_code(desc->env, virt_page2);
133
- if (tb->page_addr[1] == phys_page2) {
133
- if (tb->page_addr[1] == phys_page2) {
134
- return true;
134
- return true;
135
- }
135
- }
136
- }
136
- }
137
- }
137
- }
138
- return false;
138
- return false;
139
-}
139
-}
140
-
140
-
141
-TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
141
-TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
142
- target_ulong cs_base, uint32_t flags,
142
- target_ulong cs_base, uint32_t flags,
143
- uint32_t cflags)
143
- uint32_t cflags)
144
-{
144
-{
145
- tb_page_addr_t phys_pc;
145
- tb_page_addr_t phys_pc;
146
- struct tb_desc desc;
146
- struct tb_desc desc;
147
- uint32_t h;
147
- uint32_t h;
148
-
148
-
149
- desc.env = cpu->env_ptr;
149
- desc.env = cpu->env_ptr;
150
- desc.cs_base = cs_base;
150
- desc.cs_base = cs_base;
151
- desc.flags = flags;
151
- desc.flags = flags;
152
- desc.cflags = cflags;
152
- desc.cflags = cflags;
153
- desc.trace_vcpu_dstate = *cpu->trace_dstate;
153
- desc.trace_vcpu_dstate = *cpu->trace_dstate;
154
- desc.pc = pc;
154
- desc.pc = pc;
155
- phys_pc = get_page_addr_code(desc.env, pc);
155
- phys_pc = get_page_addr_code(desc.env, pc);
156
- if (phys_pc == -1) {
156
- if (phys_pc == -1) {
157
- return NULL;
157
- return NULL;
158
- }
158
- }
159
- desc.phys_page1 = phys_pc & TARGET_PAGE_MASK;
159
- desc.phys_page1 = phys_pc & TARGET_PAGE_MASK;
160
- h = tb_hash_func(phys_pc, pc, flags, cflags, *cpu->trace_dstate);
160
- h = tb_hash_func(phys_pc, pc, flags, cflags, *cpu->trace_dstate);
161
- return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
161
- return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
162
-}
162
-}
163
-
163
-
164
void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr)
164
void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr)
165
{
165
{
166
if (TCG_TARGET_HAS_direct_jump) {
166
if (TCG_TARGET_HAS_direct_jump) {
167
--
167
--
168
2.34.1
168
2.34.1
diff view generated by jsdifflib
1
The base qemu_ram_addr_from_host function is already in
1
The base qemu_ram_addr_from_host function is already in
2
softmmu/physmem.c; move the nofail version to be adjacent.
2
softmmu/physmem.c; move the nofail version to be adjacent.
3
3
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
5
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
8
---
9
include/exec/cpu-common.h | 1 +
9
include/exec/cpu-common.h | 1 +
10
accel/tcg/cputlb.c | 12 ------------
10
accel/tcg/cputlb.c | 12 ------------
11
softmmu/physmem.c | 12 ++++++++++++
11
softmmu/physmem.c | 12 ++++++++++++
12
3 files changed, 13 insertions(+), 12 deletions(-)
12
3 files changed, 13 insertions(+), 12 deletions(-)
13
13
14
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
14
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/cpu-common.h
16
--- a/include/exec/cpu-common.h
17
+++ b/include/exec/cpu-common.h
17
+++ b/include/exec/cpu-common.h
18
@@ -XXX,XX +XXX,XX @@ typedef uintptr_t ram_addr_t;
18
@@ -XXX,XX +XXX,XX @@ typedef uintptr_t ram_addr_t;
19
void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
19
void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
20
/* This should not be used by devices. */
20
/* This should not be used by devices. */
21
ram_addr_t qemu_ram_addr_from_host(void *ptr);
21
ram_addr_t qemu_ram_addr_from_host(void *ptr);
22
+ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
22
+ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
23
RAMBlock *qemu_ram_block_by_name(const char *name);
23
RAMBlock *qemu_ram_block_by_name(const char *name);
24
RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
24
RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
25
ram_addr_t *offset);
25
ram_addr_t *offset);
26
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
26
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
27
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
28
--- a/accel/tcg/cputlb.c
28
--- a/accel/tcg/cputlb.c
29
+++ b/accel/tcg/cputlb.c
29
+++ b/accel/tcg/cputlb.c
30
@@ -XXX,XX +XXX,XX @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
30
@@ -XXX,XX +XXX,XX @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
31
prot, mmu_idx, size);
31
prot, mmu_idx, size);
32
}
32
}
33
33
34
-static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
34
-static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
35
-{
35
-{
36
- ram_addr_t ram_addr;
36
- ram_addr_t ram_addr;
37
-
37
-
38
- ram_addr = qemu_ram_addr_from_host(ptr);
38
- ram_addr = qemu_ram_addr_from_host(ptr);
39
- if (ram_addr == RAM_ADDR_INVALID) {
39
- if (ram_addr == RAM_ADDR_INVALID) {
40
- error_report("Bad ram pointer %p", ptr);
40
- error_report("Bad ram pointer %p", ptr);
41
- abort();
41
- abort();
42
- }
42
- }
43
- return ram_addr;
43
- return ram_addr;
44
-}
44
-}
45
-
45
-
46
/*
46
/*
47
* Note: tlb_fill() can trigger a resize of the TLB. This means that all of the
47
* Note: tlb_fill() can trigger a resize of the TLB. This means that all of the
48
* caller's prior references to the TLB table (e.g. CPUTLBEntry pointers) must
48
* caller's prior references to the TLB table (e.g. CPUTLBEntry pointers) must
49
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
49
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
50
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
51
--- a/softmmu/physmem.c
51
--- a/softmmu/physmem.c
52
+++ b/softmmu/physmem.c
52
+++ b/softmmu/physmem.c
53
@@ -XXX,XX +XXX,XX @@ ram_addr_t qemu_ram_addr_from_host(void *ptr)
53
@@ -XXX,XX +XXX,XX @@ ram_addr_t qemu_ram_addr_from_host(void *ptr)
54
return block->offset + offset;
54
return block->offset + offset;
55
}
55
}
56
56
57
+ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
57
+ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
58
+{
58
+{
59
+ ram_addr_t ram_addr;
59
+ ram_addr_t ram_addr;
60
+
60
+
61
+ ram_addr = qemu_ram_addr_from_host(ptr);
61
+ ram_addr = qemu_ram_addr_from_host(ptr);
62
+ if (ram_addr == RAM_ADDR_INVALID) {
62
+ if (ram_addr == RAM_ADDR_INVALID) {
63
+ error_report("Bad ram pointer %p", ptr);
63
+ error_report("Bad ram pointer %p", ptr);
64
+ abort();
64
+ abort();
65
+ }
65
+ }
66
+ return ram_addr;
66
+ return ram_addr;
67
+}
67
+}
68
+
68
+
69
static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
69
static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
70
MemTxAttrs attrs, void *buf, hwaddr len);
70
MemTxAttrs attrs, void *buf, hwaddr len);
71
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
71
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
72
--
72
--
73
2.34.1
73
2.34.1
diff view generated by jsdifflib
1
Simplify the implementation of get_page_addr_code_hostp
1
Simplify the implementation of get_page_addr_code_hostp
2
by reusing the existing probe_access infrastructure.
2
by reusing the existing probe_access infrastructure.
3
3
4
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
4
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
5
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
5
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
7
---
8
accel/tcg/cputlb.c | 76 ++++++++++++++++------------------------------
8
accel/tcg/cputlb.c | 76 ++++++++++++++++------------------------------
9
1 file changed, 26 insertions(+), 50 deletions(-)
9
1 file changed, 26 insertions(+), 50 deletions(-)
10
10
11
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
11
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/accel/tcg/cputlb.c
13
--- a/accel/tcg/cputlb.c
14
+++ b/accel/tcg/cputlb.c
14
+++ b/accel/tcg/cputlb.c
15
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
15
@@ -XXX,XX +XXX,XX @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
16
victim_tlb_hit(env, mmu_idx, index, offsetof(CPUTLBEntry, TY), \
16
victim_tlb_hit(env, mmu_idx, index, offsetof(CPUTLBEntry, TY), \
17
(ADDR) & TARGET_PAGE_MASK)
17
(ADDR) & TARGET_PAGE_MASK)
18
18
19
-/*
19
-/*
20
- * Return a ram_addr_t for the virtual address for execution.
20
- * Return a ram_addr_t for the virtual address for execution.
21
- *
21
- *
22
- * Return -1 if we can't translate and execute from an entire page
22
- * Return -1 if we can't translate and execute from an entire page
23
- * of RAM. This will force us to execute by loading and translating
23
- * of RAM. This will force us to execute by loading and translating
24
- * one insn at a time, without caching.
24
- * one insn at a time, without caching.
25
- *
25
- *
26
- * NOTE: This function will trigger an exception if the page is
26
- * NOTE: This function will trigger an exception if the page is
27
- * not executable.
27
- * not executable.
28
- */
28
- */
29
-tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
29
-tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
30
- void **hostp)
30
- void **hostp)
31
-{
31
-{
32
- uintptr_t mmu_idx = cpu_mmu_index(env, true);
32
- uintptr_t mmu_idx = cpu_mmu_index(env, true);
33
- uintptr_t index = tlb_index(env, mmu_idx, addr);
33
- uintptr_t index = tlb_index(env, mmu_idx, addr);
34
- CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
34
- CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
35
- void *p;
35
- void *p;
36
-
36
-
37
- if (unlikely(!tlb_hit(entry->addr_code, addr))) {
37
- if (unlikely(!tlb_hit(entry->addr_code, addr))) {
38
- if (!VICTIM_TLB_HIT(addr_code, addr)) {
38
- if (!VICTIM_TLB_HIT(addr_code, addr)) {
39
- tlb_fill(env_cpu(env), addr, 0, MMU_INST_FETCH, mmu_idx, 0);
39
- tlb_fill(env_cpu(env), addr, 0, MMU_INST_FETCH, mmu_idx, 0);
40
- index = tlb_index(env, mmu_idx, addr);
40
- index = tlb_index(env, mmu_idx, addr);
41
- entry = tlb_entry(env, mmu_idx, addr);
41
- entry = tlb_entry(env, mmu_idx, addr);
42
-
42
-
43
- if (unlikely(entry->addr_code & TLB_INVALID_MASK)) {
43
- if (unlikely(entry->addr_code & TLB_INVALID_MASK)) {
44
- /*
44
- /*
45
- * The MMU protection covers a smaller range than a target
45
- * The MMU protection covers a smaller range than a target
46
- * page, so we must redo the MMU check for every insn.
46
- * page, so we must redo the MMU check for every insn.
47
- */
47
- */
48
- return -1;
48
- return -1;
49
- }
49
- }
50
- }
50
- }
51
- assert(tlb_hit(entry->addr_code, addr));
51
- assert(tlb_hit(entry->addr_code, addr));
52
- }
52
- }
53
-
53
-
54
- if (unlikely(entry->addr_code & TLB_MMIO)) {
54
- if (unlikely(entry->addr_code & TLB_MMIO)) {
55
- /* The region is not backed by RAM. */
55
- /* The region is not backed by RAM. */
56
- if (hostp) {
56
- if (hostp) {
57
- *hostp = NULL;
57
- *hostp = NULL;
58
- }
58
- }
59
- return -1;
59
- return -1;
60
- }
60
- }
61
-
61
-
62
- p = (void *)((uintptr_t)addr + entry->addend);
62
- p = (void *)((uintptr_t)addr + entry->addend);
63
- if (hostp) {
63
- if (hostp) {
64
- *hostp = p;
64
- *hostp = p;
65
- }
65
- }
66
- return qemu_ram_addr_from_host_nofail(p);
66
- return qemu_ram_addr_from_host_nofail(p);
67
-}
67
-}
68
-
68
-
69
static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size,
69
static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size,
70
CPUIOTLBEntry *iotlbentry, uintptr_t retaddr)
70
CPUIOTLBEntry *iotlbentry, uintptr_t retaddr)
71
{
71
{
72
@@ -XXX,XX +XXX,XX @@ void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
72
@@ -XXX,XX +XXX,XX @@ void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
73
return flags ? NULL : host;
73
return flags ? NULL : host;
74
}
74
}
75
75
76
+/*
76
+/*
77
+ * Return a ram_addr_t for the virtual address for execution.
77
+ * Return a ram_addr_t for the virtual address for execution.
78
+ *
78
+ *
79
+ * Return -1 if we can't translate and execute from an entire page
79
+ * Return -1 if we can't translate and execute from an entire page
80
+ * of RAM. This will force us to execute by loading and translating
80
+ * of RAM. This will force us to execute by loading and translating
81
+ * one insn at a time, without caching.
81
+ * one insn at a time, without caching.
82
+ *
82
+ *
83
+ * NOTE: This function will trigger an exception if the page is
83
+ * NOTE: This function will trigger an exception if the page is
84
+ * not executable.
84
+ * not executable.
85
+ */
85
+ */
86
+tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
86
+tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
87
+ void **hostp)
87
+ void **hostp)
88
+{
88
+{
89
+ void *p;
89
+ void *p;
90
+
90
+
91
+ (void)probe_access_internal(env, addr, 1, MMU_INST_FETCH,
91
+ (void)probe_access_internal(env, addr, 1, MMU_INST_FETCH,
92
+ cpu_mmu_index(env, true), false, &p, 0);
92
+ cpu_mmu_index(env, true), false, &p, 0);
93
+ if (p == NULL) {
93
+ if (p == NULL) {
94
+ return -1;
94
+ return -1;
95
+ }
95
+ }
96
+ if (hostp) {
96
+ if (hostp) {
97
+ *hostp = p;
97
+ *hostp = p;
98
+ }
98
+ }
99
+ return qemu_ram_addr_from_host_nofail(p);
99
+ return qemu_ram_addr_from_host_nofail(p);
100
+}
100
+}
101
+
101
+
102
#ifdef CONFIG_PLUGIN
102
#ifdef CONFIG_PLUGIN
103
/*
103
/*
104
* Perform a TLB lookup and populate the qemu_plugin_hwaddr structure.
104
* Perform a TLB lookup and populate the qemu_plugin_hwaddr structure.
105
--
105
--
106
2.34.1
106
2.34.1
diff view generated by jsdifflib
1
It was non-obvious to me why we can raise an exception in
1
It was non-obvious to me why we can raise an exception in
2
the middle of a comparison function, but it works.
2
the middle of a comparison function, but it works.
3
While nearby, use TARGET_PAGE_ALIGN instead of open-coding.
3
While nearby, use TARGET_PAGE_ALIGN instead of open-coding.
4
4
5
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
5
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
7
---
8
accel/tcg/cpu-exec.c | 11 ++++++++++-
8
accel/tcg/cpu-exec.c | 11 ++++++++++-
9
1 file changed, 10 insertions(+), 1 deletion(-)
9
1 file changed, 10 insertions(+), 1 deletion(-)
10
10
11
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
11
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/accel/tcg/cpu-exec.c
13
--- a/accel/tcg/cpu-exec.c
14
+++ b/accel/tcg/cpu-exec.c
14
+++ b/accel/tcg/cpu-exec.c
15
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
15
@@ -XXX,XX +XXX,XX @@ static bool tb_lookup_cmp(const void *p, const void *d)
16
tb_page_addr_t phys_page2;
16
tb_page_addr_t phys_page2;
17
target_ulong virt_page2;
17
target_ulong virt_page2;
18
18
19
- virt_page2 = (desc->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
19
- virt_page2 = (desc->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
20
+ /*
20
+ /*
21
+ * We know that the first page matched, and an otherwise valid TB
21
+ * We know that the first page matched, and an otherwise valid TB
22
+ * encountered an incomplete instruction at the end of that page,
22
+ * encountered an incomplete instruction at the end of that page,
23
+ * therefore we know that generating a new TB from the current PC
23
+ * therefore we know that generating a new TB from the current PC
24
+ * must also require reading from the next page -- even if the
24
+ * must also require reading from the next page -- even if the
25
+ * second pages do not match, and therefore the resulting insn
25
+ * second pages do not match, and therefore the resulting insn
26
+ * is different for the new TB. Therefore any exception raised
26
+ * is different for the new TB. Therefore any exception raised
27
+ * here by the faulting lookup is not premature.
27
+ * here by the faulting lookup is not premature.
28
+ */
28
+ */
29
+ virt_page2 = TARGET_PAGE_ALIGN(desc->pc);
29
+ virt_page2 = TARGET_PAGE_ALIGN(desc->pc);
30
phys_page2 = get_page_addr_code(desc->env, virt_page2);
30
phys_page2 = get_page_addr_code(desc->env, virt_page2);
31
if (tb->page_addr[1] == phys_page2) {
31
if (tb->page_addr[1] == phys_page2) {
32
return true;
32
return true;
33
--
33
--
34
2.34.1
34
2.34.1
diff view generated by jsdifflib
1
The only user can easily use translator_lduw and
1
The only user can easily use translator_lduw and
2
adjust the type to signed during the return.
2
adjust the type to signed during the return.
3
3
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
5
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
---
8
---
9
include/exec/translator.h | 1 -
9
include/exec/translator.h | 1 -
10
target/i386/tcg/translate.c | 2 +-
10
target/i386/tcg/translate.c | 2 +-
11
2 files changed, 1 insertion(+), 2 deletions(-)
11
2 files changed, 1 insertion(+), 2 deletions(-)
12
12
13
diff --git a/include/exec/translator.h b/include/exec/translator.h
13
diff --git a/include/exec/translator.h b/include/exec/translator.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/exec/translator.h
15
--- a/include/exec/translator.h
16
+++ b/include/exec/translator.h
16
+++ b/include/exec/translator.h
17
@@ -XXX,XX +XXX,XX @@ bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest);
17
@@ -XXX,XX +XXX,XX @@ bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest);
18
18
19
#define FOR_EACH_TRANSLATOR_LD(F) \
19
#define FOR_EACH_TRANSLATOR_LD(F) \
20
F(translator_ldub, uint8_t, cpu_ldub_code, /* no swap */) \
20
F(translator_ldub, uint8_t, cpu_ldub_code, /* no swap */) \
21
- F(translator_ldsw, int16_t, cpu_ldsw_code, bswap16) \
21
- F(translator_ldsw, int16_t, cpu_ldsw_code, bswap16) \
22
F(translator_lduw, uint16_t, cpu_lduw_code, bswap16) \
22
F(translator_lduw, uint16_t, cpu_lduw_code, bswap16) \
23
F(translator_ldl, uint32_t, cpu_ldl_code, bswap32) \
23
F(translator_ldl, uint32_t, cpu_ldl_code, bswap32) \
24
F(translator_ldq, uint64_t, cpu_ldq_code, bswap64)
24
F(translator_ldq, uint64_t, cpu_ldq_code, bswap64)
25
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
25
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
26
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/i386/tcg/translate.c
27
--- a/target/i386/tcg/translate.c
28
+++ b/target/i386/tcg/translate.c
28
+++ b/target/i386/tcg/translate.c
29
@@ -XXX,XX +XXX,XX @@ static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
29
@@ -XXX,XX +XXX,XX @@ static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
30
30
31
static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
31
static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
32
{
32
{
33
- return translator_ldsw(env, &s->base, advance_pc(env, s, 2));
33
- return translator_ldsw(env, &s->base, advance_pc(env, s, 2));
34
+ return translator_lduw(env, &s->base, advance_pc(env, s, 2));
34
+ return translator_lduw(env, &s->base, advance_pc(env, s, 2));
35
}
35
}
36
36
37
static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
37
static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
38
--
38
--
39
2.34.1
39
2.34.1
diff view generated by jsdifflib
1
Pass these along to translator_loop -- pc may be used instead
1
Pass these along to translator_loop -- pc may be used instead
2
of tb->pc, and host_pc is currently unused. Adjust all targets
2
of tb->pc, and host_pc is currently unused. Adjust all targets
3
at one time.
3
at one time.
4
4
5
Acked-by: Alistair Francis <alistair.francis@wdc.com>
5
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
9
---
10
include/exec/exec-all.h | 1 -
10
include/exec/exec-all.h | 1 -
11
include/exec/translator.h | 24 ++++++++++++++++++++----
11
include/exec/translator.h | 24 ++++++++++++++++++++----
12
accel/tcg/translate-all.c | 6 ++++--
12
accel/tcg/translate-all.c | 6 ++++--
13
accel/tcg/translator.c | 9 +++++----
13
accel/tcg/translator.c | 9 +++++----
14
target/alpha/translate.c | 5 +++--
14
target/alpha/translate.c | 5 +++--
15
target/arm/translate.c | 5 +++--
15
target/arm/translate.c | 5 +++--
16
target/avr/translate.c | 5 +++--
16
target/avr/translate.c | 5 +++--
17
target/cris/translate.c | 5 +++--
17
target/cris/translate.c | 5 +++--
18
target/hexagon/translate.c | 6 ++++--
18
target/hexagon/translate.c | 6 ++++--
19
target/hppa/translate.c | 5 +++--
19
target/hppa/translate.c | 5 +++--
20
target/i386/tcg/translate.c | 5 +++--
20
target/i386/tcg/translate.c | 5 +++--
21
target/loongarch/translate.c | 6 ++++--
21
target/loongarch/translate.c | 6 ++++--
22
target/m68k/translate.c | 5 +++--
22
target/m68k/translate.c | 5 +++--
23
target/microblaze/translate.c | 5 +++--
23
target/microblaze/translate.c | 5 +++--
24
target/mips/tcg/translate.c | 5 +++--
24
target/mips/tcg/translate.c | 5 +++--
25
target/nios2/translate.c | 5 +++--
25
target/nios2/translate.c | 5 +++--
26
target/openrisc/translate.c | 6 ++++--
26
target/openrisc/translate.c | 6 ++++--
27
target/ppc/translate.c | 5 +++--
27
target/ppc/translate.c | 5 +++--
28
target/riscv/translate.c | 5 +++--
28
target/riscv/translate.c | 5 +++--
29
target/rx/translate.c | 5 +++--
29
target/rx/translate.c | 5 +++--
30
target/s390x/tcg/translate.c | 5 +++--
30
target/s390x/tcg/translate.c | 5 +++--
31
target/sh4/translate.c | 5 +++--
31
target/sh4/translate.c | 5 +++--
32
target/sparc/translate.c | 5 +++--
32
target/sparc/translate.c | 5 +++--
33
target/tricore/translate.c | 6 ++++--
33
target/tricore/translate.c | 6 ++++--
34
target/xtensa/translate.c | 6 ++++--
34
target/xtensa/translate.c | 6 ++++--
35
25 files changed, 97 insertions(+), 53 deletions(-)
35
25 files changed, 97 insertions(+), 53 deletions(-)
36
36
37
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
37
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
38
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/exec/exec-all.h
39
--- a/include/exec/exec-all.h
40
+++ b/include/exec/exec-all.h
40
+++ b/include/exec/exec-all.h
41
@@ -XXX,XX +XXX,XX @@ typedef ram_addr_t tb_page_addr_t;
41
@@ -XXX,XX +XXX,XX @@ typedef ram_addr_t tb_page_addr_t;
42
#define TB_PAGE_ADDR_FMT RAM_ADDR_FMT
42
#define TB_PAGE_ADDR_FMT RAM_ADDR_FMT
43
#endif
43
#endif
44
44
45
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns);
45
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns);
46
void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb,
46
void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb,
47
target_ulong *data);
47
target_ulong *data);
48
48
49
diff --git a/include/exec/translator.h b/include/exec/translator.h
49
diff --git a/include/exec/translator.h b/include/exec/translator.h
50
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
51
--- a/include/exec/translator.h
51
--- a/include/exec/translator.h
52
+++ b/include/exec/translator.h
52
+++ b/include/exec/translator.h
53
@@ -XXX,XX +XXX,XX @@
53
@@ -XXX,XX +XXX,XX @@
54
#include "exec/translate-all.h"
54
#include "exec/translate-all.h"
55
#include "tcg/tcg.h"
55
#include "tcg/tcg.h"
56
56
57
+/**
57
+/**
58
+ * gen_intermediate_code
58
+ * gen_intermediate_code
59
+ * @cpu: cpu context
59
+ * @cpu: cpu context
60
+ * @tb: translation block
60
+ * @tb: translation block
61
+ * @max_insns: max number of instructions to translate
61
+ * @max_insns: max number of instructions to translate
62
+ * @pc: guest virtual program counter address
62
+ * @pc: guest virtual program counter address
63
+ * @host_pc: host physical program counter address
63
+ * @host_pc: host physical program counter address
64
+ *
64
+ *
65
+ * This function must be provided by the target, which should create
65
+ * This function must be provided by the target, which should create
66
+ * the target-specific DisasContext, and then invoke translator_loop.
66
+ * the target-specific DisasContext, and then invoke translator_loop.
67
+ */
67
+ */
68
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
68
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
69
+ target_ulong pc, void *host_pc);
69
+ target_ulong pc, void *host_pc);
70
70
71
/**
71
/**
72
* DisasJumpType:
72
* DisasJumpType:
73
@@ -XXX,XX +XXX,XX @@ typedef struct TranslatorOps {
73
@@ -XXX,XX +XXX,XX @@ typedef struct TranslatorOps {
74
74
75
/**
75
/**
76
* translator_loop:
76
* translator_loop:
77
- * @ops: Target-specific operations.
77
- * @ops: Target-specific operations.
78
- * @db: Disassembly context.
78
- * @db: Disassembly context.
79
* @cpu: Target vCPU.
79
* @cpu: Target vCPU.
80
* @tb: Translation block.
80
* @tb: Translation block.
81
* @max_insns: Maximum number of insns to translate.
81
* @max_insns: Maximum number of insns to translate.
82
+ * @pc: guest virtual program counter address
82
+ * @pc: guest virtual program counter address
83
+ * @host_pc: host physical program counter address
83
+ * @host_pc: host physical program counter address
84
+ * @ops: Target-specific operations.
84
+ * @ops: Target-specific operations.
85
+ * @db: Disassembly context.
85
+ * @db: Disassembly context.
86
*
86
*
87
* Generic translator loop.
87
* Generic translator loop.
88
*
88
*
89
@@ -XXX,XX +XXX,XX @@ typedef struct TranslatorOps {
89
@@ -XXX,XX +XXX,XX @@ typedef struct TranslatorOps {
90
* - When single-stepping is enabled (system-wide or on the current vCPU).
90
* - When single-stepping is enabled (system-wide or on the current vCPU).
91
* - When too many instructions have been translated.
91
* - When too many instructions have been translated.
92
*/
92
*/
93
-void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
93
-void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
94
- CPUState *cpu, TranslationBlock *tb, int max_insns);
94
- CPUState *cpu, TranslationBlock *tb, int max_insns);
95
+void translator_loop(CPUState *cpu, TranslationBlock *tb, int max_insns,
95
+void translator_loop(CPUState *cpu, TranslationBlock *tb, int max_insns,
96
+ target_ulong pc, void *host_pc,
96
+ target_ulong pc, void *host_pc,
97
+ const TranslatorOps *ops, DisasContextBase *db);
97
+ const TranslatorOps *ops, DisasContextBase *db);
98
98
99
void translator_loop_temp_check(DisasContextBase *db);
99
void translator_loop_temp_check(DisasContextBase *db);
100
100
101
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
101
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
102
index XXXXXXX..XXXXXXX 100644
102
index XXXXXXX..XXXXXXX 100644
103
--- a/accel/tcg/translate-all.c
103
--- a/accel/tcg/translate-all.c
104
+++ b/accel/tcg/translate-all.c
104
+++ b/accel/tcg/translate-all.c
105
@@ -XXX,XX +XXX,XX @@
105
@@ -XXX,XX +XXX,XX @@
106
106
107
#include "exec/cputlb.h"
107
#include "exec/cputlb.h"
108
#include "exec/translate-all.h"
108
#include "exec/translate-all.h"
109
+#include "exec/translator.h"
109
+#include "exec/translator.h"
110
#include "qemu/bitmap.h"
110
#include "qemu/bitmap.h"
111
#include "qemu/qemu-print.h"
111
#include "qemu/qemu-print.h"
112
#include "qemu/timer.h"
112
#include "qemu/timer.h"
113
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
113
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
114
TCGProfile *prof = &tcg_ctx->prof;
114
TCGProfile *prof = &tcg_ctx->prof;
115
int64_t ti;
115
int64_t ti;
116
#endif
116
#endif
117
+ void *host_pc;
117
+ void *host_pc;
118
118
119
assert_memory_lock();
119
assert_memory_lock();
120
qemu_thread_jit_write();
120
qemu_thread_jit_write();
121
121
122
- phys_pc = get_page_addr_code(env, pc);
122
- phys_pc = get_page_addr_code(env, pc);
123
+ phys_pc = get_page_addr_code_hostp(env, pc, &host_pc);
123
+ phys_pc = get_page_addr_code_hostp(env, pc, &host_pc);
124
124
125
if (phys_pc == -1) {
125
if (phys_pc == -1) {
126
/* Generate a one-shot TB with 1 insn in it */
126
/* Generate a one-shot TB with 1 insn in it */
127
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
127
@@ -XXX,XX +XXX,XX @@ TranslationBlock *tb_gen_code(CPUState *cpu,
128
tcg_func_start(tcg_ctx);
128
tcg_func_start(tcg_ctx);
129
129
130
tcg_ctx->cpu = env_cpu(env);
130
tcg_ctx->cpu = env_cpu(env);
131
- gen_intermediate_code(cpu, tb, max_insns);
131
- gen_intermediate_code(cpu, tb, max_insns);
132
+ gen_intermediate_code(cpu, tb, max_insns, pc, host_pc);
132
+ gen_intermediate_code(cpu, tb, max_insns, pc, host_pc);
133
assert(tb->size != 0);
133
assert(tb->size != 0);
134
tcg_ctx->cpu = NULL;
134
tcg_ctx->cpu = NULL;
135
max_insns = tb->icount;
135
max_insns = tb->icount;
136
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
136
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
137
index XXXXXXX..XXXXXXX 100644
137
index XXXXXXX..XXXXXXX 100644
138
--- a/accel/tcg/translator.c
138
--- a/accel/tcg/translator.c
139
+++ b/accel/tcg/translator.c
139
+++ b/accel/tcg/translator.c
140
@@ -XXX,XX +XXX,XX @@ static inline void translator_page_protect(DisasContextBase *dcbase,
140
@@ -XXX,XX +XXX,XX @@ static inline void translator_page_protect(DisasContextBase *dcbase,
141
#endif
141
#endif
142
}
142
}
143
143
144
-void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
144
-void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
145
- CPUState *cpu, TranslationBlock *tb, int max_insns)
145
- CPUState *cpu, TranslationBlock *tb, int max_insns)
146
+void translator_loop(CPUState *cpu, TranslationBlock *tb, int max_insns,
146
+void translator_loop(CPUState *cpu, TranslationBlock *tb, int max_insns,
147
+ target_ulong pc, void *host_pc,
147
+ target_ulong pc, void *host_pc,
148
+ const TranslatorOps *ops, DisasContextBase *db)
148
+ const TranslatorOps *ops, DisasContextBase *db)
149
{
149
{
150
uint32_t cflags = tb_cflags(tb);
150
uint32_t cflags = tb_cflags(tb);
151
bool plugin_enabled;
151
bool plugin_enabled;
152
152
153
/* Initialize DisasContext */
153
/* Initialize DisasContext */
154
db->tb = tb;
154
db->tb = tb;
155
- db->pc_first = tb->pc;
155
- db->pc_first = tb->pc;
156
- db->pc_next = db->pc_first;
156
- db->pc_next = db->pc_first;
157
+ db->pc_first = pc;
157
+ db->pc_first = pc;
158
+ db->pc_next = pc;
158
+ db->pc_next = pc;
159
db->is_jmp = DISAS_NEXT;
159
db->is_jmp = DISAS_NEXT;
160
db->num_insns = 0;
160
db->num_insns = 0;
161
db->max_insns = max_insns;
161
db->max_insns = max_insns;
162
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
162
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
163
index XXXXXXX..XXXXXXX 100644
163
index XXXXXXX..XXXXXXX 100644
164
--- a/target/alpha/translate.c
164
--- a/target/alpha/translate.c
165
+++ b/target/alpha/translate.c
165
+++ b/target/alpha/translate.c
166
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps alpha_tr_ops = {
166
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps alpha_tr_ops = {
167
.disas_log = alpha_tr_disas_log,
167
.disas_log = alpha_tr_disas_log,
168
};
168
};
169
169
170
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
170
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
171
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
171
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
172
+ target_ulong pc, void *host_pc)
172
+ target_ulong pc, void *host_pc)
173
{
173
{
174
DisasContext dc;
174
DisasContext dc;
175
- translator_loop(&alpha_tr_ops, &dc.base, cpu, tb, max_insns);
175
- translator_loop(&alpha_tr_ops, &dc.base, cpu, tb, max_insns);
176
+ translator_loop(cpu, tb, max_insns, pc, host_pc, &alpha_tr_ops, &dc.base);
176
+ translator_loop(cpu, tb, max_insns, pc, host_pc, &alpha_tr_ops, &dc.base);
177
}
177
}
178
178
179
void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb,
179
void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb,
180
diff --git a/target/arm/translate.c b/target/arm/translate.c
180
diff --git a/target/arm/translate.c b/target/arm/translate.c
181
index XXXXXXX..XXXXXXX 100644
181
index XXXXXXX..XXXXXXX 100644
182
--- a/target/arm/translate.c
182
--- a/target/arm/translate.c
183
+++ b/target/arm/translate.c
183
+++ b/target/arm/translate.c
184
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps thumb_translator_ops = {
184
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps thumb_translator_ops = {
185
};
185
};
186
186
187
/* generate intermediate code for basic block 'tb'. */
187
/* generate intermediate code for basic block 'tb'. */
188
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
188
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
189
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
189
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
190
+ target_ulong pc, void *host_pc)
190
+ target_ulong pc, void *host_pc)
191
{
191
{
192
DisasContext dc = { };
192
DisasContext dc = { };
193
const TranslatorOps *ops = &arm_translator_ops;
193
const TranslatorOps *ops = &arm_translator_ops;
194
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
194
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
195
}
195
}
196
#endif
196
#endif
197
197
198
- translator_loop(ops, &dc.base, cpu, tb, max_insns);
198
- translator_loop(ops, &dc.base, cpu, tb, max_insns);
199
+ translator_loop(cpu, tb, max_insns, pc, host_pc, ops, &dc.base);
199
+ translator_loop(cpu, tb, max_insns, pc, host_pc, ops, &dc.base);
200
}
200
}
201
201
202
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
202
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
203
diff --git a/target/avr/translate.c b/target/avr/translate.c
203
diff --git a/target/avr/translate.c b/target/avr/translate.c
204
index XXXXXXX..XXXXXXX 100644
204
index XXXXXXX..XXXXXXX 100644
205
--- a/target/avr/translate.c
205
--- a/target/avr/translate.c
206
+++ b/target/avr/translate.c
206
+++ b/target/avr/translate.c
207
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps avr_tr_ops = {
207
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps avr_tr_ops = {
208
.disas_log = avr_tr_disas_log,
208
.disas_log = avr_tr_disas_log,
209
};
209
};
210
210
211
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
211
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
212
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
212
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
213
+ target_ulong pc, void *host_pc)
213
+ target_ulong pc, void *host_pc)
214
{
214
{
215
DisasContext dc = { };
215
DisasContext dc = { };
216
- translator_loop(&avr_tr_ops, &dc.base, cs, tb, max_insns);
216
- translator_loop(&avr_tr_ops, &dc.base, cs, tb, max_insns);
217
+ translator_loop(cs, tb, max_insns, pc, host_pc, &avr_tr_ops, &dc.base);
217
+ translator_loop(cs, tb, max_insns, pc, host_pc, &avr_tr_ops, &dc.base);
218
}
218
}
219
219
220
void restore_state_to_opc(CPUAVRState *env, TranslationBlock *tb,
220
void restore_state_to_opc(CPUAVRState *env, TranslationBlock *tb,
221
diff --git a/target/cris/translate.c b/target/cris/translate.c
221
diff --git a/target/cris/translate.c b/target/cris/translate.c
222
index XXXXXXX..XXXXXXX 100644
222
index XXXXXXX..XXXXXXX 100644
223
--- a/target/cris/translate.c
223
--- a/target/cris/translate.c
224
+++ b/target/cris/translate.c
224
+++ b/target/cris/translate.c
225
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps cris_tr_ops = {
225
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps cris_tr_ops = {
226
.disas_log = cris_tr_disas_log,
226
.disas_log = cris_tr_disas_log,
227
};
227
};
228
228
229
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
229
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
230
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
230
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
231
+ target_ulong pc, void *host_pc)
231
+ target_ulong pc, void *host_pc)
232
{
232
{
233
DisasContext dc;
233
DisasContext dc;
234
- translator_loop(&cris_tr_ops, &dc.base, cs, tb, max_insns);
234
- translator_loop(&cris_tr_ops, &dc.base, cs, tb, max_insns);
235
+ translator_loop(cs, tb, max_insns, pc, host_pc, &cris_tr_ops, &dc.base);
235
+ translator_loop(cs, tb, max_insns, pc, host_pc, &cris_tr_ops, &dc.base);
236
}
236
}
237
237
238
void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags)
238
void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags)
239
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
239
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
240
index XXXXXXX..XXXXXXX 100644
240
index XXXXXXX..XXXXXXX 100644
241
--- a/target/hexagon/translate.c
241
--- a/target/hexagon/translate.c
242
+++ b/target/hexagon/translate.c
242
+++ b/target/hexagon/translate.c
243
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hexagon_tr_ops = {
243
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hexagon_tr_ops = {
244
.disas_log = hexagon_tr_disas_log,
244
.disas_log = hexagon_tr_disas_log,
245
};
245
};
246
246
247
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
247
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
248
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
248
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
249
+ target_ulong pc, void *host_pc)
249
+ target_ulong pc, void *host_pc)
250
{
250
{
251
DisasContext ctx;
251
DisasContext ctx;
252
252
253
- translator_loop(&hexagon_tr_ops, &ctx.base, cs, tb, max_insns);
253
- translator_loop(&hexagon_tr_ops, &ctx.base, cs, tb, max_insns);
254
+ translator_loop(cs, tb, max_insns, pc, host_pc,
254
+ translator_loop(cs, tb, max_insns, pc, host_pc,
255
+ &hexagon_tr_ops, &ctx.base);
255
+ &hexagon_tr_ops, &ctx.base);
256
}
256
}
257
257
258
#define NAME_LEN 64
258
#define NAME_LEN 64
259
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
259
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
260
index XXXXXXX..XXXXXXX 100644
260
index XXXXXXX..XXXXXXX 100644
261
--- a/target/hppa/translate.c
261
--- a/target/hppa/translate.c
262
+++ b/target/hppa/translate.c
262
+++ b/target/hppa/translate.c
263
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hppa_tr_ops = {
263
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps hppa_tr_ops = {
264
.disas_log = hppa_tr_disas_log,
264
.disas_log = hppa_tr_disas_log,
265
};
265
};
266
266
267
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
267
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
268
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
268
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
269
+ target_ulong pc, void *host_pc)
269
+ target_ulong pc, void *host_pc)
270
{
270
{
271
DisasContext ctx;
271
DisasContext ctx;
272
- translator_loop(&hppa_tr_ops, &ctx.base, cs, tb, max_insns);
272
- translator_loop(&hppa_tr_ops, &ctx.base, cs, tb, max_insns);
273
+ translator_loop(cs, tb, max_insns, pc, host_pc, &hppa_tr_ops, &ctx.base);
273
+ translator_loop(cs, tb, max_insns, pc, host_pc, &hppa_tr_ops, &ctx.base);
274
}
274
}
275
275
276
void restore_state_to_opc(CPUHPPAState *env, TranslationBlock *tb,
276
void restore_state_to_opc(CPUHPPAState *env, TranslationBlock *tb,
277
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
277
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
278
index XXXXXXX..XXXXXXX 100644
278
index XXXXXXX..XXXXXXX 100644
279
--- a/target/i386/tcg/translate.c
279
--- a/target/i386/tcg/translate.c
280
+++ b/target/i386/tcg/translate.c
280
+++ b/target/i386/tcg/translate.c
281
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps i386_tr_ops = {
281
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps i386_tr_ops = {
282
};
282
};
283
283
284
/* generate intermediate code for basic block 'tb'. */
284
/* generate intermediate code for basic block 'tb'. */
285
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
285
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
286
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
286
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
287
+ target_ulong pc, void *host_pc)
287
+ target_ulong pc, void *host_pc)
288
{
288
{
289
DisasContext dc;
289
DisasContext dc;
290
290
291
- translator_loop(&i386_tr_ops, &dc.base, cpu, tb, max_insns);
291
- translator_loop(&i386_tr_ops, &dc.base, cpu, tb, max_insns);
292
+ translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base);
292
+ translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base);
293
}
293
}
294
294
295
void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
295
void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
296
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
296
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
297
index XXXXXXX..XXXXXXX 100644
297
index XXXXXXX..XXXXXXX 100644
298
--- a/target/loongarch/translate.c
298
--- a/target/loongarch/translate.c
299
+++ b/target/loongarch/translate.c
299
+++ b/target/loongarch/translate.c
300
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps loongarch_tr_ops = {
300
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps loongarch_tr_ops = {
301
.disas_log = loongarch_tr_disas_log,
301
.disas_log = loongarch_tr_disas_log,
302
};
302
};
303
303
304
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
304
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
305
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
305
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
306
+ target_ulong pc, void *host_pc)
306
+ target_ulong pc, void *host_pc)
307
{
307
{
308
DisasContext ctx;
308
DisasContext ctx;
309
309
310
- translator_loop(&loongarch_tr_ops, &ctx.base, cs, tb, max_insns);
310
- translator_loop(&loongarch_tr_ops, &ctx.base, cs, tb, max_insns);
311
+ translator_loop(cs, tb, max_insns, pc, host_pc,
311
+ translator_loop(cs, tb, max_insns, pc, host_pc,
312
+ &loongarch_tr_ops, &ctx.base);
312
+ &loongarch_tr_ops, &ctx.base);
313
}
313
}
314
314
315
void loongarch_translate_init(void)
315
void loongarch_translate_init(void)
316
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
316
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
317
index XXXXXXX..XXXXXXX 100644
317
index XXXXXXX..XXXXXXX 100644
318
--- a/target/m68k/translate.c
318
--- a/target/m68k/translate.c
319
+++ b/target/m68k/translate.c
319
+++ b/target/m68k/translate.c
320
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps m68k_tr_ops = {
320
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps m68k_tr_ops = {
321
.disas_log = m68k_tr_disas_log,
321
.disas_log = m68k_tr_disas_log,
322
};
322
};
323
323
324
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
324
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
325
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
325
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
326
+ target_ulong pc, void *host_pc)
326
+ target_ulong pc, void *host_pc)
327
{
327
{
328
DisasContext dc;
328
DisasContext dc;
329
- translator_loop(&m68k_tr_ops, &dc.base, cpu, tb, max_insns);
329
- translator_loop(&m68k_tr_ops, &dc.base, cpu, tb, max_insns);
330
+ translator_loop(cpu, tb, max_insns, pc, host_pc, &m68k_tr_ops, &dc.base);
330
+ translator_loop(cpu, tb, max_insns, pc, host_pc, &m68k_tr_ops, &dc.base);
331
}
331
}
332
332
333
static double floatx80_to_double(CPUM68KState *env, uint16_t high, uint64_t low)
333
static double floatx80_to_double(CPUM68KState *env, uint16_t high, uint64_t low)
334
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
334
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
335
index XXXXXXX..XXXXXXX 100644
335
index XXXXXXX..XXXXXXX 100644
336
--- a/target/microblaze/translate.c
336
--- a/target/microblaze/translate.c
337
+++ b/target/microblaze/translate.c
337
+++ b/target/microblaze/translate.c
338
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mb_tr_ops = {
338
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mb_tr_ops = {
339
.disas_log = mb_tr_disas_log,
339
.disas_log = mb_tr_disas_log,
340
};
340
};
341
341
342
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
342
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
343
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
343
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
344
+ target_ulong pc, void *host_pc)
344
+ target_ulong pc, void *host_pc)
345
{
345
{
346
DisasContext dc;
346
DisasContext dc;
347
- translator_loop(&mb_tr_ops, &dc.base, cpu, tb, max_insns);
347
- translator_loop(&mb_tr_ops, &dc.base, cpu, tb, max_insns);
348
+ translator_loop(cpu, tb, max_insns, pc, host_pc, &mb_tr_ops, &dc.base);
348
+ translator_loop(cpu, tb, max_insns, pc, host_pc, &mb_tr_ops, &dc.base);
349
}
349
}
350
350
351
void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
351
void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
352
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
352
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
353
index XXXXXXX..XXXXXXX 100644
353
index XXXXXXX..XXXXXXX 100644
354
--- a/target/mips/tcg/translate.c
354
--- a/target/mips/tcg/translate.c
355
+++ b/target/mips/tcg/translate.c
355
+++ b/target/mips/tcg/translate.c
356
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mips_tr_ops = {
356
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps mips_tr_ops = {
357
.disas_log = mips_tr_disas_log,
357
.disas_log = mips_tr_disas_log,
358
};
358
};
359
359
360
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
360
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
361
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
361
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
362
+ target_ulong pc, void *host_pc)
362
+ target_ulong pc, void *host_pc)
363
{
363
{
364
DisasContext ctx;
364
DisasContext ctx;
365
365
366
- translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
366
- translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
367
+ translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base);
367
+ translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base);
368
}
368
}
369
369
370
void mips_tcg_init(void)
370
void mips_tcg_init(void)
371
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
371
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
372
index XXXXXXX..XXXXXXX 100644
372
index XXXXXXX..XXXXXXX 100644
373
--- a/target/nios2/translate.c
373
--- a/target/nios2/translate.c
374
+++ b/target/nios2/translate.c
374
+++ b/target/nios2/translate.c
375
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps nios2_tr_ops = {
375
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps nios2_tr_ops = {
376
.disas_log = nios2_tr_disas_log,
376
.disas_log = nios2_tr_disas_log,
377
};
377
};
378
378
379
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
379
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
380
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
380
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
381
+ target_ulong pc, void *host_pc)
381
+ target_ulong pc, void *host_pc)
382
{
382
{
383
DisasContext dc;
383
DisasContext dc;
384
- translator_loop(&nios2_tr_ops, &dc.base, cs, tb, max_insns);
384
- translator_loop(&nios2_tr_ops, &dc.base, cs, tb, max_insns);
385
+ translator_loop(cs, tb, max_insns, pc, host_pc, &nios2_tr_ops, &dc.base);
385
+ translator_loop(cs, tb, max_insns, pc, host_pc, &nios2_tr_ops, &dc.base);
386
}
386
}
387
387
388
void nios2_cpu_dump_state(CPUState *cs, FILE *f, int flags)
388
void nios2_cpu_dump_state(CPUState *cs, FILE *f, int flags)
389
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
389
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
390
index XXXXXXX..XXXXXXX 100644
390
index XXXXXXX..XXXXXXX 100644
391
--- a/target/openrisc/translate.c
391
--- a/target/openrisc/translate.c
392
+++ b/target/openrisc/translate.c
392
+++ b/target/openrisc/translate.c
393
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps openrisc_tr_ops = {
393
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps openrisc_tr_ops = {
394
.disas_log = openrisc_tr_disas_log,
394
.disas_log = openrisc_tr_disas_log,
395
};
395
};
396
396
397
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
397
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
398
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
398
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
399
+ target_ulong pc, void *host_pc)
399
+ target_ulong pc, void *host_pc)
400
{
400
{
401
DisasContext ctx;
401
DisasContext ctx;
402
402
403
- translator_loop(&openrisc_tr_ops, &ctx.base, cs, tb, max_insns);
403
- translator_loop(&openrisc_tr_ops, &ctx.base, cs, tb, max_insns);
404
+ translator_loop(cs, tb, max_insns, pc, host_pc,
404
+ translator_loop(cs, tb, max_insns, pc, host_pc,
405
+ &openrisc_tr_ops, &ctx.base);
405
+ &openrisc_tr_ops, &ctx.base);
406
}
406
}
407
407
408
void openrisc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
408
void openrisc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
409
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
409
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
410
index XXXXXXX..XXXXXXX 100644
410
index XXXXXXX..XXXXXXX 100644
411
--- a/target/ppc/translate.c
411
--- a/target/ppc/translate.c
412
+++ b/target/ppc/translate.c
412
+++ b/target/ppc/translate.c
413
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps ppc_tr_ops = {
413
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps ppc_tr_ops = {
414
.disas_log = ppc_tr_disas_log,
414
.disas_log = ppc_tr_disas_log,
415
};
415
};
416
416
417
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
417
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
418
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
418
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
419
+ target_ulong pc, void *host_pc)
419
+ target_ulong pc, void *host_pc)
420
{
420
{
421
DisasContext ctx;
421
DisasContext ctx;
422
422
423
- translator_loop(&ppc_tr_ops, &ctx.base, cs, tb, max_insns);
423
- translator_loop(&ppc_tr_ops, &ctx.base, cs, tb, max_insns);
424
+ translator_loop(cs, tb, max_insns, pc, host_pc, &ppc_tr_ops, &ctx.base);
424
+ translator_loop(cs, tb, max_insns, pc, host_pc, &ppc_tr_ops, &ctx.base);
425
}
425
}
426
426
427
void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb,
427
void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb,
428
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
428
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
429
index XXXXXXX..XXXXXXX 100644
429
index XXXXXXX..XXXXXXX 100644
430
--- a/target/riscv/translate.c
430
--- a/target/riscv/translate.c
431
+++ b/target/riscv/translate.c
431
+++ b/target/riscv/translate.c
432
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps riscv_tr_ops = {
432
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps riscv_tr_ops = {
433
.disas_log = riscv_tr_disas_log,
433
.disas_log = riscv_tr_disas_log,
434
};
434
};
435
435
436
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
436
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
437
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
437
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
438
+ target_ulong pc, void *host_pc)
438
+ target_ulong pc, void *host_pc)
439
{
439
{
440
DisasContext ctx;
440
DisasContext ctx;
441
441
442
- translator_loop(&riscv_tr_ops, &ctx.base, cs, tb, max_insns);
442
- translator_loop(&riscv_tr_ops, &ctx.base, cs, tb, max_insns);
443
+ translator_loop(cs, tb, max_insns, pc, host_pc, &riscv_tr_ops, &ctx.base);
443
+ translator_loop(cs, tb, max_insns, pc, host_pc, &riscv_tr_ops, &ctx.base);
444
}
444
}
445
445
446
void riscv_translate_init(void)
446
void riscv_translate_init(void)
447
diff --git a/target/rx/translate.c b/target/rx/translate.c
447
diff --git a/target/rx/translate.c b/target/rx/translate.c
448
index XXXXXXX..XXXXXXX 100644
448
index XXXXXXX..XXXXXXX 100644
449
--- a/target/rx/translate.c
449
--- a/target/rx/translate.c
450
+++ b/target/rx/translate.c
450
+++ b/target/rx/translate.c
451
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps rx_tr_ops = {
451
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps rx_tr_ops = {
452
.disas_log = rx_tr_disas_log,
452
.disas_log = rx_tr_disas_log,
453
};
453
};
454
454
455
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
455
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
456
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
456
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
457
+ target_ulong pc, void *host_pc)
457
+ target_ulong pc, void *host_pc)
458
{
458
{
459
DisasContext dc;
459
DisasContext dc;
460
460
461
- translator_loop(&rx_tr_ops, &dc.base, cs, tb, max_insns);
461
- translator_loop(&rx_tr_ops, &dc.base, cs, tb, max_insns);
462
+ translator_loop(cs, tb, max_insns, pc, host_pc, &rx_tr_ops, &dc.base);
462
+ translator_loop(cs, tb, max_insns, pc, host_pc, &rx_tr_ops, &dc.base);
463
}
463
}
464
464
465
void restore_state_to_opc(CPURXState *env, TranslationBlock *tb,
465
void restore_state_to_opc(CPURXState *env, TranslationBlock *tb,
466
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
466
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
467
index XXXXXXX..XXXXXXX 100644
467
index XXXXXXX..XXXXXXX 100644
468
--- a/target/s390x/tcg/translate.c
468
--- a/target/s390x/tcg/translate.c
469
+++ b/target/s390x/tcg/translate.c
469
+++ b/target/s390x/tcg/translate.c
470
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps s390x_tr_ops = {
470
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps s390x_tr_ops = {
471
.disas_log = s390x_tr_disas_log,
471
.disas_log = s390x_tr_disas_log,
472
};
472
};
473
473
474
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
474
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
475
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
475
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
476
+ target_ulong pc, void *host_pc)
476
+ target_ulong pc, void *host_pc)
477
{
477
{
478
DisasContext dc;
478
DisasContext dc;
479
479
480
- translator_loop(&s390x_tr_ops, &dc.base, cs, tb, max_insns);
480
- translator_loop(&s390x_tr_ops, &dc.base, cs, tb, max_insns);
481
+ translator_loop(cs, tb, max_insns, pc, host_pc, &s390x_tr_ops, &dc.base);
481
+ translator_loop(cs, tb, max_insns, pc, host_pc, &s390x_tr_ops, &dc.base);
482
}
482
}
483
483
484
void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb,
484
void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb,
485
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
485
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
486
index XXXXXXX..XXXXXXX 100644
486
index XXXXXXX..XXXXXXX 100644
487
--- a/target/sh4/translate.c
487
--- a/target/sh4/translate.c
488
+++ b/target/sh4/translate.c
488
+++ b/target/sh4/translate.c
489
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sh4_tr_ops = {
489
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sh4_tr_ops = {
490
.disas_log = sh4_tr_disas_log,
490
.disas_log = sh4_tr_disas_log,
491
};
491
};
492
492
493
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
493
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
494
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
494
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
495
+ target_ulong pc, void *host_pc)
495
+ target_ulong pc, void *host_pc)
496
{
496
{
497
DisasContext ctx;
497
DisasContext ctx;
498
498
499
- translator_loop(&sh4_tr_ops, &ctx.base, cs, tb, max_insns);
499
- translator_loop(&sh4_tr_ops, &ctx.base, cs, tb, max_insns);
500
+ translator_loop(cs, tb, max_insns, pc, host_pc, &sh4_tr_ops, &ctx.base);
500
+ translator_loop(cs, tb, max_insns, pc, host_pc, &sh4_tr_ops, &ctx.base);
501
}
501
}
502
502
503
void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb,
503
void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb,
504
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
504
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
505
index XXXXXXX..XXXXXXX 100644
505
index XXXXXXX..XXXXXXX 100644
506
--- a/target/sparc/translate.c
506
--- a/target/sparc/translate.c
507
+++ b/target/sparc/translate.c
507
+++ b/target/sparc/translate.c
508
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sparc_tr_ops = {
508
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps sparc_tr_ops = {
509
.disas_log = sparc_tr_disas_log,
509
.disas_log = sparc_tr_disas_log,
510
};
510
};
511
511
512
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
512
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
513
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
513
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
514
+ target_ulong pc, void *host_pc)
514
+ target_ulong pc, void *host_pc)
515
{
515
{
516
DisasContext dc = {};
516
DisasContext dc = {};
517
517
518
- translator_loop(&sparc_tr_ops, &dc.base, cs, tb, max_insns);
518
- translator_loop(&sparc_tr_ops, &dc.base, cs, tb, max_insns);
519
+ translator_loop(cs, tb, max_insns, pc, host_pc, &sparc_tr_ops, &dc.base);
519
+ translator_loop(cs, tb, max_insns, pc, host_pc, &sparc_tr_ops, &dc.base);
520
}
520
}
521
521
522
void sparc_tcg_init(void)
522
void sparc_tcg_init(void)
523
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
523
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
524
index XXXXXXX..XXXXXXX 100644
524
index XXXXXXX..XXXXXXX 100644
525
--- a/target/tricore/translate.c
525
--- a/target/tricore/translate.c
526
+++ b/target/tricore/translate.c
526
+++ b/target/tricore/translate.c
527
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps tricore_tr_ops = {
527
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps tricore_tr_ops = {
528
};
528
};
529
529
530
530
531
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
531
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
532
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
532
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
533
+ target_ulong pc, void *host_pc)
533
+ target_ulong pc, void *host_pc)
534
{
534
{
535
DisasContext ctx;
535
DisasContext ctx;
536
- translator_loop(&tricore_tr_ops, &ctx.base, cs, tb, max_insns);
536
- translator_loop(&tricore_tr_ops, &ctx.base, cs, tb, max_insns);
537
+ translator_loop(cs, tb, max_insns, pc, host_pc,
537
+ translator_loop(cs, tb, max_insns, pc, host_pc,
538
+ &tricore_tr_ops, &ctx.base);
538
+ &tricore_tr_ops, &ctx.base);
539
}
539
}
540
540
541
void
541
void
542
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
542
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
543
index XXXXXXX..XXXXXXX 100644
543
index XXXXXXX..XXXXXXX 100644
544
--- a/target/xtensa/translate.c
544
--- a/target/xtensa/translate.c
545
+++ b/target/xtensa/translate.c
545
+++ b/target/xtensa/translate.c
546
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps xtensa_translator_ops = {
546
@@ -XXX,XX +XXX,XX @@ static const TranslatorOps xtensa_translator_ops = {
547
.disas_log = xtensa_tr_disas_log,
547
.disas_log = xtensa_tr_disas_log,
548
};
548
};
549
549
550
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
550
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
551
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
551
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
552
+ target_ulong pc, void *host_pc)
552
+ target_ulong pc, void *host_pc)
553
{
553
{
554
DisasContext dc = {};
554
DisasContext dc = {};
555
- translator_loop(&xtensa_translator_ops, &dc.base, cpu, tb, max_insns);
555
- translator_loop(&xtensa_translator_ops, &dc.base, cpu, tb, max_insns);
556
+ translator_loop(cpu, tb, max_insns, pc, host_pc,
556
+ translator_loop(cpu, tb, max_insns, pc, host_pc,
557
+ &xtensa_translator_ops, &dc.base);
557
+ &xtensa_translator_ops, &dc.base);
558
}
558
}
559
559
560
void xtensa_cpu_dump_state(CPUState *cs, FILE *f, int flags)
560
void xtensa_cpu_dump_state(CPUState *cs, FILE *f, int flags)
561
--
561
--
562
2.34.1
562
2.34.1
diff view generated by jsdifflib
...
...
96
-#undef GEN_TRANSLATOR_LD
96
-#undef GEN_TRANSLATOR_LD
97
+static inline uint64_t
97
+static inline uint64_t
98
+translator_ldq_swap(CPUArchState *env, DisasContextBase *db,
98
+translator_ldq_swap(CPUArchState *env, DisasContextBase *db,
99
+ abi_ptr pc, bool do_swap)
99
+ abi_ptr pc, bool do_swap)
100
+{
100
+{
101
+ uint64_t ret = translator_ldq_swap(env, db, pc, false);
101
+ uint64_t ret = translator_ldq(env, db, pc);
102
+ if (do_swap) {
102
+ if (do_swap) {
103
+ ret = bswap64(ret);
103
+ ret = bswap64(ret);
104
+ }
104
+ }
105
+ return ret;
105
+ return ret;
106
+}
106
+}
...
...
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
2
2
3
Right now translator stops right *after* the end of a page, which
3
Right now translator stops right *after* the end of a page, which
4
breaks reporting of fault locations when the last instruction of a
4
breaks reporting of fault locations when the last instruction of a
5
multi-insn translation block crosses a page boundary.
5
multi-insn translation block crosses a page boundary.
6
6
7
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-Id: <20220817150506.592862-3-iii@linux.ibm.com>
9
Message-Id: <20220817150506.592862-3-iii@linux.ibm.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
---
11
---
12
target/s390x/tcg/translate.c | 15 +++-
12
target/s390x/tcg/translate.c | 15 +++-
13
tests/tcg/s390x/noexec.c | 106 +++++++++++++++++++++++
13
tests/tcg/s390x/noexec.c | 106 +++++++++++++++++++++++
14
tests/tcg/multiarch/noexec.c.inc | 139 +++++++++++++++++++++++++++++++
14
tests/tcg/multiarch/noexec.c.inc | 139 +++++++++++++++++++++++++++++++
15
tests/tcg/s390x/Makefile.target | 1 +
15
tests/tcg/s390x/Makefile.target | 1 +
16
4 files changed, 257 insertions(+), 4 deletions(-)
16
4 files changed, 257 insertions(+), 4 deletions(-)
17
create mode 100644 tests/tcg/s390x/noexec.c
17
create mode 100644 tests/tcg/s390x/noexec.c
18
create mode 100644 tests/tcg/multiarch/noexec.c.inc
18
create mode 100644 tests/tcg/multiarch/noexec.c.inc
19
19
20
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
20
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
21
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/s390x/tcg/translate.c
22
--- a/target/s390x/tcg/translate.c
23
+++ b/target/s390x/tcg/translate.c
23
+++ b/target/s390x/tcg/translate.c
24
@@ -XXX,XX +XXX,XX @@ static void s390x_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
24
@@ -XXX,XX +XXX,XX @@ static void s390x_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
25
dc->insn_start = tcg_last_op();
25
dc->insn_start = tcg_last_op();
26
}
26
}
27
27
28
+static target_ulong get_next_pc(CPUS390XState *env, DisasContext *s,
28
+static target_ulong get_next_pc(CPUS390XState *env, DisasContext *s,
29
+ uint64_t pc)
29
+ uint64_t pc)
30
+{
30
+{
31
+ uint64_t insn = ld_code2(env, s, pc);
31
+ uint64_t insn = ld_code2(env, s, pc);
32
+
32
+
33
+ return pc + get_ilen((insn >> 8) & 0xff);
33
+ return pc + get_ilen((insn >> 8) & 0xff);
34
+}
34
+}
35
+
35
+
36
static void s390x_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
36
static void s390x_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
37
{
37
{
38
CPUS390XState *env = cs->env_ptr;
38
CPUS390XState *env = cs->env_ptr;
39
@@ -XXX,XX +XXX,XX @@ static void s390x_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
39
@@ -XXX,XX +XXX,XX @@ static void s390x_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
40
40
41
dc->base.is_jmp = translate_one(env, dc);
41
dc->base.is_jmp = translate_one(env, dc);
42
if (dc->base.is_jmp == DISAS_NEXT) {
42
if (dc->base.is_jmp == DISAS_NEXT) {
43
- uint64_t page_start;
43
- uint64_t page_start;
44
-
44
-
45
- page_start = dc->base.pc_first & TARGET_PAGE_MASK;
45
- page_start = dc->base.pc_first & TARGET_PAGE_MASK;
46
- if (dc->base.pc_next - page_start >= TARGET_PAGE_SIZE || dc->ex_value) {
46
- if (dc->base.pc_next - page_start >= TARGET_PAGE_SIZE || dc->ex_value) {
47
+ if (!is_same_page(dcbase, dc->base.pc_next) ||
47
+ if (!is_same_page(dcbase, dc->base.pc_next) ||
48
+ !is_same_page(dcbase, get_next_pc(env, dc, dc->base.pc_next)) ||
48
+ !is_same_page(dcbase, get_next_pc(env, dc, dc->base.pc_next)) ||
49
+ dc->ex_value) {
49
+ dc->ex_value) {
50
dc->base.is_jmp = DISAS_TOO_MANY;
50
dc->base.is_jmp = DISAS_TOO_MANY;
51
}
51
}
52
}
52
}
53
diff --git a/tests/tcg/s390x/noexec.c b/tests/tcg/s390x/noexec.c
53
diff --git a/tests/tcg/s390x/noexec.c b/tests/tcg/s390x/noexec.c
54
new file mode 100644
54
new file mode 100644
55
index XXXXXXX..XXXXXXX
55
index XXXXXXX..XXXXXXX
56
--- /dev/null
56
--- /dev/null
57
+++ b/tests/tcg/s390x/noexec.c
57
+++ b/tests/tcg/s390x/noexec.c
58
@@ -XXX,XX +XXX,XX @@
58
@@ -XXX,XX +XXX,XX @@
59
+#include "../multiarch/noexec.c.inc"
59
+#include "../multiarch/noexec.c.inc"
60
+
60
+
61
+static void *arch_mcontext_pc(const mcontext_t *ctx)
61
+static void *arch_mcontext_pc(const mcontext_t *ctx)
62
+{
62
+{
63
+ return (void *)ctx->psw.addr;
63
+ return (void *)ctx->psw.addr;
64
+}
64
+}
65
+
65
+
66
+static int arch_mcontext_arg(const mcontext_t *ctx)
66
+static int arch_mcontext_arg(const mcontext_t *ctx)
67
+{
67
+{
68
+ return ctx->gregs[2];
68
+ return ctx->gregs[2];
69
+}
69
+}
70
+
70
+
71
+static void arch_flush(void *p, int len)
71
+static void arch_flush(void *p, int len)
72
+{
72
+{
73
+}
73
+}
74
+
74
+
75
+extern char noexec_1[];
75
+extern char noexec_1[];
76
+extern char noexec_2[];
76
+extern char noexec_2[];
77
+extern char noexec_end[];
77
+extern char noexec_end[];
78
+
78
+
79
+asm("noexec_1:\n"
79
+asm("noexec_1:\n"
80
+ " lgfi %r2,1\n" /* %r2 is 0 on entry, set 1. */
80
+ " lgfi %r2,1\n" /* %r2 is 0 on entry, set 1. */
81
+ "noexec_2:\n"
81
+ "noexec_2:\n"
82
+ " lgfi %r2,2\n" /* %r2 is 0/1; set 2. */
82
+ " lgfi %r2,2\n" /* %r2 is 0/1; set 2. */
83
+ " br %r14\n" /* return */
83
+ " br %r14\n" /* return */
84
+ "noexec_end:");
84
+ "noexec_end:");
85
+
85
+
86
+extern char exrl_1[];
86
+extern char exrl_1[];
87
+extern char exrl_2[];
87
+extern char exrl_2[];
88
+extern char exrl_end[];
88
+extern char exrl_end[];
89
+
89
+
90
+asm("exrl_1:\n"
90
+asm("exrl_1:\n"
91
+ " exrl %r0, exrl_2\n"
91
+ " exrl %r0, exrl_2\n"
92
+ " br %r14\n"
92
+ " br %r14\n"
93
+ "exrl_2:\n"
93
+ "exrl_2:\n"
94
+ " lgfi %r2,2\n"
94
+ " lgfi %r2,2\n"
95
+ "exrl_end:");
95
+ "exrl_end:");
96
+
96
+
97
+int main(void)
97
+int main(void)
98
+{
98
+{
99
+ struct noexec_test noexec_tests[] = {
99
+ struct noexec_test noexec_tests[] = {
100
+ {
100
+ {
101
+ .name = "fallthrough",
101
+ .name = "fallthrough",
102
+ .test_code = noexec_1,
102
+ .test_code = noexec_1,
103
+ .test_len = noexec_end - noexec_1,
103
+ .test_len = noexec_end - noexec_1,
104
+ .page_ofs = noexec_1 - noexec_2,
104
+ .page_ofs = noexec_1 - noexec_2,
105
+ .entry_ofs = noexec_1 - noexec_2,
105
+ .entry_ofs = noexec_1 - noexec_2,
106
+ .expected_si_ofs = 0,
106
+ .expected_si_ofs = 0,
107
+ .expected_pc_ofs = 0,
107
+ .expected_pc_ofs = 0,
108
+ .expected_arg = 1,
108
+ .expected_arg = 1,
109
+ },
109
+ },
110
+ {
110
+ {
111
+ .name = "jump",
111
+ .name = "jump",
112
+ .test_code = noexec_1,
112
+ .test_code = noexec_1,
113
+ .test_len = noexec_end - noexec_1,
113
+ .test_len = noexec_end - noexec_1,
114
+ .page_ofs = noexec_1 - noexec_2,
114
+ .page_ofs = noexec_1 - noexec_2,
115
+ .entry_ofs = 0,
115
+ .entry_ofs = 0,
116
+ .expected_si_ofs = 0,
116
+ .expected_si_ofs = 0,
117
+ .expected_pc_ofs = 0,
117
+ .expected_pc_ofs = 0,
118
+ .expected_arg = 0,
118
+ .expected_arg = 0,
119
+ },
119
+ },
120
+ {
120
+ {
121
+ .name = "exrl",
121
+ .name = "exrl",
122
+ .test_code = exrl_1,
122
+ .test_code = exrl_1,
123
+ .test_len = exrl_end - exrl_1,
123
+ .test_len = exrl_end - exrl_1,
124
+ .page_ofs = exrl_1 - exrl_2,
124
+ .page_ofs = exrl_1 - exrl_2,
125
+ .entry_ofs = exrl_1 - exrl_2,
125
+ .entry_ofs = exrl_1 - exrl_2,
126
+ .expected_si_ofs = 0,
126
+ .expected_si_ofs = 0,
127
+ .expected_pc_ofs = exrl_1 - exrl_2,
127
+ .expected_pc_ofs = exrl_1 - exrl_2,
128
+ .expected_arg = 0,
128
+ .expected_arg = 0,
129
+ },
129
+ },
130
+ {
130
+ {
131
+ .name = "fallthrough [cross]",
131
+ .name = "fallthrough [cross]",
132
+ .test_code = noexec_1,
132
+ .test_code = noexec_1,
133
+ .test_len = noexec_end - noexec_1,
133
+ .test_len = noexec_end - noexec_1,
134
+ .page_ofs = noexec_1 - noexec_2 - 2,
134
+ .page_ofs = noexec_1 - noexec_2 - 2,
135
+ .entry_ofs = noexec_1 - noexec_2 - 2,
135
+ .entry_ofs = noexec_1 - noexec_2 - 2,
136
+ .expected_si_ofs = 0,
136
+ .expected_si_ofs = 0,
137
+ .expected_pc_ofs = -2,
137
+ .expected_pc_ofs = -2,
138
+ .expected_arg = 1,
138
+ .expected_arg = 1,
139
+ },
139
+ },
140
+ {
140
+ {
141
+ .name = "jump [cross]",
141
+ .name = "jump [cross]",
142
+ .test_code = noexec_1,
142
+ .test_code = noexec_1,
143
+ .test_len = noexec_end - noexec_1,
143
+ .test_len = noexec_end - noexec_1,
144
+ .page_ofs = noexec_1 - noexec_2 - 2,
144
+ .page_ofs = noexec_1 - noexec_2 - 2,
145
+ .entry_ofs = -2,
145
+ .entry_ofs = -2,
146
+ .expected_si_ofs = 0,
146
+ .expected_si_ofs = 0,
147
+ .expected_pc_ofs = -2,
147
+ .expected_pc_ofs = -2,
148
+ .expected_arg = 0,
148
+ .expected_arg = 0,
149
+ },
149
+ },
150
+ {
150
+ {
151
+ .name = "exrl [cross]",
151
+ .name = "exrl [cross]",
152
+ .test_code = exrl_1,
152
+ .test_code = exrl_1,
153
+ .test_len = exrl_end - exrl_1,
153
+ .test_len = exrl_end - exrl_1,
154
+ .page_ofs = exrl_1 - exrl_2 - 2,
154
+ .page_ofs = exrl_1 - exrl_2 - 2,
155
+ .entry_ofs = exrl_1 - exrl_2 - 2,
155
+ .entry_ofs = exrl_1 - exrl_2 - 2,
156
+ .expected_si_ofs = 0,
156
+ .expected_si_ofs = 0,
157
+ .expected_pc_ofs = exrl_1 - exrl_2 - 2,
157
+ .expected_pc_ofs = exrl_1 - exrl_2 - 2,
158
+ .expected_arg = 0,
158
+ .expected_arg = 0,
159
+ },
159
+ },
160
+ };
160
+ };
161
+
161
+
162
+ return test_noexec(noexec_tests,
162
+ return test_noexec(noexec_tests,
163
+ sizeof(noexec_tests) / sizeof(noexec_tests[0]));
163
+ sizeof(noexec_tests) / sizeof(noexec_tests[0]));
164
+}
164
+}
165
diff --git a/tests/tcg/multiarch/noexec.c.inc b/tests/tcg/multiarch/noexec.c.inc
165
diff --git a/tests/tcg/multiarch/noexec.c.inc b/tests/tcg/multiarch/noexec.c.inc
166
new file mode 100644
166
new file mode 100644
167
index XXXXXXX..XXXXXXX
167
index XXXXXXX..XXXXXXX
168
--- /dev/null
168
--- /dev/null
169
+++ b/tests/tcg/multiarch/noexec.c.inc
169
+++ b/tests/tcg/multiarch/noexec.c.inc
170
@@ -XXX,XX +XXX,XX @@
170
@@ -XXX,XX +XXX,XX @@
171
+/*
171
+/*
172
+ * Common code for arch-specific MMU_INST_FETCH fault testing.
172
+ * Common code for arch-specific MMU_INST_FETCH fault testing.
173
+ */
173
+ */
174
+
174
+
175
+#define _GNU_SOURCE
175
+#define _GNU_SOURCE
176
+
176
+
177
+#include <assert.h>
177
+#include <assert.h>
178
+#include <signal.h>
178
+#include <signal.h>
179
+#include <stdio.h>
179
+#include <stdio.h>
180
+#include <stdlib.h>
180
+#include <stdlib.h>
181
+#include <string.h>
181
+#include <string.h>
182
+#include <errno.h>
182
+#include <errno.h>
183
+#include <unistd.h>
183
+#include <unistd.h>
184
+#include <sys/mman.h>
184
+#include <sys/mman.h>
185
+#include <sys/ucontext.h>
185
+#include <sys/ucontext.h>
186
+
186
+
187
+/* Forward declarations. */
187
+/* Forward declarations. */
188
+
188
+
189
+static void *arch_mcontext_pc(const mcontext_t *ctx);
189
+static void *arch_mcontext_pc(const mcontext_t *ctx);
190
+static int arch_mcontext_arg(const mcontext_t *ctx);
190
+static int arch_mcontext_arg(const mcontext_t *ctx);
191
+static void arch_flush(void *p, int len);
191
+static void arch_flush(void *p, int len);
192
+
192
+
193
+/* Testing infrastructure. */
193
+/* Testing infrastructure. */
194
+
194
+
195
+struct noexec_test {
195
+struct noexec_test {
196
+ const char *name;
196
+ const char *name;
197
+ const char *test_code;
197
+ const char *test_code;
198
+ int test_len;
198
+ int test_len;
199
+ int page_ofs;
199
+ int page_ofs;
200
+ int entry_ofs;
200
+ int entry_ofs;
201
+ int expected_si_ofs;
201
+ int expected_si_ofs;
202
+ int expected_pc_ofs;
202
+ int expected_pc_ofs;
203
+ int expected_arg;
203
+ int expected_arg;
204
+};
204
+};
205
+
205
+
206
+static void *page_base;
206
+static void *page_base;
207
+static int page_size;
207
+static int page_size;
208
+static const struct noexec_test *current_noexec_test;
208
+static const struct noexec_test *current_noexec_test;
209
+
209
+
210
+static void handle_err(const char *syscall)
210
+static void handle_err(const char *syscall)
211
+{
211
+{
212
+ printf("[ FAILED ] %s: %s\n", syscall, strerror(errno));
212
+ printf("[ FAILED ] %s: %s\n", syscall, strerror(errno));
213
+ exit(EXIT_FAILURE);
213
+ exit(EXIT_FAILURE);
214
+}
214
+}
215
+
215
+
216
+static void handle_segv(int sig, siginfo_t *info, void *ucontext)
216
+static void handle_segv(int sig, siginfo_t *info, void *ucontext)
217
+{
217
+{
218
+ const struct noexec_test *test = current_noexec_test;
218
+ const struct noexec_test *test = current_noexec_test;
219
+ const mcontext_t *mc = &((ucontext_t *)ucontext)->uc_mcontext;
219
+ const mcontext_t *mc = &((ucontext_t *)ucontext)->uc_mcontext;
220
+ void *expected_si;
220
+ void *expected_si;
221
+ void *expected_pc;
221
+ void *expected_pc;
222
+ void *pc;
222
+ void *pc;
223
+ int arg;
223
+ int arg;
224
+
224
+
225
+ if (test == NULL) {
225
+ if (test == NULL) {
226
+ printf("[ FAILED ] unexpected SEGV\n");
226
+ printf("[ FAILED ] unexpected SEGV\n");
227
+ exit(EXIT_FAILURE);
227
+ exit(EXIT_FAILURE);
228
+ }
228
+ }
229
+ current_noexec_test = NULL;
229
+ current_noexec_test = NULL;
230
+
230
+
231
+ expected_si = page_base + test->expected_si_ofs;
231
+ expected_si = page_base + test->expected_si_ofs;
232
+ if (info->si_addr != expected_si) {
232
+ if (info->si_addr != expected_si) {
233
+ printf("[ FAILED ] wrong si_addr (%p != %p)\n",
233
+ printf("[ FAILED ] wrong si_addr (%p != %p)\n",
234
+ info->si_addr, expected_si);
234
+ info->si_addr, expected_si);
235
+ exit(EXIT_FAILURE);
235
+ exit(EXIT_FAILURE);
236
+ }
236
+ }
237
+
237
+
238
+ pc = arch_mcontext_pc(mc);
238
+ pc = arch_mcontext_pc(mc);
239
+ expected_pc = page_base + test->expected_pc_ofs;
239
+ expected_pc = page_base + test->expected_pc_ofs;
240
+ if (pc != expected_pc) {
240
+ if (pc != expected_pc) {
241
+ printf("[ FAILED ] wrong pc (%p != %p)\n", pc, expected_pc);
241
+ printf("[ FAILED ] wrong pc (%p != %p)\n", pc, expected_pc);
242
+ exit(EXIT_FAILURE);
242
+ exit(EXIT_FAILURE);
243
+ }
243
+ }
244
+
244
+
245
+ arg = arch_mcontext_arg(mc);
245
+ arg = arch_mcontext_arg(mc);
246
+ if (arg != test->expected_arg) {
246
+ if (arg != test->expected_arg) {
247
+ printf("[ FAILED ] wrong arg (%d != %d)\n", arg, test->expected_arg);
247
+ printf("[ FAILED ] wrong arg (%d != %d)\n", arg, test->expected_arg);
248
+ exit(EXIT_FAILURE);
248
+ exit(EXIT_FAILURE);
249
+ }
249
+ }
250
+
250
+
251
+ if (mprotect(page_base, page_size,
251
+ if (mprotect(page_base, page_size,
252
+ PROT_READ | PROT_WRITE | PROT_EXEC) < 0) {
252
+ PROT_READ | PROT_WRITE | PROT_EXEC) < 0) {
253
+ handle_err("mprotect");
253
+ handle_err("mprotect");
254
+ }
254
+ }
255
+}
255
+}
256
+
256
+
257
+static void test_noexec_1(const struct noexec_test *test)
257
+static void test_noexec_1(const struct noexec_test *test)
258
+{
258
+{
259
+ void *start = page_base + test->page_ofs;
259
+ void *start = page_base + test->page_ofs;
260
+ void (*fn)(int arg) = page_base + test->entry_ofs;
260
+ void (*fn)(int arg) = page_base + test->entry_ofs;
261
+
261
+
262
+ memcpy(start, test->test_code, test->test_len);
262
+ memcpy(start, test->test_code, test->test_len);
263
+ arch_flush(start, test->test_len);
263
+ arch_flush(start, test->test_len);
264
+
264
+
265
+ /* Trigger TB creation in order to test invalidation. */
265
+ /* Trigger TB creation in order to test invalidation. */
266
+ fn(0);
266
+ fn(0);
267
+
267
+
268
+ if (mprotect(page_base, page_size, PROT_NONE) < 0) {
268
+ if (mprotect(page_base, page_size, PROT_NONE) < 0) {
269
+ handle_err("mprotect");
269
+ handle_err("mprotect");
270
+ }
270
+ }
271
+
271
+
272
+ /* Trigger SEGV and check that handle_segv() ran. */
272
+ /* Trigger SEGV and check that handle_segv() ran. */
273
+ current_noexec_test = test;
273
+ current_noexec_test = test;
274
+ fn(0);
274
+ fn(0);
275
+ assert(current_noexec_test == NULL);
275
+ assert(current_noexec_test == NULL);
276
+}
276
+}
277
+
277
+
278
+static int test_noexec(struct noexec_test *tests, size_t n_tests)
278
+static int test_noexec(struct noexec_test *tests, size_t n_tests)
279
+{
279
+{
280
+ struct sigaction act;
280
+ struct sigaction act;
281
+ size_t i;
281
+ size_t i;
282
+
282
+
283
+ memset(&act, 0, sizeof(act));
283
+ memset(&act, 0, sizeof(act));
284
+ act.sa_sigaction = handle_segv;
284
+ act.sa_sigaction = handle_segv;
285
+ act.sa_flags = SA_SIGINFO;
285
+ act.sa_flags = SA_SIGINFO;
286
+ if (sigaction(SIGSEGV, &act, NULL) < 0) {
286
+ if (sigaction(SIGSEGV, &act, NULL) < 0) {
287
+ handle_err("sigaction");
287
+ handle_err("sigaction");
288
+ }
288
+ }
289
+
289
+
290
+ page_size = getpagesize();
290
+ page_size = getpagesize();
291
+ page_base = mmap(NULL, 2 * page_size,
291
+ page_base = mmap(NULL, 2 * page_size,
292
+ PROT_READ | PROT_WRITE | PROT_EXEC,
292
+ PROT_READ | PROT_WRITE | PROT_EXEC,
293
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
293
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
294
+ if (page_base == MAP_FAILED) {
294
+ if (page_base == MAP_FAILED) {
295
+ handle_err("mmap");
295
+ handle_err("mmap");
296
+ }
296
+ }
297
+ page_base += page_size;
297
+ page_base += page_size;
298
+
298
+
299
+ for (i = 0; i < n_tests; i++) {
299
+ for (i = 0; i < n_tests; i++) {
300
+ struct noexec_test *test = &tests[i];
300
+ struct noexec_test *test = &tests[i];
301
+
301
+
302
+ printf("[ RUN ] %s\n", test->name);
302
+ printf("[ RUN ] %s\n", test->name);
303
+ test_noexec_1(test);
303
+ test_noexec_1(test);
304
+ printf("[ OK ]\n");
304
+ printf("[ OK ]\n");
305
+ }
305
+ }
306
+
306
+
307
+ printf("[ PASSED ]\n");
307
+ printf("[ PASSED ]\n");
308
+ return EXIT_SUCCESS;
308
+ return EXIT_SUCCESS;
309
+}
309
+}
310
diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
310
diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
311
index XXXXXXX..XXXXXXX 100644
311
index XXXXXXX..XXXXXXX 100644
312
--- a/tests/tcg/s390x/Makefile.target
312
--- a/tests/tcg/s390x/Makefile.target
313
+++ b/tests/tcg/s390x/Makefile.target
313
+++ b/tests/tcg/s390x/Makefile.target
314
@@ -XXX,XX +XXX,XX @@ TESTS+=shift
314
@@ -XXX,XX +XXX,XX @@ TESTS+=shift
315
TESTS+=trap
315
TESTS+=trap
316
TESTS+=signals-s390x
316
TESTS+=signals-s390x
317
TESTS+=branch-relative-long
317
TESTS+=branch-relative-long
318
+TESTS+=noexec
318
+TESTS+=noexec
319
319
320
Z14_TESTS=vfminmax
320
Z14_TESTS=vfminmax
321
vfminmax: LDFLAGS+=-lm
321
vfminmax: LDFLAGS+=-lm
322
--
322
--
323
2.34.1
323
2.34.1
diff view generated by jsdifflib
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
1
From: Ilya Leoshkevich <iii@linux.ibm.com>
2
2
3
Right now translator stops right *after* the end of a page, which
3
Right now translator stops right *after* the end of a page, which
4
breaks reporting of fault locations when the last instruction of a
4
breaks reporting of fault locations when the last instruction of a
5
multi-insn translation block crosses a page boundary.
5
multi-insn translation block crosses a page boundary.
6
6
7
An implementation, like the one arm and s390x have, would require an
7
An implementation, like the one arm and s390x have, would require an
8
i386 length disassembler, which is burdensome to maintain. Another
8
i386 length disassembler, which is burdensome to maintain. Another
9
alternative would be to single-step at the end of a guest page, but
9
alternative would be to single-step at the end of a guest page, but
10
this may come with a performance impact.
10
this may come with a performance impact.
11
11
12
Fix by snapshotting disassembly state and restoring it after we figure
12
Fix by snapshotting disassembly state and restoring it after we figure
13
out we crossed a page boundary. This includes rolling back cc_op
13
out we crossed a page boundary. This includes rolling back cc_op
14
updates and emitted ops.
14
updates and emitted ops.
15
15
16
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
16
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1143
18
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1143
19
Message-Id: <20220817150506.592862-4-iii@linux.ibm.com>
19
Message-Id: <20220817150506.592862-4-iii@linux.ibm.com>
20
[rth: Simplify end-of-insn cross-page checks.]
20
[rth: Simplify end-of-insn cross-page checks.]
21
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
21
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
22
---
22
---
23
target/i386/tcg/translate.c | 64 ++++++++++++++++-----------
23
target/i386/tcg/translate.c | 64 ++++++++++++++++-----------
24
tests/tcg/x86_64/noexec.c | 75 ++++++++++++++++++++++++++++++++
24
tests/tcg/x86_64/noexec.c | 75 ++++++++++++++++++++++++++++++++
25
tests/tcg/x86_64/Makefile.target | 3 +-
25
tests/tcg/x86_64/Makefile.target | 3 +-
26
3 files changed, 116 insertions(+), 26 deletions(-)
26
3 files changed, 116 insertions(+), 26 deletions(-)
27
create mode 100644 tests/tcg/x86_64/noexec.c
27
create mode 100644 tests/tcg/x86_64/noexec.c
28
28
29
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
29
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
30
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/i386/tcg/translate.c
31
--- a/target/i386/tcg/translate.c
32
+++ b/target/i386/tcg/translate.c
32
+++ b/target/i386/tcg/translate.c
33
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
33
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
34
TCGv_i64 tmp1_i64;
34
TCGv_i64 tmp1_i64;
35
35
36
sigjmp_buf jmpbuf;
36
sigjmp_buf jmpbuf;
37
+ TCGOp *prev_insn_end;
37
+ TCGOp *prev_insn_end;
38
} DisasContext;
38
} DisasContext;
39
39
40
/* The environment in which user-only runs is constrained. */
40
/* The environment in which user-only runs is constrained. */
41
@@ -XXX,XX +XXX,XX @@ static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
41
@@ -XXX,XX +XXX,XX @@ static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
42
{
42
{
43
uint64_t pc = s->pc;
43
uint64_t pc = s->pc;
44
44
45
+ /* This is a subsequent insn that crosses a page boundary. */
45
+ /* This is a subsequent insn that crosses a page boundary. */
46
+ if (s->base.num_insns > 1 &&
46
+ if (s->base.num_insns > 1 &&
47
+ !is_same_page(&s->base, s->pc + num_bytes - 1)) {
47
+ !is_same_page(&s->base, s->pc + num_bytes - 1)) {
48
+ siglongjmp(s->jmpbuf, 2);
48
+ siglongjmp(s->jmpbuf, 2);
49
+ }
49
+ }
50
+
50
+
51
s->pc += num_bytes;
51
s->pc += num_bytes;
52
if (unlikely(s->pc - s->pc_start > X86_MAX_INSN_LENGTH)) {
52
if (unlikely(s->pc - s->pc_start > X86_MAX_INSN_LENGTH)) {
53
/* If the instruction's 16th byte is on a different page than the 1st, a
53
/* If the instruction's 16th byte is on a different page than the 1st, a
54
@@ -XXX,XX +XXX,XX @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
54
@@ -XXX,XX +XXX,XX @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
55
int modrm, reg, rm, mod, op, opreg, val;
55
int modrm, reg, rm, mod, op, opreg, val;
56
target_ulong next_eip, tval;
56
target_ulong next_eip, tval;
57
target_ulong pc_start = s->base.pc_next;
57
target_ulong pc_start = s->base.pc_next;
58
+ bool orig_cc_op_dirty = s->cc_op_dirty;
58
+ bool orig_cc_op_dirty = s->cc_op_dirty;
59
+ CCOp orig_cc_op = s->cc_op;
59
+ CCOp orig_cc_op = s->cc_op;
60
60
61
s->pc_start = s->pc = pc_start;
61
s->pc_start = s->pc = pc_start;
62
s->override = -1;
62
s->override = -1;
63
@@ -XXX,XX +XXX,XX @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
63
@@ -XXX,XX +XXX,XX @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
64
s->rip_offset = 0; /* for relative ip address */
64
s->rip_offset = 0; /* for relative ip address */
65
s->vex_l = 0;
65
s->vex_l = 0;
66
s->vex_v = 0;
66
s->vex_v = 0;
67
- if (sigsetjmp(s->jmpbuf, 0) != 0) {
67
- if (sigsetjmp(s->jmpbuf, 0) != 0) {
68
+ switch (sigsetjmp(s->jmpbuf, 0)) {
68
+ switch (sigsetjmp(s->jmpbuf, 0)) {
69
+ case 0:
69
+ case 0:
70
+ break;
70
+ break;
71
+ case 1:
71
+ case 1:
72
gen_exception_gpf(s);
72
gen_exception_gpf(s);
73
return s->pc;
73
return s->pc;
74
+ case 2:
74
+ case 2:
75
+ /* Restore state that may affect the next instruction. */
75
+ /* Restore state that may affect the next instruction. */
76
+ s->cc_op_dirty = orig_cc_op_dirty;
76
+ s->cc_op_dirty = orig_cc_op_dirty;
77
+ s->cc_op = orig_cc_op;
77
+ s->cc_op = orig_cc_op;
78
+ s->base.num_insns--;
78
+ s->base.num_insns--;
79
+ tcg_remove_ops_after(s->prev_insn_end);
79
+ tcg_remove_ops_after(s->prev_insn_end);
80
+ s->base.is_jmp = DISAS_TOO_MANY;
80
+ s->base.is_jmp = DISAS_TOO_MANY;
81
+ return pc_start;
81
+ return pc_start;
82
+ default:
82
+ default:
83
+ g_assert_not_reached();
83
+ g_assert_not_reached();
84
}
84
}
85
85
86
prefixes = 0;
86
prefixes = 0;
87
@@ -XXX,XX +XXX,XX @@ static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
87
@@ -XXX,XX +XXX,XX @@ static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
88
{
88
{
89
DisasContext *dc = container_of(dcbase, DisasContext, base);
89
DisasContext *dc = container_of(dcbase, DisasContext, base);
90
90
91
+ dc->prev_insn_end = tcg_last_op();
91
+ dc->prev_insn_end = tcg_last_op();
92
tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
92
tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
93
}
93
}
94
94
95
@@ -XXX,XX +XXX,XX @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
95
@@ -XXX,XX +XXX,XX @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
96
#endif
96
#endif
97
97
98
pc_next = disas_insn(dc, cpu);
98
pc_next = disas_insn(dc, cpu);
99
-
99
-
100
- if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
100
- if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
101
- /* if single step mode, we generate only one instruction and
101
- /* if single step mode, we generate only one instruction and
102
- generate an exception */
102
- generate an exception */
103
- /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
103
- /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
104
- the flag and abort the translation to give the irqs a
104
- the flag and abort the translation to give the irqs a
105
- chance to happen */
105
- chance to happen */
106
- dc->base.is_jmp = DISAS_TOO_MANY;
106
- dc->base.is_jmp = DISAS_TOO_MANY;
107
- } else if ((tb_cflags(dc->base.tb) & CF_USE_ICOUNT)
107
- } else if ((tb_cflags(dc->base.tb) & CF_USE_ICOUNT)
108
- && ((pc_next & TARGET_PAGE_MASK)
108
- && ((pc_next & TARGET_PAGE_MASK)
109
- != ((pc_next + TARGET_MAX_INSN_SIZE - 1)
109
- != ((pc_next + TARGET_MAX_INSN_SIZE - 1)
110
- & TARGET_PAGE_MASK)
110
- & TARGET_PAGE_MASK)
111
- || (pc_next & ~TARGET_PAGE_MASK) == 0)) {
111
- || (pc_next & ~TARGET_PAGE_MASK) == 0)) {
112
- /* Do not cross the boundary of the pages in icount mode,
112
- /* Do not cross the boundary of the pages in icount mode,
113
- it can cause an exception. Do it only when boundary is
113
- it can cause an exception. Do it only when boundary is
114
- crossed by the first instruction in the block.
114
- crossed by the first instruction in the block.
115
- If current instruction already crossed the bound - it's ok,
115
- If current instruction already crossed the bound - it's ok,
116
- because an exception hasn't stopped this code.
116
- because an exception hasn't stopped this code.
117
- */
117
- */
118
- dc->base.is_jmp = DISAS_TOO_MANY;
118
- dc->base.is_jmp = DISAS_TOO_MANY;
119
- } else if ((pc_next - dc->base.pc_first) >= (TARGET_PAGE_SIZE - 32)) {
119
- } else if ((pc_next - dc->base.pc_first) >= (TARGET_PAGE_SIZE - 32)) {
120
- dc->base.is_jmp = DISAS_TOO_MANY;
120
- dc->base.is_jmp = DISAS_TOO_MANY;
121
- }
121
- }
122
-
122
-
123
dc->base.pc_next = pc_next;
123
dc->base.pc_next = pc_next;
124
+
124
+
125
+ if (dc->base.is_jmp == DISAS_NEXT) {
125
+ if (dc->base.is_jmp == DISAS_NEXT) {
126
+ if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
126
+ if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
127
+ /*
127
+ /*
128
+ * If single step mode, we generate only one instruction and
128
+ * If single step mode, we generate only one instruction and
129
+ * generate an exception.
129
+ * generate an exception.
130
+ * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
130
+ * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
131
+ * the flag and abort the translation to give the irqs a
131
+ * the flag and abort the translation to give the irqs a
132
+ * chance to happen.
132
+ * chance to happen.
133
+ */
133
+ */
134
+ dc->base.is_jmp = DISAS_TOO_MANY;
134
+ dc->base.is_jmp = DISAS_TOO_MANY;
135
+ } else if (!is_same_page(&dc->base, pc_next)) {
135
+ } else if (!is_same_page(&dc->base, pc_next)) {
136
+ dc->base.is_jmp = DISAS_TOO_MANY;
136
+ dc->base.is_jmp = DISAS_TOO_MANY;
137
+ }
137
+ }
138
+ }
138
+ }
139
}
139
}
140
140
141
static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
141
static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
142
diff --git a/tests/tcg/x86_64/noexec.c b/tests/tcg/x86_64/noexec.c
142
diff --git a/tests/tcg/x86_64/noexec.c b/tests/tcg/x86_64/noexec.c
143
new file mode 100644
143
new file mode 100644
144
index XXXXXXX..XXXXXXX
144
index XXXXXXX..XXXXXXX
145
--- /dev/null
145
--- /dev/null
146
+++ b/tests/tcg/x86_64/noexec.c
146
+++ b/tests/tcg/x86_64/noexec.c
147
@@ -XXX,XX +XXX,XX @@
147
@@ -XXX,XX +XXX,XX @@
148
+#include "../multiarch/noexec.c.inc"
148
+#include "../multiarch/noexec.c.inc"
149
+
149
+
150
+static void *arch_mcontext_pc(const mcontext_t *ctx)
150
+static void *arch_mcontext_pc(const mcontext_t *ctx)
151
+{
151
+{
152
+ return (void *)ctx->gregs[REG_RIP];
152
+ return (void *)ctx->gregs[REG_RIP];
153
+}
153
+}
154
+
154
+
155
+int arch_mcontext_arg(const mcontext_t *ctx)
155
+int arch_mcontext_arg(const mcontext_t *ctx)
156
+{
156
+{
157
+ return ctx->gregs[REG_RDI];
157
+ return ctx->gregs[REG_RDI];
158
+}
158
+}
159
+
159
+
160
+static void arch_flush(void *p, int len)
160
+static void arch_flush(void *p, int len)
161
+{
161
+{
162
+}
162
+}
163
+
163
+
164
+extern char noexec_1[];
164
+extern char noexec_1[];
165
+extern char noexec_2[];
165
+extern char noexec_2[];
166
+extern char noexec_end[];
166
+extern char noexec_end[];
167
+
167
+
168
+asm("noexec_1:\n"
168
+asm("noexec_1:\n"
169
+ " movq $1,%rdi\n" /* %rdi is 0 on entry, set 1. */
169
+ " movq $1,%rdi\n" /* %rdi is 0 on entry, set 1. */
170
+ "noexec_2:\n"
170
+ "noexec_2:\n"
171
+ " movq $2,%rdi\n" /* %rdi is 0/1; set 2. */
171
+ " movq $2,%rdi\n" /* %rdi is 0/1; set 2. */
172
+ " ret\n"
172
+ " ret\n"
173
+ "noexec_end:");
173
+ "noexec_end:");
174
+
174
+
175
+int main(void)
175
+int main(void)
176
+{
176
+{
177
+ struct noexec_test noexec_tests[] = {
177
+ struct noexec_test noexec_tests[] = {
178
+ {
178
+ {
179
+ .name = "fallthrough",
179
+ .name = "fallthrough",
180
+ .test_code = noexec_1,
180
+ .test_code = noexec_1,
181
+ .test_len = noexec_end - noexec_1,
181
+ .test_len = noexec_end - noexec_1,
182
+ .page_ofs = noexec_1 - noexec_2,
182
+ .page_ofs = noexec_1 - noexec_2,
183
+ .entry_ofs = noexec_1 - noexec_2,
183
+ .entry_ofs = noexec_1 - noexec_2,
184
+ .expected_si_ofs = 0,
184
+ .expected_si_ofs = 0,
185
+ .expected_pc_ofs = 0,
185
+ .expected_pc_ofs = 0,
186
+ .expected_arg = 1,
186
+ .expected_arg = 1,
187
+ },
187
+ },
188
+ {
188
+ {
189
+ .name = "jump",
189
+ .name = "jump",
190
+ .test_code = noexec_1,
190
+ .test_code = noexec_1,
191
+ .test_len = noexec_end - noexec_1,
191
+ .test_len = noexec_end - noexec_1,
192
+ .page_ofs = noexec_1 - noexec_2,
192
+ .page_ofs = noexec_1 - noexec_2,
193
+ .entry_ofs = 0,
193
+ .entry_ofs = 0,
194
+ .expected_si_ofs = 0,
194
+ .expected_si_ofs = 0,
195
+ .expected_pc_ofs = 0,
195
+ .expected_pc_ofs = 0,
196
+ .expected_arg = 0,
196
+ .expected_arg = 0,
197
+ },
197
+ },
198
+ {
198
+ {
199
+ .name = "fallthrough [cross]",
199
+ .name = "fallthrough [cross]",
200
+ .test_code = noexec_1,
200
+ .test_code = noexec_1,
201
+ .test_len = noexec_end - noexec_1,
201
+ .test_len = noexec_end - noexec_1,
202
+ .page_ofs = noexec_1 - noexec_2 - 2,
202
+ .page_ofs = noexec_1 - noexec_2 - 2,
203
+ .entry_ofs = noexec_1 - noexec_2 - 2,
203
+ .entry_ofs = noexec_1 - noexec_2 - 2,
204
+ .expected_si_ofs = 0,
204
+ .expected_si_ofs = 0,
205
+ .expected_pc_ofs = -2,
205
+ .expected_pc_ofs = -2,
206
+ .expected_arg = 1,
206
+ .expected_arg = 1,
207
+ },
207
+ },
208
+ {
208
+ {
209
+ .name = "jump [cross]",
209
+ .name = "jump [cross]",
210
+ .test_code = noexec_1,
210
+ .test_code = noexec_1,
211
+ .test_len = noexec_end - noexec_1,
211
+ .test_len = noexec_end - noexec_1,
212
+ .page_ofs = noexec_1 - noexec_2 - 2,
212
+ .page_ofs = noexec_1 - noexec_2 - 2,
213
+ .entry_ofs = -2,
213
+ .entry_ofs = -2,
214
+ .expected_si_ofs = 0,
214
+ .expected_si_ofs = 0,
215
+ .expected_pc_ofs = -2,
215
+ .expected_pc_ofs = -2,
216
+ .expected_arg = 0,
216
+ .expected_arg = 0,
217
+ },
217
+ },
218
+ };
218
+ };
219
+
219
+
220
+ return test_noexec(noexec_tests,
220
+ return test_noexec(noexec_tests,
221
+ sizeof(noexec_tests) / sizeof(noexec_tests[0]));
221
+ sizeof(noexec_tests) / sizeof(noexec_tests[0]));
222
+}
222
+}
223
diff --git a/tests/tcg/x86_64/Makefile.target b/tests/tcg/x86_64/Makefile.target
223
diff --git a/tests/tcg/x86_64/Makefile.target b/tests/tcg/x86_64/Makefile.target
224
index XXXXXXX..XXXXXXX 100644
224
index XXXXXXX..XXXXXXX 100644
225
--- a/tests/tcg/x86_64/Makefile.target
225
--- a/tests/tcg/x86_64/Makefile.target
226
+++ b/tests/tcg/x86_64/Makefile.target
226
+++ b/tests/tcg/x86_64/Makefile.target
227
@@ -XXX,XX +XXX,XX @@ include $(SRC_PATH)/tests/tcg/i386/Makefile.target
227
@@ -XXX,XX +XXX,XX @@ include $(SRC_PATH)/tests/tcg/i386/Makefile.target
228
228
229
ifeq ($(filter %-linux-user, $(TARGET)),$(TARGET))
229
ifeq ($(filter %-linux-user, $(TARGET)),$(TARGET))
230
X86_64_TESTS += vsyscall
230
X86_64_TESTS += vsyscall
231
+X86_64_TESTS += noexec
231
+X86_64_TESTS += noexec
232
TESTS=$(MULTIARCH_TESTS) $(X86_64_TESTS) test-x86_64
232
TESTS=$(MULTIARCH_TESTS) $(X86_64_TESTS) test-x86_64
233
else
233
else
234
TESTS=$(MULTIARCH_TESTS)
234
TESTS=$(MULTIARCH_TESTS)
235
@@ -XXX,XX +XXX,XX @@ test-x86_64: LDFLAGS+=-lm -lc
235
@@ -XXX,XX +XXX,XX @@ test-x86_64: LDFLAGS+=-lm -lc
236
test-x86_64: test-i386.c test-i386.h test-i386-shift.h test-i386-muldiv.h
236
test-x86_64: test-i386.c test-i386.h test-i386-shift.h test-i386-muldiv.h
237
    $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
237
    $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
238
238
239
-vsyscall: $(SRC_PATH)/tests/tcg/x86_64/vsyscall.c
239
-vsyscall: $(SRC_PATH)/tests/tcg/x86_64/vsyscall.c
240
+%: $(SRC_PATH)/tests/tcg/x86_64/%.c
240
+%: $(SRC_PATH)/tests/tcg/x86_64/%.c
241
    $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
241
    $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
242
--
242
--
243
2.34.1
243
2.34.1
diff view generated by jsdifflib
1
These will be useful in properly ending the TB.
1
These will be useful in properly ending the TB.
2
2
3
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
3
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
4
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
4
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
5
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
5
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
7
---
8
target/riscv/translate.c | 10 +++++++++-
8
target/riscv/translate.c | 10 +++++++++-
9
1 file changed, 9 insertions(+), 1 deletion(-)
9
1 file changed, 9 insertions(+), 1 deletion(-)
10
10
11
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
11
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/translate.c
13
--- a/target/riscv/translate.c
14
+++ b/target/riscv/translate.c
14
+++ b/target/riscv/translate.c
15
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
15
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
16
/* Include decoders for factored-out extensions */
16
/* Include decoders for factored-out extensions */
17
#include "decode-XVentanaCondOps.c.inc"
17
#include "decode-XVentanaCondOps.c.inc"
18
18
19
+/* The specification allows for longer insns, but not supported by qemu. */
19
+/* The specification allows for longer insns, but not supported by qemu. */
20
+#define MAX_INSN_LEN 4
20
+#define MAX_INSN_LEN 4
21
+
21
+
22
+static inline int insn_len(uint16_t first_word)
22
+static inline int insn_len(uint16_t first_word)
23
+{
23
+{
24
+ return (first_word & 3) == 3 ? 4 : 2;
24
+ return (first_word & 3) == 3 ? 4 : 2;
25
+}
25
+}
26
+
26
+
27
static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
27
static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
28
{
28
{
29
/*
29
/*
30
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
30
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
31
};
31
};
32
32
33
/* Check for compressed insn */
33
/* Check for compressed insn */
34
- if (extract16(opcode, 0, 2) != 3) {
34
- if (extract16(opcode, 0, 2) != 3) {
35
+ if (insn_len(opcode) == 2) {
35
+ if (insn_len(opcode) == 2) {
36
if (!has_ext(ctx, RVC)) {
36
if (!has_ext(ctx, RVC)) {
37
gen_exception_illegal(ctx);
37
gen_exception_illegal(ctx);
38
} else {
38
} else {
39
--
39
--
40
2.34.1
40
2.34.1
diff view generated by jsdifflib
1
Right now the translator stops right *after* the end of a page, which
1
Right now the translator stops right *after* the end of a page, which
2
breaks reporting of fault locations when the last instruction of a
2
breaks reporting of fault locations when the last instruction of a
3
multi-insn translation block crosses a page boundary.
3
multi-insn translation block crosses a page boundary.
4
4
5
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1155
5
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1155
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
7
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
8
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
10
---
11
target/riscv/translate.c | 17 +++++--
11
target/riscv/translate.c | 17 +++++--
12
tests/tcg/riscv64/noexec.c | 79 +++++++++++++++++++++++++++++++
12
tests/tcg/riscv64/noexec.c | 79 +++++++++++++++++++++++++++++++
13
tests/tcg/riscv64/Makefile.target | 1 +
13
tests/tcg/riscv64/Makefile.target | 1 +
14
3 files changed, 93 insertions(+), 4 deletions(-)
14
3 files changed, 93 insertions(+), 4 deletions(-)
15
create mode 100644 tests/tcg/riscv64/noexec.c
15
create mode 100644 tests/tcg/riscv64/noexec.c
16
16
17
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
17
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/translate.c
19
--- a/target/riscv/translate.c
20
+++ b/target/riscv/translate.c
20
+++ b/target/riscv/translate.c
21
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
21
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
22
}
22
}
23
ctx->nftemp = 0;
23
ctx->nftemp = 0;
24
24
25
+ /* Only the first insn within a TB is allowed to cross a page boundary. */
25
+ /* Only the first insn within a TB is allowed to cross a page boundary. */
26
if (ctx->base.is_jmp == DISAS_NEXT) {
26
if (ctx->base.is_jmp == DISAS_NEXT) {
27
- target_ulong page_start;
27
- target_ulong page_start;
28
-
28
-
29
- page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29
- page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
30
- if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE) {
30
- if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE) {
31
+ if (!is_same_page(&ctx->base, ctx->base.pc_next)) {
31
+ if (!is_same_page(&ctx->base, ctx->base.pc_next)) {
32
ctx->base.is_jmp = DISAS_TOO_MANY;
32
ctx->base.is_jmp = DISAS_TOO_MANY;
33
+ } else {
33
+ } else {
34
+ unsigned page_ofs = ctx->base.pc_next & ~TARGET_PAGE_MASK;
34
+ unsigned page_ofs = ctx->base.pc_next & ~TARGET_PAGE_MASK;
35
+
35
+
36
+ if (page_ofs > TARGET_PAGE_SIZE - MAX_INSN_LEN) {
36
+ if (page_ofs > TARGET_PAGE_SIZE - MAX_INSN_LEN) {
37
+ uint16_t next_insn = cpu_lduw_code(env, ctx->base.pc_next);
37
+ uint16_t next_insn = cpu_lduw_code(env, ctx->base.pc_next);
38
+ int len = insn_len(next_insn);
38
+ int len = insn_len(next_insn);
39
+
39
+
40
+ if (!is_same_page(&ctx->base, ctx->base.pc_next + len)) {
40
+ if (!is_same_page(&ctx->base, ctx->base.pc_next + len)) {
41
+ ctx->base.is_jmp = DISAS_TOO_MANY;
41
+ ctx->base.is_jmp = DISAS_TOO_MANY;
42
+ }
42
+ }
43
+ }
43
+ }
44
}
44
}
45
}
45
}
46
}
46
}
47
diff --git a/tests/tcg/riscv64/noexec.c b/tests/tcg/riscv64/noexec.c
47
diff --git a/tests/tcg/riscv64/noexec.c b/tests/tcg/riscv64/noexec.c
48
new file mode 100644
48
new file mode 100644
49
index XXXXXXX..XXXXXXX
49
index XXXXXXX..XXXXXXX
50
--- /dev/null
50
--- /dev/null
51
+++ b/tests/tcg/riscv64/noexec.c
51
+++ b/tests/tcg/riscv64/noexec.c
52
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@
53
+#include "../multiarch/noexec.c.inc"
53
+#include "../multiarch/noexec.c.inc"
54
+
54
+
55
+static void *arch_mcontext_pc(const mcontext_t *ctx)
55
+static void *arch_mcontext_pc(const mcontext_t *ctx)
56
+{
56
+{
57
+ return (void *)ctx->__gregs[REG_PC];
57
+ return (void *)ctx->__gregs[REG_PC];
58
+}
58
+}
59
+
59
+
60
+static int arch_mcontext_arg(const mcontext_t *ctx)
60
+static int arch_mcontext_arg(const mcontext_t *ctx)
61
+{
61
+{
62
+ return ctx->__gregs[REG_A0];
62
+ return ctx->__gregs[REG_A0];
63
+}
63
+}
64
+
64
+
65
+static void arch_flush(void *p, int len)
65
+static void arch_flush(void *p, int len)
66
+{
66
+{
67
+ __builtin___clear_cache(p, p + len);
67
+ __builtin___clear_cache(p, p + len);
68
+}
68
+}
69
+
69
+
70
+extern char noexec_1[];
70
+extern char noexec_1[];
71
+extern char noexec_2[];
71
+extern char noexec_2[];
72
+extern char noexec_end[];
72
+extern char noexec_end[];
73
+
73
+
74
+asm(".option push\n"
74
+asm(".option push\n"
75
+ ".option norvc\n"
75
+ ".option norvc\n"
76
+ "noexec_1:\n"
76
+ "noexec_1:\n"
77
+ " li a0,1\n" /* a0 is 0 on entry, set 1. */
77
+ " li a0,1\n" /* a0 is 0 on entry, set 1. */
78
+ "noexec_2:\n"
78
+ "noexec_2:\n"
79
+ " li a0,2\n" /* a0 is 0/1; set 2. */
79
+ " li a0,2\n" /* a0 is 0/1; set 2. */
80
+ " ret\n"
80
+ " ret\n"
81
+ "noexec_end:\n"
81
+ "noexec_end:\n"
82
+ ".option pop");
82
+ ".option pop");
83
+
83
+
84
+int main(void)
84
+int main(void)
85
+{
85
+{
86
+ struct noexec_test noexec_tests[] = {
86
+ struct noexec_test noexec_tests[] = {
87
+ {
87
+ {
88
+ .name = "fallthrough",
88
+ .name = "fallthrough",
89
+ .test_code = noexec_1,
89
+ .test_code = noexec_1,
90
+ .test_len = noexec_end - noexec_1,
90
+ .test_len = noexec_end - noexec_1,
91
+ .page_ofs = noexec_1 - noexec_2,
91
+ .page_ofs = noexec_1 - noexec_2,
92
+ .entry_ofs = noexec_1 - noexec_2,
92
+ .entry_ofs = noexec_1 - noexec_2,
93
+ .expected_si_ofs = 0,
93
+ .expected_si_ofs = 0,
94
+ .expected_pc_ofs = 0,
94
+ .expected_pc_ofs = 0,
95
+ .expected_arg = 1,
95
+ .expected_arg = 1,
96
+ },
96
+ },
97
+ {
97
+ {
98
+ .name = "jump",
98
+ .name = "jump",
99
+ .test_code = noexec_1,
99
+ .test_code = noexec_1,
100
+ .test_len = noexec_end - noexec_1,
100
+ .test_len = noexec_end - noexec_1,
101
+ .page_ofs = noexec_1 - noexec_2,
101
+ .page_ofs = noexec_1 - noexec_2,
102
+ .entry_ofs = 0,
102
+ .entry_ofs = 0,
103
+ .expected_si_ofs = 0,
103
+ .expected_si_ofs = 0,
104
+ .expected_pc_ofs = 0,
104
+ .expected_pc_ofs = 0,
105
+ .expected_arg = 0,
105
+ .expected_arg = 0,
106
+ },
106
+ },
107
+ {
107
+ {
108
+ .name = "fallthrough [cross]",
108
+ .name = "fallthrough [cross]",
109
+ .test_code = noexec_1,
109
+ .test_code = noexec_1,
110
+ .test_len = noexec_end - noexec_1,
110
+ .test_len = noexec_end - noexec_1,
111
+ .page_ofs = noexec_1 - noexec_2 - 2,
111
+ .page_ofs = noexec_1 - noexec_2 - 2,
112
+ .entry_ofs = noexec_1 - noexec_2 - 2,
112
+ .entry_ofs = noexec_1 - noexec_2 - 2,
113
+ .expected_si_ofs = 0,
113
+ .expected_si_ofs = 0,
114
+ .expected_pc_ofs = -2,
114
+ .expected_pc_ofs = -2,
115
+ .expected_arg = 1,
115
+ .expected_arg = 1,
116
+ },
116
+ },
117
+ {
117
+ {
118
+ .name = "jump [cross]",
118
+ .name = "jump [cross]",
119
+ .test_code = noexec_1,
119
+ .test_code = noexec_1,
120
+ .test_len = noexec_end - noexec_1,
120
+ .test_len = noexec_end - noexec_1,
121
+ .page_ofs = noexec_1 - noexec_2 - 2,
121
+ .page_ofs = noexec_1 - noexec_2 - 2,
122
+ .entry_ofs = -2,
122
+ .entry_ofs = -2,
123
+ .expected_si_ofs = 0,
123
+ .expected_si_ofs = 0,
124
+ .expected_pc_ofs = -2,
124
+ .expected_pc_ofs = -2,
125
+ .expected_arg = 0,
125
+ .expected_arg = 0,
126
+ },
126
+ },
127
+ };
127
+ };
128
+
128
+
129
+ return test_noexec(noexec_tests,
129
+ return test_noexec(noexec_tests,
130
+ sizeof(noexec_tests) / sizeof(noexec_tests[0]));
130
+ sizeof(noexec_tests) / sizeof(noexec_tests[0]));
131
+}
131
+}
132
diff --git a/tests/tcg/riscv64/Makefile.target b/tests/tcg/riscv64/Makefile.target
132
diff --git a/tests/tcg/riscv64/Makefile.target b/tests/tcg/riscv64/Makefile.target
133
index XXXXXXX..XXXXXXX 100644
133
index XXXXXXX..XXXXXXX 100644
134
--- a/tests/tcg/riscv64/Makefile.target
134
--- a/tests/tcg/riscv64/Makefile.target
135
+++ b/tests/tcg/riscv64/Makefile.target
135
+++ b/tests/tcg/riscv64/Makefile.target
136
@@ -XXX,XX +XXX,XX @@
136
@@ -XXX,XX +XXX,XX @@
137
137
138
VPATH += $(SRC_PATH)/tests/tcg/riscv64
138
VPATH += $(SRC_PATH)/tests/tcg/riscv64
139
TESTS += test-div
139
TESTS += test-div
140
+TESTS += noexec
140
+TESTS += noexec
141
--
141
--
142
2.34.1
142
2.34.1
diff view generated by jsdifflib