lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
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

Powered by Openwall GNU/*/Linux Powered by OpenVZ