Skip to content

Commit d6dfd8d

Browse files
committed
Merge tag 'pull-target-arm-20250926' of https://gitlab.com/pm215/qemu into staging
target-arm queue: * reimplement VHE alias register handling * replace magic GIC values by proper definitions * convert power control DPRINTF() uses to trace events * better reset related tracepoints * implement ID_AA64PFR2_EL1 * hw/usb/hcd-uhci: don't assert for SETUP to non-0 endpoint * net/passt: Fix build failure due to missing GIO dependency # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmjWnkUZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3upeD/4x0k6ciiJ2wRE1PFUA2KHZ # bS12+j6Um5BNdcZtRV1aT3x3xOrW3X0JTcmhb9/UdpEPki/krQQgQX50tOiLCeU2 # U4lZke5160Gk3ThdkpELlQDnCVDuNR0wxYgy1GBgAInCa/T/qFnyWwaWBIooCCUh # +UMJ9tP4XWKvKlkzw9ONFYChxerY2enpOewEbnfSU4NPg9pU8OEZ3yeFWaLZ3Tnl # 0bei/iFFeuN8RtgJEkuqWI6oENEZZbxGtJ+J/+wvggAfOzfy0I6CmW6y9tQMmKe8 # fTnCQ837uHmlRPWQ615M2wWydbJ1ffdEIYDb5U6UsbfG8sMt5+qg38yo0AyDs6RK # qJkTceuhqFTDIoi92o2+NFnohCTfASeYaCHjODgcdjGUtbZO7LZ31fOKQrdsHc5e # chAOnzNxCu9Bt4UqpUmb+ED0fXWDahV1tmgazFS2LORYxnr2q+/WJEdwSgHXNzVy # 2rdyUx7v7U1finhRE1nAdy8XwJTCQ3gDwDbPGBrH9mhR9DnK6eotFCljI2XnDtAE # f1i0w/47cnyRW6KsBVK6dJObiOfBRrRYqe3Rt4nA4xjeCNmWcr5IcytpnL/2YT1p # 1vj+RklbcK7Ns+kWH3H2a9b44zKQrtGGXf8fcNyAqT1YrzrrLUqaiKTfesGfjWit # ekMWOulOe6UePnoC3SJHFw== # =+Aj+ # -----END PGP SIGNATURE----- # gpg: Signature made Fri 26 Sep 2025 07:08:05 AM PDT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [unknown] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [unknown] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [unknown] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [unknown] # gpg: WARNING: The key's User ID is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * tag 'pull-target-arm-20250926' of https://gitlab.com/pm215/qemu: (44 commits) target/arm: Implement ID_AA64PFR2_EL1 target/arm: Move ID register field defs to cpu-features.h target/arm: Trace vCPU reset call target/arm: Trace emulated firmware reset call target/arm: Convert power control DPRINTF() uses to trace events target/arm: Replace magic GIC values by proper definitions target/arm: Remove define_arm_vh_e2h_redirects_aliases target/arm: Rename some cpreg to their aarch64 names target/arm: Redirect VHE FOO_EL12 to FOO_EL1 during translation target/arm: Redirect VHE FOO_EL1 -> FOO_EL2 during translation target/arm: Split out redirect_cpreg target/arm: Rename TBFLAG_A64_NV2_MEM_E20 with *_E2H target/arm: Move endianness fixup for 32-bit registers target/arm: Move writeback of CP_ANY fields target/arm: Move alias setting for wildcards target/arm: Remove name argument to alloc_cpreg target/arm: Hoist the allocation of ARMCPRegInfo target/arm: Split out alloc_cpreg target/arm: Add key parameter to add_cpreg_to_hashtable target/arm: Move cpreg elimination to define_one_arm_cp_reg ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2 parents d08b8be + b71e2b2 commit d6dfd8d

File tree

21 files changed

+1199
-1236
lines changed

21 files changed

+1199
-1236
lines changed

hw/intc/arm_gicv3_cpuif.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3037,15 +3037,7 @@ void gicv3_init_cpuif(GICv3State *s)
30373037
* cpu->gic_pribits
30383038
*/
30393039

3040-
/* Note that we can't just use the GICv3CPUState as an opaque pointer
3041-
* in define_arm_cp_regs_with_opaque(), because when we're called back
3042-
* it might be with code translated by CPU 0 but run by CPU 1, in
3043-
* which case we'd get the wrong value.
3044-
* So instead we define the regs with no ri->opaque info, and
3045-
* get back to the GICv3CPUState from the CPUARMState.
3046-
*
3047-
* These CP regs callbacks can be called from either TCG or HVF code.
3048-
*/
3040+
/* These CP regs callbacks can be called from either TCG or HVF. */
30493041
define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
30503042

