@samitouri / QOSamiQemu / commits / 9548e5b2fe

target/i386: emulate: indirect access to CRs

Prepare to have on-demand fetch of registers from the backend during faults. For x86_64 macOS, copy the function there too. Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr> Link: https://lore.kernel.org/r/20260324151323.74473-9-mohamed@unpredictable.fr Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Mohamed Mediouni committed Mar 24, 2026 at 16:13 UTC 9548e5b2fe5054dfc5c9cff939ce807e7ea8a418
4 files changed +32 -17
target/i386/emulate/x86_emu.h
+3
@@ -28,6 +28,7 @@ struct x86_emul_ops {
28 MMUTranslateResult (*mmu_gva_to_gpa) (CPUState *cpu, target_ulong gva, uint64_t *gpa, MMUTranslateFlags flags);
29 void (*read_segment_descriptor)(CPUState *cpu, struct x86_segment_descriptor *desc,
30 enum X86Seg seg);
31 + target_ulong (*read_cr) (CPUState *cpu, int cr);
32 void (*handle_io)(CPUState *cpu, uint16_t port, void *data, int direction,
33 int size, int count);
34 void (*simulate_rdmsr)(CPUState *cs);
@@ -45,6 +46,8 @@ void x86_emul_raise_exception(CPUX86State *env, int exception_index, int error_c
46
47 target_ulong read_reg(CPUX86State *env, int reg, int size);
48 void write_reg(CPUX86State *env, int reg, target_ulong val, int size);
49 +target_ulong x86_read_cr(CPUState *cpu, int cr);
50 +
51 target_ulong read_val_from_reg(void *reg_ptr, int size);
52 void write_val_to_reg(void *reg_ptr, target_ulong val, int size);
53 bool write_val_ext(CPUX86State *env, struct x86_decode_op *decode, target_ulong val, int size);
target/i386/emulate/x86_helpers.c
+16 -11
@@ -206,15 +206,26 @@ bool x86_read_call_gate(CPUState *cpu, struct x86_call_gate *idt_desc,
206 return true;
207 }
208
209 -bool x86_is_protected(CPUState *cpu)
209 +target_ulong x86_read_cr(CPUState *cpu, int cr)
210 {
211 X86CPU *x86_cpu = X86_CPU(cpu);
212 CPUX86State *env = &x86_cpu->env;
213 - uint64_t cr0 = env->cr[0];
213 +
214 + if (emul_ops->read_cr) {
215 + return emul_ops->read_cr(cpu, cr);
216 + }
217 + return env->cr[cr];
218 +}
219 +
220 +bool x86_is_protected(CPUState *cpu)
221 +{
222 + uint64_t cr0;
223 +
224 if (emul_ops->is_protected_mode) {
225 return emul_ops->is_protected_mode(cpu);
226 }
227
228 + cr0 = x86_read_cr(cpu, 0);
229 return cr0 & CR0_PE_MASK;
230 }
231
@@ -245,9 +256,7 @@ bool x86_is_long_mode(CPUState *cpu)
256
257 bool x86_is_la57(CPUState *cpu)
258 {
248 - X86CPU *x86_cpu = X86_CPU(cpu);
249 - CPUX86State *env = &x86_cpu->env;
250 - uint64_t is_la57 = env->cr[4] & CR4_LA57_MASK;
259 + uint64_t is_la57 = x86_read_cr(cpu, 4) & CR4_LA57_MASK;
260 return is_la57;
261 }
262
@@ -259,18 +268,14 @@ bool x86_is_long64_mode(CPUState *cpu)
268
269 bool x86_is_paging_mode(CPUState *cpu)
270 {
262 - X86CPU *x86_cpu = X86_CPU(cpu);
263 - CPUX86State *env = &x86_cpu->env;
264 - uint64_t cr0 = env->cr[0];
271 + uint64_t cr0 = x86_read_cr(cpu, 0);
272
273 return cr0 & CR0_PG_MASK;
274 }
275
276 bool x86_is_pae_enabled(CPUState *cpu)
277 {
271 - X86CPU *x86_cpu = X86_CPU(cpu);
272 - CPUX86State *env = &x86_cpu->env;
273 - uint64_t cr4 = env->cr[4];
278 + uint64_t cr4 = x86_read_cr(cpu, 4);
279
280 return cr4 & CR4_PAE_MASK;
281 }
target/i386/emulate/x86_mmu.c
+2 -6
@@ -114,8 +114,6 @@ static bool get_pt_entry(CPUState *cpu, struct gpt_translation *pt,
114 static MMUTranslateResult test_pt_entry(CPUState *cpu, struct gpt_translation *pt,
115 int level, int *largeness, bool pae, MMUTranslateFlags flags)
116 {
117 - X86CPU *x86_cpu = X86_CPU(cpu);
118 - CPUX86State *env = &x86_cpu->env;
117 uint64_t pte = pt->pte[level];
118
119 if (!pte_present(pte)) {
@@ -130,7 +128,7 @@ static MMUTranslateResult test_pt_entry(CPUState *cpu, struct gpt_translation *p
128 *largeness = level;
129 }
130
133 - uint32_t cr0 = env->cr[0];
131 + uint32_t cr0 = x86_read_cr(cpu, 0);
132 /* check protection */
133 if (cr0 & CR0_WP_MASK) {
134 if (mmu_validate_write(flags) && !pte_write_access(pte)) {
@@ -184,11 +182,9 @@ static inline uint64_t large_page_gpa(struct gpt_translation *pt, bool pae,
182 static MMUTranslateResult walk_gpt(CPUState *cpu, target_ulong addr, MMUTranslateFlags flags,
183 struct gpt_translation *pt, bool pae)
184 {
187 - X86CPU *x86_cpu = X86_CPU(cpu);
188 - CPUX86State *env = &x86_cpu->env;
185 int top_level, level;
186 int largeness = 0;
191 - target_ulong cr3 = env->cr[3];
187 + target_ulong cr3 = x86_read_cr(cpu, 3);
188 uint64_t page_mask = pae ? PAE_PTE_PAGE_MASK : LEGACY_PTE_PAGE_MASK;
189 MMUTranslateResult res;
190
target/i386/hvf/x86.c
+11
@@ -143,6 +143,17 @@ bool x86_is_la57(CPUState *cpu)
143 return false;
144 }
145
146 +target_ulong x86_read_cr(CPUState *cpu, int cr)
147 +{
148 + X86CPU *x86_cpu = X86_CPU(cpu);
149 + CPUX86State *env = &x86_cpu->env;
150 +
151 + if (emul_ops->read_cr) {
152 + return emul_ops->read_cr(cpu, cr);
153 + }
154 + return env->cr[cr];
155 +}
156 +
157 bool x86_is_long64_mode(CPUState *cpu)
158 {
159 struct vmx_segment desc;