[PATCH v1 13/26] s390: Introduce read/write ARM sysreg instructions
Janosch Frank
frankja at linux.ibm.com
Tue Jun 9 08:04:10 PDT 2026
On 5/29/26 17:55, Steffen Eiden wrote:
> Introduce Extract Arm System Register and Store Arm System Register to
> enable s390 hosts to read and write system registers for arm64 guests.
> The new instructions use the new RIE_H instruction format. Add assembler
> macros to create instructions in RIE_H format manually. Add Support for
> disassembling the new instructions.
>
> Co-developed-by: Andreas Grapentin <gra at linux.ibm.com>
> Signed-off-by: Andreas Grapentin <gra at linux.ibm.com>
> Signed-off-by: Steffen Eiden <seiden at linux.ibm.com>
> ---
> arch/s390/include/asm/sae-asm.h | 48 +++++++++++++++++++++++++++
> arch/s390/include/asm/sae.h | 58 +++++++++++++++++++++++++++++++++
> arch/s390/kernel/dis.c | 1 +
> arch/s390/tools/opcodes.txt | 2 ++
> 4 files changed, 109 insertions(+)
> create mode 100644 arch/s390/include/asm/sae-asm.h
>
> diff --git a/arch/s390/include/asm/sae-asm.h b/arch/s390/include/asm/sae-asm.h
> new file mode 100644
> index 000000000000..d81ed89eb4ed
> --- /dev/null
> +++ b/arch/s390/include/asm/sae-asm.h
> @@ -0,0 +1,48 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ASM_S390_SAE_ASM_H
> +#define __ASM_S390_SAE_ASM_H
> +
> +#ifdef __ASSEMBLER__
> +
> +.macro GPR_NUM opd gr
> + \opd = 255
> + .irp rs,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
> + .ifc \gr,%r\rs
> + \opd = \rs
> + .endif
> + .endr
> + .if \opd == 255
> + \opd = \gr
> + .endif
> +.endm
> +
> +/*
> + * RIE_H - RIE-h instruction format
> + *
> + * RIE-h format: <insn> R1, R3, I2, M4
> + * +--------+----+----+----+-----------------+----+--------+
> + * | OpCode | R1 |////| R3 | I2 | M4 | Opcode |
> + * +--------+----+----+----+-----------------+----+--------+
> + * 0 8 12 16 20 36 40 47
> + */
> +.macro RIE_H opc, gr1, gr3, imm2, m4
> + GPR_NUM r1, \gr1
> + GPR_NUM r3, \gr3
> + .byte (\opc & 0xff00) >> 8
> + .byte r1 << 4
> + .byte (r3 << 4) | ((\imm2 & 0xf000) >> 12)
> + .byte ((\imm2 & 0x0ff0) >> 4)
> + .byte ((\imm2 & 0x000f) << 4) | (\m4 & 0xf)
> + .byte \opc & 0xff
> +.endm
> +
> +.macro SASR r1, r3, i2, m4
> + RIE_H 0xed99, \r1, \r3, \i2, \m4,
> +.endm
> +
> +.macro EASR r1, r3, i2, m4
> + RIE_H 0xed9b, \r1, \r3, \i2, \m4,
> +.endm
> +
> +#endif /* __ASSEMBLER__ */
> +#endif /* __ASM_S390_SAE_ASM_H */
> diff --git a/arch/s390/include/asm/sae.h b/arch/s390/include/asm/sae.h
> index fe010a1a7729..1d9a16b91b23 100644
> --- a/arch/s390/include/asm/sae.h
> +++ b/arch/s390/include/asm/sae.h
> @@ -4,6 +4,7 @@
>
> #include "linux/linkage.h"
> #include <linux/types.h>
> +#include <asm/sae-asm.h>
>
> /* defined in arch/s390/kernel/entry.S */
> asmlinkage int __sae64a(phys_addr_t sae_block_phys);
> @@ -12,6 +13,12 @@ asmlinkage int __sae64a(phys_addr_t sae_block_phys);
> #include <linux/io.h>
> #include <asm/kvm_host_arm64_types.h>
>
> +asm(".include \"asm/sae-asm.h\"\n");
> +
> +#define _SAE_ASR_REG_SHIFT 5
> +#define SASR_FLAG_INITIALIZED 0x8
> +#define EASR_FLAG_SA 0x8
s/SA/SAVE_AREA/ or SAVEAREA
I think both might fit.
> +
> /**
> * __sae64a() - Start Arm Execution
> */
> @@ -20,6 +27,57 @@ static inline void sae64a(struct kvm_sae_block *sae_block)
> __sae64a(virt_to_phys(sae_block));
> }
>
> +/**
> + * sasr() - Set Arm System Register
> + * @arm_reg: ARM system register identifier; compile-time constant
> + * @val: Value to set
> + * @save_area: Pointer to SAE save area
> + * @flags: Operation flags; compile-time constant
> + *
> + * Sets an ARM system register value.
> + */
> +static __always_inline void sasr(unsigned int arm_reg, u64 val,
> + struct kvm_sae_save_area *save_area,
> + u64 flags)
m4 is 4 bits in length, any reason why we use a u64 here?
Same for easr.
> +{
> + struct kvm_sae_save_area *sdo = (void *)save_area->sdo;
> + u16 reg = arm_reg >> _SAE_ASR_REG_SHIFT;
> +
> + asm volatile (
> + " SASR %[r1],%[r3],%[i2],%[m4]\n"
> + : "+m" (*save_area), "+m" (*sdo)
> + : [r1] "d" (val),
> + [r3] "a" (save_area), [i2] "K" (reg), [m4] "I" (flags)
> + );
> +}
More information about the linux-arm-kernel
mailing list