30513043
/*

hw/usb/hcd-uhci.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,7 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
735735
bool spd;
736736
bool queuing = (q != NULL);
737737
uint8_t pid = td->token & 0xff;
738+
uint8_t ep_id = (td->token >> 15) & 0xf;
738739
UHCIAsync *async;
739740

740741
async = uhci_async_find_td(s, td_addr);
@@ -778,9 +779,14 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
778779

779780
switch (pid) {
780781
case USB_TOKEN_OUT:
781-
case USB_TOKEN_SETUP:
782782
case USB_TOKEN_IN:
783783
break;
784+
case USB_TOKEN_SETUP:
785+
/* SETUP is only valid to endpoint 0 */
786+
if (ep_id == 0) {
787+
break;
788+
}
789+
/* fallthrough */
784790
default:
785791
/* invalid pid : frame interrupted */
786792
s->status |= UHCI_STS_HCPERR;
@@ -829,7 +835,7 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
829835
return uhci_handle_td_error(s, td, td_addr, USB_RET_NODEV,
830836
int_mask);
831837
}
832-
ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf);
838+
ep = usb_ep_get(dev, pid, ep_id);
833839
q = uhci_queue_new(s, qh_addr, td, ep);
834840
}
835841
async = uhci_async_alloc(q, td_addr);

linux-user/arm/target_proc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#ifndef ARM_TARGET_PROC_H
77
#define ARM_TARGET_PROC_H
88

