Message ID | 20241212155610.76522-28-steven.price@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | arm64: Support for Arm CCA in KVM | expand |
On 12/13/24 1:55 AM, Steven Price wrote: > From: Joey Gouly <joey.gouly@arm.com> > > Forward RSI_HOST_CALLS to KVM's HVC handler. > > Signed-off-by: Joey Gouly <joey.gouly@arm.com> > Signed-off-by: Steven Price <steven.price@arm.com> > --- > Changes since v4: > * Setting GPRS is now done by kvm_rec_enter() rather than > rec_exit_host_call() (see previous patch - arm64: RME: Handle realm > enter/exit). This fixes a bug where the registers set by user space > were being ignored. > --- > arch/arm64/kvm/rme-exit.c | 22 ++++++++++++++++++++++ > 1 file changed, 22 insertions(+) > > diff --git a/arch/arm64/kvm/rme-exit.c b/arch/arm64/kvm/rme-exit.c > index 8f0f9ab57f28..b2a367474d74 100644 > --- a/arch/arm64/kvm/rme-exit.c > +++ b/arch/arm64/kvm/rme-exit.c > @@ -103,6 +103,26 @@ static int rec_exit_ripas_change(struct kvm_vcpu *vcpu) > return 0; > } > > +static int rec_exit_host_call(struct kvm_vcpu *vcpu) > +{ > + int ret, i; > + struct realm_rec *rec = &vcpu->arch.rec; > + > + vcpu->stat.hvc_exit_stat++; > + > + for (i = 0; i < REC_RUN_GPRS; i++) > + vcpu_set_reg(vcpu, i, rec->run->exit.gprs[i]); > + > + ret = kvm_smccc_call_handler(vcpu); > + > + if (ret < 0) { > + vcpu_set_reg(vcpu, 0, ~0UL); > + ret = 1; > + } > + > + return ret; > +} > + It seems that the return value from kvm_smccc_call() won't be negative. Besides, the host call requests are currently handled by kvm_psci_call(), which isn't what we want. So I think a new helper is needed and called in kvm_smccc_call_handler(). The new helper simply push the error (NOT_SUPPORTED) to x0. Otherwise, a unexpected return value will be seen by guest. handle_rec_exit rec_exit_host_call kvm_smccc_call_handler > static void update_arch_timer_irq_lines(struct kvm_vcpu *vcpu) > { > struct realm_rec *rec = &vcpu->arch.rec; > @@ -164,6 +184,8 @@ int handle_rec_exit(struct kvm_vcpu *vcpu, int rec_run_ret) > return rec_exit_psci(vcpu); > case RMI_EXIT_RIPAS_CHANGE: > return rec_exit_ripas_change(vcpu); > + case RMI_EXIT_HOST_CALL: > + return rec_exit_host_call(vcpu); > } > > kvm_pr_unimpl("Unsupported exit reason: %u\n", Thanks, Gavin
On 02/02/2025 06:41, Gavin Shan wrote: > On 12/13/24 1:55 AM, Steven Price wrote: >> From: Joey Gouly <joey.gouly@arm.com> >> >> Forward RSI_HOST_CALLS to KVM's HVC handler. >> >> Signed-off-by: Joey Gouly <joey.gouly@arm.com> >> Signed-off-by: Steven Price <steven.price@arm.com> >> --- >> Changes since v4: >> * Setting GPRS is now done by kvm_rec_enter() rather than >> rec_exit_host_call() (see previous patch - arm64: RME: Handle realm >> enter/exit). This fixes a bug where the registers set by user space >> were being ignored. >> --- >> arch/arm64/kvm/rme-exit.c | 22 ++++++++++++++++++++++ >> 1 file changed, 22 insertions(+) >> >> diff --git a/arch/arm64/kvm/rme-exit.c b/arch/arm64/kvm/rme-exit.c >> index 8f0f9ab57f28..b2a367474d74 100644 >> --- a/arch/arm64/kvm/rme-exit.c >> +++ b/arch/arm64/kvm/rme-exit.c >> @@ -103,6 +103,26 @@ static int rec_exit_ripas_change(struct kvm_vcpu >> *vcpu) >> return 0; >> } >> +static int rec_exit_host_call(struct kvm_vcpu *vcpu) >> +{ >> + int ret, i; >> + struct realm_rec *rec = &vcpu->arch.rec; >> + >> + vcpu->stat.hvc_exit_stat++; >> + >> + for (i = 0; i < REC_RUN_GPRS; i++) >> + vcpu_set_reg(vcpu, i, rec->run->exit.gprs[i]); >> + >> + ret = kvm_smccc_call_handler(vcpu); >> + >> + if (ret < 0) { >> + vcpu_set_reg(vcpu, 0, ~0UL); >> + ret = 1; >> + } >> + >> + return ret; >> +} >> + > > It seems that the return value from kvm_smccc_call() won't be negative. Well the comment above kvm_psci_call() explains that the return value can be negative which would be passed through, so there's definitely a convention that it could be negative. However... > Besides, > the host call requests are currently handled by kvm_psci_call(), which > isn't > what we want. Indeed, we shouldn't be getting PSCI calls this way as the RMM needs to be involved for proper handling of PSCI. > So I think a new helper is needed and called in> kvm_smccc_call_handler(). > The new helper simply push the error (NOT_SUPPORTED) to x0. Otherwise, a > unexpected > return value will be seen by guest. > > handle_rec_exit > rec_exit_host_call > kvm_smccc_call_handler I'm not sure I follow here. Are you saying that we should have separate handling of HOST_CALLs to SMCCC? That's certainly a possibility, but the expectation is that HOST_CALL is effectively equivalent to a simple SMC/HVC call in a normal guest. To be honest a "Realm Host Interface" is something that we're currently lacking a spec for. Thanks, Steve >> static void update_arch_timer_irq_lines(struct kvm_vcpu *vcpu) >> { >> struct realm_rec *rec = &vcpu->arch.rec; >> @@ -164,6 +184,8 @@ int handle_rec_exit(struct kvm_vcpu *vcpu, int >> rec_run_ret) >> return rec_exit_psci(vcpu); >> case RMI_EXIT_RIPAS_CHANGE: >> return rec_exit_ripas_change(vcpu); >> + case RMI_EXIT_HOST_CALL: >> + return rec_exit_host_call(vcpu); >> } >> kvm_pr_unimpl("Unsupported exit reason: %u\n", > > Thanks, > Gavin >
diff --git a/arch/arm64/kvm/rme-exit.c b/arch/arm64/kvm/rme-exit.c index 8f0f9ab57f28..b2a367474d74 100644 --- a/arch/arm64/kvm/rme-exit.c +++ b/arch/arm64/kvm/rme-exit.c @@ -103,6 +103,26 @@ static int rec_exit_ripas_change(struct kvm_vcpu *vcpu) return 0; } +static int rec_exit_host_call(struct kvm_vcpu *vcpu) +{ + int ret, i; + struct realm_rec *rec = &vcpu->arch.rec; + + vcpu->stat.hvc_exit_stat++; + + for (i = 0; i < REC_RUN_GPRS; i++) + vcpu_set_reg(vcpu, i, rec->run->exit.gprs[i]); + + ret = kvm_smccc_call_handler(vcpu); + + if (ret < 0) { + vcpu_set_reg(vcpu, 0, ~0UL); + ret = 1; + } + + return ret; +} + static void update_arch_timer_irq_lines(struct kvm_vcpu *vcpu) { struct realm_rec *rec = &vcpu->arch.rec; @@ -164,6 +184,8 @@ int handle_rec_exit(struct kvm_vcpu *vcpu, int rec_run_ret) return rec_exit_psci(vcpu); case RMI_EXIT_RIPAS_CHANGE: return rec_exit_ripas_change(vcpu); + case RMI_EXIT_HOST_CALL: + return rec_exit_host_call(vcpu); } kvm_pr_unimpl("Unsupported exit reason: %u\n",