[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <YmETmWvPPQvHpQwP@google.com>
Date: Thu, 21 Apr 2022 08:19:37 +0000
From: Oliver Upton <oupton@...gle.com>
To: Gavin Shan <gshan@...hat.com>
Cc: kvmarm@...ts.cs.columbia.edu, linux-kernel@...r.kernel.org,
eauger@...hat.com, Jonathan.Cameron@...wei.com,
vkuznets@...hat.com, will@...nel.org, shannon.zhaosl@...il.com,
james.morse@....com, mark.rutland@....com, maz@...nel.org,
pbonzini@...hat.com, shan.gavin@...il.com
Subject: Re: [PATCH v6 02/18] KVM: arm64: Route hypercalls based on their
owner
Hi Gavin,
On Sun, Apr 03, 2022 at 11:38:55PM +0800, Gavin Shan wrote:
> kvm_hvc_call_handler() directly handles the incoming hypercall, or
> and routes it based on its (function) ID. kvm_psci_call() becomes
> the gate keeper to handle the hypercall that can't be handled by
> any one else. It makes kvm_hvc_call_handler() a bit messy.
>
> This reorgnizes the code to route the hypercall to the corresponding
> handler based on its owner.
nit: write changelogs in the imperative:
Reorganize the code to ...
> The hypercall may be handled directly
> in the handler or routed further to the corresponding functionality.
> The (function) ID is always verified before it's routed to the
> corresponding functionality. By the way, @func_id is repalced by
> @func, to be consistent with by smccc_get_function().
>
> PSCI is the only exception, those hypercalls defined by 0.2 or
> beyond are routed to the handler for Standard Secure Service, but
> those defined in 0.1 are routed to the handler for Standard
> Hypervisor Service.
>
> Suggested-by: Oliver Upton <oupton@...gle.com>
> Signed-off-by: Gavin Shan <gshan@...hat.com>
> ---
> arch/arm64/kvm/hypercalls.c | 199 +++++++++++++++++++++++-------------
> 1 file changed, 127 insertions(+), 72 deletions(-)
>
> diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
> index 8438fd79e3f0..b659387d8919 100644
> --- a/arch/arm64/kvm/hypercalls.c
> +++ b/arch/arm64/kvm/hypercalls.c
[...]
> +static int kvm_hvc_standard(struct kvm_vcpu *vcpu, u32 func)
> +{
> + u64 val = SMCCC_RET_NOT_SUPPORTED;
> +
> + switch (func) {
> + case ARM_SMCCC_TRNG_VERSION ... ARM_SMCCC_TRNG_RND32:
> + case ARM_SMCCC_TRNG_RND64:
> + return kvm_trng_call(vcpu);
> + case PSCI_0_2_FN_PSCI_VERSION ... PSCI_0_2_FN_SYSTEM_RESET:
> + case PSCI_0_2_FN64_CPU_SUSPEND ... PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
> + case PSCI_1_0_FN_PSCI_FEATURES ... PSCI_1_0_FN_SET_SUSPEND_MODE:
> + case PSCI_1_0_FN64_SYSTEM_SUSPEND:
> + case PSCI_1_1_FN_SYSTEM_RESET2:
> + case PSCI_1_1_FN64_SYSTEM_RESET2:
Isn't it known from the SMCCC what range of hypercall numbers PSCI and
TRNG fall under, respectively?
https://developer.arm.com/documentation/den0028/e/
See sections 6.3 and 6.4.
> + return kvm_psci_call(vcpu);
> + }
> +
> + smccc_set_retval(vcpu, val, 0, 0, 0);
> + return 1;
I don't think any cases of the switch statement change val, could you
just use SMCCC_RET_NOT_SUPPORTED here?
> +}
> +
> +static int kvm_hvc_standard_hyp(struct kvm_vcpu *vcpu, u32 func)
> +{
> + u64 val = SMCCC_RET_NOT_SUPPORTED;
> + gpa_t gpa;
> +
> + switch (func) {
> case ARM_SMCCC_HV_PV_TIME_FEATURES:
> - val[0] = kvm_hypercall_pv_features(vcpu);
> + val = kvm_hypercall_pv_features(vcpu);
> break;
> case ARM_SMCCC_HV_PV_TIME_ST:
> gpa = kvm_init_stolen_time(vcpu);
> if (gpa != GPA_INVALID)
> - val[0] = gpa;
> + val = gpa;
> break;
> + case KVM_PSCI_FN_CPU_SUSPEND ... KVM_PSCI_FN_MIGRATE:
> + return kvm_psci_call(vcpu);
You might want to handle these from the main call handler with a giant
disclaimer that these values predate SMCCC and therefore collide with
the standard hypervisor service range.
[...]
> +
> +int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
> +{
> + u32 func = smccc_get_function(vcpu);
> + u64 val = SMCCC_RET_NOT_SUPPORTED;
> +
> + switch (ARM_SMCCC_OWNER_NUM(func)) {
> + case ARM_SMCCC_OWNER_ARCH:
> + return kvm_hvc_arch(vcpu, func);
> + case ARM_SMCCC_OWNER_STANDARD:
> + return kvm_hvc_standard(vcpu, func);
> + case ARM_SMCCC_OWNER_STANDARD_HYP:
> + return kvm_hvc_standard_hyp(vcpu, func);
> + case ARM_SMCCC_OWNER_VENDOR_HYP:
> + return kvm_hvc_vendor_hyp(vcpu, func);
> + }
> +
> + smccc_set_retval(vcpu, val, 0, 0, 0);
Same here, avoid indirecting the return value through a local variable.
--
Thanks,
Oliver
Powered by blists - more mailing lists