9+
#include "target/arm/cpu-features.h" /* for MIDR_EL1 field definitions */
10+
911
static int open_cpuinfo(CPUArchState *cpu_env, int fd)
1012
{
1113
ARMCPU *cpu = env_archcpu(cpu_env);

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,7 @@ endif
12801280

12811281
enable_passt = get_option('passt') \
12821282
.require(host_os == 'linux', error_message: 'passt is supported only on Linux') \
1283+
.require(gio.found(), error_message: 'passt requires gio') \
12831284
.allowed()
12841285

12851286
vde = not_found

target/arm/arm-powerctl.c

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,12 @@
1717
#include "qemu/main-loop.h"
1818
#include "system/tcg.h"
1919
#include "target/arm/multiprocessing.h"
20-
21-
#ifndef DEBUG_ARM_POWERCTL
22-
#define DEBUG_ARM_POWERCTL 0
23-
#endif
24-
25-
#define DPRINTF(fmt, args...) \
26-
do { \
27-
if (DEBUG_ARM_POWERCTL) { \
28-
fprintf(stderr, "[ARM]%s: " fmt , __func__, ##args); \
29-
} \
30-
} while (0)
20+
#include "trace.h"
3121

3222
CPUState *arm_get_cpu_by_id(uint64_t id)
3323
{
3424
CPUState *cpu;
3525

36-
DPRINTF("cpu %" PRId64 "\n", id);
37-
3826
CPU_FOREACH(cpu) {
3927
ARMCPU *armcpu = ARM_CPU(cpu);
4028

@@ -102,9 +90,9 @@ int arm_set_cpu_on(uint64_t cpuid, uint64_t entry, uint64_t context_id,
10290

10391
assert(bql_locked());
10492

105-
DPRINTF("cpu %" PRId64 " (EL %d, %s) @ 0x%" PRIx64 " with R0 = 0x%" PRIx64
106-
"\n", cpuid, target_el, target_aa64 ? "aarch64" : "aarch32", entry,
107-
context_id);
93+
trace_arm_powerctl_set_cpu_on(cpuid, target_el,
94+
target_aa64 ? "aarch64" : "aarch32",
95+
entry, context_id);
10896

10997
/* requested EL level need to be in the 1 to 3 range */
11098
assert((target_el > 0) && (target_el < 4));
@@ -208,6 +196,8 @@ int arm_set_cpu_on_and_reset(uint64_t cpuid)
208196

209197
assert(bql_locked());
210198

199+
trace_arm_powerctl_set_cpu_on_and_reset(cpuid);
200+
211201
/* Retrieve the cpu we are powering up */
212202
target_cpu_state = arm_get_cpu_by_id(cpuid);
213203
if (!target_cpu_state) {
@@ -261,7 +251,7 @@ int arm_set_cpu_off(uint64_t cpuid)
261251

262252
assert(bql_locked());
263253

264-
DPRINTF("cpu %" PRId64 "\n", cpuid);
254+
trace_arm_powerctl_set_cpu_off(cpuid);
265255

266256
/* change to the cpu we are powering up */
267257
target_cpu_state = arm_get_cpu_by_id(cpuid);
@@ -297,7 +287,7 @@ int arm_reset_cpu(uint64_t cpuid)
297287

298288
assert(bql_locked());
299289

300-
DPRINTF("cpu %" PRId64 "\n", cpuid);
290+
trace_arm_powerctl_set_cpu_off(cpuid);
301291

302292
/* change to the cpu we are resetting */
303293
target_cpu_state = arm_get_cpu_by_id(cpuid);

target/arm/cpregs.h

Lines changed: 45 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#define TARGET_ARM_CPREGS_H
2323

2424
#include "hw/registerfields.h"
25+
#include "exec/memop.h"
2526
#include "target/arm/kvm-consts.h"
2627
#include "cpu.h"
2728

@@ -174,16 +175,20 @@ enum {
174175
* add a bit to distinguish between secure and non-secure cpregs in the
175176
* hashtable.
176177
*/
177-
#define CP_REG_NS_SHIFT 29
178-
#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
178+
#define CP_REG_AA32_NS_SHIFT 29
179+
#define CP_REG_AA32_NS_MASK (1 << CP_REG_AA32_NS_SHIFT)
180+
181+
/* Distinguish 32-bit and 64-bit views of AArch32 system registers. */
182+
#define CP_REG_AA32_64BIT_SHIFT 15
183+
#define CP_REG_AA32_64BIT_MASK (1 << CP_REG_AA32_64BIT_SHIFT)
179184

180185
#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
181-
((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \
182-
((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
186+
(((ns) << CP_REG_AA32_NS_SHIFT) | \
187+
((is64) << CP_REG_AA32_64BIT_SHIFT) | \
188+
((cp) << 16) | ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
183189

184-
#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
185-
(CP_REG_AA64_MASK | \
186-
((cp) << CP_REG_ARM_COPROC_SHIFT) | \
190+
#define ENCODE_AA64_CP_REG(op0, op1, crn, crm, op2) \
191+
(CP_REG_AA64_MASK | CP_REG_ARM64_SYSREG | \
187192
((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
188193
((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
189194
((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
@@ -201,14 +206,14 @@ static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
201206
cpregid |= CP_REG_AA64_MASK;
202207
} else {
203208
if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
204-
cpregid |= (1 << 15);
209+
cpregid |= CP_REG_AA32_64BIT_MASK;
205210
}
206211

207212
/*
208213
* KVM is always non-secure so add the NS flag on AArch32 register
209214
* entries.
210215
*/
211-
cpregid |= 1 << CP_REG_NS_SHIFT;
216+
cpregid |= CP_REG_AA32_NS_MASK;
212217
}
213218
return cpregid;
214219
}
@@ -225,8 +230,8 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
225230
kvmid = cpregid & ~CP_REG_AA64_MASK;
226231
kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64;
227232
} else {
228-
kvmid = cpregid & ~(1 << 15);
229-
if (cpregid & (1 << 15)) {
233+
kvmid = cpregid & ~CP_REG_AA32_64BIT_MASK;
234+
if (cpregid & CP_REG_AA32_64BIT_MASK) {
230235
kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
231236
} else {
232237
kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
@@ -866,15 +871,15 @@ typedef struct ARMCPRegInfo ARMCPRegInfo;
866871
* Access functions for coprocessor registers. These cannot fail and
867872
* may not raise exceptions.
868873
*/
869-
typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
870-
typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
874+
typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *ri);
875+
typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *ri,
871876
uint64_t value);
872877
/* Access permission check functions for coprocessor registers. */
873878
typedef CPAccessResult CPAccessFn(CPUARMState *env,
874-
const ARMCPRegInfo *opaque,
879+
const ARMCPRegInfo *ri,
875880
bool isread);
876881
/* Hook function for register reset */
877-
typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
882+
typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *ri);
878883

879884
#define CP_ANY 0xff
880885

@@ -932,11 +937,19 @@ struct ARMCPRegInfo {
932937
uint32_t nv2_redirect_offset;
933938

934939
/*
935-
* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
936-
* this register was defined: can be used to hand data through to the
937-
* register read/write functions, since they are passed the ARMCPRegInfo*.
940+
* With VHE, with E2H, at EL2, access to this EL0/EL1 reg redirects
941+
* to the EL2 reg with the specified key.
938942
*/
939-
void *opaque;
943+
uint32_t vhe_redir_to_el2;
944+
945+
/*
946+
* For VHE. Before registration, this field holds the key for an
947+
* EL02/EL12 reg to be created to point back to this EL0/EL1 reg.
948+
* After registration, this field is set only on the EL02/EL12 reg
949+
* and points back to the EL02/EL12 reg for redirection with E2H.
950+
*/
951+
uint32_t vhe_redir_to_el01;
952+
940953
/*
941954
* Value of this register, if it is ARM_CP_CONST. Otherwise, if
942955
* fieldoffset is non-zero, the reset value of the register.
@@ -1004,52 +1017,17 @@ struct ARMCPRegInfo {
10041017
* fieldoffset is 0 then no reset will be done.
10051018
*/
10061019
CPResetFn *resetfn;
1007-
1008-
/*
1009-
* "Original" readfn, writefn, accessfn.
1010-
* For ARMv8.1-VHE register aliases, we overwrite the read/write
1011-
* accessor functions of various EL1/EL0 to perform the runtime
1012-
* check for which sysreg should actually be modified, and then
1013-
* forwards the operation. Before overwriting the accessors,
1014-
* the original function is copied here, so that accesses that
1015-
* really do go to the EL1/EL0 version proceed normally.
1016-
* (The corresponding EL2 register is linked via opaque.)
1017-
*/
1018-
CPReadFn *orig_readfn;
1019-
CPWriteFn *orig_writefn;
1020-
CPAccessFn *orig_accessfn;
10211020
};
10221021

1023-
/*
1024-
* Macros which are lvalues for the field in CPUARMState for the
1025-
* ARMCPRegInfo *ri.
1026-
*/
1027-
#define CPREG_FIELD32(env, ri) \
1028-
(*(uint32_t *)((char *)(env) + (ri)->fieldoffset))
1029-
#define CPREG_FIELD64(env, ri) \
1030-
(*(uint64_t *)((char *)(env) + (ri)->fieldoffset))
1022+
void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs);
1023+
void define_arm_cp_regs_len(ARMCPU *cpu, const ARMCPRegInfo *regs, size_t len);
10311024

1032-
void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, const ARMCPRegInfo *reg,
1033-
void *opaque);
1034-
1035-
static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
1036-
{
1037-
define_one_arm_cp_reg_with_opaque(cpu, regs, NULL);
1038-
}
1039-
1040-
void define_arm_cp_regs_with_opaque_len(ARMCPU *cpu, const ARMCPRegInfo *regs,
1041-
void *opaque, size_t len);
1042-
1043-
#define define_arm_cp_regs_with_opaque(CPU, REGS, OPAQUE) \
1044-
do { \
1045-
QEMU_BUILD_BUG_ON(ARRAY_SIZE(REGS) == 0); \
1046-
define_arm_cp_regs_with_opaque_len(CPU, REGS, OPAQUE, \
1047-
ARRAY_SIZE(REGS)); \
1025+
#define define_arm_cp_regs(CPU, REGS) \
1026+
do { \
1027+
QEMU_BUILD_BUG_ON(ARRAY_SIZE(REGS) == 0); \
1028+
define_arm_cp_regs_len(CPU, REGS, ARRAY_SIZE(REGS)); \
10481029
} while (0)
10491030

1050-
#define define_arm_cp_regs(CPU, REGS) \
1051-
define_arm_cp_regs_with_opaque(CPU, REGS, NULL)
1052-
10531031
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
10541032

10551033
/*
@@ -1100,15 +1078,16 @@ void raw_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value);
11001078
* CPResetFn that does nothing, for use if no reset is required even
11011079
* if fieldoffset is non zero.
11021080
*/
1103-
void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
1081+
void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *ri);
11041082

11051083
/*
1106-
* Return true if this reginfo struct's field in the cpu state struct
1107-
* is 64 bits wide.
1084+
* Return MO_32 if the field in CPUARMState is uint32_t or
1085+
* MO_64 if the field in CPUARMState is uint64_t.
11081086
*/
1109-
static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri)
1087+
static inline MemOp cpreg_field_type(const ARMCPRegInfo *ri)
11101088
{
1111-
return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT);
1089+
return (ri->state == ARM_CP_STATE_AA64 || (ri->type & ARM_CP_64BIT)
1090+
? MO_64 : MO_32);
11121091
}
11131092

11141093
static inline bool cp_access_ok(int current_el,
@@ -1168,7 +1147,7 @@ static inline bool arm_cpreg_traps_in_nv(const ARMCPRegInfo *ri)
11681147
* means that the right set of registers is exactly those where
11691148
* the opc1 field is 4 or 5. (You can see this also in the assert
11701149
* we do that the opc1 field and the permissions mask line up in
1171-
* define_one_arm_cp_reg_with_opaque().)
1150+
* define_one_arm_cp_reg().)
11721151
* Checking the opc1 field is easier for us and avoids the problem
11731152
* that we do not consistently use the right architectural names
11741153
* for all sysregs, since we treat the name field as largely for debug.

0 commit comments

Comments
 (0)