Subject: Re: [PATCH v1 15/26] s390: Add functions to query arm guest time

From: Oliver Upton <[email-masked]>
Date: Mon, 1 Jun 2026 15:25:55 -0700

On Fri, May 29, 2026 at 05:55:48PM +0200, Steffen Eiden wrote:
> Add functions to convert between ARM guest time (LSB0) and s390 host
> time (MSB0) using new ptff function codes.
> 
> Co-developed-by: Nico Boehr <[email-masked]>
> Signed-off-by: Nico Boehr <[email-masked]>
> Signed-off-by: Steffen Eiden <[email-masked]>
> ---
>  arch/s390/include/asm/timex.h | 49 +++++++++++++++++++++++++++++++++++
>  arch/s390/kernel/time.c       |  1 +
>  arch/s390/kvm/arm64/arm.c     |  9 ++++++-
>  3 files changed, 58 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h
> index 49447b40f038..9ec22a28bbda 100644
> --- a/arch/s390/include/asm/timex.h
> +++ b/arch/s390/include/asm/timex.h
> @@ -99,6 +99,8 @@ extern unsigned char ptff_function_mask[16];
>  #define PTFF_QSI	0x02	/* query steering information */
>  #define PTFF_QPT	0x03	/* query physical clock */
>  #define PTFF_QUI	0x04	/* query UTC information */
> +#define PTFF_QAGTO	0x10	/* query arm guest time offset */
> +#define PTFF_QAGPT	0x11	/* query arm guest physical time offset */

Are these analogous to CNTVOFF_EL2 and CNTPOFF_EL2?

Thanks,
Oliver 

>  #define PTFF_ATO	0x40	/* adjust tod offset */
>  #define PTFF_STO	0x41	/* set tod offset */
>  #define PTFF_SFS	0x42	/* set fine steering rate */
> @@ -136,6 +138,17 @@ struct ptff_qui {
>  	unsigned int pad_0x5c[41];
>  } __packed;
>  
> +/*
> + * Query Arm Guest Time
> + * used for:
> + *	- Query Arm Guest Time Offset
> + *	- Query Arm Guest Physical Time
> + */
> +struct ptff_qagt {
> +	u64 in;
> +	u64 out;
> +};
> +
>  /*
>   * ptff - Perform timing facility function
>   * @ptff_block: Pointer to ptff parameter block
> @@ -286,4 +299,40 @@ static inline int tod_after_eq(unsigned long a, unsigned long b)
>  	return a >= b;
>  }
>  
> +/*
> + * ptff_qagto() -  Query Arm Guest Time Offset
> + *
> + * @physical_time: Arm guest physical time in MSb 0
> + *
> + * Converts Arm guest physical time in MSb 0 bit ordering
> + * into the Arm guest offset in LSb 0 bit ordering.
> + *
> + * Return: Arm guest time offset in LSb 0
> + */
> +static inline u64 ptff_qagto(u64 physical_time)
> +{
> +	struct ptff_qagt qagto = { .in = physical_time };
> +
> +	ptff(&qagto, sizeof(qagto), PTFF_QAGTO);
> +	return qagto.out;
> +}
> +
> +/*
> + * ptff_qagpt() - Query Arm Guest Physical Time
> + *
> + * @guest_time_offset: Arm guest time offset in MSb 0
> + *
> + * Converts Arm guest offset in MSb 0 bit ordering
> + * into the Arm guest physical time in LSb 0 bit ordering.
> + *
> + * Return: Arm guest physical time in LSb 0
> + * */
> +static inline u64 ptff_qagpt(u64 guest_time_offset)
> +{
> +	struct ptff_qagt qagpt = { .in = guest_time_offset };
> +
> +	ptff(&qagpt, sizeof(qagpt), PTFF_QAGPT);
> +	return qagpt.out;
> +}
> +
>  #endif
> diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
> index bd0df61d1907..2b989bebd220 100644
> --- a/arch/s390/kernel/time.c
> +++ b/arch/s390/kernel/time.c
> @@ -65,6 +65,7 @@ ATOMIC_NOTIFIER_HEAD(s390_epoch_delta_notifier);
>  EXPORT_SYMBOL(s390_epoch_delta_notifier);
>  
>  unsigned char ptff_function_mask[16];
> +EXPORT_SYMBOL(ptff_function_mask);
>  
>  static unsigned long lpar_offset;
>  static unsigned long initial_leap_seconds;
> diff --git a/arch/s390/kvm/arm64/arm.c b/arch/s390/kvm/arm64/arm.c
> index bf0866659421..636bbeda98a8 100644
> --- a/arch/s390/kvm/arm64/arm.c
> +++ b/arch/s390/kvm/arm64/arm.c
> @@ -692,8 +692,15 @@ long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, unsigned int ioctl,
>  
>  static int __init kvm_s390_arm64_init(void)
>  {
> -	if (!sclp.has_aef)
> +	if (!sclp.has_aef) {
> +		pr_info("SAE is not available\n");
>  		return -ENXIO;
> +	}
> +
> +	if (!(ptff_query(PTFF_QAGTO) && ptff_query(PTFF_QAGPT))) {
> +		pr_info("PTFF for arm on s390 is not available\n");
> +		return -ENXIO;
> +	}
>  
>  	return kvm_init_with_dev(sizeof(struct kvm_vcpu), 0, THIS_MODULE,
>  				 KVM_DEV_NAME, MISC_DYNAMIC_MINOR);
> -- 
> 2.53.0
>