1
ARM queue, various patches accumulated over the Christmas break.
1
Hi; this is the latest target-arm queue. Most of the patches
2
here are RTH's FEAT_HAFDBS finally landing. I've also included
3
the RNG-seed randomization patches from Jason, as well as a few
4
more minor things. The patches include a couple of regression
5
fixes:
6
* the resettable patch fixes a SCSI reset regression
7
* the 'do not re-randomize on snapshot load' patches fix
8
record-and-replay regressions
2
9
10
thanks
3
-- PMM
11
-- PMM
4
12
5
The following changes since commit 612061b277915fadd80631eb7a6926f48a110c44:
13
The following changes since commit e750a7ace492f0b450653d4ad368a77d6f660fb8:
6
14
7
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-01-10' into staging (2018-01-11 11:52:40 +0000)
15
Merge tag 'pull-9p-20221024' of https://github.com/cschoenebeck/qemu into staging (2022-10-24 14:27:12 -0400)
8
16
9
are available in the git repository at:
17
are available in the Git repository at:
10
18
11
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180111
19
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20221025
12
20
13
for you to fetch changes up to 0cf09852015e47a5fbb974ff7ac320366afd21ee:
21
for you to fetch changes up to e2114f701c78f76246e4b1872639dad94a6bdd21:
14
22
15
hw/intc/arm_gic: reserved register addresses are RAZ/WI (2018-01-11 13:25:40 +0000)
23
rx: re-randomize rng-seed on reboot (2022-10-25 17:32:24 +0100)
16
24
17
----------------------------------------------------------------
25
----------------------------------------------------------------
18
target-arm queue:
26
target-arm queue:
19
* add aarch64_be linux-user target
27
* Implement FEAT_E0PD
20
* Virt: ACPI: fix qemu assert due to re-assigned table data address
28
* Implement FEAT_HAFDBS
21
* imx_fec: various bug fixes and cleanups
29
* honor HCR_E2H and HCR_TGE in arm_excp_unmasked()
22
* hw/timer/pxa2xx_timer: replace hw_error() -> qemu_log_mask()
30
* hw/arm/virt: Fix devicetree warnings about the virtio-iommu node
23
* hw/sd/pxa2xx_mmci: add read/write() trace events
31
* hw/core/resettable: fix reset level counting
24
* linux-user/arm/nwfpe: Check coprocessor number for FPA emulation
32
* hw/hyperv/hyperv.c: Use device_cold_reset() instead of device_legacy_reset()
25
* target/arm: Make disas_thumb2_insn() generate its own UNDEF exceptions
33
* imx: reload cmp timer outside of the reload ptimer transaction
26
* hw/intc/arm_gicv3: Make reserved register addresses RAZ/WI
34
* x86: do not re-randomize RNG seed on snapshot load
27
* hw/intc/arm_gic: reserved register addresses are RAZ/WI
35
* m68k/virt: do not re-randomize RNG seed on snapshot load
36
* m68k/q800: do not re-randomize RNG seed on snapshot load
37
* arm: re-randomize rng-seed on reboot
38
* riscv: re-randomize rng-seed on reboot
39
* mips/boston: re-randomize rng-seed on reboot
40
* openrisc: re-randomize rng-seed on reboot
41
* rx: re-randomize rng-seed on reboot
28
42
29
----------------------------------------------------------------
43
----------------------------------------------------------------
30
Andrey Smirnov (11):
44
Ake Koomsin (1):
31
imx_fec: Do not link to netdev
45
target/arm: honor HCR_E2H and HCR_TGE in arm_excp_unmasked()
32
imx_fec: Refactor imx_eth_enable_rx()
33
imx_fec: Change queue flushing heuristics
34
imx_fec: Move Tx frame buffer away from the stack
35
imx_fec: Use ENET_FTRL to determine truncation length
36
imx_fec: Use MIN instead of explicit ternary operator
37
imx_fec: Emulate SHIFT16 in ENETx_RACC
38
imx_fec: Add support for multiple Tx DMA rings
39
imx_fec: Use correct length for packet size
40
imx_fec: Fix a typo in imx_enet_receive()
41
imx_fec: Reserve full FSL_IMX25_FEC_SIZE page for the register file
42
46
43
Michael Weiser (8):
47
Axel Heider (1):
44
linux-user: Add support for big-endian aarch64
48
target/imx: reload cmp timer outside of the reload ptimer transaction
45
linux-user: Add separate aarch64_be uname
46
linux-user: Fix endianess of aarch64 signal trampoline
47
configure: Add aarch64_be-linux-user target
48
linux-user: Add aarch64_be magic numbers to qemu-binfmt-conf.sh
49
linux-user: Separate binfmt arm CPU families
50
linux-user: Activate armeb handler registration
51
target/arm: Fix stlxp for aarch64_be
52
49
53
Peter Maydell (4):
50
Damien Hedde (1):
54
linux-user/arm/nwfpe: Check coprocessor number for FPA emulation
51
hw/core/resettable: fix reset level counting
55
target/arm: Make disas_thumb2_insn() generate its own UNDEF exceptions
56
hw/intc/arm_gicv3: Make reserved register addresses RAZ/WI
57
hw/intc/arm_gic: reserved register addresses are RAZ/WI
58
52
59
Philippe Mathieu-Daudé (2):
53
Jason A. Donenfeld (10):
60
hw/timer/pxa2xx_timer: replace hw_error() -> qemu_log_mask()
54
reset: allow registering handlers that aren't called by snapshot loading
61
hw/sd/pxa2xx_mmci: add read/write() trace events
55
device-tree: add re-randomization helper function
56
x86: do not re-randomize RNG seed on snapshot load
57
arm: re-randomize rng-seed on reboot
58
riscv: re-randomize rng-seed on reboot
59
m68k/virt: do not re-randomize RNG seed on snapshot load
60
m68k/q800: do not re-randomize RNG seed on snapshot load
61
mips/boston: re-randomize rng-seed on reboot
62
openrisc: re-randomize rng-seed on reboot
63
rx: re-randomize rng-seed on reboot
62
64
63
Zhaoshenglong (1):
65
Jean-Philippe Brucker (1):
64
Virt: ACPI: fix qemu assert due to re-assigned table data address
66
hw/arm/virt: Fix devicetree warnings about the virtio-iommu node
65
67
66
configure | 5 +-
68
Peter Maydell (2):
67
include/hw/arm/fsl-imx25.h | 1 -
69
target/arm: Implement FEAT_E0PD
68
include/hw/net/imx_fec.h | 27 +++-
70
hw/hyperv/hyperv.c: Use device_cold_reset() instead of device_legacy_reset()
69
linux-user/aarch64/target_syscall.h | 4 +
70
hw/arm/fsl-imx6.c | 1 +
71
hw/arm/virt-acpi-build.c | 18 ++-
72
hw/intc/arm_gic.c | 5 +-
73
hw/intc/arm_gicv3_dist.c | 13 ++
74
hw/intc/arm_gicv3_its_common.c | 8 +-
75
hw/intc/arm_gicv3_redist.c | 13 ++
76
hw/net/imx_fec.c | 210 +++++++++++++++++++++++-------
77
hw/sd/pxa2xx_mmci.c | 78 +++++++----
78
hw/timer/pxa2xx_timer.c | 17 ++-
79
linux-user/arm/nwfpe/fpa11.c | 9 ++
80
linux-user/main.c | 6 +
81
linux-user/signal.c | 10 +-
82
target/arm/helper-a64.c | 7 +-
83
target/arm/translate.c | 23 ++--
84
default-configs/aarch64_be-linux-user.mak | 1 +
85
hw/sd/trace-events | 4 +
86
scripts/qemu-binfmt-conf.sh | 15 ++-
87
21 files changed, 356 insertions(+), 119 deletions(-)
88
create mode 100644 default-configs/aarch64_be-linux-user.mak
89
71
72
Richard Henderson (14):
73
target/arm: Introduce regime_is_stage2
74
target/arm: Add ptw_idx to S1Translate
75
target/arm: Add isar predicates for FEAT_HAFDBS
76
target/arm: Extract HA and HD in aa64_va_parameters
77
target/arm: Move S1_ptw_translate outside arm_ld[lq]_ptw
78
target/arm: Add ARMFault_UnsuppAtomicUpdate
79
target/arm: Remove loop from get_phys_addr_lpae
80
target/arm: Fix fault reporting in get_phys_addr_lpae
81
target/arm: Don't shift attrs in get_phys_addr_lpae
82
target/arm: Consider GP an attribute in get_phys_addr_lpae
83
target/arm: Tidy merging of attributes from descriptor and table
84
target/arm: Implement FEAT_HAFDBS, access flag portion
85
target/arm: Implement FEAT_HAFDBS, dirty bit portion
86
target/arm: Use the max page size in a 2-stage ptw
87
88
docs/devel/reset.rst | 8 +-
89
docs/system/arm/emulation.rst | 2 +
90
qapi/run-state.json | 6 +-
91
include/hw/boards.h | 2 +-
92
include/sysemu/device_tree.h | 9 +
93
include/sysemu/reset.h | 5 +-
94
target/arm/cpu.h | 15 ++
95
target/arm/internals.h | 30 +++
96
hw/arm/aspeed.c | 4 +-
97
hw/arm/boot.c | 2 +
98
hw/arm/mps2-tz.c | 4 +-
99
hw/arm/virt.c | 5 +-
100
hw/core/reset.c | 17 +-
101
hw/core/resettable.c | 3 +-
102
hw/hppa/machine.c | 4 +-
103
hw/hyperv/hyperv.c | 2 +-
104
hw/i386/microvm.c | 4 +-
105
hw/i386/pc.c | 6 +-
106
hw/i386/x86.c | 2 +-
107
hw/m68k/q800.c | 33 ++-
108
hw/m68k/virt.c | 20 +-
109
hw/mips/boston.c | 3 +
110
hw/openrisc/boot.c | 3 +
111
hw/ppc/pegasos2.c | 4 +-
112
hw/ppc/pnv.c | 4 +-
113
hw/ppc/spapr.c | 4 +-
114
hw/riscv/boot.c | 3 +
115
hw/rx/rx-gdbsim.c | 3 +
116
hw/s390x/s390-virtio-ccw.c | 4 +-
117
hw/timer/imx_epit.c | 9 +-
118
migration/savevm.c | 2 +-
119
softmmu/device_tree.c | 21 ++
120
softmmu/runstate.c | 11 +-
121
target/arm/cpu.c | 24 +-
122
target/arm/cpu64.c | 2 +
123
target/arm/helper.c | 31 ++-
124
target/arm/ptw.c | 524 +++++++++++++++++++++++++++---------------
125
37 files changed, 572 insertions(+), 263 deletions(-)
diff view generated by jsdifflib
1
From: Zhaoshenglong <zhaoshenglong@huawei.com>
1
FEAT_E0PD adds new bits E0PD0 and E0PD1 to TCR_EL1, which allow the
2
OS to forbid EL0 access to half of the address space. Since this is
3
an EL0-specific variation on the existing TCR_ELx.{EPD0,EPD1}, we can
4
implement it entirely in aa64_va_parameters().
2
5
3
acpi_data_push uses g_array_set_size to resize the memory size. If there
6
This requires moving the existing regime_is_user() to internals.h
4
is no enough contiguous memory, the address will be changed. If we use
7
so that the code in helper.c can get at it.
5
the old value, it will assert.
6
qemu-kvm: hw/acpi/bios-linker-loader.c:214: bios_linker_loader_add_checksum:
7
Assertion `start_offset < file->blob->len' failed.`
8
8
9
This issue only happens in building SRAT table now but here we unify the
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
pattern for other tables as well to avoid possible issues in the future.
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20221021160131.3531787-1-peter.maydell@linaro.org
12
---
13
docs/system/arm/emulation.rst | 1 +
14
target/arm/cpu.h | 5 +++++
15
target/arm/internals.h | 19 +++++++++++++++++++
16
target/arm/cpu64.c | 1 +
17
target/arm/helper.c | 9 +++++++++
18
target/arm/ptw.c | 19 -------------------
19
6 files changed, 35 insertions(+), 19 deletions(-)
11
20
12
Signed-off-by: Zhaoshenglong <zhaoshenglong@huawei.com>
21
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
13
Reviewed-by: Andrew Jones <drjones@redhat.com>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/arm/virt-acpi-build.c | 18 +++++++++++-------
17
1 file changed, 11 insertions(+), 7 deletions(-)
18
19
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
20
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/virt-acpi-build.c
23
--- a/docs/system/arm/emulation.rst
22
+++ b/hw/arm/virt-acpi-build.c
24
+++ b/docs/system/arm/emulation.rst
23
@@ -XXX,XX +XXX,XX @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
25
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
24
AcpiSerialPortConsoleRedirection *spcr;
26
- FEAT_Debugv8p4 (Debug changes for v8.4)
25
const MemMapEntry *uart_memmap = &vms->memmap[VIRT_UART];
27
- FEAT_DotProd (Advanced SIMD dot product instructions)
26
int irq = vms->irqmap[VIRT_UART] + ARM_SPI_BASE;
28
- FEAT_DoubleFault (Double Fault Extension)
27
+ int spcr_start = table_data->len;
29
+- FEAT_E0PD (Preventing EL0 access to halves of address maps)
28
30
- FEAT_ETS (Enhanced Translation Synchronization)
29
spcr = acpi_data_push(table_data, sizeof(*spcr));
31
- FEAT_FCMA (Floating-point complex number instructions)
30
32
- FEAT_FHM (Floating-point half-precision multiplication instructions)
31
@@ -XXX,XX +XXX,XX @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
33
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
spcr->pci_device_id = 0xffff; /* PCI Device ID: not a PCI device */
34
index XXXXXXX..XXXXXXX 100644
33
spcr->pci_vendor_id = 0xffff; /* PCI Vendor ID: not a PCI device */
35
--- a/target/arm/cpu.h
34
36
+++ b/target/arm/cpu.h
35
- build_header(linker, table_data, (void *)spcr, "SPCR", sizeof(*spcr), 2,
37
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
36
- NULL, NULL);
38
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
37
+ build_header(linker, table_data, (void *)(table_data->data + spcr_start),
38
+ "SPCR", table_data->len - spcr_start, 2, NULL, NULL);
39
}
39
}
40
40
41
static void
41
+static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
42
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
42
+{
43
mem_base += numa_info[i].node_mem;
43
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
44
+}
45
+
46
static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
47
{
48
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
49
diff --git a/target/arm/internals.h b/target/arm/internals.h
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/internals.h
52
+++ b/target/arm/internals.h
53
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
44
}
54
}
45
46
- build_header(linker, table_data, (void *)srat, "SRAT",
47
- table_data->len - srat_start, 3, NULL, NULL);
48
+ build_header(linker, table_data, (void *)(table_data->data + srat_start),
49
+ "SRAT", table_data->len - srat_start, 3, NULL, NULL);
50
}
55
}
51
56
52
static void
57
+static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
53
@@ -XXX,XX +XXX,XX @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
58
+{
54
AcpiTableMcfg *mcfg;
59
+ switch (mmu_idx) {
55
const MemMapEntry *memmap = vms->memmap;
60
+ case ARMMMUIdx_E20_0:
56
int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
61
+ case ARMMMUIdx_Stage1_E0:
57
+ int mcfg_start = table_data->len;
62
+ case ARMMMUIdx_MUser:
58
63
+ case ARMMMUIdx_MSUser:
59
mcfg = acpi_data_push(table_data, len);
64
+ case ARMMMUIdx_MUserNegPri:
60
mcfg->allocation[0].address = cpu_to_le64(memmap[VIRT_PCIE_ECAM].base);
65
+ case ARMMMUIdx_MSUserNegPri:
61
@@ -XXX,XX +XXX,XX @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
+ return true;
62
mcfg->allocation[0].end_bus_number = (memmap[VIRT_PCIE_ECAM].size
67
+ default:
63
/ PCIE_MMCFG_SIZE_MIN) - 1;
68
+ return false;
64
69
+ case ARMMMUIdx_E10_0:
65
- build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
70
+ case ARMMMUIdx_E10_1:
66
+ build_header(linker, table_data, (void *)(table_data->data + mcfg_start),
71
+ case ARMMMUIdx_E10_1_PAN:
67
+ "MCFG", table_data->len - mcfg_start, 1, NULL, NULL);
72
+ g_assert_not_reached();
73
+ }
74
+}
75
+
76
/* Return the SCTLR value which controls this address translation regime */
77
static inline uint64_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
78
{
79
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/cpu64.c
82
+++ b/target/arm/cpu64.c
83
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
84
t = FIELD_DP64(t, ID_AA64MMFR2, FWB, 1); /* FEAT_S2FWB */
85
t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
86
t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
87
+ t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */
88
cpu->isar.id_aa64mmfr2 = t;
89
90
t = cpu->isar.id_aa64zfr0;
91
diff --git a/target/arm/helper.c b/target/arm/helper.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/helper.c
94
+++ b/target/arm/helper.c
95
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
96
ps = extract32(tcr, 16, 3);
97
ds = extract64(tcr, 32, 1);
98
} else {
99
+ bool e0pd;
100
+
101
/*
102
* Bit 55 is always between the two regions, and is canonical for
103
* determining if address tagging is enabled.
104
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
105
epd = extract32(tcr, 7, 1);
106
sh = extract32(tcr, 12, 2);
107
hpd = extract64(tcr, 41, 1);
108
+ e0pd = extract64(tcr, 55, 1);
109
} else {
110
tsz = extract32(tcr, 16, 6);
111
gran = tg1_to_gran_size(extract32(tcr, 30, 2));
112
epd = extract32(tcr, 23, 1);
113
sh = extract32(tcr, 28, 2);
114
hpd = extract64(tcr, 42, 1);
115
+ e0pd = extract64(tcr, 56, 1);
116
}
117
ps = extract64(tcr, 32, 3);
118
ds = extract64(tcr, 59, 1);
119
+
120
+ if (e0pd && cpu_isar_feature(aa64_e0pd, cpu) &&
121
+ regime_is_user(env, mmu_idx)) {
122
+ epd = true;
123
+ }
124
}
125
126
gran = sanitize_gran_size(cpu, gran, stage2);
127
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
128
index XXXXXXX..XXXXXXX 100644
129
--- a/target/arm/ptw.c
130
+++ b/target/arm/ptw.c
131
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_big_endian(CPUARMState *env, ARMMMUIdx mmu_idx)
132
return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0;
68
}
133
}
69
134
70
/* GTDT */
135
-static bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
71
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
136
-{
72
static void build_fadt(GArray *table_data, BIOSLinker *linker,
137
- switch (mmu_idx) {
73
VirtMachineState *vms, unsigned dsdt_tbl_offset)
138
- case ARMMMUIdx_E20_0:
139
- case ARMMMUIdx_Stage1_E0:
140
- case ARMMMUIdx_MUser:
141
- case ARMMMUIdx_MSUser:
142
- case ARMMMUIdx_MUserNegPri:
143
- case ARMMMUIdx_MSUserNegPri:
144
- return true;
145
- default:
146
- return false;
147
- case ARMMMUIdx_E10_0:
148
- case ARMMMUIdx_E10_1:
149
- case ARMMMUIdx_E10_1_PAN:
150
- g_assert_not_reached();
151
- }
152
-}
153
-
154
/* Return the TTBR associated with this translation regime */
155
static uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx, int ttbrn)
74
{
156
{
75
+ int fadt_start = table_data->len;
76
AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
77
unsigned xdsdt_entry_offset = (char *)&fadt->x_dsdt - table_data->data;
78
uint16_t bootflags;
79
@@ -XXX,XX +XXX,XX @@ static void build_fadt(GArray *table_data, BIOSLinker *linker,
80
ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->x_dsdt),
81
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
82
83
- build_header(linker, table_data,
84
- (void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL);
85
+ build_header(linker, table_data, (void *)(table_data->data + fadt_start),
86
+ "FACP", table_data->len - fadt_start, 5, NULL, NULL);
87
}
88
89
/* DSDT */
90
--
157
--
91
2.7.4
158
2.25.1
92
93
diff view generated by jsdifflib
1
The GICv2 specification says that reserved register addresses
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
must RAZ/WI; now that we implement external abort handling
3
for Arm CPUs this means we must return MEMTX_OK rather than
4
MEMTX_ERROR, to avoid generating a spurious guest data abort.
5
2
6
Cc: qemu-stable@nongnu.org
3
The "PCI Bus Binding to: IEEE Std 1275-1994" defines the compatible
4
string for a PCIe bus or endpoint as "pci<vendorid>,<deviceid>" or
5
similar. Since the initial binding for PCI virtio-iommu didn't follow
6
this rule, it was modified to accept both strings and ensure backward
7
compatibility. Also, the unit-name for the node should be
8
"device,function".
9
10
Fix corresponding dt-validate and dtc warnings:
11
12
pcie@10000000: virtio_iommu@16:compatible: ['virtio,pci-iommu'] does not contain items matching the given schema
13
pcie@10000000: Unevaluated properties are not allowed (... 'virtio_iommu@16' were unexpected)
14
From schema: linux/Documentation/devicetree/bindings/pci/host-generic-pci.yaml
15
virtio_iommu@16: compatible: 'oneOf' conditional failed, one must be fixed:
16
['virtio,pci-iommu'] is too short
17
'pci1af4,1057' was expected
18
From schema: dtschema/schemas/pci/pci-bus.yaml
19
20
Warning (pci_device_reg): /pcie@10000000/virtio_iommu@16: PCI unit address format error, expected "2,0"
21
22
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1513183941-24300-3-git-send-email-peter.maydell@linaro.org
9
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
10
---
25
---
11
hw/intc/arm_gic.c | 5 +++--
26
hw/arm/virt.c | 5 +++--
12
1 file changed, 3 insertions(+), 2 deletions(-)
27
1 file changed, 3 insertions(+), 2 deletions(-)
13
28
14
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/arm_gic.c
31
--- a/hw/arm/virt.c
17
+++ b/hw/intc/arm_gic.c
32
+++ b/hw/arm/virt.c
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
33
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms,
19
default:
34
20
qemu_log_mask(LOG_GUEST_ERROR,
35
static void create_virtio_iommu_dt_bindings(VirtMachineState *vms)
21
"gic_cpu_read: Bad offset %x\n", (int)offset);
36
{
22
- return MEMTX_ERROR;
37
- const char compat[] = "virtio,pci-iommu";
23
+ *data = 0;
38
+ const char compat[] = "virtio,pci-iommu\0pci1af4,1057";
24
+ break;
39
uint16_t bdf = vms->virtio_iommu_bdf;
25
}
40
MachineState *ms = MACHINE(vms);
26
return MEMTX_OK;
41
char *node;
27
}
42
28
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
43
vms->iommu_phandle = qemu_fdt_alloc_phandle(ms->fdt);
29
default:
44
30
qemu_log_mask(LOG_GUEST_ERROR,
45
- node = g_strdup_printf("%s/virtio_iommu@%d", vms->pciehb_nodename, bdf);
31
"gic_cpu_write: Bad offset %x\n", (int)offset);
46
+ node = g_strdup_printf("%s/virtio_iommu@%x,%x", vms->pciehb_nodename,
32
- return MEMTX_ERROR;
47
+ PCI_SLOT(bdf), PCI_FUNC(bdf));
33
+ return MEMTX_OK;
48
qemu_fdt_add_subnode(ms->fdt, node);
34
}
49
qemu_fdt_setprop(ms->fdt, node, "compatible", compat, sizeof(compat));
35
gic_update(s);
50
qemu_fdt_setprop_sized_cells(ms->fdt, node, "reg",
36
return MEMTX_OK;
37
--
51
--
38
2.7.4
52
2.25.1
39
40
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Ake Koomsin <ake@igel.co.jp>
2
2
3
Cc: Peter Maydell <peter.maydell@linaro.org>
3
An exception targeting EL2 from lower EL is actually maskable when
4
Cc: Jason Wang <jasowang@redhat.com>
4
HCR_E2H and HCR_TGE are both set. This applies to both secure and
5
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
non-secure Security state.
6
Cc: qemu-devel@nongnu.org
6
7
Cc: qemu-arm@nongnu.org
7
We can remove the conditions that try to suppress masking of
8
Cc: yurovsky@gmail.com
8
interrupts when we are Secure and the exception targets EL2 and
9
Secure EL2 is disabled. This is OK because in that situation
10
arm_phys_excp_target_el() will never return 2 as the target EL. The
11
'not if secure' check in this function was originally written before
12
arm_hcr_el2_eff(), and back then the target EL returned by
13
arm_phys_excp_target_el() could be 2 even if we were in Secure
14
EL0/EL1; but it is no longer needed.
15
16
Signed-off-by: Ake Koomsin <ake@igel.co.jp>
17
Message-id: 20221017092432.546881-1-ake@igel.co.jp
18
[PMM: Add commit message paragraph explaining why it's OK to
19
remove the checks on secure and SCR_EEL2]
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
22
---
13
hw/net/imx_fec.c | 2 +-
23
target/arm/cpu.c | 24 +++++++++++++++++-------
14
1 file changed, 1 insertion(+), 1 deletion(-)
24
1 file changed, 17 insertions(+), 7 deletions(-)
15
25
16
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/imx_fec.c
28
--- a/target/arm/cpu.c
19
+++ b/hw/net/imx_fec.c
29
+++ b/target/arm/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
30
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
21
size += 2;
31
if ((target_el > cur_el) && (target_el != 1)) {
22
}
32
/* Exceptions targeting a higher EL may not be maskable */
23
33
if (arm_feature(env, ARM_FEATURE_AARCH64)) {
24
- /* Huge frames are truncted. */
34
- /*
25
+ /* Huge frames are truncated. */
35
- * 64-bit masking rules are simple: exceptions to EL3
26
if (size > s->regs[ENET_FTRL]) {
36
- * can't be masked, and exceptions to EL2 can only be
27
size = s->regs[ENET_FTRL];
37
- * masked from Secure state. The HCR and SCR settings
28
flags |= ENET_BD_TR | ENET_BD_LG;
38
- * don't affect the masking logic, only the interrupt routing.
39
- */
40
- if (target_el == 3 || !secure || (env->cp15.scr_el3 & SCR_EEL2)) {
41
+ switch (target_el) {
42
+ case 2:
43
+ /*
44
+ * According to ARM DDI 0487H.a, an interrupt can be masked
45
+ * when HCR_E2H and HCR_TGE are both set regardless of the
46
+ * current Security state. Note that we need to revisit this
47
+ * part again once we need to support NMI.
48
+ */
49
+ if ((hcr_el2 & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
50
+ unmasked = true;
51
+ }
52
+ break;
53
+ case 3:
54
+ /* Interrupt cannot be masked when the target EL is 3 */
55
unmasked = true;
56
+ break;
57
+ default:
58
+ g_assert_not_reached();
59
}
60
} else {
61
/*
29
--
62
--
30
2.7.4
63
2.25.1
31
32
diff view generated by jsdifflib
1
Our copy of the nwfpe code for emulating of the old FPA11 floating
1
From: Damien Hedde <damien.hedde@greensocs.com>
2
point unit doesn't check the coprocessor number in the instruction
3
when it emulates it. This means that we might treat some
4
instructions which should really UNDEF as being FPA11 instructions by
5
accident.
6
2
7
The kernel's copy of the nwfpe code doesn't make this error; I suspect
3
The code for handling the reset level count in the Resettable code
8
the bug was noticed and fixed as part of the process of mainlining
4
has two issues:
9
the nwfpe code more than a decade ago.
10
5
11
Add a check that the coprocessor number (which is always in bits
6
The reset count is only decremented for the 1->0 case. This means
12
[11:8] of the instruction) is either 1 or 2, which is where the
7
that if there's ever a nested reset that takes the count to 2 then it
13
FPA11 lives.
8
will never again be decremented. Eventually the count will exceed
9
the '50' limit in resettable_phase_enter() and QEMU will trip over
10
the assertion failure. The repro case in issue 1266 is an example of
11
this that happens now the SCSI subsystem uses three-phase reset.
14
12
15
Reported-by: Richard Henderson <richard.henderson@linaro.org>
13
Secondly, the count is decremented only after the exit phase handler
14
is called. Moving the reset count decrement from "just after" to
15
"just before" calling the exit phase handler allows
16
resettable_is_in_reset() to return false during the handler
17
execution.
18
19
This simplifies reset handling in resettable devices. Typically, a
20
function that updates the device state will just need to read the
21
current reset state and not anymore treat the "in a reset-exit
22
transition" as a special case.
23
24
Note that the semantics change to the *_is_in_reset() functions
25
will have no effect on the current codebase, because only two
26
devices (hw/char/cadence_uart.c and hw/misc/zynq_sclr.c) currently
27
call those functions, and in neither case do they do it from the
28
device's exit phase methed.
29
30
Fixes: 4a5fc890 ("scsi: Use device_cold_reset() and bus_cold_reset()")
31
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1266
32
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Reported-by: Michael Peter <michael.peter@hensoldt-cyber.com>
35
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
36
Message-id: 20221020142749.3357951-1-peter.maydell@linaro.org
37
Buglink: https://bugs.launchpad.net/qemu/+bug/1905297
38
Reported-by: Michael Peter <michael.peter@hensoldt-cyber.com>
39
[PMM: adjust the docs paragraph changed to get the name of the
40
'enter' phase right and to clarify exactly when the count is
41
adjusted; rewrite the commit message]
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
43
---
18
linux-user/arm/nwfpe/fpa11.c | 9 +++++++++
44
docs/devel/reset.rst | 8 +++++---
19
1 file changed, 9 insertions(+)
45
hw/core/resettable.c | 3 +--
46
2 files changed, 6 insertions(+), 5 deletions(-)
20
47
21
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
48
diff --git a/docs/devel/reset.rst b/docs/devel/reset.rst
22
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
23
--- a/linux-user/arm/nwfpe/fpa11.c
50
--- a/docs/devel/reset.rst
24
+++ b/linux-user/arm/nwfpe/fpa11.c
51
+++ b/docs/devel/reset.rst
25
@@ -XXX,XX +XXX,XX @@ unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs)
52
@@ -XXX,XX +XXX,XX @@ Polling the reset state
26
unsigned int nRc = 0;
53
Resettable interface provides the ``resettable_is_in_reset()`` function.
27
// unsigned long flags;
54
This function returns true if the object parameter is currently under reset.
28
FPA11 *fpa11;
55
29
+ unsigned int cp;
56
-An object is under reset from the beginning of the *init* phase to the end of
30
// save_flags(flags); sti();
57
-the *exit* phase. During all three phases, the function will return that the
31
58
-object is in reset.
32
+ /* Check that this is really an FPA11 instruction: the coprocessor
59
+An object is under reset from the beginning of the *enter* phase (before
33
+ * field in bits [11:8] must be 1 or 2.
60
+either its children or its own enter method is called) to the *exit*
34
+ */
61
+phase. During *enter* and *hold* phase only, the function will return that the
35
+ cp = (opcode >> 8) & 0xf;
62
+object is in reset. The state is changed after the *exit* is propagated to
36
+ if (cp != 1 && cp != 2) {
63
+its children and just before calling the object's own *exit* method.
37
+ return 0;
64
38
+ }
65
This function may be used if the object behavior has to be adapted
39
+
66
while in reset state. For example if a device has an irq input,
40
qemufpa=qfpa;
67
diff --git a/hw/core/resettable.c b/hw/core/resettable.c
41
user_registers=qregs;
68
index XXXXXXX..XXXXXXX 100644
42
69
--- a/hw/core/resettable.c
70
+++ b/hw/core/resettable.c
71
@@ -XXX,XX +XXX,XX @@ static void resettable_phase_exit(Object *obj, void *opaque, ResetType type)
72
resettable_child_foreach(rc, obj, resettable_phase_exit, NULL, type);
73
74
assert(s->count > 0);
75
- if (s->count == 1) {
76
+ if (--s->count == 0) {
77
trace_resettable_phase_exit_exec(obj, obj_typename, !!rc->phases.exit);
78
if (rc->phases.exit && !resettable_get_tr_func(rc, obj)) {
79
rc->phases.exit(obj);
80
}
81
- s->count = 0;
82
}
83
s->exit_phase_in_progress = false;
84
trace_resettable_phase_exit_end(obj, obj_typename, s->count);
43
--
85
--
44
2.7.4
86
2.25.1
45
87
46
88
diff view generated by jsdifflib
1
Refactor disas_thumb2_insn() so that it generates the code for raising
1
The semantic difference between the deprecated device_legacy_reset()
2
an UNDEF exception for invalid insns, rather than returning a flag
2
function and the newer device_cold_reset() function is that the new
3
which the caller must check to see if it needs to generate the UNDEF
3
function resets both the device itself and any qbuses it owns,
4
code. This brings the function in to line with the behaviour of
4
whereas the legacy function resets just the device itself and nothing
5
disas_thumb_insn() and disas_arm_insn().
5
else. In hyperv_synic_reset() we reset a SynICState, which has no
6
qbuses, so for this purpose the two functions behave identically and
7
we can stop using the deprecated one.
6
8
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
9
Message-id: 1513080506-17703-1-git-send-email-peter.maydell@linaro.org
11
Message-id: 20221013171817.1447562-1-peter.maydell@linaro.org
10
---
12
---
11
target/arm/translate.c | 23 ++++++++++-------------
13
hw/hyperv/hyperv.c | 2 +-
12
1 file changed, 10 insertions(+), 13 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
13
15
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
18
--- a/hw/hyperv/hyperv.c
17
+++ b/target/arm/translate.c
19
+++ b/hw/hyperv/hyperv.c
18
@@ -XXX,XX +XXX,XX @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
20
@@ -XXX,XX +XXX,XX @@ void hyperv_synic_reset(CPUState *cs)
19
return 0;
21
SynICState *synic = get_synic(cs);
22
23
if (synic) {
24
- device_legacy_reset(DEVICE(synic));
25
+ device_cold_reset(DEVICE(synic));
26
}
20
}
27
}
21
28
22
-/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
23
- is not legal. */
24
-static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
25
+/* Translate a 32-bit thumb instruction. */
26
+static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
27
{
28
uint32_t imm, shift, offset;
29
uint32_t rd, rn, rm, rs;
30
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
31
/* UNPREDICTABLE, unallocated hint or
32
* PLD/PLDW/PLI (literal)
33
*/
34
- return 0;
35
+ return;
36
}
37
if (op1 & 1) {
38
- return 0; /* PLD/PLDW/PLI or unallocated hint */
39
+ return; /* PLD/PLDW/PLI or unallocated hint */
40
}
41
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
42
- return 0; /* PLD/PLDW/PLI or unallocated hint */
43
+ return; /* PLD/PLDW/PLI or unallocated hint */
44
}
45
/* UNDEF space, or an UNPREDICTABLE */
46
- return 1;
47
+ goto illegal_op;
48
}
49
}
50
memidx = get_mem_index(s);
51
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
52
default:
53
goto illegal_op;
54
}
55
- return 0;
56
+ return;
57
illegal_op:
58
- return 1;
59
+ gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
60
+ default_exception_el(s));
61
}
62
63
static void disas_thumb_insn(DisasContext *s, uint32_t insn)
64
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
65
if (is_16bit) {
66
disas_thumb_insn(dc, insn);
67
} else {
68
- if (disas_thumb2_insn(dc, insn)) {
69
- gen_exception_insn(dc, 4, EXCP_UDEF, syn_uncategorized(),
70
- default_exception_el(dc));
71
- }
72
+ disas_thumb2_insn(dc, insn);
73
}
74
75
/* Advance the Thumb condexec condition. */
76
--
29
--
77
2.7.4
30
2.25.1
78
79
diff view generated by jsdifflib
1
The GICv3 specification says that reserved register addresses
1
From: Axel Heider <axel.heider@hensoldt.net>
2
should RAZ/WI. This means we need to return MEMTX_OK, not MEMTX_ERROR,
3
because now that we support generating external aborts the
4
latter will cause an abort on new board models.
5
2
6
Cc: qemu-stable@nongnu.org
3
When running seL4 tests (https://docs.sel4.systems/projects/sel4test)
4
on the sabrelight platform, the timer tests fail. The arm/imx6 EPIT
5
timer interrupt does not fire properly, instead of a e.g. second in
6
can take up to a minute to finally see the interrupt.
7
8
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1263
9
10
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
11
Message-id: 166663118138.13362.1229967229046092876-0@git.sr.ht
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1513183941-24300-2-git-send-email-peter.maydell@linaro.org
9
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
10
---
14
---
11
hw/intc/arm_gicv3_dist.c | 13 +++++++++++++
15
hw/timer/imx_epit.c | 9 +++++++--
12
hw/intc/arm_gicv3_its_common.c | 8 +++-----
16
1 file changed, 7 insertions(+), 2 deletions(-)
13
hw/intc/arm_gicv3_redist.c | 13 +++++++++++++
14
3 files changed, 29 insertions(+), 5 deletions(-)
15
17
16
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
18
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/arm_gicv3_dist.c
20
--- a/hw/timer/imx_epit.c
19
+++ b/hw/intc/arm_gicv3_dist.c
21
+++ b/hw/timer/imx_epit.c
20
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_dist_read(void *opaque, hwaddr offset, uint64_t *data,
22
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
21
"%s: invalid guest read at offset " TARGET_FMT_plx
23
/* If IOVW bit is set then set the timer value */
22
"size %u\n", __func__, offset, size);
24
ptimer_set_count(s->timer_reload, s->lr);
23
trace_gicv3_dist_badread(offset, size, attrs.secure);
24
+ /* The spec requires that reserved registers are RAZ/WI;
25
+ * so use MEMTX_ERROR returns from leaf functions as a way to
26
+ * trigger the guest-error logging but don't return it to
27
+ * the caller, or we'll cause a spurious guest data abort.
28
+ */
29
+ r = MEMTX_OK;
30
+ *data = 0;
31
} else {
32
trace_gicv3_dist_read(offset, *data, size, attrs.secure);
33
}
34
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_dist_write(void *opaque, hwaddr offset, uint64_t data,
35
"%s: invalid guest write at offset " TARGET_FMT_plx
36
"size %u\n", __func__, offset, size);
37
trace_gicv3_dist_badwrite(offset, data, size, attrs.secure);
38
+ /* The spec requires that reserved registers are RAZ/WI;
39
+ * so use MEMTX_ERROR returns from leaf functions as a way to
40
+ * trigger the guest-error logging but don't return it to
41
+ * the caller, or we'll cause a spurious guest data abort.
42
+ */
43
+ r = MEMTX_OK;
44
} else {
45
trace_gicv3_dist_write(offset, data, size, attrs.secure);
46
}
47
diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/intc/arm_gicv3_its_common.c
50
+++ b/hw/intc/arm_gicv3_its_common.c
51
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_trans_read(void *opaque, hwaddr offset,
52
MemTxAttrs attrs)
53
{
54
qemu_log_mask(LOG_GUEST_ERROR, "ITS read at offset 0x%"PRIx64"\n", offset);
55
- return MEMTX_ERROR;
56
+ *data = 0;
57
+ return MEMTX_OK;
58
}
59
60
static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset,
61
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset,
62
if (ret <= 0) {
63
qemu_log_mask(LOG_GUEST_ERROR,
64
"ITS: Error sending MSI: %s\n", strerror(-ret));
65
- return MEMTX_DECODE_ERROR;
66
}
25
}
67
-
26
-
68
- return MEMTX_OK;
27
+ /*
69
} else {
28
+ * Commit the change to s->timer_reload, so it can propagate. Otherwise
70
qemu_log_mask(LOG_GUEST_ERROR,
29
+ * the timer interrupt may not fire properly. The commit must happen
71
"ITS write at bad offset 0x%"PRIx64"\n", offset);
30
+ * before calling imx_epit_reload_compare_timer(), which reads
72
- return MEMTX_DECODE_ERROR;
31
+ * s->timer_reload internally again.
73
}
74
+ return MEMTX_OK;
75
}
76
77
static const MemoryRegionOps gicv3_its_trans_ops = {
78
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/intc/arm_gicv3_redist.c
81
+++ b/hw/intc/arm_gicv3_redist.c
82
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
83
"size %u\n", __func__, offset, size);
84
trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset,
85
size, attrs.secure);
86
+ /* The spec requires that reserved registers are RAZ/WI;
87
+ * so use MEMTX_ERROR returns from leaf functions as a way to
88
+ * trigger the guest-error logging but don't return it to
89
+ * the caller, or we'll cause a spurious guest data abort.
90
+ */
32
+ */
91
+ r = MEMTX_OK;
33
+ ptimer_transaction_commit(s->timer_reload);
92
+ *data = 0;
34
imx_epit_reload_compare_timer(s);
93
} else {
35
ptimer_transaction_commit(s->timer_cmp);
94
trace_gicv3_redist_read(gicv3_redist_affid(cs), offset, *data,
36
- ptimer_transaction_commit(s->timer_reload);
95
size, attrs.secure);
37
break;
96
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
38
97
"size %u\n", __func__, offset, size);
39
case 3: /* CMP */
98
trace_gicv3_redist_badwrite(gicv3_redist_affid(cs), offset, data,
99
size, attrs.secure);
100
+ /* The spec requires that reserved registers are RAZ/WI;
101
+ * so use MEMTX_ERROR returns from leaf functions as a way to
102
+ * trigger the guest-error logging but don't return it to
103
+ * the caller, or we'll cause a spurious guest data abort.
104
+ */
105
+ r = MEMTX_OK;
106
} else {
107
trace_gicv3_redist_write(gicv3_redist_affid(cs), offset, data,
108
size, attrs.secure);
109
--
40
--
110
2.7.4
41
2.25.1
111
112
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In current implementation, packet queue flushing logic seem to suffer
3
Reduce the amount of typing required for this check.
4
from a deadlock like scenario if a packet is received by the interface
5
before before Rx ring is initialized by Guest's driver. Consider the
6
following sequence of events:
7
4
8
    1. A QEMU instance is started against a TAP device on Linux
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
     host, running Linux guest, e. g., something to the effect
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
     of:
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
8
Message-id: 20221024051851.3074715-2-richard.henderson@linaro.org
12
     qemu-system-arm \
13
     -net nic,model=imx.fec,netdev=lan0 \
14
     netdev tap,id=lan0,ifname=tap0,script=no,downscript=no \
15
     ... rest of the arguments ...
16
17
    2. Once QEMU starts, but before guest reaches the point where
18
     FEC deriver is done initializing the HW, Guest, via TAP
19
     interface, receives a number of multicast MDNS packets from
20
     Host (not necessarily true for every OS, but it happens at
21
     least on Fedora 25)
22
23
    3. Recieving a packet in such a state results in
24
     imx_eth_can_receive() returning '0', which in turn causes
25
     tap_send() to disable corresponding event (tap.c:203)
26
27
    4. Once Guest's driver reaches the point where it is ready to
28
     recieve packets it prepares Rx ring descriptors and writes
29
     ENET_RDAR_RDAR to ENET_RDAR register to indicate to HW that
30
     more descriptors are ready. And at this points emulation
31
     layer does this:
32
33
          s->regs[index] = ENET_RDAR_RDAR;
34
imx_eth_enable_rx(s);
35
36
     which, combined with:
37
38
          if (!s->regs[ENET_RDAR]) {
39
         qemu_flush_queued_packets(qemu_get_queue(s->nic));
40
         }
41
42
     results in Rx queue never being flushed and corresponding
43
     I/O event beign disabled.
44
45
To prevent the problem, change the code to always flush packet queue
46
when ENET_RDAR transitions 0 -> ENET_RDAR_RDAR.
47
48
Cc: Peter Maydell <peter.maydell@linaro.org>
49
Cc: Jason Wang <jasowang@redhat.com>
50
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
51
Cc: qemu-devel@nongnu.org
52
Cc: qemu-arm@nongnu.org
53
Cc: yurovsky@gmail.com
54
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
55
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
56
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
57
---
10
---
58
hw/net/imx_fec.c | 12 ++++++------
11
target/arm/internals.h | 5 +++++
59
1 file changed, 6 insertions(+), 6 deletions(-)
12
target/arm/helper.c | 14 +++++---------
13
target/arm/ptw.c | 14 ++++++--------
14
3 files changed, 16 insertions(+), 17 deletions(-)
60
15
61
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
62
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/net/imx_fec.c
18
--- a/target/arm/internals.h
64
+++ b/hw/net/imx_fec.c
19
+++ b/target/arm/internals.h
65
@@ -XXX,XX +XXX,XX @@ static void imx_eth_do_tx(IMXFECState *s)
20
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
66
}
21
}
67
}
22
}
68
23
69
-static void imx_eth_enable_rx(IMXFECState *s)
24
+static inline bool regime_is_stage2(ARMMMUIdx mmu_idx)
70
+static void imx_eth_enable_rx(IMXFECState *s, bool flush)
25
+{
26
+ return mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S;
27
+}
28
+
29
/* Return the exception level which controls this address translation regime */
30
static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
71
{
31
{
72
IMXFECBufDesc bd;
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
73
bool rx_ring_full;
33
index XXXXXXX..XXXXXXX 100644
74
@@ -XXX,XX +XXX,XX @@ static void imx_eth_enable_rx(IMXFECState *s)
34
--- a/target/arm/helper.c
75
35
+++ b/target/arm/helper.c
76
if (rx_ring_full) {
36
@@ -XXX,XX +XXX,XX @@ int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
77
FEC_PRINTF("RX buffer full\n");
37
{
78
- } else if (!s->regs[ENET_RDAR]) {
38
if (regime_has_2_ranges(mmu_idx)) {
79
+ } else if (flush) {
39
return extract64(tcr, 37, 2);
80
qemu_flush_queued_packets(qemu_get_queue(s->nic));
40
- } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
41
+ } else if (regime_is_stage2(mmu_idx)) {
42
return 0; /* VTCR_EL2 */
43
} else {
44
/* Replicate the single TBI bit so we always have 2 bits. */
45
@@ -XXX,XX +XXX,XX @@ int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
46
{
47
if (regime_has_2_ranges(mmu_idx)) {
48
return extract64(tcr, 51, 2);
49
- } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
50
+ } else if (regime_is_stage2(mmu_idx)) {
51
return 0; /* VTCR_EL2 */
52
} else {
53
/* Replicate the single TBID bit so we always have 2 bits. */
54
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
55
int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
56
ARMGranuleSize gran;
57
ARMCPU *cpu = env_archcpu(env);
58
- bool stage2 = mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S;
59
+ bool stage2 = regime_is_stage2(mmu_idx);
60
61
if (!regime_has_2_ranges(mmu_idx)) {
62
select = 0;
63
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
64
}
65
ds = false;
66
} else if (ds) {
67
- switch (mmu_idx) {
68
- case ARMMMUIdx_Stage2:
69
- case ARMMMUIdx_Stage2_S:
70
+ if (regime_is_stage2(mmu_idx)) {
71
if (gran == Gran16K) {
72
ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
73
} else {
74
ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
75
}
76
- break;
77
- default:
78
+ } else {
79
if (gran == Gran16K) {
80
ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
81
} else {
82
ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
83
}
84
- break;
85
}
86
if (ds) {
87
min_tsz = 12;
88
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/ptw.c
91
+++ b/target/arm/ptw.c
92
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
93
bool have_wxn;
94
int wxn = 0;
95
96
- assert(mmu_idx != ARMMMUIdx_Stage2);
97
- assert(mmu_idx != ARMMMUIdx_Stage2_S);
98
+ assert(!regime_is_stage2(mmu_idx));
99
100
user_rw = simple_ap_to_rw_prot_is_user(ap, true);
101
if (is_user) {
102
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
103
goto do_fault;
81
}
104
}
82
105
83
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
106
- if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
84
if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
107
+ if (!regime_is_stage2(mmu_idx)) {
85
if (!s->regs[index]) {
108
/*
86
s->regs[index] = ENET_RDAR_RDAR;
109
* The starting level depends on the virtual address size (which can
87
- imx_eth_enable_rx(s);
110
* be up to 48 bits) and the translation granule size. It indicates
88
+ imx_eth_enable_rx(s, true);
111
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
89
}
112
attrs = extract64(descriptor, 2, 10)
90
} else {
113
| (extract64(descriptor, 52, 12) << 10);
91
s->regs[index] = 0;
114
92
@@ -XXX,XX +XXX,XX @@ static int imx_eth_can_receive(NetClientState *nc)
115
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
93
116
+ if (regime_is_stage2(mmu_idx)) {
94
FEC_PRINTF("\n");
117
/* Stage 2 table descriptors do not include any attribute fields */
95
118
break;
96
- return s->regs[ENET_RDAR] ? 1 : 0;
97
+ return !!s->regs[ENET_RDAR];
98
}
99
100
static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
101
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
102
}
119
}
120
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
121
122
ap = extract32(attrs, 4, 2);
123
124
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
125
+ if (regime_is_stage2(mmu_idx)) {
126
ns = mmu_idx == ARMMMUIdx_Stage2;
127
xn = extract32(attrs, 11, 2);
128
result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
129
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
130
result->f.guarded = guarded;
103
}
131
}
104
s->rx_descriptor = addr;
132
105
- imx_eth_enable_rx(s);
133
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
106
+ imx_eth_enable_rx(s, false);
134
+ if (regime_is_stage2(mmu_idx)) {
107
imx_eth_update(s);
135
result->cacheattrs.is_s2_format = true;
108
return len;
136
result->cacheattrs.attrs = extract32(attrs, 0, 4);
109
}
137
} else {
110
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
138
@@ -XXX,XX +XXX,XX @@ do_fault:
111
}
139
fi->type = fault_type;
112
}
140
fi->level = level;
113
s->rx_descriptor = addr;
141
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
114
- imx_eth_enable_rx(s);
142
- fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_Stage2 ||
115
+ imx_eth_enable_rx(s, false);
143
- mmu_idx == ARMMMUIdx_Stage2_S);
116
imx_eth_update(s);
144
+ fi->stage2 = fi->s1ptw || regime_is_stage2(mmu_idx);
117
return len;
145
fi->s1ns = mmu_idx == ARMMMUIdx_Stage2;
146
return true;
118
}
147
}
119
--
148
--
120
2.7.4
149
2.25.1
121
150
122
151
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
As we now have a linux-user aarch64_be target, we can add it to the list
3
Hoist the computation of the mmu_idx for the ptw up to
4
of supported targets in qemu-binfmt-conf.sh
4
get_phys_addr_with_struct and get_phys_addr_twostage.
5
This removes the duplicate check for stage2 disabled
6
from the middle of the walk, performing it only once.
5
7
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20171220212308.12614-6-michael.weiser@gmx.de
10
Tested-by: Alex Bennée <alex.bennee@linaro.org>
11
Message-id: 20221024051851.3074715-3-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
scripts/qemu-binfmt-conf.sh | 6 +++++-
14
target/arm/ptw.c | 71 ++++++++++++++++++++++++++++++++++++------------
12
1 file changed, 5 insertions(+), 1 deletion(-)
15
1 file changed, 54 insertions(+), 17 deletions(-)
13
16
14
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100755
18
index XXXXXXX..XXXXXXX 100644
16
--- a/scripts/qemu-binfmt-conf.sh
19
--- a/target/arm/ptw.c
17
+++ b/scripts/qemu-binfmt-conf.sh
20
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
19
22
20
qemu_target_list="i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le m68k \
23
typedef struct S1Translate {
21
mips mipsel mipsn32 mipsn32el mips64 mips64el \
24
ARMMMUIdx in_mmu_idx;
22
-sh4 sh4eb s390x aarch64 hppa"
25
+ ARMMMUIdx in_ptw_idx;
23
+sh4 sh4eb s390x aarch64 aarch64_be hppa"
26
bool in_secure;
24
27
bool in_debug;
25
i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
28
bool out_secure;
26
i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
29
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
27
@@ -XXX,XX +XXX,XX @@ aarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x
30
{
28
aarch64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
31
bool is_secure = ptw->in_secure;
29
aarch64_family=arm
32
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
30
33
- ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
31
+aarch64_be_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7'
34
- bool s2_phys = false;
32
+aarch64_be_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
35
+ ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx;
33
+aarch64_be_family=arm
36
uint8_t pte_attrs;
37
bool pte_secure;
38
39
- if (!arm_mmu_idx_is_stage1_of_2(mmu_idx)
40
- || regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
41
- s2_mmu_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
42
- s2_phys = true;
43
- }
44
-
45
if (unlikely(ptw->in_debug)) {
46
/*
47
* From gdbstub, do not use softmmu so that we don't modify the
48
* state of the cpu at all, including softmmu tlb contents.
49
*/
50
- if (s2_phys) {
51
- ptw->out_phys = addr;
52
- pte_attrs = 0;
53
- pte_secure = is_secure;
54
- } else {
55
+ if (regime_is_stage2(s2_mmu_idx)) {
56
S1Translate s2ptw = {
57
.in_mmu_idx = s2_mmu_idx,
58
+ .in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS,
59
.in_secure = is_secure,
60
.in_debug = true,
61
};
62
GetPhysAddrResult s2 = { };
34
+
63
+
35
hppa_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f'
64
if (!get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD,
36
hppa_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
65
false, &s2, fi)) {
37
hppa_family=hppa
66
goto fail;
67
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
68
ptw->out_phys = s2.f.phys_addr;
69
pte_attrs = s2.cacheattrs.attrs;
70
pte_secure = s2.f.attrs.secure;
71
+ } else {
72
+ /* Regime is physical. */
73
+ ptw->out_phys = addr;
74
+ pte_attrs = 0;
75
+ pte_secure = is_secure;
76
}
77
ptw->out_host = NULL;
78
} else {
79
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
80
pte_secure = full->attrs.secure;
81
}
82
83
- if (!s2_phys) {
84
+ if (regime_is_stage2(s2_mmu_idx)) {
85
uint64_t hcr = arm_hcr_el2_eff_secstate(env, is_secure);
86
87
if ((hcr & HCR_PTW) && S2_attrs_are_device(hcr, pte_attrs)) {
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
89
descaddr |= (address >> (stride * (4 - level))) & indexmask;
90
descaddr &= ~7ULL;
91
nstable = extract32(tableattrs, 4, 1);
92
- ptw->in_secure = !nstable;
93
+ if (!nstable) {
94
+ /*
95
+ * Stage2_S -> Stage2 or Phys_S -> Phys_NS
96
+ * Assert that the non-secure idx are even, and relative order.
97
+ */
98
+ QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0);
99
+ QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0);
100
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S);
101
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S);
102
+ ptw->in_ptw_idx &= ~1;
103
+ ptw->in_secure = false;
104
+ }
105
descriptor = arm_ldq_ptw(env, ptw, descaddr, fi);
106
if (fi->type != ARMFault_None) {
107
goto do_fault;
108
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
109
110
is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
111
ptw->in_mmu_idx = s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
112
+ ptw->in_ptw_idx = s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
113
ptw->in_secure = s2walk_secure;
114
115
/*
116
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
117
ARMMMUFaultInfo *fi)
118
{
119
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
120
- ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
121
bool is_secure = ptw->in_secure;
122
+ ARMMMUIdx s1_mmu_idx;
123
124
- if (mmu_idx != s1_mmu_idx) {
125
+ switch (mmu_idx) {
126
+ case ARMMMUIdx_Phys_S:
127
+ case ARMMMUIdx_Phys_NS:
128
+ /* Checking Phys early avoids special casing later vs regime_el. */
129
+ return get_phys_addr_disabled(env, address, access_type, mmu_idx,
130
+ is_secure, result, fi);
131
+
132
+ case ARMMMUIdx_Stage1_E0:
133
+ case ARMMMUIdx_Stage1_E1:
134
+ case ARMMMUIdx_Stage1_E1_PAN:
135
+ /* First stage lookup uses second stage for ptw. */
136
+ ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
137
+ break;
138
+
139
+ case ARMMMUIdx_E10_0:
140
+ s1_mmu_idx = ARMMMUIdx_Stage1_E0;
141
+ goto do_twostage;
142
+ case ARMMMUIdx_E10_1:
143
+ s1_mmu_idx = ARMMMUIdx_Stage1_E1;
144
+ goto do_twostage;
145
+ case ARMMMUIdx_E10_1_PAN:
146
+ s1_mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
147
+ do_twostage:
148
/*
149
* Call ourselves recursively to do the stage 1 and then stage 2
150
* translations if mmu_idx is a two-stage regime, and EL2 present.
151
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
152
return get_phys_addr_twostage(env, ptw, address, access_type,
153
result, fi);
154
}
155
+ /* fall through */
156
+
157
+ default:
158
+ /* Single stage and second stage uses physical for ptw. */
159
+ ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
160
+ break;
161
}
162
163
/*
38
--
164
--
39
2.7.4
165
2.25.1
40
166
41
167
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The MMFR1 field may indicate support for hardware update of
4
access flag alone, or access flag and dirty bit.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221024051851.3074715-4-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 10 ++++++++++
12
1 file changed, 10 insertions(+)
13
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
19
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
20
}
21
22
+static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id)
23
+{
24
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0;
25
+}
26
+
27
+static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id)
28
+{
29
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2;
30
+}
31
+
32
static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
33
{
34
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
35
--
36
2.25.1
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Some i.MX SoCs (e.g. i.MX7) have FEC registers going as far as offset
4
0x614, so to avoid getting aborts when accessing those on QEMU, extend
5
the register file to cover FSL_IMX25_FEC_SIZE(16K) of address space
6
instead of just 1K.
7
8
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Cc: Jason Wang <jasowang@redhat.com>
10
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Cc: qemu-devel@nongnu.org
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20221024051851.3074715-5-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
8
---
18
include/hw/arm/fsl-imx25.h | 1 -
9
target/arm/internals.h | 2 ++
19
include/hw/net/imx_fec.h | 1 +
10
target/arm/helper.c | 8 +++++++-
20
hw/net/imx_fec.c | 2 +-
11
2 files changed, 9 insertions(+), 1 deletion(-)
21
3 files changed, 2 insertions(+), 2 deletions(-)
22
12
23
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
24
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/fsl-imx25.h
15
--- a/target/arm/internals.h
26
+++ b/include/hw/arm/fsl-imx25.h
16
+++ b/target/arm/internals.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
17
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
28
#define FSL_IMX25_UART5_ADDR 0x5002C000
18
bool hpd : 1;
29
#define FSL_IMX25_UART5_SIZE 0x4000
19
bool tsz_oob : 1; /* tsz has been clamped to legal range */
30
#define FSL_IMX25_FEC_ADDR 0x50038000
20
bool ds : 1;
31
-#define FSL_IMX25_FEC_SIZE 0x4000
21
+ bool ha : 1;
32
#define FSL_IMX25_CCM_ADDR 0x53F80000
22
+ bool hd : 1;
33
#define FSL_IMX25_CCM_SIZE 0x4000
23
ARMGranuleSize gran : 2;
34
#define FSL_IMX25_GPT4_ADDR 0x53F84000
24
} ARMVAParameters;
35
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
25
26
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
37
--- a/include/hw/net/imx_fec.h
28
--- a/target/arm/helper.c
38
+++ b/include/hw/net/imx_fec.h
29
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ typedef struct {
30
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
40
31
ARMMMUIdx mmu_idx, bool data)
41
#define ENET_TX_RING_NUM 3
32
{
42
33
uint64_t tcr = regime_tcr(env, mmu_idx);
43
+#define FSL_IMX25_FEC_SIZE 0x4000
34
- bool epd, hpd, tsz_oob, ds;
44
35
+ bool epd, hpd, tsz_oob, ds, ha, hd;
45
typedef struct IMXFECState {
36
int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
46
/*< private >*/
37
ARMGranuleSize gran;
47
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
38
ARMCPU *cpu = env_archcpu(env);
48
index XXXXXXX..XXXXXXX 100644
39
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
49
--- a/hw/net/imx_fec.c
40
epd = false;
50
+++ b/hw/net/imx_fec.c
41
sh = extract32(tcr, 12, 2);
51
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
42
ps = extract32(tcr, 16, 3);
52
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
43
+ ha = extract32(tcr, 21, 1) && cpu_isar_feature(aa64_hafs, cpu);
53
44
+ hd = extract32(tcr, 22, 1) && cpu_isar_feature(aa64_hdbs, cpu);
54
memory_region_init_io(&s->iomem, OBJECT(dev), &imx_eth_ops, s,
45
ds = extract64(tcr, 32, 1);
55
- TYPE_IMX_FEC, 0x400);
46
} else {
56
+ TYPE_IMX_FEC, FSL_IMX25_FEC_SIZE);
47
bool e0pd;
57
sysbus_init_mmio(sbd, &s->iomem);
48
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
58
sysbus_init_irq(sbd, &s->irq[0]);
49
e0pd = extract64(tcr, 56, 1);
59
sysbus_init_irq(sbd, &s->irq[1]);
50
}
51
ps = extract64(tcr, 32, 3);
52
+ ha = extract64(tcr, 39, 1) && cpu_isar_feature(aa64_hafs, cpu);
53
+ hd = extract64(tcr, 40, 1) && cpu_isar_feature(aa64_hdbs, cpu);
54
ds = extract64(tcr, 59, 1);
55
56
if (e0pd && cpu_isar_feature(aa64_e0pd, cpu) &&
57
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
58
.hpd = hpd,
59
.tsz_oob = tsz_oob,
60
.ds = ds,
61
+ .ha = ha,
62
+ .hd = ha && hd,
63
.gran = gran,
64
};
65
}
60
--
66
--
61
2.7.4
67
2.25.1
62
68
63
69
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Separate S1 translation from the actual lookup.
4
Will enable lpae hardware updates.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221024051851.3074715-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/ptw.c | 41 ++++++++++++++++++++++-------------------
12
1 file changed, 22 insertions(+), 19 deletions(-)
13
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/ptw.c
17
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
19
}
20
21
/* All loads done in the course of a page table walk go through here. */
22
-static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
23
+static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw,
24
ARMMMUFaultInfo *fi)
25
{
26
CPUState *cs = env_cpu(env);
27
uint32_t data;
28
29
- if (!S1_ptw_translate(env, ptw, addr, fi)) {
30
- /* Failure. */
31
- assert(fi->s1ptw);
32
- return 0;
33
- }
34
-
35
if (likely(ptw->out_host)) {
36
/* Page tables are in RAM, and we have the host address. */
37
if (ptw->out_be) {
38
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
39
return data;
40
}
41
42
-static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
43
+static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
44
ARMMMUFaultInfo *fi)
45
{
46
CPUState *cs = env_cpu(env);
47
uint64_t data;
48
49
- if (!S1_ptw_translate(env, ptw, addr, fi)) {
50
- /* Failure. */
51
- assert(fi->s1ptw);
52
- return 0;
53
- }
54
-
55
if (likely(ptw->out_host)) {
56
/* Page tables are in RAM, and we have the host address. */
57
if (ptw->out_be) {
58
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, S1Translate *ptw,
59
fi->type = ARMFault_Translation;
60
goto do_fault;
61
}
62
- desc = arm_ldl_ptw(env, ptw, table, fi);
63
+ if (!S1_ptw_translate(env, ptw, table, fi)) {
64
+ goto do_fault;
65
+ }
66
+ desc = arm_ldl_ptw(env, ptw, fi);
67
if (fi->type != ARMFault_None) {
68
goto do_fault;
69
}
70
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, S1Translate *ptw,
71
/* Fine pagetable. */
72
table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
73
}
74
- desc = arm_ldl_ptw(env, ptw, table, fi);
75
+ if (!S1_ptw_translate(env, ptw, table, fi)) {
76
+ goto do_fault;
77
+ }
78
+ desc = arm_ldl_ptw(env, ptw, fi);
79
if (fi->type != ARMFault_None) {
80
goto do_fault;
81
}
82
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
83
fi->type = ARMFault_Translation;
84
goto do_fault;
85
}
86
- desc = arm_ldl_ptw(env, ptw, table, fi);
87
+ if (!S1_ptw_translate(env, ptw, table, fi)) {
88
+ goto do_fault;
89
+ }
90
+ desc = arm_ldl_ptw(env, ptw, fi);
91
if (fi->type != ARMFault_None) {
92
goto do_fault;
93
}
94
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
95
ns = extract32(desc, 3, 1);
96
/* Lookup l2 entry. */
97
table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
98
- desc = arm_ldl_ptw(env, ptw, table, fi);
99
+ if (!S1_ptw_translate(env, ptw, table, fi)) {
100
+ goto do_fault;
101
+ }
102
+ desc = arm_ldl_ptw(env, ptw, fi);
103
if (fi->type != ARMFault_None) {
104
goto do_fault;
105
}
106
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
107
ptw->in_ptw_idx &= ~1;
108
ptw->in_secure = false;
109
}
110
- descriptor = arm_ldq_ptw(env, ptw, descaddr, fi);
111
+ if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
112
+ goto do_fault;
113
+ }
114
+ descriptor = arm_ldq_ptw(env, ptw, fi);
115
if (fi->type != ARMFault_None) {
116
goto do_fault;
117
}
118
--
119
2.25.1
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Make big-endian aarch64 systems identify as aarch64_be as expected by
3
This fault type is to be used with FEAT_HAFDBS when
4
big-endian userland and toolchains.
4
the guest enables hw updates, but places the tables
5
in memory where atomic updates are unsupported.
5
6
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20171220212308.12614-3-michael.weiser@gmx.de
10
Message-id: 20221024051851.3074715-7-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
linux-user/aarch64/target_syscall.h | 4 ++++
13
target/arm/internals.h | 4 ++++
13
1 file changed, 4 insertions(+)
14
1 file changed, 4 insertions(+)
14
15
15
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/aarch64/target_syscall.h
18
--- a/target/arm/internals.h
18
+++ b/linux-user/aarch64/target_syscall.h
19
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
20
@@ -XXX,XX +XXX,XX @@ typedef enum ARMFaultType {
20
uint64_t pstate;
21
ARMFault_AsyncExternal,
21
};
22
ARMFault_Debug,
22
23
ARMFault_TLBConflict,
23
+#if defined(TARGET_WORDS_BIGENDIAN)
24
+ ARMFault_UnsuppAtomicUpdate,
24
+#define UNAME_MACHINE "aarch64_be"
25
ARMFault_Lockdown,
25
+#else
26
ARMFault_Exclusive,
26
#define UNAME_MACHINE "aarch64"
27
ARMFault_ICacheMaint,
27
+#endif
28
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
28
#define UNAME_MINIMUM_RELEASE "3.8.0"
29
case ARMFault_TLBConflict:
29
#define TARGET_CLONE_BACKWARDS
30
fsc = 0x30;
30
#define TARGET_MINSIGSTKSZ 2048
31
break;
32
+ case ARMFault_UnsuppAtomicUpdate:
33
+ fsc = 0x31;
34
+ break;
35
case ARMFault_Lockdown:
36
fsc = 0x34;
37
break;
31
--
38
--
32
2.7.4
39
2.25.1
33
40
34
41
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
The unconditional loop was used both to iterate over levels
4
and to control parsing of attributes. Use an explicit goto
5
in both cases.
6
7
While this appears less clean for iterating over levels, we
8
will need to jump back into the middle of this loop for
9
atomic updates, which is even uglier.
10
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20221024051851.3074715-8-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/ptw.c | 192 +++++++++++++++++++++++------------------------
17
1 file changed, 96 insertions(+), 96 deletions(-)
18
19
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/ptw.c
22
+++ b/target/arm/ptw.c
23
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
24
uint64_t descaddrmask;
25
bool aarch64 = arm_el_is_aa64(env, el);
26
bool guarded = false;
27
+ uint64_t descriptor;
28
+ bool nstable;
29
30
/* TODO: This code does not support shareability levels. */
31
if (aarch64) {
32
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
33
* bits at each step.
34
*/
35
tableattrs = is_secure ? 0 : (1 << 4);
36
- for (;;) {
37
- uint64_t descriptor;
38
- bool nstable;
39
-
40
- descaddr |= (address >> (stride * (4 - level))) & indexmask;
41
- descaddr &= ~7ULL;
42
- nstable = extract32(tableattrs, 4, 1);
43
- if (!nstable) {
44
- /*
45
- * Stage2_S -> Stage2 or Phys_S -> Phys_NS
46
- * Assert that the non-secure idx are even, and relative order.
47
- */
48
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0);
49
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0);
50
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S);
51
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S);
52
- ptw->in_ptw_idx &= ~1;
53
- ptw->in_secure = false;
54
- }
55
- if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
56
- goto do_fault;
57
- }
58
- descriptor = arm_ldq_ptw(env, ptw, fi);
59
- if (fi->type != ARMFault_None) {
60
- goto do_fault;
61
- }
62
-
63
- if (!(descriptor & 1) ||
64
- (!(descriptor & 2) && (level == 3))) {
65
- /* Invalid, or the Reserved level 3 encoding */
66
- goto do_fault;
67
- }
68
-
69
- descaddr = descriptor & descaddrmask;
70
71
+ next_level:
72
+ descaddr |= (address >> (stride * (4 - level))) & indexmask;
73
+ descaddr &= ~7ULL;
74
+ nstable = extract32(tableattrs, 4, 1);
75
+ if (!nstable) {
76
/*
77
- * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
78
- * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of
79
- * descaddr are in [9:8]. Otherwise, if descaddr is out of range,
80
- * raise AddressSizeFault.
81
+ * Stage2_S -> Stage2 or Phys_S -> Phys_NS
82
+ * Assert that the non-secure idx are even, and relative order.
83
*/
84
- if (outputsize > 48) {
85
- if (param.ds) {
86
- descaddr |= extract64(descriptor, 8, 2) << 50;
87
- } else {
88
- descaddr |= extract64(descriptor, 12, 4) << 48;
89
- }
90
- } else if (descaddr >> outputsize) {
91
- fault_type = ARMFault_AddressSize;
92
- goto do_fault;
93
- }
94
-
95
- if ((descriptor & 2) && (level < 3)) {
96
- /*
97
- * Table entry. The top five bits are attributes which may
98
- * propagate down through lower levels of the table (and
99
- * which are all arranged so that 0 means "no effect", so
100
- * we can gather them up by ORing in the bits at each level).
101
- */
102
- tableattrs |= extract64(descriptor, 59, 5);
103
- level++;
104
- indexmask = indexmask_grainsize;
105
- continue;
106
- }
107
- /*
108
- * Block entry at level 1 or 2, or page entry at level 3.
109
- * These are basically the same thing, although the number
110
- * of bits we pull in from the vaddr varies. Note that although
111
- * descaddrmask masks enough of the low bits of the descriptor
112
- * to give a correct page or table address, the address field
113
- * in a block descriptor is smaller; so we need to explicitly
114
- * clear the lower bits here before ORing in the low vaddr bits.
115
- */
116
- page_size = (1ULL << ((stride * (4 - level)) + 3));
117
- descaddr &= ~(hwaddr)(page_size - 1);
118
- descaddr |= (address & (page_size - 1));
119
- /* Extract attributes from the descriptor */
120
- attrs = extract64(descriptor, 2, 10)
121
- | (extract64(descriptor, 52, 12) << 10);
122
-
123
- if (regime_is_stage2(mmu_idx)) {
124
- /* Stage 2 table descriptors do not include any attribute fields */
125
- break;
126
- }
127
- /* Merge in attributes from table descriptors */
128
- attrs |= nstable << 3; /* NS */
129
- guarded = extract64(descriptor, 50, 1); /* GP */
130
- if (param.hpd) {
131
- /* HPD disables all the table attributes except NSTable. */
132
- break;
133
- }
134
- attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
135
- /*
136
- * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
137
- * means "force PL1 access only", which means forcing AP[1] to 0.
138
- */
139
- attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */
140
- attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */
141
- break;
142
+ QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0);
143
+ QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0);
144
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S);
145
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S);
146
+ ptw->in_ptw_idx &= ~1;
147
+ ptw->in_secure = false;
148
}
149
+ if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
150
+ goto do_fault;
151
+ }
152
+ descriptor = arm_ldq_ptw(env, ptw, fi);
153
+ if (fi->type != ARMFault_None) {
154
+ goto do_fault;
155
+ }
156
+
157
+ if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) {
158
+ /* Invalid, or the Reserved level 3 encoding */
159
+ goto do_fault;
160
+ }
161
+
162
+ descaddr = descriptor & descaddrmask;
163
+
164
+ /*
165
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
166
+ * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of
167
+ * descaddr are in [9:8]. Otherwise, if descaddr is out of range,
168
+ * raise AddressSizeFault.
169
+ */
170
+ if (outputsize > 48) {
171
+ if (param.ds) {
172
+ descaddr |= extract64(descriptor, 8, 2) << 50;
173
+ } else {
174
+ descaddr |= extract64(descriptor, 12, 4) << 48;
175
+ }
176
+ } else if (descaddr >> outputsize) {
177
+ fault_type = ARMFault_AddressSize;
178
+ goto do_fault;
179
+ }
180
+
181
+ if ((descriptor & 2) && (level < 3)) {
182
+ /*
183
+ * Table entry. The top five bits are attributes which may
184
+ * propagate down through lower levels of the table (and
185
+ * which are all arranged so that 0 means "no effect", so
186
+ * we can gather them up by ORing in the bits at each level).
187
+ */
188
+ tableattrs |= extract64(descriptor, 59, 5);
189
+ level++;
190
+ indexmask = indexmask_grainsize;
191
+ goto next_level;
192
+ }
193
+
194
+ /*
195
+ * Block entry at level 1 or 2, or page entry at level 3.
196
+ * These are basically the same thing, although the number
197
+ * of bits we pull in from the vaddr varies. Note that although
198
+ * descaddrmask masks enough of the low bits of the descriptor
199
+ * to give a correct page or table address, the address field
200
+ * in a block descriptor is smaller; so we need to explicitly
201
+ * clear the lower bits here before ORing in the low vaddr bits.
202
+ */
203
+ page_size = (1ULL << ((stride * (4 - level)) + 3));
204
+ descaddr &= ~(hwaddr)(page_size - 1);
205
+ descaddr |= (address & (page_size - 1));
206
+ /* Extract attributes from the descriptor */
207
+ attrs = extract64(descriptor, 2, 10)
208
+ | (extract64(descriptor, 52, 12) << 10);
209
+
210
+ if (regime_is_stage2(mmu_idx)) {
211
+ /* Stage 2 table descriptors do not include any attribute fields */
212
+ goto skip_attrs;
213
+ }
214
+ /* Merge in attributes from table descriptors */
215
+ attrs |= nstable << 3; /* NS */
216
+ guarded = extract64(descriptor, 50, 1); /* GP */
217
+ if (param.hpd) {
218
+ /* HPD disables all the table attributes except NSTable. */
219
+ goto skip_attrs;
220
+ }
221
+ attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
222
+ /*
223
+ * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
224
+ * means "force PL1 access only", which means forcing AP[1] to 0.
225
+ */
226
+ attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */
227
+ attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */
228
+ skip_attrs:
229
+
230
/*
231
* Here descaddr is the final physical address, and attributes
232
* are all in attrs.
233
--
234
2.25.1
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
More recent version of the IP block support more than one Tx DMA ring,
3
Always overriding fi->type was incorrect, as we would not properly
4
so add the code implementing that feature.
4
propagate the fault type from S1_ptw_translate, or arm_ldq_ptw.
5
Simplify things by providing a new label for a translation fault.
6
For other faults, store into fi directly.
5
7
6
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Cc: Jason Wang <jasowang@redhat.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: yurovsky@gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Message-id: 20221024051851.3074715-9-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
include/hw/net/imx_fec.h | 18 ++++++-
14
target/arm/ptw.c | 31 +++++++++++++------------------
17
hw/net/imx_fec.c | 133 ++++++++++++++++++++++++++++++++++++++++-------
15
1 file changed, 13 insertions(+), 18 deletions(-)
18
2 files changed, 130 insertions(+), 21 deletions(-)
19
16
20
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/net/imx_fec.h
19
--- a/target/arm/ptw.c
23
+++ b/include/hw/net/imx_fec.h
20
+++ b/target/arm/ptw.c
24
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
25
#define ENET_TFWR 81
22
ARMCPU *cpu = env_archcpu(env);
26
#define ENET_FRBR 83
23
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
27
#define ENET_FRSR 84
24
bool is_secure = ptw->in_secure;
28
+#define ENET_TDSR1 89
25
- /* Read an LPAE long-descriptor translation table. */
29
+#define ENET_TDSR2 92
26
- ARMFaultType fault_type = ARMFault_Translation;
30
#define ENET_RDSR 96
27
uint32_t level;
31
#define ENET_TDSR 97
28
ARMVAParameters param;
32
#define ENET_MRBR 98
29
uint64_t ttbr;
33
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
34
#define ENET_FTRL 108
31
* so our choice is to always raise the fault.
35
#define ENET_TACC 112
32
*/
36
#define ENET_RACC 113
33
if (param.tsz_oob) {
37
+#define ENET_TDAR1 121
34
- fault_type = ARMFault_Translation;
38
+#define ENET_TDAR2 123
35
- goto do_fault;
39
#define ENET_MIIGSK_CFGR 192
36
+ goto do_translation_fault;
40
#define ENET_MIIGSK_ENR 194
37
}
41
#define ENET_ATCR 256
38
42
@@ -XXX,XX +XXX,XX @@
39
addrsize = 64 - 8 * param.tbi;
43
#define ENET_INT_WAKEUP (1 << 17)
40
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
44
#define ENET_INT_TS_AVAIL (1 << 16)
41
addrsize - inputsize);
45
#define ENET_INT_TS_TIMER (1 << 15)
42
if (-top_bits != param.select) {
46
+#define ENET_INT_TXF2 (1 << 7)
43
/* The gap between the two regions is a Translation fault */
47
+#define ENET_INT_TXB2 (1 << 6)
44
- fault_type = ARMFault_Translation;
48
+#define ENET_INT_TXF1 (1 << 3)
45
- goto do_fault;
49
+#define ENET_INT_TXB1 (1 << 2)
46
+ goto do_translation_fault;
50
51
#define ENET_INT_MAC (ENET_INT_HB | ENET_INT_BABR | ENET_INT_BABT | \
52
ENET_INT_GRA | ENET_INT_TXF | ENET_INT_TXB | \
53
ENET_INT_RXF | ENET_INT_RXB | ENET_INT_MII | \
54
ENET_INT_EBERR | ENET_INT_LC | ENET_INT_RL | \
55
ENET_INT_UN | ENET_INT_PLR | ENET_INT_WAKEUP | \
56
- ENET_INT_TS_AVAIL)
57
+ ENET_INT_TS_AVAIL | ENET_INT_TXF1 | \
58
+ ENET_INT_TXB1 | ENET_INT_TXF2 | ENET_INT_TXB2)
59
60
/* RDAR */
61
#define ENET_RDAR_RDAR (1 << 24)
62
@@ -XXX,XX +XXX,XX @@ typedef struct {
63
64
#define ENET_BD_BDU (1 << 31)
65
66
+#define ENET_TX_RING_NUM 3
67
+
68
+
69
typedef struct IMXFECState {
70
/*< private >*/
71
SysBusDevice parent_obj;
72
@@ -XXX,XX +XXX,XX @@ typedef struct IMXFECState {
73
74
uint32_t regs[ENET_MAX];
75
uint32_t rx_descriptor;
76
- uint32_t tx_descriptor;
77
+
78
+ uint32_t tx_descriptor[ENET_TX_RING_NUM];
79
+ uint32_t tx_ring_num;
80
81
uint32_t phy_status;
82
uint32_t phy_control;
83
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/net/imx_fec.c
86
+++ b/hw/net/imx_fec.c
87
@@ -XXX,XX +XXX,XX @@ static const char *imx_eth_reg_name(IMXFECState *s, uint32_t index)
88
}
89
}
90
91
+/*
92
+ * Versions of this device with more than one TX descriptor save the
93
+ * 2nd and 3rd descriptors in a subsection, to maintain migration
94
+ * compatibility with previous versions of the device that only
95
+ * supported a single descriptor.
96
+ */
97
+static bool imx_eth_is_multi_tx_ring(void *opaque)
98
+{
99
+ IMXFECState *s = IMX_FEC(opaque);
100
+
101
+ return s->tx_ring_num > 1;
102
+}
103
+
104
+static const VMStateDescription vmstate_imx_eth_txdescs = {
105
+ .name = "imx.fec/txdescs",
106
+ .version_id = 1,
107
+ .minimum_version_id = 1,
108
+ .needed = imx_eth_is_multi_tx_ring,
109
+ .fields = (VMStateField[]) {
110
+ VMSTATE_UINT32(tx_descriptor[1], IMXFECState),
111
+ VMSTATE_UINT32(tx_descriptor[2], IMXFECState),
112
+ VMSTATE_END_OF_LIST()
113
+ }
114
+};
115
+
116
static const VMStateDescription vmstate_imx_eth = {
117
.name = TYPE_IMX_FEC,
118
.version_id = 2,
119
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth = {
120
.fields = (VMStateField[]) {
121
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
122
VMSTATE_UINT32(rx_descriptor, IMXFECState),
123
- VMSTATE_UINT32(tx_descriptor, IMXFECState),
124
-
125
+ VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
126
VMSTATE_UINT32(phy_status, IMXFECState),
127
VMSTATE_UINT32(phy_control, IMXFECState),
128
VMSTATE_UINT32(phy_advertise, IMXFECState),
129
VMSTATE_UINT32(phy_int, IMXFECState),
130
VMSTATE_UINT32(phy_int_mask, IMXFECState),
131
VMSTATE_END_OF_LIST()
132
- }
133
+ },
134
+ .subsections = (const VMStateDescription * []) {
135
+ &vmstate_imx_eth_txdescs,
136
+ NULL
137
+ },
138
};
139
140
#define PHY_INT_ENERGYON (1 << 7)
141
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
142
{
143
int frame_size = 0, descnt = 0;
144
uint8_t *ptr = s->frame;
145
- uint32_t addr = s->tx_descriptor;
146
+ uint32_t addr = s->tx_descriptor[0];
147
148
while (descnt++ < IMX_MAX_DESC) {
149
IMXFECBufDesc bd;
150
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
151
}
47
}
152
}
48
}
153
49
154
- s->tx_descriptor = addr;
50
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
155
+ s->tx_descriptor[0] = addr;
51
* Translation table walk disabled => Translation fault on TLB miss
156
52
* Note: This is always 0 on 64-bit EL2 and EL3.
157
imx_eth_update(s);
53
*/
158
}
54
- goto do_fault;
159
55
+ goto do_translation_fault;
160
-static void imx_enet_do_tx(IMXFECState *s)
56
}
161
+static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
57
162
{
58
if (!regime_is_stage2(mmu_idx)) {
163
int frame_size = 0, descnt = 0;
59
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
164
+
60
if (param.ds && stride == 9 && sl2) {
165
uint8_t *ptr = s->frame;
61
if (sl0 != 0) {
166
- uint32_t addr = s->tx_descriptor;
62
level = 0;
167
+ uint32_t addr, int_txb, int_txf, tdsr;
63
- fault_type = ARMFault_Translation;
168
+ size_t ring;
64
- goto do_fault;
169
+
65
+ goto do_translation_fault;
170
+ switch (index) {
171
+ case ENET_TDAR:
172
+ ring = 0;
173
+ int_txb = ENET_INT_TXB;
174
+ int_txf = ENET_INT_TXF;
175
+ tdsr = ENET_TDSR;
176
+ break;
177
+ case ENET_TDAR1:
178
+ ring = 1;
179
+ int_txb = ENET_INT_TXB1;
180
+ int_txf = ENET_INT_TXF1;
181
+ tdsr = ENET_TDSR1;
182
+ break;
183
+ case ENET_TDAR2:
184
+ ring = 2;
185
+ int_txb = ENET_INT_TXB2;
186
+ int_txf = ENET_INT_TXF2;
187
+ tdsr = ENET_TDSR2;
188
+ break;
189
+ default:
190
+ qemu_log_mask(LOG_GUEST_ERROR,
191
+ "%s: bogus value for index %x\n",
192
+ __func__, index);
193
+ abort();
194
+ break;
195
+ }
196
+
197
+ addr = s->tx_descriptor[ring];
198
199
while (descnt++ < IMX_MAX_DESC) {
200
IMXENETBufDesc bd;
201
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s)
202
203
frame_size = 0;
204
if (bd.option & ENET_BD_TX_INT) {
205
- s->regs[ENET_EIR] |= ENET_INT_TXF;
206
+ s->regs[ENET_EIR] |= int_txf;
207
}
66
}
67
startlevel = -1;
68
} else if (!aarch64 || stride == 9) {
69
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
70
ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
71
inputsize, stride, outputsize);
72
if (!ok) {
73
- fault_type = ARMFault_Translation;
74
- goto do_fault;
75
+ goto do_translation_fault;
208
}
76
}
209
if (bd.option & ENET_BD_TX_INT) {
77
level = startlevel;
210
- s->regs[ENET_EIR] |= ENET_INT_TXB;
78
}
211
+ s->regs[ENET_EIR] |= int_txb;
79
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
80
descaddr |= extract64(ttbr, 2, 4) << 48;
81
} else if (descaddr >> outputsize) {
82
level = 0;
83
- fault_type = ARMFault_AddressSize;
84
+ fi->type = ARMFault_AddressSize;
85
goto do_fault;
86
}
87
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
89
90
if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) {
91
/* Invalid, or the Reserved level 3 encoding */
92
- goto do_fault;
93
+ goto do_translation_fault;
94
}
95
96
descaddr = descriptor & descaddrmask;
97
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
98
descaddr |= extract64(descriptor, 12, 4) << 48;
212
}
99
}
213
bd.flags &= ~ENET_BD_R;
100
} else if (descaddr >> outputsize) {
214
/* Write back the modified descriptor. */
101
- fault_type = ARMFault_AddressSize;
215
imx_enet_write_bd(&bd, addr);
102
+ fi->type = ARMFault_AddressSize;
216
/* Advance to the next descriptor. */
103
goto do_fault;
217
if ((bd.flags & ENET_BD_W) != 0) {
218
- addr = s->regs[ENET_TDSR];
219
+ addr = s->regs[tdsr];
220
} else {
221
addr += sizeof(bd);
222
}
223
}
104
}
224
105
225
- s->tx_descriptor = addr;
106
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
226
+ s->tx_descriptor[ring] = addr;
107
* Here descaddr is the final physical address, and attributes
227
108
* are all in attrs.
228
imx_eth_update(s);
109
*/
229
}
110
- fault_type = ARMFault_AccessFlag;
230
111
if ((attrs & (1 << 8)) == 0) {
231
-static void imx_eth_do_tx(IMXFECState *s)
112
/* Access flag */
232
+static void imx_eth_do_tx(IMXFECState *s, uint32_t index)
113
+ fi->type = ARMFault_AccessFlag;
233
{
114
goto do_fault;
234
if (!s->is_fec && (s->regs[ENET_ECR] & ENET_ECR_EN1588)) {
235
- imx_enet_do_tx(s);
236
+ imx_enet_do_tx(s, index);
237
} else {
238
imx_fec_do_tx(s);
239
}
115
}
240
@@ -XXX,XX +XXX,XX @@ static void imx_eth_reset(DeviceState *d)
116
117
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
118
result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
241
}
119
}
242
120
243
s->rx_descriptor = 0;
121
- fault_type = ARMFault_Permission;
244
- s->tx_descriptor = 0;
122
if (!(result->f.prot & (1 << access_type))) {
245
+ memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
123
+ fi->type = ARMFault_Permission;
246
124
goto do_fault;
247
/* We also reset the PHY */
125
}
248
phy_reset(s);
126
249
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
127
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
250
unsigned size)
128
result->f.lg_page_size = ctz64(page_size);
251
{
129
return false;
252
IMXFECState *s = IMX_FEC(opaque);
130
253
+ const bool single_tx_ring = !imx_eth_is_multi_tx_ring(s);
131
-do_fault:
254
uint32_t index = offset >> 2;
132
- fi->type = fault_type;
255
133
+ do_translation_fault:
256
FEC_PRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_eth_reg_name(s, index),
134
+ fi->type = ARMFault_Translation;
257
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
135
+ do_fault:
258
s->regs[index] = 0;
136
fi->level = level;
259
}
137
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
260
break;
138
fi->stage2 = fi->s1ptw || regime_is_stage2(mmu_idx);
261
- case ENET_TDAR:
262
+ case ENET_TDAR1: /* FALLTHROUGH */
263
+ case ENET_TDAR2: /* FALLTHROUGH */
264
+ if (unlikely(single_tx_ring)) {
265
+ qemu_log_mask(LOG_GUEST_ERROR,
266
+ "[%s]%s: trying to access TDAR2 or TDAR1\n",
267
+ TYPE_IMX_FEC, __func__);
268
+ return;
269
+ }
270
+ case ENET_TDAR: /* FALLTHROUGH */
271
if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
272
s->regs[index] = ENET_TDAR_TDAR;
273
- imx_eth_do_tx(s);
274
+ imx_eth_do_tx(s, index);
275
}
276
s->regs[index] = 0;
277
break;
278
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
279
if ((s->regs[index] & ENET_ECR_ETHEREN) == 0) {
280
s->regs[ENET_RDAR] = 0;
281
s->rx_descriptor = s->regs[ENET_RDSR];
282
- s->regs[ENET_TDAR] = 0;
283
- s->tx_descriptor = s->regs[ENET_TDSR];
284
+ s->regs[ENET_TDAR] = 0;
285
+ s->regs[ENET_TDAR1] = 0;
286
+ s->regs[ENET_TDAR2] = 0;
287
+ s->tx_descriptor[0] = s->regs[ENET_TDSR];
288
+ s->tx_descriptor[1] = s->regs[ENET_TDSR1];
289
+ s->tx_descriptor[2] = s->regs[ENET_TDSR2];
290
}
291
break;
292
case ENET_MMFR:
293
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
294
} else {
295
s->regs[index] = value & ~7;
296
}
297
- s->tx_descriptor = s->regs[index];
298
+ s->tx_descriptor[0] = s->regs[index];
299
+ break;
300
+ case ENET_TDSR1:
301
+ if (unlikely(single_tx_ring)) {
302
+ qemu_log_mask(LOG_GUEST_ERROR,
303
+ "[%s]%s: trying to access TDSR1\n",
304
+ TYPE_IMX_FEC, __func__);
305
+ return;
306
+ }
307
+
308
+ s->regs[index] = value & ~7;
309
+ s->tx_descriptor[1] = s->regs[index];
310
+ break;
311
+ case ENET_TDSR2:
312
+ if (unlikely(single_tx_ring)) {
313
+ qemu_log_mask(LOG_GUEST_ERROR,
314
+ "[%s]%s: trying to access TDSR2\n",
315
+ TYPE_IMX_FEC, __func__);
316
+ return;
317
+ }
318
+
319
+ s->regs[index] = value & ~7;
320
+ s->tx_descriptor[2] = s->regs[index];
321
break;
322
case ENET_MRBR:
323
s->regs[index] = value & 0x00003ff0;
324
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
325
326
static Property imx_eth_properties[] = {
327
DEFINE_NIC_PROPERTIES(IMXFECState, conf),
328
+ DEFINE_PROP_UINT32("tx-ring-num", IMXFECState, tx_ring_num, 1),
329
DEFINE_PROP_END_OF_LIST(),
330
};
331
332
--
139
--
333
2.7.4
140
2.25.1
334
141
335
142
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use 'frame_size' instead of 'len' when calling qemu_send_packet(),
3
Leave the upper and lower attributes in the place they originate
4
failing to do so results in malformed packets send in case when that
4
from in the descriptor. Shifting them around is confusing, since
5
packed is fragmented into multiple DMA transactions.
5
one cannot read the bit numbers out of the manual. Also, new
6
attributes have been added which would alter the shifts.
6
7
7
Cc: Peter Maydell <peter.maydell@linaro.org>
8
Cc: Jason Wang <jasowang@redhat.com>
9
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20221024051851.3074715-10-richard.henderson@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/net/imx_fec.c | 2 +-
14
target/arm/ptw.c | 31 +++++++++++++++----------------
18
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 15 insertions(+), 16 deletions(-)
19
16
20
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/net/imx_fec.c
19
--- a/target/arm/ptw.c
23
+++ b/hw/net/imx_fec.c
20
+++ b/target/arm/ptw.c
24
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
21
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
25
}
22
hwaddr descaddr, indexmask, indexmask_grainsize;
26
/* Last buffer in frame. */
23
uint32_t tableattrs;
27
24
target_ulong page_size;
28
- qemu_send_packet(qemu_get_queue(s->nic), s->frame, len);
25
- uint32_t attrs;
29
+ qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
26
+ uint64_t attrs;
30
ptr = s->frame;
27
int32_t stride;
31
28
int addrsize, inputsize, outputsize;
32
frame_size = 0;
29
uint64_t tcr = regime_tcr(env, mmu_idx);
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
31
descaddr &= ~(hwaddr)(page_size - 1);
32
descaddr |= (address & (page_size - 1));
33
/* Extract attributes from the descriptor */
34
- attrs = extract64(descriptor, 2, 10)
35
- | (extract64(descriptor, 52, 12) << 10);
36
+ attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(52, 12));
37
38
if (regime_is_stage2(mmu_idx)) {
39
/* Stage 2 table descriptors do not include any attribute fields */
40
goto skip_attrs;
41
}
42
/* Merge in attributes from table descriptors */
43
- attrs |= nstable << 3; /* NS */
44
+ attrs |= nstable << 5; /* NS */
45
guarded = extract64(descriptor, 50, 1); /* GP */
46
if (param.hpd) {
47
/* HPD disables all the table attributes except NSTable. */
48
goto skip_attrs;
49
}
50
- attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
51
+ attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
52
/*
53
* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
54
* means "force PL1 access only", which means forcing AP[1] to 0.
55
*/
56
- attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */
57
- attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */
58
+ attrs &= ~(extract64(tableattrs, 2, 1) << 6); /* !APT[0] => AP[1] */
59
+ attrs |= extract32(tableattrs, 3, 1) << 7; /* APT[1] => AP[2] */
60
skip_attrs:
61
62
/*
63
* Here descaddr is the final physical address, and attributes
64
* are all in attrs.
65
*/
66
- if ((attrs & (1 << 8)) == 0) {
67
+ if ((attrs & (1 << 10)) == 0) {
68
/* Access flag */
69
fi->type = ARMFault_AccessFlag;
70
goto do_fault;
71
}
72
73
- ap = extract32(attrs, 4, 2);
74
+ ap = extract32(attrs, 6, 2);
75
76
if (regime_is_stage2(mmu_idx)) {
77
ns = mmu_idx == ARMMMUIdx_Stage2;
78
- xn = extract32(attrs, 11, 2);
79
+ xn = extract64(attrs, 53, 2);
80
result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
81
} else {
82
- ns = extract32(attrs, 3, 1);
83
- xn = extract32(attrs, 12, 1);
84
- pxn = extract32(attrs, 11, 1);
85
+ ns = extract32(attrs, 5, 1);
86
+ xn = extract64(attrs, 54, 1);
87
+ pxn = extract64(attrs, 53, 1);
88
result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
92
93
if (regime_is_stage2(mmu_idx)) {
94
result->cacheattrs.is_s2_format = true;
95
- result->cacheattrs.attrs = extract32(attrs, 0, 4);
96
+ result->cacheattrs.attrs = extract32(attrs, 2, 4);
97
} else {
98
/* Index into MAIR registers for cache attributes */
99
- uint8_t attrindx = extract32(attrs, 0, 3);
100
+ uint8_t attrindx = extract32(attrs, 2, 3);
101
uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
102
assert(attrindx <= 7);
103
result->cacheattrs.is_s2_format = false;
104
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
105
if (param.ds) {
106
result->cacheattrs.shareability = param.sh;
107
} else {
108
- result->cacheattrs.shareability = extract32(attrs, 6, 2);
109
+ result->cacheattrs.shareability = extract32(attrs, 8, 2);
110
}
111
112
result->f.phys_addr = descaddr;
33
--
113
--
34
2.7.4
114
2.25.1
35
115
36
116
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Cc: Peter Maydell <peter.maydell@linaro.org>
3
Both GP and DBM are in the upper attribute block.
4
Cc: Jason Wang <jasowang@redhat.com>
4
Extend the computation of attrs to include them,
5
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
then simplify the setting of guarded.
6
Cc: qemu-devel@nongnu.org
6
7
Cc: qemu-arm@nongnu.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Cc: yurovsky@gmail.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Message-id: 20221024051851.3074715-11-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
hw/net/imx_fec.c | 2 +-
14
target/arm/ptw.c | 6 ++----
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 2 insertions(+), 4 deletions(-)
15
16
16
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/imx_fec.c
19
--- a/target/arm/ptw.c
19
+++ b/hw/net/imx_fec.c
20
+++ b/target/arm/ptw.c
20
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
21
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
21
TYPE_IMX_FEC, __func__);
22
uint32_t el = regime_el(env, mmu_idx);
22
break;
23
uint64_t descaddrmask;
23
}
24
bool aarch64 = arm_el_is_aa64(env, el);
24
- buf_len = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];
25
- bool guarded = false;
25
+ buf_len = MIN(size, s->regs[ENET_MRBR]);
26
uint64_t descriptor;
26
bd.length = buf_len;
27
bool nstable;
27
size -= buf_len;
28
28
29
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
30
descaddr &= ~(hwaddr)(page_size - 1);
31
descaddr |= (address & (page_size - 1));
32
/* Extract attributes from the descriptor */
33
- attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(52, 12));
34
+ attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
35
36
if (regime_is_stage2(mmu_idx)) {
37
/* Stage 2 table descriptors do not include any attribute fields */
38
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
39
}
40
/* Merge in attributes from table descriptors */
41
attrs |= nstable << 5; /* NS */
42
- guarded = extract64(descriptor, 50, 1); /* GP */
43
if (param.hpd) {
44
/* HPD disables all the table attributes except NSTable. */
45
goto skip_attrs;
46
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
47
48
/* When in aarch64 mode, and BTI is enabled, remember GP in the TLB. */
49
if (aarch64 && cpu_isar_feature(aa64_bti, cpu)) {
50
- result->f.guarded = guarded;
51
+ result->f.guarded = extract64(attrs, 50, 1); /* GP */
52
}
53
54
if (regime_is_stage2(mmu_idx)) {
29
--
55
--
30
2.7.4
56
2.25.1
31
57
32
58
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
ldxp loads two consecutive doublewords from memory regardless of CPU
3
Replace some gotos with some nested if statements.
4
endianness. On store, stlxp currently assumes to work with a 128bit
5
value and consequently switches order in big-endian mode. With this
6
change it packs the doublewords in reverse order in anticipation of the
7
128bit big-endian store operation interposing them so they end up in
8
memory in the right order. This makes it work for both MTTCG and !MTTCG.
9
It effectively implements the ARM ARM STLXP operation pseudo-code:
10
4
11
data = if BigEndian() then el1:el2 else el2:el1;
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
With this change an aarch64_be Linux 4.14.4 kernel succeeds to boot up
7
Message-id: 20221024051851.3074715-12-richard.henderson@linaro.org
14
in system emulation mode.
15
16
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
9
---
20
target/arm/helper-a64.c | 7 +++++--
10
target/arm/ptw.c | 34 ++++++++++++++++------------------
21
1 file changed, 5 insertions(+), 2 deletions(-)
11
1 file changed, 16 insertions(+), 18 deletions(-)
22
12
23
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
13
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
24
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-a64.c
15
--- a/target/arm/ptw.c
26
+++ b/target/arm/helper-a64.c
16
+++ b/target/arm/ptw.c
27
@@ -XXX,XX +XXX,XX @@ static uint64_t do_paired_cmpxchg64_be(CPUARMState *env, uint64_t addr,
17
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
28
Int128 oldv, cmpv, newv;
18
page_size = (1ULL << ((stride * (4 - level)) + 3));
29
bool success;
19
descaddr &= ~(hwaddr)(page_size - 1);
30
20
descaddr |= (address & (page_size - 1));
31
- cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
21
- /* Extract attributes from the descriptor */
32
- newv = int128_make128(new_lo, new_hi);
22
- attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
33
+ /* high and low need to be switched here because this is not actually a
23
34
+ * 128bit store but two doublewords stored consecutively
24
- if (regime_is_stage2(mmu_idx)) {
35
+ */
25
- /* Stage 2 table descriptors do not include any attribute fields */
36
+ cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
26
- goto skip_attrs;
37
+ newv = int128_make128(new_hi, new_lo);
27
- }
38
28
- /* Merge in attributes from table descriptors */
39
if (parallel) {
29
- attrs |= nstable << 5; /* NS */
40
#ifndef CONFIG_ATOMIC128
30
- if (param.hpd) {
31
- /* HPD disables all the table attributes except NSTable. */
32
- goto skip_attrs;
33
- }
34
- attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
35
/*
36
- * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
37
- * means "force PL1 access only", which means forcing AP[1] to 0.
38
+ * Extract attributes from the descriptor, and apply table descriptors.
39
+ * Stage 2 table descriptors do not include any attribute fields.
40
+ * HPD disables all the table attributes except NSTable.
41
*/
42
- attrs &= ~(extract64(tableattrs, 2, 1) << 6); /* !APT[0] => AP[1] */
43
- attrs |= extract32(tableattrs, 3, 1) << 7; /* APT[1] => AP[2] */
44
- skip_attrs:
45
+ attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
46
+ if (!regime_is_stage2(mmu_idx)) {
47
+ attrs |= nstable << 5; /* NS */
48
+ if (!param.hpd) {
49
+ attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
50
+ /*
51
+ * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
52
+ * means "force PL1 access only", which means forcing AP[1] to 0.
53
+ */
54
+ attrs &= ~(extract64(tableattrs, 2, 1) << 6); /* !APT[0] => AP[1] */
55
+ attrs |= extract32(tableattrs, 3, 1) << 7; /* APT[1] => AP[2] */
56
+ }
57
+ }
58
59
/*
60
* Here descaddr is the final physical address, and attributes
41
--
61
--
42
2.7.4
62
2.25.1
43
63
44
64
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Enable big-endian mode for data accesses on aarch64 for big-endian linux
3
Perform the atomic update for hardware management of the access flag.
4
user mode. Activate it for all exception levels as documented by ARM:
5
Set the SCTLR EE bit for ELs 1 through 3. Additionally set bit E0E in
6
EL1 to enable it in EL0 as well.
7
4
8
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20171220212308.12614-2-michael.weiser@gmx.de
7
Message-id: 20221024051851.3074715-13-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
9
---
13
linux-user/main.c | 6 ++++++
10
docs/system/arm/emulation.rst | 1 +
14
1 file changed, 6 insertions(+)
11
target/arm/cpu64.c | 1 +
12
target/arm/ptw.c | 176 +++++++++++++++++++++++++++++-----
13
3 files changed, 156 insertions(+), 22 deletions(-)
15
14
16
diff --git a/linux-user/main.c b/linux-user/main.c
15
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/linux-user/main.c
17
--- a/docs/system/arm/emulation.rst
19
+++ b/linux-user/main.c
18
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
19
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
}
20
- FEAT_FlagM (Flag manipulation instructions v2)
22
env->pc = regs->pc;
21
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
23
env->xregs[31] = regs->sp;
22
- FEAT_GTG (Guest translation granule size)
24
+#ifdef TARGET_WORDS_BIGENDIAN
23
+- FEAT_HAFDBS (Hardware management of the access flag and dirty bit state)
25
+ env->cp15.sctlr_el[1] |= SCTLR_E0E;
24
- FEAT_HCX (Support for the HCRX_EL2 register)
26
+ for (i = 1; i < 4; ++i) {
25
- FEAT_HPDS (Hierarchical permission disables)
27
+ env->cp15.sctlr_el[i] |= SCTLR_EE;
26
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
27
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu64.c
30
+++ b/target/arm/cpu64.c
31
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
32
cpu->isar.id_aa64mmfr0 = t;
33
34
t = cpu->isar.id_aa64mmfr1;
35
+ t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 1); /* FEAT_HAFDBS, AF only */
36
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
37
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
38
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
39
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/ptw.c
42
+++ b/target/arm/ptw.c
43
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
44
bool in_secure;
45
bool in_debug;
46
bool out_secure;
47
+ bool out_rw;
48
bool out_be;
49
+ hwaddr out_virt;
50
hwaddr out_phys;
51
void *out_host;
52
} S1Translate;
53
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
54
uint8_t pte_attrs;
55
bool pte_secure;
56
57
+ ptw->out_virt = addr;
58
+
59
if (unlikely(ptw->in_debug)) {
60
/*
61
* From gdbstub, do not use softmmu so that we don't modify the
62
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
63
pte_secure = is_secure;
64
}
65
ptw->out_host = NULL;
66
+ ptw->out_rw = false;
67
} else {
68
CPUTLBEntryFull *full;
69
int flags;
70
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
71
goto fail;
72
}
73
ptw->out_phys = full->phys_addr;
74
+ ptw->out_rw = full->prot & PROT_WRITE;
75
pte_attrs = full->pte_attrs;
76
pte_secure = full->attrs.secure;
77
}
78
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw,
79
ARMMMUFaultInfo *fi)
80
{
81
CPUState *cs = env_cpu(env);
82
+ void *host = ptw->out_host;
83
uint32_t data;
84
85
- if (likely(ptw->out_host)) {
86
+ if (likely(host)) {
87
/* Page tables are in RAM, and we have the host address. */
88
+ data = qatomic_read((uint32_t *)host);
89
if (ptw->out_be) {
90
- data = ldl_be_p(ptw->out_host);
91
+ data = be32_to_cpu(data);
92
} else {
93
- data = ldl_le_p(ptw->out_host);
94
+ data = le32_to_cpu(data);
95
}
96
} else {
97
/* Page tables are in MMIO. */
98
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
99
ARMMMUFaultInfo *fi)
100
{
101
CPUState *cs = env_cpu(env);
102
+ void *host = ptw->out_host;
103
uint64_t data;
104
105
- if (likely(ptw->out_host)) {
106
+ if (likely(host)) {
107
/* Page tables are in RAM, and we have the host address. */
108
+#ifdef CONFIG_ATOMIC64
109
+ data = qatomic_read__nocheck((uint64_t *)host);
110
if (ptw->out_be) {
111
- data = ldq_be_p(ptw->out_host);
112
+ data = be64_to_cpu(data);
113
} else {
114
- data = ldq_le_p(ptw->out_host);
115
+ data = le64_to_cpu(data);
116
}
117
+#else
118
+ if (ptw->out_be) {
119
+ data = ldq_be_p(host);
120
+ } else {
121
+ data = ldq_le_p(host);
28
+ }
122
+ }
29
+#endif
123
+#endif
124
} else {
125
/* Page tables are in MMIO. */
126
MemTxAttrs attrs = { .secure = ptw->out_secure };
127
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
128
return data;
129
}
130
131
+static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
132
+ uint64_t new_val, S1Translate *ptw,
133
+ ARMMMUFaultInfo *fi)
134
+{
135
+ uint64_t cur_val;
136
+ void *host = ptw->out_host;
137
+
138
+ if (unlikely(!host)) {
139
+ fi->type = ARMFault_UnsuppAtomicUpdate;
140
+ fi->s1ptw = true;
141
+ return 0;
142
+ }
143
+
144
+ /*
145
+ * Raising a stage2 Protection fault for an atomic update to a read-only
146
+ * page is delayed until it is certain that there is a change to make.
147
+ */
148
+ if (unlikely(!ptw->out_rw)) {
149
+ int flags;
150
+ void *discard;
151
+
152
+ env->tlb_fi = fi;
153
+ flags = probe_access_flags(env, ptw->out_virt, MMU_DATA_STORE,
154
+ arm_to_core_mmu_idx(ptw->in_ptw_idx),
155
+ true, &discard, 0);
156
+ env->tlb_fi = NULL;
157
+
158
+ if (unlikely(flags & TLB_INVALID_MASK)) {
159
+ assert(fi->type != ARMFault_None);
160
+ fi->s2addr = ptw->out_virt;
161
+ fi->stage2 = true;
162
+ fi->s1ptw = true;
163
+ fi->s1ns = !ptw->in_secure;
164
+ return 0;
165
+ }
166
+
167
+ /* In case CAS mismatches and we loop, remember writability. */
168
+ ptw->out_rw = true;
169
+ }
170
+
171
+#ifdef CONFIG_ATOMIC64
172
+ if (ptw->out_be) {
173
+ old_val = cpu_to_be64(old_val);
174
+ new_val = cpu_to_be64(new_val);
175
+ cur_val = qatomic_cmpxchg__nocheck((uint64_t *)host, old_val, new_val);
176
+ cur_val = be64_to_cpu(cur_val);
177
+ } else {
178
+ old_val = cpu_to_le64(old_val);
179
+ new_val = cpu_to_le64(new_val);
180
+ cur_val = qatomic_cmpxchg__nocheck((uint64_t *)host, old_val, new_val);
181
+ cur_val = le64_to_cpu(cur_val);
182
+ }
183
+#else
184
+ /*
185
+ * We can't support the full 64-bit atomic cmpxchg on the host.
186
+ * Because this is only used for FEAT_HAFDBS, which is only for AA64,
187
+ * we know that TCG_OVERSIZED_GUEST is set, which means that we are
188
+ * running in round-robin mode and could only race with dma i/o.
189
+ */
190
+#ifndef TCG_OVERSIZED_GUEST
191
+# error "Unexpected configuration"
192
+#endif
193
+ bool locked = qemu_mutex_iothread_locked();
194
+ if (!locked) {
195
+ qemu_mutex_lock_iothread();
196
+ }
197
+ if (ptw->out_be) {
198
+ cur_val = ldq_be_p(host);
199
+ if (cur_val == old_val) {
200
+ stq_be_p(host, new_val);
201
+ }
202
+ } else {
203
+ cur_val = ldq_le_p(host);
204
+ if (cur_val == old_val) {
205
+ stq_le_p(host, new_val);
206
+ }
207
+ }
208
+ if (!locked) {
209
+ qemu_mutex_unlock_iothread();
210
+ }
211
+#endif
212
+
213
+ return cur_val;
214
+}
215
+
216
static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
217
uint32_t *table, uint32_t address)
218
{
219
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
220
uint32_t el = regime_el(env, mmu_idx);
221
uint64_t descaddrmask;
222
bool aarch64 = arm_el_is_aa64(env, el);
223
- uint64_t descriptor;
224
+ uint64_t descriptor, new_descriptor;
225
bool nstable;
226
227
/* TODO: This code does not support shareability levels. */
228
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
229
if (fi->type != ARMFault_None) {
230
goto do_fault;
30
}
231
}
31
#elif defined(TARGET_ARM)
232
+ new_descriptor = descriptor;
32
{
233
234
+ restart_atomic_update:
235
if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) {
236
/* Invalid, or the Reserved level 3 encoding */
237
goto do_translation_fault;
238
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
239
* to give a correct page or table address, the address field
240
* in a block descriptor is smaller; so we need to explicitly
241
* clear the lower bits here before ORing in the low vaddr bits.
242
+ *
243
+ * Afterward, descaddr is the final physical address.
244
*/
245
page_size = (1ULL << ((stride * (4 - level)) + 3));
246
descaddr &= ~(hwaddr)(page_size - 1);
247
descaddr |= (address & (page_size - 1));
248
249
+ if (likely(!ptw->in_debug)) {
250
+ /*
251
+ * Access flag.
252
+ * If HA is enabled, prepare to update the descriptor below.
253
+ * Otherwise, pass the access fault on to software.
254
+ */
255
+ if (!(descriptor & (1 << 10))) {
256
+ if (param.ha) {
257
+ new_descriptor |= 1 << 10; /* AF */
258
+ } else {
259
+ fi->type = ARMFault_AccessFlag;
260
+ goto do_fault;
261
+ }
262
+ }
263
+ }
264
+
265
/*
266
- * Extract attributes from the descriptor, and apply table descriptors.
267
- * Stage 2 table descriptors do not include any attribute fields.
268
- * HPD disables all the table attributes except NSTable.
269
+ * Extract attributes from the (modified) descriptor, and apply
270
+ * table descriptors. Stage 2 table descriptors do not include
271
+ * any attribute fields. HPD disables all the table attributes
272
+ * except NSTable.
273
*/
274
- attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
275
+ attrs = new_descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
276
if (!regime_is_stage2(mmu_idx)) {
277
attrs |= nstable << 5; /* NS */
278
if (!param.hpd) {
279
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
280
}
281
}
282
283
- /*
284
- * Here descaddr is the final physical address, and attributes
285
- * are all in attrs.
286
- */
287
- if ((attrs & (1 << 10)) == 0) {
288
- /* Access flag */
289
- fi->type = ARMFault_AccessFlag;
290
- goto do_fault;
291
- }
292
-
293
ap = extract32(attrs, 6, 2);
294
-
295
if (regime_is_stage2(mmu_idx)) {
296
ns = mmu_idx == ARMMMUIdx_Stage2;
297
xn = extract64(attrs, 53, 2);
298
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
299
goto do_fault;
300
}
301
302
+ /* If FEAT_HAFDBS has made changes, update the PTE. */
303
+ if (new_descriptor != descriptor) {
304
+ new_descriptor = arm_casq_ptw(env, descriptor, new_descriptor, ptw, fi);
305
+ if (fi->type != ARMFault_None) {
306
+ goto do_fault;
307
+ }
308
+ /*
309
+ * I_YZSVV says that if the in-memory descriptor has changed,
310
+ * then we must use the information in that new value
311
+ * (which might include a different output address, different
312
+ * attributes, or generate a fault).
313
+ * Restart the handling of the descriptor value from scratch.
314
+ */
315
+ if (new_descriptor != descriptor) {
316
+ descriptor = new_descriptor;
317
+ goto restart_atomic_update;
318
+ }
319
+ }
320
+
321
if (ns) {
322
/*
323
* The NS bit will (as required by the architecture) have no effect if
33
--
324
--
34
2.7.4
325
2.25.1
35
36
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Refactor imx_eth_enable_rx() to have more meaningfull variable name
3
Perform the atomic update for hardware management of the dirty bit.
4
than 'tmp' and to reduce number of logical negations done.
5
4
6
Cc: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Cc: Jason Wang <jasowang@redhat.com>
6
Message-id: 20221024051851.3074715-14-richard.henderson@linaro.org
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: yurovsky@gmail.com
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
8
---
17
hw/net/imx_fec.c | 8 ++++----
9
target/arm/cpu64.c | 2 +-
18
1 file changed, 4 insertions(+), 4 deletions(-)
10
target/arm/ptw.c | 16 ++++++++++++++++
11
2 files changed, 17 insertions(+), 1 deletion(-)
19
12
20
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
13
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/net/imx_fec.c
15
--- a/target/arm/cpu64.c
23
+++ b/hw/net/imx_fec.c
16
+++ b/target/arm/cpu64.c
24
@@ -XXX,XX +XXX,XX @@ static void imx_eth_do_tx(IMXFECState *s)
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
25
static void imx_eth_enable_rx(IMXFECState *s)
18
cpu->isar.id_aa64mmfr0 = t;
26
{
19
27
IMXFECBufDesc bd;
20
t = cpu->isar.id_aa64mmfr1;
28
- bool tmp;
21
- t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 1); /* FEAT_HAFDBS, AF only */
29
+ bool rx_ring_full;
22
+ t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 2); /* FEAT_HAFDBS */
30
23
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
31
imx_fec_read_bd(&bd, s->rx_descriptor);
24
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
32
25
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
33
- tmp = ((bd.flags & ENET_BD_E) != 0);
26
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
34
+ rx_ring_full = !(bd.flags & ENET_BD_E);
27
index XXXXXXX..XXXXXXX 100644
35
28
--- a/target/arm/ptw.c
36
- if (!tmp) {
29
+++ b/target/arm/ptw.c
37
+ if (rx_ring_full) {
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
38
FEC_PRINTF("RX buffer full\n");
31
goto do_fault;
39
} else if (!s->regs[ENET_RDAR]) {
32
}
40
qemu_flush_queued_packets(qemu_get_queue(s->nic));
33
}
34
+
35
+ /*
36
+ * Dirty Bit.
37
+ * If HD is enabled, pre-emptively set/clear the appropriate AP/S2AP
38
+ * bit for writeback. The actual write protection test may still be
39
+ * overridden by tableattrs, to be merged below.
40
+ */
41
+ if (param.hd
42
+ && extract64(descriptor, 51, 1) /* DBM */
43
+ && access_type == MMU_DATA_STORE) {
44
+ if (regime_is_stage2(mmu_idx)) {
45
+ new_descriptor |= 1ull << 7; /* set S2AP[1] */
46
+ } else {
47
+ new_descriptor &= ~(1ull << 7); /* clear AP[2] */
48
+ }
49
+ }
41
}
50
}
42
51
43
- s->regs[ENET_RDAR] = tmp ? ENET_RDAR_RDAR : 0;
52
/*
44
+ s->regs[ENET_RDAR] = rx_ring_full ? 0 : ENET_RDAR_RDAR;
45
}
46
47
static void imx_eth_reset(DeviceState *d)
48
--
53
--
49
2.7.4
54
2.25.1
50
51
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Needed to support latest Linux kernel driver which relies on that
3
We had only been reporting the stage2 page size. This causes
4
functionality.
4
problems if stage1 is using a larger page size (16k, 2M, etc),
5
but stage2 is using a smaller page size, because cputlb does
6
not set large_page_{addr,mask} properly.
5
7
6
Cc: Peter Maydell <peter.maydell@linaro.org>
8
Fix by using the max of the two page sizes.
7
Cc: Jason Wang <jasowang@redhat.com>
9
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reported-by: Marc Zyngier <maz@kernel.org>
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: yurovsky@gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20221024051851.3074715-15-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
15
---
16
include/hw/net/imx_fec.h | 2 ++
16
target/arm/ptw.c | 11 ++++++++++-
17
hw/net/imx_fec.c | 23 +++++++++++++++++++++++
17
1 file changed, 10 insertions(+), 1 deletion(-)
18
2 files changed, 25 insertions(+)
19
18
20
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
19
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
21
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/net/imx_fec.h
21
--- a/target/arm/ptw.c
23
+++ b/include/hw/net/imx_fec.h
22
+++ b/target/arm/ptw.c
24
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
25
#define ENET_TWFR_TFWR_LENGTH (6)
24
ARMMMUFaultInfo *fi)
26
#define ENET_TWFR_STRFWD (1 << 8)
25
{
27
26
hwaddr ipa;
28
+#define ENET_RACC_SHIFT16 BIT(7)
27
- int s1_prot;
29
+
28
+ int s1_prot, s1_lgpgsz;
30
/* Buffer Descriptor. */
29
bool is_secure = ptw->in_secure;
31
typedef struct {
30
bool ret, ipa_secure, s2walk_secure;
32
uint16_t length;
31
ARMCacheAttrs cacheattrs1;
33
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
32
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
34
index XXXXXXX..XXXXXXX 100644
33
* Save the stage1 results so that we may merge prot and cacheattrs later.
35
--- a/hw/net/imx_fec.c
34
*/
36
+++ b/hw/net/imx_fec.c
35
s1_prot = result->f.prot;
37
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
36
+ s1_lgpgsz = result->f.lg_page_size;
38
uint8_t *crc_ptr;
37
cacheattrs1 = result->cacheattrs;
39
unsigned int buf_len;
38
memset(result, 0, sizeof(*result));
40
size_t size = len;
39
41
+ bool shift16 = s->regs[ENET_RACC] & ENET_RACC_SHIFT16;
40
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
42
41
return ret;
43
FEC_PRINTF("len %d\n", (int)size);
42
}
44
43
45
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
44
+ /*
46
crc = cpu_to_be32(crc32(~0, buf, size));
45
+ * Use the maximum of the S1 & S2 page size, so that invalidation
47
crc_ptr = (uint8_t *) &crc;
46
+ * of pages > TARGET_PAGE_SIZE works correctly.
48
47
+ */
49
+ if (shift16) {
48
+ if (result->f.lg_page_size < s1_lgpgsz) {
50
+ size += 2;
49
+ result->f.lg_page_size = s1_lgpgsz;
51
+ }
50
+ }
52
+
51
+
53
/* Huge frames are truncted. */
52
/* Combine the S1 and S2 cache attributes. */
54
if (size > s->regs[ENET_FTRL]) {
53
hcr = arm_hcr_el2_eff_secstate(env, is_secure);
55
size = s->regs[ENET_FTRL];
54
if (hcr & HCR_DC) {
56
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
57
buf_len += size - 4;
58
}
59
buf_addr = bd.data;
60
+
61
+ if (shift16) {
62
+ /*
63
+ * If SHIFT16 bit of ENETx_RACC register is set we need to
64
+ * align the payload to 4-byte boundary.
65
+ */
66
+ const uint8_t zeros[2] = { 0 };
67
+
68
+ dma_memory_write(&address_space_memory, buf_addr,
69
+ zeros, sizeof(zeros));
70
+
71
+ buf_addr += sizeof(zeros);
72
+ buf_len -= sizeof(zeros);
73
+
74
+ /* We only do this once per Ethernet frame */
75
+ shift16 = false;
76
+ }
77
+
78
dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);
79
buf += buf_len;
80
if (size < 4) {
81
--
55
--
82
2.7.4
56
2.25.1
83
84
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Make Tx frame assembly buffer to be a paort of IMXFECState structure
3
Snapshot loading only expects to call deterministic handlers, not
4
to avoid a concern about having large data buffer on the stack.
4
non-deterministic ones. So introduce a way of registering handlers that
5
won't be called when reseting for snapshots.
5
6
6
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
7
Cc: Jason Wang <jasowang@redhat.com>
8
Message-id: 20221025004327.568476-2-Jason@zx2c4.com
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
[PMM: updated json doc comment with Markus' text; fixed
9
Cc: qemu-devel@nongnu.org
10
checkpatch style nit]
10
Cc: qemu-arm@nongnu.org
11
Cc: yurovsky@gmail.com
12
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
include/hw/net/imx_fec.h | 3 +++
14
qapi/run-state.json | 6 +++++-
17
hw/net/imx_fec.c | 22 +++++++++++-----------
15
include/hw/boards.h | 2 +-
18
2 files changed, 14 insertions(+), 11 deletions(-)
16
include/sysemu/reset.h | 5 ++++-
17
hw/arm/aspeed.c | 4 ++--
18
hw/arm/mps2-tz.c | 4 ++--
19
hw/core/reset.c | 17 ++++++++++++++++-
20
hw/hppa/machine.c | 4 ++--
21
hw/i386/microvm.c | 4 ++--
22
hw/i386/pc.c | 6 +++---
23
hw/ppc/pegasos2.c | 4 ++--
24
hw/ppc/pnv.c | 4 ++--
25
hw/ppc/spapr.c | 4 ++--
26
hw/s390x/s390-virtio-ccw.c | 4 ++--
27
migration/savevm.c | 2 +-
28
softmmu/runstate.c | 11 ++++++++---
29
15 files changed, 54 insertions(+), 27 deletions(-)
19
30
20
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
31
diff --git a/qapi/run-state.json b/qapi/run-state.json
21
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/net/imx_fec.h
33
--- a/qapi/run-state.json
23
+++ b/include/hw/net/imx_fec.h
34
+++ b/qapi/run-state.json
24
@@ -XXX,XX +XXX,XX @@ typedef struct IMXFECState {
35
@@ -XXX,XX +XXX,XX @@
25
uint32_t phy_int_mask;
36
# ignores --no-reboot. This is useful for sanitizing
26
37
# hypercalls on s390 that are used during kexec/kdump/boot
27
bool is_fec;
38
#
39
+# @snapshot-load: A snapshot is being loaded by the record & replay
40
+# subsystem. This value is used only within QEMU. It
41
+# doesn't occur in QMP. (since 7.2)
42
+#
43
##
44
{ 'enum': 'ShutdownCause',
45
# Beware, shutdown_caused_by_guest() depends on enumeration order
46
'data': [ 'none', 'host-error', 'host-qmp-quit', 'host-qmp-system-reset',
47
'host-signal', 'host-ui', 'guest-shutdown', 'guest-reset',
48
- 'guest-panic', 'subsystem-reset'] }
49
+ 'guest-panic', 'subsystem-reset', 'snapshot-load'] }
50
51
##
52
# @StatusInfo:
53
diff --git a/include/hw/boards.h b/include/hw/boards.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/include/hw/boards.h
56
+++ b/include/hw/boards.h
57
@@ -XXX,XX +XXX,XX @@ struct MachineClass {
58
const char *deprecation_reason;
59
60
void (*init)(MachineState *state);
61
- void (*reset)(MachineState *state);
62
+ void (*reset)(MachineState *state, ShutdownCause reason);
63
void (*wakeup)(MachineState *state);
64
int (*kvm_type)(MachineState *machine, const char *arg);
65
66
diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h
67
index XXXXXXX..XXXXXXX 100644
68
--- a/include/sysemu/reset.h
69
+++ b/include/sysemu/reset.h
70
@@ -XXX,XX +XXX,XX @@
71
#ifndef QEMU_SYSEMU_RESET_H
72
#define QEMU_SYSEMU_RESET_H
73
74
+#include "qapi/qapi-events-run-state.h"
28
+
75
+
29
+ /* Buffer used to assemble a Tx frame */
76
typedef void QEMUResetHandler(void *opaque);
30
+ uint8_t frame[ENET_MAX_FRAME_SIZE];
77
31
} IMXFECState;
78
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
79
+void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque);
80
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
81
-void qemu_devices_reset(void);
82
+void qemu_devices_reset(ShutdownCause reason);
32
83
33
#endif
84
#endif
34
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
85
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
35
index XXXXXXX..XXXXXXX 100644
86
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/net/imx_fec.c
87
--- a/hw/arm/aspeed.c
37
+++ b/hw/net/imx_fec.c
88
+++ b/hw/arm/aspeed.c
38
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s)
89
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
39
static void imx_fec_do_tx(IMXFECState *s)
90
aspeed_soc_num_cpus(amc->soc_name);
40
{
91
}
41
int frame_size = 0, descnt = 0;
92
42
- uint8_t frame[ENET_MAX_FRAME_SIZE];
93
-static void fby35_reset(MachineState *state)
43
- uint8_t *ptr = frame;
94
+static void fby35_reset(MachineState *state, ShutdownCause reason)
44
+ uint8_t *ptr = s->frame;
95
{
45
uint32_t addr = s->tx_descriptor;
96
AspeedMachineState *bmc = ASPEED_MACHINE(state);
46
97
AspeedGPIOState *gpio = &bmc->soc.gpio;
47
while (descnt++ < IMX_MAX_DESC) {
98
48
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
99
- qemu_devices_reset();
49
frame_size += len;
100
+ qemu_devices_reset(reason);
50
if (bd.flags & ENET_BD_L) {
101
51
/* Last buffer in frame. */
102
/* Board ID: 7 (Class-1, 4 slots) */
52
- qemu_send_packet(qemu_get_queue(s->nic), frame, frame_size);
103
object_property_set_bool(OBJECT(gpio), "gpioV4", true, &error_fatal);
53
- ptr = frame;
104
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
54
+ qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
105
index XXXXXXX..XXXXXXX 100644
55
+ ptr = s->frame;
106
--- a/hw/arm/mps2-tz.c
56
frame_size = 0;
107
+++ b/hw/arm/mps2-tz.c
57
s->regs[ENET_EIR] |= ENET_INT_TXF;
108
@@ -XXX,XX +XXX,XX @@ static void mps2_set_remap(Object *obj, const char *value, Error **errp)
109
}
110
}
111
112
-static void mps2_machine_reset(MachineState *machine)
113
+static void mps2_machine_reset(MachineState *machine, ShutdownCause reason)
114
{
115
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
116
117
@@ -XXX,XX +XXX,XX @@ static void mps2_machine_reset(MachineState *machine)
118
* reset see the correct mapping.
119
*/
120
remap_memory(mms, mms->remap);
121
- qemu_devices_reset();
122
+ qemu_devices_reset(reason);
123
}
124
125
static void mps2tz_class_init(ObjectClass *oc, void *data)
126
diff --git a/hw/core/reset.c b/hw/core/reset.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/core/reset.c
129
+++ b/hw/core/reset.c
130
@@ -XXX,XX +XXX,XX @@ typedef struct QEMUResetEntry {
131
QTAILQ_ENTRY(QEMUResetEntry) entry;
132
QEMUResetHandler *func;
133
void *opaque;
134
+ bool skip_on_snapshot_load;
135
} QEMUResetEntry;
136
137
static QTAILQ_HEAD(, QEMUResetEntry) reset_handlers =
138
@@ -XXX,XX +XXX,XX @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque)
139
QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
140
}
141
142
+void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque)
143
+{
144
+ QEMUResetEntry *re = g_new0(QEMUResetEntry, 1);
145
+
146
+ re->func = func;
147
+ re->opaque = opaque;
148
+ re->skip_on_snapshot_load = true;
149
+ QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
150
+}
151
+
152
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
153
{
154
QEMUResetEntry *re;
155
@@ -XXX,XX +XXX,XX @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
156
}
157
}
158
159
-void qemu_devices_reset(void)
160
+void qemu_devices_reset(ShutdownCause reason)
161
{
162
QEMUResetEntry *re, *nre;
163
164
/* reset all devices */
165
QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
166
+ if (reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD &&
167
+ re->skip_on_snapshot_load) {
168
+ continue;
169
+ }
170
re->func(re->opaque);
171
}
172
}
173
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
174
index XXXXXXX..XXXXXXX 100644
175
--- a/hw/hppa/machine.c
176
+++ b/hw/hppa/machine.c
177
@@ -XXX,XX +XXX,XX @@ static void machine_hppa_init(MachineState *machine)
178
cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
179
}
180
181
-static void hppa_machine_reset(MachineState *ms)
182
+static void hppa_machine_reset(MachineState *ms, ShutdownCause reason)
183
{
184
unsigned int smp_cpus = ms->smp.cpus;
185
int i;
186
187
- qemu_devices_reset();
188
+ qemu_devices_reset(reason);
189
190
/* Start all CPUs at the firmware entry point.
191
* Monarch CPU will initialize firmware, secondary CPUs
192
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/hw/i386/microvm.c
195
+++ b/hw/i386/microvm.c
196
@@ -XXX,XX +XXX,XX @@ static void microvm_machine_state_init(MachineState *machine)
197
microvm_devices_init(mms);
198
}
199
200
-static void microvm_machine_reset(MachineState *machine)
201
+static void microvm_machine_reset(MachineState *machine, ShutdownCause reason)
202
{
203
MicrovmMachineState *mms = MICROVM_MACHINE(machine);
204
CPUState *cs;
205
@@ -XXX,XX +XXX,XX @@ static void microvm_machine_reset(MachineState *machine)
206
mms->kernel_cmdline_fixed = true;
207
}
208
209
- qemu_devices_reset();
210
+ qemu_devices_reset(reason);
211
212
CPU_FOREACH(cs) {
213
cpu = X86_CPU(cs);
214
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
215
index XXXXXXX..XXXXXXX 100644
216
--- a/hw/i386/pc.c
217
+++ b/hw/i386/pc.c
218
@@ -XXX,XX +XXX,XX @@ static void pc_machine_initfn(Object *obj)
219
cxl_machine_init(obj, &pcms->cxl_devices_state);
220
}
221
222
-static void pc_machine_reset(MachineState *machine)
223
+static void pc_machine_reset(MachineState *machine, ShutdownCause reason)
224
{
225
CPUState *cs;
226
X86CPU *cpu;
227
228
- qemu_devices_reset();
229
+ qemu_devices_reset(reason);
230
231
/* Reset APIC after devices have been reset to cancel
232
* any changes that qemu_devices_reset() might have done.
233
@@ -XXX,XX +XXX,XX @@ static void pc_machine_reset(MachineState *machine)
234
static void pc_machine_wakeup(MachineState *machine)
235
{
236
cpu_synchronize_all_states();
237
- pc_machine_reset(machine);
238
+ pc_machine_reset(machine, SHUTDOWN_CAUSE_NONE);
239
cpu_synchronize_all_post_reset();
240
}
241
242
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
243
index XXXXXXX..XXXXXXX 100644
244
--- a/hw/ppc/pegasos2.c
245
+++ b/hw/ppc/pegasos2.c
246
@@ -XXX,XX +XXX,XX @@ static void pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
247
pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);
248
}
249
250
-static void pegasos2_machine_reset(MachineState *machine)
251
+static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
252
{
253
Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
254
void *fdt;
255
uint64_t d[2];
256
int sz;
257
258
- qemu_devices_reset();
259
+ qemu_devices_reset(reason);
260
if (!pm->vof) {
261
return; /* Firmware should set up machine so nothing to do */
262
}
263
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
264
index XXXXXXX..XXXXXXX 100644
265
--- a/hw/ppc/pnv.c
266
+++ b/hw/ppc/pnv.c
267
@@ -XXX,XX +XXX,XX @@ static void pnv_powerdown_notify(Notifier *n, void *opaque)
268
}
269
}
270
271
-static void pnv_reset(MachineState *machine)
272
+static void pnv_reset(MachineState *machine, ShutdownCause reason)
273
{
274
PnvMachineState *pnv = PNV_MACHINE(machine);
275
IPMIBmc *bmc;
276
void *fdt;
277
278
- qemu_devices_reset();
279
+ qemu_devices_reset(reason);
280
281
/*
282
* The machine should provide by default an internal BMC simulator.
283
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
284
index XXXXXXX..XXXXXXX 100644
285
--- a/hw/ppc/spapr.c
286
+++ b/hw/ppc/spapr.c
287
@@ -XXX,XX +XXX,XX @@ void spapr_check_mmu_mode(bool guest_radix)
288
}
289
}
290
291
-static void spapr_machine_reset(MachineState *machine)
292
+static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
293
{
294
SpaprMachineState *spapr = SPAPR_MACHINE(machine);
295
PowerPCCPU *first_ppc_cpu;
296
@@ -XXX,XX +XXX,XX @@ static void spapr_machine_reset(MachineState *machine)
297
spapr_setup_hpt(spapr);
298
}
299
300
- qemu_devices_reset();
301
+ qemu_devices_reset(reason);
302
303
spapr_ovec_cleanup(spapr->ov5_cas);
304
spapr->ov5_cas = spapr_ovec_new();
305
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
306
index XXXXXXX..XXXXXXX 100644
307
--- a/hw/s390x/s390-virtio-ccw.c
308
+++ b/hw/s390x/s390-virtio-ccw.c
309
@@ -XXX,XX +XXX,XX @@ static void s390_pv_prepare_reset(S390CcwMachineState *ms)
310
s390_pv_prep_reset();
311
}
312
313
-static void s390_machine_reset(MachineState *machine)
314
+static void s390_machine_reset(MachineState *machine, ShutdownCause reason)
315
{
316
S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
317
enum s390_reset reset_type;
318
@@ -XXX,XX +XXX,XX @@ static void s390_machine_reset(MachineState *machine)
319
s390_machine_unprotect(ms);
58
}
320
}
59
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
321
60
static void imx_enet_do_tx(IMXFECState *s)
322
- qemu_devices_reset();
61
{
323
+ qemu_devices_reset(reason);
62
int frame_size = 0, descnt = 0;
324
s390_crypto_reset();
63
- uint8_t frame[ENET_MAX_FRAME_SIZE];
325
64
- uint8_t *ptr = frame;
326
/* configure and start the ipl CPU only */
65
+ uint8_t *ptr = s->frame;
327
diff --git a/migration/savevm.c b/migration/savevm.c
66
uint32_t addr = s->tx_descriptor;
328
index XXXXXXX..XXXXXXX 100644
67
329
--- a/migration/savevm.c
68
while (descnt++ < IMX_MAX_DESC) {
330
+++ b/migration/savevm.c
69
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s)
331
@@ -XXX,XX +XXX,XX @@ bool load_snapshot(const char *name, const char *vmstate,
70
frame_size += len;
332
goto err_drain;
71
if (bd.flags & ENET_BD_L) {
333
}
72
if (bd.option & ENET_BD_PINS) {
334
73
- struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
335
- qemu_system_reset(SHUTDOWN_CAUSE_NONE);
74
+ struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
336
+ qemu_system_reset(SHUTDOWN_CAUSE_SNAPSHOT_LOAD);
75
if (IP_HEADER_VERSION(ip_hd) == 4) {
337
mis->from_src_file = f;
76
- net_checksum_calculate(frame, frame_size);
338
77
+ net_checksum_calculate(s->frame, frame_size);
339
if (!yank_register_instance(MIGRATION_YANK_INSTANCE, errp)) {
78
}
340
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
79
}
341
index XXXXXXX..XXXXXXX 100644
80
if (bd.option & ENET_BD_IINS) {
342
--- a/softmmu/runstate.c
81
- struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
343
+++ b/softmmu/runstate.c
82
+ struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
344
@@ -XXX,XX +XXX,XX @@ void qemu_system_reset(ShutdownCause reason)
83
/* We compute checksum only for IPv4 frames */
345
cpu_synchronize_all_states();
84
if (IP_HEADER_VERSION(ip_hd) == 4) {
346
85
uint16_t csum;
347
if (mc && mc->reset) {
86
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s)
348
- mc->reset(current_machine);
87
}
349
+ mc->reset(current_machine, reason);
88
}
350
} else {
89
/* Last buffer in frame. */
351
- qemu_devices_reset();
90
- qemu_send_packet(qemu_get_queue(s->nic), frame, len);
352
+ qemu_devices_reset(reason);
91
- ptr = frame;
353
}
92
+
354
- if (reason && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
93
+ qemu_send_packet(qemu_get_queue(s->nic), s->frame, len);
355
+ switch (reason) {
94
+ ptr = s->frame;
356
+ case SHUTDOWN_CAUSE_NONE:
95
+
357
+ case SHUTDOWN_CAUSE_SUBSYSTEM_RESET:
96
frame_size = 0;
358
+ case SHUTDOWN_CAUSE_SNAPSHOT_LOAD:
97
if (bd.option & ENET_BD_TX_INT) {
359
+ break;
98
s->regs[ENET_EIR] |= ENET_INT_TXF;
360
+ default:
361
qapi_event_send_reset(shutdown_caused_by_guest(reason), reason);
362
}
363
cpu_synchronize_all_post_reset();
99
--
364
--
100
2.7.4
365
2.25.1
101
102
diff view generated by jsdifflib
New patch
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
1
2
3
When the system reboots, the rng-seed that the FDT has should be
4
re-randomized, so that the new boot gets a new seed. Several
5
architectures require this functionality, so export a function for
6
injecting a new seed into the given FDT.
7
8
Cc: Alistair Francis <alistair.francis@wdc.com>
9
Cc: David Gibson <david@gibson.dropbear.id.au>
10
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-id: 20221025004327.568476-3-Jason@zx2c4.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/sysemu/device_tree.h | 9 +++++++++
16
softmmu/device_tree.c | 21 +++++++++++++++++++++
17
2 files changed, 30 insertions(+)
18
19
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/sysemu/device_tree.h
22
+++ b/include/sysemu/device_tree.h
23
@@ -XXX,XX +XXX,XX @@ int qemu_fdt_setprop_sized_cells_from_array(void *fdt,
24
qdt_tmp); \
25
})
26
27
+
28
+/**
29
+ * qemu_fdt_randomize_seeds:
30
+ * @fdt: device tree blob
31
+ *
32
+ * Re-randomize all "rng-seed" properties with new seeds.
33
+ */
34
+void qemu_fdt_randomize_seeds(void *fdt);
35
+
36
#define FDT_PCI_RANGE_RELOCATABLE 0x80000000
37
#define FDT_PCI_RANGE_PREFETCHABLE 0x40000000
38
#define FDT_PCI_RANGE_ALIASED 0x20000000
39
diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/softmmu/device_tree.c
42
+++ b/softmmu/device_tree.c
43
@@ -XXX,XX +XXX,XX @@
44
#include "qemu/option.h"
45
#include "qemu/bswap.h"
46
#include "qemu/cutils.h"
47
+#include "qemu/guest-random.h"
48
#include "sysemu/device_tree.h"
49
#include "hw/loader.h"
50
#include "hw/boards.h"
51
@@ -XXX,XX +XXX,XX @@ void hmp_dumpdtb(Monitor *mon, const QDict *qdict)
52
53
info_report("dtb dumped to %s", filename);
54
}
55
+
56
+void qemu_fdt_randomize_seeds(void *fdt)
57
+{
58
+ int noffset, poffset, len;
59
+ const char *name;
60
+ uint8_t *data;
61
+
62
+ for (noffset = fdt_next_node(fdt, 0, NULL);
63
+ noffset >= 0;
64
+ noffset = fdt_next_node(fdt, noffset, NULL)) {
65
+ for (poffset = fdt_first_property_offset(fdt, noffset);
66
+ poffset >= 0;
67
+ poffset = fdt_next_property_offset(fdt, poffset)) {
68
+ data = (uint8_t *)fdt_getprop_by_offset(fdt, poffset, &name, &len);
69
+ if (!data || strcmp(name, "rng-seed"))
70
+ continue;
71
+ qemu_guest_getrandom_nofail(data, len);
72
+ }
73
+ }
74
+}
75
--
76
2.25.1
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
armeb is missing from the target list in qemu-binfmt-conf.sh. Add it so
3
Snapshot loading is supposed to be deterministic, so we shouldn't
4
the handler for those binaries gets registered by the script.
4
re-randomize the various seeds used.
5
5
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
6
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
7
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
7
Message-id: 20221025004327.568476-4-Jason@zx2c4.com
8
Message-id: 20171220212308.12614-8-michael.weiser@gmx.de
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
scripts/qemu-binfmt-conf.sh | 2 +-
11
hw/i386/x86.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
13
14
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
14
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
15
index XXXXXXX..XXXXXXX 100755
15
index XXXXXXX..XXXXXXX 100644
16
--- a/scripts/qemu-binfmt-conf.sh
16
--- a/hw/i386/x86.c
17
+++ b/scripts/qemu-binfmt-conf.sh
17
+++ b/hw/i386/x86.c
18
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ void x86_load_linux(X86MachineState *x86ms,
19
# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390/HPPA
19
setup_data->type = cpu_to_le32(SETUP_RNG_SEED);
20
# program execution by the kernel
20
setup_data->len = cpu_to_le32(RNG_SEED_LENGTH);
21
21
qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH);
22
-qemu_target_list="i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le m68k \
22
- qemu_register_reset(reset_rng_seed, setup_data);
23
+qemu_target_list="i386 i486 alpha arm armeb sparc32plus ppc ppc64 ppc64le m68k \
23
+ qemu_register_reset_nosnapshotload(reset_rng_seed, setup_data);
24
mips mipsel mipsn32 mipsn32el mips64 mips64el \
24
fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_KERNEL_DATA, reset_rng_seed, NULL,
25
sh4 sh4eb s390x aarch64 aarch64_be hppa"
25
setup_data, kernel, kernel_size, true);
26
26
} else {
27
--
27
--
28
2.7.4
28
2.25.1
29
30
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Frame truncation length, TRUNC_FL, is determined by the contents of
3
When the system reboots, the rng-seed that the FDT has should be
4
ENET_FTRL register, so convert the code to use it instead of a
4
re-randomized, so that the new boot gets a new seed. Since the FDT is in
5
hardcoded constant.
5
the ROM region at this point, we add a hook right after the ROM has been
6
6
added, so that we have a pointer to that copy of the FDT.
7
To avoid the case where TRUNC_FL is greater that ENET_MAX_FRAME_SIZE,
8
increase the value of the latter to its theoretical maximum of 16K.
9
7
10
Cc: Peter Maydell <peter.maydell@linaro.org>
8
Cc: Peter Maydell <peter.maydell@linaro.org>
11
Cc: Jason Wang <jasowang@redhat.com>
12
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Cc: qemu-devel@nongnu.org
14
Cc: qemu-arm@nongnu.org
9
Cc: qemu-arm@nongnu.org
15
Cc: yurovsky@gmail.com
10
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
16
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
11
Message-id: 20221025004327.568476-5-Jason@zx2c4.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
14
---
20
include/hw/net/imx_fec.h | 3 ++-
15
hw/arm/boot.c | 2 ++
21
hw/net/imx_fec.c | 4 ++--
16
1 file changed, 2 insertions(+)
22
2 files changed, 4 insertions(+), 3 deletions(-)
23
17
24
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
18
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
25
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/net/imx_fec.h
20
--- a/hw/arm/boot.c
27
+++ b/include/hw/net/imx_fec.h
21
+++ b/hw/arm/boot.c
28
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
29
#define ENET_TCCR3 393
23
* the DTB is copied again upon reset, even if addr points into RAM.
30
#define ENET_MAX 400
24
*/
31
25
rom_add_blob_fixed_as("dtb", fdt, size, addr, as);
32
-#define ENET_MAX_FRAME_SIZE 2032
26
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
33
27
+ rom_ptr_for_as(as, addr, size));
34
/* EIR and EIMR */
28
35
#define ENET_INT_HB (1 << 31)
29
g_free(fdt);
36
@@ -XXX,XX +XXX,XX @@
37
#define ENET_RCR_NLC (1 << 30)
38
#define ENET_RCR_GRS (1 << 31)
39
40
+#define ENET_MAX_FRAME_SIZE (1 << ENET_RCR_MAX_FL_LENGTH)
41
+
42
/* TCR */
43
#define ENET_TCR_GTS (1 << 0)
44
#define ENET_TCR_FDEN (1 << 2)
45
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/net/imx_fec.c
48
+++ b/hw/net/imx_fec.c
49
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
50
crc_ptr = (uint8_t *) &crc;
51
52
/* Huge frames are truncted. */
53
- if (size > ENET_MAX_FRAME_SIZE) {
54
- size = ENET_MAX_FRAME_SIZE;
55
+ if (size > s->regs[ENET_FTRL]) {
56
+ size = s->regs[ENET_FTRL];
57
flags |= ENET_BD_TR | ENET_BD_LG;
58
}
59
30
60
--
31
--
61
2.7.4
32
2.25.1
62
63
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Give big-endian arm and aarch64 CPUs their own family in
3
When the system reboots, the rng-seed that the FDT has should be
4
qemu-binfmt-conf.sh to make sure we register qemu-user for binaries of
4
re-randomized, so that the new boot gets a new seed. Since the FDT is in
5
the opposite endianness on arm and aarch64. Apart from the family
5
the ROM region at this point, we add a hook right after the ROM has been
6
assignments of the magic values, qemu_get_family() needs to be able to
6
added, so that we have a pointer to that copy of the FDT.
7
distinguish the two and recognise aarch64{,_be} as well.
8
7
9
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
8
Cc: Palmer Dabbelt <palmer@dabbelt.com>
10
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
9
Cc: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 20171220212308.12614-7-michael.weiser@gmx.de
10
Cc: Bin Meng <bin.meng@windriver.com>
11
Cc: qemu-riscv@nongnu.org
12
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-id: 20221025004327.568476-6-Jason@zx2c4.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
16
---
14
scripts/qemu-binfmt-conf.sh | 9 ++++++---
17
hw/riscv/boot.c | 3 +++
15
1 file changed, 6 insertions(+), 3 deletions(-)
18
1 file changed, 3 insertions(+)
16
19
17
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
20
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
18
index XXXXXXX..XXXXXXX 100755
21
index XXXXXXX..XXXXXXX 100644
19
--- a/scripts/qemu-binfmt-conf.sh
22
--- a/hw/riscv/boot.c
20
+++ b/scripts/qemu-binfmt-conf.sh
23
+++ b/hw/riscv/boot.c
21
@@ -XXX,XX +XXX,XX @@ arm_family=arm
24
@@ -XXX,XX +XXX,XX @@
22
25
#include "sysemu/device_tree.h"
23
armeb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28'
26
#include "sysemu/qtest.h"
24
armeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
27
#include "sysemu/kvm.h"
25
-armeb_family=arm
28
+#include "sysemu/reset.h"
26
+armeb_family=armeb
29
27
30
#include <libfdt.h>
28
sparc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'
31
29
sparc_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
32
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
30
@@ -XXX,XX +XXX,XX @@ aarch64_family=arm
33
31
34
rom_add_blob_fixed_as("fdt", fdt, fdtsize, fdt_addr,
32
aarch64_be_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7'
35
&address_space_memory);
33
aarch64_be_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
36
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
34
-aarch64_be_family=arm
37
+ rom_ptr_for_as(&address_space_memory, fdt_addr, fdtsize));
35
+aarch64_be_family=armeb
38
36
39
return fdt_addr;
37
hppa_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f'
40
}
38
hppa_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
39
@@ -XXX,XX +XXX,XX @@ qemu_get_family() {
40
ppc64el|ppc64le)
41
echo "ppcle"
42
;;
43
- arm|armel|armhf|arm64|armv[4-9]*)
44
+ arm|armel|armhf|arm64|armv[4-9]*l|aarch64)
45
echo "arm"
46
;;
47
+ armeb|armv[4-9]*b|aarch64_be)
48
+ echo "armeb"
49
+ ;;
50
sparc*)
51
echo "sparc"
52
;;
53
--
41
--
54
2.7.4
42
2.25.1
55
56
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Snapshot loading is supposed to be deterministic, so we shouldn't
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
re-randomize the various seeds used.
5
Message-id: 20180104000156.30932-1-f4bug@amsat.org
5
6
[PMM: add missing include]
6
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
7
Message-id: 20221025004327.568476-7-Jason@zx2c4.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
hw/sd/pxa2xx_mmci.c | 78 ++++++++++++++++++++++++++++++++++-------------------
11
hw/m68k/virt.c | 20 +++++++++++---------
10
hw/sd/trace-events | 4 +++
12
1 file changed, 11 insertions(+), 9 deletions(-)
11
2 files changed, 54 insertions(+), 28 deletions(-)
12
13
13
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
14
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/sd/pxa2xx_mmci.c
16
--- a/hw/m68k/virt.c
16
+++ b/hw/sd/pxa2xx_mmci.c
17
+++ b/hw/m68k/virt.c
17
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ typedef struct {
18
#include "hw/qdev.h"
19
M68kCPU *cpu;
19
#include "hw/qdev-properties.h"
20
hwaddr initial_pc;
20
#include "qemu/error-report.h"
21
hwaddr initial_stack;
21
+#include "qemu/log.h"
22
- struct bi_record *rng_seed;
22
+#include "trace.h"
23
} ResetInfo;
23
24
24
#define TYPE_PXA2XX_MMCI "pxa2xx-mmci"
25
static void main_cpu_reset(void *opaque)
25
#define PXA2XX_MMCI(obj) OBJECT_CHECK(PXA2xxMMCIState, (obj), TYPE_PXA2XX_MMCI)
26
@@ -XXX,XX +XXX,XX @@ static void main_cpu_reset(void *opaque)
26
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_wakequeues(PXA2xxMMCIState *s)
27
M68kCPU *cpu = reset_info->cpu;
27
static uint64_t pxa2xx_mmci_read(void *opaque, hwaddr offset, unsigned size)
28
CPUState *cs = CPU(cpu);
29
30
- if (reset_info->rng_seed) {
31
- qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2,
32
- be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data));
33
- }
34
-
35
cpu_reset(cs);
36
cpu->env.aregs[7] = reset_info->initial_stack;
37
cpu->env.pc = reset_info->initial_pc;
38
}
39
40
+static void rerandomize_rng_seed(void *opaque)
41
+{
42
+ struct bi_record *rng_seed = opaque;
43
+ qemu_guest_getrandom_nofail((void *)rng_seed->data + 2,
44
+ be16_to_cpu(*(uint16_t *)rng_seed->data));
45
+}
46
+
47
static void virt_init(MachineState *machine)
28
{
48
{
29
PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
49
M68kCPU *cpu = NULL;
30
- uint32_t ret;
50
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
31
+ uint32_t ret = 0;
51
BOOTINFO0(param_ptr, BI_LAST);
32
52
rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob,
33
switch (offset) {
53
parameters_base, cs->as);
34
case MMC_STRPCL:
54
- reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base,
35
- return 0;
55
- param_ptr - param_blob) +
36
+ break;
56
- (param_rng_seed - param_blob);
37
case MMC_STAT:
57
+ qemu_register_reset_nosnapshotload(rerandomize_rng_seed,
38
- return s->status;
58
+ rom_ptr_for_as(cs->as, parameters_base,
39
+ ret = s->status;
59
+ param_ptr - param_blob) +
40
+ break;
60
+ (param_rng_seed - param_blob));
41
case MMC_CLKRT:
61
g_free(param_blob);
42
- return s->clkrt;
43
+ ret = s->clkrt;
44
+ break;
45
case MMC_SPI:
46
- return s->spi;
47
+ ret = s->spi;
48
+ break;
49
case MMC_CMDAT:
50
- return s->cmdat;
51
+ ret = s->cmdat;
52
+ break;
53
case MMC_RESTO:
54
- return s->resp_tout;
55
+ ret = s->resp_tout;
56
+ break;
57
case MMC_RDTO:
58
- return s->read_tout;
59
+ ret = s->read_tout;
60
+ break;
61
case MMC_BLKLEN:
62
- return s->blklen;
63
+ ret = s->blklen;
64
+ break;
65
case MMC_NUMBLK:
66
- return s->numblk;
67
+ ret = s->numblk;
68
+ break;
69
case MMC_PRTBUF:
70
- return 0;
71
+ break;
72
case MMC_I_MASK:
73
- return s->intmask;
74
+ ret = s->intmask;
75
+ break;
76
case MMC_I_REG:
77
- return s->intreq;
78
+ ret = s->intreq;
79
+ break;
80
case MMC_CMD:
81
- return s->cmd | 0x40;
82
+ ret = s->cmd | 0x40;
83
+ break;
84
case MMC_ARGH:
85
- return s->arg >> 16;
86
+ ret = s->arg >> 16;
87
+ break;
88
case MMC_ARGL:
89
- return s->arg & 0xffff;
90
+ ret = s->arg & 0xffff;
91
+ break;
92
case MMC_RES:
93
- if (s->resp_len < 9)
94
- return s->resp_fifo[s->resp_len ++];
95
- return 0;
96
+ ret = (s->resp_len < 9) ? s->resp_fifo[s->resp_len++] : 0;
97
+ break;
98
case MMC_RXFIFO:
99
- ret = 0;
100
while (size-- && s->rx_len) {
101
ret |= s->rx_fifo[s->rx_start++] << (size << 3);
102
s->rx_start &= 0x1f;
103
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_mmci_read(void *opaque, hwaddr offset, unsigned size)
104
}
105
s->intreq &= ~INT_RXFIFO_REQ;
106
pxa2xx_mmci_fifo_update(s);
107
- return ret;
108
+ break;
109
case MMC_RDWAIT:
110
- return 0;
111
+ break;
112
case MMC_BLKS_REM:
113
- return s->numblk;
114
+ ret = s->numblk;
115
+ break;
116
default:
117
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
118
+ qemu_log_mask(LOG_GUEST_ERROR,
119
+ "%s: incorrect register 0x%02" HWADDR_PRIx "\n",
120
+ __func__, offset);
121
}
122
+ trace_pxa2xx_mmci_read(size, offset, ret);
123
124
- return 0;
125
+ return ret;
126
}
127
128
static void pxa2xx_mmci_write(void *opaque,
129
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_write(void *opaque,
130
{
131
PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
132
133
+ trace_pxa2xx_mmci_write(size, offset, value);
134
switch (offset) {
135
case MMC_STRPCL:
136
if (value & STRPCL_STRT_CLK) {
137
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_write(void *opaque,
138
139
case MMC_SPI:
140
s->spi = value & 0xf;
141
- if (value & SPI_SPI_MODE)
142
- printf("%s: attempted to use card in SPI mode\n", __FUNCTION__);
143
+ if (value & SPI_SPI_MODE) {
144
+ qemu_log_mask(LOG_GUEST_ERROR,
145
+ "%s: attempted to use card in SPI mode\n", __func__);
146
+ }
147
break;
148
149
case MMC_CMDAT:
150
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_write(void *opaque,
151
break;
152
153
default:
154
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
155
+ qemu_log_mask(LOG_GUEST_ERROR,
156
+ "%s: incorrect reg 0x%02" HWADDR_PRIx " "
157
+ "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
158
}
62
}
159
}
63
}
160
161
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
162
index XXXXXXX..XXXXXXX 100644
163
--- a/hw/sd/trace-events
164
+++ b/hw/sd/trace-events
165
@@ -XXX,XX +XXX,XX @@
166
# hw/sd/milkymist-memcard.c
167
milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
168
milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
169
+
170
+# hw/sd/pxa2xx_mmci.c
171
+pxa2xx_mmci_read(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"
172
+pxa2xx_mmci_write(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"
173
--
64
--
174
2.7.4
65
2.25.1
175
176
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Binding to a particular netdev doesn't seem to belong to this layer
3
Snapshot loading is supposed to be deterministic, so we shouldn't
4
and should probably be done as a part of board or SoC specific code.
4
re-randomize the various seeds used.
5
5
6
Convert all of the users of this IP block to use
6
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
7
qdev_set_nic_properties() instead.
7
Message-id: 20221025004327.568476-8-Jason@zx2c4.com
8
9
Cc: Peter Maydell <peter.maydell@linaro.org>
10
Cc: Jason Wang <jasowang@redhat.com>
11
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Cc: qemu-devel@nongnu.org
13
Cc: qemu-arm@nongnu.org
14
Cc: yurovsky@gmail.com
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
10
---
19
hw/arm/fsl-imx6.c | 1 +
11
hw/m68k/q800.c | 33 +++++++++++++--------------------
20
hw/net/imx_fec.c | 2 --
12
1 file changed, 13 insertions(+), 20 deletions(-)
21
2 files changed, 1 insertion(+), 2 deletions(-)
22
13
23
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
14
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/fsl-imx6.c
16
--- a/hw/m68k/q800.c
26
+++ b/hw/arm/fsl-imx6.c
17
+++ b/hw/m68k/q800.c
27
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ static const TypeInfo glue_info = {
28
spi_table[i].irq));
19
},
20
};
21
22
-typedef struct {
23
- M68kCPU *cpu;
24
- struct bi_record *rng_seed;
25
-} ResetInfo;
26
-
27
static void main_cpu_reset(void *opaque)
28
{
29
- ResetInfo *reset_info = opaque;
30
- M68kCPU *cpu = reset_info->cpu;
31
+ M68kCPU *cpu = opaque;
32
CPUState *cs = CPU(cpu);
33
34
- if (reset_info->rng_seed) {
35
- qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2,
36
- be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data));
37
- }
38
-
39
cpu_reset(cs);
40
cpu->env.aregs[7] = ldl_phys(cs->as, 0);
41
cpu->env.pc = ldl_phys(cs->as, 4);
42
}
43
44
+static void rerandomize_rng_seed(void *opaque)
45
+{
46
+ struct bi_record *rng_seed = opaque;
47
+ qemu_guest_getrandom_nofail((void *)rng_seed->data + 2,
48
+ be16_to_cpu(*(uint16_t *)rng_seed->data));
49
+}
50
+
51
static uint8_t fake_mac_rom[] = {
52
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
53
54
@@ -XXX,XX +XXX,XX @@ static void q800_init(MachineState *machine)
55
NubusBus *nubus;
56
DeviceState *glue;
57
DriveInfo *dinfo;
58
- ResetInfo *reset_info;
59
uint8_t rng_seed[32];
60
61
linux_boot = (kernel_filename != NULL);
62
@@ -XXX,XX +XXX,XX @@ static void q800_init(MachineState *machine)
63
exit(1);
29
}
64
}
30
65
31
+ qdev_set_nic_properties(DEVICE(&s->eth), &nd_table[0]);
66
- reset_info = g_new0(ResetInfo, 1);
32
object_property_set_bool(OBJECT(&s->eth), true, "realized", &err);
33
if (err) {
34
error_propagate(errp, err);
35
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/net/imx_fec.c
38
+++ b/hw/net/imx_fec.c
39
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
40
41
qemu_macaddr_default_if_unset(&s->conf.macaddr);
42
43
- s->conf.peers.ncs[0] = nd_table[0].netdev;
44
-
67
-
45
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
68
/* init CPUs */
46
object_get_typename(OBJECT(dev)),
69
cpu = M68K_CPU(cpu_create(machine->cpu_type));
47
DEVICE(dev)->id, s);
70
- reset_info->cpu = cpu;
71
- qemu_register_reset(main_cpu_reset, reset_info);
72
+ qemu_register_reset(main_cpu_reset, cpu);
73
74
/* RAM */
75
memory_region_add_subregion(get_system_memory(), 0, machine->ram);
76
@@ -XXX,XX +XXX,XX @@ static void q800_init(MachineState *machine)
77
BOOTINFO0(param_ptr, BI_LAST);
78
rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob,
79
parameters_base, cs->as);
80
- reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base,
81
- param_ptr - param_blob) +
82
- (param_rng_seed - param_blob);
83
+ qemu_register_reset_nosnapshotload(rerandomize_rng_seed,
84
+ rom_ptr_for_as(cs->as, parameters_base,
85
+ param_ptr - param_blob) +
86
+ (param_rng_seed - param_blob));
87
g_free(param_blob);
88
} else {
89
uint8_t *ptr;
48
--
90
--
49
2.7.4
91
2.25.1
50
51
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
When the system reboots, the rng-seed that the FDT has should be
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
re-randomized, so that the new boot gets a new seed. Since the FDT is in
5
Message-id: 20180103224208.30291-2-f4bug@amsat.org
5
the ROM region at this point, we add a hook right after the ROM has been
6
added, so that we have a pointer to that copy of the FDT.
7
8
Cc: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>
9
Cc: Paul Burton <paulburton@kernel.org>
10
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
12
Message-id: 20221025004327.568476-9-Jason@zx2c4.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
15
---
8
hw/timer/pxa2xx_timer.c | 17 +++++++++++++++--
16
hw/mips/boston.c | 3 +++
9
1 file changed, 15 insertions(+), 2 deletions(-)
17
1 file changed, 3 insertions(+)
10
18
11
diff --git a/hw/timer/pxa2xx_timer.c b/hw/timer/pxa2xx_timer.c
19
diff --git a/hw/mips/boston.c b/hw/mips/boston.c
12
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/timer/pxa2xx_timer.c
21
--- a/hw/mips/boston.c
14
+++ b/hw/timer/pxa2xx_timer.c
22
+++ b/hw/mips/boston.c
15
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
16
#include "sysemu/sysemu.h"
24
#include "sysemu/sysemu.h"
17
#include "hw/arm/pxa.h"
25
#include "sysemu/qtest.h"
18
#include "hw/sysbus.h"
26
#include "sysemu/runstate.h"
19
+#include "qemu/log.h"
27
+#include "sysemu/reset.h"
20
28
21
#define OSMR0    0x00
29
#include <libfdt.h>
22
#define OSMR1    0x04
30
#include "qom/object.h"
23
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
31
@@ -XXX,XX +XXX,XX @@ static void boston_mach_init(MachineState *machine)
24
case OSNR:
32
/* Calculate real fdt size after filter */
25
return s->snapshot;
33
dt_size = fdt_totalsize(dtb_load_data);
26
default:
34
rom_add_blob_fixed("dtb", dtb_load_data, dt_size, dtb_paddr);
27
+ qemu_log_mask(LOG_UNIMP,
35
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
28
+ "%s: unknown register 0x%02" HWADDR_PRIx "\n",
36
+ rom_ptr(dtb_paddr, dt_size));
29
+ __func__, offset);
37
} else {
30
+ break;
38
/* Try to load file as FIT */
31
badreg:
39
fit_err = load_fit(&boston_fit_loader, machine->kernel_filename, s);
32
- hw_error("pxa2xx_timer_read: Bad offset " REG_FMT "\n", offset);
33
+ qemu_log_mask(LOG_GUEST_ERROR,
34
+ "%s: incorrect register 0x%02" HWADDR_PRIx "\n",
35
+ __func__, offset);
36
}
37
38
return 0;
39
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
40
}
41
break;
42
default:
43
+ qemu_log_mask(LOG_UNIMP,
44
+ "%s: unknown register 0x%02" HWADDR_PRIx " "
45
+ "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
46
+ break;
47
badreg:
48
- hw_error("pxa2xx_timer_write: Bad offset " REG_FMT "\n", offset);
49
+ qemu_log_mask(LOG_GUEST_ERROR,
50
+ "%s: incorrect register 0x%02" HWADDR_PRIx " "
51
+ "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
52
}
53
}
54
55
--
40
--
56
2.7.4
41
2.25.1
57
42
58
43
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Add target aarch64_be-linux-user. This allows a qemu-aarch64_be binary
3
When the system reboots, the rng-seed that the FDT has should be
4
to be built that will run big-endian aarch64 binaries.
4
re-randomized, so that the new boot gets a new seed. Since the FDT is in
5
the ROM region at this point, we add a hook right after the ROM has been
6
added, so that we have a pointer to that copy of the FDT.
5
7
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
8
Cc: Stafford Horne <shorne@gmail.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
8
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
10
Message-id: 20221025004327.568476-11-Jason@zx2c4.com
9
Message-id: 20171220212308.12614-5-michael.weiser@gmx.de
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
configure | 5 +++--
14
hw/openrisc/boot.c | 3 +++
13
default-configs/aarch64_be-linux-user.mak | 1 +
15
1 file changed, 3 insertions(+)
14
2 files changed, 4 insertions(+), 2 deletions(-)
15
create mode 100644 default-configs/aarch64_be-linux-user.mak
16
16
17
diff --git a/configure b/configure
17
diff --git a/hw/openrisc/boot.c b/hw/openrisc/boot.c
18
index XXXXXXX..XXXXXXX 100755
18
index XXXXXXX..XXXXXXX 100644
19
--- a/configure
19
--- a/hw/openrisc/boot.c
20
+++ b/configure
20
+++ b/hw/openrisc/boot.c
21
@@ -XXX,XX +XXX,XX @@ target_name=$(echo $target | cut -d '-' -f 1)
21
@@ -XXX,XX +XXX,XX @@
22
target_bigendian="no"
22
#include "hw/openrisc/boot.h"
23
23
#include "sysemu/device_tree.h"
24
case "$target_name" in
24
#include "sysemu/qtest.h"
25
- armeb|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
25
+#include "sysemu/reset.h"
26
+ armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
26
27
target_bigendian=yes
27
#include <libfdt.h>
28
;;
28
29
esac
29
@@ -XXX,XX +XXX,XX @@ uint32_t openrisc_load_fdt(void *fdt, hwaddr load_start,
30
@@ -XXX,XX +XXX,XX @@ case "$target_name" in
30
31
mttcg="yes"
31
rom_add_blob_fixed_as("fdt", fdt, fdtsize, fdt_addr,
32
gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
32
&address_space_memory);
33
;;
33
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
34
- aarch64)
34
+ rom_ptr_for_as(&address_space_memory, fdt_addr, fdtsize));
35
+ aarch64|aarch64_be)
35
36
+ TARGET_ARCH=aarch64
36
return fdt_addr;
37
TARGET_BASE_ARCH=arm
37
}
38
bflt="yes"
39
mttcg="yes"
40
diff --git a/default-configs/aarch64_be-linux-user.mak b/default-configs/aarch64_be-linux-user.mak
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/default-configs/aarch64_be-linux-user.mak
45
@@ -0,0 +1 @@
46
+# Default configuration for aarch64_be-linux-user
47
--
38
--
48
2.7.4
39
2.25.1
49
50
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
2
2
3
Since for aarch64 the signal trampoline is synthesized directly into the
3
When the system reboots, the rng-seed that the FDT has should be
4
signal frame we need to make sure the instructions end up little-endian.
4
re-randomized, so that the new boot gets a new seed. Since the FDT is in
5
Otherwise the wrong endianness will cause a SIGILL upon return from the
5
the ROM region at this point, we add a hook right after the ROM has been
6
signal handler on big-endian targets.
6
added, so that we have a pointer to that copy of the FDT.
7
7
8
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
8
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
10
Message-id: 20171220212308.12614-4-michael.weiser@gmx.de
10
Message-id: 20221025004327.568476-12-Jason@zx2c4.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
linux-user/signal.c | 10 +++++++---
14
hw/rx/rx-gdbsim.c | 3 +++
14
1 file changed, 7 insertions(+), 3 deletions(-)
15
1 file changed, 3 insertions(+)
15
16
16
diff --git a/linux-user/signal.c b/linux-user/signal.c
17
diff --git a/hw/rx/rx-gdbsim.c b/hw/rx/rx-gdbsim.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/linux-user/signal.c
19
--- a/hw/rx/rx-gdbsim.c
19
+++ b/linux-user/signal.c
20
+++ b/hw/rx/rx-gdbsim.c
20
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
21
@@ -XXX,XX +XXX,XX @@
21
if (ka->sa_flags & TARGET_SA_RESTORER) {
22
#include "hw/rx/rx62n.h"
22
return_addr = ka->sa_restorer;
23
#include "sysemu/qtest.h"
23
} else {
24
#include "sysemu/device_tree.h"
24
- /* mov x8,#__NR_rt_sigreturn; svc #0 */
25
+#include "sysemu/reset.h"
25
- __put_user(0xd2801168, &frame->tramp[0]);
26
#include "hw/boards.h"
26
- __put_user(0xd4000001, &frame->tramp[1]);
27
#include "qom/object.h"
27
+ /*
28
28
+ * mov x8,#__NR_rt_sigreturn; svc #0
29
@@ -XXX,XX +XXX,XX @@ static void rx_gdbsim_init(MachineState *machine)
29
+ * Since these are instructions they need to be put as little-endian
30
dtb_offset = ROUND_DOWN(machine->ram_size - dtb_size, 16);
30
+ * regardless of target default or current CPU endianness.
31
rom_add_blob_fixed("dtb", dtb, dtb_size,
31
+ */
32
SDRAM_BASE + dtb_offset);
32
+ __put_user_e(0xd2801168, &frame->tramp[0], le);
33
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
33
+ __put_user_e(0xd4000001, &frame->tramp[1], le);
34
+ rom_ptr(SDRAM_BASE + dtb_offset, dtb_size));
34
return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
35
/* Set dtb address to R1 */
35
}
36
RX_CPU(first_cpu)->env.regs[1] = SDRAM_BASE + dtb_offset;
36
env->xregs[0] = usig;
37
}
37
--
38
--
38
2.7.4
39
2.25.1
39
40
diff view generated by jsdifflib