Commit 09e6be12 authored by Marc Zyngier's avatar Marc Zyngier Committed by Catalin Marinas

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: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 58e0b223
...@@ -36,7 +36,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run) ...@@ -36,7 +36,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
kvm_vcpu_hvc_get_imm(vcpu)); kvm_vcpu_hvc_get_imm(vcpu));
vcpu->stat.hvc_exit_stat++; vcpu->stat.hvc_exit_stat++;
ret = kvm_psci_call(vcpu); ret = kvm_hvc_call_handler(vcpu);
if (ret < 0) { if (ret < 0) {
vcpu_set_reg(vcpu, 0, ~0UL); vcpu_set_reg(vcpu, 0, ~0UL);
return 1; return 1;
......
...@@ -52,7 +52,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run) ...@@ -52,7 +52,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
kvm_vcpu_hvc_get_imm(vcpu)); kvm_vcpu_hvc_get_imm(vcpu));
vcpu->stat.hvc_exit_stat++; vcpu->stat.hvc_exit_stat++;
ret = kvm_psci_call(vcpu); ret = kvm_hvc_call_handler(vcpu);
if (ret < 0) { if (ret < 0) {
vcpu_set_reg(vcpu, 0, ~0UL); vcpu_set_reg(vcpu, 0, ~0UL);
return 1; return 1;
......
...@@ -27,6 +27,6 @@ ...@@ -27,6 +27,6 @@
#define KVM_ARM_PSCI_LATEST KVM_ARM_PSCI_1_0 #define KVM_ARM_PSCI_LATEST KVM_ARM_PSCI_1_0
int kvm_psci_version(struct kvm_vcpu *vcpu); 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__ */ #endif /* __KVM_ARM_PSCI_H__ */
...@@ -60,6 +60,19 @@ ...@@ -60,6 +60,19 @@
#define ARM_SMCCC_QUIRK_NONE 0 #define ARM_SMCCC_QUIRK_NONE 0
#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */ #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__ #ifndef __ASSEMBLY__
#include <linux/linkage.h> #include <linux/linkage.h>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <linux/arm-smccc.h>
#include <linux/preempt.h> #include <linux/preempt.h>
#include <linux/kvm_host.h> #include <linux/kvm_host.h>
#include <linux/wait.h> #include <linux/wait.h>
...@@ -339,6 +340,7 @@ static int kvm_psci_1_0_call(struct kvm_vcpu *vcpu) ...@@ -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_OFF:
case PSCI_0_2_FN_SYSTEM_RESET: case PSCI_0_2_FN_SYSTEM_RESET:
case PSCI_1_0_FN_PSCI_FEATURES: case PSCI_1_0_FN_PSCI_FEATURES:
case ARM_SMCCC_VERSION_FUNC_ID:
val = 0; val = 0;
break; break;
default: default:
...@@ -393,7 +395,7 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu) ...@@ -393,7 +395,7 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
* Errors: * Errors:
* -EINVAL: Unrecognized PSCI function * -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)) { switch (kvm_psci_version(vcpu)) {
case KVM_ARM_PSCI_1_0: case KVM_ARM_PSCI_1_0:
...@@ -406,3 +408,23 @@ int kvm_psci_call(struct kvm_vcpu *vcpu) ...@@ -406,3 +408,23 @@ int kvm_psci_call(struct kvm_vcpu *vcpu)
return -EINVAL; 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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment