Commit 75807528 authored by Jingyi Wang's avatar Jingyi Wang Committed by lishusen
Browse files

KVM: arm64: Make use of TWED feature

virt inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8WMG6


CVE: NA

-----------------------------

For HCR_EL2, TWEDEn(bit[59]) decides whether TWED is enabled, and
when the configurable delay is enabled, TWEDEL (bits[63:60]) encodes
the minimum delay in taking a trap of WFE caused by the TWE bit in
this register as 2^(TWEDEL + 8) cycles.

We use two kernel parameters "twed_enable" and "twedel" to configure
the register.

Signed-off-by: default avatarZengruan Ye <yezengruan@huawei.com>
Signed-off-by: default avatarJingyi Wang <wangjingyi11@huawei.com>
Signed-off-by: default avatarlishusen <lishusen2@huawei.com>
parent d5925c19
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@

/* Hyp Configuration Register (HCR) bits */

#define HCR_TWEDEN	(UL(1) << 59)
#define HCR_TID5	(UL(1) << 58)
#define HCR_DCT		(UL(1) << 57)
#define HCR_ATA_SHIFT	56
@@ -74,6 +75,12 @@
#define HCR_VM		(UL(1) << 0)
#define HCR_RES0	((UL(1) << 48) | (UL(1) << 39))

#ifdef CONFIG_ARM64_TWED
#define HCR_TWEDEL_SHIFT	60
#define HCR_TWEDEL_MAX		(UL(0xf))
#define HCR_TWEDEL_MASK		(HCR_TWEDEL_MAX << HCR_TWEDEL_SHIFT)
#endif

/*
 * The bits we set in HCR:
 * TLOR:	Trap LORegion register accesses
+21 −0
Original line number Diff line number Diff line
@@ -124,6 +124,27 @@ static inline void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu)
	vcpu->arch.hcr_el2 |= HCR_TWI;
}

#ifdef CONFIG_ARM64_TWED
static inline void vcpu_set_twed(struct kvm_vcpu *vcpu)
{
	if (!cpus_have_const_cap(ARM64_HAS_TWED))
		return;

	if (twed_enable) {
		u64 delay = (u64)twedel;

		delay = (delay > HCR_TWEDEL_MAX) ? HCR_TWEDEL_MAX : delay;
		vcpu->arch.hcr_el2 |= HCR_TWEDEN;
		vcpu->arch.hcr_el2 &= ~HCR_TWEDEL_MASK;
		vcpu->arch.hcr_el2 |= (delay << HCR_TWEDEL_SHIFT);
	} else {
		vcpu->arch.hcr_el2 &= ~HCR_TWEDEN;
	}
}
#else
static inline void vcpu_set_twed(struct kvm_vcpu *vcpu) {}
#endif

static inline void vcpu_ptrauth_enable(struct kvm_vcpu *vcpu)
{
	vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
+5 −0
Original line number Diff line number Diff line
@@ -1151,6 +1151,11 @@ void __init kvm_hyp_reserve(void);
static inline void kvm_hyp_reserve(void) { }
#endif

#ifdef CONFIG_ARM64_TWED
extern bool twed_enable;
extern unsigned int twedel;
#endif

void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu);
bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);

+10 −0
Original line number Diff line number Diff line
@@ -64,6 +64,14 @@ bool is_kvm_arm_initialised(void)
	return kvm_arm_initialised;
}

#ifdef CONFIG_ARM64_TWED
bool twed_enable;
module_param(twed_enable, bool, 0644);

unsigned int twedel;
module_param(twedel, uint, 0644);
#endif

int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
{
	return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
@@ -983,6 +991,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
		kvm_arm_setup_debug(vcpu);
		kvm_arch_vcpu_ctxflush_fp(vcpu);

		vcpu_set_twed(vcpu);

		/**************************************************************
		 * Enter the guest
		 */