> On 13. Mar 2026, at 03:18, Lucas Amaral <[email protected]> wrote:
> 
> Add a shared emulation library in target/arm/emulate/ using a
> decodetree decoder (a64-ldst.decode) and a callback-based interface
> (struct arm_emul_ops) that any hypervisor backend can implement.
> 
> The hypervisor cannot emulate ISV=0 data aborts without decoding the
> faulting instruction, since the ESR syndrome does not carry the access
> size or target register.
> 
> Signed-off-by: Lucas Amaral <[email protected]>
[…]
> +/**
> + * struct arm_emul_ops - hypervisor register/memory callbacks
> + *
> + * GPR reg 31 = SP (the XZR/SP distinction is handled internally).
> + * Memory callbacks use guest virtual addresses.
> + */
> +struct arm_emul_ops {
> +    uint64_t (*read_gpr)(CPUState *cpu, int reg);
> +    void (*write_gpr)(CPUState *cpu, int reg, uint64_t val);
> +
> +    /* @size: access width in bytes (4, 8, or 16) */
> +    void (*read_fpreg)(CPUState *cpu, int reg, void *buf, int size);
> +    void (*write_fpreg)(CPUState *cpu, int reg, const void *buf, int size);
Hello,

Can be good to have, but you should have a default implementation using 
CPUState in an arm_helpers
to not duplicate them across each backend. and then do an 
if(ctx->ops->read_gpr) { use override } else { default }
with a default implementation.

> +
> +    /* Returns 0 on success, non-zero on failure */
> +    int (*read_mem)(CPUState *cpu, uint64_t va, void *buf, int size);
> +    int (*write_mem)(CPUState *cpu, uint64_t va, const void *buf, int size);
> +};

A memory access - especially one that will be emulated - can span multiple 
(physical) pages under
the hood. If everything is mapped you’re fine, but that’s a bit depending on 
precious luck, especially
as the AArch64 glibc does unaligned accesses on memcpy.

On x86 side of things, was able to run Windows (NT) and Linux but not Haiku, 
(the Hurd needs more complexity that I don’t even handle yet for x86), and 
Win9x without handling such a fault case.

And there are memory to memory instructions on the way (FEAT_MOPS) where that’s 
even more likely to happen.
The downside of read_mem/write_mem is even if you return a fault code, you 
don’t know which one of the two pages
(or more potentially for memory-to-memory instructions) raised the fault.

Made a design change away to an mmu_gva_to_gpa callback and not having 
read/write ops anymore like this because of that factor (see 
target/i386/emulate/x86_mmu.c x86_write_mem_ex/x86_read_mem_ex)

Maybe you could keep a read_mem/write_mem matching those two on top of 
mmu_gva_to_gpa for your unit tests. Or run those
in a guest context as kvm-unit-tests does.

Thank you,
> +
> +/**
> + * arm_emul_insn - decode and emulate one AArch64 instruction
> + *
> + * Caller must synchronize CPU state and fetch @insn before calling.
> + */
> +ArmEmulResult arm_emul_insn(CPUState *cpu, const struct arm_emul_ops *ops,
> +                            uint32_t insn);
> +
> +#endif /* ARM_EMULATE_H */
> diff --git a/target/arm/emulate/meson.build b/target/arm/emulate/meson.build
> new file mode 100644
> index 0000000..29b7879
> --- /dev/null
> +++ b/target/arm/emulate/meson.build
> @@ -0,0 +1,16 @@
> +gen_a64_ldst = decodetree.process('a64-ldst.decode',
> +    extra_args: ['--static-decode=decode_a64_ldst'])
> +
> +arm_common_system_ss.add(when: 'TARGET_AARCH64', if_true: [
> +    gen_a64_ldst, files('arm_emulate.c')
> +])
> +
> +# Static library for unit testing (links emulation code + decodetree decoder)
> +arm_emulate_test_lib = static_library('arm-emulate-test',
> +    sources: [files('arm_emulate.c'), gen_a64_ldst],
> +    dependencies: [qemuutil],
> +    include_directories: include_directories('.'))
> +
> +arm_emulate_test = declare_dependency(
> +    link_with: arm_emulate_test_lib,
> +    include_directories: include_directories('.'))
> diff --git a/target/arm/meson.build b/target/arm/meson.build
> index 6e0e504..a4b2291 100644
> --- a/target/arm/meson.build
> +++ b/target/arm/meson.build
> @@ -57,6 +57,7 @@ arm_common_system_ss.add(files(
>   'vfp_fpscr.c',
> ))
> 
> +subdir('emulate')
> subdir('hvf')
> subdir('whpx')
> 
> -- 
> 2.52.0
> 
> 


Reply via email to