Add functions to convert between ARM guest time (LSB0) and s390 host time (MSB0) using new ptff function codes. Co-developed-by: Nico Boehr Signed-off-by: Nico Boehr Signed-off-by: Steffen Eiden --- 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 */ #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