On 2026-08-20 18:24, Philippe Mathieu-Daudé wrote:
On 2026-08-20 17:21, Richard Henderson wrote:
On 8/20/26 03:47, Philippe Mathieu-Daudé wrote:
Introduce const-qualified variants of cpu_env() and
env_archcpu(), to safely access CPU architecture
state when it should not be modified.
Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
---
include/exec/cpu-common.h | 11 +++++++++++
include/hw/core/cpu.h | 6 ++++++
2 files changed, 17 insertions(+)
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 6594f7fa1be..f3a3799f451 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -79,6 +79,17 @@ static inline bool cpu_loop_exit_requested(const
CPUState *cpu)
}
#endif /* CONFIG_TCG */
+/**
+ * env_archcpu_const(env)
+ * @env: The architecture environment (const).
+ *
+ * Return the const ArchCPU associated with the environment.
+ */
+static inline const ArchCPU *env_archcpu_const(const CPUArchState *env)
+{
+ return (const void *)env - sizeof(CPUState);
+}
+
/**
* env_archcpu(env)
* @env: The architecture environment
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 81af7b9ee1a..59f777f3f15 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -594,6 +594,12 @@ struct CPUState {
QEMU_BUILD_BUG_ON(offsetof(CPUState, neg) !=
sizeof(CPUState) - sizeof(CPUNegativeOffsetState));
+static inline const CPUArchState *cpu_env_const(const CPUState *cpu)
+{
+ /* We validate that CPUArchState follows CPUState in cpu-
target.c */
+ return (const CPUArchState *)(cpu + 1);
+}
+
static inline CPUArchState *cpu_env(CPUState *cpu)
{
/* We validate that CPUArchState follows CPUState in cpu-
target.c */
I wonder if we can use _Generic to make this automatic, rather than
have to choose between two different function names.
Eh clever :) This seems to work:
#define env_archcpu_(p) _Generic(*(p), \
CPUArchState: (void *)p, \
const CPUArchState: (const void *)p)
Actually simpler and even well readable:
-- >8 --
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 6594f7fa1b..d67d008236 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -85,21 +85,11 @@ static inline bool cpu_loop_exit_requested(const
CPUState *cpu)
*
* Return the ArchCPU associated with the environment.
*/
-static inline ArchCPU *env_archcpu(CPUArchState *env)
-{
- return (void *)env - sizeof(CPUState);
-}
-
-/**
- * env_cpu_const(env)
- * @env: The architecture environment
- *
- * Return the CPUState associated with the environment.
- */
-static inline const CPUState *env_cpu_const(const CPUArchState *env)
-{
- return (void *)env - sizeof(CPUState);
-}
+#define env_archcpu(env) _Generic(*(env), \
+ CPUArchState: \
+ (ArchCPU *)((void *)env - sizeof(CPUState)), \
+ const CPUArchState: \
+ (const ArchCPU *)((const void *)env - sizeof(CPUState)))
/**
* env_cpu(env)
@@ -107,9 +97,10 @@ static inline const CPUState *env_cpu_const(const
CPUArchState *env)
*
* Return the CPUState associated with the environment.
*/
-static inline CPUState *env_cpu(CPUArchState *env)
-{
- return (CPUState *)env_cpu_const(env);
-}
+#define env_cpu(env) _Generic(*(env), \
+ CPUArchState: \
+ (CPUState *)((void *)env - sizeof(CPUState)), \
+ const CPUArchState: \
+ (const CPUState *)((const void *)env - sizeof(CPUState)))
#endif /* CPU_COMMON_H */
---