1
The following changes since commit 4c41341af76cfc85b5a6c0f87de4838672ab9f89:
1
Nothing too exciting, but does include the last bits of v8.1M support work.
2
2
3
Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20201020' into staging (2020-10-20 11:20:36 +0100)
3
-- PMM
4
5
The following changes since commit e79de63ab1bd1f6550e7b915e433bec1ad1a870a:
6
7
Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-tcg-20210107' into staging (2021-01-07 20:34:05 +0000)
4
8
5
are available in the Git repository at:
9
are available in the Git repository at:
6
10
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201020
11
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210108
8
12
9
for you to fetch changes up to 6358890cb939192f6169fdf7664d903bf9b1d338:
13
for you to fetch changes up to c9f8511ea8d2b80723af0fea1f716d752c1b5208:
10
14
11
tests/tcg/aarch64: Add bti smoke tests (2020-10-20 16:12:02 +0100)
15
docs/system: arm: Add sabrelite board description (2021-01-08 15:13:39 +0000)
12
16
13
----------------------------------------------------------------
17
----------------------------------------------------------------
14
target-arm queue:
18
target-arm queue:
15
* Fix AArch32 SMLAD incorrect setting of Q bit
19
* intc/arm_gic: Fix gic_irq_signaling_enabled() for vCPUs
16
* AArch32 VCVT fixed-point to float is always round-to-nearest
20
* target/arm: Fix MTE0_ACTIVE
17
* strongarm: Fix 'time to transmit a char' unit comment
21
* target/arm: Implement v8.1M and Cortex-M55 model
18
* Restrict APEI tables generation to the 'virt' machine
22
* hw/arm/highbank: Drop dead KVM support code
19
* bcm2835: minor code cleanups
23
* util/qemu-timer: Make timer_free() imply timer_del()
20
* correctly flush TLBs when TBI is enabled
24
* various devices: Use ptimer_free() in finalize function
21
* tests/qtest: Add npcm7xx timer test
25
* docs/system: arm: Add sabrelite board description
22
* loads-stores.rst: add footnote that clarifies GETPC usage
26
* sabrelite: Minor fixes to allow booting U-Boot
23
* Fix reported EL for mte_check_fail
24
* Ignore HCR_EL2.ATA when {E2H,TGE} != 11
25
* microbit_i2c: Fix coredump when dump-vmstate
26
* nseries: Fix loading kernel image on n8x0 machines
27
* Implement v8.1M low-overhead-loops
28
* linux-user: Support AArch64 BTI
29
27
30
----------------------------------------------------------------
28
----------------------------------------------------------------
31
Emanuele Giuseppe Esposito (1):
29
Andrew Jones (1):
32
loads-stores.rst: add footnote that clarifies GETPC usage
30
hw/arm/virt: Remove virt machine state 'smp_cpus'
33
31
34
Havard Skinnemoen (1):
32
Bin Meng (4):
35
tests/qtest: Add npcm7xx timer test
33
hw/misc: imx6_ccm: Update PMU_MISC0 reset value
34
hw/msic: imx6_ccm: Correct register value for silicon type
35
hw/arm: sabrelite: Connect the Ethernet PHY at address 6
36
docs/system: arm: Add sabrelite board description
36
37
37
Peng Liang (1):
38
Edgar E. Iglesias (1):
38
microbit_i2c: Fix coredump when dump-vmstate
39
intc/arm_gic: Fix gic_irq_signaling_enabled() for vCPUs
39
40
40
Peter Maydell (12):
41
Gan Qixin (7):
41
target/arm: Fix SMLAD incorrect setting of Q bit
42
digic-timer: Use ptimer_free() in the finalize function to avoid memleaks
42
target/arm: AArch32 VCVT fixed-point to float is always round-to-nearest
43
allwinner-a10-pit: Use ptimer_free() in the finalize function to avoid memleaks
43
decodetree: Fix codegen for non-overlapping group inside overlapping group
44
exynos4210_rtc: Use ptimer_free() in the finalize function to avoid memleaks
44
target/arm: Implement v8.1M NOCP handling
45
exynos4210_pwm: Use ptimer_free() in the finalize function to avoid memleaks
45
target/arm: Implement v8.1M conditional-select insns
46
mss-timer: Use ptimer_free() in the finalize function to avoid memleaks
46
target/arm: Make the t32 insn[25:23]=111 group non-overlapping
47
musicpal: Use ptimer_free() in the finalize function to avoid memleaks
47
target/arm: Don't allow BLX imm for M-profile
48
exynos4210_mct: Use ptimer_free() in the finalize function to avoid memleaks
48
target/arm: Implement v8.1M branch-future insns (as NOPs)
49
target/arm: Implement v8.1M low-overhead-loop instructions
50
target/arm: Fix has_vfp/has_neon ID reg squashing for M-profile
51
target/arm: Allow M-profile CPUs with FP16 to set FPSCR.FP16
52
target/arm: Implement FPSCR.LTPSIZE for M-profile LOB extension
53
49
54
Philippe Mathieu-Daudé (10):
50
Peter Maydell (9):
55
hw/arm/strongarm: Fix 'time to transmit a char' unit comment
51
hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN
56
hw/arm: Restrict APEI tables generation to the 'virt' machine
52
target/arm: Correct store of FPSCR value via FPCXT_S
57
hw/timer/bcm2835: Introduce BCM2835_SYSTIMER_COUNT definition
53
target/arm: Implement FPCXT_NS fp system register
58
hw/timer/bcm2835: Rename variable holding CTRL_STATUS register
54
target/arm: Implement Cortex-M55 model
59
hw/timer/bcm2835: Support the timer COMPARE registers
55
hw/arm/highbank: Drop dead KVM support code
60
hw/arm/bcm2835_peripherals: Correctly wire the SYS_timer IRQs
56
util/qemu-timer: Make timer_free() imply timer_del()
61
hw/intc/bcm2835_ic: Trace GPU/CPU IRQ handlers
57
scripts/coccinelle: New script to remove unnecessary timer_del() calls
62
hw/intc/bcm2836_control: Use IRQ definitions instead of magic numbers
58
Remove superfluous timer_del() calls
63
hw/arm/nseries: Fix loading kernel image on n8x0 machines
59
target/arm: Remove timer_del()/timer_deinit() before timer_free()
64
linux-user/elfload: Avoid leaking interp_name using GLib memory API
65
60
66
Richard Henderson (16):
61
Richard Henderson (1):
67
accel/tcg: Add tlb_flush_page_bits_by_mmuidx*
62
target/arm: Fix MTE0_ACTIVE
68
target/arm: Use tlb_flush_page_bits_by_mmuidx*
69
target/arm: Remove redundant mmu_idx lookup
70
target/arm: Fix reported EL for mte_check_fail
71
target/arm: Ignore HCR_EL2.ATA when {E2H,TGE} != 11
72
linux-user/aarch64: Reset btype for signals
73
linux-user: Set PAGE_TARGET_1 for TARGET_PROT_BTI
74
include/elf: Add defines related to GNU property notes for AArch64
75
linux-user/elfload: Fix coding style in load_elf_image
76
linux-user/elfload: Adjust iteration over phdr
77
linux-user/elfload: Move PT_INTERP detection to first loop
78
linux-user/elfload: Use Error for load_elf_image
79
linux-user/elfload: Use Error for load_elf_interp
80
linux-user/elfload: Parse NT_GNU_PROPERTY_TYPE_0 notes
81
linux-user/elfload: Parse GNU_PROPERTY_AARCH64_FEATURE_1_AND
82
tests/tcg/aarch64: Add bti smoke tests
83
63
84
docs/devel/loads-stores.rst | 8 +-
64
docs/system/arm/sabrelite.rst | 119 ++++++++++++++++++++++++++
85
default-configs/devices/arm-softmmu.mak | 1 -
65
docs/system/target-arm.rst | 1 +
86
include/elf.h | 22 ++
66
scripts/coccinelle/timer-del-timer-free.cocci | 18 ++++
87
include/exec/cpu-all.h | 2 +
67
include/hw/arm/virt.h | 3 +-
88
include/exec/exec-all.h | 36 ++
68
include/qemu/timer.h | 24 +++---
89
include/hw/timer/bcm2835_systmr.h | 17 +-
69
block/iscsi.c | 2 -
90
linux-user/qemu.h | 4 +
70
block/nbd.c | 1 -
91
linux-user/syscall_defs.h | 4 +
71
block/qcow2.c | 1 -
92
target/arm/cpu.h | 13 +
72
hw/arm/highbank.c | 14 +--
93
target/arm/helper.h | 13 +
73
hw/arm/musicpal.c | 12 +++
94
target/arm/internals.h | 9 +-
74
hw/arm/sabrelite.c | 4 +
95
target/arm/m-nocp.decode | 10 +-
75
hw/arm/virt-acpi-build.c | 9 +-
96
target/arm/t32.decode | 50 ++-
76
hw/arm/virt.c | 21 +++--
97
accel/tcg/cputlb.c | 275 +++++++++++++++-
77
hw/block/nvme.c | 2 -
98
hw/arm/bcm2835_peripherals.c | 13 +-
78
hw/char/serial.c | 2 -
99
hw/arm/nseries.c | 1 +
79
hw/char/virtio-serial-bus.c | 2 -
100
hw/arm/strongarm.c | 2 +-
80
hw/ide/core.c | 1 -
101
hw/i2c/microbit_i2c.c | 1 +
81
hw/input/hid.c | 1 -
102
hw/intc/bcm2835_ic.c | 4 +-
82
hw/intc/apic.c | 1 -
103
hw/intc/bcm2836_control.c | 8 +-
83
hw/intc/arm_gic.c | 4 +-
104
hw/timer/bcm2835_systmr.c | 57 ++--
84
hw/intc/armv7m_nvic.c | 15 ++++
105
linux-user/aarch64/signal.c | 10 +-
85
hw/intc/ioapic.c | 1 -
106
linux-user/elfload.c | 326 ++++++++++++++----
86
hw/ipmi/ipmi_bmc_extern.c | 1 -
107
linux-user/mmap.c | 16 +
87
hw/misc/imx6_ccm.c | 4 +-
108
target/arm/cpu.c | 38 ++-
88
hw/net/e1000.c | 3 -
109
target/arm/helper.c | 55 +++-
89
hw/net/e1000e_core.c | 8 --
110
target/arm/mte_helper.c | 13 +-
90
hw/net/pcnet-pci.c | 1 -
111
target/arm/translate-a64.c | 6 +-
91
hw/net/rtl8139.c | 1 -
112
target/arm/translate.c | 239 +++++++++++++-
92
hw/net/spapr_llan.c | 1 -
113
target/arm/vfp_helper.c | 76 +++--
93
hw/net/virtio-net.c | 2 -
114
tests/qtest/npcm7xx_timer-test.c | 562 ++++++++++++++++++++++++++++++++
94
hw/rtc/exynos4210_rtc.c | 9 ++
115
tests/tcg/aarch64/bti-1.c | 62 ++++
95
hw/s390x/s390-pci-inst.c | 1 -
116
tests/tcg/aarch64/bti-2.c | 108 ++++++
96
hw/sd/sd.c | 1 -
117
tests/tcg/aarch64/bti-crt.inc.c | 51 +++
97
hw/sd/sdhci.c | 2 -
118
hw/arm/Kconfig | 1 +
98
hw/timer/allwinner-a10-pit.c | 11 +++
119
hw/intc/trace-events | 4 +
99
hw/timer/digic-timer.c | 8 ++
120
hw/timer/trace-events | 6 +-
100
hw/timer/exynos4210_mct.c | 14 +++
121
scripts/decodetree.py | 2 +-
101
hw/timer/exynos4210_pwm.c | 11 +++
122
target/arm/translate-vfp.c.inc | 41 ++-
102
hw/timer/mss-timer.c | 13 +++
123
tests/qtest/meson.build | 1 +
103
hw/usb/dev-hub.c | 1 -
124
tests/tcg/aarch64/Makefile.target | 10 +
104
hw/usb/hcd-ehci.c | 1 -
125
tests/tcg/configure.sh | 4 +
105
hw/usb/hcd-ohci-pci.c | 1 -
126
42 files changed, 1973 insertions(+), 208 deletions(-)
106
hw/usb/hcd-uhci.c | 1 -
127
create mode 100644 tests/qtest/npcm7xx_timer-test.c
107
hw/usb/hcd-xhci.c | 1 -
128
create mode 100644 tests/tcg/aarch64/bti-1.c
108
hw/usb/redirect.c | 1 -
129
create mode 100644 tests/tcg/aarch64/bti-2.c
109
hw/vfio/display.c | 1 -
130
create mode 100644 tests/tcg/aarch64/bti-crt.inc.c
110
hw/virtio/vhost-vsock-common.c | 1 -
111
hw/virtio/virtio-balloon.c | 1 -
112
hw/virtio/virtio-rng.c | 1 -
113
hw/watchdog/wdt_diag288.c | 1 -
114
hw/watchdog/wdt_i6300esb.c | 1 -
115
migration/colo.c | 1 -
116
monitor/hmp-cmds.c | 1 -
117
net/announce.c | 1 -
118
net/colo-compare.c | 1 -
119
net/slirp.c | 1 -
120
replay/replay-debugging.c | 1 -
121
target/arm/cpu.c | 2 -
122
target/arm/cpu_tcg.c | 42 +++++++++
123
target/arm/helper.c | 2 +-
124
target/s390x/cpu.c | 2 -
125
ui/console.c | 1 -
126
ui/spice-core.c | 1 -
127
util/throttle.c | 1 -
128
target/arm/translate-vfp.c.inc | 114 ++++++++++++++++++++++--
129
65 files changed, 421 insertions(+), 111 deletions(-)
130
create mode 100644 docs/system/arm/sabrelite.rst
131
create mode 100644 scripts/coccinelle/timer-del-timer-free.cocci
131
132
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
This is a bit clearer than open-coding some of this
3
Correct the indexing into s->cpu_ctlr for vCPUs.
4
with a bare c string.
5
4
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20201016184207.786698-9-richard.henderson@linaro.org
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20201214222154.3480243-2-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
linux-user/elfload.c | 37 ++++++++++++++++++++-----------------
11
hw/intc/arm_gic.c | 4 +++-
12
1 file changed, 20 insertions(+), 17 deletions(-)
12
1 file changed, 3 insertions(+), 1 deletion(-)
13
13
14
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
14
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/elfload.c
16
--- a/hw/intc/arm_gic.c
17
+++ b/linux-user/elfload.c
17
+++ b/hw/intc/arm_gic.c
18
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static inline void gic_get_best_virq(GICState *s, int cpu,
19
#include "qemu/guest-random.h"
19
static inline bool gic_irq_signaling_enabled(GICState *s, int cpu, bool virt,
20
#include "qemu/units.h"
20
int group_mask)
21
#include "qemu/selfmap.h"
21
{
22
+#include "qapi/error.h"
22
+ int cpu_iface = virt ? (cpu + GIC_NCPU) : cpu;
23
23
+
24
#ifdef _ARCH_PPC64
24
if (!virt && !(s->ctlr & group_mask)) {
25
#undef ARCH_DLINFO
25
return false;
26
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
27
struct elf_phdr *phdr;
28
abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
29
int i, retval;
30
- const char *errmsg;
31
+ Error *err = NULL;
32
33
/* First of all, some simple consistency checks */
34
- errmsg = "Invalid ELF image for this architecture";
35
if (!elf_check_ident(ehdr)) {
36
+ error_setg(&err, "Invalid ELF image for this architecture");
37
goto exit_errmsg;
38
}
26
}
39
bswap_ehdr(ehdr);
27
@@ -XXX,XX +XXX,XX @@ static inline bool gic_irq_signaling_enabled(GICState *s, int cpu, bool virt,
40
if (!elf_check_ehdr(ehdr)) {
28
return false;
41
+ error_setg(&err, "Invalid ELF image for this architecture");
42
goto exit_errmsg;
43
}
29
}
44
30
45
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
31
- if (!(s->cpu_ctlr[cpu] & group_mask)) {
46
g_autofree char *interp_name = NULL;
32
+ if (!(s->cpu_ctlr[cpu_iface] & group_mask)) {
47
33
return false;
48
if (*pinterp_name) {
49
- errmsg = "Multiple PT_INTERP entries";
50
+ error_setg(&err, "Multiple PT_INTERP entries");
51
goto exit_errmsg;
52
}
53
+
54
interp_name = g_malloc(eppnt->p_filesz);
55
- if (!interp_name) {
56
- goto exit_perror;
57
- }
58
59
if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
60
memcpy(interp_name, bprm_buf + eppnt->p_offset,
61
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
62
retval = pread(image_fd, interp_name, eppnt->p_filesz,
63
eppnt->p_offset);
64
if (retval != eppnt->p_filesz) {
65
- goto exit_perror;
66
+ goto exit_read;
67
}
68
}
69
if (interp_name[eppnt->p_filesz - 1] != 0) {
70
- errmsg = "Invalid PT_INTERP entry";
71
+ error_setg(&err, "Invalid PT_INTERP entry");
72
goto exit_errmsg;
73
}
74
*pinterp_name = g_steal_pointer(&interp_name);
75
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
76
(ehdr->e_type == ET_EXEC ? MAP_FIXED : 0),
77
-1, 0);
78
if (load_addr == -1) {
79
- goto exit_perror;
80
+ goto exit_mmap;
81
}
34
}
82
load_bias = load_addr - loaddr;
83
84
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
85
image_fd, eppnt->p_offset - vaddr_po);
86
87
if (error == -1) {
88
- goto exit_perror;
89
+ goto exit_mmap;
90
}
91
}
92
93
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
94
} else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
95
Mips_elf_abiflags_v0 abiflags;
96
if (eppnt->p_filesz < sizeof(Mips_elf_abiflags_v0)) {
97
- errmsg = "Invalid PT_MIPS_ABIFLAGS entry";
98
+ error_setg(&err, "Invalid PT_MIPS_ABIFLAGS entry");
99
goto exit_errmsg;
100
}
101
if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
102
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
103
retval = pread(image_fd, &abiflags, sizeof(Mips_elf_abiflags_v0),
104
eppnt->p_offset);
105
if (retval != sizeof(Mips_elf_abiflags_v0)) {
106
- goto exit_perror;
107
+ goto exit_read;
108
}
109
}
110
bswap_mips_abiflags(&abiflags);
111
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
112
113
exit_read:
114
if (retval >= 0) {
115
- errmsg = "Incomplete read of file header";
116
- goto exit_errmsg;
117
+ error_setg(&err, "Incomplete read of file header");
118
+ } else {
119
+ error_setg_errno(&err, errno, "Error reading file header");
120
}
121
- exit_perror:
122
- errmsg = strerror(errno);
123
+ goto exit_errmsg;
124
+ exit_mmap:
125
+ error_setg_errno(&err, errno, "Error mapping file");
126
+ goto exit_errmsg;
127
exit_errmsg:
128
- fprintf(stderr, "%s: %s\n", image_name, errmsg);
129
+ error_reportf_err(err, "%s: ", image_name);
130
exit(-1);
131
}
132
35
133
--
36
--
134
2.20.1
37
2.20.1
135
38
136
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
This is slightly clearer than just using strerror, though
3
virt machine's 'smp_cpus' and machine->smp.cpus must always have the
4
the different forms produced by error_setg_file_open and
4
same value. And, anywhere we have virt machine state we have machine
5
error_setg_errno isn't entirely convenient.
5
state. So let's remove the redundancy. Also, to make it easier to see
6
that machine->smp is the true source for "smp_cpus" and "max_cpus",
7
avoid passing them in function parameters, preferring instead to get
8
them from the state.
6
9
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
No functional change intended.
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
9
Message-id: 20201016184207.786698-10-richard.henderson@linaro.org
12
Signed-off-by: Andrew Jones <drjones@redhat.com>
13
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
14
Reviewed-by: Ying Fang <fangying1@huawei.com>
15
Message-id: 20201215174815.51520-1-drjones@redhat.com
16
[PMM: minor formatting tweak to smp_cpus variable declaration]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
18
---
12
linux-user/elfload.c | 15 ++++++++-------
19
include/hw/arm/virt.h | 3 +--
13
1 file changed, 8 insertions(+), 7 deletions(-)
20
hw/arm/virt-acpi-build.c | 9 +++++----
21
hw/arm/virt.c | 21 ++++++++++-----------
22
3 files changed, 16 insertions(+), 17 deletions(-)
14
23
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
24
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
16
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
26
--- a/include/hw/arm/virt.h
18
+++ b/linux-user/elfload.c
27
+++ b/include/hw/arm/virt.h
19
@@ -XXX,XX +XXX,XX @@ static void load_elf_interp(const char *filename, struct image_info *info,
28
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
20
char bprm_buf[BPRM_BUF_SIZE])
29
MemMapEntry *memmap;
30
char *pciehb_nodename;
31
const int *irqmap;
32
- int smp_cpus;
33
void *fdt;
34
int fdt_size;
35
uint32_t clock_phandle;
36
@@ -XXX,XX +XXX,XX @@ static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
37
38
assert(vms->gic_version == VIRT_GIC_VERSION_3);
39
40
- return vms->smp_cpus > redist0_capacity ? 2 : 1;
41
+ return MACHINE(vms)->smp.cpus > redist0_capacity ? 2 : 1;
42
}
43
44
#endif /* QEMU_ARM_VIRT_H */
45
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/virt-acpi-build.c
48
+++ b/hw/arm/virt-acpi-build.c
49
@@ -XXX,XX +XXX,XX @@
50
51
#define ACPI_BUILD_TABLE_SIZE 0x20000
52
53
-static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
54
+static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms)
21
{
55
{
22
int fd, retval;
56
+ MachineState *ms = MACHINE(vms);
23
+ Error *err = NULL;
57
uint16_t i;
24
58
25
fd = open(path(filename), O_RDONLY);
59
- for (i = 0; i < smp_cpus; i++) {
26
if (fd < 0) {
60
+ for (i = 0; i < ms->smp.cpus; i++) {
27
- goto exit_perror;
61
Aml *dev = aml_device("C%.03X", i);
28
+ error_setg_file_open(&err, errno, filename);
62
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
29
+ error_report_err(err);
63
aml_append(dev, aml_name_decl("_UID", aml_int(i)));
30
+ exit(-1);
64
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
65
gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base);
66
gicd->version = vms->gic_version;
67
68
- for (i = 0; i < vms->smp_cpus; i++) {
69
+ for (i = 0; i < MACHINE(vms)->smp.cpus; i++) {
70
AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data,
71
sizeof(*gicc));
72
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
73
@@ -XXX,XX +XXX,XX @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
74
* the RTC ACPI device at all when using UEFI.
75
*/
76
scope = aml_scope("\\_SB");
77
- acpi_dsdt_add_cpus(scope, vms->smp_cpus);
78
+ acpi_dsdt_add_cpus(scope, vms);
79
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
80
(irqmap[VIRT_UART] + ARM_SPI_BASE));
81
if (vmc->acpi_expose_flash) {
82
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/arm/virt.c
85
+++ b/hw/arm/virt.c
86
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
87
if (vms->gic_version == VIRT_GIC_VERSION_2) {
88
irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
89
GIC_FDT_IRQ_PPI_CPU_WIDTH,
90
- (1 << vms->smp_cpus) - 1);
91
+ (1 << MACHINE(vms)->smp.cpus) - 1);
31
}
92
}
32
93
33
retval = read(fd, bprm_buf, BPRM_BUF_SIZE);
94
qemu_fdt_add_subnode(vms->fdt, "/timer");
34
if (retval < 0) {
95
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
35
- goto exit_perror;
96
int cpu;
36
+ error_setg_errno(&err, errno, "Error reading file header");
97
int addr_cells = 1;
37
+ error_reportf_err(err, "%s: ", filename);
98
const MachineState *ms = MACHINE(vms);
38
+ exit(-1);
99
+ int smp_cpus = ms->smp.cpus;
100
101
/*
102
* From Documentation/devicetree/bindings/arm/cpus.txt
103
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
104
* The simplest way to go is to examine affinity IDs of all our CPUs. If
105
* at least one of them has Aff3 populated, we set #address-cells to 2.
106
*/
107
- for (cpu = 0; cpu < vms->smp_cpus; cpu++) {
108
+ for (cpu = 0; cpu < smp_cpus; cpu++) {
109
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
110
111
if (armcpu->mp_affinity & ARM_AFF3_MASK) {
112
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
113
qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#address-cells", addr_cells);
114
qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#size-cells", 0x0);
115
116
- for (cpu = vms->smp_cpus - 1; cpu >= 0; cpu--) {
117
+ for (cpu = smp_cpus - 1; cpu >= 0; cpu--) {
118
char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
119
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
120
CPUState *cs = CPU(armcpu);
121
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
122
qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
123
armcpu->dtb_compatible);
124
125
- if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED
126
- && vms->smp_cpus > 1) {
127
+ if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED && smp_cpus > 1) {
128
qemu_fdt_setprop_string(vms->fdt, nodename,
129
"enable-method", "psci");
130
}
131
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
132
if (vms->gic_version == VIRT_GIC_VERSION_2) {
133
irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
134
GIC_FDT_IRQ_PPI_CPU_WIDTH,
135
- (1 << vms->smp_cpus) - 1);
136
+ (1 << MACHINE(vms)->smp.cpus) - 1);
39
}
137
}
40
+
138
41
if (retval < BPRM_BUF_SIZE) {
139
qemu_fdt_add_subnode(vms->fdt, "/pmu");
42
memset(bprm_buf + retval, 0, BPRM_BUF_SIZE - retval);
140
@@ -XXX,XX +XXX,XX @@ static void finalize_gic_version(VirtMachineState *vms)
141
* virt_cpu_post_init() must be called after the CPUs have
142
* been realized and the GIC has been created.
143
*/
144
-static void virt_cpu_post_init(VirtMachineState *vms, int max_cpus,
145
- MemoryRegion *sysmem)
146
+static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem)
147
{
148
+ int max_cpus = MACHINE(vms)->smp.max_cpus;
149
bool aarch64, pmu, steal_time;
150
CPUState *cpu;
151
152
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
153
exit(1);
43
}
154
}
44
155
45
load_elf_image(filename, fd, info, NULL, bprm_buf);
156
- vms->smp_cpus = smp_cpus;
46
- return;
47
-
157
-
48
- exit_perror:
158
if (vms->virt && kvm_enabled()) {
49
- fprintf(stderr, "%s: %s\n", filename, strerror(errno));
159
error_report("mach-virt: KVM does not support providing "
50
- exit(-1);
160
"Virtualization extensions to the guest CPU");
51
}
161
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
52
162
create_fdt(vms);
53
static int symfind(const void *s0, const void *s1)
163
164
possible_cpus = mc->possible_cpu_arch_ids(machine);
165
+ assert(possible_cpus->len == max_cpus);
166
for (n = 0; n < possible_cpus->len; n++) {
167
Object *cpuobj;
168
CPUState *cs;
169
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
170
171
create_gic(vms);
172
173
- virt_cpu_post_init(vms, possible_cpus->len, sysmem);
174
+ virt_cpu_post_init(vms, sysmem);
175
176
fdt_add_pmu_nodes(vms);
177
54
--
178
--
55
2.20.1
179
2.20.1
56
180
57
181
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
When TBI is enabled in a given regime, 56 bits of the address
3
In 50244cc76abc we updated mte_check_fail to match the ARM
4
are significant and we need to clear out any other matching
4
pseudocode, using the correct EL to select the TCF field.
5
virtual addresses with differing tags.
5
But we failed to update MTE0_ACTIVE the same way, which led
6
to g_assert_not_reached().
6
7
7
The other uses of tlb_flush_page (without mmuidx) in this file
8
Cc: qemu-stable@nongnu.org
8
are only used by aarch32 mode.
9
Buglink: https://bugs.launchpad.net/bugs/1907137
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Fixes: 38d931687fa1
11
Message-id: 20201221204426.88514-1-richard.henderson@linaro.org
11
Reported-by: Jordan Frank <jordanfrank@fb.com>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20201016210754.818257-3-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
14
---
18
target/arm/helper.c | 46 ++++++++++++++++++++++++++++++++++++++-------
15
target/arm/helper.c | 2 +-
19
1 file changed, 39 insertions(+), 7 deletions(-)
16
1 file changed, 1 insertion(+), 1 deletion(-)
20
17
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
20
--- a/target/arm/helper.c
24
+++ b/target/arm/helper.c
21
+++ b/target/arm/helper.c
25
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
22
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
26
#endif
23
if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
27
24
&& tbid
28
static void switch_mode(CPUARMState *env, int mode);
25
&& !(env->pstate & PSTATE_TCO)
29
+static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx);
26
- && (sctlr & SCTLR_TCF0)
30
27
+ && (sctlr & SCTLR_TCF)
31
static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
28
&& allocation_tag_access_enabled(env, 0, sctlr)) {
32
{
29
flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
33
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbmask(CPUARMState *env)
30
}
34
}
35
}
36
37
+/* Return 56 if TBI is enabled, 64 otherwise. */
38
+static int tlbbits_for_regime(CPUARMState *env, ARMMMUIdx mmu_idx,
39
+ uint64_t addr)
40
+{
41
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
42
+ int tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
43
+ int select = extract64(addr, 55, 1);
44
+
45
+ return (tbi >> select) & 1 ? 56 : 64;
46
+}
47
+
48
+static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
49
+{
50
+ ARMMMUIdx mmu_idx;
51
+
52
+ /* Only the regime of the mmu_idx below is significant. */
53
+ if (arm_is_secure_below_el3(env)) {
54
+ mmu_idx = ARMMMUIdx_SE10_0;
55
+ } else if ((env->cp15.hcr_el2 & (HCR_E2H | HCR_TGE))
56
+ == (HCR_E2H | HCR_TGE)) {
57
+ mmu_idx = ARMMMUIdx_E20_0;
58
+ } else {
59
+ mmu_idx = ARMMMUIdx_E10_0;
60
+ }
61
+ return tlbbits_for_regime(env, mmu_idx, addr);
62
+}
63
+
64
static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
65
uint64_t value)
66
{
67
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
68
CPUState *cs = env_cpu(env);
69
int mask = vae1_tlbmask(env);
70
uint64_t pageaddr = sextract64(value << 12, 0, 56);
71
+ int bits = vae1_tlbbits(env, pageaddr);
72
73
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask);
74
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
75
}
76
77
static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
78
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
79
CPUState *cs = env_cpu(env);
80
int mask = vae1_tlbmask(env);
81
uint64_t pageaddr = sextract64(value << 12, 0, 56);
82
+ int bits = vae1_tlbbits(env, pageaddr);
83
84
if (tlb_force_broadcast(env)) {
85
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask);
86
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
87
} else {
88
- tlb_flush_page_by_mmuidx(cs, pageaddr, mask);
89
+ tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits);
90
}
91
}
92
93
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
94
{
95
CPUState *cs = env_cpu(env);
96
uint64_t pageaddr = sextract64(value << 12, 0, 56);
97
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_E2, pageaddr);
98
99
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
100
- ARMMMUIdxBit_E2);
101
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
102
+ ARMMMUIdxBit_E2, bits);
103
}
104
105
static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
106
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
107
{
108
CPUState *cs = env_cpu(env);
109
uint64_t pageaddr = sextract64(value << 12, 0, 56);
110
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_SE3, pageaddr);
111
112
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
113
- ARMMMUIdxBit_SE3);
114
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
115
+ ARMMMUIdxBit_SE3, bits);
116
}
117
118
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
119
--
31
--
120
2.20.1
32
2.20.1
121
33
122
34
diff view generated by jsdifflib
1
If the M-profile low-overhead-branch extension is implemented, FPSCR
1
The CCR is a register most of whose bits are banked between security
2
bits [18:16] are a new field LTPSIZE. If MVE is not implemented
2
states but where BFHFNMIGN is not, and we keep it in the non-secure
3
(currently always true for us) then this field always reads as 4 and
3
entry of the v7m.ccr[] array. The logic which tries to handle this
4
ignores writes.
4
bit fails to implement the "RAZ/WI from Nonsecure if AIRCR.BFHFNMINS
5
5
is zero" requirement; correct the omission.
6
These bits used to be the vector-length field for the old
7
short-vector extension, so we need to take care that they are not
8
misinterpreted as setting vec_len. We do this with a rearrangement
9
of the vfp_set_fpscr() code that deals with vec_len, vec_stride
10
and also the QC bit; this obviates the need for the M-profile
11
only masking step that we used to have at the start of the function.
12
13
We provide a new field in CPUState for LTPSIZE, even though this
14
will always be 4, in preparation for MVE, so we don't have to
15
come back later and split it out of the vfp.xregs[FPSCR] value.
16
(This state struct field will be saved and restored as part of
17
the FPSCR value via the vmstate_fpscr in machine.c.)
18
6
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20201019151301.2046-11-peter.maydell@linaro.org
9
Message-id: 20201210201433.26262-2-peter.maydell@linaro.org
22
---
10
---
23
target/arm/cpu.h | 1 +
11
hw/intc/armv7m_nvic.c | 15 +++++++++++++++
24
target/arm/cpu.c | 9 +++++++++
12
1 file changed, 15 insertions(+)
25
target/arm/vfp_helper.c | 6 ++++++
26
3 files changed, 16 insertions(+)
27
13
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
29
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
16
--- a/hw/intc/armv7m_nvic.c
31
+++ b/target/arm/cpu.h
17
+++ b/hw/intc/armv7m_nvic.c
32
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
18
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
33
uint32_t fpdscr[M_REG_NUM_BANKS];
19
*/
34
uint32_t cpacr[M_REG_NUM_BANKS];
20
val = cpu->env.v7m.ccr[attrs.secure];
35
uint32_t nsacr;
21
val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
36
+ int ltpsize;
22
+ /* BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0 */
37
} v7m;
23
+ if (!attrs.secure) {
38
24
+ if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
39
/* Information associated with an exception about to be taken:
25
+ val &= ~R_V7M_CCR_BFHFNMIGN_MASK;
40
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
26
+ }
41
index XXXXXXX..XXXXXXX 100644
27
+ }
42
--- a/target/arm/cpu.c
28
return val;
43
+++ b/target/arm/cpu.c
29
case 0xd24: /* System Handler Control and State (SHCSR) */
44
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
30
if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
45
uint8_t *rom;
31
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
46
uint32_t vecbase;
32
(cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)
47
33
| (value & R_V7M_CCR_BFHFNMIGN_MASK);
48
+ if (cpu_isar_feature(aa32_lob, cpu)) {
34
value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
35
+ } else {
49
+ /*
36
+ /*
50
+ * LTPSIZE is constant 4 if MVE not implemented, and resets
37
+ * BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0, so
51
+ * to an UNKNOWN value if MVE is implemented. We choose to
38
+ * preserve the state currently in the NS element of the array
52
+ * always reset to 4.
53
+ */
39
+ */
54
+ env->v7m.ltpsize = 4;
40
+ if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
55
+ }
41
+ value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
56
+
42
+ value |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
57
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
43
+ }
58
env->v7m.secure = true;
44
}
59
} else {
45
60
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
46
cpu->env.v7m.ccr[attrs.secure] = value;
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/vfp_helper.c
63
+++ b/target/arm/vfp_helper.c
64
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
65
| (env->vfp.vec_len << 16)
66
| (env->vfp.vec_stride << 20);
67
68
+ /*
69
+ * M-profile LTPSIZE overlaps A-profile Stride; whichever of the
70
+ * two is not applicable to this CPU will always be zero.
71
+ */
72
+ fpscr |= env->v7m.ltpsize << 16;
73
+
74
fpscr |= vfp_get_fpscr_from_host(env);
75
76
i = env->vfp.qc[0] | env->vfp.qc[1] | env->vfp.qc[2] | env->vfp.qc[3];
77
--
47
--
78
2.20.1
48
2.20.1
79
49
80
50
diff view generated by jsdifflib
1
For AArch32, unlike the VCVT of integer to float, which honours the
1
In commit 64f863baeedc8659 we implemented the v8.1M FPCXT_S register,
2
rounding mode specified by the FPSCR, VCVT of fixed-point to float is
2
but we got the write behaviour wrong. On read, this register reads
3
always round-to-nearest. (AArch64 fixed-point-to-float conversions
3
bits [27:0] of FPSCR plus the CONTROL.SFPA bit. On write, it doesn't
4
always honour the FPCR rounding mode.)
4
just write back those bits -- it writes a value to the whole FPSCR,
5
whose upper 4 bits are zeroes.
5
6
6
Implement this by providing _round_to_nearest versions of the
7
We also incorrectly implemented the write-to-FPSCR as a simple store
7
relevant helpers which set the rounding mode temporarily when making
8
to vfp.xregs; this skips the "update the softfloat flags" part of
8
the call to the underlying softfloat function.
9
the vfp_set_fpscr helper so the value would read back correctly but
10
not actually take effect.
9
11
10
We only need to change the VFP VCVT instructions, because the
12
Fix both of these things by doing a complete write to the FPSCR
11
standard- FPSCR value used by the Neon VCVT is always set to
13
using the helper function.
12
round-to-nearest, so we don't need to do the extra work of saving
13
and restoring the rounding mode.
14
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20201013103532.13391-1-peter.maydell@linaro.org
17
Message-id: 20201210201433.26262-3-peter.maydell@linaro.org
18
---
18
---
19
target/arm/helper.h | 13 +++++++++++++
19
target/arm/translate-vfp.c.inc | 12 ++++++------
20
target/arm/vfp_helper.c | 23 ++++++++++++++++++++++-
20
1 file changed, 6 insertions(+), 6 deletions(-)
21
target/arm/translate-vfp.c.inc | 24 ++++++++++++------------
22
3 files changed, 47 insertions(+), 13 deletions(-)
23
21
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
27
+++ b/target/arm/helper.h
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_ultoh, f16, i32, i32, ptr)
29
DEF_HELPER_3(vfp_sqtoh, f16, i64, i32, ptr)
30
DEF_HELPER_3(vfp_uqtoh, f16, i64, i32, ptr)
31
32
+DEF_HELPER_3(vfp_shtos_round_to_nearest, f32, i32, i32, ptr)
33
+DEF_HELPER_3(vfp_sltos_round_to_nearest, f32, i32, i32, ptr)
34
+DEF_HELPER_3(vfp_uhtos_round_to_nearest, f32, i32, i32, ptr)
35
+DEF_HELPER_3(vfp_ultos_round_to_nearest, f32, i32, i32, ptr)
36
+DEF_HELPER_3(vfp_shtod_round_to_nearest, f64, i64, i32, ptr)
37
+DEF_HELPER_3(vfp_sltod_round_to_nearest, f64, i64, i32, ptr)
38
+DEF_HELPER_3(vfp_uhtod_round_to_nearest, f64, i64, i32, ptr)
39
+DEF_HELPER_3(vfp_ultod_round_to_nearest, f64, i64, i32, ptr)
40
+DEF_HELPER_3(vfp_shtoh_round_to_nearest, f16, i32, i32, ptr)
41
+DEF_HELPER_3(vfp_uhtoh_round_to_nearest, f16, i32, i32, ptr)
42
+DEF_HELPER_3(vfp_sltoh_round_to_nearest, f16, i32, i32, ptr)
43
+DEF_HELPER_3(vfp_ultoh_round_to_nearest, f16, i32, i32, ptr)
44
+
45
DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
46
47
DEF_HELPER_FLAGS_3(vfp_fcvt_f16_to_f32, TCG_CALL_NO_RWG, f32, f16, ptr, i32)
48
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/vfp_helper.c
51
+++ b/target/arm/vfp_helper.c
52
@@ -XXX,XX +XXX,XX @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
53
return float64_to_float32(x, &env->vfp.fp_status);
54
}
55
56
-/* VFP3 fixed point conversion. */
57
+/*
58
+ * VFP3 fixed point conversion. The AArch32 versions of fix-to-float
59
+ * must always round-to-nearest; the AArch64 ones honour the FPSCR
60
+ * rounding mode. (For AArch32 Neon the standard-FPSCR is set to
61
+ * round-to-nearest so either helper will work.) AArch32 float-to-fix
62
+ * must round-to-zero.
63
+ */
64
#define VFP_CONV_FIX_FLOAT(name, p, fsz, ftype, isz, itype) \
65
ftype HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
66
void *fpstp) \
67
{ return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); }
68
69
+#define VFP_CONV_FIX_FLOAT_ROUND(name, p, fsz, ftype, isz, itype) \
70
+ ftype HELPER(vfp_##name##to##p##_round_to_nearest)(uint##isz##_t x, \
71
+ uint32_t shift, \
72
+ void *fpstp) \
73
+ { \
74
+ ftype ret; \
75
+ float_status *fpst = fpstp; \
76
+ FloatRoundMode oldmode = fpst->float_rounding_mode; \
77
+ fpst->float_rounding_mode = float_round_nearest_even; \
78
+ ret = itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); \
79
+ fpst->float_rounding_mode = oldmode; \
80
+ return ret; \
81
+ }
82
+
83
#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, ftype, isz, itype, ROUND, suff) \
84
uint##isz##_t HELPER(vfp_to##name##p##suff)(ftype x, uint32_t shift, \
85
void *fpst) \
86
@@ -XXX,XX +XXX,XX @@ uint##isz##_t HELPER(vfp_to##name##p##suff)(ftype x, uint32_t shift, \
87
88
#define VFP_CONV_FIX(name, p, fsz, ftype, isz, itype) \
89
VFP_CONV_FIX_FLOAT(name, p, fsz, ftype, isz, itype) \
90
+VFP_CONV_FIX_FLOAT_ROUND(name, p, fsz, ftype, isz, itype) \
91
VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, ftype, isz, itype, \
92
float_round_to_zero, _round_to_zero) \
93
VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, ftype, isz, itype, \
94
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
22
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
95
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/translate-vfp.c.inc
24
--- a/target/arm/translate-vfp.c.inc
97
+++ b/target/arm/translate-vfp.c.inc
25
+++ b/target/arm/translate-vfp.c.inc
98
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
26
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
99
/* Switch on op:U:sx bits */
27
}
100
switch (a->opc) {
28
case ARM_VFP_FPCXT_S:
101
case 0:
29
{
102
- gen_helper_vfp_shtoh(vd, vd, shift, fpst);
30
- TCGv_i32 sfpa, control, fpscr;
103
+ gen_helper_vfp_shtoh_round_to_nearest(vd, vd, shift, fpst);
31
- /* Set FPSCR[27:0] and CONTROL.SFPA from value */
32
+ TCGv_i32 sfpa, control;
33
+ /*
34
+ * Set FPSCR and CONTROL.SFPA from value; the new FPSCR takes
35
+ * bits [27:0] from value and zeroes bits [31:28].
36
+ */
37
tmp = loadfn(s, opaque);
38
sfpa = tcg_temp_new_i32();
39
tcg_gen_shri_i32(sfpa, tmp, 31);
40
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
41
tcg_gen_deposit_i32(control, control, sfpa,
42
R_V7M_CONTROL_SFPA_SHIFT, 1);
43
store_cpu_field(control, v7m.control[M_REG_S]);
44
- fpscr = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
45
- tcg_gen_andi_i32(fpscr, fpscr, FPCR_NZCV_MASK);
46
tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK);
47
- tcg_gen_or_i32(fpscr, fpscr, tmp);
48
- store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]);
49
+ gen_helper_vfp_set_fpscr(cpu_env, tmp);
50
tcg_temp_free_i32(tmp);
51
tcg_temp_free_i32(sfpa);
104
break;
52
break;
105
case 1:
106
- gen_helper_vfp_sltoh(vd, vd, shift, fpst);
107
+ gen_helper_vfp_sltoh_round_to_nearest(vd, vd, shift, fpst);
108
break;
109
case 2:
110
- gen_helper_vfp_uhtoh(vd, vd, shift, fpst);
111
+ gen_helper_vfp_uhtoh_round_to_nearest(vd, vd, shift, fpst);
112
break;
113
case 3:
114
- gen_helper_vfp_ultoh(vd, vd, shift, fpst);
115
+ gen_helper_vfp_ultoh_round_to_nearest(vd, vd, shift, fpst);
116
break;
117
case 4:
118
gen_helper_vfp_toshh_round_to_zero(vd, vd, shift, fpst);
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
120
/* Switch on op:U:sx bits */
121
switch (a->opc) {
122
case 0:
123
- gen_helper_vfp_shtos(vd, vd, shift, fpst);
124
+ gen_helper_vfp_shtos_round_to_nearest(vd, vd, shift, fpst);
125
break;
126
case 1:
127
- gen_helper_vfp_sltos(vd, vd, shift, fpst);
128
+ gen_helper_vfp_sltos_round_to_nearest(vd, vd, shift, fpst);
129
break;
130
case 2:
131
- gen_helper_vfp_uhtos(vd, vd, shift, fpst);
132
+ gen_helper_vfp_uhtos_round_to_nearest(vd, vd, shift, fpst);
133
break;
134
case 3:
135
- gen_helper_vfp_ultos(vd, vd, shift, fpst);
136
+ gen_helper_vfp_ultos_round_to_nearest(vd, vd, shift, fpst);
137
break;
138
case 4:
139
gen_helper_vfp_toshs_round_to_zero(vd, vd, shift, fpst);
140
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
141
/* Switch on op:U:sx bits */
142
switch (a->opc) {
143
case 0:
144
- gen_helper_vfp_shtod(vd, vd, shift, fpst);
145
+ gen_helper_vfp_shtod_round_to_nearest(vd, vd, shift, fpst);
146
break;
147
case 1:
148
- gen_helper_vfp_sltod(vd, vd, shift, fpst);
149
+ gen_helper_vfp_sltod_round_to_nearest(vd, vd, shift, fpst);
150
break;
151
case 2:
152
- gen_helper_vfp_uhtod(vd, vd, shift, fpst);
153
+ gen_helper_vfp_uhtod_round_to_nearest(vd, vd, shift, fpst);
154
break;
155
case 3:
156
- gen_helper_vfp_ultod(vd, vd, shift, fpst);
157
+ gen_helper_vfp_ultod_round_to_nearest(vd, vd, shift, fpst);
158
break;
159
case 4:
160
gen_helper_vfp_toshd_round_to_zero(vd, vd, shift, fpst);
161
--
53
--
162
2.20.1
54
2.20.1
163
55
164
56
diff view generated by jsdifflib
1
From v8.1M, disabled-coprocessor handling changes slightly:
1
Implement the v8.1M FPCXT_NS floating-point system register. This is
2
* coprocessors 8, 9, 14 and 15 are also governed by the
2
a little more complicated than FPCXT_S, because it has specific
3
cp10 enable bit, like cp11
3
handling for "current FP state is inactive", and it only wants to do
4
* an extra range of instruction patterns is considered
4
PreserveFPState(), not the full set of actions done by
5
to be inside the coprocessor space
5
ExecuteFPCheck() which vfp_access_check() implements.
6
7
We previously marked these up with TODO comments; implement the
8
correct behaviour.
9
10
Unfortunately there is no ID register field which indicates this
11
behaviour. We could in theory test an unrelated ID register which
12
indicates guaranteed-to-be-in-v8.1M behaviour like ID_ISAR0.CmpBranch
13
>= 3 (low-overhead-loops), but it seems better to simply define a new
14
ARM_FEATURE_V8_1M feature flag and use it for this and other
15
new-in-v8.1M behaviour that isn't identifiable from the ID registers.
16
6
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20201019151301.2046-3-peter.maydell@linaro.org
9
Message-id: 20201210201433.26262-4-peter.maydell@linaro.org
20
---
10
---
21
target/arm/cpu.h | 1 +
11
target/arm/translate-vfp.c.inc | 102 ++++++++++++++++++++++++++++++++-
22
target/arm/m-nocp.decode | 10 ++++++----
12
1 file changed, 99 insertions(+), 3 deletions(-)
23
target/arm/translate-vfp.c.inc | 17 +++++++++++++++--
24
3 files changed, 22 insertions(+), 6 deletions(-)
25
13
26
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu.h
29
+++ b/target/arm/cpu.h
30
@@ -XXX,XX +XXX,XX @@ enum arm_features {
31
ARM_FEATURE_VBAR, /* has cp15 VBAR */
32
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
33
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
34
+ ARM_FEATURE_V8_1M, /* M profile extras only in v8.1M and later */
35
};
36
37
static inline int arm_feature(CPUARMState *env, int feature)
38
diff --git a/target/arm/m-nocp.decode b/target/arm/m-nocp.decode
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/m-nocp.decode
41
+++ b/target/arm/m-nocp.decode
42
@@ -XXX,XX +XXX,XX @@
43
# If the coprocessor is not present or disabled then we will generate
44
# the NOCP exception; otherwise we let the insn through to the main decode.
45
46
+&nocp cp
47
+
48
{
49
# Special cases which do not take an early NOCP: VLLDM and VLSTM
50
VLLDM_VLSTM 1110 1100 001 l:1 rn:4 0000 1010 0000 0000
51
# TODO: VSCCLRM (new in v8.1M) is similar:
52
#VSCCLRM 1110 1100 1-01 1111 ---- 1011 ---- ---0
53
54
- NOCP 111- 1110 ---- ---- ---- cp:4 ---- ----
55
- NOCP 111- 110- ---- ---- ---- cp:4 ---- ----
56
- # TODO: From v8.1M onwards we will also want this range to NOCP
57
- #NOCP_8_1 111- 1111 ---- ---- ---- ---- ---- ---- cp=10
58
+ NOCP 111- 1110 ---- ---- ---- cp:4 ---- ---- &nocp
59
+ NOCP 111- 110- ---- ---- ---- cp:4 ---- ---- &nocp
60
+ # From v8.1M onwards this range will also NOCP:
61
+ NOCP_8_1 111- 1111 ---- ---- ---- ---- ---- ---- &nocp cp=10
62
}
63
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
14
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
64
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate-vfp.c.inc
16
--- a/target/arm/translate-vfp.c.inc
66
+++ b/target/arm/translate-vfp.c.inc
17
+++ b/target/arm/translate-vfp.c.inc
67
@@ -XXX,XX +XXX,XX @@ static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
18
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
19
}
20
break;
21
case ARM_VFP_FPCXT_S:
22
+ case ARM_VFP_FPCXT_NS:
23
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
24
return false;
25
}
26
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
27
return FPSysRegCheckFailed;
28
}
29
30
- if (!vfp_access_check(s)) {
31
+ /*
32
+ * FPCXT_NS is a special case: it has specific handling for
33
+ * "current FP state is inactive", and must do the PreserveFPState()
34
+ * but not the usual full set of actions done by ExecuteFPCheck().
35
+ * So we don't call vfp_access_check() and the callers must handle this.
36
+ */
37
+ if (regno != ARM_VFP_FPCXT_NS && !vfp_access_check(s)) {
38
return FPSysRegCheckDone;
39
}
40
-
41
return FPSysRegCheckContinue;
42
}
43
44
+static void gen_branch_fpInactive(DisasContext *s, TCGCond cond,
45
+ TCGLabel *label)
46
+{
47
+ /*
48
+ * FPCXT_NS is a special case: it has specific handling for
49
+ * "current FP state is inactive", and must do the PreserveFPState()
50
+ * but not the usual full set of actions done by ExecuteFPCheck().
51
+ * We don't have a TB flag that matches the fpInactive check, so we
52
+ * do it at runtime as we don't expect FPCXT_NS accesses to be frequent.
53
+ *
54
+ * Emit code that checks fpInactive and does a conditional
55
+ * branch to label based on it:
56
+ * if cond is TCG_COND_NE then branch if fpInactive != 0 (ie if inactive)
57
+ * if cond is TCG_COND_EQ then branch if fpInactive == 0 (ie if active)
58
+ */
59
+ assert(cond == TCG_COND_EQ || cond == TCG_COND_NE);
60
+
61
+ /* fpInactive = FPCCR_NS.ASPEN == 1 && CONTROL.FPCA == 0 */
62
+ TCGv_i32 aspen, fpca;
63
+ aspen = load_cpu_field(v7m.fpccr[M_REG_NS]);
64
+ fpca = load_cpu_field(v7m.control[M_REG_S]);
65
+ tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
66
+ tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
67
+ tcg_gen_andi_i32(fpca, fpca, R_V7M_CONTROL_FPCA_MASK);
68
+ tcg_gen_or_i32(fpca, fpca, aspen);
69
+ tcg_gen_brcondi_i32(tcg_invert_cond(cond), fpca, 0, label);
70
+ tcg_temp_free_i32(aspen);
71
+ tcg_temp_free_i32(fpca);
72
+}
73
+
74
static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
75
76
fp_sysreg_loadfn *loadfn,
77
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
78
{
79
/* Do a write to an M-profile floating point system register */
80
TCGv_i32 tmp;
81
+ TCGLabel *lab_end = NULL;
82
83
switch (fp_sysreg_checks(s, regno)) {
84
case FPSysRegCheckFailed:
85
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
86
tcg_temp_free_i32(tmp);
87
break;
88
}
89
+ case ARM_VFP_FPCXT_NS:
90
+ lab_end = gen_new_label();
91
+ /* fpInactive case: write is a NOP, so branch to end */
92
+ gen_branch_fpInactive(s, TCG_COND_NE, lab_end);
93
+ /* !fpInactive: PreserveFPState(), and reads same as FPCXT_S */
94
+ gen_preserve_fp_state(s);
95
+ /* fall through */
96
case ARM_VFP_FPCXT_S:
97
{
98
TCGv_i32 sfpa, control;
99
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
100
default:
101
g_assert_not_reached();
102
}
103
+ if (lab_end) {
104
+ gen_set_label(lab_end);
105
+ }
68
return true;
106
return true;
69
}
107
}
70
108
71
-static bool trans_NOCP(DisasContext *s, arg_NOCP *a)
109
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
72
+static bool trans_NOCP(DisasContext *s, arg_nocp *a)
73
{
110
{
74
/*
111
/* Do a read from an M-profile floating point system register */
75
* Handle M-profile early check for disabled coprocessor:
112
TCGv_i32 tmp;
76
@@ -XXX,XX +XXX,XX @@ static bool trans_NOCP(DisasContext *s, arg_NOCP *a)
113
+ TCGLabel *lab_end = NULL;
77
if (a->cp == 11) {
114
+ bool lookup_tb = false;
78
a->cp = 10;
115
116
switch (fp_sysreg_checks(s, regno)) {
117
case FPSysRegCheckFailed:
118
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
119
fpscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
120
gen_helper_vfp_set_fpscr(cpu_env, fpscr);
121
tcg_temp_free_i32(fpscr);
122
- gen_lookup_tb(s);
123
+ lookup_tb = true;
124
+ break;
125
+ }
126
+ case ARM_VFP_FPCXT_NS:
127
+ {
128
+ TCGv_i32 control, sfpa, fpscr, fpdscr, zero;
129
+ TCGLabel *lab_active = gen_new_label();
130
+
131
+ lookup_tb = true;
132
+
133
+ gen_branch_fpInactive(s, TCG_COND_EQ, lab_active);
134
+ /* fpInactive case: reads as FPDSCR_NS */
135
+ TCGv_i32 tmp = load_cpu_field(v7m.fpdscr[M_REG_NS]);
136
+ storefn(s, opaque, tmp);
137
+ lab_end = gen_new_label();
138
+ tcg_gen_br(lab_end);
139
+
140
+ gen_set_label(lab_active);
141
+ /* !fpInactive: Reads the same as FPCXT_S, but side effects differ */
142
+ gen_preserve_fp_state(s);
143
+ tmp = tcg_temp_new_i32();
144
+ sfpa = tcg_temp_new_i32();
145
+ fpscr = tcg_temp_new_i32();
146
+ gen_helper_vfp_get_fpscr(fpscr, cpu_env);
147
+ tcg_gen_andi_i32(tmp, fpscr, ~FPCR_NZCV_MASK);
148
+ control = load_cpu_field(v7m.control[M_REG_S]);
149
+ tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK);
150
+ tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT);
151
+ tcg_gen_or_i32(tmp, tmp, sfpa);
152
+ tcg_temp_free_i32(control);
153
+ /* Store result before updating FPSCR, in case it faults */
154
+ storefn(s, opaque, tmp);
155
+ /* If SFPA is zero then set FPSCR from FPDSCR_NS */
156
+ fpdscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
157
+ zero = tcg_const_i32(0);
158
+ tcg_gen_movcond_i32(TCG_COND_EQ, fpscr, sfpa, zero, fpdscr, fpscr);
159
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
160
+ tcg_temp_free_i32(zero);
161
+ tcg_temp_free_i32(sfpa);
162
+ tcg_temp_free_i32(fpdscr);
163
+ tcg_temp_free_i32(fpscr);
164
break;
79
}
165
}
80
- /* TODO: in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
166
default:
81
+ if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
167
g_assert_not_reached();
82
+ (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
168
}
83
+ /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
169
+
84
+ a->cp = 10;
170
+ if (lab_end) {
171
+ gen_set_label(lab_end);
85
+ }
172
+ }
86
173
+ if (lookup_tb) {
87
if (a->cp != 10) {
174
+ gen_lookup_tb(s);
88
gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
175
+ }
89
@@ -XXX,XX +XXX,XX @@ static bool trans_NOCP(DisasContext *s, arg_NOCP *a)
176
return true;
90
return false;
91
}
177
}
92
178
93
+static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
94
+{
95
+ /* This range needs a coprocessor check for v8.1M and later only */
96
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
97
+ return false;
98
+ }
99
+ return trans_NOCP(s, a);
100
+}
101
+
102
static bool trans_VINS(DisasContext *s, arg_VINS *a)
103
{
104
TCGv_i32 rd, rm;
105
--
179
--
106
2.20.1
180
2.20.1
107
181
108
182
diff view generated by jsdifflib
1
v8.1M's "low-overhead-loop" extension has three instructions
1
Now that we have implemented all the features needed by the v8.1M
2
for looping:
2
architecture, we can add the model of the Cortex-M55. This is the
3
* DLS (start of a do-loop)
3
configuration without MVE support; we'll add MVE later.
4
* WLS (start of a while-loop)
5
* LE (end of a loop)
6
7
The loop-start instructions are both simple operations to start a
8
loop whose iteration count (if any) is in LR. The loop-end
9
instruction handles "decrement iteration count and jump back to loop
10
start"; it also caches the information about the branch back to the
11
start of the loop to improve performance of the branch on subsequent
12
iterations.
13
14
As with the branch-future instructions, the architecture permits an
15
implementation to discard the LO_BRANCH_INFO cache at any time, and
16
QEMU takes the IMPDEF option to never set it in the first place
17
(equivalent to discarding it immediately), because for us a "real"
18
implementation would be unnecessary complexity.
19
20
(This implementation only provides the simple looping constructs; the
21
vector extension MVE (Helium) adds some extra variants to handle
22
looping across vectors. We'll add those later when we implement
23
MVE.)
24
4
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20201019151301.2046-8-peter.maydell@linaro.org
7
Message-id: 20201210201433.26262-5-peter.maydell@linaro.org
28
---
8
---
29
target/arm/t32.decode | 8 ++++
9
target/arm/cpu_tcg.c | 42 ++++++++++++++++++++++++++++++++++++++++++
30
target/arm/translate.c | 93 +++++++++++++++++++++++++++++++++++++++++-
10
1 file changed, 42 insertions(+)
31
2 files changed, 99 insertions(+), 2 deletions(-)
32
11
33
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
12
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
34
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/t32.decode
14
--- a/target/arm/cpu_tcg.c
36
+++ b/target/arm/t32.decode
15
+++ b/target/arm/cpu_tcg.c
37
@@ -XXX,XX +XXX,XX @@ BL 1111 0. .......... 11.1 ............ @branch24
16
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
38
BF 1111 0 boff:4 10 ----- 1110 - ---------- 1 # BF
17
cpu->ctr = 0x8000c000;
39
BF 1111 0 boff:4 11 ----- 1110 0 0000000000 1 # BFX, BFLX
18
}
40
]
19
41
+ [
20
+static void cortex_m55_initfn(Object *obj)
42
+ # LE and WLS immediate
21
+{
43
+ %lob_imm 1:10 11:1 !function=times_2
22
+ ARMCPU *cpu = ARM_CPU(obj);
44
+
23
+
45
+ DLS 1111 0 0000 100 rn:4 1110 0000 0000 0001
24
+ set_feature(&cpu->env, ARM_FEATURE_V8);
46
+ WLS 1111 0 0000 100 rn:4 1100 . .......... 1 imm=%lob_imm
25
+ set_feature(&cpu->env, ARM_FEATURE_V8_1M);
47
+ LE 1111 0 0000 0 f:1 0 1111 1100 . .......... 1 imm=%lob_imm
26
+ set_feature(&cpu->env, ARM_FEATURE_M);
48
+ ]
27
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
49
}
28
+ set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
50
diff --git a/target/arm/translate.c b/target/arm/translate.c
29
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
51
index XXXXXXX..XXXXXXX 100644
30
+ cpu->midr = 0x410fd221; /* r0p1 */
52
--- a/target/arm/translate.c
31
+ cpu->revidr = 0;
53
+++ b/target/arm/translate.c
32
+ cpu->pmsav7_dregion = 16;
54
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
33
+ cpu->sau_sregion = 8;
55
s->base.is_jmp = DISAS_NORETURN;
34
+ /*
56
}
35
+ * These are the MVFR* values for the FPU, no MVE configuration;
57
36
+ * we will update them later when we implement MVE
58
-static inline void gen_jmp (DisasContext *s, uint32_t dest)
37
+ */
59
+/* Jump, specifying which TB number to use if we gen_goto_tb() */
38
+ cpu->isar.mvfr0 = 0x10110221;
60
+static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
39
+ cpu->isar.mvfr1 = 0x12100011;
61
{
40
+ cpu->isar.mvfr2 = 0x00000040;
62
if (unlikely(is_singlestepping(s))) {
41
+ cpu->isar.id_pfr0 = 0x20000030;
63
/* An indirect jump so that we still trigger the debug exception. */
42
+ cpu->isar.id_pfr1 = 0x00000230;
64
gen_set_pc_im(s, dest);
43
+ cpu->isar.id_dfr0 = 0x10200000;
65
s->base.is_jmp = DISAS_JUMP;
44
+ cpu->id_afr0 = 0x00000000;
66
} else {
45
+ cpu->isar.id_mmfr0 = 0x00111040;
67
- gen_goto_tb(s, 0, dest);
46
+ cpu->isar.id_mmfr1 = 0x00000000;
68
+ gen_goto_tb(s, tbno, dest);
47
+ cpu->isar.id_mmfr2 = 0x01000000;
69
}
48
+ cpu->isar.id_mmfr3 = 0x00000011;
70
}
49
+ cpu->isar.id_isar0 = 0x01103110;
71
50
+ cpu->isar.id_isar1 = 0x02212000;
72
+static inline void gen_jmp(DisasContext *s, uint32_t dest)
51
+ cpu->isar.id_isar2 = 0x20232232;
73
+{
52
+ cpu->isar.id_isar3 = 0x01111131;
74
+ gen_jmp_tb(s, dest, 0);
53
+ cpu->isar.id_isar4 = 0x01310132;
54
+ cpu->isar.id_isar5 = 0x00000000;
55
+ cpu->isar.id_isar6 = 0x00000000;
56
+ cpu->clidr = 0x00000000; /* caches not implemented */
57
+ cpu->ctr = 0x8303c003;
75
+}
58
+}
76
+
59
+
77
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
60
static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
78
{
61
/* Dummy the TCM region regs for the moment */
79
if (x)
62
{ .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
80
@@ -XXX,XX +XXX,XX @@ static bool trans_BF(DisasContext *s, arg_BF *a)
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
81
return true;
64
.class_init = arm_v7m_class_init },
82
}
65
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
83
66
.class_init = arm_v7m_class_init },
84
+static bool trans_DLS(DisasContext *s, arg_DLS *a)
67
+ { .name = "cortex-m55", .initfn = cortex_m55_initfn,
85
+{
68
+ .class_init = arm_v7m_class_init },
86
+ /* M-profile low-overhead loop start */
69
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
87
+ TCGv_i32 tmp;
70
{ .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
88
+
71
{ .name = "ti925t", .initfn = ti925t_initfn },
89
+ if (!dc_isar_feature(aa32_lob, s)) {
90
+ return false;
91
+ }
92
+ if (a->rn == 13 || a->rn == 15) {
93
+ /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
94
+ return false;
95
+ }
96
+
97
+ /* Not a while loop, no tail predication: just set LR to the count */
98
+ tmp = load_reg(s, a->rn);
99
+ store_reg(s, 14, tmp);
100
+ return true;
101
+}
102
+
103
+static bool trans_WLS(DisasContext *s, arg_WLS *a)
104
+{
105
+ /* M-profile low-overhead while-loop start */
106
+ TCGv_i32 tmp;
107
+ TCGLabel *nextlabel;
108
+
109
+ if (!dc_isar_feature(aa32_lob, s)) {
110
+ return false;
111
+ }
112
+ if (a->rn == 13 || a->rn == 15) {
113
+ /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
114
+ return false;
115
+ }
116
+ if (s->condexec_mask) {
117
+ /*
118
+ * WLS in an IT block is CONSTRAINED UNPREDICTABLE;
119
+ * we choose to UNDEF, because otherwise our use of
120
+ * gen_goto_tb(1) would clash with the use of TB exit 1
121
+ * in the dc->condjmp condition-failed codepath in
122
+ * arm_tr_tb_stop() and we'd get an assertion.
123
+ */
124
+ return false;
125
+ }
126
+ nextlabel = gen_new_label();
127
+ tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel);
128
+ tmp = load_reg(s, a->rn);
129
+ store_reg(s, 14, tmp);
130
+ gen_jmp_tb(s, s->base.pc_next, 1);
131
+
132
+ gen_set_label(nextlabel);
133
+ gen_jmp(s, read_pc(s) + a->imm);
134
+ return true;
135
+}
136
+
137
+static bool trans_LE(DisasContext *s, arg_LE *a)
138
+{
139
+ /*
140
+ * M-profile low-overhead loop end. The architecture permits an
141
+ * implementation to discard the LO_BRANCH_INFO cache at any time,
142
+ * and we take the IMPDEF option to never set it in the first place
143
+ * (equivalent to always discarding it immediately), because for QEMU
144
+ * a "real" implementation would be complicated and wouldn't execute
145
+ * any faster.
146
+ */
147
+ TCGv_i32 tmp;
148
+
149
+ if (!dc_isar_feature(aa32_lob, s)) {
150
+ return false;
151
+ }
152
+
153
+ if (!a->f) {
154
+ /* Not loop-forever. If LR <= 1 this is the last loop: do nothing. */
155
+ arm_gen_condlabel(s);
156
+ tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, s->condlabel);
157
+ /* Decrement LR */
158
+ tmp = load_reg(s, 14);
159
+ tcg_gen_addi_i32(tmp, tmp, -1);
160
+ store_reg(s, 14, tmp);
161
+ }
162
+ /* Jump back to the loop start */
163
+ gen_jmp(s, read_pc(s) - a->imm);
164
+ return true;
165
+}
166
+
167
static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
168
{
169
TCGv_i32 addr, tmp;
170
--
72
--
171
2.20.1
73
2.20.1
172
74
173
75
diff view generated by jsdifflib
1
M-profile CPUs with half-precision floating point support should
1
Support for running KVM on 32-bit Arm hosts was removed in commit
2
be able to write to FPSCR.FZ16, but an M-profile specific masking
2
82bf7ae84ce739e. You can still run a 32-bit guest on a 64-bit Arm
3
of the value at the top of vfp_set_fpscr() currently prevents that.
3
host CPU, but because Arm KVM requires the host and guest CPU types
4
This is not yet an active bug because we have no M-profile
4
to match, it is not possible to run a guest that requires a Cortex-A9
5
FP16 CPUs, but needs to be fixed before we can add any.
5
or Cortex-A15 CPU there. That means that the code in the
6
6
highbank/midway board models to support KVM is no longer used, and we
7
The bits that the masking is effectively preventing from being
7
can delete it.
8
set are the A-profile only short-vector Len and Stride fields,
9
plus the Neon QC bit. Rearrange the order of the function so
10
that those fields are handled earlier and only under a suitable
11
guard; this allows us to drop the M-profile specific masking,
12
making FZ16 writeable.
13
14
This change also makes the QC bit correctly RAZ/WI for older
15
no-Neon A-profile cores.
16
17
This refactoring also paves the way for the low-overhead-branch
18
LTPSIZE field, which uses some of the bits that are used for
19
A-profile Stride and Len.
20
8
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20201019151301.2046-10-peter.maydell@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20201215144215.28482-1-peter.maydell@linaro.org
24
---
13
---
25
target/arm/vfp_helper.c | 47 ++++++++++++++++++++++++-----------------
14
hw/arm/highbank.c | 14 ++++----------
26
1 file changed, 28 insertions(+), 19 deletions(-)
15
1 file changed, 4 insertions(+), 10 deletions(-)
27
16
28
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
17
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
29
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/vfp_helper.c
19
--- a/hw/arm/highbank.c
31
+++ b/target/arm/vfp_helper.c
20
+++ b/hw/arm/highbank.c
32
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
21
@@ -XXX,XX +XXX,XX @@
33
val &= ~FPCR_FZ16;
22
#include "hw/arm/boot.h"
34
}
23
#include "hw/loader.h"
35
24
#include "net/net.h"
36
- if (arm_feature(env, ARM_FEATURE_M)) {
25
-#include "sysemu/kvm.h"
37
+ vfp_set_fpscr_to_host(env, val);
26
#include "sysemu/runstate.h"
38
+
27
#include "sysemu/sysemu.h"
39
+ if (!arm_feature(env, ARM_FEATURE_M)) {
28
#include "hw/boards.h"
40
/*
29
@@ -XXX,XX +XXX,XX @@
41
- * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
30
#include "hw/cpu/a15mpcore.h"
42
- * and also for the trapped-exception-handling bits IxE.
31
#include "qemu/log.h"
43
+ * Short-vector length and stride; on M-profile these bits
32
#include "qom/object.h"
44
+ * are used for different purposes.
33
+#include "cpu.h"
45
+ * We can't make this conditional be "if MVFR0.FPShVec != 0",
34
46
+ * because in v7A no-short-vector-support cores still had to
35
#define SMP_BOOT_ADDR 0x100
47
+ * allow Stride/Len to be written with the only effect that
36
#define SMP_BOOT_REG 0x40
48
+ * some insns are required to UNDEF if the guest sets them.
37
@@ -XXX,XX +XXX,XX @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
49
+ *
38
highbank_binfo.loader_start = 0;
50
+ * TODO: if M-profile MVE implemented, set LTPSIZE.
39
highbank_binfo.write_secondary_boot = hb_write_secondary;
51
*/
40
highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary;
52
- val &= 0xf7c0009f;
41
- if (!kvm_enabled()) {
53
+ env->vfp.vec_len = extract32(val, 16, 3);
42
- highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR;
54
+ env->vfp.vec_stride = extract32(val, 20, 2);
43
- highbank_binfo.write_board_setup = hb_write_board_setup;
55
}
44
- highbank_binfo.secure_board_setup = true;
56
45
- } else {
57
- vfp_set_fpscr_to_host(env, val);
46
- warn_report("cannot load built-in Monitor support "
58
+ if (arm_feature(env, ARM_FEATURE_NEON)) {
47
- "if KVM is enabled. Some guests (such as Linux) "
59
+ /*
48
- "may not boot.");
60
+ * The bit we set within fpscr_q is arbitrary; the register as a
49
- }
61
+ * whole being zero/non-zero is what counts.
50
+ highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR;
62
+ * TODO: M-profile MVE also has a QC bit.
51
+ highbank_binfo.write_board_setup = hb_write_board_setup;
63
+ */
52
+ highbank_binfo.secure_board_setup = true;
64
+ env->vfp.qc[0] = val & FPCR_QC;
53
65
+ env->vfp.qc[1] = 0;
54
arm_load_kernel(ARM_CPU(first_cpu), machine, &highbank_binfo);
66
+ env->vfp.qc[2] = 0;
67
+ env->vfp.qc[3] = 0;
68
+ }
69
70
/*
71
* We don't implement trapped exception handling, so the
72
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
73
*
74
- * If we exclude the exception flags, IOC|DZC|OFC|UFC|IXC|IDC
75
- * (which are stored in fp_status), and the other RES0 bits
76
- * in between, then we clear all of the low 16 bits.
77
+ * The exception flags IOC|DZC|OFC|UFC|IXC|IDC are stored in
78
+ * fp_status; QC, Len and Stride are stored separately earlier.
79
+ * Clear out all of those and the RES0 bits: only NZCV, AHP, DN,
80
+ * FZ, RMode and FZ16 are kept in vfp.xregs[FPSCR].
81
*/
82
env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c80000;
83
- env->vfp.vec_len = (val >> 16) & 7;
84
- env->vfp.vec_stride = (val >> 20) & 3;
85
-
86
- /*
87
- * The bit we set within fpscr_q is arbitrary; the register as a
88
- * whole being zero/non-zero is what counts.
89
- */
90
- env->vfp.qc[0] = val & FPCR_QC;
91
- env->vfp.qc[1] = 0;
92
- env->vfp.qc[2] = 0;
93
- env->vfp.qc[3] = 0;
94
}
55
}
95
96
void vfp_set_fpscr(CPUARMState *env, uint32_t val)
97
--
56
--
98
2.20.1
57
2.20.1
99
58
100
59
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Currently timer_free() is a simple wrapper for g_free(). This means
2
that the timer being freed must not be currently active, as otherwise
3
QEMU might crash later when the active list is processed and still
4
has a pointer to freed memory on it. As a result almost all calls to
5
timer_free() are preceded by a timer_del() call, as can be seen in
6
the output of
7
git grep -B1 '\<timer_free\>'
2
8
3
This peripheral has 1 free-running timer and 4 compare registers.
9
This is unfortunate API design as it makes it easy to accidentally
10
misuse (by forgetting the timer_del()), and the correct use is
11
annoyingly verbose.
4
12
5
Only the free-running timer is implemented. Add support the
13
Make timer_free() imply a timer_del().
6
COMPARE registers (each register is wired to an IRQ).
7
14
8
Reference: "BCM2835 ARM Peripherals" datasheet [*]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
chapter 12 "System Timer":
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20201215154107.3255-2-peter.maydell@linaro.org
19
---
20
include/qemu/timer.h | 24 +++++++++++++-----------
21
1 file changed, 13 insertions(+), 11 deletions(-)
10
22
11
The System Timer peripheral provides four 32-bit timer channels
23
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
12
and a single 64-bit free running counter. Each channel has an
13
output compare register, which is compared against the 32 least
14
significant bits of the free running counter values. When the
15
two values match, the system timer peripheral generates a signal
16
to indicate a match for the appropriate channel. The match signal
17
is then fed into the interrupt controller.
18
19
This peripheral is used since Linux 3.7, commit ee4af5696720
20
("ARM: bcm2835: add system timer").
21
22
[*] https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
23
24
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Reviewed-by: Luc Michel <luc@lmichel.fr>
26
Message-id: 20201010203709.3116542-4-f4bug@amsat.org
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
---
29
include/hw/timer/bcm2835_systmr.h | 11 +++++--
30
hw/timer/bcm2835_systmr.c | 48 ++++++++++++++++++++-----------
31
hw/timer/trace-events | 6 ++--
32
3 files changed, 44 insertions(+), 21 deletions(-)
33
34
diff --git a/include/hw/timer/bcm2835_systmr.h b/include/hw/timer/bcm2835_systmr.h
35
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/timer/bcm2835_systmr.h
25
--- a/include/qemu/timer.h
37
+++ b/include/hw/timer/bcm2835_systmr.h
26
+++ b/include/qemu/timer.h
38
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb,
39
28
*/
40
#include "hw/sysbus.h"
29
void timer_deinit(QEMUTimer *ts);
41
#include "hw/irq.h"
30
42
+#include "qemu/timer.h"
31
-/**
43
#include "qom/object.h"
32
- * timer_free:
44
33
- * @ts: the timer
45
#define TYPE_BCM2835_SYSTIMER "bcm2835-sys-timer"
34
- *
46
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(BCM2835SystemTimerState, BCM2835_SYSTIMER)
35
- * Free a timer (it must not be on the active list)
47
36
- */
48
#define BCM2835_SYSTIMER_COUNT 4
37
-static inline void timer_free(QEMUTimer *ts)
49
38
-{
50
+typedef struct {
39
- g_free(ts);
51
+ unsigned id;
52
+ QEMUTimer timer;
53
+ qemu_irq irq;
54
+ BCM2835SystemTimerState *state;
55
+} BCM2835SystemTimerCompare;
56
+
57
struct BCM2835SystemTimerState {
58
/*< private >*/
59
SysBusDevice parent_obj;
60
61
/*< public >*/
62
MemoryRegion iomem;
63
- qemu_irq irq;
64
-
65
struct {
66
uint32_t ctrl_status;
67
uint32_t compare[BCM2835_SYSTIMER_COUNT];
68
} reg;
69
+ BCM2835SystemTimerCompare tmr[BCM2835_SYSTIMER_COUNT];
70
};
71
72
#endif
73
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/timer/bcm2835_systmr.c
76
+++ b/hw/timer/bcm2835_systmr.c
77
@@ -XXX,XX +XXX,XX @@ REG32(COMPARE1, 0x10)
78
REG32(COMPARE2, 0x14)
79
REG32(COMPARE3, 0x18)
80
81
-static void bcm2835_systmr_update_irq(BCM2835SystemTimerState *s)
82
+static void bcm2835_systmr_timer_expire(void *opaque)
83
{
84
- bool enable = !!s->reg.ctrl_status;
85
+ BCM2835SystemTimerCompare *tmr = opaque;
86
87
- trace_bcm2835_systmr_irq(enable);
88
- qemu_set_irq(s->irq, enable);
89
-}
40
-}
90
-
41
-
91
-static void bcm2835_systmr_update_compare(BCM2835SystemTimerState *s,
42
/**
92
- unsigned timer_index)
43
* timer_del:
93
-{
44
* @ts: the timer
94
- /* TODO fow now, since neither Linux nor U-boot use these timers. */
45
@@ -XXX,XX +XXX,XX @@ static inline void timer_free(QEMUTimer *ts)
95
- qemu_log_mask(LOG_UNIMP, "COMPARE register %u not implemented\n",
46
*/
96
- timer_index);
47
void timer_del(QEMUTimer *ts);
97
+ trace_bcm2835_systmr_timer_expired(tmr->id);
48
98
+ tmr->state->reg.ctrl_status |= 1 << tmr->id;
49
+/**
99
+ qemu_set_irq(tmr->irq, 1);
50
+ * timer_free:
100
}
51
+ * @ts: the timer
101
52
+ *
102
static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
53
+ * Free a timer. This will call timer_del() for you to remove
103
@@ -XXX,XX +XXX,XX @@ static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
54
+ * the timer from the active list if it was still active.
104
}
55
+ */
105
56
+static inline void timer_free(QEMUTimer *ts)
106
static void bcm2835_systmr_write(void *opaque, hwaddr offset,
57
+{
107
- uint64_t value, unsigned size)
58
+ timer_del(ts);
108
+ uint64_t value64, unsigned size)
59
+ g_free(ts);
109
{
60
+}
110
BCM2835SystemTimerState *s = BCM2835_SYSTIMER(opaque);
111
+ int index;
112
+ uint32_t value = value64;
113
+ uint32_t triggers_delay_us;
114
+ uint64_t now;
115
116
trace_bcm2835_systmr_write(offset, value);
117
switch (offset) {
118
case A_CTRL_STATUS:
119
s->reg.ctrl_status &= ~value; /* Ack */
120
- bcm2835_systmr_update_irq(s);
121
+ for (index = 0; index < ARRAY_SIZE(s->tmr); index++) {
122
+ if (extract32(value, index, 1)) {
123
+ trace_bcm2835_systmr_irq_ack(index);
124
+ qemu_set_irq(s->tmr[index].irq, 0);
125
+ }
126
+ }
127
break;
128
case A_COMPARE0 ... A_COMPARE3:
129
- s->reg.compare[(offset - A_COMPARE0) >> 2] = value;
130
- bcm2835_systmr_update_compare(s, (offset - A_COMPARE0) >> 2);
131
+ index = (offset - A_COMPARE0) >> 2;
132
+ s->reg.compare[index] = value;
133
+ now = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
134
+ /* Compare lower 32-bits of the free-running counter. */
135
+ triggers_delay_us = value - now;
136
+ trace_bcm2835_systmr_run(index, triggers_delay_us);
137
+ timer_mod(&s->tmr[index].timer, now + triggers_delay_us);
138
break;
139
case A_COUNTER_LOW:
140
case A_COUNTER_HIGH:
141
@@ -XXX,XX +XXX,XX @@ static void bcm2835_systmr_realize(DeviceState *dev, Error **errp)
142
memory_region_init_io(&s->iomem, OBJECT(dev), &bcm2835_systmr_ops,
143
s, "bcm2835-sys-timer", 0x20);
144
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
145
- sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
146
+
61
+
147
+ for (size_t i = 0; i < ARRAY_SIZE(s->tmr); i++) {
62
/**
148
+ s->tmr[i].id = i;
63
* timer_mod_ns:
149
+ s->tmr[i].state = s;
64
* @ts: the timer
150
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->tmr[i].irq);
151
+ timer_init_us(&s->tmr[i].timer, QEMU_CLOCK_VIRTUAL,
152
+ bcm2835_systmr_timer_expire, &s->tmr[i]);
153
+ }
154
}
155
156
static const VMStateDescription bcm2835_systmr_vmstate = {
157
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
158
index XXXXXXX..XXXXXXX 100644
159
--- a/hw/timer/trace-events
160
+++ b/hw/timer/trace-events
161
@@ -XXX,XX +XXX,XX @@ nrf51_timer_write(uint8_t timer_id, uint64_t addr, uint32_t value, unsigned size
162
nrf51_timer_set_count(uint8_t timer_id, uint8_t counter_id, uint32_t value) "timer %u counter %u count 0x%" PRIx32
163
164
# bcm2835_systmr.c
165
-bcm2835_systmr_irq(bool enable) "timer irq state %u"
166
+bcm2835_systmr_timer_expired(unsigned id) "timer #%u expired"
167
+bcm2835_systmr_irq_ack(unsigned id) "timer #%u acked"
168
bcm2835_systmr_read(uint64_t offset, uint64_t data) "timer read: offset 0x%" PRIx64 " data 0x%" PRIx64
169
-bcm2835_systmr_write(uint64_t offset, uint64_t data) "timer write: offset 0x%" PRIx64 " data 0x%" PRIx64
170
+bcm2835_systmr_write(uint64_t offset, uint32_t data) "timer write: offset 0x%" PRIx64 " data 0x%" PRIx32
171
+bcm2835_systmr_run(unsigned id, uint64_t delay_us) "timer #%u expiring in %"PRIu64" us"
172
173
# avr_timer16.c
174
avr_timer16_read(uint8_t addr, uint8_t value) "timer16 read addr:%u value:%u"
175
--
65
--
176
2.20.1
66
2.20.1
177
67
178
68
diff view generated by jsdifflib
1
The SMLAD instruction is supposed to:
1
Now that timer_free() implicitly calls timer_del(), sequences
2
* signed multiply Rn[15:0] * Rm[15:0]
2
timer_del(mytimer);
3
* signed multiply Rn[31:16] * Rm[31:16]
3
timer_free(mytimer);
4
* perform a signed addition of the products and Ra
5
* set Rd to the low 32 bits of the theoretical
6
infinite-precision result
7
* set the Q flag if the sign-extension of Rd
8
would differ from the infinite-precision result
9
(ie on overflow)
10
4
11
Our current implementation doesn't quite do this, though: it performs
5
can be simplified to just
12
an addition of the products setting Q on overflow, and then it adds
6
timer_free(mytimer);
13
Ra, again possibly setting Q. This sometimes incorrectly sets Q when
14
the architecturally mandated only-check-for-overflow-once algorithm
15
does not. For instance:
16
r1 = 0x80008000; r2 = 0x80008000; r3 = 0xffffffff
17
smlad r0, r1, r2, r3
18
This is (-32768 * -32768) + (-32768 * -32768) - 1
19
7
20
The products are both 0x4000_0000, so when added together as 32-bit
8
Add a Coccinelle script to do this transformation.
21
signed numbers they overflow (and QEMU sets Q), but because the
22
addition of Ra == -1 brings the total back down to 0x7fff_ffff
23
there is no overflow for the complete operation and setting Q is
24
incorrect.
25
26
Fix this edge case by resorting to 64-bit arithmetic for the
27
case where we need to add three values together.
28
9
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Message-id: 20201009144712.11187-1-peter.maydell@linaro.org
14
Message-id: 20201215154107.3255-3-peter.maydell@linaro.org
32
---
15
---
33
target/arm/translate.c | 58 ++++++++++++++++++++++++++++++++++--------
16
scripts/coccinelle/timer-del-timer-free.cocci | 18 ++++++++++++++++++
34
1 file changed, 48 insertions(+), 10 deletions(-)
17
1 file changed, 18 insertions(+)
18
create mode 100644 scripts/coccinelle/timer-del-timer-free.cocci
35
19
36
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
diff --git a/scripts/coccinelle/timer-del-timer-free.cocci b/scripts/coccinelle/timer-del-timer-free.cocci
37
index XXXXXXX..XXXXXXX 100644
21
new file mode 100644
38
--- a/target/arm/translate.c
22
index XXXXXXX..XXXXXXX
39
+++ b/target/arm/translate.c
23
--- /dev/null
40
@@ -XXX,XX +XXX,XX @@ static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
24
+++ b/scripts/coccinelle/timer-del-timer-free.cocci
41
gen_smul_dual(t1, t2);
25
@@ -XXX,XX +XXX,XX @@
42
26
+// Remove superfluous timer_del() calls
43
if (sub) {
27
+//
44
- /* This subtraction cannot overflow. */
28
+// Copyright Linaro Limited 2020
45
+ /*
29
+// This work is licensed under the terms of the GNU GPLv2 or later.
46
+ * This subtraction cannot overflow, so we can do a simple
30
+//
47
+ * 32-bit subtraction and then a possible 32-bit saturating
31
+// spatch --macro-file scripts/cocci-macro-file.h \
48
+ * addition of Ra.
32
+// --sp-file scripts/coccinelle/timer-del-timer-free.cocci \
49
+ */
33
+// --in-place --dir .
50
tcg_gen_sub_i32(t1, t1, t2);
34
+//
51
+ tcg_temp_free_i32(t2);
35
+// The timer_free() function now implicitly calls timer_del()
36
+// for you, so calls to timer_del() immediately before the
37
+// timer_free() of the same timer can be deleted.
52
+
38
+
53
+ if (a->ra != 15) {
39
+@@
54
+ t2 = load_reg(s, a->ra);
40
+expression T;
55
+ gen_helper_add_setq(t1, cpu_env, t1, t2);
41
+@@
56
+ tcg_temp_free_i32(t2);
42
+-timer_del(T);
57
+ }
43
+ timer_free(T);
58
+ } else if (a->ra == 15) {
59
+ /* Single saturation-checking addition */
60
+ gen_helper_add_setq(t1, cpu_env, t1, t2);
61
+ tcg_temp_free_i32(t2);
62
} else {
63
/*
64
- * This addition cannot overflow 32 bits; however it may
65
- * overflow considered as a signed operation, in which case
66
- * we must set the Q flag.
67
+ * We need to add the products and Ra together and then
68
+ * determine whether the final result overflowed. Doing
69
+ * this as two separate add-and-check-overflow steps incorrectly
70
+ * sets Q for cases like (-32768 * -32768) + (-32768 * -32768) + -1.
71
+ * Do all the arithmetic at 64-bits and then check for overflow.
72
*/
73
- gen_helper_add_setq(t1, cpu_env, t1, t2);
74
- }
75
- tcg_temp_free_i32(t2);
76
+ TCGv_i64 p64, q64;
77
+ TCGv_i32 t3, qf, one;
78
79
- if (a->ra != 15) {
80
- t2 = load_reg(s, a->ra);
81
- gen_helper_add_setq(t1, cpu_env, t1, t2);
82
+ p64 = tcg_temp_new_i64();
83
+ q64 = tcg_temp_new_i64();
84
+ tcg_gen_ext_i32_i64(p64, t1);
85
+ tcg_gen_ext_i32_i64(q64, t2);
86
+ tcg_gen_add_i64(p64, p64, q64);
87
+ load_reg_var(s, t2, a->ra);
88
+ tcg_gen_ext_i32_i64(q64, t2);
89
+ tcg_gen_add_i64(p64, p64, q64);
90
+ tcg_temp_free_i64(q64);
91
+
92
+ tcg_gen_extr_i64_i32(t1, t2, p64);
93
+ tcg_temp_free_i64(p64);
94
+ /*
95
+ * t1 is the low half of the result which goes into Rd.
96
+ * We have overflow and must set Q if the high half (t2)
97
+ * is different from the sign-extension of t1.
98
+ */
99
+ t3 = tcg_temp_new_i32();
100
+ tcg_gen_sari_i32(t3, t1, 31);
101
+ qf = load_cpu_field(QF);
102
+ one = tcg_const_i32(1);
103
+ tcg_gen_movcond_i32(TCG_COND_NE, qf, t2, t3, one, qf);
104
+ store_cpu_field(qf, QF);
105
+ tcg_temp_free_i32(one);
106
+ tcg_temp_free_i32(t3);
107
tcg_temp_free_i32(t2);
108
}
109
store_reg(s, a->rd, t1);
110
--
44
--
111
2.20.1
45
2.20.1
112
46
113
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
This commit is the result of running the timer-del-timer-free.cocci
2
script on the whole source tree.
2
3
3
For BTI, we need to know if the executable is static or dynamic,
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
which means looking for PT_INTERP earlier.
5
Acked-by: Corey Minyard <cminyard@mvista.com>
6
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20201215154107.3255-4-peter.maydell@linaro.org
10
---
11
block/iscsi.c | 2 --
12
block/nbd.c | 1 -
13
block/qcow2.c | 1 -
14
hw/block/nvme.c | 2 --
15
hw/char/serial.c | 2 --
16
hw/char/virtio-serial-bus.c | 2 --
17
hw/ide/core.c | 1 -
18
hw/input/hid.c | 1 -
19
hw/intc/apic.c | 1 -
20
hw/intc/ioapic.c | 1 -
21
hw/ipmi/ipmi_bmc_extern.c | 1 -
22
hw/net/e1000.c | 3 ---
23
hw/net/e1000e_core.c | 8 --------
24
hw/net/pcnet-pci.c | 1 -
25
hw/net/rtl8139.c | 1 -
26
hw/net/spapr_llan.c | 1 -
27
hw/net/virtio-net.c | 2 --
28
hw/s390x/s390-pci-inst.c | 1 -
29
hw/sd/sd.c | 1 -
30
hw/sd/sdhci.c | 2 --
31
hw/usb/dev-hub.c | 1 -
32
hw/usb/hcd-ehci.c | 1 -
33
hw/usb/hcd-ohci-pci.c | 1 -
34
hw/usb/hcd-uhci.c | 1 -
35
hw/usb/hcd-xhci.c | 1 -
36
hw/usb/redirect.c | 1 -
37
hw/vfio/display.c | 1 -
38
hw/virtio/vhost-vsock-common.c | 1 -
39
hw/virtio/virtio-balloon.c | 1 -
40
hw/virtio/virtio-rng.c | 1 -
41
hw/watchdog/wdt_diag288.c | 1 -
42
hw/watchdog/wdt_i6300esb.c | 1 -
43
migration/colo.c | 1 -
44
monitor/hmp-cmds.c | 1 -
45
net/announce.c | 1 -
46
net/colo-compare.c | 1 -
47
net/slirp.c | 1 -
48
replay/replay-debugging.c | 1 -
49
target/s390x/cpu.c | 2 --
50
ui/console.c | 1 -
51
ui/spice-core.c | 1 -
52
util/throttle.c | 1 -
53
42 files changed, 58 deletions(-)
5
54
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
55
diff --git a/block/iscsi.c b/block/iscsi.c
7
Message-id: 20201016184207.786698-8-richard.henderson@linaro.org
56
index XXXXXXX..XXXXXXX 100644
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
57
--- a/block/iscsi.c
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
58
+++ b/block/iscsi.c
10
---
59
@@ -XXX,XX +XXX,XX @@ static void iscsi_detach_aio_context(BlockDriverState *bs)
11
linux-user/elfload.c | 60 +++++++++++++++++++++++---------------------
60
iscsilun->events = 0;
12
1 file changed, 31 insertions(+), 29 deletions(-)
61
13
62
if (iscsilun->nop_timer) {
14
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
63
- timer_del(iscsilun->nop_timer);
15
index XXXXXXX..XXXXXXX 100644
64
timer_free(iscsilun->nop_timer);
16
--- a/linux-user/elfload.c
65
iscsilun->nop_timer = NULL;
17
+++ b/linux-user/elfload.c
66
}
18
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
67
if (iscsilun->event_timer) {
19
68
- timer_del(iscsilun->event_timer);
20
mmap_lock();
69
timer_free(iscsilun->event_timer);
21
70
iscsilun->event_timer = NULL;
22
- /* Find the maximum size of the image and allocate an appropriate
71
}
23
- amount of memory to handle that. */
72
diff --git a/block/nbd.c b/block/nbd.c
24
+ /*
73
index XXXXXXX..XXXXXXX 100644
25
+ * Find the maximum size of the image and allocate an appropriate
74
--- a/block/nbd.c
26
+ * amount of memory to handle that. Locate the interpreter, if any.
75
+++ b/block/nbd.c
27
+ */
76
@@ -XXX,XX +XXX,XX @@ static void nbd_recv_coroutines_wake_all(BDRVNBDState *s)
28
loaddr = -1, hiaddr = 0;
77
static void reconnect_delay_timer_del(BDRVNBDState *s)
29
info->alignment = 0;
78
{
30
for (i = 0; i < ehdr->e_phnum; ++i) {
79
if (s->reconnect_delay_timer) {
31
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
80
- timer_del(s->reconnect_delay_timer);
32
}
81
timer_free(s->reconnect_delay_timer);
33
++info->nsegs;
82
s->reconnect_delay_timer = NULL;
34
info->alignment |= eppnt->p_align;
83
}
35
+ } else if (eppnt->p_type == PT_INTERP && pinterp_name) {
84
diff --git a/block/qcow2.c b/block/qcow2.c
36
+ g_autofree char *interp_name = NULL;
85
index XXXXXXX..XXXXXXX 100644
37
+
86
--- a/block/qcow2.c
38
+ if (*pinterp_name) {
87
+++ b/block/qcow2.c
39
+ errmsg = "Multiple PT_INTERP entries";
88
@@ -XXX,XX +XXX,XX @@ static void cache_clean_timer_del(BlockDriverState *bs)
40
+ goto exit_errmsg;
89
{
41
+ }
90
BDRVQcow2State *s = bs->opaque;
42
+ interp_name = g_malloc(eppnt->p_filesz);
91
if (s->cache_clean_timer) {
43
+ if (!interp_name) {
92
- timer_del(s->cache_clean_timer);
44
+ goto exit_perror;
93
timer_free(s->cache_clean_timer);
45
+ }
94
s->cache_clean_timer = NULL;
46
+
95
}
47
+ if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
96
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
48
+ memcpy(interp_name, bprm_buf + eppnt->p_offset,
97
index XXXXXXX..XXXXXXX 100644
49
+ eppnt->p_filesz);
98
--- a/hw/block/nvme.c
50
+ } else {
99
+++ b/hw/block/nvme.c
51
+ retval = pread(image_fd, interp_name, eppnt->p_filesz,
100
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest *req)
52
+ eppnt->p_offset);
101
static void nvme_free_sq(NvmeSQueue *sq, NvmeCtrl *n)
53
+ if (retval != eppnt->p_filesz) {
102
{
54
+ goto exit_perror;
103
n->sq[sq->sqid] = NULL;
55
+ }
104
- timer_del(sq->timer);
56
+ }
105
timer_free(sq->timer);
57
+ if (interp_name[eppnt->p_filesz - 1] != 0) {
106
g_free(sq->io_req);
58
+ errmsg = "Invalid PT_INTERP entry";
107
if (sq->sqid) {
59
+ goto exit_errmsg;
108
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_get_log(NvmeCtrl *n, NvmeRequest *req)
60
+ }
109
static void nvme_free_cq(NvmeCQueue *cq, NvmeCtrl *n)
61
+ *pinterp_name = g_steal_pointer(&interp_name);
110
{
111
n->cq[cq->cqid] = NULL;
112
- timer_del(cq->timer);
113
timer_free(cq->timer);
114
msix_vector_unuse(&n->parent_obj, cq->vector);
115
if (cq->cqid) {
116
diff --git a/hw/char/serial.c b/hw/char/serial.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/char/serial.c
119
+++ b/hw/char/serial.c
120
@@ -XXX,XX +XXX,XX @@ static void serial_unrealize(DeviceState *dev)
121
122
qemu_chr_fe_deinit(&s->chr, false);
123
124
- timer_del(s->modem_status_poll);
125
timer_free(s->modem_status_poll);
126
127
- timer_del(s->fifo_timeout_timer);
128
timer_free(s->fifo_timeout_timer);
129
130
fifo8_destroy(&s->recv_fifo);
131
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/char/virtio-serial-bus.c
134
+++ b/hw/char/virtio-serial-bus.c
135
@@ -XXX,XX +XXX,XX @@ static void virtio_serial_post_load_timer_cb(void *opaque)
62
}
136
}
63
}
137
}
64
138
g_free(s->post_load->connected);
65
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
139
- timer_del(s->post_load->timer);
66
if (vaddr_em > info->brk) {
140
timer_free(s->post_load->timer);
67
info->brk = vaddr_em;
141
g_free(s->post_load);
68
}
142
s->post_load = NULL;
69
- } else if (eppnt->p_type == PT_INTERP && pinterp_name) {
143
@@ -XXX,XX +XXX,XX @@ static void virtio_serial_device_unrealize(DeviceState *dev)
70
- g_autofree char *interp_name = NULL;
144
g_free(vser->ports_map);
71
-
145
if (vser->post_load) {
72
- if (*pinterp_name) {
146
g_free(vser->post_load->connected);
73
- errmsg = "Multiple PT_INTERP entries";
147
- timer_del(vser->post_load->timer);
74
- goto exit_errmsg;
148
timer_free(vser->post_load->timer);
75
- }
149
g_free(vser->post_load);
76
- interp_name = g_malloc(eppnt->p_filesz);
150
}
77
- if (!interp_name) {
151
diff --git a/hw/ide/core.c b/hw/ide/core.c
78
- goto exit_perror;
152
index XXXXXXX..XXXXXXX 100644
79
- }
153
--- a/hw/ide/core.c
80
-
154
+++ b/hw/ide/core.c
81
- if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
155
@@ -XXX,XX +XXX,XX @@ void ide_init2(IDEBus *bus, qemu_irq irq)
82
- memcpy(interp_name, bprm_buf + eppnt->p_offset,
156
83
- eppnt->p_filesz);
157
void ide_exit(IDEState *s)
84
- } else {
158
{
85
- retval = pread(image_fd, interp_name, eppnt->p_filesz,
159
- timer_del(s->sector_write_timer);
86
- eppnt->p_offset);
160
timer_free(s->sector_write_timer);
87
- if (retval != eppnt->p_filesz) {
161
qemu_vfree(s->smart_selftest_data);
88
- goto exit_perror;
162
qemu_vfree(s->io_buffer);
89
- }
163
diff --git a/hw/input/hid.c b/hw/input/hid.c
90
- }
164
index XXXXXXX..XXXXXXX 100644
91
- if (interp_name[eppnt->p_filesz - 1] != 0) {
165
--- a/hw/input/hid.c
92
- errmsg = "Invalid PT_INTERP entry";
166
+++ b/hw/input/hid.c
93
- goto exit_errmsg;
167
@@ -XXX,XX +XXX,XX @@ static void hid_idle_timer(void *opaque)
94
- }
168
static void hid_del_idle_timer(HIDState *hs)
95
- *pinterp_name = g_steal_pointer(&interp_name);
169
{
96
#ifdef TARGET_MIPS
170
if (hs->idle_timer) {
97
} else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
171
- timer_del(hs->idle_timer);
98
Mips_elf_abiflags_v0 abiflags;
172
timer_free(hs->idle_timer);
173
hs->idle_timer = NULL;
174
}
175
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
176
index XXXXXXX..XXXXXXX 100644
177
--- a/hw/intc/apic.c
178
+++ b/hw/intc/apic.c
179
@@ -XXX,XX +XXX,XX @@ static void apic_unrealize(DeviceState *dev)
180
{
181
APICCommonState *s = APIC(dev);
182
183
- timer_del(s->timer);
184
timer_free(s->timer);
185
local_apics[s->id] = NULL;
186
}
187
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
188
index XXXXXXX..XXXXXXX 100644
189
--- a/hw/intc/ioapic.c
190
+++ b/hw/intc/ioapic.c
191
@@ -XXX,XX +XXX,XX @@ static void ioapic_unrealize(DeviceState *dev)
192
{
193
IOAPICCommonState *s = IOAPIC_COMMON(dev);
194
195
- timer_del(s->delayed_ioapic_service_timer);
196
timer_free(s->delayed_ioapic_service_timer);
197
}
198
199
diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/hw/ipmi/ipmi_bmc_extern.c
202
+++ b/hw/ipmi/ipmi_bmc_extern.c
203
@@ -XXX,XX +XXX,XX @@ static void ipmi_bmc_extern_finalize(Object *obj)
204
{
205
IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(obj);
206
207
- timer_del(ibe->extern_timer);
208
timer_free(ibe->extern_timer);
209
}
210
211
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/hw/net/e1000.c
214
+++ b/hw/net/e1000.c
215
@@ -XXX,XX +XXX,XX @@ pci_e1000_uninit(PCIDevice *dev)
216
{
217
E1000State *d = E1000(dev);
218
219
- timer_del(d->autoneg_timer);
220
timer_free(d->autoneg_timer);
221
- timer_del(d->mit_timer);
222
timer_free(d->mit_timer);
223
- timer_del(d->flush_queue_timer);
224
timer_free(d->flush_queue_timer);
225
qemu_del_nic(d->nic);
226
}
227
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
228
index XXXXXXX..XXXXXXX 100644
229
--- a/hw/net/e1000e_core.c
230
+++ b/hw/net/e1000e_core.c
231
@@ -XXX,XX +XXX,XX @@ e1000e_intrmgr_pci_unint(E1000ECore *core)
232
{
233
int i;
234
235
- timer_del(core->radv.timer);
236
timer_free(core->radv.timer);
237
- timer_del(core->rdtr.timer);
238
timer_free(core->rdtr.timer);
239
- timer_del(core->raid.timer);
240
timer_free(core->raid.timer);
241
242
- timer_del(core->tadv.timer);
243
timer_free(core->tadv.timer);
244
- timer_del(core->tidv.timer);
245
timer_free(core->tidv.timer);
246
247
- timer_del(core->itr.timer);
248
timer_free(core->itr.timer);
249
250
for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
251
- timer_del(core->eitr[i].timer);
252
timer_free(core->eitr[i].timer);
253
}
254
}
255
@@ -XXX,XX +XXX,XX @@ e1000e_core_pci_uninit(E1000ECore *core)
256
{
257
int i;
258
259
- timer_del(core->autoneg_timer);
260
timer_free(core->autoneg_timer);
261
262
e1000e_intrmgr_pci_unint(core);
263
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
264
index XXXXXXX..XXXXXXX 100644
265
--- a/hw/net/pcnet-pci.c
266
+++ b/hw/net/pcnet-pci.c
267
@@ -XXX,XX +XXX,XX @@ static void pci_pcnet_uninit(PCIDevice *dev)
268
PCIPCNetState *d = PCI_PCNET(dev);
269
270
qemu_free_irq(d->state.irq);
271
- timer_del(d->state.poll_timer);
272
timer_free(d->state.poll_timer);
273
qemu_del_nic(d->state.nic);
274
}
275
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
276
index XXXXXXX..XXXXXXX 100644
277
--- a/hw/net/rtl8139.c
278
+++ b/hw/net/rtl8139.c
279
@@ -XXX,XX +XXX,XX @@ static void pci_rtl8139_uninit(PCIDevice *dev)
280
281
g_free(s->cplus_txbuffer);
282
s->cplus_txbuffer = NULL;
283
- timer_del(s->timer);
284
timer_free(s->timer);
285
qemu_del_nic(s->nic);
286
}
287
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
288
index XXXXXXX..XXXXXXX 100644
289
--- a/hw/net/spapr_llan.c
290
+++ b/hw/net/spapr_llan.c
291
@@ -XXX,XX +XXX,XX @@ static void spapr_vlan_instance_finalize(Object *obj)
292
}
293
294
if (dev->rxp_timer) {
295
- timer_del(dev->rxp_timer);
296
timer_free(dev->rxp_timer);
297
}
298
}
299
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
300
index XXXXXXX..XXXXXXX 100644
301
--- a/hw/net/virtio-net.c
302
+++ b/hw/net/virtio-net.c
303
@@ -XXX,XX +XXX,XX @@ static void virtio_net_rsc_cleanup(VirtIONet *n)
304
g_free(seg);
305
}
306
307
- timer_del(chain->drain_timer);
308
timer_free(chain->drain_timer);
309
QTAILQ_REMOVE(&n->rsc_chains, chain, next);
310
g_free(chain);
311
@@ -XXX,XX +XXX,XX @@ static void virtio_net_del_queue(VirtIONet *n, int index)
312
313
virtio_del_queue(vdev, index * 2);
314
if (q->tx_timer) {
315
- timer_del(q->tx_timer);
316
timer_free(q->tx_timer);
317
q->tx_timer = NULL;
318
} else {
319
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
320
index XXXXXXX..XXXXXXX 100644
321
--- a/hw/s390x/s390-pci-inst.c
322
+++ b/hw/s390x/s390-pci-inst.c
323
@@ -XXX,XX +XXX,XX @@ void pci_dereg_ioat(S390PCIIOMMU *iommu)
324
void fmb_timer_free(S390PCIBusDevice *pbdev)
325
{
326
if (pbdev->fmb_timer) {
327
- timer_del(pbdev->fmb_timer);
328
timer_free(pbdev->fmb_timer);
329
pbdev->fmb_timer = NULL;
330
}
331
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
332
index XXXXXXX..XXXXXXX 100644
333
--- a/hw/sd/sd.c
334
+++ b/hw/sd/sd.c
335
@@ -XXX,XX +XXX,XX @@ static void sd_instance_finalize(Object *obj)
336
{
337
SDState *sd = SD_CARD(obj);
338
339
- timer_del(sd->ocr_power_timer);
340
timer_free(sd->ocr_power_timer);
341
}
342
343
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
344
index XXXXXXX..XXXXXXX 100644
345
--- a/hw/sd/sdhci.c
346
+++ b/hw/sd/sdhci.c
347
@@ -XXX,XX +XXX,XX @@ void sdhci_initfn(SDHCIState *s)
348
349
void sdhci_uninitfn(SDHCIState *s)
350
{
351
- timer_del(s->insert_timer);
352
timer_free(s->insert_timer);
353
- timer_del(s->transfer_timer);
354
timer_free(s->transfer_timer);
355
356
g_free(s->fifo_buffer);
357
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
358
index XXXXXXX..XXXXXXX 100644
359
--- a/hw/usb/dev-hub.c
360
+++ b/hw/usb/dev-hub.c
361
@@ -XXX,XX +XXX,XX @@ static void usb_hub_unrealize(USBDevice *dev)
362
&s->ports[i].port);
363
}
364
365
- timer_del(s->port_timer);
366
timer_free(s->port_timer);
367
}
368
369
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
370
index XXXXXXX..XXXXXXX 100644
371
--- a/hw/usb/hcd-ehci.c
372
+++ b/hw/usb/hcd-ehci.c
373
@@ -XXX,XX +XXX,XX @@ void usb_ehci_unrealize(EHCIState *s, DeviceState *dev)
374
trace_usb_ehci_unrealize();
375
376
if (s->frame_timer) {
377
- timer_del(s->frame_timer);
378
timer_free(s->frame_timer);
379
s->frame_timer = NULL;
380
}
381
diff --git a/hw/usb/hcd-ohci-pci.c b/hw/usb/hcd-ohci-pci.c
382
index XXXXXXX..XXXXXXX 100644
383
--- a/hw/usb/hcd-ohci-pci.c
384
+++ b/hw/usb/hcd-ohci-pci.c
385
@@ -XXX,XX +XXX,XX @@ static void usb_ohci_exit(PCIDevice *dev)
386
usb_bus_release(&s->bus);
387
}
388
389
- timer_del(s->eof_timer);
390
timer_free(s->eof_timer);
391
}
392
393
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
394
index XXXXXXX..XXXXXXX 100644
395
--- a/hw/usb/hcd-uhci.c
396
+++ b/hw/usb/hcd-uhci.c
397
@@ -XXX,XX +XXX,XX @@ static void usb_uhci_exit(PCIDevice *dev)
398
trace_usb_uhci_exit();
399
400
if (s->frame_timer) {
401
- timer_del(s->frame_timer);
402
timer_free(s->frame_timer);
403
s->frame_timer = NULL;
404
}
405
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
406
index XXXXXXX..XXXXXXX 100644
407
--- a/hw/usb/hcd-xhci.c
408
+++ b/hw/usb/hcd-xhci.c
409
@@ -XXX,XX +XXX,XX @@ static void usb_xhci_unrealize(DeviceState *dev)
410
}
411
412
if (xhci->mfwrap_timer) {
413
- timer_del(xhci->mfwrap_timer);
414
timer_free(xhci->mfwrap_timer);
415
xhci->mfwrap_timer = NULL;
416
}
417
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
418
index XXXXXXX..XXXXXXX 100644
419
--- a/hw/usb/redirect.c
420
+++ b/hw/usb/redirect.c
421
@@ -XXX,XX +XXX,XX @@ static void usbredir_unrealize(USBDevice *udev)
422
qemu_bh_delete(dev->chardev_close_bh);
423
qemu_bh_delete(dev->device_reject_bh);
424
425
- timer_del(dev->attach_timer);
426
timer_free(dev->attach_timer);
427
428
usbredir_cleanup_device_queues(dev);
429
diff --git a/hw/vfio/display.c b/hw/vfio/display.c
430
index XXXXXXX..XXXXXXX 100644
431
--- a/hw/vfio/display.c
432
+++ b/hw/vfio/display.c
433
@@ -XXX,XX +XXX,XX @@ static void vfio_display_edid_exit(VFIODisplay *dpy)
434
435
g_free(dpy->edid_regs);
436
g_free(dpy->edid_blob);
437
- timer_del(dpy->edid_link_timer);
438
timer_free(dpy->edid_link_timer);
439
}
440
441
diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c
442
index XXXXXXX..XXXXXXX 100644
443
--- a/hw/virtio/vhost-vsock-common.c
444
+++ b/hw/virtio/vhost-vsock-common.c
445
@@ -XXX,XX +XXX,XX @@ static void vhost_vsock_common_post_load_timer_cleanup(VHostVSockCommon *vvc)
446
return;
447
}
448
449
- timer_del(vvc->post_load_timer);
450
timer_free(vvc->post_load_timer);
451
vvc->post_load_timer = NULL;
452
}
453
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
454
index XXXXXXX..XXXXXXX 100644
455
--- a/hw/virtio/virtio-balloon.c
456
+++ b/hw/virtio/virtio-balloon.c
457
@@ -XXX,XX +XXX,XX @@ static bool balloon_stats_enabled(const VirtIOBalloon *s)
458
static void balloon_stats_destroy_timer(VirtIOBalloon *s)
459
{
460
if (balloon_stats_enabled(s)) {
461
- timer_del(s->stats_timer);
462
timer_free(s->stats_timer);
463
s->stats_timer = NULL;
464
s->stats_poll_interval = 0;
465
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
466
index XXXXXXX..XXXXXXX 100644
467
--- a/hw/virtio/virtio-rng.c
468
+++ b/hw/virtio/virtio-rng.c
469
@@ -XXX,XX +XXX,XX @@ static void virtio_rng_device_unrealize(DeviceState *dev)
470
VirtIORNG *vrng = VIRTIO_RNG(dev);
471
472
qemu_del_vm_change_state_handler(vrng->vmstate);
473
- timer_del(vrng->rate_limit_timer);
474
timer_free(vrng->rate_limit_timer);
475
virtio_del_queue(vdev, 0);
476
virtio_cleanup(vdev);
477
diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c
478
index XXXXXXX..XXXXXXX 100644
479
--- a/hw/watchdog/wdt_diag288.c
480
+++ b/hw/watchdog/wdt_diag288.c
481
@@ -XXX,XX +XXX,XX @@ static void wdt_diag288_unrealize(DeviceState *dev)
482
{
483
DIAG288State *diag288 = DIAG288(dev);
484
485
- timer_del(diag288->timer);
486
timer_free(diag288->timer);
487
}
488
489
diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
490
index XXXXXXX..XXXXXXX 100644
491
--- a/hw/watchdog/wdt_i6300esb.c
492
+++ b/hw/watchdog/wdt_i6300esb.c
493
@@ -XXX,XX +XXX,XX @@ static void i6300esb_exit(PCIDevice *dev)
494
{
495
I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev);
496
497
- timer_del(d->timer);
498
timer_free(d->timer);
499
}
500
501
diff --git a/migration/colo.c b/migration/colo.c
502
index XXXXXXX..XXXXXXX 100644
503
--- a/migration/colo.c
504
+++ b/migration/colo.c
505
@@ -XXX,XX +XXX,XX @@ out:
506
* error.
507
*/
508
colo_compare_unregister_notifier(&packets_compare_notifier);
509
- timer_del(s->colo_delay_timer);
510
timer_free(s->colo_delay_timer);
511
qemu_event_destroy(&s->colo_checkpoint_event);
512
513
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
514
index XXXXXXX..XXXXXXX 100644
515
--- a/monitor/hmp-cmds.c
516
+++ b/monitor/hmp-cmds.c
517
@@ -XXX,XX +XXX,XX @@ static void hmp_migrate_status_cb(void *opaque)
518
error_report("%s", info->error_desc);
519
}
520
monitor_resume(status->mon);
521
- timer_del(status->timer);
522
timer_free(status->timer);
523
g_free(status);
524
}
525
diff --git a/net/announce.c b/net/announce.c
526
index XXXXXXX..XXXXXXX 100644
527
--- a/net/announce.c
528
+++ b/net/announce.c
529
@@ -XXX,XX +XXX,XX @@ void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named)
530
{
531
bool free_timer = false;
532
if (timer->tm) {
533
- timer_del(timer->tm);
534
timer_free(timer->tm);
535
timer->tm = NULL;
536
}
537
diff --git a/net/colo-compare.c b/net/colo-compare.c
538
index XXXXXXX..XXXXXXX 100644
539
--- a/net/colo-compare.c
540
+++ b/net/colo-compare.c
541
@@ -XXX,XX +XXX,XX @@ static void colo_compare_timer_init(CompareState *s)
542
static void colo_compare_timer_del(CompareState *s)
543
{
544
if (s->packet_check_timer) {
545
- timer_del(s->packet_check_timer);
546
timer_free(s->packet_check_timer);
547
s->packet_check_timer = NULL;
548
}
549
diff --git a/net/slirp.c b/net/slirp.c
550
index XXXXXXX..XXXXXXX 100644
551
--- a/net/slirp.c
552
+++ b/net/slirp.c
553
@@ -XXX,XX +XXX,XX @@ static void *net_slirp_timer_new(SlirpTimerCb cb,
554
555
static void net_slirp_timer_free(void *timer, void *opaque)
556
{
557
- timer_del(timer);
558
timer_free(timer);
559
}
560
561
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
562
index XXXXXXX..XXXXXXX 100644
563
--- a/replay/replay-debugging.c
564
+++ b/replay/replay-debugging.c
565
@@ -XXX,XX +XXX,XX @@ static void replay_delete_break(void)
566
assert(replay_mutex_locked());
567
568
if (replay_break_timer) {
569
- timer_del(replay_break_timer);
570
timer_free(replay_break_timer);
571
replay_break_timer = NULL;
572
}
573
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
574
index XXXXXXX..XXXXXXX 100644
575
--- a/target/s390x/cpu.c
576
+++ b/target/s390x/cpu.c
577
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_finalize(Object *obj)
578
#if !defined(CONFIG_USER_ONLY)
579
S390CPU *cpu = S390_CPU(obj);
580
581
- timer_del(cpu->env.tod_timer);
582
timer_free(cpu->env.tod_timer);
583
- timer_del(cpu->env.cpu_timer);
584
timer_free(cpu->env.cpu_timer);
585
586
qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu);
587
diff --git a/ui/console.c b/ui/console.c
588
index XXXXXXX..XXXXXXX 100644
589
--- a/ui/console.c
590
+++ b/ui/console.c
591
@@ -XXX,XX +XXX,XX @@ static void gui_setup_refresh(DisplayState *ds)
592
timer_mod(ds->gui_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
593
}
594
if (!need_timer && ds->gui_timer != NULL) {
595
- timer_del(ds->gui_timer);
596
timer_free(ds->gui_timer);
597
ds->gui_timer = NULL;
598
}
599
diff --git a/ui/spice-core.c b/ui/spice-core.c
600
index XXXXXXX..XXXXXXX 100644
601
--- a/ui/spice-core.c
602
+++ b/ui/spice-core.c
603
@@ -XXX,XX +XXX,XX @@ static void timer_cancel(SpiceTimer *timer)
604
605
static void timer_remove(SpiceTimer *timer)
606
{
607
- timer_del(timer->timer);
608
timer_free(timer->timer);
609
g_free(timer);
610
}
611
diff --git a/util/throttle.c b/util/throttle.c
612
index XXXXXXX..XXXXXXX 100644
613
--- a/util/throttle.c
614
+++ b/util/throttle.c
615
@@ -XXX,XX +XXX,XX @@ static void throttle_timer_destroy(QEMUTimer **timer)
616
{
617
assert(*timer != NULL);
618
619
- timer_del(*timer);
620
timer_free(*timer);
621
*timer = NULL;
622
}
99
--
623
--
100
2.20.1
624
2.20.1
101
625
102
626
diff view generated by jsdifflib
1
In arm_cpu_realizefn(), if the CPU has VFP or Neon disabled then we
1
The Arm CPU finalize function uses a sequence of timer_del(), timer_deinit(),
2
squash the ID register fields so that we don't advertise it to the
2
timer_free() to free the timer. The timer_deinit() step in this was always
3
guest. This code was written for A-profile and needs some tweaks to
3
unnecessary, and now the timer_del() is implied by timer_free(), so we can
4
work correctly on M-profile:
4
collapse this down to simply calling timer_free().
5
5
6
* A-profile only fields should not be zeroed on M-profile:
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
- MVFR0.FPSHVEC,FPTRAP
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
- MVFR1.SIMDLS,SIMDINT,SIMDSP,SIMDHP
9
- MVFR2.SIMDMISC
10
* M-profile only fields should be zeroed on M-profile:
11
- MVFR1.FP16
12
13
In particular, because MVFR1.SIMDHP on A-profile is the same field as
14
MVFR1.FP16 on M-profile this code was incorrectly disabling FP16
15
support on an M-profile CPU (where has_neon is always false). This
16
isn't a visible bug yet because we don't have any M-profile CPUs with
17
FP16 support, but the change is necessary before we introduce any.
18
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20201215154107.3255-5-peter.maydell@linaro.org
21
Message-id: 20201019151301.2046-9-peter.maydell@linaro.org
22
---
10
---
23
target/arm/cpu.c | 29 ++++++++++++++++++-----------
11
target/arm/cpu.c | 2 --
24
1 file changed, 18 insertions(+), 11 deletions(-)
12
1 file changed, 2 deletions(-)
25
13
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
27
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu.c
16
--- a/target/arm/cpu.c
29
+++ b/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
30
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_finalizefn(Object *obj)
31
u = cpu->isar.mvfr0;
32
u = FIELD_DP32(u, MVFR0, FPSP, 0);
33
u = FIELD_DP32(u, MVFR0, FPDP, 0);
34
- u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
35
u = FIELD_DP32(u, MVFR0, FPDIVIDE, 0);
36
u = FIELD_DP32(u, MVFR0, FPSQRT, 0);
37
- u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
38
u = FIELD_DP32(u, MVFR0, FPROUND, 0);
39
+ if (!arm_feature(env, ARM_FEATURE_M)) {
40
+ u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
41
+ u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
42
+ }
43
cpu->isar.mvfr0 = u;
44
45
u = cpu->isar.mvfr1;
46
u = FIELD_DP32(u, MVFR1, FPFTZ, 0);
47
u = FIELD_DP32(u, MVFR1, FPDNAN, 0);
48
u = FIELD_DP32(u, MVFR1, FPHP, 0);
49
+ if (arm_feature(env, ARM_FEATURE_M)) {
50
+ u = FIELD_DP32(u, MVFR1, FP16, 0);
51
+ }
52
cpu->isar.mvfr1 = u;
53
54
u = cpu->isar.mvfr2;
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
56
u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
57
cpu->isar.id_isar6 = u;
58
59
- u = cpu->isar.mvfr1;
60
- u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
61
- u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
62
- u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
63
- u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
64
- cpu->isar.mvfr1 = u;
65
+ if (!arm_feature(env, ARM_FEATURE_M)) {
66
+ u = cpu->isar.mvfr1;
67
+ u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
68
+ u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
69
+ u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
70
+ u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
71
+ cpu->isar.mvfr1 = u;
72
73
- u = cpu->isar.mvfr2;
74
- u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
75
- cpu->isar.mvfr2 = u;
76
+ u = cpu->isar.mvfr2;
77
+ u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
78
+ cpu->isar.mvfr2 = u;
79
+ }
80
}
19
}
81
20
#ifndef CONFIG_USER_ONLY
82
if (!cpu->has_neon && !cpu->has_vfp) {
21
if (cpu->pmu_timer) {
22
- timer_del(cpu->pmu_timer);
23
- timer_deinit(cpu->pmu_timer);
24
timer_free(cpu->pmu_timer);
25
}
26
#endif
83
--
27
--
84
2.20.1
28
2.20.1
85
29
86
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
The note test requires gcc 10 for -mbranch-protection=standard.
3
When running device-introspect-test, a memory leak occurred in the
4
The mmap test uses PROT_BTI and does not require special compiler support.
4
digic_timer_init function, so use ptimer_free() in the finalize function to
5
avoid it.
5
6
6
Acked-by: Alex Bennée <alex.bennee@linaro.org>
7
ASAN shows memory leak stack:
8
9
Indirect leak of 288 byte(s) in 3 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf5b04084 in digic_timer_init /qemu/hw/timer/digic-timer.c:142
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564
16
#6 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547
17
#7 0xaaabf5b40e84 in digic_init /qemu/hw/arm/digic.c:46
18
#8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
19
#9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
20
#10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
21
#11 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
22
#12 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20201016184207.786698-13-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
28
---
12
tests/tcg/aarch64/bti-1.c | 62 +++++++++++++++++
29
hw/timer/digic-timer.c | 8 ++++++++
13
tests/tcg/aarch64/bti-2.c | 108 ++++++++++++++++++++++++++++++
30
1 file changed, 8 insertions(+)
14
tests/tcg/aarch64/bti-crt.inc.c | 51 ++++++++++++++
15
tests/tcg/aarch64/Makefile.target | 10 +++
16
tests/tcg/configure.sh | 4 ++
17
5 files changed, 235 insertions(+)
18
create mode 100644 tests/tcg/aarch64/bti-1.c
19
create mode 100644 tests/tcg/aarch64/bti-2.c
20
create mode 100644 tests/tcg/aarch64/bti-crt.inc.c
21
31
22
diff --git a/tests/tcg/aarch64/bti-1.c b/tests/tcg/aarch64/bti-1.c
32
diff --git a/hw/timer/digic-timer.c b/hw/timer/digic-timer.c
23
new file mode 100644
33
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX
34
--- a/hw/timer/digic-timer.c
25
--- /dev/null
35
+++ b/hw/timer/digic-timer.c
26
+++ b/tests/tcg/aarch64/bti-1.c
36
@@ -XXX,XX +XXX,XX @@ static void digic_timer_init(Object *obj)
27
@@ -XXX,XX +XXX,XX @@
37
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
28
+/*
38
}
29
+ * Branch target identification, basic notskip cases.
39
30
+ */
40
+static void digic_timer_finalize(Object *obj)
41
+{
42
+ DigicTimerState *s = DIGIC_TIMER(obj);
31
+
43
+
32
+#include "bti-crt.inc.c"
44
+ ptimer_free(s->ptimer);
33
+
34
+static void skip2_sigill(int sig, siginfo_t *info, ucontext_t *uc)
35
+{
36
+ uc->uc_mcontext.pc += 8;
37
+ uc->uc_mcontext.pstate = 1;
38
+}
45
+}
39
+
46
+
40
+#define NOP "nop"
47
static void digic_timer_class_init(ObjectClass *klass, void *class_data)
41
+#define BTI_N "hint #32"
48
{
42
+#define BTI_C "hint #34"
49
DeviceClass *dc = DEVICE_CLASS(klass);
43
+#define BTI_J "hint #36"
50
@@ -XXX,XX +XXX,XX @@ static const TypeInfo digic_timer_info = {
44
+#define BTI_JC "hint #38"
51
.parent = TYPE_SYS_BUS_DEVICE,
45
+
52
.instance_size = sizeof(DigicTimerState),
46
+#define BTYPE_1(DEST) \
53
.instance_init = digic_timer_init,
47
+ asm("mov %0,#1; adr x16, 1f; br x16; 1: " DEST "; mov %0,#0" \
54
+ .instance_finalize = digic_timer_finalize,
48
+ : "=r"(skipped) : : "x16")
55
.class_init = digic_timer_class_init,
49
+
56
};
50
+#define BTYPE_2(DEST) \
51
+ asm("mov %0,#1; adr x16, 1f; blr x16; 1: " DEST "; mov %0,#0" \
52
+ : "=r"(skipped) : : "x16", "x30")
53
+
54
+#define BTYPE_3(DEST) \
55
+ asm("mov %0,#1; adr x15, 1f; br x15; 1: " DEST "; mov %0,#0" \
56
+ : "=r"(skipped) : : "x15")
57
+
58
+#define TEST(WHICH, DEST, EXPECT) \
59
+ do { WHICH(DEST); fail += skipped ^ EXPECT; } while (0)
60
+
61
+
62
+int main()
63
+{
64
+ int fail = 0;
65
+ int skipped;
66
+
67
+ /* Signal-like with SA_SIGINFO. */
68
+ signal_info(SIGILL, skip2_sigill);
69
+
70
+ TEST(BTYPE_1, NOP, 1);
71
+ TEST(BTYPE_1, BTI_N, 1);
72
+ TEST(BTYPE_1, BTI_C, 0);
73
+ TEST(BTYPE_1, BTI_J, 0);
74
+ TEST(BTYPE_1, BTI_JC, 0);
75
+
76
+ TEST(BTYPE_2, NOP, 1);
77
+ TEST(BTYPE_2, BTI_N, 1);
78
+ TEST(BTYPE_2, BTI_C, 0);
79
+ TEST(BTYPE_2, BTI_J, 1);
80
+ TEST(BTYPE_2, BTI_JC, 0);
81
+
82
+ TEST(BTYPE_3, NOP, 1);
83
+ TEST(BTYPE_3, BTI_N, 1);
84
+ TEST(BTYPE_3, BTI_C, 1);
85
+ TEST(BTYPE_3, BTI_J, 0);
86
+ TEST(BTYPE_3, BTI_JC, 0);
87
+
88
+ return fail;
89
+}
90
diff --git a/tests/tcg/aarch64/bti-2.c b/tests/tcg/aarch64/bti-2.c
91
new file mode 100644
92
index XXXXXXX..XXXXXXX
93
--- /dev/null
94
+++ b/tests/tcg/aarch64/bti-2.c
95
@@ -XXX,XX +XXX,XX @@
96
+/*
97
+ * Branch target identification, basic notskip cases.
98
+ */
99
+
100
+#include <stdio.h>
101
+#include <signal.h>
102
+#include <string.h>
103
+#include <unistd.h>
104
+#include <sys/mman.h>
105
+
106
+#ifndef PROT_BTI
107
+#define PROT_BTI 0x10
108
+#endif
109
+
110
+static void skip2_sigill(int sig, siginfo_t *info, void *vuc)
111
+{
112
+ ucontext_t *uc = vuc;
113
+ uc->uc_mcontext.pc += 8;
114
+ uc->uc_mcontext.pstate = 1;
115
+}
116
+
117
+#define NOP "nop"
118
+#define BTI_N "hint #32"
119
+#define BTI_C "hint #34"
120
+#define BTI_J "hint #36"
121
+#define BTI_JC "hint #38"
122
+
123
+#define BTYPE_1(DEST) \
124
+ "mov x1, #1\n\t" \
125
+ "adr x16, 1f\n\t" \
126
+ "br x16\n" \
127
+"1: " DEST "\n\t" \
128
+ "mov x1, #0"
129
+
130
+#define BTYPE_2(DEST) \
131
+ "mov x1, #1\n\t" \
132
+ "adr x16, 1f\n\t" \
133
+ "blr x16\n" \
134
+"1: " DEST "\n\t" \
135
+ "mov x1, #0"
136
+
137
+#define BTYPE_3(DEST) \
138
+ "mov x1, #1\n\t" \
139
+ "adr x15, 1f\n\t" \
140
+ "br x15\n" \
141
+"1: " DEST "\n\t" \
142
+ "mov x1, #0"
143
+
144
+#define TEST(WHICH, DEST, EXPECT) \
145
+ WHICH(DEST) "\n" \
146
+ ".if " #EXPECT "\n\t" \
147
+ "eor x1, x1," #EXPECT "\n" \
148
+ ".endif\n\t" \
149
+ "add x0, x0, x1\n\t"
150
+
151
+extern char test_begin[], test_end[];
152
+
153
+asm("\n"
154
+"test_begin:\n\t"
155
+ BTI_C "\n\t"
156
+ "mov x2, x30\n\t"
157
+ "mov x0, #0\n\t"
158
+
159
+ TEST(BTYPE_1, NOP, 1)
160
+ TEST(BTYPE_1, BTI_N, 1)
161
+ TEST(BTYPE_1, BTI_C, 0)
162
+ TEST(BTYPE_1, BTI_J, 0)
163
+ TEST(BTYPE_1, BTI_JC, 0)
164
+
165
+ TEST(BTYPE_2, NOP, 1)
166
+ TEST(BTYPE_2, BTI_N, 1)
167
+ TEST(BTYPE_2, BTI_C, 0)
168
+ TEST(BTYPE_2, BTI_J, 1)
169
+ TEST(BTYPE_2, BTI_JC, 0)
170
+
171
+ TEST(BTYPE_3, NOP, 1)
172
+ TEST(BTYPE_3, BTI_N, 1)
173
+ TEST(BTYPE_3, BTI_C, 1)
174
+ TEST(BTYPE_3, BTI_J, 0)
175
+ TEST(BTYPE_3, BTI_JC, 0)
176
+
177
+ "ret x2\n"
178
+"test_end:"
179
+);
180
+
181
+int main()
182
+{
183
+ struct sigaction sa;
184
+
185
+ void *p = mmap(0, getpagesize(),
186
+ PROT_EXEC | PROT_READ | PROT_WRITE | PROT_BTI,
187
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
188
+ if (p == MAP_FAILED) {
189
+ perror("mmap");
190
+ return 1;
191
+ }
192
+
193
+ memset(&sa, 0, sizeof(sa));
194
+ sa.sa_sigaction = skip2_sigill;
195
+ sa.sa_flags = SA_SIGINFO;
196
+ if (sigaction(SIGILL, &sa, NULL) < 0) {
197
+ perror("sigaction");
198
+ return 1;
199
+ }
200
+
201
+ memcpy(p, test_begin, test_end - test_begin);
202
+ return ((int (*)(void))p)();
203
+}
204
diff --git a/tests/tcg/aarch64/bti-crt.inc.c b/tests/tcg/aarch64/bti-crt.inc.c
205
new file mode 100644
206
index XXXXXXX..XXXXXXX
207
--- /dev/null
208
+++ b/tests/tcg/aarch64/bti-crt.inc.c
209
@@ -XXX,XX +XXX,XX @@
210
+/*
211
+ * Minimal user-environment for testing BTI.
212
+ *
213
+ * Normal libc is not (yet) built with BTI support enabled,
214
+ * and so could generate a BTI TRAP before ever reaching main.
215
+ */
216
+
217
+#include <stdlib.h>
218
+#include <signal.h>
219
+#include <ucontext.h>
220
+#include <asm/unistd.h>
221
+
222
+int main(void);
223
+
224
+void _start(void)
225
+{
226
+ exit(main());
227
+}
228
+
229
+void exit(int ret)
230
+{
231
+ register int x0 __asm__("x0") = ret;
232
+ register int x8 __asm__("x8") = __NR_exit;
233
+
234
+ asm volatile("svc #0" : : "r"(x0), "r"(x8));
235
+ __builtin_unreachable();
236
+}
237
+
238
+/*
239
+ * Irritatingly, the user API struct sigaction does not match the
240
+ * kernel API struct sigaction. So for simplicity, isolate the
241
+ * kernel ABI here, and make this act like signal.
242
+ */
243
+void signal_info(int sig, void (*fn)(int, siginfo_t *, ucontext_t *))
244
+{
245
+ struct kernel_sigaction {
246
+ void (*handler)(int, siginfo_t *, ucontext_t *);
247
+ unsigned long flags;
248
+ unsigned long restorer;
249
+ unsigned long mask;
250
+ } sa = { fn, SA_SIGINFO, 0, 0 };
251
+
252
+ register int x0 __asm__("x0") = sig;
253
+ register void *x1 __asm__("x1") = &sa;
254
+ register void *x2 __asm__("x2") = 0;
255
+ register int x3 __asm__("x3") = sizeof(unsigned long);
256
+ register int x8 __asm__("x8") = __NR_rt_sigaction;
257
+
258
+ asm volatile("svc #0"
259
+ : : "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x8) : "memory");
260
+}
261
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
262
index XXXXXXX..XXXXXXX 100644
263
--- a/tests/tcg/aarch64/Makefile.target
264
+++ b/tests/tcg/aarch64/Makefile.target
265
@@ -XXX,XX +XXX,XX @@ run-pauth-%: QEMU_OPTS += -cpu max
266
run-plugin-pauth-%: QEMU_OPTS += -cpu max
267
endif
268
269
+# BTI Tests
270
+# bti-1 tests the elf notes, so we require special compiler support.
271
+ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_ARMV8_BTI),)
272
+AARCH64_TESTS += bti-1
273
+bti-1: CFLAGS += -mbranch-protection=standard
274
+bti-1: LDFLAGS += -nostdlib
275
+endif
276
+# bti-2 tests PROT_BTI, so no special compiler support required.
277
+AARCH64_TESTS += bti-2
278
+
279
# Semihosting smoke test for linux-user
280
AARCH64_TESTS += semihosting
281
run-semihosting: semihosting
282
diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
283
index XXXXXXX..XXXXXXX 100755
284
--- a/tests/tcg/configure.sh
285
+++ b/tests/tcg/configure.sh
286
@@ -XXX,XX +XXX,XX @@ for target in $target_list; do
287
-march=armv8.3-a -o $TMPE $TMPC; then
288
echo "CROSS_CC_HAS_ARMV8_3=y" >> $config_target_mak
289
fi
290
+ if do_compiler "$target_compiler" $target_compiler_cflags \
291
+ -mbranch-protection=standard -o $TMPE $TMPC; then
292
+ echo "CROSS_CC_HAS_ARMV8_BTI=y" >> $config_target_mak
293
+ fi
294
;;
295
esac
296
57
297
--
58
--
298
2.20.1
59
2.20.1
299
60
300
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
On ARM, the Top Byte Ignore feature means that only 56 bits of
3
When running device-introspect-test, a memory leak occurred in the a10_pit_init
4
the address are significant in the virtual address. We are
4
function, so use ptimer_free() in the finalize function to avoid it.
5
required to give the entire 64-bit address to FAR_ELx on fault,
6
which means that we do not "clean" the top byte early in TCG.
7
5
8
This new interface allows us to flush all 256 possible aliases
6
ASAN shows memory leak stack:
9
for a given page, currently missed by tlb_flush_page*.
10
7
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Indirect leak of 288 byte(s) in 6 object(s) allocated from:
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
10
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
11
#2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523
12
#3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544
13
#4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562
14
#5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433
15
#6 0xaaabf57415e8 in a10_pit_init /qemu/hw/timer/allwinner-a10-pit.c:278
16
#7 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
17
#8 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564
18
#9 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547
19
#10 0xaaabf5b94680 in aw_a10_init /qemu/hw/arm/allwinner-a10.c:49
20
#11 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
21
#12 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
22
23
Reported-by: Euler Robot <euler.robot@huawei.com>
24
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20201016210754.818257-2-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
27
---
17
include/exec/exec-all.h | 36 ++++++
28
hw/timer/allwinner-a10-pit.c | 11 +++++++++++
18
accel/tcg/cputlb.c | 275 ++++++++++++++++++++++++++++++++++++++--
29
1 file changed, 11 insertions(+)
19
2 files changed, 302 insertions(+), 9 deletions(-)
20
30
21
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
31
diff --git a/hw/timer/allwinner-a10-pit.c b/hw/timer/allwinner-a10-pit.c
22
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
23
--- a/include/exec/exec-all.h
33
--- a/hw/timer/allwinner-a10-pit.c
24
+++ b/include/exec/exec-all.h
34
+++ b/hw/timer/allwinner-a10-pit.c
25
@@ -XXX,XX +XXX,XX @@ void tlb_flush_by_mmuidx_all_cpus(CPUState *cpu, uint16_t idxmap);
35
@@ -XXX,XX +XXX,XX @@ static void a10_pit_init(Object *obj)
26
* depend on when the guests translation ends the TB.
27
*/
28
void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu, uint16_t idxmap);
29
+
30
+/**
31
+ * tlb_flush_page_bits_by_mmuidx
32
+ * @cpu: CPU whose TLB should be flushed
33
+ * @addr: virtual address of page to be flushed
34
+ * @idxmap: bitmap of mmu indexes to flush
35
+ * @bits: number of significant bits in address
36
+ *
37
+ * Similar to tlb_flush_page_mask, but with a bitmap of indexes.
38
+ */
39
+void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
40
+ uint16_t idxmap, unsigned bits);
41
+
42
+/* Similarly, with broadcast and syncing. */
43
+void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *cpu, target_ulong addr,
44
+ uint16_t idxmap, unsigned bits);
45
+void tlb_flush_page_bits_by_mmuidx_all_cpus_synced
46
+ (CPUState *cpu, target_ulong addr, uint16_t idxmap, unsigned bits);
47
+
48
/**
49
* tlb_set_page_with_attrs:
50
* @cpu: CPU to add this TLB entry for
51
@@ -XXX,XX +XXX,XX @@ static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
52
uint16_t idxmap)
53
{
54
}
55
+static inline void tlb_flush_page_bits_by_mmuidx(CPUState *cpu,
56
+ target_ulong addr,
57
+ uint16_t idxmap,
58
+ unsigned bits)
59
+{
60
+}
61
+static inline void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *cpu,
62
+ target_ulong addr,
63
+ uint16_t idxmap,
64
+ unsigned bits)
65
+{
66
+}
67
+static inline void
68
+tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *cpu, target_ulong addr,
69
+ uint16_t idxmap, unsigned bits)
70
+{
71
+}
72
#endif
73
/**
74
* probe_access:
75
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/accel/tcg/cputlb.c
78
+++ b/accel/tcg/cputlb.c
79
@@ -XXX,XX +XXX,XX @@ void tlb_flush_all_cpus_synced(CPUState *src_cpu)
80
tlb_flush_by_mmuidx_all_cpus_synced(src_cpu, ALL_MMUIDX_BITS);
81
}
82
83
+static bool tlb_hit_page_mask_anyprot(CPUTLBEntry *tlb_entry,
84
+ target_ulong page, target_ulong mask)
85
+{
86
+ page &= mask;
87
+ mask &= TARGET_PAGE_MASK | TLB_INVALID_MASK;
88
+
89
+ return (page == (tlb_entry->addr_read & mask) ||
90
+ page == (tlb_addr_write(tlb_entry) & mask) ||
91
+ page == (tlb_entry->addr_code & mask));
92
+}
93
+
94
static inline bool tlb_hit_page_anyprot(CPUTLBEntry *tlb_entry,
95
target_ulong page)
96
{
97
- return tlb_hit_page(tlb_entry->addr_read, page) ||
98
- tlb_hit_page(tlb_addr_write(tlb_entry), page) ||
99
- tlb_hit_page(tlb_entry->addr_code, page);
100
+ return tlb_hit_page_mask_anyprot(tlb_entry, page, -1);
101
}
102
103
/**
104
@@ -XXX,XX +XXX,XX @@ static inline bool tlb_entry_is_empty(const CPUTLBEntry *te)
105
}
106
107
/* Called with tlb_c.lock held */
108
-static inline bool tlb_flush_entry_locked(CPUTLBEntry *tlb_entry,
109
- target_ulong page)
110
+static bool tlb_flush_entry_mask_locked(CPUTLBEntry *tlb_entry,
111
+ target_ulong page,
112
+ target_ulong mask)
113
{
114
- if (tlb_hit_page_anyprot(tlb_entry, page)) {
115
+ if (tlb_hit_page_mask_anyprot(tlb_entry, page, mask)) {
116
memset(tlb_entry, -1, sizeof(*tlb_entry));
117
return true;
118
}
119
return false;
120
}
121
122
+static inline bool tlb_flush_entry_locked(CPUTLBEntry *tlb_entry,
123
+ target_ulong page)
124
+{
125
+ return tlb_flush_entry_mask_locked(tlb_entry, page, -1);
126
+}
127
+
128
/* Called with tlb_c.lock held */
129
-static inline void tlb_flush_vtlb_page_locked(CPUArchState *env, int mmu_idx,
130
- target_ulong page)
131
+static void tlb_flush_vtlb_page_mask_locked(CPUArchState *env, int mmu_idx,
132
+ target_ulong page,
133
+ target_ulong mask)
134
{
135
CPUTLBDesc *d = &env_tlb(env)->d[mmu_idx];
136
int k;
137
138
assert_cpu_is_self(env_cpu(env));
139
for (k = 0; k < CPU_VTLB_SIZE; k++) {
140
- if (tlb_flush_entry_locked(&d->vtable[k], page)) {
141
+ if (tlb_flush_entry_mask_locked(&d->vtable[k], page, mask)) {
142
tlb_n_used_entries_dec(env, mmu_idx);
143
}
144
}
36
}
145
}
37
}
146
38
147
+static inline void tlb_flush_vtlb_page_locked(CPUArchState *env, int mmu_idx,
39
+static void a10_pit_finalize(Object *obj)
148
+ target_ulong page)
149
+{
40
+{
150
+ tlb_flush_vtlb_page_mask_locked(env, mmu_idx, page, -1);
41
+ AwA10PITState *s = AW_A10_PIT(obj);
151
+}
42
+ int i;
152
+
43
+
153
static void tlb_flush_page_locked(CPUArchState *env, int midx,
44
+ for (i = 0; i < AW_A10_PIT_TIMER_NR; i++) {
154
target_ulong page)
45
+ ptimer_free(s->timer[i]);
155
{
156
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_all_cpus_synced(CPUState *src, target_ulong addr)
157
tlb_flush_page_by_mmuidx_all_cpus_synced(src, addr, ALL_MMUIDX_BITS);
158
}
159
160
+static void tlb_flush_page_bits_locked(CPUArchState *env, int midx,
161
+ target_ulong page, unsigned bits)
162
+{
163
+ CPUTLBDesc *d = &env_tlb(env)->d[midx];
164
+ CPUTLBDescFast *f = &env_tlb(env)->f[midx];
165
+ target_ulong mask = MAKE_64BIT_MASK(0, bits);
166
+
167
+ /*
168
+ * If @bits is smaller than the tlb size, there may be multiple entries
169
+ * within the TLB; otherwise all addresses that match under @mask hit
170
+ * the same TLB entry.
171
+ *
172
+ * TODO: Perhaps allow bits to be a few bits less than the size.
173
+ * For now, just flush the entire TLB.
174
+ */
175
+ if (mask < f->mask) {
176
+ tlb_debug("forcing full flush midx %d ("
177
+ TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
178
+ midx, page, mask);
179
+ tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
180
+ return;
181
+ }
182
+
183
+ /* Check if we need to flush due to large pages. */
184
+ if ((page & d->large_page_mask) == d->large_page_addr) {
185
+ tlb_debug("forcing full flush midx %d ("
186
+ TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
187
+ midx, d->large_page_addr, d->large_page_mask);
188
+ tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
189
+ return;
190
+ }
191
+
192
+ if (tlb_flush_entry_mask_locked(tlb_entry(env, midx, page), page, mask)) {
193
+ tlb_n_used_entries_dec(env, midx);
194
+ }
195
+ tlb_flush_vtlb_page_mask_locked(env, midx, page, mask);
196
+}
197
+
198
+typedef struct {
199
+ target_ulong addr;
200
+ uint16_t idxmap;
201
+ uint16_t bits;
202
+} TLBFlushPageBitsByMMUIdxData;
203
+
204
+static void
205
+tlb_flush_page_bits_by_mmuidx_async_0(CPUState *cpu,
206
+ TLBFlushPageBitsByMMUIdxData d)
207
+{
208
+ CPUArchState *env = cpu->env_ptr;
209
+ int mmu_idx;
210
+
211
+ assert_cpu_is_self(cpu);
212
+
213
+ tlb_debug("page addr:" TARGET_FMT_lx "/%u mmu_map:0x%x\n",
214
+ d.addr, d.bits, d.idxmap);
215
+
216
+ qemu_spin_lock(&env_tlb(env)->c.lock);
217
+ for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
218
+ if ((d.idxmap >> mmu_idx) & 1) {
219
+ tlb_flush_page_bits_locked(env, mmu_idx, d.addr, d.bits);
220
+ }
221
+ }
222
+ qemu_spin_unlock(&env_tlb(env)->c.lock);
223
+
224
+ tb_flush_jmp_cache(cpu, d.addr);
225
+}
226
+
227
+static bool encode_pbm_to_runon(run_on_cpu_data *out,
228
+ TLBFlushPageBitsByMMUIdxData d)
229
+{
230
+ /* We need 6 bits to hold to hold @bits up to 63. */
231
+ if (d.idxmap <= MAKE_64BIT_MASK(0, TARGET_PAGE_BITS - 6)) {
232
+ *out = RUN_ON_CPU_TARGET_PTR(d.addr | (d.idxmap << 6) | d.bits);
233
+ return true;
234
+ }
235
+ return false;
236
+}
237
+
238
+static TLBFlushPageBitsByMMUIdxData
239
+decode_runon_to_pbm(run_on_cpu_data data)
240
+{
241
+ target_ulong addr_map_bits = (target_ulong) data.target_ptr;
242
+ return (TLBFlushPageBitsByMMUIdxData){
243
+ .addr = addr_map_bits & TARGET_PAGE_MASK,
244
+ .idxmap = (addr_map_bits & ~TARGET_PAGE_MASK) >> 6,
245
+ .bits = addr_map_bits & 0x3f
246
+ };
247
+}
248
+
249
+static void tlb_flush_page_bits_by_mmuidx_async_1(CPUState *cpu,
250
+ run_on_cpu_data runon)
251
+{
252
+ tlb_flush_page_bits_by_mmuidx_async_0(cpu, decode_runon_to_pbm(runon));
253
+}
254
+
255
+static void tlb_flush_page_bits_by_mmuidx_async_2(CPUState *cpu,
256
+ run_on_cpu_data data)
257
+{
258
+ TLBFlushPageBitsByMMUIdxData *d = data.host_ptr;
259
+ tlb_flush_page_bits_by_mmuidx_async_0(cpu, *d);
260
+ g_free(d);
261
+}
262
+
263
+void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
264
+ uint16_t idxmap, unsigned bits)
265
+{
266
+ TLBFlushPageBitsByMMUIdxData d;
267
+ run_on_cpu_data runon;
268
+
269
+ /* If all bits are significant, this devolves to tlb_flush_page. */
270
+ if (bits >= TARGET_LONG_BITS) {
271
+ tlb_flush_page_by_mmuidx(cpu, addr, idxmap);
272
+ return;
273
+ }
274
+ /* If no page bits are significant, this devolves to tlb_flush. */
275
+ if (bits < TARGET_PAGE_BITS) {
276
+ tlb_flush_by_mmuidx(cpu, idxmap);
277
+ return;
278
+ }
279
+
280
+ /* This should already be page aligned */
281
+ d.addr = addr & TARGET_PAGE_MASK;
282
+ d.idxmap = idxmap;
283
+ d.bits = bits;
284
+
285
+ if (qemu_cpu_is_self(cpu)) {
286
+ tlb_flush_page_bits_by_mmuidx_async_0(cpu, d);
287
+ } else if (encode_pbm_to_runon(&runon, d)) {
288
+ async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
289
+ } else {
290
+ TLBFlushPageBitsByMMUIdxData *p
291
+ = g_new(TLBFlushPageBitsByMMUIdxData, 1);
292
+
293
+ /* Otherwise allocate a structure, freed by the worker. */
294
+ *p = d;
295
+ async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_2,
296
+ RUN_ON_CPU_HOST_PTR(p));
297
+ }
46
+ }
298
+}
47
+}
299
+
48
+
300
+void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
49
static void a10_pit_class_init(ObjectClass *klass, void *data)
301
+ target_ulong addr,
50
{
302
+ uint16_t idxmap,
51
DeviceClass *dc = DEVICE_CLASS(klass);
303
+ unsigned bits)
52
@@ -XXX,XX +XXX,XX @@ static const TypeInfo a10_pit_info = {
304
+{
53
.parent = TYPE_SYS_BUS_DEVICE,
305
+ TLBFlushPageBitsByMMUIdxData d;
54
.instance_size = sizeof(AwA10PITState),
306
+ run_on_cpu_data runon;
55
.instance_init = a10_pit_init,
307
+
56
+ .instance_finalize = a10_pit_finalize,
308
+ /* If all bits are significant, this devolves to tlb_flush_page. */
57
.class_init = a10_pit_class_init,
309
+ if (bits >= TARGET_LONG_BITS) {
58
};
310
+ tlb_flush_page_by_mmuidx_all_cpus(src_cpu, addr, idxmap);
59
311
+ return;
312
+ }
313
+ /* If no page bits are significant, this devolves to tlb_flush. */
314
+ if (bits < TARGET_PAGE_BITS) {
315
+ tlb_flush_by_mmuidx_all_cpus(src_cpu, idxmap);
316
+ return;
317
+ }
318
+
319
+ /* This should already be page aligned */
320
+ d.addr = addr & TARGET_PAGE_MASK;
321
+ d.idxmap = idxmap;
322
+ d.bits = bits;
323
+
324
+ if (encode_pbm_to_runon(&runon, d)) {
325
+ flush_all_helper(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
326
+ } else {
327
+ CPUState *dst_cpu;
328
+ TLBFlushPageBitsByMMUIdxData *p;
329
+
330
+ /* Allocate a separate data block for each destination cpu. */
331
+ CPU_FOREACH(dst_cpu) {
332
+ if (dst_cpu != src_cpu) {
333
+ p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
334
+ *p = d;
335
+ async_run_on_cpu(dst_cpu,
336
+ tlb_flush_page_bits_by_mmuidx_async_2,
337
+ RUN_ON_CPU_HOST_PTR(p));
338
+ }
339
+ }
340
+ }
341
+
342
+ tlb_flush_page_bits_by_mmuidx_async_0(src_cpu, d);
343
+}
344
+
345
+void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
346
+ target_ulong addr,
347
+ uint16_t idxmap,
348
+ unsigned bits)
349
+{
350
+ TLBFlushPageBitsByMMUIdxData d;
351
+ run_on_cpu_data runon;
352
+
353
+ /* If all bits are significant, this devolves to tlb_flush_page. */
354
+ if (bits >= TARGET_LONG_BITS) {
355
+ tlb_flush_page_by_mmuidx_all_cpus_synced(src_cpu, addr, idxmap);
356
+ return;
357
+ }
358
+ /* If no page bits are significant, this devolves to tlb_flush. */
359
+ if (bits < TARGET_PAGE_BITS) {
360
+ tlb_flush_by_mmuidx_all_cpus_synced(src_cpu, idxmap);
361
+ return;
362
+ }
363
+
364
+ /* This should already be page aligned */
365
+ d.addr = addr & TARGET_PAGE_MASK;
366
+ d.idxmap = idxmap;
367
+ d.bits = bits;
368
+
369
+ if (encode_pbm_to_runon(&runon, d)) {
370
+ flush_all_helper(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
371
+ async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1,
372
+ runon);
373
+ } else {
374
+ CPUState *dst_cpu;
375
+ TLBFlushPageBitsByMMUIdxData *p;
376
+
377
+ /* Allocate a separate data block for each destination cpu. */
378
+ CPU_FOREACH(dst_cpu) {
379
+ if (dst_cpu != src_cpu) {
380
+ p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
381
+ *p = d;
382
+ async_run_on_cpu(dst_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
383
+ RUN_ON_CPU_HOST_PTR(p));
384
+ }
385
+ }
386
+
387
+ p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
388
+ *p = d;
389
+ async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
390
+ RUN_ON_CPU_HOST_PTR(p));
391
+ }
392
+}
393
+
394
/* update the TLBs so that writes to code in the virtual page 'addr'
395
can be detected */
396
void tlb_protect_code(ram_addr_t ram_addr)
397
--
60
--
398
2.20.1
61
2.20.1
399
62
400
63
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
Use the new generic support for NT_GNU_PROPERTY_TYPE_0.
3
When running device-introspect-test, a memory leak occurred in the
4
exynos4210_rtc_init function, so use ptimer_free() in the finalize function to
5
avoid it.
4
6
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
ASAN shows memory leak stack:
6
Message-id: 20201016184207.786698-12-richard.henderson@linaro.org
8
9
Indirect leak of 96 byte(s) in 1 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf57b3934 in exynos4210_rtc_init /qemu/hw/rtc/exynos4210_rtc.c:567
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
16
#6 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
17
#7 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
18
#8 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
19
#9 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136
20
#10 0xaaabf6552708 in aio_bh_poll /qemu/util/async.c:164
21
#11 0xaaabf655f19c in aio_dispatch /qemu/util/aio-posix.c:381
22
#12 0xaaabf65523f4 in aio_ctx_dispatch /qemu/util/async.c:306
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
28
---
10
linux-user/elfload.c | 48 ++++++++++++++++++++++++++++++++++++++++++--
29
hw/rtc/exynos4210_rtc.c | 9 +++++++++
11
1 file changed, 46 insertions(+), 2 deletions(-)
30
1 file changed, 9 insertions(+)
12
31
13
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
32
diff --git a/hw/rtc/exynos4210_rtc.c b/hw/rtc/exynos4210_rtc.c
14
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/elfload.c
34
--- a/hw/rtc/exynos4210_rtc.c
16
+++ b/linux-user/elfload.c
35
+++ b/hw/rtc/exynos4210_rtc.c
17
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
36
@@ -XXX,XX +XXX,XX @@ static void exynos4210_rtc_init(Object *obj)
18
37
sysbus_init_mmio(dev, &s->iomem);
19
#include "elf.h"
38
}
20
39
21
+/* We must delay the following stanzas until after "elf.h". */
40
+static void exynos4210_rtc_finalize(Object *obj)
22
+#if defined(TARGET_AARCH64)
41
+{
42
+ Exynos4210RTCState *s = EXYNOS4210_RTC(obj);
23
+
43
+
24
+static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
44
+ ptimer_free(s->ptimer);
25
+ const uint32_t *data,
45
+ ptimer_free(s->ptimer_1Hz);
26
+ struct image_info *info,
27
+ Error **errp)
28
+{
29
+ if (pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) {
30
+ if (pr_datasz != sizeof(uint32_t)) {
31
+ error_setg(errp, "Ill-formed GNU_PROPERTY_AARCH64_FEATURE_1_AND");
32
+ return false;
33
+ }
34
+ /* We will extract GNU_PROPERTY_AARCH64_FEATURE_1_BTI later. */
35
+ info->note_flags = *data;
36
+ }
37
+ return true;
38
+}
46
+}
39
+#define ARCH_USE_GNU_PROPERTY 1
40
+
47
+
41
+#else
48
static void exynos4210_rtc_class_init(ObjectClass *klass, void *data)
42
+
43
static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
44
const uint32_t *data,
45
struct image_info *info,
46
@@ -XXX,XX +XXX,XX @@ static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
47
}
48
#define ARCH_USE_GNU_PROPERTY 0
49
50
+#endif
51
+
52
struct exec
53
{
49
{
54
unsigned int a_info; /* Use macros N_MAGIC, etc for access */
50
DeviceClass *dc = DEVICE_CLASS(klass);
55
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
51
@@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_rtc_info = {
56
struct elfhdr *ehdr = (struct elfhdr *)bprm_buf;
52
.parent = TYPE_SYS_BUS_DEVICE,
57
struct elf_phdr *phdr;
53
.instance_size = sizeof(Exynos4210RTCState),
58
abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
54
.instance_init = exynos4210_rtc_init,
59
- int i, retval;
55
+ .instance_finalize = exynos4210_rtc_finalize,
60
+ int i, retval, prot_exec;
56
.class_init = exynos4210_rtc_class_init,
61
Error *err = NULL;
57
};
62
58
63
/* First of all, some simple consistency checks */
64
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
65
info->brk = 0;
66
info->elf_flags = ehdr->e_flags;
67
68
+ prot_exec = PROT_EXEC;
69
+#ifdef TARGET_AARCH64
70
+ /*
71
+ * If the BTI feature is present, this indicates that the executable
72
+ * pages of the startup binary should be mapped with PROT_BTI, so that
73
+ * branch targets are enforced.
74
+ *
75
+ * The startup binary is either the interpreter or the static executable.
76
+ * The interpreter is responsible for all pages of a dynamic executable.
77
+ *
78
+ * Elf notes are backward compatible to older cpus.
79
+ * Do not enable BTI unless it is supported.
80
+ */
81
+ if ((info->note_flags & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
82
+ && (pinterp_name == NULL || *pinterp_name == 0)
83
+ && cpu_isar_feature(aa64_bti, ARM_CPU(thread_cpu))) {
84
+ prot_exec |= TARGET_PROT_BTI;
85
+ }
86
+#endif
87
+
88
for (i = 0; i < ehdr->e_phnum; i++) {
89
struct elf_phdr *eppnt = phdr + i;
90
if (eppnt->p_type == PT_LOAD) {
91
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
92
elf_prot |= PROT_WRITE;
93
}
94
if (eppnt->p_flags & PF_X) {
95
- elf_prot |= PROT_EXEC;
96
+ elf_prot |= prot_exec;
97
}
98
99
vaddr = load_bias + eppnt->p_vaddr;
100
--
59
--
101
2.20.1
60
2.20.1
102
61
103
62
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
This is generic support, with the code disabled for all targets.
3
When running device-introspect-test, a memory leak occurred in the
4
exynos4210_pwm_init function, so use ptimer_free() in the finalize function to
5
avoid it.
4
6
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
ASAN shows memory leak stack:
6
Message-id: 20201016184207.786698-11-richard.henderson@linaro.org
8
9
Indirect leak of 240 byte(s) in 5 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523
13
#3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544
14
#4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562
15
#5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433
16
#6 0xaaabf56a36cc in exynos4210_pwm_init /qemu/hw/timer/exynos4210_pwm.c:401
17
#7 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
18
#8 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
19
#9 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
20
#10 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
21
#11 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
22
#12 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
28
---
10
linux-user/qemu.h | 4 ++
29
hw/timer/exynos4210_pwm.c | 11 +++++++++++
11
linux-user/elfload.c | 157 +++++++++++++++++++++++++++++++++++++++++++
30
1 file changed, 11 insertions(+)
12
2 files changed, 161 insertions(+)
13
31
14
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
32
diff --git a/hw/timer/exynos4210_pwm.c b/hw/timer/exynos4210_pwm.c
15
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/qemu.h
34
--- a/hw/timer/exynos4210_pwm.c
17
+++ b/linux-user/qemu.h
35
+++ b/hw/timer/exynos4210_pwm.c
18
@@ -XXX,XX +XXX,XX @@ struct image_info {
36
@@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_init(Object *obj)
19
abi_ulong interpreter_loadmap_addr;
37
sysbus_init_mmio(dev, &s->iomem);
20
abi_ulong interpreter_pt_dynamic_addr;
38
}
21
struct image_info *other_info;
39
40
+static void exynos4210_pwm_finalize(Object *obj)
41
+{
42
+ Exynos4210PWMState *s = EXYNOS4210_PWM(obj);
43
+ int i;
22
+
44
+
23
+ /* For target-specific processing of NT_GNU_PROPERTY_TYPE_0. */
45
+ for (i = 0; i < EXYNOS4210_PWM_TIMERS_NUM; i++) {
24
+ uint32_t note_flags;
46
+ ptimer_free(s->timer[i].ptimer);
25
+
26
#ifdef TARGET_MIPS
27
int fp_abi;
28
int interp_fp_abi;
29
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/linux-user/elfload.c
32
+++ b/linux-user/elfload.c
33
@@ -XXX,XX +XXX,XX @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
34
35
#include "elf.h"
36
37
+static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
38
+ const uint32_t *data,
39
+ struct image_info *info,
40
+ Error **errp)
41
+{
42
+ g_assert_not_reached();
43
+}
44
+#define ARCH_USE_GNU_PROPERTY 0
45
+
46
struct exec
47
{
48
unsigned int a_info; /* Use macros N_MAGIC, etc for access */
49
@@ -XXX,XX +XXX,XX @@ void probe_guest_base(const char *image_name, abi_ulong guest_loaddr,
50
"@ 0x%" PRIx64 "\n", (uint64_t)guest_base);
51
}
52
53
+enum {
54
+ /* The string "GNU\0" as a magic number. */
55
+ GNU0_MAGIC = const_le32('G' | 'N' << 8 | 'U' << 16),
56
+ NOTE_DATA_SZ = 1 * KiB,
57
+ NOTE_NAME_SZ = 4,
58
+ ELF_GNU_PROPERTY_ALIGN = ELF_CLASS == ELFCLASS32 ? 4 : 8,
59
+};
60
+
61
+/*
62
+ * Process a single gnu_property entry.
63
+ * Return false for error.
64
+ */
65
+static bool parse_elf_property(const uint32_t *data, int *off, int datasz,
66
+ struct image_info *info, bool have_prev_type,
67
+ uint32_t *prev_type, Error **errp)
68
+{
69
+ uint32_t pr_type, pr_datasz, step;
70
+
71
+ if (*off > datasz || !QEMU_IS_ALIGNED(*off, ELF_GNU_PROPERTY_ALIGN)) {
72
+ goto error_data;
73
+ }
74
+ datasz -= *off;
75
+ data += *off / sizeof(uint32_t);
76
+
77
+ if (datasz < 2 * sizeof(uint32_t)) {
78
+ goto error_data;
79
+ }
80
+ pr_type = data[0];
81
+ pr_datasz = data[1];
82
+ data += 2;
83
+ datasz -= 2 * sizeof(uint32_t);
84
+ step = ROUND_UP(pr_datasz, ELF_GNU_PROPERTY_ALIGN);
85
+ if (step > datasz) {
86
+ goto error_data;
87
+ }
88
+
89
+ /* Properties are supposed to be unique and sorted on pr_type. */
90
+ if (have_prev_type && pr_type <= *prev_type) {
91
+ if (pr_type == *prev_type) {
92
+ error_setg(errp, "Duplicate property in PT_GNU_PROPERTY");
93
+ } else {
94
+ error_setg(errp, "Unsorted property in PT_GNU_PROPERTY");
95
+ }
96
+ return false;
97
+ }
98
+ *prev_type = pr_type;
99
+
100
+ if (!arch_parse_elf_property(pr_type, pr_datasz, data, info, errp)) {
101
+ return false;
102
+ }
103
+
104
+ *off += 2 * sizeof(uint32_t) + step;
105
+ return true;
106
+
107
+ error_data:
108
+ error_setg(errp, "Ill-formed property in PT_GNU_PROPERTY");
109
+ return false;
110
+}
111
+
112
+/* Process NT_GNU_PROPERTY_TYPE_0. */
113
+static bool parse_elf_properties(int image_fd,
114
+ struct image_info *info,
115
+ const struct elf_phdr *phdr,
116
+ char bprm_buf[BPRM_BUF_SIZE],
117
+ Error **errp)
118
+{
119
+ union {
120
+ struct elf_note nhdr;
121
+ uint32_t data[NOTE_DATA_SZ / sizeof(uint32_t)];
122
+ } note;
123
+
124
+ int n, off, datasz;
125
+ bool have_prev_type;
126
+ uint32_t prev_type;
127
+
128
+ /* Unless the arch requires properties, ignore them. */
129
+ if (!ARCH_USE_GNU_PROPERTY) {
130
+ return true;
131
+ }
132
+
133
+ /* If the properties are crazy large, that's too bad. */
134
+ n = phdr->p_filesz;
135
+ if (n > sizeof(note)) {
136
+ error_setg(errp, "PT_GNU_PROPERTY too large");
137
+ return false;
138
+ }
139
+ if (n < sizeof(note.nhdr)) {
140
+ error_setg(errp, "PT_GNU_PROPERTY too small");
141
+ return false;
142
+ }
143
+
144
+ if (phdr->p_offset + n <= BPRM_BUF_SIZE) {
145
+ memcpy(&note, bprm_buf + phdr->p_offset, n);
146
+ } else {
147
+ ssize_t len = pread(image_fd, &note, n, phdr->p_offset);
148
+ if (len != n) {
149
+ error_setg_errno(errp, errno, "Error reading file header");
150
+ return false;
151
+ }
152
+ }
153
+
154
+ /*
155
+ * The contents of a valid PT_GNU_PROPERTY is a sequence
156
+ * of uint32_t -- swap them all now.
157
+ */
158
+#ifdef BSWAP_NEEDED
159
+ for (int i = 0; i < n / 4; i++) {
160
+ bswap32s(note.data + i);
161
+ }
162
+#endif
163
+
164
+ /*
165
+ * Note that nhdr is 3 words, and that the "name" described by namesz
166
+ * immediately follows nhdr and is thus at the 4th word. Further, all
167
+ * of the inputs to the kernel's round_up are multiples of 4.
168
+ */
169
+ if (note.nhdr.n_type != NT_GNU_PROPERTY_TYPE_0 ||
170
+ note.nhdr.n_namesz != NOTE_NAME_SZ ||
171
+ note.data[3] != GNU0_MAGIC) {
172
+ error_setg(errp, "Invalid note in PT_GNU_PROPERTY");
173
+ return false;
174
+ }
175
+ off = sizeof(note.nhdr) + NOTE_NAME_SZ;
176
+
177
+ datasz = note.nhdr.n_descsz + off;
178
+ if (datasz > n) {
179
+ error_setg(errp, "Invalid note size in PT_GNU_PROPERTY");
180
+ return false;
181
+ }
182
+
183
+ have_prev_type = false;
184
+ prev_type = 0;
185
+ while (1) {
186
+ if (off == datasz) {
187
+ return true; /* end, exit ok */
188
+ }
189
+ if (!parse_elf_property(note.data, &off, datasz, info,
190
+ have_prev_type, &prev_type, errp)) {
191
+ return false;
192
+ }
193
+ have_prev_type = true;
194
+ }
47
+ }
195
+}
48
+}
196
+
49
+
197
/* Load an ELF image into the address space.
50
static void exynos4210_pwm_class_init(ObjectClass *klass, void *data)
198
51
{
199
IMAGE_NAME is the filename of the image, to use in error messages.
52
DeviceClass *dc = DEVICE_CLASS(klass);
200
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
53
@@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_pwm_info = {
201
goto exit_errmsg;
54
.parent = TYPE_SYS_BUS_DEVICE,
202
}
55
.instance_size = sizeof(Exynos4210PWMState),
203
*pinterp_name = g_steal_pointer(&interp_name);
56
.instance_init = exynos4210_pwm_init,
204
+ } else if (eppnt->p_type == PT_GNU_PROPERTY) {
57
+ .instance_finalize = exynos4210_pwm_finalize,
205
+ if (!parse_elf_properties(image_fd, info, eppnt, bprm_buf, &err)) {
58
.class_init = exynos4210_pwm_class_init,
206
+ goto exit_errmsg;
59
};
207
+ }
208
}
209
}
210
60
211
--
61
--
212
2.20.1
62
2.20.1
213
63
214
64
diff view generated by jsdifflib
1
From: Peng Liang <liangpeng10@huawei.com>
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
VMStateDescription.fields should be end with VMSTATE_END_OF_LIST().
3
When running device-introspect-test, a memory leak occurred in the
4
However, microbit_i2c_vmstate doesn't follow it. Let's change it.
4
mss_timer_init function, so use ptimer_free() in the finalize function to avoid
5
it.
5
6
6
Fixes: 9d68bf564e ("arm: Stub out NRF51 TWI magnetometer/accelerometer detection")
7
ASAN shows memory leak stack:
8
9
Indirect leak of 192 byte(s) in 2 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf58a0010 in mss_timer_init /qemu/hw/timer/mss-timer.c:235
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564
16
#6 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547
17
#7 0xaaabf5b8316c in m2sxxx_soc_initfn /qemu/hw/arm/msf2-soc.c:70
18
#8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
19
#9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
20
#10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
21
#11 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
22
#12 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
23
7
Reported-by: Euler Robot <euler.robot@huawei.com>
24
Reported-by: Euler Robot <euler.robot@huawei.com>
8
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20201019093401.2993833-1-liangpeng10@huawei.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
28
---
13
hw/i2c/microbit_i2c.c | 1 +
29
hw/timer/mss-timer.c | 13 +++++++++++++
14
1 file changed, 1 insertion(+)
30
1 file changed, 13 insertions(+)
15
31
16
diff --git a/hw/i2c/microbit_i2c.c b/hw/i2c/microbit_i2c.c
32
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
17
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/i2c/microbit_i2c.c
34
--- a/hw/timer/mss-timer.c
19
+++ b/hw/i2c/microbit_i2c.c
35
+++ b/hw/timer/mss-timer.c
20
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription microbit_i2c_vmstate = {
36
@@ -XXX,XX +XXX,XX @@ static void mss_timer_init(Object *obj)
21
.fields = (VMStateField[]) {
37
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &t->mmio);
22
VMSTATE_UINT32_ARRAY(regs, MicrobitI2CState, MICROBIT_I2C_NREGS),
38
}
23
VMSTATE_UINT32(read_idx, MicrobitI2CState),
39
24
+ VMSTATE_END_OF_LIST()
40
+static void mss_timer_finalize(Object *obj)
25
},
41
+{
42
+ MSSTimerState *t = MSS_TIMER(obj);
43
+ int i;
44
+
45
+ for (i = 0; i < NUM_TIMERS; i++) {
46
+ struct Msf2Timer *st = &t->timers[i];
47
+
48
+ ptimer_free(st->ptimer);
49
+ }
50
+}
51
+
52
static const VMStateDescription vmstate_timers = {
53
.name = "mss-timer-block",
54
.version_id = 1,
55
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mss_timer_info = {
56
.parent = TYPE_SYS_BUS_DEVICE,
57
.instance_size = sizeof(MSSTimerState),
58
.instance_init = mss_timer_init,
59
+ .instance_finalize = mss_timer_finalize,
60
.class_init = mss_timer_class_init,
26
};
61
};
27
62
28
--
63
--
29
2.20.1
64
2.20.1
30
65
31
66
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
The IRQ values are defined few lines earlier, use them instead of
3
When running device-introspect-test, a memory leak occurred in the
4
the magic numbers.
4
mv88w8618_pit_init function, so use ptimer_free() in the finalize function to
5
avoid it.
5
6
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
ASAN shows memory leak stack:
7
Message-id: 20201017180731.1165871-3-f4bug@amsat.org
8
9
Indirect leak of 192 byte(s) in 4 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523
13
#3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544
14
#4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562
15
#5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433
16
#6 0xaaabf5bb2290 in mv88w8618_timer_init /qemu/hw/arm/musicpal.c:862
17
#7 0xaaabf5bb2290 in mv88w8618_pit_init /qemu/hw/arm/musicpal.c:954
18
#8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
19
#9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
20
#10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
21
#11 0xaaabf5a95540 in qdev_device_help /qemu/softmmu/qdev-monitor.c:283
22
#12 0xaaabf5a96940 in qmp_device_add /qemu/softmmu/qdev-monitor.c:801
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
28
---
11
hw/intc/bcm2836_control.c | 8 ++++----
29
hw/arm/musicpal.c | 12 ++++++++++++
12
1 file changed, 4 insertions(+), 4 deletions(-)
30
1 file changed, 12 insertions(+)
13
31
14
diff --git a/hw/intc/bcm2836_control.c b/hw/intc/bcm2836_control.c
32
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
15
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/bcm2836_control.c
34
--- a/hw/arm/musicpal.c
17
+++ b/hw/intc/bcm2836_control.c
35
+++ b/hw/arm/musicpal.c
18
@@ -XXX,XX +XXX,XX @@ static void bcm2836_control_set_local_irq(void *opaque, int core, int local_irq,
36
@@ -XXX,XX +XXX,XX @@ static void mv88w8618_pit_init(Object *obj)
19
37
sysbus_init_mmio(dev, &s->iomem);
20
static void bcm2836_control_set_local_irq0(void *opaque, int core, int level)
21
{
22
- bcm2836_control_set_local_irq(opaque, core, 0, level);
23
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTPSIRQ, level);
24
}
38
}
25
39
26
static void bcm2836_control_set_local_irq1(void *opaque, int core, int level)
40
+static void mv88w8618_pit_finalize(Object *obj)
27
{
41
+{
28
- bcm2836_control_set_local_irq(opaque, core, 1, level);
42
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
29
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTPNSIRQ, level);
43
+ mv88w8618_pit_state *s = MV88W8618_PIT(dev);
30
}
44
+ int i;
31
45
+
32
static void bcm2836_control_set_local_irq2(void *opaque, int core, int level)
46
+ for (i = 0; i < 4; i++) {
33
{
47
+ ptimer_free(s->timer[i].ptimer);
34
- bcm2836_control_set_local_irq(opaque, core, 2, level);
48
+ }
35
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTHPIRQ, level);
49
+}
36
}
50
+
37
51
static const VMStateDescription mv88w8618_timer_vmsd = {
38
static void bcm2836_control_set_local_irq3(void *opaque, int core, int level)
52
.name = "timer",
39
{
53
.version_id = 1,
40
- bcm2836_control_set_local_irq(opaque, core, 3, level);
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mv88w8618_pit_info = {
41
+ bcm2836_control_set_local_irq(opaque, core, IRQ_CNTVIRQ, level);
55
.parent = TYPE_SYS_BUS_DEVICE,
42
}
56
.instance_size = sizeof(mv88w8618_pit_state),
43
57
.instance_init = mv88w8618_pit_init,
44
static void bcm2836_control_set_gpu_irq(void *opaque, int irq, int level)
58
+ .instance_finalize = mv88w8618_pit_finalize,
59
.class_init = mv88w8618_pit_class_init,
60
};
61
45
--
62
--
46
2.20.1
63
2.20.1
47
64
48
65
diff view generated by jsdifflib
1
From: Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
Current documentation is not too clear on the GETPC usage.
3
When running device-introspect-test, a memory leak occurred in the
4
In particular, when used outside the top level helper function
4
exynos4210_mct_init function, so use ptimer_free() in the finalize function to
5
it causes unexpected behavior.
5
avoid it.
6
6
7
Signed-off-by: Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
7
ASAN shows memory leak stack:
8
Message-id: 20201015095147.1691-1-e.emanuelegiuseppe@gmail.com
8
9
Indirect leak of 96 byte(s) in 1 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf56b01a0 in exynos4210_mct_init /qemu/hw/timer/exynos4210_mct.c:1505
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
16
#6 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
17
#7 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
18
#8 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
19
#9 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136
20
#10 0xaaabf6552708 in aio_bh_poll /qemu/util/async.c:164
21
#11 0xaaabf655f19c in aio_dispatch /qemu/util/aio-posix.c:381
22
#12 0xaaabf65523f4 in aio_ctx_dispatch /qemu/util/async.c:306
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
28
---
12
docs/devel/loads-stores.rst | 8 +++++++-
29
hw/timer/exynos4210_mct.c | 14 ++++++++++++++
13
1 file changed, 7 insertions(+), 1 deletion(-)
30
1 file changed, 14 insertions(+)
14
31
15
diff --git a/docs/devel/loads-stores.rst b/docs/devel/loads-stores.rst
32
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
16
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
17
--- a/docs/devel/loads-stores.rst
34
--- a/hw/timer/exynos4210_mct.c
18
+++ b/docs/devel/loads-stores.rst
35
+++ b/hw/timer/exynos4210_mct.c
19
@@ -XXX,XX +XXX,XX @@ guest CPU state in case of a guest CPU exception. This is passed
36
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_init(Object *obj)
20
to ``cpu_restore_state()``. Therefore the value should either be 0,
37
sysbus_init_mmio(dev, &s->iomem);
21
to indicate that the guest CPU state is already synchronized, or
38
}
22
the result of ``GETPC()`` from the top level ``HELPER(foo)``
39
23
-function, which is a return address into the generated code.
40
+static void exynos4210_mct_finalize(Object *obj)
24
+function, which is a return address into the generated code [#gpc]_.
41
+{
42
+ int i;
43
+ Exynos4210MCTState *s = EXYNOS4210_MCT(obj);
25
+
44
+
26
+.. [#gpc] Note that ``GETPC()`` should be used with great care: calling
45
+ ptimer_free(s->g_timer.ptimer_frc);
27
+ it in other functions that are *not* the top level
46
+
28
+ ``HELPER(foo)`` will cause unexpected behavior. Instead, the
47
+ for (i = 0; i < 2; i++) {
29
+ value of ``GETPC()`` should be read from the helper and passed
48
+ ptimer_free(s->l_timer[i].tick_timer.ptimer_tick);
30
+ if needed to the functions that the helper calls.
49
+ ptimer_free(s->l_timer[i].ptimer_frc);
31
50
+ }
32
Function names follow the pattern:
51
+}
52
+
53
static void exynos4210_mct_class_init(ObjectClass *klass, void *data)
54
{
55
DeviceClass *dc = DEVICE_CLASS(klass);
56
@@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_mct_info = {
57
.parent = TYPE_SYS_BUS_DEVICE,
58
.instance_size = sizeof(Exynos4210MCTState),
59
.instance_init = exynos4210_mct_init,
60
+ .instance_finalize = exynos4210_mct_finalize,
61
.class_init = exynos4210_mct_class_init,
62
};
33
63
34
--
64
--
35
2.20.1
65
2.20.1
36
66
37
67
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The second loop uses a loop induction variable, and the first
3
U-Boot expects PMU_MISC0 register bit 7 is set (see init_bandgap()
4
does not. Transform the first to match the second, to simplify
4
in arch/arm/mach-imx/mx6/soc.c) during boot. This bit indicates the
5
a following patch moving code between them.
5
bandgap has stabilized.
6
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
With this change, the latest upstream U-Boot (v2021.01-rc3) for imx6
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
sabrelite board (mx6qsabrelite_defconfig), with a slight change made
9
Message-id: 20201016184207.786698-7-richard.henderson@linaro.org
9
by switching CONFIG_OF_SEPARATE to CONFIG_OF_EMBED, boots to U-Boot
10
shell on QEMU with the following command:
11
12
$ qemu-system-arm -M sabrelite -smp 4 -m 1G -kernel u-boot \
13
-display none -serial null -serial stdio
14
15
Boot log below:
16
17
U-Boot 2021.01-rc3 (Dec 12 2020 - 17:40:02 +0800)
18
19
CPU: Freescale i.MX?? rev1.0 at 792 MHz
20
Reset cause: POR
21
Model: Freescale i.MX6 Quad SABRE Lite Board
22
Board: SABRE Lite
23
I2C: ready
24
DRAM: 1 GiB
25
force_idle_bus: sda=0 scl=0 sda.gp=0x5c scl.gp=0x55
26
force_idle_bus: failed to clear bus, sda=0 scl=0
27
force_idle_bus: sda=0 scl=0 sda.gp=0x6d scl.gp=0x6c
28
force_idle_bus: failed to clear bus, sda=0 scl=0
29
force_idle_bus: sda=0 scl=0 sda.gp=0xcb scl.gp=0x5
30
force_idle_bus: failed to clear bus, sda=0 scl=0
31
MMC: FSL_SDHC: 0, FSL_SDHC: 1
32
Loading Environment from MMC... *** Warning - No block device, using default environment
33
34
In: serial
35
Out: serial
36
Err: serial
37
Net: Board Net Initialization Failed
38
No ethernet found.
39
starting USB...
40
Bus usb@2184000: usb dr_mode not found
41
USB EHCI 1.00
42
Bus usb@2184200: USB EHCI 1.00
43
scanning bus usb@2184000 for devices... 1 USB Device(s) found
44
scanning bus usb@2184200 for devices... 1 USB Device(s) found
45
scanning usb for storage devices... 0 Storage Device(s) found
46
scanning usb for ethernet devices... 0 Ethernet Device(s) found
47
Hit any key to stop autoboot: 0
48
=>
49
50
Signed-off-by: Bin Meng <bin.meng@windriver.com>
51
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
52
Message-id: 20210106063504.10841-2-bmeng.cn@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
53
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
54
---
12
linux-user/elfload.c | 9 +++++----
55
hw/misc/imx6_ccm.c | 2 +-
13
1 file changed, 5 insertions(+), 4 deletions(-)
56
1 file changed, 1 insertion(+), 1 deletion(-)
14
57
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
58
diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
16
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
60
--- a/hw/misc/imx6_ccm.c
18
+++ b/linux-user/elfload.c
61
+++ b/hw/misc/imx6_ccm.c
19
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
62
@@ -XXX,XX +XXX,XX @@ static void imx6_ccm_reset(DeviceState *dev)
20
loaddr = -1, hiaddr = 0;
63
s->analog[PMU_REG_3P0] = 0x00000F74;
21
info->alignment = 0;
64
s->analog[PMU_REG_2P5] = 0x00005071;
22
for (i = 0; i < ehdr->e_phnum; ++i) {
65
s->analog[PMU_REG_CORE] = 0x00402010;
23
- if (phdr[i].p_type == PT_LOAD) {
66
- s->analog[PMU_MISC0] = 0x04000000;
24
- abi_ulong a = phdr[i].p_vaddr - phdr[i].p_offset;
67
+ s->analog[PMU_MISC0] = 0x04000080;
25
+ struct elf_phdr *eppnt = phdr + i;
68
s->analog[PMU_MISC1] = 0x00000000;
26
+ if (eppnt->p_type == PT_LOAD) {
69
s->analog[PMU_MISC2] = 0x00272727;
27
+ abi_ulong a = eppnt->p_vaddr - eppnt->p_offset;
28
if (a < loaddr) {
29
loaddr = a;
30
}
31
- a = phdr[i].p_vaddr + phdr[i].p_memsz;
32
+ a = eppnt->p_vaddr + eppnt->p_memsz;
33
if (a > hiaddr) {
34
hiaddr = a;
35
}
36
++info->nsegs;
37
- info->alignment |= phdr[i].p_align;
38
+ info->alignment |= eppnt->p_align;
39
}
40
}
41
70
42
--
71
--
43
2.20.1
72
2.20.1
44
73
45
74
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The time to transmit a char is expressed in nanoseconds, not in ticks.
3
Currently when U-Boot boots, it prints "??" for i.MX processor:
4
4
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
CPU: Freescale i.MX?? rev1.0 at 792 MHz
6
Message-id: 20201014213601.205222-1-f4bug@amsat.org
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
The register that was used to determine the silicon type is
8
undocumented in the latest IMX6DQRM (Rev. 6, 05/2020), but we
9
can refer to get_cpu_rev() in arch/arm/mach-imx/mx6/soc.c in
10
the U-Boot source codes that USB_ANALOG_DIGPROG is used.
11
12
Update its reset value to indicate i.MX6Q.
13
14
Signed-off-by: Bin Meng <bin.meng@windriver.com>
15
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
Message-id: 20210106063504.10841-3-bmeng.cn@gmail.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
18
---
10
hw/arm/strongarm.c | 2 +-
19
hw/misc/imx6_ccm.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
20
1 file changed, 1 insertion(+), 1 deletion(-)
12
21
13
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
22
diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/strongarm.c
24
--- a/hw/misc/imx6_ccm.c
16
+++ b/hw/arm/strongarm.c
25
+++ b/hw/misc/imx6_ccm.c
17
@@ -XXX,XX +XXX,XX @@ struct StrongARMUARTState {
26
@@ -XXX,XX +XXX,XX @@ static void imx6_ccm_reset(DeviceState *dev)
18
uint8_t rx_start;
27
s->analog[USB_ANALOG_USB2_VBUS_DETECT] = 0x00000004;
19
uint8_t rx_len;
28
s->analog[USB_ANALOG_USB2_CHRG_DETECT] = 0x00000000;
20
29
s->analog[USB_ANALOG_USB2_MISC] = 0x00000002;
21
- uint64_t char_transmit_time; /* time to transmit a char in ticks*/
30
- s->analog[USB_ANALOG_DIGPROG] = 0x00000000;
22
+ uint64_t char_transmit_time; /* time to transmit a char in nanoseconds */
31
+ s->analog[USB_ANALOG_DIGPROG] = 0x00630000;
23
bool wait_break_end;
32
24
QEMUTimer *rx_timeout_timer;
33
/* all PLLs need to be locked */
25
QEMUTimer *tx_timer;
34
s->analog[CCM_ANALOG_PLL_ARM] |= CCM_ANALOG_PLL_LOCK;
26
--
35
--
27
2.20.1
36
2.20.1
28
37
29
38
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
While APEI is a generic ACPI feature (usable by X86 and ARM64), only
4
the 'virt' machine uses it, by enabling the RAS Virtualization. See
5
commit 2afa8c8519: "hw/arm/virt: Introduce a RAS machine option").
6
7
Restrict the APEI tables generation code to the single user: the virt
8
machine. If another machine wants to use it, it simply has to 'select
9
ACPI_APEI' in its Kconfig.
10
11
Fixes: aa16508f1d ("ACPI: Build related register address fields via hardware error fw_cfg blob")
12
Acked-by: Michael S. Tsirkin <mst@redhat.com>
13
Reviewed-by: Dongjiu Geng <gengdongjiu@huawei.com>
14
Acked-by: Laszlo Ersek <lersek@redhat.com>
15
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Message-id: 20201008161414.2672569-1-philmd@redhat.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
default-configs/devices/arm-softmmu.mak | 1 -
21
hw/arm/Kconfig | 1 +
22
2 files changed, 1 insertion(+), 1 deletion(-)
23
24
diff --git a/default-configs/devices/arm-softmmu.mak b/default-configs/devices/arm-softmmu.mak
25
index XXXXXXX..XXXXXXX 100644
26
--- a/default-configs/devices/arm-softmmu.mak
27
+++ b/default-configs/devices/arm-softmmu.mak
28
@@ -XXX,XX +XXX,XX @@ CONFIG_FSL_IMX7=y
29
CONFIG_FSL_IMX6UL=y
30
CONFIG_SEMIHOSTING=y
31
CONFIG_ALLWINNER_H3=y
32
-CONFIG_ACPI_APEI=y
33
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/Kconfig
36
+++ b/hw/arm/Kconfig
37
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
38
select ACPI_MEMORY_HOTPLUG
39
select ACPI_HW_REDUCED
40
select ACPI_NVDIMM
41
+ select ACPI_APEI
42
43
config CHEETAH
44
bool
45
--
46
2.20.1
47
48
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Use the BCM2835_SYSTIMER_COUNT definition instead of the
4
magic '4' value.
5
6
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20201010203709.3116542-2-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/timer/bcm2835_systmr.h | 4 +++-
13
hw/timer/bcm2835_systmr.c | 3 ++-
14
2 files changed, 5 insertions(+), 2 deletions(-)
15
16
diff --git a/include/hw/timer/bcm2835_systmr.h b/include/hw/timer/bcm2835_systmr.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/timer/bcm2835_systmr.h
19
+++ b/include/hw/timer/bcm2835_systmr.h
20
@@ -XXX,XX +XXX,XX @@
21
#define TYPE_BCM2835_SYSTIMER "bcm2835-sys-timer"
22
OBJECT_DECLARE_SIMPLE_TYPE(BCM2835SystemTimerState, BCM2835_SYSTIMER)
23
24
+#define BCM2835_SYSTIMER_COUNT 4
25
+
26
struct BCM2835SystemTimerState {
27
/*< private >*/
28
SysBusDevice parent_obj;
29
@@ -XXX,XX +XXX,XX @@ struct BCM2835SystemTimerState {
30
31
struct {
32
uint32_t status;
33
- uint32_t compare[4];
34
+ uint32_t compare[BCM2835_SYSTIMER_COUNT];
35
} reg;
36
};
37
38
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/timer/bcm2835_systmr.c
41
+++ b/hw/timer/bcm2835_systmr.c
42
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription bcm2835_systmr_vmstate = {
43
.minimum_version_id = 1,
44
.fields = (VMStateField[]) {
45
VMSTATE_UINT32(reg.status, BCM2835SystemTimerState),
46
- VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState, 4),
47
+ VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState,
48
+ BCM2835_SYSTIMER_COUNT),
49
VMSTATE_END_OF_LIST()
50
}
51
};
52
--
53
2.20.1
54
55
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
The variable holding the CTRL_STATUS register is misnamed
4
'status'. Rename it 'ctrl_status' to make it more obvious
5
this register is also used to control the peripheral.
6
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20201010203709.3116542-3-f4bug@amsat.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/timer/bcm2835_systmr.h | 2 +-
14
hw/timer/bcm2835_systmr.c | 8 ++++----
15
2 files changed, 5 insertions(+), 5 deletions(-)
16
17
diff --git a/include/hw/timer/bcm2835_systmr.h b/include/hw/timer/bcm2835_systmr.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/timer/bcm2835_systmr.h
20
+++ b/include/hw/timer/bcm2835_systmr.h
21
@@ -XXX,XX +XXX,XX @@ struct BCM2835SystemTimerState {
22
qemu_irq irq;
23
24
struct {
25
- uint32_t status;
26
+ uint32_t ctrl_status;
27
uint32_t compare[BCM2835_SYSTIMER_COUNT];
28
} reg;
29
};
30
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/timer/bcm2835_systmr.c
33
+++ b/hw/timer/bcm2835_systmr.c
34
@@ -XXX,XX +XXX,XX @@ REG32(COMPARE3, 0x18)
35
36
static void bcm2835_systmr_update_irq(BCM2835SystemTimerState *s)
37
{
38
- bool enable = !!s->reg.status;
39
+ bool enable = !!s->reg.ctrl_status;
40
41
trace_bcm2835_systmr_irq(enable);
42
qemu_set_irq(s->irq, enable);
43
@@ -XXX,XX +XXX,XX @@ static uint64_t bcm2835_systmr_read(void *opaque, hwaddr offset,
44
45
switch (offset) {
46
case A_CTRL_STATUS:
47
- r = s->reg.status;
48
+ r = s->reg.ctrl_status;
49
break;
50
case A_COMPARE0 ... A_COMPARE3:
51
r = s->reg.compare[(offset - A_COMPARE0) >> 2];
52
@@ -XXX,XX +XXX,XX @@ static void bcm2835_systmr_write(void *opaque, hwaddr offset,
53
trace_bcm2835_systmr_write(offset, value);
54
switch (offset) {
55
case A_CTRL_STATUS:
56
- s->reg.status &= ~value; /* Ack */
57
+ s->reg.ctrl_status &= ~value; /* Ack */
58
bcm2835_systmr_update_irq(s);
59
break;
60
case A_COMPARE0 ... A_COMPARE3:
61
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription bcm2835_systmr_vmstate = {
62
.version_id = 1,
63
.minimum_version_id = 1,
64
.fields = (VMStateField[]) {
65
- VMSTATE_UINT32(reg.status, BCM2835SystemTimerState),
66
+ VMSTATE_UINT32(reg.ctrl_status, BCM2835SystemTimerState),
67
VMSTATE_UINT32_ARRAY(reg.compare, BCM2835SystemTimerState,
68
BCM2835_SYSTIMER_COUNT),
69
VMSTATE_END_OF_LIST()
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
The SYS_timer is not directly wired to the ARM core, but to the
4
SoC (peripheral) interrupt controller.
5
6
Fixes: 0e5bbd74064 ("hw/arm/bcm2835_peripherals: Use the SYS_timer")
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20201010203709.3116542-5-f4bug@amsat.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/bcm2835_peripherals.c | 13 +++++++++++--
14
1 file changed, 11 insertions(+), 2 deletions(-)
15
16
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/bcm2835_peripherals.c
19
+++ b/hw/arm/bcm2835_peripherals.c
20
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
21
memory_region_add_subregion(&s->peri_mr, ST_OFFSET,
22
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systmr), 0));
23
sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 0,
24
- qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
25
- INTERRUPT_ARM_TIMER));
26
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
27
+ INTERRUPT_TIMER0));
28
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 1,
29
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
30
+ INTERRUPT_TIMER1));
31
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 2,
32
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
33
+ INTERRUPT_TIMER2));
34
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systmr), 3,
35
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
36
+ INTERRUPT_TIMER3));
37
38
/* UART0 */
39
qdev_prop_set_chr(DEVICE(&s->uart0), "chardev", serial_hd(0));
40
--
41
2.20.1
42
43
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Fixing this now will clarify following patches.
3
At present, when booting U-Boot on QEMU sabrelite, we see:
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Net: Board Net Initialization Failed
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
No ethernet found.
7
Message-id: 20201016184207.786698-6-richard.henderson@linaro.org
7
8
U-Boot scans PHY at address 4/5/6/7 (see board_eth_init() in the
9
U-Boot source: board/boundary/nitrogen6x/nitrogen6x.c). On the real
10
board, the Ethernet PHY is at address 6. Adjust this by updating the
11
"fec-phy-num" property of the fsl_imx6 SoC object.
12
13
With this change, U-Boot sees the PHY but complains MAC address:
14
15
Net: using phy at 6
16
FEC [PRIME]
17
Error: FEC address not set.
18
19
This is due to U-Boot tries to read the MAC address from the fuse,
20
which QEMU does not have any valid content filled in. However this
21
does not prevent the Ethernet from working in QEMU. We just need to
22
set up the MAC address later in the U-Boot command shell, by:
23
24
=> setenv ethaddr 00:11:22:33:44:55
25
26
Signed-off-by: Bin Meng <bin.meng@windriver.com>
27
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
28
Message-id: 20210106063504.10841-4-bmeng.cn@gmail.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
30
---
10
linux-user/elfload.c | 12 +++++++++---
31
hw/arm/sabrelite.c | 4 ++++
11
1 file changed, 9 insertions(+), 3 deletions(-)
32
1 file changed, 4 insertions(+)
12
33
13
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
34
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
14
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/elfload.c
36
--- a/hw/arm/sabrelite.c
16
+++ b/linux-user/elfload.c
37
+++ b/hw/arm/sabrelite.c
17
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
38
@@ -XXX,XX +XXX,XX @@ static void sabrelite_init(MachineState *machine)
18
abi_ulong vaddr, vaddr_po, vaddr_ps, vaddr_ef, vaddr_em, vaddr_len;
39
19
int elf_prot = 0;
40
s = FSL_IMX6(object_new(TYPE_FSL_IMX6));
20
41
object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
21
- if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
42
+
22
- if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
43
+ /* Ethernet PHY address is 6 */
23
- if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
44
+ object_property_set_int(OBJECT(s), "fec-phy-num", 6, &error_fatal);
24
+ if (eppnt->p_flags & PF_R) {
45
+
25
+ elf_prot |= PROT_READ;
46
qdev_realize(DEVICE(s), NULL, &error_fatal);
26
+ }
47
27
+ if (eppnt->p_flags & PF_W) {
48
memory_region_add_subregion(get_system_memory(), FSL_IMX6_MMDC_ADDR,
28
+ elf_prot |= PROT_WRITE;
29
+ }
30
+ if (eppnt->p_flags & PF_X) {
31
+ elf_prot |= PROT_EXEC;
32
+ }
33
34
vaddr = load_bias + eppnt->p_vaddr;
35
vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr);
36
--
49
--
37
2.20.1
50
2.20.1
38
51
39
52
diff view generated by jsdifflib
1
From: Havard Skinnemoen <hskinnemoen@google.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
This test exercises the various modes of the npcm7xx timer. In
3
This adds the target guide for SABRE Lite board, and documents how
4
particular, it triggers the bug found by the fuzzer, as reported here:
4
to boot a Linux kernel and U-Boot bootloader.
5
5
6
https://lists.gnu.org/archive/html/qemu-devel/2020-09/msg02992.html
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
It also found several other bugs, especially related to interrupt
8
Message-id: 20210106063504.10841-5-bmeng.cn@gmail.com
9
handling.
10
11
The test exercises all the timers in all the timer modules, which
12
expands to 180 test cases in total.
13
14
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
15
Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com>
16
Message-id: 20201008232154.94221-2-hskinnemoen@google.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
10
---
19
tests/qtest/npcm7xx_timer-test.c | 562 +++++++++++++++++++++++++++++++
11
docs/system/arm/sabrelite.rst | 119 ++++++++++++++++++++++++++++++++++
20
tests/qtest/meson.build | 1 +
12
docs/system/target-arm.rst | 1 +
21
2 files changed, 563 insertions(+)
13
2 files changed, 120 insertions(+)
22
create mode 100644 tests/qtest/npcm7xx_timer-test.c
14
create mode 100644 docs/system/arm/sabrelite.rst
23
15
24
diff --git a/tests/qtest/npcm7xx_timer-test.c b/tests/qtest/npcm7xx_timer-test.c
16
diff --git a/docs/system/arm/sabrelite.rst b/docs/system/arm/sabrelite.rst
25
new file mode 100644
17
new file mode 100644
26
index XXXXXXX..XXXXXXX
18
index XXXXXXX..XXXXXXX
27
--- /dev/null
19
--- /dev/null
28
+++ b/tests/qtest/npcm7xx_timer-test.c
20
+++ b/docs/system/arm/sabrelite.rst
29
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
30
+/*
22
+Boundary Devices SABRE Lite (``sabrelite``)
31
+ * QTest testcase for the Nuvoton NPCM7xx Timer
23
+===========================================
32
+ *
33
+ * Copyright 2020 Google LLC
34
+ *
35
+ * This program is free software; you can redistribute it and/or modify it
36
+ * under the terms of the GNU General Public License as published by the
37
+ * Free Software Foundation; either version 2 of the License, or
38
+ * (at your option) any later version.
39
+ *
40
+ * This program is distributed in the hope that it will be useful, but WITHOUT
41
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
42
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
43
+ * for more details.
44
+ */
45
+
24
+
46
+#include "qemu/osdep.h"
25
+Boundary Devices SABRE Lite i.MX6 Development Board is a low-cost development
47
+#include "qemu/timer.h"
26
+platform featuring the powerful Freescale / NXP Semiconductor's i.MX 6 Quad
48
+#include "libqtest-single.h"
27
+Applications Processor.
49
+
28
+
50
+#define TIM_REF_HZ (25000000)
29
+Supported devices
30
+-----------------
51
+
31
+
52
+/* Bits in TCSRx */
32
+The SABRE Lite machine supports the following devices:
53
+#define CEN BIT(30)
54
+#define IE BIT(29)
55
+#define MODE_ONESHOT (0 << 27)
56
+#define MODE_PERIODIC (1 << 27)
57
+#define CRST BIT(26)
58
+#define CACT BIT(25)
59
+#define PRESCALE(x) (x)
60
+
33
+
61
+/* Registers shared between all timers in a module. */
34
+ * Up to 4 Cortex A9 cores
62
+#define TISR 0x18
35
+ * Generic Interrupt Controller
63
+#define WTCR 0x1c
36
+ * 1 Clock Controller Module
64
+# define WTCLK(x) ((x) << 10)
37
+ * 1 System Reset Controller
38
+ * 5 UARTs
39
+ * 2 EPIC timers
40
+ * 1 GPT timer
41
+ * 2 Watchdog timers
42
+ * 1 FEC Ethernet controller
43
+ * 3 I2C controllers
44
+ * 7 GPIO controllers
45
+ * 4 SDHC storage controllers
46
+ * 4 USB 2.0 host controllers
47
+ * 5 ECSPI controllers
48
+ * 1 SST 25VF016B flash
65
+
49
+
66
+/* Power-on default; used to re-initialize timers before each test. */
50
+Please note above list is a complete superset the QEMU SABRE Lite machine can
67
+#define TCSR_DEFAULT PRESCALE(5)
51
+support. For a normal use case, a device tree blob that represents a real world
52
+SABRE Lite board, only exposes a subset of devices to the guest software.
68
+
53
+
69
+/* Register offsets for a timer within a timer block. */
54
+Boot options
70
+typedef struct Timer {
55
+------------
71
+ unsigned int tcsr_offset;
72
+ unsigned int ticr_offset;
73
+ unsigned int tdr_offset;
74
+} Timer;
75
+
56
+
76
+/* A timer block containing 5 timers. */
57
+The SABRE Lite machine can start using the standard -kernel functionality
77
+typedef struct TimerBlock {
58
+for loading a Linux kernel, U-Boot bootloader or ELF executable.
78
+ int irq_base;
79
+ uint64_t base_addr;
80
+} TimerBlock;
81
+
59
+
82
+/* Testdata for testing a particular timer within a timer block. */
60
+Running Linux kernel
83
+typedef struct TestData {
61
+--------------------
84
+ const TimerBlock *tim;
85
+ const Timer *timer;
86
+} TestData;
87
+
62
+
88
+const TimerBlock timer_block[] = {
63
+Linux mainline v5.10 release is tested at the time of writing. To build a Linux
89
+ {
64
+mainline kernel that can be booted by the SABRE Lite machine, simply configure
90
+ .irq_base = 32,
65
+the kernel using the imx_v6_v7_defconfig configuration:
91
+ .base_addr = 0xf0008000,
92
+ },
93
+ {
94
+ .irq_base = 37,
95
+ .base_addr = 0xf0009000,
96
+ },
97
+ {
98
+ .irq_base = 42,
99
+ .base_addr = 0xf000a000,
100
+ },
101
+};
102
+
66
+
103
+const Timer timer[] = {
67
+.. code-block:: bash
104
+ {
105
+ .tcsr_offset = 0x00,
106
+ .ticr_offset = 0x08,
107
+ .tdr_offset = 0x10,
108
+ }, {
109
+ .tcsr_offset = 0x04,
110
+ .ticr_offset = 0x0c,
111
+ .tdr_offset = 0x14,
112
+ }, {
113
+ .tcsr_offset = 0x20,
114
+ .ticr_offset = 0x28,
115
+ .tdr_offset = 0x30,
116
+ }, {
117
+ .tcsr_offset = 0x24,
118
+ .ticr_offset = 0x2c,
119
+ .tdr_offset = 0x34,
120
+ }, {
121
+ .tcsr_offset = 0x40,
122
+ .ticr_offset = 0x48,
123
+ .tdr_offset = 0x50,
124
+ },
125
+};
126
+
68
+
127
+/* Returns the index of the timer block. */
69
+ $ export ARCH=arm
128
+static int tim_index(const TimerBlock *tim)
70
+ $ export CROSS_COMPILE=arm-linux-gnueabihf-
129
+{
71
+ $ make imx_v6_v7_defconfig
130
+ ptrdiff_t diff = tim - timer_block;
72
+ $ make
131
+
73
+
132
+ g_assert(diff >= 0 && diff < ARRAY_SIZE(timer_block));
74
+To boot the newly built Linux kernel in QEMU with the SABRE Lite machine, use:
133
+
75
+
134
+ return diff;
76
+.. code-block:: bash
135
+}
136
+
77
+
137
+/* Returns the index of a timer within a timer block. */
78
+ $ qemu-system-arm -M sabrelite -smp 4 -m 1G \
138
+static int timer_index(const Timer *t)
79
+ -display none -serial null -serial stdio \
139
+{
80
+ -kernel arch/arm/boot/zImage \
140
+ ptrdiff_t diff = t - timer;
81
+ -dtb arch/arm/boot/dts/imx6q-sabrelite.dtb \
82
+ -initrd /path/to/rootfs.ext4 \
83
+ -append "root=/dev/ram"
141
+
84
+
142
+ g_assert(diff >= 0 && diff < ARRAY_SIZE(timer));
85
+Running U-Boot
86
+--------------
143
+
87
+
144
+ return diff;
88
+U-Boot mainline v2020.10 release is tested at the time of writing. To build a
145
+}
89
+U-Boot mainline bootloader that can be booted by the SABRE Lite machine, use
90
+the mx6qsabrelite_defconfig with similar commands as described above for Linux:
146
+
91
+
147
+/* Returns the irq line for a given timer. */
92
+.. code-block:: bash
148
+static int tim_timer_irq(const TestData *td)
149
+{
150
+ return td->tim->irq_base + timer_index(td->timer);
151
+}
152
+
93
+
153
+/* Register read/write accessors. */
94
+ $ export CROSS_COMPILE=arm-linux-gnueabihf-
95
+ $ make mx6qsabrelite_defconfig
154
+
96
+
155
+static void tim_write(const TestData *td,
97
+Note we need to adjust settings by:
156
+ unsigned int offset, uint32_t value)
157
+{
158
+ writel(td->tim->base_addr + offset, value);
159
+}
160
+
98
+
161
+static uint32_t tim_read(const TestData *td, unsigned int offset)
99
+.. code-block:: bash
162
+{
163
+ return readl(td->tim->base_addr + offset);
164
+}
165
+
100
+
166
+static void tim_write_tcsr(const TestData *td, uint32_t value)
101
+ $ make menuconfig
167
+{
168
+ tim_write(td, td->timer->tcsr_offset, value);
169
+}
170
+
102
+
171
+static uint32_t tim_read_tcsr(const TestData *td)
103
+then manually select the following configuration in U-Boot:
172
+{
173
+ return tim_read(td, td->timer->tcsr_offset);
174
+}
175
+
104
+
176
+static void tim_write_ticr(const TestData *td, uint32_t value)
105
+ Device Tree Control > Provider of DTB for DT Control > Embedded DTB
177
+{
178
+ tim_write(td, td->timer->ticr_offset, value);
179
+}
180
+
106
+
181
+static uint32_t tim_read_ticr(const TestData *td)
107
+To start U-Boot using the SABRE Lite machine, provide the u-boot binary to
182
+{
108
+the -kernel argument, along with an SD card image with rootfs:
183
+ return tim_read(td, td->timer->ticr_offset);
184
+}
185
+
109
+
186
+static uint32_t tim_read_tdr(const TestData *td)
110
+.. code-block:: bash
187
+{
188
+ return tim_read(td, td->timer->tdr_offset);
189
+}
190
+
111
+
191
+/* Returns the number of nanoseconds to count the given number of cycles. */
112
+ $ qemu-system-arm -M sabrelite -smp 4 -m 1G \
192
+static int64_t tim_calculate_step(uint32_t count, uint32_t prescale)
113
+ -display none -serial null -serial stdio \
193
+{
114
+ -kernel u-boot
194
+ return (1000000000LL / TIM_REF_HZ) * count * (prescale + 1);
195
+}
196
+
115
+
197
+/* Returns a bitmask corresponding to the timer under test. */
116
+The following example shows booting Linux kernel from dhcp, and uses the
198
+static uint32_t tim_timer_bit(const TestData *td)
117
+rootfs on an SD card. This requires some additional command line parameters
199
+{
118
+for QEMU:
200
+ return BIT(timer_index(td->timer));
201
+}
202
+
119
+
203
+/* Resets all timers to power-on defaults. */
120
+.. code-block:: none
204
+static void tim_reset(const TestData *td)
205
+{
206
+ int i, j;
207
+
121
+
208
+ /* Reset all the timers, in case a previous test left a timer running. */
122
+ -nic user,tftp=/path/to/kernel/zImage \
209
+ for (i = 0; i < ARRAY_SIZE(timer_block); i++) {
123
+ -drive file=sdcard.img,id=rootfs -device sd-card,drive=rootfs
210
+ for (j = 0; j < ARRAY_SIZE(timer); j++) {
211
+ writel(timer_block[i].base_addr + timer[j].tcsr_offset,
212
+ CRST | TCSR_DEFAULT);
213
+ }
214
+ writel(timer_block[i].base_addr + TISR, -1);
215
+ }
216
+}
217
+
124
+
218
+/* Verifies the reset state of a timer. */
125
+The directory for the built-in TFTP server should also contain the device tree
219
+static void test_reset(gconstpointer test_data)
126
+blob of the SABRE Lite board. The sample SD card image was populated with the
220
+{
127
+root file system with one single partition. You may adjust the kernel "root="
221
+ const TestData *td = test_data;
128
+boot parameter accordingly.
222
+
129
+
223
+ tim_reset(td);
130
+After U-Boot boots, type the following commands in the U-Boot command shell to
131
+boot the Linux kernel:
224
+
132
+
225
+ g_assert_cmphex(tim_read_tcsr(td), ==, TCSR_DEFAULT);
133
+.. code-block:: none
226
+ g_assert_cmphex(tim_read_ticr(td), ==, 0);
227
+ g_assert_cmphex(tim_read_tdr(td), ==, 0);
228
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
229
+ g_assert_cmphex(tim_read(td, WTCR), ==, WTCLK(1));
230
+}
231
+
134
+
232
+/* Verifies that CRST wins if both CEN and CRST are set. */
135
+ => setenv ethaddr 00:11:22:33:44:55
233
+static void test_reset_overrides_enable(gconstpointer test_data)
136
+ => setenv bootfile zImage
234
+{
137
+ => dhcp
235
+ const TestData *td = test_data;
138
+ => tftpboot 14000000 imx6q-sabrelite.dtb
236
+
139
+ => setenv bootargs root=/dev/mmcblk3p1
237
+ tim_reset(td);
140
+ => bootz 12000000 - 14000000
238
+
141
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
239
+ /* CRST should force CEN to 0 */
240
+ tim_write_tcsr(td, CEN | CRST | TCSR_DEFAULT);
241
+
242
+ g_assert_cmphex(tim_read_tcsr(td), ==, TCSR_DEFAULT);
243
+ g_assert_cmphex(tim_read_tdr(td), ==, 0);
244
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
245
+}
246
+
247
+/* Verifies the behavior when CEN is set and then cleared. */
248
+static void test_oneshot_enable_then_disable(gconstpointer test_data)
249
+{
250
+ const TestData *td = test_data;
251
+
252
+ tim_reset(td);
253
+
254
+ /* Enable the timer with zero initial count, then disable it again. */
255
+ tim_write_tcsr(td, CEN | TCSR_DEFAULT);
256
+ tim_write_tcsr(td, TCSR_DEFAULT);
257
+
258
+ g_assert_cmphex(tim_read_tcsr(td), ==, TCSR_DEFAULT);
259
+ g_assert_cmphex(tim_read_tdr(td), ==, 0);
260
+ /* Timer interrupt flag should be set, but interrupts are not enabled. */
261
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
262
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
263
+}
264
+
265
+/* Verifies that a one-shot timer fires when expected with prescaler 5. */
266
+static void test_oneshot_ps5(gconstpointer test_data)
267
+{
268
+ const TestData *td = test_data;
269
+ unsigned int count = 256;
270
+ unsigned int ps = 5;
271
+
272
+ tim_reset(td);
273
+
274
+ tim_write_ticr(td, count);
275
+ tim_write_tcsr(td, CEN | PRESCALE(ps));
276
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
277
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
278
+
279
+ clock_step(tim_calculate_step(count, ps) - 1);
280
+
281
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
282
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
283
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
284
+
285
+ clock_step(1);
286
+
287
+ g_assert_cmphex(tim_read_tcsr(td), ==, PRESCALE(ps));
288
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
289
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
290
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
291
+
292
+ /* Clear the interrupt flag. */
293
+ tim_write(td, TISR, tim_timer_bit(td));
294
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
295
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
296
+
297
+ /* Verify that this isn't a periodic timer. */
298
+ clock_step(2 * tim_calculate_step(count, ps));
299
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
300
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
301
+}
302
+
303
+/* Verifies that a one-shot timer fires when expected with prescaler 0. */
304
+static void test_oneshot_ps0(gconstpointer test_data)
305
+{
306
+ const TestData *td = test_data;
307
+ unsigned int count = 1;
308
+ unsigned int ps = 0;
309
+
310
+ tim_reset(td);
311
+
312
+ tim_write_ticr(td, count);
313
+ tim_write_tcsr(td, CEN | PRESCALE(ps));
314
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
315
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
316
+
317
+ clock_step(tim_calculate_step(count, ps) - 1);
318
+
319
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
320
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
321
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
322
+
323
+ clock_step(1);
324
+
325
+ g_assert_cmphex(tim_read_tcsr(td), ==, PRESCALE(ps));
326
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
327
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
328
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
329
+}
330
+
331
+/* Verifies that a one-shot timer fires when expected with highest prescaler. */
332
+static void test_oneshot_ps255(gconstpointer test_data)
333
+{
334
+ const TestData *td = test_data;
335
+ unsigned int count = (1U << 24) - 1;
336
+ unsigned int ps = 255;
337
+
338
+ tim_reset(td);
339
+
340
+ tim_write_ticr(td, count);
341
+ tim_write_tcsr(td, CEN | PRESCALE(ps));
342
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
343
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
344
+
345
+ clock_step(tim_calculate_step(count, ps) - 1);
346
+
347
+ g_assert_cmphex(tim_read_tcsr(td), ==, CEN | CACT | PRESCALE(ps));
348
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
349
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
350
+
351
+ clock_step(1);
352
+
353
+ g_assert_cmphex(tim_read_tcsr(td), ==, PRESCALE(ps));
354
+ g_assert_cmpuint(tim_read_tdr(td), ==, count);
355
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
356
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
357
+}
358
+
359
+/* Verifies that a oneshot timer fires an interrupt when expected. */
360
+static void test_oneshot_interrupt(gconstpointer test_data)
361
+{
362
+ const TestData *td = test_data;
363
+ unsigned int count = 256;
364
+ unsigned int ps = 7;
365
+
366
+ tim_reset(td);
367
+
368
+ tim_write_ticr(td, count);
369
+ tim_write_tcsr(td, IE | CEN | MODE_ONESHOT | PRESCALE(ps));
370
+
371
+ clock_step_next();
372
+
373
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
374
+ g_assert_true(qtest_get_irq(global_qtest, tim_timer_irq(td)));
375
+}
376
+
377
+/*
378
+ * Verifies that the timer can be paused and later resumed, and it still fires
379
+ * at the right moment.
380
+ */
381
+static void test_pause_resume(gconstpointer test_data)
382
+{
383
+ const TestData *td = test_data;
384
+ unsigned int count = 256;
385
+ unsigned int ps = 1;
386
+
387
+ tim_reset(td);
388
+
389
+ tim_write_ticr(td, count);
390
+ tim_write_tcsr(td, IE | CEN | MODE_ONESHOT | PRESCALE(ps));
391
+
392
+ /* Pause the timer halfway to expiration. */
393
+ clock_step(tim_calculate_step(count / 2, ps));
394
+ tim_write_tcsr(td, IE | MODE_ONESHOT | PRESCALE(ps));
395
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
396
+
397
+ /* Counter should not advance during the following step. */
398
+ clock_step(2 * tim_calculate_step(count, ps));
399
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
400
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
401
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
402
+
403
+ /* Resume the timer and run _almost_ to expiration. */
404
+ tim_write_tcsr(td, IE | CEN | MODE_ONESHOT | PRESCALE(ps));
405
+ clock_step(tim_calculate_step(count / 2, ps) - 1);
406
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
407
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
408
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
409
+
410
+ /* Now, run the rest of the way and verify that the interrupt fires. */
411
+ clock_step(1);
412
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
413
+ g_assert_true(qtest_get_irq(global_qtest, tim_timer_irq(td)));
414
+}
415
+
416
+/* Verifies that the prescaler can be changed while the timer is runnin. */
417
+static void test_prescaler_change(gconstpointer test_data)
418
+{
419
+ const TestData *td = test_data;
420
+ unsigned int count = 256;
421
+ unsigned int ps = 5;
422
+
423
+ tim_reset(td);
424
+
425
+ tim_write_ticr(td, count);
426
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
427
+
428
+ /* Run a quarter of the way, and change the prescaler. */
429
+ clock_step(tim_calculate_step(count / 4, ps));
430
+ g_assert_cmpuint(tim_read_tdr(td), ==, 3 * count / 4);
431
+ ps = 2;
432
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
433
+ /* The counter must not change. */
434
+ g_assert_cmpuint(tim_read_tdr(td), ==, 3 * count / 4);
435
+
436
+ /* Run another quarter of the way, and change the prescaler again. */
437
+ clock_step(tim_calculate_step(count / 4, ps));
438
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
439
+ ps = 8;
440
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
441
+ /* The counter must not change. */
442
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 2);
443
+
444
+ /* Run another quarter of the way, and change the prescaler again. */
445
+ clock_step(tim_calculate_step(count / 4, ps));
446
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 4);
447
+ ps = 0;
448
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
449
+ /* The counter must not change. */
450
+ g_assert_cmpuint(tim_read_tdr(td), ==, count / 4);
451
+
452
+ /* Run almost to expiration, and verify the timer didn't fire yet. */
453
+ clock_step(tim_calculate_step(count / 4, ps) - 1);
454
+ g_assert_cmpuint(tim_read_tdr(td), <, count);
455
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
456
+
457
+ /* Now, run the rest of the way and verify that the timer fires. */
458
+ clock_step(1);
459
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
460
+}
461
+
462
+/* Verifies that a periodic timer automatically restarts after expiration. */
463
+static void test_periodic_no_interrupt(gconstpointer test_data)
464
+{
465
+ const TestData *td = test_data;
466
+ unsigned int count = 2;
467
+ unsigned int ps = 3;
468
+ int i;
469
+
470
+ tim_reset(td);
471
+
472
+ tim_write_ticr(td, count);
473
+ tim_write_tcsr(td, CEN | MODE_PERIODIC | PRESCALE(ps));
474
+
475
+ for (i = 0; i < 4; i++) {
476
+ clock_step_next();
477
+
478
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
479
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
480
+
481
+ tim_write(td, TISR, tim_timer_bit(td));
482
+
483
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
484
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
485
+ }
486
+}
487
+
488
+/* Verifies that a periodict timer fires an interrupt every time it expires. */
489
+static void test_periodic_interrupt(gconstpointer test_data)
490
+{
491
+ const TestData *td = test_data;
492
+ unsigned int count = 65535;
493
+ unsigned int ps = 2;
494
+ int i;
495
+
496
+ tim_reset(td);
497
+
498
+ tim_write_ticr(td, count);
499
+ tim_write_tcsr(td, CEN | IE | MODE_PERIODIC | PRESCALE(ps));
500
+
501
+ for (i = 0; i < 4; i++) {
502
+ clock_step_next();
503
+
504
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
505
+ g_assert_true(qtest_get_irq(global_qtest, tim_timer_irq(td)));
506
+
507
+ tim_write(td, TISR, tim_timer_bit(td));
508
+
509
+ g_assert_cmphex(tim_read(td, TISR), ==, 0);
510
+ g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
511
+ }
512
+}
513
+
514
+/*
515
+ * Verifies that the timer behaves correctly when disabled right before and
516
+ * exactly when it's supposed to expire.
517
+ */
518
+static void test_disable_on_expiration(gconstpointer test_data)
519
+{
520
+ const TestData *td = test_data;
521
+ unsigned int count = 8;
522
+ unsigned int ps = 255;
523
+
524
+ tim_reset(td);
525
+
526
+ tim_write_ticr(td, count);
527
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
528
+
529
+ clock_step(tim_calculate_step(count, ps) - 1);
530
+
531
+ tim_write_tcsr(td, MODE_ONESHOT | PRESCALE(ps));
532
+ tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
533
+ clock_step(1);
534
+ tim_write_tcsr(td, MODE_ONESHOT | PRESCALE(ps));
535
+ g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
536
+}
537
+
538
+/*
539
+ * Constructs a name that includes the timer block, timer and testcase name,
540
+ * and adds the test to the test suite.
541
+ */
542
+static void tim_add_test(const char *name, const TestData *td, GTestDataFunc fn)
543
+{
544
+ g_autofree char *full_name;
545
+
546
+ full_name = g_strdup_printf("npcm7xx_timer/tim[%d]/timer[%d]/%s",
547
+ tim_index(td->tim), timer_index(td->timer),
548
+ name);
549
+ qtest_add_data_func(full_name, td, fn);
550
+}
551
+
552
+/* Convenience macro for adding a test with a predictable function name. */
553
+#define add_test(name, td) tim_add_test(#name, td, test_##name)
554
+
555
+int main(int argc, char **argv)
556
+{
557
+ TestData testdata[ARRAY_SIZE(timer_block) * ARRAY_SIZE(timer)];
558
+ int ret;
559
+ int i, j;
560
+
561
+ g_test_init(&argc, &argv, NULL);
562
+ g_test_set_nonfatal_assertions();
563
+
564
+ for (i = 0; i < ARRAY_SIZE(timer_block); i++) {
565
+ for (j = 0; j < ARRAY_SIZE(timer); j++) {
566
+ TestData *td = &testdata[i * ARRAY_SIZE(timer) + j];
567
+ td->tim = &timer_block[i];
568
+ td->timer = &timer[j];
569
+
570
+ add_test(reset, td);
571
+ add_test(reset_overrides_enable, td);
572
+ add_test(oneshot_enable_then_disable, td);
573
+ add_test(oneshot_ps5, td);
574
+ add_test(oneshot_ps0, td);
575
+ add_test(oneshot_ps255, td);
576
+ add_test(oneshot_interrupt, td);
577
+ add_test(pause_resume, td);
578
+ add_test(prescaler_change, td);
579
+ add_test(periodic_no_interrupt, td);
580
+ add_test(periodic_interrupt, td);
581
+ add_test(disable_on_expiration, td);
582
+ }
583
+ }
584
+
585
+ qtest_start("-machine npcm750-evb");
586
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/a9mpcore/gic");
587
+ ret = g_test_run();
588
+ qtest_end();
589
+
590
+ return ret;
591
+}
592
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
593
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
594
--- a/tests/qtest/meson.build
143
--- a/docs/system/target-arm.rst
595
+++ b/tests/qtest/meson.build
144
+++ b/docs/system/target-arm.rst
596
@@ -XXX,XX +XXX,XX @@ qtests_arm = \
145
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
597
['arm-cpu-features',
146
arm/versatile
598
'microbit-test',
147
arm/vexpress
599
'm25p80-test',
148
arm/aspeed
600
+ 'npcm7xx_timer-test',
149
+ arm/sabrelite
601
'test-arm-mptimer',
150
arm/digic
602
'boot-serial-test',
151
arm/musicpal
603
'hexloader-test']
152
arm/gumstix
604
--
153
--
605
2.20.1
154
2.20.1
606
155
607
156
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Add trace events for GPU and CPU IRQs.
4
5
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20201017180731.1165871-2-f4bug@amsat.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/intc/bcm2835_ic.c | 4 +++-
11
hw/intc/trace-events | 4 ++++
12
2 files changed, 7 insertions(+), 1 deletion(-)
13
14
diff --git a/hw/intc/bcm2835_ic.c b/hw/intc/bcm2835_ic.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/bcm2835_ic.c
17
+++ b/hw/intc/bcm2835_ic.c
18
@@ -XXX,XX +XXX,XX @@
19
#include "migration/vmstate.h"
20
#include "qemu/log.h"
21
#include "qemu/module.h"
22
+#include "trace.h"
23
24
#define GPU_IRQS 64
25
#define ARM_IRQS 8
26
@@ -XXX,XX +XXX,XX @@ static void bcm2835_ic_update(BCM2835ICState *s)
27
set = (s->gpu_irq_level & s->gpu_irq_enable)
28
|| (s->arm_irq_level & s->arm_irq_enable);
29
qemu_set_irq(s->irq, set);
30
-
31
}
32
33
static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level)
34
@@ -XXX,XX +XXX,XX @@ static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level)
35
BCM2835ICState *s = opaque;
36
37
assert(irq >= 0 && irq < 64);
38
+ trace_bcm2835_ic_set_gpu_irq(irq, level);
39
s->gpu_irq_level = deposit64(s->gpu_irq_level, irq, 1, level != 0);
40
bcm2835_ic_update(s);
41
}
42
@@ -XXX,XX +XXX,XX @@ static void bcm2835_ic_set_arm_irq(void *opaque, int irq, int level)
43
BCM2835ICState *s = opaque;
44
45
assert(irq >= 0 && irq < 8);
46
+ trace_bcm2835_ic_set_cpu_irq(irq, level);
47
s->arm_irq_level = deposit32(s->arm_irq_level, irq, 1, level != 0);
48
bcm2835_ic_update(s);
49
}
50
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/intc/trace-events
53
+++ b/hw/intc/trace-events
54
@@ -XXX,XX +XXX,XX @@ nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg wri
55
heathrow_write(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 0x%"PRIx64
56
heathrow_read(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 0x%"PRIx64
57
heathrow_set_irq(int num, int level) "set_irq: num=0x%02x level=%d"
58
+
59
+# bcm2835_ic.c
60
+bcm2835_ic_set_gpu_irq(int irq, int level) "GPU irq #%d level %d"
61
+bcm2835_ic_set_cpu_irq(int irq, int level) "CPU irq #%d level %d"
62
--
63
2.20.1
64
65
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We already have the full ARMMMUIdx as computed from the
4
function parameter.
5
6
For the purpose of regime_has_2_ranges, we can ignore any
7
difference between AccType_Normal and AccType_Unpriv, which
8
would be the only difference between the passed mmu_idx
9
and arm_mmu_idx_el.
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
14
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
15
Message-id: 20201008162155.161886-2-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/mte_helper.c | 3 +--
19
1 file changed, 1 insertion(+), 2 deletions(-)
20
21
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/mte_helper.c
24
+++ b/target/arm/mte_helper.c
25
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
26
27
case 2:
28
/* Tag check fail causes asynchronous flag set. */
29
- mmu_idx = arm_mmu_idx_el(env, el);
30
- if (regime_has_2_ranges(mmu_idx)) {
31
+ if (regime_has_2_ranges(arm_mmu_idx)) {
32
select = extract64(dirty_ptr, 55, 1);
33
} else {
34
select = 0;
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The reporting in AArch64.TagCheckFail only depends on PSTATE.EL,
4
and not the AccType of the operation. There are two guest
5
visible problems that affect LDTR and STTR because of this:
6
7
(1) Selecting TCF0 vs TCF1 to decide on reporting,
8
(2) Report "data abort same el" not "data abort lower el".
9
10
Reported-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
13
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
14
Message-id: 20201008162155.161886-3-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/mte_helper.c | 10 +++-------
18
1 file changed, 3 insertions(+), 7 deletions(-)
19
20
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/mte_helper.c
23
+++ b/target/arm/mte_helper.c
24
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
25
reg_el = regime_el(env, arm_mmu_idx);
26
sctlr = env->cp15.sctlr_el[reg_el];
27
28
- switch (arm_mmu_idx) {
29
- case ARMMMUIdx_E10_0:
30
- case ARMMMUIdx_E20_0:
31
- el = 0;
32
+ el = arm_current_el(env);
33
+ if (el == 0) {
34
tcf = extract64(sctlr, 38, 2);
35
- break;
36
- default:
37
- el = reg_el;
38
+ } else {
39
tcf = extract64(sctlr, 40, 2);
40
}
41
42
--
43
2.20.1
44
45
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Unlike many other bits in HCR_EL2, the description for this
4
bit does not contain the phrase "if ... this field behaves
5
as 0 for all purposes other than", so do not squash the bit
6
in arm_hcr_el2_eff.
7
8
Instead, replicate the E2H+TGE test in the two places that
9
require it.
10
11
Reported-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
14
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
15
Message-id: 20201008162155.161886-4-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/internals.h | 9 +++++----
19
target/arm/helper.c | 9 +++++----
20
2 files changed, 10 insertions(+), 8 deletions(-)
21
22
diff --git a/target/arm/internals.h b/target/arm/internals.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/internals.h
25
+++ b/target/arm/internals.h
26
@@ -XXX,XX +XXX,XX @@ static inline bool allocation_tag_access_enabled(CPUARMState *env, int el,
27
&& !(env->cp15.scr_el3 & SCR_ATA)) {
28
return false;
29
}
30
- if (el < 2
31
- && arm_feature(env, ARM_FEATURE_EL2)
32
- && !(arm_hcr_el2_eff(env) & HCR_ATA)) {
33
- return false;
34
+ if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
35
+ uint64_t hcr = arm_hcr_el2_eff(env);
36
+ if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
37
+ return false;
38
+ }
39
}
40
sctlr &= (el == 0 ? SCTLR_ATA0 : SCTLR_ATA);
41
return sctlr != 0;
42
diff --git a/target/arm/helper.c b/target/arm/helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper.c
45
+++ b/target/arm/helper.c
46
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_mte(CPUARMState *env, const ARMCPRegInfo *ri,
47
{
48
int el = arm_current_el(env);
49
50
- if (el < 2 &&
51
- arm_feature(env, ARM_FEATURE_EL2) &&
52
- !(arm_hcr_el2_eff(env) & HCR_ATA)) {
53
- return CP_ACCESS_TRAP_EL2;
54
+ if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
55
+ uint64_t hcr = arm_hcr_el2_eff(env);
56
+ if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
57
+ return CP_ACCESS_TRAP_EL2;
58
+ }
59
}
60
if (el < 3 &&
61
arm_feature(env, ARM_FEATURE_EL3) &&
62
--
63
2.20.1
64
65
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Commit 7998beb9c2e removed the ram_size initialization in the
4
arm_boot_info structure, however it is used by arm_load_kernel().
5
6
Initialize the field to fix:
7
8
$ qemu-system-arm -M n800 -append 'console=ttyS1' \
9
-kernel meego-arm-n8x0-1.0.80.20100712.1431-vmlinuz-2.6.35~rc4-129.1-n8x0
10
qemu-system-arm: kernel 'meego-arm-n8x0-1.0.80.20100712.1431-vmlinuz-2.6.35~rc4-129.1-n8x0' is too large to fit in RAM (kernel size 1964608, RAM size 0)
11
12
Noticed while running the test introduced in commit 050a82f0c5b
13
("tests/acceptance: Add a test for the N800 and N810 arm machines").
14
15
Fixes: 7998beb9c2e ("arm/nseries: use memdev for RAM")
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Tested-by: Thomas Huth <thuth@redhat.com>
19
Message-id: 20201019095148.1602119-1-f4bug@amsat.org
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
hw/arm/nseries.c | 1 +
23
1 file changed, 1 insertion(+)
24
25
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/nseries.c
28
+++ b/hw/arm/nseries.c
29
@@ -XXX,XX +XXX,XX @@ static void n8x0_init(MachineState *machine,
30
g_free(sz);
31
exit(EXIT_FAILURE);
32
}
33
+ binfo->ram_size = machine->ram_size;
34
35
memory_region_add_subregion(get_system_memory(), OMAP2_Q2_BASE,
36
machine->ram);
37
--
38
2.20.1
39
40
diff view generated by jsdifflib
Deleted patch
1
For nested groups like:
2
1
3
{
4
[
5
pattern 1
6
pattern 2
7
]
8
pattern 3
9
}
10
11
the intended behaviour is that patterns 1 and 2 must not
12
overlap with each other; if the insn matches neither then
13
we fall through to pattern 3 as the next thing in the
14
outer overlapping group.
15
16
Currently we generate incorrect code for this situation,
17
because in the code path for a failed match inside the
18
inner non-overlapping group we generate a "return" statement,
19
which causes decode to stop entirely rather than continuing
20
to the next thing in the outer group.
21
22
Generate a "break" instead, so that decode flow behaves
23
as required for this nested group case.
24
25
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Message-id: 20201019151301.2046-2-peter.maydell@linaro.org
29
---
30
scripts/decodetree.py | 2 +-
31
1 file changed, 1 insertion(+), 1 deletion(-)
32
33
diff --git a/scripts/decodetree.py b/scripts/decodetree.py
34
index XXXXXXX..XXXXXXX 100644
35
--- a/scripts/decodetree.py
36
+++ b/scripts/decodetree.py
37
@@ -XXX,XX +XXX,XX @@ class Tree:
38
output(ind, ' /* ',
39
str_match_bits(innerbits, innermask), ' */\n')
40
s.output_code(i + 4, extracted, innerbits, innermask)
41
- output(ind, ' return false;\n')
42
+ output(ind, ' break;\n')
43
output(ind, '}\n')
44
# end Tree
45
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
v8.1M brings four new insns to M-profile:
2
* CSEL : Rd = cond ? Rn : Rm
3
* CSINC : Rd = cond ? Rn : Rm+1
4
* CSINV : Rd = cond ? Rn : ~Rm
5
* CSNEG : Rd = cond ? Rn : -Rm
6
1
7
Implement these.
8
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20201019151301.2046-4-peter.maydell@linaro.org
12
---
13
target/arm/t32.decode | 3 +++
14
target/arm/translate.c | 60 ++++++++++++++++++++++++++++++++++++++++++
15
2 files changed, 63 insertions(+)
16
17
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/t32.decode
20
+++ b/target/arm/t32.decode
21
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
22
}
23
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
24
25
+# v8.1M CSEL and friends
26
+CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
27
+
28
# Data-processing (register-shifted register)
29
30
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
31
diff --git a/target/arm/translate.c b/target/arm/translate.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate.c
34
+++ b/target/arm/translate.c
35
@@ -XXX,XX +XXX,XX @@ static bool trans_IT(DisasContext *s, arg_IT *a)
36
return true;
37
}
38
39
+/* v8.1M CSEL/CSINC/CSNEG/CSINV */
40
+static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
41
+{
42
+ TCGv_i32 rn, rm, zero;
43
+ DisasCompare c;
44
+
45
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
46
+ return false;
47
+ }
48
+
49
+ if (a->rm == 13) {
50
+ /* SEE "Related encodings" (MVE shifts) */
51
+ return false;
52
+ }
53
+
54
+ if (a->rd == 13 || a->rd == 15 || a->rn == 13 || a->fcond >= 14) {
55
+ /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
56
+ return false;
57
+ }
58
+
59
+ /* In this insn input reg fields of 0b1111 mean "zero", not "PC" */
60
+ if (a->rn == 15) {
61
+ rn = tcg_const_i32(0);
62
+ } else {
63
+ rn = load_reg(s, a->rn);
64
+ }
65
+ if (a->rm == 15) {
66
+ rm = tcg_const_i32(0);
67
+ } else {
68
+ rm = load_reg(s, a->rm);
69
+ }
70
+
71
+ switch (a->op) {
72
+ case 0: /* CSEL */
73
+ break;
74
+ case 1: /* CSINC */
75
+ tcg_gen_addi_i32(rm, rm, 1);
76
+ break;
77
+ case 2: /* CSINV */
78
+ tcg_gen_not_i32(rm, rm);
79
+ break;
80
+ case 3: /* CSNEG */
81
+ tcg_gen_neg_i32(rm, rm);
82
+ break;
83
+ default:
84
+ g_assert_not_reached();
85
+ }
86
+
87
+ arm_test_cc(&c, a->fcond);
88
+ zero = tcg_const_i32(0);
89
+ tcg_gen_movcond_i32(c.cond, rn, c.value, zero, rn, rm);
90
+ arm_free_cc(&c);
91
+ tcg_temp_free_i32(zero);
92
+
93
+ store_reg(s, a->rd, rn);
94
+ tcg_temp_free_i32(rm);
95
+
96
+ return true;
97
+}
98
+
99
/*
100
* Legacy decoder.
101
*/
102
--
103
2.20.1
104
105
diff view generated by jsdifflib
Deleted patch
1
The t32 decode has a group which represents a set of insns
2
which overlap with B_cond_thumb because they have [25:23]=111
3
(which is an invalid condition code field for the branch insn).
4
This group is currently defined using the {} overlap-OK syntax,
5
but it is almost entirely non-overlapping patterns. Switch
6
it over to use a non-overlapping group.
7
1
8
For this to be valid syntactically, CPS must move into the same
9
overlapping-group as the hint insns (CPS vs hints was the
10
only actual use of the overlap facility for the group).
11
12
The non-overlapping subgroup for CLREX/DSB/DMB/ISB/SB is no longer
13
necessary and so we can remove it (promoting those insns to
14
be members of the parent group).
15
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Message-id: 20201019151301.2046-5-peter.maydell@linaro.org
19
---
20
target/arm/t32.decode | 26 ++++++++++++--------------
21
1 file changed, 12 insertions(+), 14 deletions(-)
22
23
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/t32.decode
26
+++ b/target/arm/t32.decode
27
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
28
{
29
# Group insn[25:23] = 111, which is cond=111x for the branch below,
30
# or unconditional, which would be illegal for the branch.
31
- {
32
- # Hints
33
+ [
34
+ # Hints, and CPS
35
{
36
YIELD 1111 0011 1010 1111 1000 0000 0000 0001
37
WFE 1111 0011 1010 1111 1000 0000 0000 0010
38
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
39
# The canonical nop ends in 0000 0000, but the whole rest
40
# of the space is "reserved hint, behaves as nop".
41
NOP 1111 0011 1010 1111 1000 0000 ---- ----
42
+
43
+ # If imod == '00' && M == '0' then SEE "Hint instructions", above.
44
+ CPS 1111 0011 1010 1111 1000 0 imod:2 M:1 A:1 I:1 F:1 mode:5 \
45
+ &cps
46
}
47
48
- # If imod == '00' && M == '0' then SEE "Hint instructions", above.
49
- CPS 1111 0011 1010 1111 1000 0 imod:2 M:1 A:1 I:1 F:1 mode:5 \
50
- &cps
51
-
52
# Miscellaneous control
53
- [
54
- CLREX 1111 0011 1011 1111 1000 1111 0010 1111
55
- DSB 1111 0011 1011 1111 1000 1111 0100 ----
56
- DMB 1111 0011 1011 1111 1000 1111 0101 ----
57
- ISB 1111 0011 1011 1111 1000 1111 0110 ----
58
- SB 1111 0011 1011 1111 1000 1111 0111 0000
59
- ]
60
+ CLREX 1111 0011 1011 1111 1000 1111 0010 1111
61
+ DSB 1111 0011 1011 1111 1000 1111 0100 ----
62
+ DMB 1111 0011 1011 1111 1000 1111 0101 ----
63
+ ISB 1111 0011 1011 1111 1000 1111 0110 ----
64
+ SB 1111 0011 1011 1111 1000 1111 0111 0000
65
66
# Note that the v7m insn overlaps both the normal and banked insn.
67
{
68
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
69
HVC 1111 0111 1110 .... 1000 .... .... .... \
70
&i imm=%imm16_16_0
71
UDF 1111 0111 1111 ---- 1010 ---- ---- ----
72
- }
73
+ ]
74
B_cond_thumb 1111 0. cond:4 ...... 10.0 ............ &ci imm=%imm21
75
}
76
77
--
78
2.20.1
79
80
diff view generated by jsdifflib
Deleted patch
1
The BLX immediate insn in the Thumb encoding always performs
2
a switch from Thumb to Arm state. This would be totally useless
3
in M-profile which has no Arm decoder, and so the instruction
4
does not exist at all there. Make the encoding UNDEF for M-profile.
5
1
6
(This part of the encoding space is used for the branch-future
7
and low-overhead-loop insns in v8.1M.)
8
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20201019151301.2046-6-peter.maydell@linaro.org
12
---
13
target/arm/translate.c | 8 ++++++++
14
1 file changed, 8 insertions(+)
15
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
19
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
21
{
22
TCGv_i32 tmp;
23
24
+ /*
25
+ * BLX <imm> would be useless on M-profile; the encoding space
26
+ * is used for other insns from v8.1M onward, and UNDEFs before that.
27
+ */
28
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
29
+ return false;
30
+ }
31
+
32
/* For A32, ARM_FEATURE_V5 is checked near the start of the uncond block. */
33
if (s->thumb && (a->imm & 2)) {
34
return false;
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
v8.1M implements a new 'branch future' feature, which is a
2
set of instructions that request the CPU to perform a branch
3
"in the future", when it reaches a particular execution address.
4
In hardware, the expected implementation is that the information
5
about the branch location and destination is cached and then
6
acted upon when execution reaches the specified address.
7
However the architecture permits an implementation to discard
8
this cached information at any point, and so guest code must
9
always include a normal branch insn at the branch point as
10
a fallback. In particular, an implementation is specifically
11
permitted to treat all BF insns as NOPs (which is equivalent
12
to discarding the cached information immediately).
13
1
14
For QEMU, implementing this caching of branch information
15
would be complicated and would not improve the speed of
16
execution at all, so we make the IMPDEF choice to implement
17
all BF insns as NOPs.
18
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Message-id: 20201019151301.2046-7-peter.maydell@linaro.org
22
---
23
target/arm/cpu.h | 6 ++++++
24
target/arm/t32.decode | 13 ++++++++++++-
25
target/arm/translate.c | 20 ++++++++++++++++++++
26
3 files changed, 38 insertions(+), 1 deletion(-)
27
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
33
return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
34
}
35
36
+static inline bool isar_feature_aa32_lob(const ARMISARegisters *id)
37
+{
38
+ /* (M-profile) low-overhead loops and branch future */
39
+ return FIELD_EX32(id->id_isar0, ID_ISAR0, CMPBRANCH) >= 3;
40
+}
41
+
42
static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
43
{
44
return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
45
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/t32.decode
48
+++ b/target/arm/t32.decode
49
@@ -XXX,XX +XXX,XX @@ MRC 1110 1110 ... 1 .... .... .... ... 1 .... @mcr
50
51
B 1111 0. .......... 10.1 ............ @branch24
52
BL 1111 0. .......... 11.1 ............ @branch24
53
-BLX_i 1111 0. .......... 11.0 ............ @branch24
54
+{
55
+ # BLX_i is non-M-profile only
56
+ BLX_i 1111 0. .......... 11.0 ............ @branch24
57
+ # M-profile only: loop and branch insns
58
+ [
59
+ # All these BF insns have boff != 0b0000; we NOP them all
60
+ BF 1111 0 boff:4 ------- 1100 - ---------- 1 # BFL
61
+ BF 1111 0 boff:4 0 ------ 1110 - ---------- 1 # BFCSEL
62
+ BF 1111 0 boff:4 10 ----- 1110 - ---------- 1 # BF
63
+ BF 1111 0 boff:4 11 ----- 1110 0 0000000000 1 # BFX, BFLX
64
+ ]
65
+}
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
71
return true;
72
}
73
74
+static bool trans_BF(DisasContext *s, arg_BF *a)
75
+{
76
+ /*
77
+ * M-profile branch future insns. The architecture permits an
78
+ * implementation to implement these as NOPs (equivalent to
79
+ * discarding the LO_BRANCH_INFO cache immediately), and we
80
+ * take that IMPDEF option because for QEMU a "real" implementation
81
+ * would be complicated and wouldn't execute any faster.
82
+ */
83
+ if (!dc_isar_feature(aa32_lob, s)) {
84
+ return false;
85
+ }
86
+ if (a->boff == 0) {
87
+ /* SEE "Related encodings" (loop insns) */
88
+ return false;
89
+ }
90
+ /* Handle as NOP */
91
+ return true;
92
+}
93
+
94
static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
95
{
96
TCGv_i32 addr, tmp;
97
--
98
2.20.1
99
100
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The kernel sets btype for the signal handler as if for a call.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201016184207.786698-2-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
linux-user/aarch64/signal.c | 10 ++++++++--
11
1 file changed, 8 insertions(+), 2 deletions(-)
12
13
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/aarch64/signal.c
16
+++ b/linux-user/aarch64/signal.c
17
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
18
+ offsetof(struct target_rt_frame_record, tramp);
19
}
20
env->xregs[0] = usig;
21
- env->xregs[31] = frame_addr;
22
env->xregs[29] = frame_addr + fr_ofs;
23
- env->pc = ka->_sa_handler;
24
env->xregs[30] = return_addr;
25
+ env->xregs[31] = frame_addr;
26
+ env->pc = ka->_sa_handler;
27
+
28
+ /* Invoke the signal handler as if by indirect call. */
29
+ if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
30
+ env->btype = 2;
31
+ }
32
+
33
if (info) {
34
tswap_siginfo(&frame->info, info);
35
env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Transform the prot bit to a qemu internal page bit, and save
4
it in the page tables.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201016184207.786698-3-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/exec/cpu-all.h | 2 ++
12
linux-user/syscall_defs.h | 4 ++++
13
target/arm/cpu.h | 5 +++++
14
linux-user/mmap.c | 16 ++++++++++++++++
15
target/arm/translate-a64.c | 6 +++---
16
5 files changed, 30 insertions(+), 3 deletions(-)
17
18
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/exec/cpu-all.h
21
+++ b/include/exec/cpu-all.h
22
@@ -XXX,XX +XXX,XX @@ extern intptr_t qemu_host_page_mask;
23
/* FIXME: Code that sets/uses this is broken and needs to go away. */
24
#define PAGE_RESERVED 0x0020
25
#endif
26
+/* Target-specific bits that will be used via page_get_flags(). */
27
+#define PAGE_TARGET_1 0x0080
28
29
#if defined(CONFIG_USER_ONLY)
30
void page_dump(FILE *f);
31
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/linux-user/syscall_defs.h
34
+++ b/linux-user/syscall_defs.h
35
@@ -XXX,XX +XXX,XX @@ struct target_winsize {
36
#define TARGET_PROT_SEM 0x08
37
#endif
38
39
+#ifdef TARGET_AARCH64
40
+#define TARGET_PROT_BTI 0x10
41
+#endif
42
+
43
/* Common */
44
#define TARGET_MAP_SHARED    0x01        /* Share changes */
45
#define TARGET_MAP_PRIVATE    0x02        /* Changes are private */
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.h
49
+++ b/target/arm/cpu.h
50
@@ -XXX,XX +XXX,XX @@ static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs *x)
51
#define arm_tlb_bti_gp(x) (typecheck_memtxattrs(x)->target_tlb_bit0)
52
#define arm_tlb_mte_tagged(x) (typecheck_memtxattrs(x)->target_tlb_bit1)
53
54
+/*
55
+ * AArch64 usage of the PAGE_TARGET_* bits for linux-user.
56
+ */
57
+#define PAGE_BTI PAGE_TARGET_1
58
+
59
/*
60
* Naming convention for isar_feature functions:
61
* Functions which test 32-bit ID registers should have _aa32_ in
62
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/linux-user/mmap.c
65
+++ b/linux-user/mmap.c
66
@@ -XXX,XX +XXX,XX @@ static int validate_prot_to_pageflags(int *host_prot, int prot)
67
*host_prot = (prot & (PROT_READ | PROT_WRITE))
68
| (prot & PROT_EXEC ? PROT_READ : 0);
69
70
+#ifdef TARGET_AARCH64
71
+ /*
72
+ * The PROT_BTI bit is only accepted if the cpu supports the feature.
73
+ * Since this is the unusual case, don't bother checking unless
74
+ * the bit has been requested. If set and valid, record the bit
75
+ * within QEMU's page_flags.
76
+ */
77
+ if (prot & TARGET_PROT_BTI) {
78
+ ARMCPU *cpu = ARM_CPU(thread_cpu);
79
+ if (cpu_isar_feature(aa64_bti, cpu)) {
80
+ valid |= TARGET_PROT_BTI;
81
+ page_flags |= PAGE_BTI;
82
+ }
83
+ }
84
+#endif
85
+
86
return prot & ~valid ? 0 : page_flags;
87
}
88
89
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/translate-a64.c
92
+++ b/target/arm/translate-a64.c
93
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
94
*/
95
static bool is_guarded_page(CPUARMState *env, DisasContext *s)
96
{
97
-#ifdef CONFIG_USER_ONLY
98
- return false; /* FIXME */
99
-#else
100
uint64_t addr = s->base.pc_first;
101
+#ifdef CONFIG_USER_ONLY
102
+ return page_get_flags(addr) & PAGE_BTI;
103
+#else
104
int mmu_idx = arm_to_core_mmu_idx(s->mmu_idx);
105
unsigned int index = tlb_index(env, mmu_idx, addr);
106
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
107
--
108
2.20.1
109
110
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
These are all of the defines required to parse
4
GNU_PROPERTY_AARCH64_FEATURE_1_AND, copied from binutils.
5
Other missing defines related to other GNU program headers
6
and notes are elided for now.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20201016184207.786698-4-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/elf.h | 22 ++++++++++++++++++++++
14
1 file changed, 22 insertions(+)
15
16
diff --git a/include/elf.h b/include/elf.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/elf.h
19
+++ b/include/elf.h
20
@@ -XXX,XX +XXX,XX @@ typedef int64_t Elf64_Sxword;
21
#define PT_NOTE 4
22
#define PT_SHLIB 5
23
#define PT_PHDR 6
24
+#define PT_LOOS 0x60000000
25
+#define PT_HIOS 0x6fffffff
26
#define PT_LOPROC 0x70000000
27
#define PT_HIPROC 0x7fffffff
28
29
+#define PT_GNU_PROPERTY (PT_LOOS + 0x474e553)
30
+
31
#define PT_MIPS_REGINFO 0x70000000
32
#define PT_MIPS_RTPROC 0x70000001
33
#define PT_MIPS_OPTIONS 0x70000002
34
@@ -XXX,XX +XXX,XX @@ typedef struct elf64_shdr {
35
#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
36
#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension regs */
37
38
+/* Defined note types for GNU systems. */
39
+
40
+#define NT_GNU_PROPERTY_TYPE_0 5 /* Program property */
41
+
42
+/* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). */
43
+
44
+#define GNU_PROPERTY_STACK_SIZE 1
45
+#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
46
+
47
+#define GNU_PROPERTY_LOPROC 0xc0000000
48
+#define GNU_PROPERTY_HIPROC 0xdfffffff
49
+#define GNU_PROPERTY_LOUSER 0xe0000000
50
+#define GNU_PROPERTY_HIUSER 0xffffffff
51
+
52
+#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
53
+#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1u << 0)
54
+#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1u << 1)
55
+
56
/*
57
* Physical entry point into the kernel.
58
*
59
--
60
2.20.1
61
62
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Fix an unlikely memory leak in load_elf_image().
4
5
Fixes: bf858897b7 ("linux-user: Re-use load_elf_image for the main binary.")
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201016184207.786698-5-richard.henderson@linaro.org
9
Message-Id: <20201003174944.1972444-1-f4bug@amsat.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
linux-user/elfload.c | 8 ++++----
15
1 file changed, 4 insertions(+), 4 deletions(-)
16
17
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/linux-user/elfload.c
20
+++ b/linux-user/elfload.c
21
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
22
info->brk = vaddr_em;
23
}
24
} else if (eppnt->p_type == PT_INTERP && pinterp_name) {
25
- char *interp_name;
26
+ g_autofree char *interp_name = NULL;
27
28
if (*pinterp_name) {
29
errmsg = "Multiple PT_INTERP entries";
30
goto exit_errmsg;
31
}
32
- interp_name = malloc(eppnt->p_filesz);
33
+ interp_name = g_malloc(eppnt->p_filesz);
34
if (!interp_name) {
35
goto exit_perror;
36
}
37
@@ -XXX,XX +XXX,XX @@ static void load_elf_image(const char *image_name, int image_fd,
38
errmsg = "Invalid PT_INTERP entry";
39
goto exit_errmsg;
40
}
41
- *pinterp_name = interp_name;
42
+ *pinterp_name = g_steal_pointer(&interp_name);
43
#ifdef TARGET_MIPS
44
} else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
45
Mips_elf_abiflags_v0 abiflags;
46
@@ -XXX,XX +XXX,XX @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
47
if (elf_interpreter) {
48
info->load_bias = interp_info.load_bias;
49
info->entry = interp_info.entry;
50
- free(elf_interpreter);
51
+ g_free(elf_interpreter);
52
}
53
54
#ifdef USE_ELF_CORE_DUMP
55
--
56
2.20.1
57
58
diff view generated by jsdifflib