From: Mohamed Mediouni Date: Tue, 24 Mar 2026 15:13:19 +0000 (+0100) Subject: target/i386: emulate: indirect access to CRs X-Git-Tag: v11.0.0-rc2~16^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9548e5b2fe5054dfc5c9cff939ce807e7ea8a418;p=thirdparty%2Fqemu.git 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 Link: https://lore.kernel.org/r/20260324151323.74473-9-mohamed@unpredictable.fr Signed-off-by: Paolo Bonzini --- diff --git a/target/i386/emulate/x86_emu.h b/target/i386/emulate/x86_emu.h index 4ed970bd536..a8d4c93098d 100644 --- a/target/i386/emulate/x86_emu.h +++ b/target/i386/emulate/x86_emu.h @@ -28,6 +28,7 @@ struct x86_emul_ops { MMUTranslateResult (*mmu_gva_to_gpa) (CPUState *cpu, target_ulong gva, uint64_t *gpa, MMUTranslateFlags flags); void (*read_segment_descriptor)(CPUState *cpu, struct x86_segment_descriptor *desc, enum X86Seg seg); + target_ulong (*read_cr) (CPUState *cpu, int cr); void (*handle_io)(CPUState *cpu, uint16_t port, void *data, int direction, int size, int count); void (*simulate_rdmsr)(CPUState *cs); @@ -45,6 +46,8 @@ void x86_emul_raise_exception(CPUX86State *env, int exception_index, int error_c target_ulong read_reg(CPUX86State *env, int reg, int size); void write_reg(CPUX86State *env, int reg, target_ulong val, int size); +target_ulong x86_read_cr(CPUState *cpu, int cr); + target_ulong read_val_from_reg(void *reg_ptr, int size); void write_val_to_reg(void *reg_ptr, target_ulong val, int size); bool write_val_ext(CPUX86State *env, struct x86_decode_op *decode, target_ulong val, int size); diff --git a/target/i386/emulate/x86_helpers.c b/target/i386/emulate/x86_helpers.c index ebbf40f2b05..c817015ef92 100644 --- a/target/i386/emulate/x86_helpers.c +++ b/target/i386/emulate/x86_helpers.c @@ -206,15 +206,26 @@ bool x86_read_call_gate(CPUState *cpu, struct x86_call_gate *idt_desc, return true; } -bool x86_is_protected(CPUState *cpu) +target_ulong x86_read_cr(CPUState *cpu, int cr) { X86CPU *x86_cpu = X86_CPU(cpu); CPUX86State *env = &x86_cpu->env; - uint64_t cr0 = env->cr[0]; + + if (emul_ops->read_cr) { + return emul_ops->read_cr(cpu, cr); + } + return env->cr[cr]; +} + +bool x86_is_protected(CPUState *cpu) +{ + uint64_t cr0; + if (emul_ops->is_protected_mode) { return emul_ops->is_protected_mode(cpu); } + cr0 = x86_read_cr(cpu, 0); return cr0 & CR0_PE_MASK; } @@ -245,9 +256,7 @@ bool x86_is_long_mode(CPUState *cpu) bool x86_is_la57(CPUState *cpu) { - X86CPU *x86_cpu = X86_CPU(cpu); - CPUX86State *env = &x86_cpu->env; - uint64_t is_la57 = env->cr[4] & CR4_LA57_MASK; + uint64_t is_la57 = x86_read_cr(cpu, 4) & CR4_LA57_MASK; return is_la57; } @@ -259,18 +268,14 @@ bool x86_is_long64_mode(CPUState *cpu) bool x86_is_paging_mode(CPUState *cpu) { - X86CPU *x86_cpu = X86_CPU(cpu); - CPUX86State *env = &x86_cpu->env; - uint64_t cr0 = env->cr[0]; + uint64_t cr0 = x86_read_cr(cpu, 0); return cr0 & CR0_PG_MASK; } bool x86_is_pae_enabled(CPUState *cpu) { - X86CPU *x86_cpu = X86_CPU(cpu); - CPUX86State *env = &x86_cpu->env; - uint64_t cr4 = env->cr[4]; + uint64_t cr4 = x86_read_cr(cpu, 4); return cr4 & CR4_PAE_MASK; } diff --git a/target/i386/emulate/x86_mmu.c b/target/i386/emulate/x86_mmu.c index 670939acdba..ba0ebe4268d 100644 --- a/target/i386/emulate/x86_mmu.c +++ b/target/i386/emulate/x86_mmu.c @@ -114,8 +114,6 @@ static bool get_pt_entry(CPUState *cpu, struct gpt_translation *pt, static MMUTranslateResult test_pt_entry(CPUState *cpu, struct gpt_translation *pt, int level, int *largeness, bool pae, MMUTranslateFlags flags) { - X86CPU *x86_cpu = X86_CPU(cpu); - CPUX86State *env = &x86_cpu->env; uint64_t pte = pt->pte[level]; if (!pte_present(pte)) { @@ -130,7 +128,7 @@ static MMUTranslateResult test_pt_entry(CPUState *cpu, struct gpt_translation *p *largeness = level; } - uint32_t cr0 = env->cr[0]; + uint32_t cr0 = x86_read_cr(cpu, 0); /* check protection */ if (cr0 & CR0_WP_MASK) { 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, static MMUTranslateResult walk_gpt(CPUState *cpu, target_ulong addr, MMUTranslateFlags flags, struct gpt_translation *pt, bool pae) { - X86CPU *x86_cpu = X86_CPU(cpu); - CPUX86State *env = &x86_cpu->env; int top_level, level; int largeness = 0; - target_ulong cr3 = env->cr[3]; + target_ulong cr3 = x86_read_cr(cpu, 3); uint64_t page_mask = pae ? PAE_PTE_PAGE_MASK : LEGACY_PTE_PAGE_MASK; MMUTranslateResult res; diff --git a/target/i386/hvf/x86.c b/target/i386/hvf/x86.c index 7fe710aca3b..bae2f30fa28 100644 --- a/target/i386/hvf/x86.c +++ b/target/i386/hvf/x86.c @@ -143,6 +143,17 @@ bool x86_is_la57(CPUState *cpu) return false; } +target_ulong x86_read_cr(CPUState *cpu, int cr) +{ + X86CPU *x86_cpu = X86_CPU(cpu); + CPUX86State *env = &x86_cpu->env; + + if (emul_ops->read_cr) { + return emul_ops->read_cr(cpu, cr); + } + return env->cr[cr]; +} + bool x86_is_long64_mode(CPUState *cpu) { struct vmx_segment desc;