mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	arm/arm64: KVM: Advertise SMCCC v1.1
The new SMC Calling Convention (v1.1) allows for a reduced overhead when calling into the firmware, and provides a new feature discovery mechanism. Make it visible to KVM guests. Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
		
							parent
							
								
									58e0b2239a
								
							
						
					
					
						commit
						09e6be12ef
					
				
					 5 changed files with 39 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -36,7 +36,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 | 
			
		|||
		      kvm_vcpu_hvc_get_imm(vcpu));
 | 
			
		||||
	vcpu->stat.hvc_exit_stat++;
 | 
			
		||||
 | 
			
		||||
	ret = kvm_psci_call(vcpu);
 | 
			
		||||
	ret = kvm_hvc_call_handler(vcpu);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		vcpu_set_reg(vcpu, 0, ~0UL);
 | 
			
		||||
		return 1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 | 
			
		|||
			    kvm_vcpu_hvc_get_imm(vcpu));
 | 
			
		||||
	vcpu->stat.hvc_exit_stat++;
 | 
			
		||||
 | 
			
		||||
	ret = kvm_psci_call(vcpu);
 | 
			
		||||
	ret = kvm_hvc_call_handler(vcpu);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		vcpu_set_reg(vcpu, 0, ~0UL);
 | 
			
		||||
		return 1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,6 @@
 | 
			
		|||
#define KVM_ARM_PSCI_LATEST	KVM_ARM_PSCI_1_0
 | 
			
		||||
 | 
			
		||||
int kvm_psci_version(struct kvm_vcpu *vcpu);
 | 
			
		||||
int kvm_psci_call(struct kvm_vcpu *vcpu);
 | 
			
		||||
int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
 | 
			
		||||
 | 
			
		||||
#endif /* __KVM_ARM_PSCI_H__ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,6 +60,19 @@
 | 
			
		|||
#define ARM_SMCCC_QUIRK_NONE		0
 | 
			
		||||
#define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */
 | 
			
		||||
 | 
			
		||||
#define ARM_SMCCC_VERSION_1_0		0x10000
 | 
			
		||||
#define ARM_SMCCC_VERSION_1_1		0x10001
 | 
			
		||||
 | 
			
		||||
#define ARM_SMCCC_VERSION_FUNC_ID					\
 | 
			
		||||
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
 | 
			
		||||
			   ARM_SMCCC_SMC_32,				\
 | 
			
		||||
			   0, 0)
 | 
			
		||||
 | 
			
		||||
#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID					\
 | 
			
		||||
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
 | 
			
		||||
			   ARM_SMCCC_SMC_32,				\
 | 
			
		||||
			   0, 1)
 | 
			
		||||
 | 
			
		||||
#ifndef __ASSEMBLY__
 | 
			
		||||
 | 
			
		||||
#include <linux/linkage.h>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,7 @@
 | 
			
		|||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <linux/arm-smccc.h>
 | 
			
		||||
#include <linux/preempt.h>
 | 
			
		||||
#include <linux/kvm_host.h>
 | 
			
		||||
#include <linux/wait.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -339,6 +340,7 @@ static int kvm_psci_1_0_call(struct kvm_vcpu *vcpu)
 | 
			
		|||
		case PSCI_0_2_FN_SYSTEM_OFF:
 | 
			
		||||
		case PSCI_0_2_FN_SYSTEM_RESET:
 | 
			
		||||
		case PSCI_1_0_FN_PSCI_FEATURES:
 | 
			
		||||
		case ARM_SMCCC_VERSION_FUNC_ID:
 | 
			
		||||
			val = 0;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
| 
						 | 
				
			
			@ -393,7 +395,7 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
 | 
			
		|||
 * Errors:
 | 
			
		||||
 * -EINVAL: Unrecognized PSCI function
 | 
			
		||||
 */
 | 
			
		||||
int kvm_psci_call(struct kvm_vcpu *vcpu)
 | 
			
		||||
static int kvm_psci_call(struct kvm_vcpu *vcpu)
 | 
			
		||||
{
 | 
			
		||||
	switch (kvm_psci_version(vcpu)) {
 | 
			
		||||
	case KVM_ARM_PSCI_1_0:
 | 
			
		||||
| 
						 | 
				
			
			@ -406,3 +408,23 @@ int kvm_psci_call(struct kvm_vcpu *vcpu)
 | 
			
		|||
		return -EINVAL;
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
 | 
			
		||||
{
 | 
			
		||||
	u32 func_id = smccc_get_function(vcpu);
 | 
			
		||||
	u32 val = PSCI_RET_NOT_SUPPORTED;
 | 
			
		||||
 | 
			
		||||
	switch (func_id) {
 | 
			
		||||
	case ARM_SMCCC_VERSION_FUNC_ID:
 | 
			
		||||
		val = ARM_SMCCC_VERSION_1_1;
 | 
			
		||||
		break;
 | 
			
		||||
	case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:
 | 
			
		||||
		/* Nothing supported yet */
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return kvm_psci_call(vcpu);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	smccc_set_retval(vcpu, val, 0, 0, 0);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue