diff options
Diffstat (limited to 'arch/arm64/kvm/psci.c')
| -rw-r--r-- | arch/arm64/kvm/psci.c | 21 | 
1 files changed, 18 insertions, 3 deletions
diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c index 3eae32876897..5918095c90a5 100644 --- a/arch/arm64/kvm/psci.c +++ b/arch/arm64/kvm/psci.c @@ -46,8 +46,7 @@ static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)  	 * specification (ARM DEN 0022A). This means all suspend states  	 * for KVM will preserve the register state.  	 */ -	kvm_vcpu_halt(vcpu); -	kvm_clear_request(KVM_REQ_UNHALT, vcpu); +	kvm_vcpu_wfi(vcpu);  	return PSCI_RET_SUCCESS;  } @@ -406,7 +405,7 @@ int kvm_psci_call(struct kvm_vcpu *vcpu)  int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)  { -	return 3;		/* PSCI version and two workaround registers */ +	return 4;		/* PSCI version and three workaround registers */  }  int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) @@ -420,6 +419,9 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)  	if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, uindices++))  		return -EFAULT; +	if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, uindices++)) +		return -EFAULT; +  	return 0;  } @@ -459,6 +461,17 @@ static int get_kernel_wa_level(u64 regid)  		case SPECTRE_VULNERABLE:  			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;  		} +		break; +	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: +		switch (arm64_get_spectre_bhb_state()) { +		case SPECTRE_VULNERABLE: +			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL; +		case SPECTRE_MITIGATED: +			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL; +		case SPECTRE_UNAFFECTED: +			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED; +		} +		return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;  	}  	return -EINVAL; @@ -475,6 +488,7 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)  		break;  	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:  	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: +	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:  		val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;  		break;  	default: @@ -520,6 +534,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)  	}  	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: +	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:  		if (val & ~KVM_REG_FEATURE_LEVEL_MASK)  			return -EINVAL;  |