mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-25 15:53:58 +00: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));
|
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)
|
||||||
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 @@
|
||||||
#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 @@
|
||||||
#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 @@
|
||||||
* 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)
|
||||||
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)
|
||||||
* 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)
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue