1
target-arm queue. This has the "plumb txattrs through various
1
Hi; here's a target-arm pullreq to go in before softfreeze.
2
bits of exec.c" patches, and a collection of bug fixes from
2
This is actually pretty much entirely bugfixes (since the
3
various people.
3
SEL2 timers we implement here are a missing part of a feature
4
we claim to already implement).
4
5
5
thanks
6
thanks
6
-- PMM
7
-- PMM
7
8
9
The following changes since commit 98c7362b1efe651327385a25874a73e008c6549e:
8
10
9
11
Merge tag 'accel-cpus-20250306' of https://github.com/philmd/qemu into staging (2025-03-07 07:39:49 +0800)
10
The following changes since commit a3ac12fba028df90f7b3dbec924995c126c41022:
11
12
Merge remote-tracking branch 'remotes/ehabkost/tags/numa-next-pull-request' into staging (2018-05-31 11:12:36 +0100)
13
12
14
are available in the Git repository at:
13
are available in the Git repository at:
15
14
16
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180531
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20250307
17
16
18
for you to fetch changes up to 49d1dca0520ea71bc21867fab6647f474fcf857b:
17
for you to fetch changes up to 0ce0739d46983e5e88fa9c149cb305689c9d8c6f:
19
18
20
KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice (2018-05-31 14:52:53 +0100)
19
target/rx: Remove TCG_CALL_NO_WG from helpers which write env (2025-03-07 15:03:20 +0000)
21
20
22
----------------------------------------------------------------
21
----------------------------------------------------------------
23
target-arm queue:
22
target-arm queue:
24
* target/arm: Honour FPCR.FZ in FRECPX
23
* hw/arm/smmu-common: Remove the repeated ttb field
25
* MAINTAINERS: Add entries for newer MPS2 boards and devices
24
* hw/gpio: npcm7xx: fixup out-of-bounds access
26
* hw/intc/arm_gicv3: Fix APxR<n> register dispatching
25
* tests/functional/test_arm_sx1: Check whether the serial console is working
27
* arm_gicv3_kvm: fix bug in writing zero bits back to the in-kernel
26
* target/arm: Fix minor bugs in generic timer register handling
28
GIC state
27
* target/arm: Implement SEL2 physical and virtual timers
29
* tcg: Fix helper function vs host abi for float16
28
* target/arm: Correct STRD, LDRD atomicity and fault behaviour
30
* arm: fix qemu crash on startup with -bios option
29
* target/arm: Make dummy debug registers RAZ, not NOP
31
* arm: fix malloc type mismatch
30
* util/qemu-timer.c: Don't warp timer from timerlist_rearm()
32
* xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors
31
* include/exec/memop.h: Expand comment for MO_ATOM_SUBALIGN
33
* Correct CPACR reset value for v7 cores
32
* hw/arm/smmu: Introduce smmu_configs_inv_sid_range() helper
34
* memory.h: Improve IOMMU related documentation
33
* target/rx: Set exception vector base to 0xffffff80
35
* exec: Plumb transaction attributes through various functions in
34
* target/rx: Remove TCG_CALL_NO_WG from helpers which write env
36
preparation for allowing IOMMUs to see them
37
* vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY
38
* ARM: ACPI: Fix use-after-free due to memory realloc
39
* KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice
40
35
41
----------------------------------------------------------------
36
----------------------------------------------------------------
42
Francisco Iglesias (1):
37
Alex Bennée (4):
43
xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors
38
target/arm: Implement SEL2 physical and virtual timers
39
target/arm: Document the architectural names of our GTIMERs
40
hw/arm: enable secure EL2 timers for virt machine
41
hw/arm: enable secure EL2 timers for sbsa machine
44
42
45
Igor Mammedov (1):
43
JianChunfu (2):
46
arm: fix qemu crash on startup with -bios option
44
hw/arm/smmu-common: Remove the repeated ttb field
45
hw/arm/smmu: Introduce smmu_configs_inv_sid_range() helper
47
46
48
Jan Kiszka (1):
47
Keith Packard (2):
49
hw/intc/arm_gicv3: Fix APxR<n> register dispatching
48
target/rx: Set exception vector base to 0xffffff80
49
target/rx: Remove TCG_CALL_NO_WG from helpers which write env
50
50
51
Paolo Bonzini (1):
51
Patrick Venture (1):
52
arm: fix malloc type mismatch
52
hw/gpio: npcm7xx: fixup out-of-bounds access
53
53
54
Peter Maydell (17):
54
Peter Maydell (11):
55
target/arm: Honour FPCR.FZ in FRECPX
55
target/arm: Apply correct timer offset when calculating deadlines
56
MAINTAINERS: Add entries for newer MPS2 boards and devices
56
target/arm: Don't apply CNTVOFF_EL2 for EL2_VIRT timer
57
Correct CPACR reset value for v7 cores
57
target/arm: Make CNTPS_* UNDEF from Secure EL1 when Secure EL2 is enabled
58
memory.h: Improve IOMMU related documentation
58
target/arm: Always apply CNTVOFF_EL2 for CNTV_TVAL_EL02 accesses
59
Make tb_invalidate_phys_addr() take a MemTxAttrs argument
59
target/arm: Refactor handling of timer offset for direct register accesses
60
Make address_space_translate{, _cached}() take a MemTxAttrs argument
60
target/arm: Correct LDRD atomicity and fault behaviour
61
Make address_space_map() take a MemTxAttrs argument
61
target/arm: Correct STRD atomicity
62
Make address_space_access_valid() take a MemTxAttrs argument
62
target/arm: Drop unused address_offset from op_addr_{rr, ri}_post()
63
Make flatview_extend_translation() take a MemTxAttrs argument
63
target/arm: Make dummy debug registers RAZ, not NOP
64
Make memory_region_access_valid() take a MemTxAttrs argument
64
util/qemu-timer.c: Don't warp timer from timerlist_rearm()
65
Make MemoryRegion valid.accepts callback take a MemTxAttrs argument
65
include/exec/memop.h: Expand comment for MO_ATOM_SUBALIGN
66
Make flatview_access_valid() take a MemTxAttrs argument
67
Make flatview_translate() take a MemTxAttrs argument
68
Make address_space_get_iotlb_entry() take a MemTxAttrs argument
69
Make flatview_do_translate() take a MemTxAttrs argument
70
Make address_space_translate_iommu take a MemTxAttrs argument
71
vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY
72
66
73
Richard Henderson (1):
67
Thomas Huth (1):
74
tcg: Fix helper function vs host abi for float16
68
tests/functional/test_arm_sx1: Check whether the serial console is working
75
69
76
Shannon Zhao (3):
70
MAINTAINERS | 1 +
77
arm_gicv3_kvm: increase clroffset accordingly
71
hw/arm/smmu-internal.h | 5 -
78
ARM: ACPI: Fix use-after-free due to memory realloc
72
include/exec/memop.h | 8 +-
79
KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice
73
include/hw/arm/bsa.h | 2 +
74
include/hw/arm/smmu-common.h | 7 +-
75
target/arm/cpu.h | 2 +
76
target/arm/gtimer.h | 14 +-
77
target/arm/internals.h | 5 +-
78
target/rx/helper.h | 34 ++--
79
hw/arm/sbsa-ref.c | 2 +
80
hw/arm/smmu-common.c | 21 +++
81
hw/arm/smmuv3.c | 19 +--
82
hw/arm/virt.c | 2 +
83
hw/gpio/npcm7xx_gpio.c | 3 +-
84
target/arm/cpu.c | 4 +
85
target/arm/debug_helper.c | 7 +-
86
target/arm/helper.c | 324 ++++++++++++++++++++++++++++++++-------
87
target/arm/tcg/op_helper.c | 8 +-
88
target/arm/tcg/translate.c | 147 +++++++++++-------
89
target/rx/helper.c | 2 +-
90
util/qemu-timer.c | 4 -
91
hw/arm/trace-events | 3 +-
92
tests/functional/test_arm_sx1.py | 7 +-
93
23 files changed, 455 insertions(+), 176 deletions(-)
80
94
81
include/exec/exec-all.h | 5 +-
82
include/exec/helper-head.h | 2 +-
83
include/exec/memory-internal.h | 3 +-
84
include/exec/memory.h | 128 +++++++++++++++++++++++++++++++++++------
85
include/migration/vmstate.h | 3 +
86
include/sysemu/dma.h | 6 +-
87
accel/tcg/translate-all.c | 4 +-
88
exec.c | 95 ++++++++++++++++++------------
89
hw/arm/boot.c | 18 +++---
90
hw/arm/virt-acpi-build.c | 20 +++++--
91
hw/dma/xlnx-zdma.c | 10 +++-
92
hw/hppa/dino.c | 3 +-
93
hw/intc/arm_gic_kvm.c | 1 -
94
hw/intc/arm_gicv3_cpuif.c | 12 ++--
95
hw/intc/arm_gicv3_kvm.c | 2 +-
96
hw/nvram/fw_cfg.c | 12 ++--
97
hw/s390x/s390-pci-inst.c | 3 +-
98
hw/scsi/esp.c | 3 +-
99
hw/vfio/common.c | 3 +-
100
hw/virtio/vhost.c | 3 +-
101
hw/xen/xen_pt_msi.c | 3 +-
102
memory.c | 12 ++--
103
memory_ldst.inc.c | 18 +++---
104
target/arm/gdbstub.c | 3 +-
105
target/arm/helper-a64.c | 41 +++++++------
106
target/arm/helper.c | 90 ++++++++++++++++-------------
107
target/ppc/mmu-hash64.c | 3 +-
108
target/riscv/helper.c | 2 +-
109
target/s390x/diag.c | 6 +-
110
target/s390x/excp_helper.c | 3 +-
111
target/s390x/mmu_helper.c | 3 +-
112
target/s390x/sigp.c | 3 +-
113
target/xtensa/op_helper.c | 3 +-
114
MAINTAINERS | 9 ++-
115
34 files changed, 353 insertions(+), 182 deletions(-)
116
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: JianChunfu <jansef.jian@hj-micro.com>
2
add MemTxAttrs as an argument to flatview_do_translate().
3
2
3
SMMUTransCfg->ttb is never used in QEMU, TT base address
4
can be accessed by SMMUTransCfg->tt[i]->ttb.
5
6
Signed-off-by: JianChunfu <jansef.jian@hj-micro.com>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20250221031034.69822-1-jansef.jian@hj-micro.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180521140402.23318-13-peter.maydell@linaro.org
8
---
10
---
9
exec.c | 9 ++++++---
11
include/hw/arm/smmu-common.h | 1 -
10
1 file changed, 6 insertions(+), 3 deletions(-)
12
1 file changed, 1 deletion(-)
11
13
12
diff --git a/exec.c b/exec.c
14
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/exec.c
16
--- a/include/hw/arm/smmu-common.h
15
+++ b/exec.c
17
+++ b/include/hw/arm/smmu-common.h
16
@@ -XXX,XX +XXX,XX @@ unassigned:
18
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
17
* @is_write: whether the translation operation is for write
19
/* Used by stage-1 only. */
18
* @is_mmio: whether this can be MMIO, set true if it can
20
bool aa64; /* arch64 or aarch32 translation table */
19
* @target_as: the address space targeted by the IOMMU
21
bool record_faults; /* record fault events */
20
+ * @attrs: memory transaction attributes
22
- uint64_t ttb; /* TT base address */
21
*
23
uint8_t oas; /* output address width */
22
* This function is called from RCU critical section
24
uint8_t tbi; /* Top Byte Ignore */
23
*/
25
int asid;
24
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
25
hwaddr *page_mask_out,
26
bool is_write,
27
bool is_mmio,
28
- AddressSpace **target_as)
29
+ AddressSpace **target_as,
30
+ MemTxAttrs attrs)
31
{
32
MemoryRegionSection *section;
33
IOMMUMemoryRegion *iommu_mr;
34
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
35
* but page mask.
36
*/
37
section = flatview_do_translate(address_space_to_flatview(as), addr, &xlat,
38
- NULL, &page_mask, is_write, false, &as);
39
+ NULL, &page_mask, is_write, false, &as,
40
+ attrs);
41
42
/* Illegal translation */
43
if (section.mr == &io_mem_unassigned) {
44
@@ -XXX,XX +XXX,XX @@ MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
45
46
/* This can be MMIO, so setup MMIO bit. */
47
section = flatview_do_translate(fv, addr, xlat, plen, NULL,
48
- is_write, true, &as);
49
+ is_write, true, &as, attrs);
50
mr = section.mr;
51
52
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
53
--
26
--
54
2.17.1
27
2.43.0
55
56
diff view generated by jsdifflib
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
acpi_data_push uses g_array_set_size to resize the memory size. If there
3
The reg isn't validated to be a possible register before
4
is no enough contiguous memory, the address will be changed. So previous
4
it's dereferenced for one case. The mmio space registered
5
pointer could not be used any more. It must update the pointer and use
5
for the gpio device is 4KiB but there aren't that many
6
the new one.
6
registers in the struct.
7
7
8
Also, previous codes wrongly use le32 conversion of iort->node_offset
8
Cc: qemu-stable@nongnu.org
9
for subsequent computations that will result incorrect value if host is
9
Fixes: 526dbbe0874 ("hw/gpio: Add GPIO model for Nuvoton NPCM7xx")
10
not litlle endian. So use the non-converted one instead.
10
Signed-off-by: Patrick Venture <venture@google.com>
11
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
12
Message-id: 20250226024603.493148-1-venture@google.com
13
Reviewed-by: Eric Auger <eric.auger@redhat.com>
14
Message-id: 1527663951-14552-1-git-send-email-zhaoshenglong@huawei.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
14
---
17
hw/arm/virt-acpi-build.c | 20 +++++++++++++++-----
15
hw/gpio/npcm7xx_gpio.c | 3 +--
18
1 file changed, 15 insertions(+), 5 deletions(-)
16
1 file changed, 1 insertion(+), 2 deletions(-)
19
17
20
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
18
diff --git a/hw/gpio/npcm7xx_gpio.c b/hw/gpio/npcm7xx_gpio.c
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/virt-acpi-build.c
20
--- a/hw/gpio/npcm7xx_gpio.c
23
+++ b/hw/arm/virt-acpi-build.c
21
+++ b/hw/gpio/npcm7xx_gpio.c
24
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
22
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_gpio_regs_write(void *opaque, hwaddr addr, uint64_t v,
25
AcpiIortItsGroup *its;
23
return;
26
AcpiIortTable *iort;
27
AcpiIortSmmu3 *smmu;
28
- size_t node_size, iort_length, smmu_offset = 0;
29
+ size_t node_size, iort_node_offset, iort_length, smmu_offset = 0;
30
AcpiIortRC *rc;
31
32
iort = acpi_data_push(table_data, sizeof(*iort));
33
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
34
35
iort_length = sizeof(*iort);
36
iort->node_count = cpu_to_le32(nb_nodes);
37
- iort->node_offset = cpu_to_le32(sizeof(*iort));
38
+ /*
39
+ * Use a copy in case table_data->data moves during acpi_data_push
40
+ * operations.
41
+ */
42
+ iort_node_offset = sizeof(*iort);
43
+ iort->node_offset = cpu_to_le32(iort_node_offset);
44
45
/* ITS group node */
46
node_size = sizeof(*its) + sizeof(uint32_t);
47
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
48
int irq = vms->irqmap[VIRT_SMMU];
49
50
/* SMMUv3 node */
51
- smmu_offset = iort->node_offset + node_size;
52
+ smmu_offset = iort_node_offset + node_size;
53
node_size = sizeof(*smmu) + sizeof(*idmap);
54
iort_length += node_size;
55
smmu = acpi_data_push(table_data, node_size);
56
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
57
idmap->id_count = cpu_to_le32(0xFFFF);
58
idmap->output_base = 0;
59
/* output IORT node is the ITS group node (the first node) */
60
- idmap->output_reference = cpu_to_le32(iort->node_offset);
61
+ idmap->output_reference = cpu_to_le32(iort_node_offset);
62
}
24
}
63
25
64
/* Root Complex Node */
26
- diff = s->regs[reg] ^ value;
65
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
27
-
66
idmap->output_reference = cpu_to_le32(smmu_offset);
28
switch (reg) {
67
} else {
29
case NPCM7XX_GPIO_TLOCK1:
68
/* output IORT node is the ITS group node (the first node) */
30
case NPCM7XX_GPIO_TLOCK2:
69
- idmap->output_reference = cpu_to_le32(iort->node_offset);
31
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_gpio_regs_write(void *opaque, hwaddr addr, uint64_t v,
70
+ idmap->output_reference = cpu_to_le32(iort_node_offset);
32
case NPCM7XX_GPIO_PU:
71
}
33
case NPCM7XX_GPIO_PD:
72
34
case NPCM7XX_GPIO_IEM:
73
+ /*
35
+ diff = s->regs[reg] ^ value;
74
+ * Update the pointer address in case table_data->data moves during above
36
s->regs[reg] = value;
75
+ * acpi_data_push operations.
37
npcm7xx_gpio_update_pins(s, diff);
76
+ */
38
break;
77
+ iort = (AcpiIortTable *)(table_data->data + iort_start);
78
iort->length = cpu_to_le32(iort_length);
79
80
build_header(linker, table_data, (void *)(table_data->data + iort_start),
81
--
39
--
82
2.17.1
40
2.43.0
83
41
84
42
diff view generated by jsdifflib
1
Add entries to MAINTAINERS to cover the newer MPS2 boards and
1
From: Thomas Huth <thuth@redhat.com>
2
the new devices they use.
3
2
3
The kernel that is used in the sx1 test prints the usual Linux log
4
onto the serial console, but this test currently ignores it. To
5
make sure that the serial device is working properly, let's check
6
for some strings in the output here.
7
8
While we're at it, also add the test to the corresponding section
9
in the MAINTAINERS file.
10
11
Signed-off-by: Thomas Huth <thuth@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-id: 20250226104833.1176253-1-thuth@redhat.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180518153157.14899-1-peter.maydell@linaro.org
6
---
15
---
7
MAINTAINERS | 9 +++++++--
16
MAINTAINERS | 1 +
8
1 file changed, 7 insertions(+), 2 deletions(-)
17
tests/functional/test_arm_sx1.py | 7 ++++---
18
2 files changed, 5 insertions(+), 3 deletions(-)
9
19
10
diff --git a/MAINTAINERS b/MAINTAINERS
20
diff --git a/MAINTAINERS b/MAINTAINERS
11
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
12
--- a/MAINTAINERS
22
--- a/MAINTAINERS
13
+++ b/MAINTAINERS
23
+++ b/MAINTAINERS
14
@@ -XXX,XX +XXX,XX @@ F: hw/timer/cmsdk-apb-timer.c
24
@@ -XXX,XX +XXX,XX @@ S: Maintained
15
F: include/hw/timer/cmsdk-apb-timer.h
25
F: hw/*/omap*
16
F: hw/char/cmsdk-apb-uart.c
26
F: include/hw/arm/omap.h
17
F: include/hw/char/cmsdk-apb-uart.h
27
F: docs/system/arm/sx1.rst
18
+F: hw/misc/tz-ppc.c
28
+F: tests/functional/test_arm_sx1.py
19
+F: include/hw/misc/tz-ppc.h
29
20
30
IPack
21
ARM cores
31
M: Alberto Garcia <berto@igalia.com>
22
M: Peter Maydell <peter.maydell@linaro.org>
32
diff --git a/tests/functional/test_arm_sx1.py b/tests/functional/test_arm_sx1.py
23
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
33
index XXXXXXX..XXXXXXX 100755
24
L: qemu-arm@nongnu.org
34
--- a/tests/functional/test_arm_sx1.py
25
S: Maintained
35
+++ b/tests/functional/test_arm_sx1.py
26
F: hw/arm/mps2.c
36
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_initrd(self):
27
-F: hw/misc/mps2-scc.c
37
self.vm.add_args('-append', f'kunit.enable=0 rdinit=/sbin/init {self.CONSOLE_ARGS}')
28
-F: include/hw/misc/mps2-scc.h
38
self.vm.add_args('-no-reboot')
29
+F: hw/arm/mps2-tz.c
39
self.launch_kernel(zimage_path,
30
+F: hw/misc/mps2-*.c
40
- initrd=initrd_path)
31
+F: include/hw/misc/mps2-*.h
41
+ initrd=initrd_path,
32
+F: hw/arm/iotkit.c
42
+ wait_for='Boot successful')
33
+F: include/hw/arm/iotkit.h
43
self.vm.wait(timeout=120)
34
44
35
Musicpal
45
def test_arm_sx1_sd(self):
36
M: Jan Kiszka <jan.kiszka@web.de>
46
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_sd(self):
47
self.vm.add_args('-no-reboot')
48
self.vm.add_args('-snapshot')
49
self.vm.add_args('-drive', f'format=raw,if=sd,file={sd_fs_path}')
50
- self.launch_kernel(zimage_path)
51
+ self.launch_kernel(zimage_path, wait_for='Boot successful')
52
self.vm.wait(timeout=120)
53
54
def test_arm_sx1_flash(self):
55
@@ -XXX,XX +XXX,XX @@ def test_arm_sx1_flash(self):
56
self.vm.add_args('-no-reboot')
57
self.vm.add_args('-snapshot')
58
self.vm.add_args('-drive', f'format=raw,if=pflash,file={flash_path}')
59
- self.launch_kernel(zimage_path)
60
+ self.launch_kernel(zimage_path, wait_for='Boot successful')
61
self.vm.wait(timeout=120)
62
63
if __name__ == '__main__':
37
--
64
--
38
2.17.1
65
2.43.0
39
66
40
67
diff view generated by jsdifflib
1
In commit f0aff255700 we made cpacr_write() enforce that some CPACR
1
When we are calculating timer deadlines, the correct definition of
2
bits are RAZ/WI and some are RAO/WI for ARMv7 cores. Unfortunately
2
whether or not to apply an offset to the physical count is described
3
we forgot to also update the register's reset value. The effect
3
in the Arm ARM DDI4087 rev L.a section D12.2.4.1. This is different
4
was that (a) a guest that read CPACR on reset would not see ones in
4
from when the offset should be applied for a direct read of the
5
the RAO bits, and (b) if you did a migration before the guest did
5
counter sysreg.
6
a write to the CPACR then the migration would fail because the
7
destination would enforce the RAO bits and then complain that they
8
didn't match the zero value from the source.
9
6
10
Implement reset for the CPACR using a custom reset function
7
We got this right for the EL1 physical timer and for the EL1 virtual
11
that just calls cpacr_write(), to avoid having to duplicate
8
timer, but got all the rest wrong: they should be using a zero offset
12
the logic for which bits are RAO.
9
always.
13
10
14
This bug would affect migration for TCG CPUs which are ARMv7
11
Factor the offset calculation out into a function that has a comment
15
with VFP but without one of Neon or VFPv3.
12
documenting exactly which offset it is calculating and which gets the
13
HYP, SEC, and HYPVIRT cases right.
16
14
17
Reported-by: Cédric Le Goater <clg@kaod.org>
15
Cc: qemu-stable@nongnu.org
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Tested-by: Cédric Le Goater <clg@kaod.org>
17
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Message-id: 20180522173713.26282-1-peter.maydell@linaro.org
18
Message-id: 20250204125009.2281315-2-peter.maydell@linaro.org
21
---
19
---
22
target/arm/helper.c | 10 +++++++++-
20
target/arm/helper.c | 29 +++++++++++++++++++++++++++--
23
1 file changed, 9 insertions(+), 1 deletion(-)
21
1 file changed, 27 insertions(+), 2 deletions(-)
24
22
25
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/helper.c
25
--- a/target/arm/helper.c
28
+++ b/target/arm/helper.c
26
+++ b/target/arm/helper.c
29
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
27
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_phys_cnt_offset(CPUARMState *env)
30
env->cp15.cpacr_el1 = value;
28
return gt_phys_raw_cnt_offset(env);
31
}
29
}
32
30
33
+static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
31
+static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
34
+{
32
+{
35
+ /* Call cpacr_write() so that we reset with the correct RAO bits set
33
+ /*
36
+ * for our CPU features.
34
+ * Return the timer offset to use for indirect accesses to the timer.
35
+ * This is the Offset value as defined in D12.2.4.1 "Operation of the
36
+ * CompareValue views of the timers".
37
+ *
38
+ * The condition here is not always the same as the condition for
39
+ * whether to apply an offset register when doing a direct read of
40
+ * the counter sysreg; those conditions are described in the
41
+ * access pseudocode for each counter register.
37
+ */
42
+ */
38
+ cpacr_write(env, ri, 0);
43
+ switch (timeridx) {
44
+ case GTIMER_PHYS:
45
+ return gt_phys_raw_cnt_offset(env);
46
+ case GTIMER_VIRT:
47
+ return env->cp15.cntvoff_el2;
48
+ case GTIMER_HYP:
49
+ case GTIMER_SEC:
50
+ case GTIMER_HYPVIRT:
51
+ return 0;
52
+ default:
53
+ g_assert_not_reached();
54
+ }
39
+}
55
+}
40
+
56
+
41
static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
57
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
42
bool isread)
43
{
58
{
44
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
59
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
45
{ .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
60
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
46
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
61
* Timer enabled: calculate and set current ISTATUS, irq, and
47
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
62
* reset timer to when ISTATUS next has to change
48
- .resetvalue = 0, .writefn = cpacr_write },
63
*/
49
+ .resetfn = cpacr_reset, .writefn = cpacr_write },
64
- uint64_t offset = timeridx == GTIMER_VIRT ?
50
REGINFO_SENTINEL
65
- cpu->env.cp15.cntvoff_el2 : gt_phys_raw_cnt_offset(&cpu->env);
51
};
66
+ uint64_t offset = gt_indirect_access_timer_offset(&cpu->env, timeridx);
52
67
uint64_t count = gt_get_countervalue(&cpu->env);
68
/* Note that this must be unsigned 64 bit arithmetic: */
69
int istatus = count - offset >= gt->cval;
53
--
70
--
54
2.17.1
71
2.43.0
55
72
56
73
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
The CNTVOFF_EL2 offset register should only be applied for accessses
2
add MemTxAttrs as an argument to address_space_get_iotlb_entry().
2
to CNTVCT_EL0 and for the EL1 virtual timer (CNTV_*). We were
3
incorrectly applying it for the EL2 virtual timer (CNTHV_*).
3
4
5
Cc: qemu-stable@nongnu.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20250204125009.2281315-3-peter.maydell@linaro.org
7
Message-id: 20180521140402.23318-12-peter.maydell@linaro.org
8
---
9
---
9
include/exec/memory.h | 2 +-
10
target/arm/helper.c | 2 --
10
exec.c | 2 +-
11
1 file changed, 2 deletions(-)
11
hw/virtio/vhost.c | 3 ++-
12
3 files changed, 4 insertions(+), 3 deletions(-)
13
12
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/memory.h
15
--- a/target/arm/helper.c
17
+++ b/include/exec/memory.h
16
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ void address_space_cache_destroy(MemoryRegionCache *cache);
17
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
19
* entry. Should be called from an RCU critical section.
18
20
*/
19
switch (timeridx) {
21
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
20
case GTIMER_VIRT:
22
- bool is_write);
21
- case GTIMER_HYPVIRT:
23
+ bool is_write, MemTxAttrs attrs);
22
offset = gt_virt_cnt_offset(env);
24
23
break;
25
/* address_space_translate: translate an address range into an address space
24
case GTIMER_PHYS:
26
* into a MemoryRegion and an address range into that section. Should be
25
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
27
diff --git a/exec.c b/exec.c
26
28
index XXXXXXX..XXXXXXX 100644
27
switch (timeridx) {
29
--- a/exec.c
28
case GTIMER_VIRT:
30
+++ b/exec.c
29
- case GTIMER_HYPVIRT:
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
30
offset = gt_virt_cnt_offset(env);
32
31
break;
33
/* Called from RCU critical section */
32
case GTIMER_PHYS:
34
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
35
- bool is_write)
36
+ bool is_write, MemTxAttrs attrs)
37
{
38
MemoryRegionSection section;
39
hwaddr xlat, page_mask;
40
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/virtio/vhost.c
43
+++ b/hw/virtio/vhost.c
44
@@ -XXX,XX +XXX,XX @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
45
trace_vhost_iotlb_miss(dev, 1);
46
47
iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
48
- iova, write);
49
+ iova, write,
50
+ MEMTXATTRS_UNSPECIFIED);
51
if (iotlb.target_as != NULL) {
52
ret = vhost_memory_region_lookup(dev, iotlb.translated_addr,
53
&uaddr, &len);
54
--
33
--
55
2.17.1
34
2.43.0
56
35
57
36
diff view generated by jsdifflib
1
Provide a VMSTATE_BOOL_SUB_ARRAY to go with VMSTATE_UINT8_SUB_ARRAY
1
When we added Secure EL2 support, we missed that this needs an update
2
and friends.
2
to the access code for the EL3 physical timer registers. These are
3
supposed to UNDEF from Secure EL1 when Secure EL2 is enabled.
3
4
5
(Note for stable backporting: for backports to branches where
6
CP_ACCESS_UNDEFINED is not defined, the old name to use instead
7
is CP_ACCESS_TRAP_UNCATEGORIZED.)
8
9
Cc: qemu-stable@nongnu.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180521140402.23318-23-peter.maydell@linaro.org
12
Message-id: 20250204125009.2281315-4-peter.maydell@linaro.org
7
---
13
---
8
include/migration/vmstate.h | 3 +++
14
target/arm/helper.c | 3 +++
9
1 file changed, 3 insertions(+)
15
1 file changed, 3 insertions(+)
10
16
11
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/include/migration/vmstate.h
19
--- a/target/arm/helper.c
14
+++ b/include/migration/vmstate.h
20
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
21
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
16
#define VMSTATE_BOOL_ARRAY(_f, _s, _n) \
22
if (!arm_is_secure(env)) {
17
VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0)
23
return CP_ACCESS_UNDEFINED;
18
24
}
19
+#define VMSTATE_BOOL_SUB_ARRAY(_f, _s, _start, _num) \
25
+ if (arm_is_el2_enabled(env)) {
20
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_bool, bool)
26
+ return CP_ACCESS_UNDEFINED;
21
+
27
+ }
22
#define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v) \
28
if (!(env->cp15.scr_el3 & SCR_ST)) {
23
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t)
29
return CP_ACCESS_TRAP_EL3;
24
30
}
25
--
31
--
26
2.17.1
32
2.43.0
27
33
28
34
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
Currently we handle CNTV_TVAL_EL02 by calling gt_tval_read() for the
2
add MemTxAttrs as an argument to the MemoryRegion valid.accepts
2
EL1 virt timer. This is almost correct, but the underlying
3
callback. We'll need this for subpage_accepts().
3
CNTV_TVAL_EL0 register behaves slightly differently. CNTV_TVAL_EL02
4
always applies the CNTVOFF_EL2 offset; CNTV_TVAL_EL0 doesn't do so if
5
we're at EL2 and HCR_EL2.E2H is 1.
4
6
5
We could take the approach we used with the read and write
7
We were getting this wrong, because we ended up in
6
callbacks and add new a new _with_attrs version, but since there
8
gt_virt_cnt_offset() and did the E2H check.
7
are so few implementations of the accepts hook we just change
8
them all.
9
9
10
Factor out the tval read/write calculation from the selection of the
11
offset, so that we can special case gt_virt_tval_read() and
12
gt_virt_tval_write() to unconditionally pass CNTVOFF_EL2.
13
14
Cc: qemu-stable@nongnu.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20250204125009.2281315-5-peter.maydell@linaro.org
13
Message-id: 20180521140402.23318-9-peter.maydell@linaro.org
14
---
18
---
15
include/exec/memory.h | 3 ++-
19
target/arm/helper.c | 36 +++++++++++++++++++++++++++---------
16
exec.c | 9 ++++++---
20
1 file changed, 27 insertions(+), 9 deletions(-)
17
hw/hppa/dino.c | 3 ++-
18
hw/nvram/fw_cfg.c | 12 ++++++++----
19
hw/scsi/esp.c | 3 ++-
20
hw/xen/xen_pt_msi.c | 3 ++-
21
memory.c | 5 +++--
22
7 files changed, 25 insertions(+), 13 deletions(-)
23
21
24
diff --git a/include/exec/memory.h b/include/exec/memory.h
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
26
--- a/include/exec/memory.h
24
--- a/target/arm/helper.c
27
+++ b/include/exec/memory.h
25
+++ b/target/arm/helper.c
28
@@ -XXX,XX +XXX,XX @@ struct MemoryRegionOps {
26
@@ -XXX,XX +XXX,XX @@ static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
29
* as a machine check exception).
27
gt_recalc_timer(env_archcpu(env), timeridx);
30
*/
31
bool (*accepts)(void *opaque, hwaddr addr,
32
- unsigned size, bool is_write);
33
+ unsigned size, bool is_write,
34
+ MemTxAttrs attrs);
35
} valid;
36
/* Internal implementation constraints: */
37
struct {
38
diff --git a/exec.c b/exec.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/exec.c
41
+++ b/exec.c
42
@@ -XXX,XX +XXX,XX @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
43
}
28
}
44
29
45
static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
30
+static uint64_t do_tval_read(CPUARMState *env, int timeridx, uint64_t offset)
46
- unsigned size, bool is_write)
31
+{
47
+ unsigned size, bool is_write,
32
+ return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
48
+ MemTxAttrs attrs)
33
+ (gt_get_countervalue(env) - offset));
34
+}
35
+
36
static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
37
int timeridx)
49
{
38
{
50
return is_write;
39
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
40
break;
41
}
42
43
- return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
44
- (gt_get_countervalue(env) - offset));
45
+ return do_tval_read(env, timeridx, offset);
46
+}
47
+
48
+static void do_tval_write(CPUARMState *env, int timeridx, uint64_t value,
49
+ uint64_t offset)
50
+{
51
+ trace_arm_gt_tval_write(timeridx, value);
52
+ env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset +
53
+ sextract64(value, 0, 32);
54
+ gt_recalc_timer(env_archcpu(env), timeridx);
51
}
55
}
52
@@ -XXX,XX +XXX,XX @@ static MemTxResult subpage_write(void *opaque, hwaddr addr,
56
57
static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
58
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
59
offset = gt_phys_cnt_offset(env);
60
break;
61
}
62
-
63
- trace_arm_gt_tval_write(timeridx, value);
64
- env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset +
65
- sextract64(value, 0, 32);
66
- gt_recalc_timer(env_archcpu(env), timeridx);
67
+ do_tval_write(env, timeridx, value, offset);
53
}
68
}
54
69
55
static bool subpage_accepts(void *opaque, hwaddr addr,
70
static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
56
- unsigned len, bool is_write)
71
@@ -XXX,XX +XXX,XX @@ static void gt_virt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
57
+ unsigned len, bool is_write,
72
58
+ MemTxAttrs attrs)
73
static uint64_t gt_virt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
59
{
74
{
60
subpage_t *subpage = opaque;
75
- return gt_tval_read(env, ri, GTIMER_VIRT);
61
#if defined(DEBUG_SUBPAGE)
76
+ /*
62
@@ -XXX,XX +XXX,XX @@ static void readonly_mem_write(void *opaque, hwaddr addr,
77
+ * This is CNTV_TVAL_EL02; unlike the underlying CNTV_TVAL_EL0
78
+ * we always apply CNTVOFF_EL2. Special case that here rather
79
+ * than going into the generic gt_tval_read() and then having
80
+ * to re-detect that it's this register.
81
+ * Note that the accessfn/perms mean we know we're at EL2 or EL3 here.
82
+ */
83
+ return do_tval_read(env, GTIMER_VIRT, env->cp15.cntvoff_el2);
63
}
84
}
64
85
65
static bool readonly_mem_accepts(void *opaque, hwaddr addr,
86
static void gt_virt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
66
- unsigned size, bool is_write)
87
uint64_t value)
67
+ unsigned size, bool is_write,
68
+ MemTxAttrs attrs)
69
{
88
{
70
return is_write;
89
- gt_tval_write(env, ri, GTIMER_VIRT, value);
90
+ /* Similarly for writes to CNTV_TVAL_EL02 */
91
+ do_tval_write(env, GTIMER_VIRT, value, env->cp15.cntvoff_el2);
71
}
92
}
72
diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
93
73
index XXXXXXX..XXXXXXX 100644
94
static void gt_virt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
74
--- a/hw/hppa/dino.c
75
+++ b/hw/hppa/dino.c
76
@@ -XXX,XX +XXX,XX @@ static void gsc_to_pci_forwarding(DinoState *s)
77
}
78
79
static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
80
- unsigned size, bool is_write)
81
+ unsigned size, bool is_write,
82
+ MemTxAttrs attrs)
83
{
84
switch (addr) {
85
case DINO_IAR0:
86
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/nvram/fw_cfg.c
89
+++ b/hw/nvram/fw_cfg.c
90
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_dma_mem_write(void *opaque, hwaddr addr,
91
}
92
93
static bool fw_cfg_dma_mem_valid(void *opaque, hwaddr addr,
94
- unsigned size, bool is_write)
95
+ unsigned size, bool is_write,
96
+ MemTxAttrs attrs)
97
{
98
return !is_write || ((size == 4 && (addr == 0 || addr == 4)) ||
99
(size == 8 && addr == 0));
100
}
101
102
static bool fw_cfg_data_mem_valid(void *opaque, hwaddr addr,
103
- unsigned size, bool is_write)
104
+ unsigned size, bool is_write,
105
+ MemTxAttrs attrs)
106
{
107
return addr == 0;
108
}
109
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_ctl_mem_write(void *opaque, hwaddr addr,
110
}
111
112
static bool fw_cfg_ctl_mem_valid(void *opaque, hwaddr addr,
113
- unsigned size, bool is_write)
114
+ unsigned size, bool is_write,
115
+ MemTxAttrs attrs)
116
{
117
return is_write && size == 2;
118
}
119
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_comb_write(void *opaque, hwaddr addr,
120
}
121
122
static bool fw_cfg_comb_valid(void *opaque, hwaddr addr,
123
- unsigned size, bool is_write)
124
+ unsigned size, bool is_write,
125
+ MemTxAttrs attrs)
126
{
127
return (size == 1) || (is_write && size == 2);
128
}
129
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/scsi/esp.c
132
+++ b/hw/scsi/esp.c
133
@@ -XXX,XX +XXX,XX @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
134
}
135
136
static bool esp_mem_accepts(void *opaque, hwaddr addr,
137
- unsigned size, bool is_write)
138
+ unsigned size, bool is_write,
139
+ MemTxAttrs attrs)
140
{
141
return (size == 1) || (is_write && size == 4);
142
}
143
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/hw/xen/xen_pt_msi.c
146
+++ b/hw/xen/xen_pt_msi.c
147
@@ -XXX,XX +XXX,XX @@ static uint64_t pci_msix_read(void *opaque, hwaddr addr,
148
}
149
150
static bool pci_msix_accepts(void *opaque, hwaddr addr,
151
- unsigned size, bool is_write)
152
+ unsigned size, bool is_write,
153
+ MemTxAttrs attrs)
154
{
155
return !(addr & (size - 1));
156
}
157
diff --git a/memory.c b/memory.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/memory.c
160
+++ b/memory.c
161
@@ -XXX,XX +XXX,XX @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
162
}
163
164
static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
165
- unsigned size, bool is_write)
166
+ unsigned size, bool is_write,
167
+ MemTxAttrs attrs)
168
{
169
return false;
170
}
171
@@ -XXX,XX +XXX,XX @@ bool memory_region_access_valid(MemoryRegion *mr,
172
access_size = MAX(MIN(size, access_size_max), access_size_min);
173
for (i = 0; i < size; i += access_size) {
174
if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
175
- is_write)) {
176
+ is_write, attrs)) {
177
return false;
178
}
179
}
180
--
95
--
181
2.17.1
96
2.43.0
182
97
183
98
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
When reading or writing the timer registers, sometimes we need to
2
add MemTxAttrs as an argument to flatview_translate(); all its
2
apply one of the timer offsets. Specifically, this happens for
3
callers now have attrs available.
3
direct reads of the counter registers CNTPCT_EL0 and CNTVCT_EL0 (and
4
4
their self-synchronized variants CNTVCTSS_EL0 and CNTPCTSS_EL0). It
5
also applies for direct reads and writes of the CNT*_TVAL_EL*
6
registers that provide the 32-bit downcounting view of each timer.
7
8
We currently do this with duplicated code in gt_tval_read() and
9
gt_tval_write() and a special-case in gt_virt_cnt_read() and
10
gt_cnt_read(). Refactor this so that we handle it all in a single
11
function gt_direct_access_timer_offset(), to parallel how we handle
12
the offset for indirect accesses.
13
14
The call in the WFIT helper previously to gt_virt_cnt_offset() is
15
now to gt_direct_access_timer_offset(); this is the correct
16
behaviour, but it's not immediately obvious that it shouldn't be
17
considered an indirect access, so we add an explanatory comment.
18
19
This commit should make no behavioural changes.
20
21
(Cc to stable because the following bugfix commit will
22
depend on this one.)
23
24
Cc: qemu-stable@nongnu.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
26
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20250204125009.2281315-6-peter.maydell@linaro.org
8
Message-id: 20180521140402.23318-11-peter.maydell@linaro.org
9
---
28
---
10
include/exec/memory.h | 7 ++++---
29
target/arm/internals.h | 5 +-
11
exec.c | 17 +++++++++--------
30
target/arm/helper.c | 103 +++++++++++++++++++------------------
12
2 files changed, 13 insertions(+), 11 deletions(-)
31
target/arm/tcg/op_helper.c | 8 ++-
13
32
3 files changed, 62 insertions(+), 54 deletions(-)
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
33
34
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/memory.h
36
--- a/target/arm/internals.h
17
+++ b/include/exec/memory.h
37
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
38
@@ -XXX,XX +XXX,XX @@ int delete_hw_watchpoint(target_ulong addr, target_ulong len, int type);
39
uint64_t gt_get_countervalue(CPUARMState *env);
40
/*
41
* Return the currently applicable offset between the system counter
42
- * and CNTVCT_EL0 (this will be either 0 or the value of CNTVOFF_EL2).
43
+ * and the counter for the specified timer, as used for direct register
44
+ * accesses.
19
*/
45
*/
20
MemoryRegion *flatview_translate(FlatView *fv,
46
-uint64_t gt_virt_cnt_offset(CPUARMState *env);
21
hwaddr addr, hwaddr *xlat,
47
+uint64_t gt_direct_access_timer_offset(CPUARMState *env, int timeridx);
22
- hwaddr *len, bool is_write);
48
23
+ hwaddr *len, bool is_write,
49
/*
24
+ MemTxAttrs attrs);
50
* Return mask of ARMMMUIdxBit values corresponding to an "invalidate
25
51
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
static inline MemoryRegion *address_space_translate(AddressSpace *as,
27
hwaddr addr, hwaddr *xlat,
28
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
29
MemTxAttrs attrs)
30
{
31
return flatview_translate(address_space_to_flatview(as),
32
- addr, xlat, len, is_write);
33
+ addr, xlat, len, is_write, attrs);
34
}
35
36
/* address_space_access_valid: check for validity of accessing an address
37
@@ -XXX,XX +XXX,XX @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
38
rcu_read_lock();
39
fv = address_space_to_flatview(as);
40
l = len;
41
- mr = flatview_translate(fv, addr, &addr1, &l, false);
42
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
43
if (len == l && memory_access_is_direct(mr, false)) {
44
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
45
memcpy(buf, ptr, len);
46
diff --git a/exec.c b/exec.c
47
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
48
--- a/exec.c
53
--- a/target/arm/helper.c
49
+++ b/exec.c
54
+++ b/target/arm/helper.c
50
@@ -XXX,XX +XXX,XX @@ iotlb_fail:
55
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_phys_raw_cnt_offset(CPUARMState *env)
51
56
return 0;
52
/* Called from RCU critical section */
57
}
53
MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
58
54
- hwaddr *plen, bool is_write)
59
-static uint64_t gt_phys_cnt_offset(CPUARMState *env)
55
+ hwaddr *plen, bool is_write,
60
-{
56
+ MemTxAttrs attrs)
61
- if (arm_current_el(env) >= 2) {
57
{
62
- return 0;
58
MemoryRegion *mr;
63
- }
59
MemoryRegionSection section;
64
- return gt_phys_raw_cnt_offset(env);
60
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
65
-}
61
}
66
-
62
67
static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
63
l = len;
68
{
64
- mr = flatview_translate(fv, addr, &addr1, &l, true);
69
/*
65
+ mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
70
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
66
}
71
}
67
72
}
68
return result;
73
69
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
74
+uint64_t gt_direct_access_timer_offset(CPUARMState *env, int timeridx)
70
MemTxResult result = MEMTX_OK;
75
+{
71
76
+ /*
72
l = len;
77
+ * Return the timer offset to use for direct accesses to the
73
- mr = flatview_translate(fv, addr, &addr1, &l, true);
78
+ * counter registers CNTPCT and CNTVCT, and for direct accesses
74
+ mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
79
+ * to the CNT*_TVAL registers.
75
result = flatview_write_continue(fv, addr, attrs, buf, len,
80
+ *
76
addr1, l, mr);
81
+ * This isn't exactly the same as the indirect-access offset,
77
82
+ * because here we also care about what EL the register access
78
@@ -XXX,XX +XXX,XX @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
83
+ * is being made from.
79
}
84
+ *
80
85
+ * This corresponds to the access pseudocode for the registers.
81
l = len;
86
+ */
82
- mr = flatview_translate(fv, addr, &addr1, &l, false);
87
+ uint64_t hcr;
83
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
88
+
84
}
89
+ switch (timeridx) {
85
90
+ case GTIMER_PHYS:
86
return result;
91
+ if (arm_current_el(env) >= 2) {
87
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
92
+ return 0;
88
MemoryRegion *mr;
93
+ }
89
94
+ return gt_phys_raw_cnt_offset(env);
90
l = len;
95
+ case GTIMER_VIRT:
91
- mr = flatview_translate(fv, addr, &addr1, &l, false);
96
+ switch (arm_current_el(env)) {
92
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
97
+ case 2:
93
return flatview_read_continue(fv, addr, attrs, buf, len,
98
+ hcr = arm_hcr_el2_eff(env);
94
addr1, l, mr);
99
+ if (hcr & HCR_E2H) {
95
}
100
+ return 0;
96
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
101
+ }
97
102
+ break;
98
while (len > 0) {
103
+ case 0:
99
l = len;
104
+ hcr = arm_hcr_el2_eff(env);
100
- mr = flatview_translate(fv, addr, &xlat, &l, is_write);
105
+ if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
101
+ mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
106
+ return 0;
102
if (!memory_access_is_direct(mr, is_write)) {
107
+ }
103
l = memory_access_size(mr, l, addr);
108
+ break;
104
if (!memory_region_access_valid(mr, xlat, l, is_write, attrs)) {
109
+ }
105
@@ -XXX,XX +XXX,XX @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
110
+ return env->cp15.cntvoff_el2;
106
111
+ case GTIMER_HYP:
107
len = target_len;
112
+ case GTIMER_SEC:
108
this_mr = flatview_translate(fv, addr, &xlat,
113
+ case GTIMER_HYPVIRT:
109
- &len, is_write);
114
+ return 0;
110
+ &len, is_write, attrs);
115
+ default:
111
if (this_mr != mr || xlat != base + done) {
116
+ g_assert_not_reached();
112
return done;
117
+ }
113
}
118
+}
114
@@ -XXX,XX +XXX,XX @@ void *address_space_map(AddressSpace *as,
119
+
115
l = len;
120
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
116
rcu_read_lock();
121
{
117
fv = address_space_to_flatview(as);
122
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
118
- mr = flatview_translate(fv, addr, &xlat, &l, is_write);
123
@@ -XXX,XX +XXX,XX @@ static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
119
+ mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
124
120
125
static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
121
if (!memory_access_is_direct(mr, is_write)) {
126
{
122
if (atomic_xchg(&bounce.in_use, true)) {
127
- return gt_get_countervalue(env) - gt_phys_cnt_offset(env);
128
-}
129
-
130
-uint64_t gt_virt_cnt_offset(CPUARMState *env)
131
-{
132
- uint64_t hcr;
133
-
134
- switch (arm_current_el(env)) {
135
- case 2:
136
- hcr = arm_hcr_el2_eff(env);
137
- if (hcr & HCR_E2H) {
138
- return 0;
139
- }
140
- break;
141
- case 0:
142
- hcr = arm_hcr_el2_eff(env);
143
- if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
144
- return 0;
145
- }
146
- break;
147
- }
148
-
149
- return env->cp15.cntvoff_el2;
150
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_PHYS);
151
+ return gt_get_countervalue(env) - offset;
152
}
153
154
static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
155
{
156
- return gt_get_countervalue(env) - gt_virt_cnt_offset(env);
157
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_VIRT);
158
+ return gt_get_countervalue(env) - offset;
159
}
160
161
static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
162
@@ -XXX,XX +XXX,XX @@ static uint64_t do_tval_read(CPUARMState *env, int timeridx, uint64_t offset)
163
static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
164
int timeridx)
165
{
166
- uint64_t offset = 0;
167
-
168
- switch (timeridx) {
169
- case GTIMER_VIRT:
170
- offset = gt_virt_cnt_offset(env);
171
- break;
172
- case GTIMER_PHYS:
173
- offset = gt_phys_cnt_offset(env);
174
- break;
175
- }
176
+ uint64_t offset = gt_direct_access_timer_offset(env, timeridx);
177
178
return do_tval_read(env, timeridx, offset);
179
}
180
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
int timeridx,
182
uint64_t value)
183
{
184
- uint64_t offset = 0;
185
+ uint64_t offset = gt_direct_access_timer_offset(env, timeridx);
186
187
- switch (timeridx) {
188
- case GTIMER_VIRT:
189
- offset = gt_virt_cnt_offset(env);
190
- break;
191
- case GTIMER_PHYS:
192
- offset = gt_phys_cnt_offset(env);
193
- break;
194
- }
195
do_tval_write(env, timeridx, value, offset);
196
}
197
198
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/target/arm/tcg/op_helper.c
201
+++ b/target/arm/tcg/op_helper.c
202
@@ -XXX,XX +XXX,XX @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
203
int target_el = check_wfx_trap(env, false, &excp);
204
/* The WFIT should time out when CNTVCT_EL0 >= the specified value. */
205
uint64_t cntval = gt_get_countervalue(env);
206
- uint64_t offset = gt_virt_cnt_offset(env);
207
+ /*
208
+ * We want the value that we would get if we read CNTVCT_EL0 from
209
+ * the current exception level, so the direct_access offset, not
210
+ * the indirect_access one. Compare the pseudocode LocalTimeoutEvent(),
211
+ * which calls VirtualCounterTimer().
212
+ */
213
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_VIRT);
214
uint64_t cntvct = cntval - offset;
215
uint64_t nexttick;
216
123
--
217
--
124
2.17.1
218
2.43.0
125
219
126
220
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Depending on the host abi, float16, aka uint16_t, values are
3
When FEAT_SEL2 was implemented the SEL2 timers were missed. This
4
passed and returned either zero-extended in the host register
4
shows up when building the latest Hafnium with SPMC_AT_EL=2. The
5
or with garbage at the top of the host register.
5
actual implementation utilises the same logic as the rest of the
6
6
timers so all we need to do is:
7
The tcg code generator has so far been assuming garbage, as that
7
8
matches the x86 abi, but this is incorrect for other host abis.
8
- define the timers and their access functions
9
Further, target/arm has so far been assuming zero-extended results,
9
- conditionally add the correct system registers
10
so that it may store the 16-bit value into a 32-bit slot with the
10
- create a new accessfn as the rules are subtly different to the
11
high 16-bits already clear.
11
existing secure timer
12
12
13
Rectify both problems by mapping "f16" in the helper definition
13
Fixes: e9152ee91c (target/arm: add ARMv8.4-SEL2 system registers)
14
to uint32_t instead of (a typedef for) uint16_t. This forces
14
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
15
the host compiler to assume garbage in the upper 16 bits on input
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
and to zero-extend the result on output.
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
17
Message-id: 20250204125009.2281315-7-peter.maydell@linaro.org
18
Cc: qemu-stable@nongnu.org
18
Cc: qemu-stable@nongnu.org
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
Cc: Andrei Homescu <ahomescu@google.com>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Cc: Arve Hjønnevåg <arve@google.com>
21
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
21
Cc: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
22
Message-id: 20180522175629.24932-1-richard.henderson@linaro.org
22
[PMM: CP_ACCESS_TRAP_UNCATEGORIZED -> CP_ACCESS_UNDEFINED;
23
offset logic now in gt_{indirect,direct}_access_timer_offset() ]
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
26
---
26
include/exec/helper-head.h | 2 +-
27
include/hw/arm/bsa.h | 2 +
27
target/arm/helper-a64.c | 35 +++++++++--------
28
target/arm/cpu.h | 2 +
28
target/arm/helper.c | 80 +++++++++++++++++++-------------------
29
target/arm/gtimer.h | 4 +-
29
3 files changed, 59 insertions(+), 58 deletions(-)
30
target/arm/cpu.c | 4 ++
30
31
target/arm/helper.c | 163 +++++++++++++++++++++++++++++++++++++++++++
31
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
32
5 files changed, 174 insertions(+), 1 deletion(-)
32
index XXXXXXX..XXXXXXX 100644
33
33
--- a/include/exec/helper-head.h
34
diff --git a/include/hw/arm/bsa.h b/include/hw/arm/bsa.h
34
+++ b/include/exec/helper-head.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/bsa.h
37
+++ b/include/hw/arm/bsa.h
35
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@
36
#define dh_ctype_int int
39
#define QEMU_ARM_BSA_H
37
#define dh_ctype_i64 uint64_t
40
38
#define dh_ctype_s64 int64_t
41
/* These are architectural INTID values */
39
-#define dh_ctype_f16 float16
42
+#define ARCH_TIMER_S_EL2_VIRT_IRQ 19
40
+#define dh_ctype_f16 uint32_t
43
+#define ARCH_TIMER_S_EL2_IRQ 20
41
#define dh_ctype_f32 float32
44
#define VIRTUAL_PMU_IRQ 23
42
#define dh_ctype_f64 float64
45
#define ARCH_GIC_MAINT_IRQ 25
43
#define dh_ctype_ptr void *
46
#define ARCH_TIMER_NS_EL2_IRQ 26
44
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
47
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
45
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/helper-a64.c
49
--- a/target/arm/cpu.h
47
+++ b/target/arm/helper-a64.c
50
+++ b/target/arm/cpu.h
48
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float_rel_to_flags(int res)
51
@@ -XXX,XX +XXX,XX @@ void arm_gt_vtimer_cb(void *opaque);
49
return flags;
52
void arm_gt_htimer_cb(void *opaque);
50
}
53
void arm_gt_stimer_cb(void *opaque);
51
54
void arm_gt_hvtimer_cb(void *opaque);
52
-uint64_t HELPER(vfp_cmph_a64)(float16 x, float16 y, void *fp_status)
55
+void arm_gt_sel2timer_cb(void *opaque);
53
+uint64_t HELPER(vfp_cmph_a64)(uint32_t x, uint32_t y, void *fp_status)
56
+void arm_gt_sel2vtimer_cb(void *opaque);
54
{
57
55
return float_rel_to_flags(float16_compare_quiet(x, y, fp_status));
58
unsigned int gt_cntfrq_period_ns(ARMCPU *cpu);
56
}
59
void gt_rme_post_el_change(ARMCPU *cpu, void *opaque);
57
60
diff --git a/target/arm/gtimer.h b/target/arm/gtimer.h
58
-uint64_t HELPER(vfp_cmpeh_a64)(float16 x, float16 y, void *fp_status)
61
index XXXXXXX..XXXXXXX 100644
59
+uint64_t HELPER(vfp_cmpeh_a64)(uint32_t x, uint32_t y, void *fp_status)
62
--- a/target/arm/gtimer.h
60
{
63
+++ b/target/arm/gtimer.h
61
return float_rel_to_flags(float16_compare(x, y, fp_status));
64
@@ -XXX,XX +XXX,XX @@ enum {
62
}
65
GTIMER_HYP = 2,
63
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
66
GTIMER_SEC = 3,
64
#define float64_three make_float64(0x4008000000000000ULL)
67
GTIMER_HYPVIRT = 4,
65
#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
68
-#define NUM_GTIMERS 5
66
69
+ GTIMER_S_EL2_PHYS = 5, /* CNTHPS_* ; only if FEAT_SEL2 */
67
-float16 HELPER(recpsf_f16)(float16 a, float16 b, void *fpstp)
70
+ GTIMER_S_EL2_VIRT = 6, /* CNTHVS_* ; only if FEAT_SEL2 */
68
+uint32_t HELPER(recpsf_f16)(uint32_t a, uint32_t b, void *fpstp)
71
+#define NUM_GTIMERS 7
69
{
72
};
70
float_status *fpst = fpstp;
73
71
74
#endif
72
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpsf_f64)(float64 a, float64 b, void *fpstp)
75
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
73
return float64_muladd(a, b, float64_two, 0, fpst);
76
index XXXXXXX..XXXXXXX 100644
74
}
77
--- a/target/arm/cpu.c
75
78
+++ b/target/arm/cpu.c
76
-float16 HELPER(rsqrtsf_f16)(float16 a, float16 b, void *fpstp)
79
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
77
+uint32_t HELPER(rsqrtsf_f16)(uint32_t a, uint32_t b, void *fpstp)
80
arm_gt_stimer_cb, cpu);
78
{
81
cpu->gt_timer[GTIMER_HYPVIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
79
float_status *fpst = fpstp;
82
arm_gt_hvtimer_cb, cpu);
80
83
+ cpu->gt_timer[GTIMER_S_EL2_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
81
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addlp_u16)(uint64_t a)
84
+ arm_gt_sel2timer_cb, cpu);
82
}
85
+ cpu->gt_timer[GTIMER_S_EL2_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
83
86
+ arm_gt_sel2vtimer_cb, cpu);
84
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */
87
}
85
-float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
88
#endif
86
+uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
87
{
88
float_status *fpst = fpstp;
89
uint16_t val16, sbit;
90
@@ -XXX,XX +XXX,XX @@ void HELPER(casp_be_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
91
#define ADVSIMD_HELPER(name, suffix) HELPER(glue(glue(advsimd_, name), suffix))
92
93
#define ADVSIMD_HALFOP(name) \
94
-float16 ADVSIMD_HELPER(name, h)(float16 a, float16 b, void *fpstp) \
95
+uint32_t ADVSIMD_HELPER(name, h)(uint32_t a, uint32_t b, void *fpstp) \
96
{ \
97
float_status *fpst = fpstp; \
98
return float16_ ## name(a, b, fpst); \
99
@@ -XXX,XX +XXX,XX @@ ADVSIMD_HALFOP(mulx)
100
ADVSIMD_TWOHALFOP(mulx)
101
102
/* fused multiply-accumulate */
103
-float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
104
+uint32_t HELPER(advsimd_muladdh)(uint32_t a, uint32_t b, uint32_t c,
105
+ void *fpstp)
106
{
107
float_status *fpst = fpstp;
108
return float16_muladd(a, b, c, 0, fpst);
109
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_muladd2h)(uint32_t two_a, uint32_t two_b,
110
111
#define ADVSIMD_CMPRES(test) (test) ? 0xffff : 0
112
113
-uint32_t HELPER(advsimd_ceq_f16)(float16 a, float16 b, void *fpstp)
114
+uint32_t HELPER(advsimd_ceq_f16)(uint32_t a, uint32_t b, void *fpstp)
115
{
116
float_status *fpst = fpstp;
117
int compare = float16_compare_quiet(a, b, fpst);
118
return ADVSIMD_CMPRES(compare == float_relation_equal);
119
}
120
121
-uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
122
+uint32_t HELPER(advsimd_cge_f16)(uint32_t a, uint32_t b, void *fpstp)
123
{
124
float_status *fpst = fpstp;
125
int compare = float16_compare(a, b, fpst);
126
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
127
compare == float_relation_equal);
128
}
129
130
-uint32_t HELPER(advsimd_cgt_f16)(float16 a, float16 b, void *fpstp)
131
+uint32_t HELPER(advsimd_cgt_f16)(uint32_t a, uint32_t b, void *fpstp)
132
{
133
float_status *fpst = fpstp;
134
int compare = float16_compare(a, b, fpst);
135
return ADVSIMD_CMPRES(compare == float_relation_greater);
136
}
137
138
-uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
139
+uint32_t HELPER(advsimd_acge_f16)(uint32_t a, uint32_t b, void *fpstp)
140
{
141
float_status *fpst = fpstp;
142
float16 f0 = float16_abs(a);
143
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
144
compare == float_relation_equal);
145
}
146
147
-uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
148
+uint32_t HELPER(advsimd_acgt_f16)(uint32_t a, uint32_t b, void *fpstp)
149
{
150
float_status *fpst = fpstp;
151
float16 f0 = float16_abs(a);
152
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
153
}
154
155
/* round to integral */
156
-float16 HELPER(advsimd_rinth_exact)(float16 x, void *fp_status)
157
+uint32_t HELPER(advsimd_rinth_exact)(uint32_t x, void *fp_status)
158
{
159
return float16_round_to_int(x, fp_status);
160
}
161
162
-float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
163
+uint32_t HELPER(advsimd_rinth)(uint32_t x, void *fp_status)
164
{
165
int old_flags = get_float_exception_flags(fp_status), new_flags;
166
float16 ret;
167
@@ -XXX,XX +XXX,XX @@ float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
168
* setting the mode appropriately before calling the helper.
169
*/
170
171
-uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
172
+uint32_t HELPER(advsimd_f16tosinth)(uint32_t a, void *fpstp)
173
{
174
float_status *fpst = fpstp;
175
176
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
177
return float16_to_int16(a, fpst);
178
}
179
180
-uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
181
+uint32_t HELPER(advsimd_f16touinth)(uint32_t a, void *fpstp)
182
{
183
float_status *fpst = fpstp;
184
185
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
186
* Square Root and Reciprocal square root
187
*/
188
189
-float16 HELPER(sqrt_f16)(float16 a, void *fpstp)
190
+uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp)
191
{
192
float_status *s = fpstp;
193
89
194
diff --git a/target/arm/helper.c b/target/arm/helper.c
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
195
index XXXXXXX..XXXXXXX 100644
91
index XXXXXXX..XXXXXXX 100644
196
--- a/target/arm/helper.c
92
--- a/target/arm/helper.c
197
+++ b/target/arm/helper.c
93
+++ b/target/arm/helper.c
198
@@ -XXX,XX +XXX,XX @@ DO_VFP_cmp(d, float64)
94
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
199
200
/* Integer to float and float to integer conversions */
201
202
-#define CONV_ITOF(name, fsz, sign) \
203
- float##fsz HELPER(name)(uint32_t x, void *fpstp) \
204
-{ \
205
- float_status *fpst = fpstp; \
206
- return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
207
+#define CONV_ITOF(name, ftype, fsz, sign) \
208
+ftype HELPER(name)(uint32_t x, void *fpstp) \
209
+{ \
210
+ float_status *fpst = fpstp; \
211
+ return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
212
}
213
214
-#define CONV_FTOI(name, fsz, sign, round) \
215
-uint32_t HELPER(name)(float##fsz x, void *fpstp) \
216
-{ \
217
- float_status *fpst = fpstp; \
218
- if (float##fsz##_is_any_nan(x)) { \
219
- float_raise(float_flag_invalid, fpst); \
220
- return 0; \
221
- } \
222
- return float##fsz##_to_##sign##int32##round(x, fpst); \
223
+#define CONV_FTOI(name, ftype, fsz, sign, round) \
224
+uint32_t HELPER(name)(ftype x, void *fpstp) \
225
+{ \
226
+ float_status *fpst = fpstp; \
227
+ if (float##fsz##_is_any_nan(x)) { \
228
+ float_raise(float_flag_invalid, fpst); \
229
+ return 0; \
230
+ } \
231
+ return float##fsz##_to_##sign##int32##round(x, fpst); \
232
}
233
234
-#define FLOAT_CONVS(name, p, fsz, sign) \
235
-CONV_ITOF(vfp_##name##to##p, fsz, sign) \
236
-CONV_FTOI(vfp_to##name##p, fsz, sign, ) \
237
-CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero)
238
+#define FLOAT_CONVS(name, p, ftype, fsz, sign) \
239
+ CONV_ITOF(vfp_##name##to##p, ftype, fsz, sign) \
240
+ CONV_FTOI(vfp_to##name##p, ftype, fsz, sign, ) \
241
+ CONV_FTOI(vfp_to##name##z##p, ftype, fsz, sign, _round_to_zero)
242
243
-FLOAT_CONVS(si, h, 16, )
244
-FLOAT_CONVS(si, s, 32, )
245
-FLOAT_CONVS(si, d, 64, )
246
-FLOAT_CONVS(ui, h, 16, u)
247
-FLOAT_CONVS(ui, s, 32, u)
248
-FLOAT_CONVS(ui, d, 64, u)
249
+FLOAT_CONVS(si, h, uint32_t, 16, )
250
+FLOAT_CONVS(si, s, float32, 32, )
251
+FLOAT_CONVS(si, d, float64, 64, )
252
+FLOAT_CONVS(ui, h, uint32_t, 16, u)
253
+FLOAT_CONVS(ui, s, float32, 32, u)
254
+FLOAT_CONVS(ui, d, float64, 64, u)
255
256
#undef CONV_ITOF
257
#undef CONV_FTOI
258
@@ -XXX,XX +XXX,XX @@ static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
259
return float64_to_float16(float64_scalbn(f, -shift, fpst), true, fpst);
260
}
261
262
-float16 HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
263
+uint32_t HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
264
{
265
return do_postscale_fp16(int32_to_float64(x, fpst), shift, fpst);
266
}
267
268
-float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
269
+uint32_t HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
270
{
271
return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
272
}
273
274
-float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
275
+uint32_t HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
276
{
277
return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst);
278
}
279
280
-float16 HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
281
+uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
282
{
283
return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst);
284
}
285
@@ -XXX,XX +XXX,XX @@ static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
286
}
95
}
287
}
96
}
288
97
289
-uint32_t HELPER(vfp_toshh)(float16 x, uint32_t shift, void *fpst)
98
+static CPAccessResult gt_sel2timer_access(CPUARMState *env,
290
+uint32_t HELPER(vfp_toshh)(uint32_t x, uint32_t shift, void *fpst)
99
+ const ARMCPRegInfo *ri,
100
+ bool isread)
101
+{
102
+ /*
103
+ * The AArch64 register view of the secure EL2 timers are mostly
104
+ * accessible from EL3 and EL2 although can also be trapped to EL2
105
+ * from EL1 depending on nested virt config.
106
+ */
107
+ switch (arm_current_el(env)) {
108
+ case 0: /* UNDEFINED */
109
+ return CP_ACCESS_UNDEFINED;
110
+ case 1:
111
+ if (!arm_is_secure(env)) {
112
+ /* UNDEFINED */
113
+ return CP_ACCESS_UNDEFINED;
114
+ } else if (arm_hcr_el2_eff(env) & HCR_NV) {
115
+ /* Aarch64.SystemAccessTrap(EL2, 0x18) */
116
+ return CP_ACCESS_TRAP_EL2;
117
+ }
118
+ /* UNDEFINED */
119
+ return CP_ACCESS_UNDEFINED;
120
+ case 2:
121
+ if (!arm_is_secure(env)) {
122
+ /* UNDEFINED */
123
+ return CP_ACCESS_UNDEFINED;
124
+ }
125
+ return CP_ACCESS_OK;
126
+ case 3:
127
+ if (env->cp15.scr_el3 & SCR_EEL2) {
128
+ return CP_ACCESS_OK;
129
+ } else {
130
+ return CP_ACCESS_UNDEFINED;
131
+ }
132
+ default:
133
+ g_assert_not_reached();
134
+ }
135
+}
136
+
137
uint64_t gt_get_countervalue(CPUARMState *env)
291
{
138
{
292
return float64_to_int16(do_prescale_fp16(x, shift, fpst), fpst);
139
ARMCPU *cpu = env_archcpu(env);
140
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_indirect_access_timer_offset(CPUARMState *env, int timeridx)
141
case GTIMER_HYP:
142
case GTIMER_SEC:
143
case GTIMER_HYPVIRT:
144
+ case GTIMER_S_EL2_PHYS:
145
+ case GTIMER_S_EL2_VIRT:
146
return 0;
147
default:
148
g_assert_not_reached();
149
@@ -XXX,XX +XXX,XX @@ uint64_t gt_direct_access_timer_offset(CPUARMState *env, int timeridx)
150
case GTIMER_HYP:
151
case GTIMER_SEC:
152
case GTIMER_HYPVIRT:
153
+ case GTIMER_S_EL2_PHYS:
154
+ case GTIMER_S_EL2_VIRT:
155
return 0;
156
default:
157
g_assert_not_reached();
158
@@ -XXX,XX +XXX,XX @@ static void gt_sec_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
159
gt_ctl_write(env, ri, GTIMER_SEC, value);
293
}
160
}
294
161
295
-uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
162
+static void gt_sec_pel2_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
296
+uint32_t HELPER(vfp_touhh)(uint32_t x, uint32_t shift, void *fpst)
163
+{
164
+ gt_timer_reset(env, ri, GTIMER_S_EL2_PHYS);
165
+}
166
+
167
+static void gt_sec_pel2_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
168
+ uint64_t value)
169
+{
170
+ gt_cval_write(env, ri, GTIMER_S_EL2_PHYS, value);
171
+}
172
+
173
+static uint64_t gt_sec_pel2_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
174
+{
175
+ return gt_tval_read(env, ri, GTIMER_S_EL2_PHYS);
176
+}
177
+
178
+static void gt_sec_pel2_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
179
+ uint64_t value)
180
+{
181
+ gt_tval_write(env, ri, GTIMER_S_EL2_PHYS, value);
182
+}
183
+
184
+static void gt_sec_pel2_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
185
+ uint64_t value)
186
+{
187
+ gt_ctl_write(env, ri, GTIMER_S_EL2_PHYS, value);
188
+}
189
+
190
+static void gt_sec_vel2_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
191
+{
192
+ gt_timer_reset(env, ri, GTIMER_S_EL2_VIRT);
193
+}
194
+
195
+static void gt_sec_vel2_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
196
+ uint64_t value)
197
+{
198
+ gt_cval_write(env, ri, GTIMER_S_EL2_VIRT, value);
199
+}
200
+
201
+static uint64_t gt_sec_vel2_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
202
+{
203
+ return gt_tval_read(env, ri, GTIMER_S_EL2_VIRT);
204
+}
205
+
206
+static void gt_sec_vel2_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
207
+ uint64_t value)
208
+{
209
+ gt_tval_write(env, ri, GTIMER_S_EL2_VIRT, value);
210
+}
211
+
212
+static void gt_sec_vel2_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
213
+ uint64_t value)
214
+{
215
+ gt_ctl_write(env, ri, GTIMER_S_EL2_VIRT, value);
216
+}
217
+
218
static void gt_hv_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
297
{
219
{
298
return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
220
gt_timer_reset(env, ri, GTIMER_HYPVIRT);
221
@@ -XXX,XX +XXX,XX @@ void arm_gt_stimer_cb(void *opaque)
222
gt_recalc_timer(cpu, GTIMER_SEC);
299
}
223
}
300
224
301
-uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst)
225
+void arm_gt_sel2timer_cb(void *opaque)
302
+uint32_t HELPER(vfp_toslh)(uint32_t x, uint32_t shift, void *fpst)
226
+{
227
+ ARMCPU *cpu = opaque;
228
+
229
+ gt_recalc_timer(cpu, GTIMER_S_EL2_PHYS);
230
+}
231
+
232
+void arm_gt_sel2vtimer_cb(void *opaque)
233
+{
234
+ ARMCPU *cpu = opaque;
235
+
236
+ gt_recalc_timer(cpu, GTIMER_S_EL2_VIRT);
237
+}
238
+
239
void arm_gt_hvtimer_cb(void *opaque)
303
{
240
{
304
return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
241
ARMCPU *cpu = opaque;
305
}
242
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
306
243
.access = PL2_RW, .accessfn = sel2_access,
307
-uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst)
244
.nv2_redirect_offset = 0x48,
308
+uint32_t HELPER(vfp_toulh)(uint32_t x, uint32_t shift, void *fpst)
245
.fieldoffset = offsetof(CPUARMState, cp15.vstcr_el2) },
309
{
246
+#ifndef CONFIG_USER_ONLY
310
return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst);
247
+ /* Secure EL2 Physical Timer */
311
}
248
+ { .name = "CNTHPS_TVAL_EL2", .state = ARM_CP_STATE_AA64,
312
249
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 5, .opc2 = 0,
313
-uint64_t HELPER(vfp_tosqh)(float16 x, uint32_t shift, void *fpst)
250
+ .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW,
314
+uint64_t HELPER(vfp_tosqh)(uint32_t x, uint32_t shift, void *fpst)
251
+ .accessfn = gt_sel2timer_access,
315
{
252
+ .readfn = gt_sec_pel2_tval_read,
316
return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst);
253
+ .writefn = gt_sec_pel2_tval_write,
317
}
254
+ .resetfn = gt_sec_pel2_timer_reset,
318
255
+ },
319
-uint64_t HELPER(vfp_touqh)(float16 x, uint32_t shift, void *fpst)
256
+ { .name = "CNTHPS_CTL_EL2", .state = ARM_CP_STATE_AA64,
320
+uint64_t HELPER(vfp_touqh)(uint32_t x, uint32_t shift, void *fpst)
257
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 5, .opc2 = 1,
321
{
258
+ .type = ARM_CP_IO, .access = PL2_RW,
322
return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst);
259
+ .accessfn = gt_sel2timer_access,
323
}
260
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_PHYS].ctl),
324
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env)
261
+ .resetvalue = 0,
325
}
262
+ .writefn = gt_sec_pel2_ctl_write, .raw_writefn = raw_write,
326
263
+ },
327
/* Half precision conversions. */
264
+ { .name = "CNTHPS_CVAL_EL2", .state = ARM_CP_STATE_AA64,
328
-float32 HELPER(vfp_fcvt_f16_to_f32)(float16 a, void *fpstp, uint32_t ahp_mode)
265
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 5, .opc2 = 2,
329
+float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, void *fpstp, uint32_t ahp_mode)
266
+ .type = ARM_CP_IO, .access = PL2_RW,
330
{
267
+ .accessfn = gt_sel2timer_access,
331
/* Squash FZ16 to 0 for the duration of conversion. In this case,
268
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_PHYS].cval),
332
* it would affect flushing input denormals.
269
+ .writefn = gt_sec_pel2_cval_write, .raw_writefn = raw_write,
333
@@ -XXX,XX +XXX,XX @@ float32 HELPER(vfp_fcvt_f16_to_f32)(float16 a, void *fpstp, uint32_t ahp_mode)
270
+ },
334
return r;
271
+ /* Secure EL2 Virtual Timer */
335
}
272
+ { .name = "CNTHVS_TVAL_EL2", .state = ARM_CP_STATE_AA64,
336
273
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 4, .opc2 = 0,
337
-float16 HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
274
+ .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW,
338
+uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
275
+ .accessfn = gt_sel2timer_access,
339
{
276
+ .readfn = gt_sec_vel2_tval_read,
340
/* Squash FZ16 to 0 for the duration of conversion. In this case,
277
+ .writefn = gt_sec_vel2_tval_write,
341
* it would affect flushing output denormals.
278
+ .resetfn = gt_sec_vel2_timer_reset,
342
@@ -XXX,XX +XXX,XX @@ float16 HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
279
+ },
343
return r;
280
+ { .name = "CNTHVS_CTL_EL2", .state = ARM_CP_STATE_AA64,
344
}
281
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 4, .opc2 = 1,
345
282
+ .type = ARM_CP_IO, .access = PL2_RW,
346
-float64 HELPER(vfp_fcvt_f16_to_f64)(float16 a, void *fpstp, uint32_t ahp_mode)
283
+ .accessfn = gt_sel2timer_access,
347
+float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, void *fpstp, uint32_t ahp_mode)
284
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_VIRT].ctl),
348
{
285
+ .resetvalue = 0,
349
/* Squash FZ16 to 0 for the duration of conversion. In this case,
286
+ .writefn = gt_sec_vel2_ctl_write, .raw_writefn = raw_write,
350
* it would affect flushing input denormals.
287
+ },
351
@@ -XXX,XX +XXX,XX @@ float64 HELPER(vfp_fcvt_f16_to_f64)(float16 a, void *fpstp, uint32_t ahp_mode)
288
+ { .name = "CNTHVS_CVAL_EL2", .state = ARM_CP_STATE_AA64,
352
return r;
289
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 4, .opc2 = 2,
353
}
290
+ .type = ARM_CP_IO, .access = PL2_RW,
354
291
+ .accessfn = gt_sel2timer_access,
355
-float16 HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
292
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_S_EL2_VIRT].cval),
356
+uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
293
+ .writefn = gt_sec_vel2_cval_write, .raw_writefn = raw_write,
357
{
294
+ },
358
/* Squash FZ16 to 0 for the duration of conversion. In this case,
295
+#endif
359
* it would affect flushing output denormals.
296
};
360
@@ -XXX,XX +XXX,XX @@ static bool round_to_inf(float_status *fpst, bool sign_bit)
297
361
g_assert_not_reached();
298
static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
362
}
363
364
-float16 HELPER(recpe_f16)(float16 input, void *fpstp)
365
+uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
366
{
367
float_status *fpst = fpstp;
368
float16 f16 = float16_squash_input_denormal(input, fpst);
369
@@ -XXX,XX +XXX,XX @@ static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
370
return extract64(estimate, 0, 8) << 44;
371
}
372
373
-float16 HELPER(rsqrte_f16)(float16 input, void *fpstp)
374
+uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
375
{
376
float_status *s = fpstp;
377
float16 f16 = float16_squash_input_denormal(input, s);
378
--
299
--
379
2.17.1
300
2.43.0
380
301
381
302
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Coverity found that the string return by 'object_get_canonical_path' was not
3
As we are about to add more physical and virtual timers let's make it
4
being freed at two locations in the model (CID 1391294 and CID 1391293) and
4
clear what each timer does.
5
also that a memset was being called with a value greater than the max of a byte
6
on the second argument (CID 1391286). This patch corrects this by adding the
7
freeing of the strings and also changing to memset to zero instead on
8
descriptor unaligned errors.
9
5
10
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20180528184859.3530-1-frasse.iglesias@gmail.com
9
Message-id: 20250204125009.2281315-8-peter.maydell@linaro.org
10
[PMM: Add timer register name prefix to each comment]
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
13
---
17
hw/dma/xlnx-zdma.c | 10 +++++++---
14
target/arm/gtimer.h | 10 +++++-----
18
1 file changed, 7 insertions(+), 3 deletions(-)
15
1 file changed, 5 insertions(+), 5 deletions(-)
19
16
20
diff --git a/hw/dma/xlnx-zdma.c b/hw/dma/xlnx-zdma.c
17
diff --git a/target/arm/gtimer.h b/target/arm/gtimer.h
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/dma/xlnx-zdma.c
19
--- a/target/arm/gtimer.h
23
+++ b/hw/dma/xlnx-zdma.c
20
+++ b/target/arm/gtimer.h
24
@@ -XXX,XX +XXX,XX @@ static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr, void *buf)
21
@@ -XXX,XX +XXX,XX @@
25
qemu_log_mask(LOG_GUEST_ERROR,
22
#define TARGET_ARM_GTIMER_H
26
"zdma: unaligned descriptor at %" PRIx64,
23
27
addr);
24
enum {
28
- memset(buf, 0xdeadbeef, sizeof(XlnxZDMADescr));
25
- GTIMER_PHYS = 0,
29
+ memset(buf, 0x0, sizeof(XlnxZDMADescr));
26
- GTIMER_VIRT = 1,
30
s->error = true;
27
- GTIMER_HYP = 2,
31
return false;
28
- GTIMER_SEC = 3,
32
}
29
- GTIMER_HYPVIRT = 4,
33
@@ -XXX,XX +XXX,XX @@ static uint64_t zdma_read(void *opaque, hwaddr addr, unsigned size)
30
+ GTIMER_PHYS = 0, /* CNTP_* ; EL1 physical timer */
34
RegisterInfo *r = &s->regs_info[addr / 4];
31
+ GTIMER_VIRT = 1, /* CNTV_* ; EL1 virtual timer */
35
32
+ GTIMER_HYP = 2, /* CNTHP_* ; EL2 physical timer */
36
if (!r->data) {
33
+ GTIMER_SEC = 3, /* CNTPS_* ; EL3 physical timer */
37
+ gchar *path = object_get_canonical_path(OBJECT(s));
34
+ GTIMER_HYPVIRT = 4, /* CNTHV_* ; EL2 virtual timer ; only if FEAT_VHE */
38
qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
35
GTIMER_S_EL2_PHYS = 5, /* CNTHPS_* ; only if FEAT_SEL2 */
39
- object_get_canonical_path(OBJECT(s)),
36
GTIMER_S_EL2_VIRT = 6, /* CNTHVS_* ; only if FEAT_SEL2 */
40
+ path,
37
#define NUM_GTIMERS 7
41
addr);
42
+ g_free(path);
43
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
44
zdma_ch_imr_update_irq(s);
45
return 0;
46
@@ -XXX,XX +XXX,XX @@ static void zdma_write(void *opaque, hwaddr addr, uint64_t value,
47
RegisterInfo *r = &s->regs_info[addr / 4];
48
49
if (!r->data) {
50
+ gchar *path = object_get_canonical_path(OBJECT(s));
51
qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
52
- object_get_canonical_path(OBJECT(s)),
53
+ path,
54
addr, value);
55
+ g_free(path);
56
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
57
zdma_ch_imr_update_irq(s);
58
return;
59
--
38
--
60
2.17.1
39
2.43.0
61
40
62
41
diff view generated by jsdifflib
1
From: Igor Mammedov <imammedo@redhat.com>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
When QEMU is started with following CLI
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
4
-machine virt,gic-version=3,accel=kvm -cpu host -bios AAVMF_CODE.fd
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
it crashes with abort at
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
accel/kvm/kvm-all.c:2164:
6
Message-id: 20250204125009.2281315-9-peter.maydell@linaro.org
7
KVM_SET_DEVICE_ATTR failed: Group 6 attr 0x000000000000c665: Invalid argument
7
Cc: qemu-stable@nongnu.org
8
9
Which is caused by implicit dependency of kvm_arm_gicv3_reset() on
10
arm_gicv3_icc_reset() where the later is called by CPU reset
11
reset callback.
12
13
However commit:
14
3b77f6c arm/boot: split load_dtb() from arm_load_kernel()
15
broke CPU reset callback registration in case
16
17
arm_load_kernel()
18
...
19
if (!info->kernel_filename || info->firmware_loaded)
20
21
branch is taken, i.e. it's sufficient to provide a firmware
22
or do not provide kernel on CLI to skip cpu reset callback
23
registration, where before offending commit the callback
24
has been registered unconditionally.
25
26
Fix it by registering the callback right at the beginning of
27
arm_load_kernel() unconditionally instead of doing it at the end.
28
29
NOTE:
30
we probably should eliminate that dependency anyways as well as
31
separate arch CPU reset parts from arm_load_kernel() into CPU
32
itself, but that refactoring that I probably would have to do
33
anyways later for CPU hotplug to work.
34
35
Reported-by: Auger Eric <eric.auger@redhat.com>
36
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
37
Reviewed-by: Eric Auger <eric.auger@redhat.com>
38
Tested-by: Eric Auger <eric.auger@redhat.com>
39
Message-id: 1527070950-208350-1-git-send-email-imammedo@redhat.com
40
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
41
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
---
10
---
43
hw/arm/boot.c | 18 +++++++++---------
11
hw/arm/virt.c | 2 ++
44
1 file changed, 9 insertions(+), 9 deletions(-)
12
1 file changed, 2 insertions(+)
45
13
46
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
47
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/boot.c
16
--- a/hw/arm/virt.c
49
+++ b/hw/arm/boot.c
17
+++ b/hw/arm/virt.c
50
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
18
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
51
static const ARMInsnFixup *primary_loader;
19
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
52
AddressSpace *as = arm_boot_address_space(cpu, info);
20
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
53
21
[GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
54
+ /* CPU objects (unlike devices) are not automatically reset on system
22
+ [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
55
+ * reset, so we must always register a handler to do so. If we're
23
+ [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
56
+ * actually loading a kernel, the handler is also responsible for
24
};
57
+ * arranging that we start it correctly.
25
58
+ */
26
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
59
+ for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
60
+ qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
61
+ }
62
+
63
/* The board code is not supposed to set secure_board_setup unless
64
* running its code in secure mode is actually possible, and KVM
65
* doesn't support secure.
66
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
67
ARM_CPU(cs)->env.boot_info = info;
68
}
69
70
- /* CPU objects (unlike devices) are not automatically reset on system
71
- * reset, so we must always register a handler to do so. If we're
72
- * actually loading a kernel, the handler is also responsible for
73
- * arranging that we start it correctly.
74
- */
75
- for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
76
- qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
77
- }
78
-
79
if (!info->skip_dtb_autoload && have_dtb(info)) {
80
if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) {
81
exit(1);
82
--
27
--
83
2.17.1
28
2.43.0
84
29
85
30
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
cpregs_keys is an uint32_t* so the allocation should use uint32_t.
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
4
g_new is even better because it is type-safe.
5
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20250204125009.2281315-10-peter.maydell@linaro.org
7
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
target/arm/gdbstub.c | 3 +--
10
hw/arm/sbsa-ref.c | 2 ++
12
1 file changed, 1 insertion(+), 2 deletions(-)
11
1 file changed, 2 insertions(+)
13
12
14
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
13
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/gdbstub.c
15
--- a/hw/arm/sbsa-ref.c
17
+++ b/target/arm/gdbstub.c
16
+++ b/hw/arm/sbsa-ref.c
18
@@ -XXX,XX +XXX,XX @@ int arm_gen_dynamic_xml(CPUState *cs)
17
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
19
RegisterSysregXmlParam param = {cs, s};
18
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
20
19
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
21
cpu->dyn_xml.num_cpregs = 0;
20
[GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
22
- cpu->dyn_xml.cpregs_keys = g_malloc(sizeof(uint32_t *) *
21
+ [GTIMER_S_EL2_PHYS] = ARCH_TIMER_S_EL2_IRQ,
23
- g_hash_table_size(cpu->cp_regs));
22
+ [GTIMER_S_EL2_VIRT] = ARCH_TIMER_S_EL2_VIRT_IRQ,
24
+ cpu->dyn_xml.cpregs_keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs));
23
};
25
g_string_printf(s, "<?xml version=\"1.0\"?>");
24
26
g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
25
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
27
g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">");
28
--
26
--
29
2.17.1
27
2.43.0
30
28
31
29
diff view generated by jsdifflib
1
From: Jan Kiszka <jan.kiszka@siemens.com>
1
Our LDRD implementation is wrong in two respects:
2
2
3
There was a nasty flip in identifying which register group an access is
3
* if the address is 4-aligned and the load crosses a page boundary
4
targeting. The issue caused spuriously raised priorities of the guest
4
and the second load faults and the first load was to the
5
when handing CPUs over in the Jailhouse hypervisor.
5
base register (as in cases like "ldrd r2, r3, [r2]", then we
6
must not update the base register before taking the fault
7
* if the address is 8-aligned the access must be a 64-bit
8
single-copy atomic access, not two 32-bit accesses
9
10
Rewrite the handling of the loads in LDRD to use a single
11
tcg_gen_qemu_ld_i64() and split the result into the destination
12
registers. This allows us to get the atomicity requirements
13
right, and also implicitly means that we won't update the
14
base register too early for the page-crossing case.
15
16
Note that because we no longer increment 'addr' by 4 in the course of
17
performing the LDRD we must change the adjustment value we pass to
18
op_addr_ri_post() and op_addr_rr_post(): it no longer needs to
19
subtract 4 to get the correct value to use if doing base register
20
writeback.
21
22
STRD has the same problem with not getting the atomicity right;
23
we will deal with that in the following commit.
6
24
7
Cc: qemu-stable@nongnu.org
25
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
26
Reported-by: Stu Grossman <stu.grossman@gmail.com>
9
Message-id: 28b927d3-da58-bce4-cc13-bfec7f9b1cb9@siemens.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Message-id: 20250227142746.1698904-2-peter.maydell@linaro.org
12
---
30
---
13
hw/intc/arm_gicv3_cpuif.c | 12 ++++++------
31
target/arm/tcg/translate.c | 70 +++++++++++++++++++++++++-------------
14
1 file changed, 6 insertions(+), 6 deletions(-)
32
1 file changed, 46 insertions(+), 24 deletions(-)
15
33
16
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
34
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
17
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/arm_gicv3_cpuif.c
36
--- a/target/arm/tcg/translate.c
19
+++ b/hw/intc/arm_gicv3_cpuif.c
37
+++ b/target/arm/tcg/translate.c
20
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
38
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
39
return true;
40
}
41
42
+static void do_ldrd_load(DisasContext *s, TCGv_i32 addr, int rt, int rt2)
43
+{
44
+ /*
45
+ * LDRD is required to be an atomic 64-bit access if the
46
+ * address is 8-aligned, two atomic 32-bit accesses if
47
+ * it's only 4-aligned, and to give an alignment fault
48
+ * if it's not 4-aligned. This is MO_ALIGN_4 | MO_ATOM_SUBALIGN.
49
+ * Rt is always the word from the lower address, and Rt2 the
50
+ * data from the higher address, regardless of endianness.
51
+ * So (like gen_load_exclusive) we avoid gen_aa32_ld_i64()
52
+ * so we don't get its SCTLR_B check, and instead do a 64-bit access
53
+ * using MO_BE if appropriate and then split the two halves.
54
+ *
55
+ * For M-profile, and for A-profile before LPAE, the 64-bit
56
+ * atomicity is not required. We could model that using
57
+ * the looser MO_ATOM_IFALIGN_PAIR, but providing a higher
58
+ * level of atomicity than required is harmless (we would not
59
+ * currently generate better code for IFALIGN_PAIR here).
60
+ *
61
+ * This also gives us the correct behaviour of not updating
62
+ * rt if the load of rt2 faults; this is required for cases
63
+ * like "ldrd r2, r3, [r2]" where rt is also the base register.
64
+ */
65
+ int mem_idx = get_mem_index(s);
66
+ MemOp opc = MO_64 | MO_ALIGN_4 | MO_ATOM_SUBALIGN | s->be_data;
67
+ TCGv taddr = gen_aa32_addr(s, addr, opc);
68
+ TCGv_i64 t64 = tcg_temp_new_i64();
69
+ TCGv_i32 tmp = tcg_temp_new_i32();
70
+ TCGv_i32 tmp2 = tcg_temp_new_i32();
71
+
72
+ tcg_gen_qemu_ld_i64(t64, taddr, mem_idx, opc);
73
+ if (s->be_data == MO_BE) {
74
+ tcg_gen_extr_i64_i32(tmp2, tmp, t64);
75
+ } else {
76
+ tcg_gen_extr_i64_i32(tmp, tmp2, t64);
77
+ }
78
+ store_reg(s, rt, tmp);
79
+ store_reg(s, rt2, tmp2);
80
+}
81
+
82
static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
21
{
83
{
22
GICv3CPUState *cs = icc_cs_from_env(env);
84
- int mem_idx = get_mem_index(s);
23
int regno = ri->opc2 & 3;
85
- TCGv_i32 addr, tmp;
24
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
86
+ TCGv_i32 addr;
25
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
87
26
uint64_t value = cs->ich_apr[grp][regno];
88
if (!ENABLE_ARCH_5TE) {
27
89
return false;
28
trace_gicv3_icv_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
90
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
29
@@ -XXX,XX +XXX,XX @@ static void icv_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
91
}
92
addr = op_addr_rr_pre(s, a);
93
94
- tmp = tcg_temp_new_i32();
95
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
96
- store_reg(s, a->rt, tmp);
97
-
98
- tcg_gen_addi_i32(addr, addr, 4);
99
-
100
- tmp = tcg_temp_new_i32();
101
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
102
- store_reg(s, a->rt + 1, tmp);
103
+ do_ldrd_load(s, addr, a->rt, a->rt + 1);
104
105
/* LDRD w/ base writeback is undefined if the registers overlap. */
106
- op_addr_rr_post(s, a, addr, -4);
107
+ op_addr_rr_post(s, a, addr, 0);
108
return true;
109
}
110
111
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
112
113
static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
30
{
114
{
31
GICv3CPUState *cs = icc_cs_from_env(env);
115
- int mem_idx = get_mem_index(s);
32
int regno = ri->opc2 & 3;
116
- TCGv_i32 addr, tmp;
33
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
117
+ TCGv_i32 addr;
34
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
118
35
119
addr = op_addr_ri_pre(s, a);
36
trace_gicv3_icv_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
120
37
121
- tmp = tcg_temp_new_i32();
38
@@ -XXX,XX +XXX,XX @@ static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
122
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
39
uint64_t value;
123
- store_reg(s, a->rt, tmp);
40
124
-
41
int regno = ri->opc2 & 3;
125
- tcg_gen_addi_i32(addr, addr, 4);
42
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
126
-
43
+ int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
127
- tmp = tcg_temp_new_i32();
44
128
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
45
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
129
- store_reg(s, rt2, tmp);
46
return icv_ap_read(env, ri);
130
+ do_ldrd_load(s, addr, a->rt, rt2);
47
@@ -XXX,XX +XXX,XX @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
131
48
GICv3CPUState *cs = icc_cs_from_env(env);
132
/* LDRD w/ base writeback is undefined if the registers overlap. */
49
133
- op_addr_ri_post(s, a, addr, -4);
50
int regno = ri->opc2 & 3;
134
+ op_addr_ri_post(s, a, addr, 0);
51
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
135
return true;
52
+ int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
136
}
53
54
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
55
icv_ap_write(env, ri, value);
56
@@ -XXX,XX +XXX,XX @@ static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
57
{
58
GICv3CPUState *cs = icc_cs_from_env(env);
59
int regno = ri->opc2 & 3;
60
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
61
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
62
uint64_t value;
63
64
value = cs->ich_apr[grp][regno];
65
@@ -XXX,XX +XXX,XX @@ static void ich_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
66
{
67
GICv3CPUState *cs = icc_cs_from_env(env);
68
int regno = ri->opc2 & 3;
69
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
70
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
71
72
trace_gicv3_ich_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
73
137
74
--
138
--
75
2.17.1
139
2.43.0
76
77
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
Our STRD implementation doesn't correctly implement the requirement:
2
add MemTxAttrs as an argument to address_space_access_valid().
2
* if the address is 8-aligned the access must be a 64-bit
3
Its callers either have an attrs value to hand, or don't care
3
single-copy atomic access, not two 32-bit accesses
4
and can use MEMTXATTRS_UNSPECIFIED.
5
4
5
Rewrite the handling of STRD to use a single tcg_gen_qemu_st_i64()
6
of a value produced by concatenating the two 32 bit source registers.
7
This allows us to get the atomicity right.
8
9
As with the LDRD change, now that we don't update 'addr' in the
10
course of performing the store we need to adjust the offset
11
we pass to op_addr_ri_post() and op_addr_rr_post().
12
13
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-6-peter.maydell@linaro.org
16
Message-id: 20250227142746.1698904-3-peter.maydell@linaro.org
10
---
17
---
11
include/exec/memory.h | 4 +++-
18
target/arm/tcg/translate.c | 59 +++++++++++++++++++++++++-------------
12
include/sysemu/dma.h | 3 ++-
19
1 file changed, 39 insertions(+), 20 deletions(-)
13
exec.c | 3 ++-
14
target/s390x/diag.c | 6 ++++--
15
target/s390x/excp_helper.c | 3 ++-
16
target/s390x/mmu_helper.c | 3 ++-
17
target/s390x/sigp.c | 3 ++-
18
7 files changed, 17 insertions(+), 8 deletions(-)
19
20
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
21
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/memory.h
23
--- a/target/arm/tcg/translate.c
23
+++ b/include/exec/memory.h
24
+++ b/target/arm/tcg/translate.c
24
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
25
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
25
* @addr: address within that address space
26
return true;
26
* @len: length of the area to be checked
27
}
27
* @is_write: indicates the transfer direction
28
28
+ * @attrs: memory attributes
29
+static void do_strd_store(DisasContext *s, TCGv_i32 addr, int rt, int rt2)
29
*/
30
+{
30
-bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write);
31
+ /*
31
+bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len,
32
+ * STRD is required to be an atomic 64-bit access if the
32
+ bool is_write, MemTxAttrs attrs);
33
+ * address is 8-aligned, two atomic 32-bit accesses if
33
34
+ * it's only 4-aligned, and to give an alignment fault
34
/* address_space_map: map a physical memory region into a host virtual address
35
+ * if it's not 4-aligned.
35
*
36
+ * Rt is always the word from the lower address, and Rt2 the
36
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
37
+ * data from the higher address, regardless of endianness.
37
index XXXXXXX..XXXXXXX 100644
38
+ * So (like gen_store_exclusive) we avoid gen_aa32_ld_i64()
38
--- a/include/sysemu/dma.h
39
+ * so we don't get its SCTLR_B check, and instead do a 64-bit access
39
+++ b/include/sysemu/dma.h
40
+ * using MO_BE if appropriate, using a value constructed
40
@@ -XXX,XX +XXX,XX @@ static inline bool dma_memory_valid(AddressSpace *as,
41
+ * by putting the two halves together in the right order.
41
DMADirection dir)
42
+ *
43
+ * As with LDRD, the 64-bit atomicity is not required for
44
+ * M-profile, or for A-profile before LPAE, and we provide
45
+ * the higher guarantee always for simplicity.
46
+ */
47
+ int mem_idx = get_mem_index(s);
48
+ MemOp opc = MO_64 | MO_ALIGN_4 | MO_ATOM_SUBALIGN | s->be_data;
49
+ TCGv taddr = gen_aa32_addr(s, addr, opc);
50
+ TCGv_i32 t1 = load_reg(s, rt);
51
+ TCGv_i32 t2 = load_reg(s, rt2);
52
+ TCGv_i64 t64 = tcg_temp_new_i64();
53
+
54
+ if (s->be_data == MO_BE) {
55
+ tcg_gen_concat_i32_i64(t64, t2, t1);
56
+ } else {
57
+ tcg_gen_concat_i32_i64(t64, t1, t2);
58
+ }
59
+ tcg_gen_qemu_st_i64(t64, taddr, mem_idx, opc);
60
+}
61
+
62
static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
42
{
63
{
43
return address_space_access_valid(as, addr, len,
64
- int mem_idx = get_mem_index(s);
44
- dir == DMA_DIRECTION_FROM_DEVICE);
65
- TCGv_i32 addr, tmp;
45
+ dir == DMA_DIRECTION_FROM_DEVICE,
66
+ TCGv_i32 addr;
46
+ MEMTXATTRS_UNSPECIFIED);
67
68
if (!ENABLE_ARCH_5TE) {
69
return false;
70
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
71
}
72
addr = op_addr_rr_pre(s, a);
73
74
- tmp = load_reg(s, a->rt);
75
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
76
+ do_strd_store(s, addr, a->rt, a->rt + 1);
77
78
- tcg_gen_addi_i32(addr, addr, 4);
79
-
80
- tmp = load_reg(s, a->rt + 1);
81
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
82
-
83
- op_addr_rr_post(s, a, addr, -4);
84
+ op_addr_rr_post(s, a, addr, 0);
85
return true;
47
}
86
}
48
87
49
static inline int dma_memory_rw_relaxed(AddressSpace *as, dma_addr_t addr,
88
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
50
diff --git a/exec.c b/exec.c
89
51
index XXXXXXX..XXXXXXX 100644
90
static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
52
--- a/exec.c
91
{
53
+++ b/exec.c
92
- int mem_idx = get_mem_index(s);
54
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
93
- TCGv_i32 addr, tmp;
94
+ TCGv_i32 addr;
95
96
addr = op_addr_ri_pre(s, a);
97
98
- tmp = load_reg(s, a->rt);
99
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
100
+ do_strd_store(s, addr, a->rt, rt2);
101
102
- tcg_gen_addi_i32(addr, addr, 4);
103
-
104
- tmp = load_reg(s, rt2);
105
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
106
-
107
- op_addr_ri_post(s, a, addr, -4);
108
+ op_addr_ri_post(s, a, addr, 0);
109
return true;
55
}
110
}
56
111
57
bool address_space_access_valid(AddressSpace *as, hwaddr addr,
58
- int len, bool is_write)
59
+ int len, bool is_write,
60
+ MemTxAttrs attrs)
61
{
62
FlatView *fv;
63
bool result;
64
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/s390x/diag.c
67
+++ b/target/s390x/diag.c
68
@@ -XXX,XX +XXX,XX @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
69
return;
70
}
71
if (!address_space_access_valid(&address_space_memory, addr,
72
- sizeof(IplParameterBlock), false)) {
73
+ sizeof(IplParameterBlock), false,
74
+ MEMTXATTRS_UNSPECIFIED)) {
75
s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
76
return;
77
}
78
@@ -XXX,XX +XXX,XX @@ out:
79
return;
80
}
81
if (!address_space_access_valid(&address_space_memory, addr,
82
- sizeof(IplParameterBlock), true)) {
83
+ sizeof(IplParameterBlock), true,
84
+ MEMTXATTRS_UNSPECIFIED)) {
85
s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
86
return;
87
}
88
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/s390x/excp_helper.c
91
+++ b/target/s390x/excp_helper.c
92
@@ -XXX,XX +XXX,XX @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr, int size,
93
94
/* check out of RAM access */
95
if (!address_space_access_valid(&address_space_memory, raddr,
96
- TARGET_PAGE_SIZE, rw)) {
97
+ TARGET_PAGE_SIZE, rw,
98
+ MEMTXATTRS_UNSPECIFIED)) {
99
DPRINTF("%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n", __func__,
100
(uint64_t)raddr, (uint64_t)ram_size);
101
trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_AUTO);
102
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/s390x/mmu_helper.c
105
+++ b/target/s390x/mmu_helper.c
106
@@ -XXX,XX +XXX,XX @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
107
return ret;
108
}
109
if (!address_space_access_valid(&address_space_memory, pages[i],
110
- TARGET_PAGE_SIZE, is_write)) {
111
+ TARGET_PAGE_SIZE, is_write,
112
+ MEMTXATTRS_UNSPECIFIED)) {
113
trigger_access_exception(env, PGM_ADDRESSING, ILEN_AUTO, 0);
114
return -EFAULT;
115
}
116
diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/s390x/sigp.c
119
+++ b/target/s390x/sigp.c
120
@@ -XXX,XX +XXX,XX @@ static void sigp_set_prefix(CPUState *cs, run_on_cpu_data arg)
121
cpu_synchronize_state(cs);
122
123
if (!address_space_access_valid(&address_space_memory, addr,
124
- sizeof(struct LowCore), false)) {
125
+ sizeof(struct LowCore), false,
126
+ MEMTXATTRS_UNSPECIFIED)) {
127
set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
128
return;
129
}
130
--
112
--
131
2.17.1
113
2.43.0
132
133
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
All the callers of op_addr_rr_post() and op_addr_ri_post() now pass in
2
add MemTxAttrs as an argument to tb_invalidate_phys_addr().
2
zero for the address_offset, so we can remove that argument.
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
3
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20180521140402.23318-3-peter.maydell@linaro.org
7
Message-id: 20250227142746.1698904-4-peter.maydell@linaro.org
10
---
8
---
11
include/exec/exec-all.h | 5 +++--
9
target/arm/tcg/translate.c | 26 +++++++++++++-------------
12
accel/tcg/translate-all.c | 2 +-
10
1 file changed, 13 insertions(+), 13 deletions(-)
13
exec.c | 2 +-
14
target/xtensa/op_helper.c | 3 ++-
15
4 files changed, 7 insertions(+), 5 deletions(-)
16
11
17
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
12
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/exec-all.h
14
--- a/target/arm/tcg/translate.c
20
+++ b/include/exec/exec-all.h
15
+++ b/target/arm/tcg/translate.c
21
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
16
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
22
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
17
}
23
hwaddr paddr, int prot,
18
24
int mmu_idx, target_ulong size);
19
static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
25
-void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr);
20
- TCGv_i32 addr, int address_offset)
26
+void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs);
21
+ TCGv_i32 addr)
27
void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
28
uintptr_t retaddr);
29
#else
30
@@ -XXX,XX +XXX,XX @@ static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
31
uint16_t idxmap)
32
{
22
{
23
if (!a->p) {
24
TCGv_i32 ofs = load_reg(s, a->rm);
25
@@ -XXX,XX +XXX,XX @@ static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
26
} else if (!a->w) {
27
return;
28
}
29
- tcg_gen_addi_i32(addr, addr, address_offset);
30
store_reg(s, a->rn, addr);
33
}
31
}
34
-static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
32
35
+static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr,
33
@@ -XXX,XX +XXX,XX @@ static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
36
+ MemTxAttrs attrs)
34
* Perform base writeback before the loaded value to
35
* ensure correct behavior with overlapping index registers.
36
*/
37
- op_addr_rr_post(s, a, addr, 0);
38
+ op_addr_rr_post(s, a, addr);
39
store_reg_from_load(s, a->rt, tmp);
40
return true;
41
}
42
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
43
gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
44
disas_set_da_iss(s, mop, issinfo);
45
46
- op_addr_rr_post(s, a, addr, 0);
47
+ op_addr_rr_post(s, a, addr);
48
return true;
49
}
50
51
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
52
do_ldrd_load(s, addr, a->rt, a->rt + 1);
53
54
/* LDRD w/ base writeback is undefined if the registers overlap. */
55
- op_addr_rr_post(s, a, addr, 0);
56
+ op_addr_rr_post(s, a, addr);
57
return true;
58
}
59
60
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
61
62
do_strd_store(s, addr, a->rt, a->rt + 1);
63
64
- op_addr_rr_post(s, a, addr, 0);
65
+ op_addr_rr_post(s, a, addr);
66
return true;
67
}
68
69
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
70
}
71
72
static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
73
- TCGv_i32 addr, int address_offset)
74
+ TCGv_i32 addr)
37
{
75
{
76
+ int address_offset = 0;
77
if (!a->p) {
78
if (a->u) {
79
- address_offset += a->imm;
80
+ address_offset = a->imm;
81
} else {
82
- address_offset -= a->imm;
83
+ address_offset = -a->imm;
84
}
85
} else if (!a->w) {
86
return;
87
@@ -XXX,XX +XXX,XX @@ static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
88
* Perform base writeback before the loaded value to
89
* ensure correct behavior with overlapping index registers.
90
*/
91
- op_addr_ri_post(s, a, addr, 0);
92
+ op_addr_ri_post(s, a, addr);
93
store_reg_from_load(s, a->rt, tmp);
94
return true;
38
}
95
}
39
#endif
96
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
40
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
97
gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
41
index XXXXXXX..XXXXXXX 100644
98
disas_set_da_iss(s, mop, issinfo);
42
--- a/accel/tcg/translate-all.c
99
43
+++ b/accel/tcg/translate-all.c
100
- op_addr_ri_post(s, a, addr, 0);
44
@@ -XXX,XX +XXX,XX @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
101
+ op_addr_ri_post(s, a, addr);
102
return true;
45
}
103
}
46
104
47
#if !defined(CONFIG_USER_ONLY)
105
@@ -XXX,XX +XXX,XX @@ static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
48
-void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
106
do_ldrd_load(s, addr, a->rt, rt2);
49
+void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
107
50
{
108
/* LDRD w/ base writeback is undefined if the registers overlap. */
51
ram_addr_t ram_addr;
109
- op_addr_ri_post(s, a, addr, 0);
52
MemoryRegion *mr;
110
+ op_addr_ri_post(s, a, addr);
53
diff --git a/exec.c b/exec.c
111
return true;
54
index XXXXXXX..XXXXXXX 100644
55
--- a/exec.c
56
+++ b/exec.c
57
@@ -XXX,XX +XXX,XX @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
58
if (phys != -1) {
59
/* Locks grabbed by tb_invalidate_phys_addr */
60
tb_invalidate_phys_addr(cpu->cpu_ases[asidx].as,
61
- phys | (pc & ~TARGET_PAGE_MASK));
62
+ phys | (pc & ~TARGET_PAGE_MASK), attrs);
63
}
64
}
112
}
65
#endif
113
66
diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c
114
@@ -XXX,XX +XXX,XX @@ static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
67
index XXXXXXX..XXXXXXX 100644
115
68
--- a/target/xtensa/op_helper.c
116
do_strd_store(s, addr, a->rt, rt2);
69
+++ b/target/xtensa/op_helper.c
117
70
@@ -XXX,XX +XXX,XX @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
118
- op_addr_ri_post(s, a, addr, 0);
71
int ret = xtensa_get_physical_addr(env, false, vaddr, 2, 0,
119
+ op_addr_ri_post(s, a, addr);
72
&paddr, &page_size, &access);
120
return true;
73
if (ret == 0) {
74
- tb_invalidate_phys_addr(&address_space_memory, paddr);
75
+ tb_invalidate_phys_addr(&address_space_memory, paddr,
76
+ MEMTXATTRS_UNSPECIFIED);
77
}
78
}
121
}
79
122
80
--
123
--
81
2.17.1
124
2.43.0
82
125
83
126
diff view generated by jsdifflib
1
Add more detail to the documentation for memory_region_init_iommu()
1
In debug_helper.c we provide a few dummy versions of
2
and other IOMMU-related functions and data structures.
2
debug registers:
3
* DBGVCR (AArch32 only): enable bits for vector-catch
4
debug events
5
* MDCCINT_EL1: interrupt enable bits for the DCC
6
debug communications channel
7
* DBGVCR32_EL2: the AArch64 accessor for the state in
8
DBGVCR
3
9
10
We implemented these only to stop Linux crashing on startup,
11
but we chose to implement them as ARM_CP_NOP. This worked
12
for Linux where it only cares about trying to write to these
13
registers, but is very confusing behaviour for anything that
14
wants to read the registers (perhaps for context state switches),
15
because the destination register will be left with whatever
16
random value it happened to have before the read.
17
18
Model these registers instead as RAZ.
19
20
Fixes: 5e8b12ffbb8c68 ("target-arm: Implement minimal DBGVCR, OSDLR_EL1, MDCCSR_EL0")
21
Fixes: 5dbdc4342f479d ("target-arm: Implement dummy MDCCINT_EL1")
22
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2708
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
25
Message-id: 20250228162424.1917269-1-peter.maydell@linaro.org
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20180521140402.23318-2-peter.maydell@linaro.org
9
---
26
---
10
include/exec/memory.h | 105 ++++++++++++++++++++++++++++++++++++++----
27
target/arm/debug_helper.c | 7 ++++---
11
1 file changed, 95 insertions(+), 10 deletions(-)
28
1 file changed, 4 insertions(+), 3 deletions(-)
12
29
13
diff --git a/include/exec/memory.h b/include/exec/memory.h
30
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
14
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
15
--- a/include/exec/memory.h
32
--- a/target/arm/debug_helper.c
16
+++ b/include/exec/memory.h
33
+++ b/target/arm/debug_helper.c
17
@@ -XXX,XX +XXX,XX @@ enum IOMMUMemoryRegionAttr {
34
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
18
IOMMU_ATTR_SPAPR_TCE_FD
35
{ .name = "DBGVCR",
36
.cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
37
.access = PL1_RW, .accessfn = access_tda,
38
- .type = ARM_CP_NOP },
39
+ .type = ARM_CP_CONST, .resetvalue = 0 },
40
/*
41
* Dummy MDCCINT_EL1, since we don't implement the Debug Communications
42
* Channel but Linux may try to access this register. The 32-bit
43
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
44
{ .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
45
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
46
.access = PL1_RW, .accessfn = access_tdcc,
47
- .type = ARM_CP_NOP },
48
+ .type = ARM_CP_CONST, .resetvalue = 0 },
49
/*
50
* Dummy DBGCLAIM registers.
51
* "The architecture does not define any functionality for the CLAIM tag bits.",
52
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_aa32_el1_reginfo[] = {
53
{ .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
54
.opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
55
.access = PL2_RW, .accessfn = access_dbgvcr32,
56
- .type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
57
+ .type = ARM_CP_CONST | ARM_CP_EL3_NO_EL2_KEEP,
58
+ .resetvalue = 0 },
19
};
59
};
20
60
21
+/**
61
static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
22
+ * IOMMUMemoryRegionClass:
23
+ *
24
+ * All IOMMU implementations need to subclass TYPE_IOMMU_MEMORY_REGION
25
+ * and provide an implementation of at least the @translate method here
26
+ * to handle requests to the memory region. Other methods are optional.
27
+ *
28
+ * The IOMMU implementation must use the IOMMU notifier infrastructure
29
+ * to report whenever mappings are changed, by calling
30
+ * memory_region_notify_iommu() (or, if necessary, by calling
31
+ * memory_region_notify_one() for each registered notifier).
32
+ */
33
typedef struct IOMMUMemoryRegionClass {
34
/* private */
35
struct DeviceClass parent_class;
36
37
/*
38
- * Return a TLB entry that contains a given address. Flag should
39
- * be the access permission of this translation operation. We can
40
- * set flag to IOMMU_NONE to mean that we don't need any
41
- * read/write permission checks, like, when for region replay.
42
+ * Return a TLB entry that contains a given address.
43
+ *
44
+ * The IOMMUAccessFlags indicated via @flag are optional and may
45
+ * be specified as IOMMU_NONE to indicate that the caller needs
46
+ * the full translation information for both reads and writes. If
47
+ * the access flags are specified then the IOMMU implementation
48
+ * may use this as an optimization, to stop doing a page table
49
+ * walk as soon as it knows that the requested permissions are not
50
+ * allowed. If IOMMU_NONE is passed then the IOMMU must do the
51
+ * full page table walk and report the permissions in the returned
52
+ * IOMMUTLBEntry. (Note that this implies that an IOMMU may not
53
+ * return different mappings for reads and writes.)
54
+ *
55
+ * The returned information remains valid while the caller is
56
+ * holding the big QEMU lock or is inside an RCU critical section;
57
+ * if the caller wishes to cache the mapping beyond that it must
58
+ * register an IOMMU notifier so it can invalidate its cached
59
+ * information when the IOMMU mapping changes.
60
+ *
61
+ * @iommu: the IOMMUMemoryRegion
62
+ * @hwaddr: address to be translated within the memory region
63
+ * @flag: requested access permissions
64
*/
65
IOMMUTLBEntry (*translate)(IOMMUMemoryRegion *iommu, hwaddr addr,
66
IOMMUAccessFlags flag);
67
- /* Returns minimum supported page size */
68
+ /* Returns minimum supported page size in bytes.
69
+ * If this method is not provided then the minimum is assumed to
70
+ * be TARGET_PAGE_SIZE.
71
+ *
72
+ * @iommu: the IOMMUMemoryRegion
73
+ */
74
uint64_t (*get_min_page_size)(IOMMUMemoryRegion *iommu);
75
- /* Called when IOMMU Notifier flag changed */
76
+ /* Called when IOMMU Notifier flag changes (ie when the set of
77
+ * events which IOMMU users are requesting notification for changes).
78
+ * Optional method -- need not be provided if the IOMMU does not
79
+ * need to know exactly which events must be notified.
80
+ *
81
+ * @iommu: the IOMMUMemoryRegion
82
+ * @old_flags: events which previously needed to be notified
83
+ * @new_flags: events which now need to be notified
84
+ */
85
void (*notify_flag_changed)(IOMMUMemoryRegion *iommu,
86
IOMMUNotifierFlag old_flags,
87
IOMMUNotifierFlag new_flags);
88
- /* Set this up to provide customized IOMMU replay function */
89
+ /* Called to handle memory_region_iommu_replay().
90
+ *
91
+ * The default implementation of memory_region_iommu_replay() is to
92
+ * call the IOMMU translate method for every page in the address space
93
+ * with flag == IOMMU_NONE and then call the notifier if translate
94
+ * returns a valid mapping. If this method is implemented then it
95
+ * overrides the default behaviour, and must provide the full semantics
96
+ * of memory_region_iommu_replay(), by calling @notifier for every
97
+ * translation present in the IOMMU.
98
+ *
99
+ * Optional method -- an IOMMU only needs to provide this method
100
+ * if the default is inefficient or produces undesirable side effects.
101
+ *
102
+ * Note: this is not related to record-and-replay functionality.
103
+ */
104
void (*replay)(IOMMUMemoryRegion *iommu, IOMMUNotifier *notifier);
105
106
- /* Get IOMMU misc attributes */
107
- int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr,
108
+ /* Get IOMMU misc attributes. This is an optional method that
109
+ * can be used to allow users of the IOMMU to get implementation-specific
110
+ * information. The IOMMU implements this method to handle calls
111
+ * by IOMMU users to memory_region_iommu_get_attr() by filling in
112
+ * the arbitrary data pointer for any IOMMUMemoryRegionAttr values that
113
+ * the IOMMU supports. If the method is unimplemented then
114
+ * memory_region_iommu_get_attr() will always return -EINVAL.
115
+ *
116
+ * @iommu: the IOMMUMemoryRegion
117
+ * @attr: attribute being queried
118
+ * @data: memory to fill in with the attribute data
119
+ *
120
+ * Returns 0 on success, or a negative errno; in particular
121
+ * returns -EINVAL for unrecognized or unimplemented attribute types.
122
+ */
123
+ int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr attr,
124
void *data);
125
} IOMMUMemoryRegionClass;
126
127
@@ -XXX,XX +XXX,XX @@ static inline void memory_region_init_reservation(MemoryRegion *mr,
128
* An IOMMU region translates addresses and forwards accesses to a target
129
* memory region.
130
*
131
+ * The IOMMU implementation must define a subclass of TYPE_IOMMU_MEMORY_REGION.
132
+ * @_iommu_mr should be a pointer to enough memory for an instance of
133
+ * that subclass, @instance_size is the size of that subclass, and
134
+ * @mrtypename is its name. This function will initialize @_iommu_mr as an
135
+ * instance of the subclass, and its methods will then be called to handle
136
+ * accesses to the memory region. See the documentation of
137
+ * #IOMMUMemoryRegionClass for further details.
138
+ *
139
* @_iommu_mr: the #IOMMUMemoryRegion to be initialized
140
* @instance_size: the IOMMUMemoryRegion subclass instance size
141
* @mrtypename: the type name of the #IOMMUMemoryRegion
142
@@ -XXX,XX +XXX,XX @@ void memory_region_register_iommu_notifier(MemoryRegion *mr,
143
* a notifier with the minimum page granularity returned by
144
* mr->iommu_ops->get_page_size().
145
*
146
+ * Note: this is not related to record-and-replay functionality.
147
+ *
148
* @iommu_mr: the memory region to observe
149
* @n: the notifier to which to replay iommu mappings
150
*/
151
@@ -XXX,XX +XXX,XX @@ void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n);
152
* memory_region_iommu_replay_all: replay existing IOMMU translations
153
* to all the notifiers registered.
154
*
155
+ * Note: this is not related to record-and-replay functionality.
156
+ *
157
* @iommu_mr: the memory region to observe
158
*/
159
void memory_region_iommu_replay_all(IOMMUMemoryRegion *iommu_mr);
160
@@ -XXX,XX +XXX,XX @@ void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
161
* memory_region_iommu_get_attr: return an IOMMU attr if get_attr() is
162
* defined on the IOMMU.
163
*
164
- * Returns 0 if succeded, error code otherwise.
165
+ * Returns 0 on success, or a negative errno otherwise. In particular,
166
+ * -EINVAL indicates that the IOMMU does not support the requested
167
+ * attribute.
168
*
169
* @iommu_mr: the memory region
170
* @attr: the requested attribute
171
--
62
--
172
2.17.1
63
2.43.0
173
174
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
Currently we call icount_start_warp_timer() from timerlist_rearm().
2
add MemTxAttrs as an argument to address_space_translate_iommu().
2
This produces incorrect behaviour, because timerlist_rearm() is
3
called, for instance, when a timer callback modifies its timer. We
4
cannot decide here to warp the timer forwards to the next timer
5
deadline merely because all_cpu_threads_idle() is true, because the
6
timer callback we were called from (or some other callback later in
7
the list of callbacks being invoked) may be about to raise a CPU
8
interrupt and move a CPU from idle to ready.
3
9
10
The only valid place to choose to warp the timer forward is from the
11
main loop, when we know we have no outstanding IO or timer callbacks
12
that might be about to wake up a CPU.
13
14
For Arm guests, this bug was mostly latent until the refactoring
15
commit f6fc36deef6abc ("target/arm/helper: Implement
16
CNTHCTL_EL2.CNT[VP]MASK"), which exposed it because it refactored a
17
timer callback so that it happened to call timer_mod() first and
18
raise the interrupt second, when it had previously raised the
19
interrupt first and called timer_mod() afterwards.
20
21
This call seems to have originally derived from the
22
pre-record-and-replay icount code, which (as of e.g. commit
23
db1a49726c3c in 2010) in this location did a call to
24
qemu_notify_event(), necessary to get the icount code in the vCPU
25
round-robin thread to stop and recalculate the icount deadline when a
26
timer was reprogrammed from the IO thread. In current QEMU,
27
everything is done on the vCPU thread when we are in icount mode, so
28
there's no need to try to notify another thread here.
29
30
I suspect that the other reason why this call was doing icount timer
31
warping is that it pre-dates commit efab87cf79077a from 2015, which
32
added a call to icount_start_warp_timer() to main_loop_wait(). Once
33
the call in timerlist_rearm() has been removed, if the timer
34
callbacks don't cause any CPU to be woken up then we will end up
35
calling icount_start_warp_timer() from main_loop_wait() when the rr
36
main loop code calls rr_wait_io_event().
37
38
Remove the incorrect call from timerlist_rearm().
39
40
Cc: qemu-stable@nongnu.org
41
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2703
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
44
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
45
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180521140402.23318-14-peter.maydell@linaro.org
46
Message-id: 20250210135804.3526943-1-peter.maydell@linaro.org
8
---
47
---
9
exec.c | 8 +++++---
48
util/qemu-timer.c | 4 ----
10
1 file changed, 5 insertions(+), 3 deletions(-)
49
1 file changed, 4 deletions(-)
11
50
12
diff --git a/exec.c b/exec.c
51
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
13
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
14
--- a/exec.c
53
--- a/util/qemu-timer.c
15
+++ b/exec.c
54
+++ b/util/qemu-timer.c
16
@@ -XXX,XX +XXX,XX @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
55
@@ -XXX,XX +XXX,XX @@ static bool timer_mod_ns_locked(QEMUTimerList *timer_list,
17
* @is_write: whether the translation operation is for write
56
18
* @is_mmio: whether this can be MMIO, set true if it can
57
static void timerlist_rearm(QEMUTimerList *timer_list)
19
* @target_as: the address space targeted by the IOMMU
20
+ * @attrs: transaction attributes
21
*
22
* This function is called from RCU critical section. It is the common
23
* part of flatview_do_translate and address_space_translate_cached.
24
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection address_space_translate_iommu(IOMMUMemoryRegion *iomm
25
hwaddr *page_mask_out,
26
bool is_write,
27
bool is_mmio,
28
- AddressSpace **target_as)
29
+ AddressSpace **target_as,
30
+ MemTxAttrs attrs)
31
{
58
{
32
MemoryRegionSection *section;
59
- /* Interrupt execution to force deadline recalculation. */
33
hwaddr page_mask = (hwaddr)-1;
60
- if (icount_enabled() && timer_list->clock->type == QEMU_CLOCK_VIRTUAL) {
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
61
- icount_start_warp_timer();
35
return address_space_translate_iommu(iommu_mr, xlat,
62
- }
36
plen_out, page_mask_out,
63
timerlist_notify(timer_list);
37
is_write, is_mmio,
38
- target_as);
39
+ target_as, attrs);
40
}
41
if (page_mask_out) {
42
/* Not behind an IOMMU, use default page size. */
43
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate_cached(
44
45
section = address_space_translate_iommu(iommu_mr, xlat, plen,
46
NULL, is_write, true,
47
- &target_as);
48
+ &target_as, attrs);
49
return section.mr;
50
}
64
}
51
65
52
--
66
--
53
2.17.1
67
2.43.0
54
68
55
69
diff view generated by jsdifflib
1
The FRECPX instructions should (like most other floating point operations)
1
Expand the example in the comment documenting MO_ATOM_SUBALIGN,
2
honour the FPCR.FZ bit which specifies whether input denormals should
2
to be clearer about the atomicity guarantees it represents.
3
be flushed to zero (or FZ16 for the half-precision version).
4
We forgot to implement this, which doesn't affect the results (since
5
the calculation doesn't actually care about the mantissa bits) but did
6
mean we were failing to set the FPSR.IDC bit.
7
3
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180521172712.19930-1-peter.maydell@linaro.org
6
Message-id: 20250228103222.1838913-1-peter.maydell@linaro.org
11
---
7
---
12
target/arm/helper-a64.c | 6 ++++++
8
include/exec/memop.h | 8 ++++++--
13
1 file changed, 6 insertions(+)
9
1 file changed, 6 insertions(+), 2 deletions(-)
14
10
15
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
11
diff --git a/include/exec/memop.h b/include/exec/memop.h
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-a64.c
13
--- a/include/exec/memop.h
18
+++ b/target/arm/helper-a64.c
14
+++ b/include/exec/memop.h
19
@@ -XXX,XX +XXX,XX @@ float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
15
@@ -XXX,XX +XXX,XX @@ typedef enum MemOp {
20
return nan;
16
* Depending on alignment, one or both will be single-copy atomic.
21
}
17
* This is the atomicity e.g. of Arm FEAT_LSE2 LDP.
22
18
* MO_ATOM_SUBALIGN: the operation is single-copy atomic by parts
23
+ a = float16_squash_input_denormal(a, fpst);
19
- * by the alignment. E.g. if the address is 0 mod 4, then each
24
+
20
- * 4-byte subobject is single-copy atomic.
25
val16 = float16_val(a);
21
+ * by the alignment. E.g. if an 8-byte value is accessed at an
26
sbit = 0x8000 & val16;
22
+ * address which is 0 mod 8, then the whole 8-byte access is
27
exp = extract32(val16, 10, 5);
23
+ * single-copy atomic; otherwise, if it is accessed at 0 mod 4
28
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
24
+ * then each 4-byte subobject is single-copy atomic; otherwise
29
return nan;
25
+ * if it is accessed at 0 mod 2 then the four 2-byte subobjects
30
}
26
+ * are single-copy atomic.
31
27
* This is the atomicity e.g. of IBM Power.
32
+ a = float32_squash_input_denormal(a, fpst);
28
* MO_ATOM_NONE: the operation has no atomicity requirements.
33
+
29
*
34
val32 = float32_val(a);
35
sbit = 0x80000000ULL & val32;
36
exp = extract32(val32, 23, 8);
37
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
38
return nan;
39
}
40
41
+ a = float64_squash_input_denormal(a, fpst);
42
+
43
val64 = float64_val(a);
44
sbit = 0x8000000000000000ULL & val64;
45
exp = extract64(float64_val(a), 52, 11);
46
--
30
--
47
2.17.1
31
2.43.0
48
49
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: JianChunfu <jansef.jian@hj-micro.com>
2
add MemTxAttrs as an argument to flatview_access_valid().
3
Its callers now all have an attrs value to hand, so we can
4
correct our earlier temporary use of MEMTXATTRS_UNSPECIFIED.
5
2
3
Use a similar terminology smmu_hash_remove_by_sid_range() as the one
4
being used for other hash table matching functions since
5
smmuv3_invalidate_ste() name is not self explanatory, and introduce a
6
helper that invokes the g_hash_table_foreach_remove.
7
8
No functional change intended.
9
10
Signed-off-by: JianChunfu <jansef.jian@hj-micro.com>
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
Message-id: 20250228031438.3916-1-jansef.jian@hj-micro.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-10-peter.maydell@linaro.org
10
---
14
---
11
exec.c | 12 +++++-------
15
hw/arm/smmu-internal.h | 5 -----
12
1 file changed, 5 insertions(+), 7 deletions(-)
16
include/hw/arm/smmu-common.h | 6 ++++++
17
hw/arm/smmu-common.c | 21 +++++++++++++++++++++
18
hw/arm/smmuv3.c | 19 ++-----------------
19
hw/arm/trace-events | 3 ++-
20
5 files changed, 31 insertions(+), 23 deletions(-)
13
21
14
diff --git a/exec.c b/exec.c
22
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/exec.c
24
--- a/hw/arm/smmu-internal.h
17
+++ b/exec.c
25
+++ b/hw/arm/smmu-internal.h
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
26
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBPageInvInfo {
19
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
27
uint64_t mask;
20
const uint8_t *buf, int len);
28
} SMMUIOTLBPageInvInfo;
21
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
29
22
- bool is_write);
30
-typedef struct SMMUSIDRange {
23
+ bool is_write, MemTxAttrs attrs);
31
- uint32_t start;
24
32
- uint32_t end;
25
static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
33
-} SMMUSIDRange;
26
unsigned len, MemTxAttrs attrs)
34
-
27
@@ -XXX,XX +XXX,XX @@ static bool subpage_accepts(void *opaque, hwaddr addr,
28
#endif
35
#endif
29
36
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
30
return flatview_access_valid(subpage->fv, addr + subpage->base,
37
index XXXXXXX..XXXXXXX 100644
31
- len, is_write);
38
--- a/include/hw/arm/smmu-common.h
32
+ len, is_write, attrs);
39
+++ b/include/hw/arm/smmu-common.h
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBKey {
41
uint8_t level;
42
} SMMUIOTLBKey;
43
44
+typedef struct SMMUSIDRange {
45
+ uint32_t start;
46
+ uint32_t end;
47
+} SMMUSIDRange;
48
+
49
struct SMMUState {
50
/* <private> */
51
SysBusDevice dev;
52
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova,
53
uint8_t tg, uint64_t num_pages, uint8_t ttl);
54
void smmu_iotlb_inv_ipa(SMMUState *s, int vmid, dma_addr_t ipa, uint8_t tg,
55
uint64_t num_pages, uint8_t ttl);
56
+void smmu_configs_inv_sid_range(SMMUState *s, SMMUSIDRange sid_range);
57
/* Unmap the range of all the notifiers registered to any IOMMU mr */
58
void smmu_inv_notifiers_all(SMMUState *s);
59
60
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/smmu-common.c
63
+++ b/hw/arm/smmu-common.c
64
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_hash_remove_by_vmid_ipa(gpointer key, gpointer value,
65
((entry->iova & ~info->mask) == info->iova);
33
}
66
}
34
67
35
static const MemoryRegionOps subpage_ops = {
68
+static gboolean
36
@@ -XXX,XX +XXX,XX @@ static void cpu_notify_map_clients(void)
69
+smmu_hash_remove_by_sid_range(gpointer key, gpointer value, gpointer user_data)
70
+{
71
+ SMMUDevice *sdev = (SMMUDevice *)key;
72
+ uint32_t sid = smmu_get_sid(sdev);
73
+ SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
74
+
75
+ if (sid < sid_range->start || sid > sid_range->end) {
76
+ return false;
77
+ }
78
+ trace_smmu_config_cache_inv(sid);
79
+ return true;
80
+}
81
+
82
+void smmu_configs_inv_sid_range(SMMUState *s, SMMUSIDRange sid_range)
83
+{
84
+ trace_smmu_configs_inv_sid_range(sid_range.start, sid_range.end);
85
+ g_hash_table_foreach_remove(s->configs, smmu_hash_remove_by_sid_range,
86
+ &sid_range);
87
+}
88
+
89
void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova,
90
uint8_t tg, uint64_t num_pages, uint8_t ttl)
91
{
92
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/arm/smmuv3.c
95
+++ b/hw/arm/smmuv3.c
96
@@ -XXX,XX +XXX,XX @@ static void smmuv3_flush_config(SMMUDevice *sdev)
97
SMMUv3State *s = sdev->smmu;
98
SMMUState *bc = &s->smmu_state;
99
100
- trace_smmuv3_config_cache_inv(smmu_get_sid(sdev));
101
+ trace_smmu_config_cache_inv(smmu_get_sid(sdev));
102
g_hash_table_remove(bc->configs, sdev);
37
}
103
}
38
104
39
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
105
@@ -XXX,XX +XXX,XX @@ static void smmuv3_range_inval(SMMUState *s, Cmd *cmd, SMMUStage stage)
40
- bool is_write)
106
}
41
+ bool is_write, MemTxAttrs attrs)
107
}
108
109
-static gboolean
110
-smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data)
111
-{
112
- SMMUDevice *sdev = (SMMUDevice *)key;
113
- uint32_t sid = smmu_get_sid(sdev);
114
- SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
115
-
116
- if (sid < sid_range->start || sid > sid_range->end) {
117
- return false;
118
- }
119
- trace_smmuv3_config_cache_inv(sid);
120
- return true;
121
-}
122
-
123
static int smmuv3_cmdq_consume(SMMUv3State *s)
42
{
124
{
43
MemoryRegion *mr;
125
SMMUState *bs = ARM_SMMU(s);
44
hwaddr l, xlat;
126
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
45
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
127
sid_range.end = sid_range.start + mask;
46
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
128
47
if (!memory_access_is_direct(mr, is_write)) {
129
trace_smmuv3_cmdq_cfgi_ste_range(sid_range.start, sid_range.end);
48
l = memory_access_size(mr, l, addr);
130
- g_hash_table_foreach_remove(bs->configs, smmuv3_invalidate_ste,
49
- /* When our callers all have attrs we'll pass them through here */
131
- &sid_range);
50
- if (!memory_region_access_valid(mr, xlat, l, is_write,
132
+ smmu_configs_inv_sid_range(bs, sid_range);
51
- MEMTXATTRS_UNSPECIFIED)) {
133
break;
52
+ if (!memory_region_access_valid(mr, xlat, l, is_write, attrs)) {
53
return false;
54
}
55
}
134
}
56
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
135
case SMMU_CMD_CFGI_CD:
57
136
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
58
rcu_read_lock();
137
index XXXXXXX..XXXXXXX 100644
59
fv = address_space_to_flatview(as);
138
--- a/hw/arm/trace-events
60
- result = flatview_access_valid(fv, addr, len, is_write);
139
+++ b/hw/arm/trace-events
61
+ result = flatview_access_valid(fv, addr, len, is_write, attrs);
140
@@ -XXX,XX +XXX,XX @@ smmu_iotlb_inv_asid_vmid(int asid, int vmid) "IOTLB invalidate asid=%d vmid=%d"
62
rcu_read_unlock();
141
smmu_iotlb_inv_vmid(int vmid) "IOTLB invalidate vmid=%d"
63
return result;
142
smmu_iotlb_inv_vmid_s1(int vmid) "IOTLB invalidate vmid=%d"
64
}
143
smmu_iotlb_inv_iova(int asid, uint64_t addr) "IOTLB invalidate asid=%d addr=0x%"PRIx64
144
+smmu_configs_inv_sid_range(uint32_t start, uint32_t end) "Config cache INV SID range from 0x%x to 0x%x"
145
+smmu_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
146
smmu_inv_notifiers_mr(const char *name) "iommu mr=%s"
147
smmu_iotlb_lookup_hit(int asid, int vmid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache HIT asid=%d vmid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
148
smmu_iotlb_lookup_miss(int asid, int vmid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache MISS asid=%d vmid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
149
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_tlbi_nh(int vmid) "vmid=%d"
150
smmuv3_cmdq_tlbi_nsnh(void) ""
151
smmuv3_cmdq_tlbi_nh_asid(int asid) "asid=%d"
152
smmuv3_cmdq_tlbi_s12_vmid(int vmid) "vmid=%d"
153
-smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
154
smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s"
155
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
156
smmuv3_inv_notifiers_iova(const char *name, int asid, int vmid, uint64_t iova, uint8_t tg, uint64_t num_pages, int stage) "iommu mr=%s asid=%d vmid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" stage=%d"
65
--
157
--
66
2.17.1
158
2.43.0
67
68
diff view generated by jsdifflib
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
1
From: Keith Packard <keithp@keithp.com>
2
2
3
kvm_irqchip_create called by kvm_init will call kvm_init_irq_routing to
3
The documentation says the vector is at 0xffffff80, instead of the
4
initialize global capability variables. If we call kvm_init_irq_routing in
4
previous value of 0xffffffc0. That value must have been a bug because
5
GIC realize function, previous allocated memory will leak.
5
the standard vector values (20, 21, 23, 25, 30) were all
6
past the end of the array.
6
7
7
Fix this by deleting the unnecessary call.
8
Signed-off-by: Keith Packard <keithp@keithp.com>
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Message-id: 1527750994-14360-1-git-send-email-zhaoshenglong@huawei.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
hw/intc/arm_gic_kvm.c | 1 -
12
target/rx/helper.c | 2 +-
15
hw/intc/arm_gicv3_kvm.c | 1 -
13
1 file changed, 1 insertion(+), 1 deletion(-)
16
2 files changed, 2 deletions(-)
17
14
18
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
15
diff --git a/target/rx/helper.c b/target/rx/helper.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gic_kvm.c
17
--- a/target/rx/helper.c
21
+++ b/hw/intc/arm_gic_kvm.c
18
+++ b/target/rx/helper.c
22
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ void rx_cpu_do_interrupt(CPUState *cs)
23
20
cpu_stl_data(env, env->isp, env->pc);
24
if (kvm_has_gsi_routing()) {
21
25
/* set up irq routing */
22
if (vec < 0x100) {
26
- kvm_init_irq_routing(kvm_state);
23
- env->pc = cpu_ldl_data(env, 0xffffffc0 + vec * 4);
27
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
24
+ env->pc = cpu_ldl_data(env, 0xffffff80 + vec * 4);
28
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
25
} else {
29
}
26
env->pc = cpu_ldl_data(env, env->intb + (vec & 0xff) * 4);
30
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/intc/arm_gicv3_kvm.c
33
+++ b/hw/intc/arm_gicv3_kvm.c
34
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
35
36
if (kvm_has_gsi_routing()) {
37
/* set up irq routing */
38
- kvm_init_irq_routing(kvm_state);
39
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
40
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
41
}
27
}
42
--
28
--
43
2.17.1
29
2.43.0
44
45
diff view generated by jsdifflib
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
1
From: Keith Packard <keithp@keithp.com>
2
2
3
It forgot to increase clroffset during the loop. So it only clear the
3
Functions which modify TCG globals must not be marked TCG_CALL_NO_WG,
4
first 4 bytes.
4
as that tells the optimizer that TCG global values already loaded in
5
machine registers are still valid, and so any changes which these
6
helpers make to the CPU state may be ignored.
5
7
6
Fixes: 367b9f527becdd20ddf116e17a3c0c2bbc486920
8
The target/rx code chooses to put (among other things) all the PSW
7
Cc: qemu-stable@nongnu.org
9
bits and also ACC into globals, so the NO_WG flag on various
8
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
10
functions that touch the PSW or ACC is incorrect and must be removed.
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
This includes all the floating point helper functions, because
10
Message-id: 1527047633-12368-1-git-send-email-zhaoshenglong@huawei.com
12
update_fpsw() will update PSW Z and S.
13
14
Signed-off-by: Keith Packard <keithp@keithp.com>
15
[PMM: Clarified commit message]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
18
---
14
hw/intc/arm_gicv3_kvm.c | 1 +
19
target/rx/helper.h | 34 +++++++++++++++++-----------------
15
1 file changed, 1 insertion(+)
20
1 file changed, 17 insertions(+), 17 deletions(-)
16
21
17
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
22
diff --git a/target/rx/helper.h b/target/rx/helper.h
18
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gicv3_kvm.c
24
--- a/target/rx/helper.h
20
+++ b/hw/intc/arm_gicv3_kvm.c
25
+++ b/target/rx/helper.h
21
@@ -XXX,XX +XXX,XX @@ static void kvm_dist_putbmp(GICv3State *s, uint32_t offset,
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(raise_privilege_violation, noreturn, env)
22
if (clroffset != 0) {
27
DEF_HELPER_1(wait, noreturn, env)
23
reg = 0;
28
DEF_HELPER_2(rxint, noreturn, env, i32)
24
kvm_gicd_access(s, clroffset, &reg, true);
29
DEF_HELPER_1(rxbrk, noreturn, env)
25
+ clroffset += 4;
30
-DEF_HELPER_FLAGS_3(fadd, TCG_CALL_NO_WG, f32, env, f32, f32)
26
}
31
-DEF_HELPER_FLAGS_3(fsub, TCG_CALL_NO_WG, f32, env, f32, f32)
27
reg = *gic_bmp_ptr32(bmp, irq);
32
-DEF_HELPER_FLAGS_3(fmul, TCG_CALL_NO_WG, f32, env, f32, f32)
28
kvm_gicd_access(s, offset, &reg, true);
33
-DEF_HELPER_FLAGS_3(fdiv, TCG_CALL_NO_WG, f32, env, f32, f32)
34
-DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_WG, void, env, f32, f32)
35
-DEF_HELPER_FLAGS_2(ftoi, TCG_CALL_NO_WG, i32, env, f32)
36
-DEF_HELPER_FLAGS_2(round, TCG_CALL_NO_WG, i32, env, f32)
37
-DEF_HELPER_FLAGS_2(itof, TCG_CALL_NO_WG, f32, env, i32)
38
+DEF_HELPER_3(fadd, f32, env, f32, f32)
39
+DEF_HELPER_3(fsub, f32, env, f32, f32)
40
+DEF_HELPER_3(fmul, f32, env, f32, f32)
41
+DEF_HELPER_3(fdiv, f32, env, f32, f32)
42
+DEF_HELPER_3(fcmp, void, env, f32, f32)
43
+DEF_HELPER_2(ftoi, i32, env, f32)
44
+DEF_HELPER_2(round, i32, env, f32)
45
+DEF_HELPER_2(itof, f32, env, i32)
46
DEF_HELPER_2(set_fpsw, void, env, i32)
47
-DEF_HELPER_FLAGS_2(racw, TCG_CALL_NO_WG, void, env, i32)
48
-DEF_HELPER_FLAGS_2(set_psw_rte, TCG_CALL_NO_WG, void, env, i32)
49
-DEF_HELPER_FLAGS_2(set_psw, TCG_CALL_NO_WG, void, env, i32)
50
+DEF_HELPER_2(racw, void, env, i32)
51
+DEF_HELPER_2(set_psw_rte, void, env, i32)
52
+DEF_HELPER_2(set_psw, void, env, i32)
53
DEF_HELPER_1(pack_psw, i32, env)
54
-DEF_HELPER_FLAGS_3(div, TCG_CALL_NO_WG, i32, env, i32, i32)
55
-DEF_HELPER_FLAGS_3(divu, TCG_CALL_NO_WG, i32, env, i32, i32)
56
-DEF_HELPER_FLAGS_1(scmpu, TCG_CALL_NO_WG, void, env)
57
+DEF_HELPER_3(div, i32, env, i32, i32)
58
+DEF_HELPER_3(divu, i32, env, i32, i32)
59
+DEF_HELPER_1(scmpu, void, env)
60
DEF_HELPER_1(smovu, void, env)
61
DEF_HELPER_1(smovf, void, env)
62
DEF_HELPER_1(smovb, void, env)
63
DEF_HELPER_2(sstr, void, env, i32)
64
-DEF_HELPER_FLAGS_2(swhile, TCG_CALL_NO_WG, void, env, i32)
65
-DEF_HELPER_FLAGS_2(suntil, TCG_CALL_NO_WG, void, env, i32)
66
-DEF_HELPER_FLAGS_2(rmpa, TCG_CALL_NO_WG, void, env, i32)
67
+DEF_HELPER_2(swhile, void, env, i32)
68
+DEF_HELPER_2(suntil, void, env, i32)
69
+DEF_HELPER_2(rmpa, void, env, i32)
70
DEF_HELPER_1(satr, void, env)
29
--
71
--
30
2.17.1
72
2.43.0
31
32
diff view generated by jsdifflib
Deleted patch
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
add MemTxAttrs as an argument to address_space_translate()
3
and address_space_translate_cached(). Callers either have an
4
attrs value to hand, or don't care and can use MEMTXATTRS_UNSPECIFIED.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-4-peter.maydell@linaro.org
10
---
11
include/exec/memory.h | 4 +++-
12
accel/tcg/translate-all.c | 2 +-
13
exec.c | 14 +++++++++-----
14
hw/vfio/common.c | 3 ++-
15
memory_ldst.inc.c | 18 +++++++++---------
16
target/riscv/helper.c | 2 +-
17
6 files changed, 25 insertions(+), 18 deletions(-)
18
19
diff --git a/include/exec/memory.h b/include/exec/memory.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/memory.h
22
+++ b/include/exec/memory.h
23
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
24
* #MemoryRegion.
25
* @len: pointer to length
26
* @is_write: indicates the transfer direction
27
+ * @attrs: memory attributes
28
*/
29
MemoryRegion *flatview_translate(FlatView *fv,
30
hwaddr addr, hwaddr *xlat,
31
@@ -XXX,XX +XXX,XX @@ MemoryRegion *flatview_translate(FlatView *fv,
32
33
static inline MemoryRegion *address_space_translate(AddressSpace *as,
34
hwaddr addr, hwaddr *xlat,
35
- hwaddr *len, bool is_write)
36
+ hwaddr *len, bool is_write,
37
+ MemTxAttrs attrs)
38
{
39
return flatview_translate(address_space_to_flatview(as),
40
addr, xlat, len, is_write);
41
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/accel/tcg/translate-all.c
44
+++ b/accel/tcg/translate-all.c
45
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
46
hwaddr l = 1;
47
48
rcu_read_lock();
49
- mr = address_space_translate(as, addr, &addr, &l, false);
50
+ mr = address_space_translate(as, addr, &addr, &l, false, attrs);
51
if (!(memory_region_is_ram(mr)
52
|| memory_region_is_romd(mr))) {
53
rcu_read_unlock();
54
diff --git a/exec.c b/exec.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/exec.c
57
+++ b/exec.c
58
@@ -XXX,XX +XXX,XX @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
59
rcu_read_lock();
60
while (len > 0) {
61
l = len;
62
- mr = address_space_translate(as, addr, &addr1, &l, true);
63
+ mr = address_space_translate(as, addr, &addr1, &l, true,
64
+ MEMTXATTRS_UNSPECIFIED);
65
66
if (!(memory_region_is_ram(mr) ||
67
memory_region_is_romd(mr))) {
68
@@ -XXX,XX +XXX,XX @@ void address_space_cache_destroy(MemoryRegionCache *cache)
69
*/
70
static inline MemoryRegion *address_space_translate_cached(
71
MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat,
72
- hwaddr *plen, bool is_write)
73
+ hwaddr *plen, bool is_write, MemTxAttrs attrs)
74
{
75
MemoryRegionSection section;
76
MemoryRegion *mr;
77
@@ -XXX,XX +XXX,XX @@ address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr,
78
MemoryRegion *mr;
79
80
l = len;
81
- mr = address_space_translate_cached(cache, addr, &addr1, &l, false);
82
+ mr = address_space_translate_cached(cache, addr, &addr1, &l, false,
83
+ MEMTXATTRS_UNSPECIFIED);
84
flatview_read_continue(cache->fv,
85
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
86
addr1, l, mr);
87
@@ -XXX,XX +XXX,XX @@ address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
88
MemoryRegion *mr;
89
90
l = len;
91
- mr = address_space_translate_cached(cache, addr, &addr1, &l, true);
92
+ mr = address_space_translate_cached(cache, addr, &addr1, &l, true,
93
+ MEMTXATTRS_UNSPECIFIED);
94
flatview_write_continue(cache->fv,
95
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
96
addr1, l, mr);
97
@@ -XXX,XX +XXX,XX @@ bool cpu_physical_memory_is_io(hwaddr phys_addr)
98
99
rcu_read_lock();
100
mr = address_space_translate(&address_space_memory,
101
- phys_addr, &phys_addr, &l, false);
102
+ phys_addr, &phys_addr, &l, false,
103
+ MEMTXATTRS_UNSPECIFIED);
104
105
res = !(memory_region_is_ram(mr) || memory_region_is_romd(mr));
106
rcu_read_unlock();
107
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/hw/vfio/common.c
110
+++ b/hw/vfio/common.c
111
@@ -XXX,XX +XXX,XX @@ static bool vfio_get_vaddr(IOMMUTLBEntry *iotlb, void **vaddr,
112
*/
113
mr = address_space_translate(&address_space_memory,
114
iotlb->translated_addr,
115
- &xlat, &len, writable);
116
+ &xlat, &len, writable,
117
+ MEMTXATTRS_UNSPECIFIED);
118
if (!memory_region_is_ram(mr)) {
119
error_report("iommu map to non memory area %"HWADDR_PRIx"",
120
xlat);
121
diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/memory_ldst.inc.c
124
+++ b/memory_ldst.inc.c
125
@@ -XXX,XX +XXX,XX @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
126
bool release_lock = false;
127
128
RCU_READ_LOCK();
129
- mr = TRANSLATE(addr, &addr1, &l, false);
130
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
131
if (l < 4 || !IS_DIRECT(mr, false)) {
132
release_lock |= prepare_mmio_access(mr);
133
134
@@ -XXX,XX +XXX,XX @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
135
bool release_lock = false;
136
137
RCU_READ_LOCK();
138
- mr = TRANSLATE(addr, &addr1, &l, false);
139
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
140
if (l < 8 || !IS_DIRECT(mr, false)) {
141
release_lock |= prepare_mmio_access(mr);
142
143
@@ -XXX,XX +XXX,XX @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
144
bool release_lock = false;
145
146
RCU_READ_LOCK();
147
- mr = TRANSLATE(addr, &addr1, &l, false);
148
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
149
if (!IS_DIRECT(mr, false)) {
150
release_lock |= prepare_mmio_access(mr);
151
152
@@ -XXX,XX +XXX,XX @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
153
bool release_lock = false;
154
155
RCU_READ_LOCK();
156
- mr = TRANSLATE(addr, &addr1, &l, false);
157
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
158
if (l < 2 || !IS_DIRECT(mr, false)) {
159
release_lock |= prepare_mmio_access(mr);
160
161
@@ -XXX,XX +XXX,XX @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
162
bool release_lock = false;
163
164
RCU_READ_LOCK();
165
- mr = TRANSLATE(addr, &addr1, &l, true);
166
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
167
if (l < 4 || !IS_DIRECT(mr, true)) {
168
release_lock |= prepare_mmio_access(mr);
169
170
@@ -XXX,XX +XXX,XX @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
171
bool release_lock = false;
172
173
RCU_READ_LOCK();
174
- mr = TRANSLATE(addr, &addr1, &l, true);
175
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
176
if (l < 4 || !IS_DIRECT(mr, true)) {
177
release_lock |= prepare_mmio_access(mr);
178
179
@@ -XXX,XX +XXX,XX @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
180
bool release_lock = false;
181
182
RCU_READ_LOCK();
183
- mr = TRANSLATE(addr, &addr1, &l, true);
184
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
185
if (!IS_DIRECT(mr, true)) {
186
release_lock |= prepare_mmio_access(mr);
187
r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
188
@@ -XXX,XX +XXX,XX @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
189
bool release_lock = false;
190
191
RCU_READ_LOCK();
192
- mr = TRANSLATE(addr, &addr1, &l, true);
193
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
194
if (l < 2 || !IS_DIRECT(mr, true)) {
195
release_lock |= prepare_mmio_access(mr);
196
197
@@ -XXX,XX +XXX,XX @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
198
bool release_lock = false;
199
200
RCU_READ_LOCK();
201
- mr = TRANSLATE(addr, &addr1, &l, true);
202
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
203
if (l < 8 || !IS_DIRECT(mr, true)) {
204
release_lock |= prepare_mmio_access(mr);
205
206
diff --git a/target/riscv/helper.c b/target/riscv/helper.c
207
index XXXXXXX..XXXXXXX 100644
208
--- a/target/riscv/helper.c
209
+++ b/target/riscv/helper.c
210
@@ -XXX,XX +XXX,XX @@ restart:
211
MemoryRegion *mr;
212
hwaddr l = sizeof(target_ulong), addr1;
213
mr = address_space_translate(cs->as, pte_addr,
214
- &addr1, &l, false);
215
+ &addr1, &l, false, MEMTXATTRS_UNSPECIFIED);
216
if (memory_access_is_direct(mr, true)) {
217
target_ulong *pte_pa =
218
qemu_map_ram_ptr(mr->ram_block, addr1);
219
--
220
2.17.1
221
222
diff view generated by jsdifflib
Deleted patch
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
add MemTxAttrs as an argument to address_space_map().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-5-peter.maydell@linaro.org
10
---
11
include/exec/memory.h | 3 ++-
12
include/sysemu/dma.h | 3 ++-
13
exec.c | 6 ++++--
14
target/ppc/mmu-hash64.c | 3 ++-
15
4 files changed, 10 insertions(+), 5 deletions(-)
16
17
diff --git a/include/exec/memory.h b/include/exec/memory.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/memory.h
20
+++ b/include/exec/memory.h
21
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
22
* @addr: address within that address space
23
* @plen: pointer to length of buffer; updated on return
24
* @is_write: indicates the transfer direction
25
+ * @attrs: memory attributes
26
*/
27
void *address_space_map(AddressSpace *as, hwaddr addr,
28
- hwaddr *plen, bool is_write);
29
+ hwaddr *plen, bool is_write, MemTxAttrs attrs);
30
31
/* address_space_unmap: Unmaps a memory region previously mapped by address_space_map()
32
*
33
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/sysemu/dma.h
36
+++ b/include/sysemu/dma.h
37
@@ -XXX,XX +XXX,XX @@ static inline void *dma_memory_map(AddressSpace *as,
38
hwaddr xlen = *len;
39
void *p;
40
41
- p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
42
+ p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE,
43
+ MEMTXATTRS_UNSPECIFIED);
44
*len = xlen;
45
return p;
46
}
47
diff --git a/exec.c b/exec.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/exec.c
50
+++ b/exec.c
51
@@ -XXX,XX +XXX,XX @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
52
void *address_space_map(AddressSpace *as,
53
hwaddr addr,
54
hwaddr *plen,
55
- bool is_write)
56
+ bool is_write,
57
+ MemTxAttrs attrs)
58
{
59
hwaddr len = *plen;
60
hwaddr l, xlat;
61
@@ -XXX,XX +XXX,XX @@ void *cpu_physical_memory_map(hwaddr addr,
62
hwaddr *plen,
63
int is_write)
64
{
65
- return address_space_map(&address_space_memory, addr, plen, is_write);
66
+ return address_space_map(&address_space_memory, addr, plen, is_write,
67
+ MEMTXATTRS_UNSPECIFIED);
68
}
69
70
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
71
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/ppc/mmu-hash64.c
74
+++ b/target/ppc/mmu-hash64.c
75
@@ -XXX,XX +XXX,XX @@ const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu,
76
return NULL;
77
}
78
79
- hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false);
80
+ hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false,
81
+ MEMTXATTRS_UNSPECIFIED);
82
if (plen < (n * HASH_PTE_SIZE_64)) {
83
hw_error("%s: Unable to map all requested HPTEs\n", __func__);
84
}
85
--
86
2.17.1
87
88
diff view generated by jsdifflib
Deleted patch
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
add MemTxAttrs as an argument to flatview_extend_translation().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-7-peter.maydell@linaro.org
10
---
11
exec.c | 15 ++++++++++-----
12
1 file changed, 10 insertions(+), 5 deletions(-)
13
14
diff --git a/exec.c b/exec.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/exec.c
17
+++ b/exec.c
18
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
19
20
static hwaddr
21
flatview_extend_translation(FlatView *fv, hwaddr addr,
22
- hwaddr target_len,
23
- MemoryRegion *mr, hwaddr base, hwaddr len,
24
- bool is_write)
25
+ hwaddr target_len,
26
+ MemoryRegion *mr, hwaddr base, hwaddr len,
27
+ bool is_write, MemTxAttrs attrs)
28
{
29
hwaddr done = 0;
30
hwaddr xlat;
31
@@ -XXX,XX +XXX,XX @@ void *address_space_map(AddressSpace *as,
32
33
memory_region_ref(mr);
34
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
35
- l, is_write);
36
+ l, is_write, attrs);
37
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
38
rcu_read_unlock();
39
40
@@ -XXX,XX +XXX,XX @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
41
mr = cache->mrs.mr;
42
memory_region_ref(mr);
43
if (memory_access_is_direct(mr, is_write)) {
44
+ /* We don't care about the memory attributes here as we're only
45
+ * doing this if we found actual RAM, which behaves the same
46
+ * regardless of attributes; so UNSPECIFIED is fine.
47
+ */
48
l = flatview_extend_translation(cache->fv, addr, len, mr,
49
- cache->xlat, l, is_write);
50
+ cache->xlat, l, is_write,
51
+ MEMTXATTRS_UNSPECIFIED);
52
cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
53
} else {
54
cache->ptr = NULL;
55
--
56
2.17.1
57
58
diff view generated by jsdifflib
Deleted patch
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
add MemTxAttrs as an argument to memory_region_access_valid().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
1
6
The callsite in flatview_access_valid() is part of a recursive
7
loop flatview_access_valid() -> memory_region_access_valid() ->
8
subpage_accepts() -> flatview_access_valid(); we make it pass
9
MEMTXATTRS_UNSPECIFIED for now, until the next several commits
10
have plumbed an attrs parameter through the rest of the loop
11
and we can add an attrs parameter to flatview_access_valid().
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20180521140402.23318-8-peter.maydell@linaro.org
17
---
18
include/exec/memory-internal.h | 3 ++-
19
exec.c | 4 +++-
20
hw/s390x/s390-pci-inst.c | 3 ++-
21
memory.c | 7 ++++---
22
4 files changed, 11 insertions(+), 6 deletions(-)
23
24
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/exec/memory-internal.h
27
+++ b/include/exec/memory-internal.h
28
@@ -XXX,XX +XXX,XX @@ void flatview_unref(FlatView *view);
29
extern const MemoryRegionOps unassigned_mem_ops;
30
31
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
32
- unsigned size, bool is_write);
33
+ unsigned size, bool is_write,
34
+ MemTxAttrs attrs);
35
36
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section);
37
AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv);
38
diff --git a/exec.c b/exec.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/exec.c
41
+++ b/exec.c
42
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
43
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
44
if (!memory_access_is_direct(mr, is_write)) {
45
l = memory_access_size(mr, l, addr);
46
- if (!memory_region_access_valid(mr, xlat, l, is_write)) {
47
+ /* When our callers all have attrs we'll pass them through here */
48
+ if (!memory_region_access_valid(mr, xlat, l, is_write,
49
+ MEMTXATTRS_UNSPECIFIED)) {
50
return false;
51
}
52
}
53
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/s390x/s390-pci-inst.c
56
+++ b/hw/s390x/s390-pci-inst.c
57
@@ -XXX,XX +XXX,XX @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
58
mr = s390_get_subregion(mr, offset, len);
59
offset -= mr->addr;
60
61
- if (!memory_region_access_valid(mr, offset, len, true)) {
62
+ if (!memory_region_access_valid(mr, offset, len, true,
63
+ MEMTXATTRS_UNSPECIFIED)) {
64
s390_program_interrupt(env, PGM_OPERAND, 6, ra);
65
return 0;
66
}
67
diff --git a/memory.c b/memory.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/memory.c
70
+++ b/memory.c
71
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps ram_device_mem_ops = {
72
bool memory_region_access_valid(MemoryRegion *mr,
73
hwaddr addr,
74
unsigned size,
75
- bool is_write)
76
+ bool is_write,
77
+ MemTxAttrs attrs)
78
{
79
int access_size_min, access_size_max;
80
int access_size, i;
81
@@ -XXX,XX +XXX,XX @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
82
{
83
MemTxResult r;
84
85
- if (!memory_region_access_valid(mr, addr, size, false)) {
86
+ if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
87
*pval = unassigned_mem_read(mr, addr, size);
88
return MEMTX_DECODE_ERROR;
89
}
90
@@ -XXX,XX +XXX,XX @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
91
unsigned size,
92
MemTxAttrs attrs)
93
{
94
- if (!memory_region_access_valid(mr, addr, size, true)) {
95
+ if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
96
unassigned_mem_write(mr, addr, data, size);
97
return MEMTX_DECODE_ERROR;
98
}
99
--
100
2.17.1
101
102
diff view generated by jsdifflib