Re: [PATCH v7 22/22] Documentation: arm64: describe asymmetric 32-bit support

Marc Zyngier
2021-05-25T18:13:16Z

On Tue, 25 May 2021 18:27:03 +0100,
Will Deacon <will@kernel.org> wrote:
>
> On Tue, May 25, 2021 at 06:13:58PM +0100, Marc Zyngier wrote:
> > On Tue, 25 May 2021 16:14:32 +0100,
> > Will Deacon <will@kernel.org> wrote:
> > >
> > > Document support for running 32-bit tasks on asymmetric 32-bit systems
> > > and its impact on the user ABI when enabled.
> > >
> > > Signed-off-by: Will Deacon <will@kernel.org>
> > > ---
> > > .../admin-guide/kernel-parameters.txt | 3 +
> > > Documentation/arm64/asymmetric-32bit.rst | 154 ++++++++++++++++++
> > > Documentation/arm64/index.rst | 1 +
> > > 3 files changed, 158 insertions(+)
> > > create mode 100644 Documentation/arm64/asymmetric-32bit.rst
> > >
> >
> > [...]
> >
> > > +KVM
> > > +---
> > > +
> > > +Although KVM will not advertise 32-bit EL0 support to any vCPUs on an
> > > +asymmetric system, a broken guest at EL1 could still attempt to execute
> > > +32-bit code at EL0. In this case, an exit from a vCPU thread in 32-bit
> > > +mode will return to host userspace with an ``exit_reason`` of
> > > +``KVM_EXIT_FAIL_ENTRY``.
> >
> > Nit: there is a bit more to it. The vcpu will be left in a permanent
> > non-runnable state until KVM_ARM_VCPU_INIT is issued to reset the vcpu
> > into a saner state.
>
> Thanks, I'll add "and will remain non-runnable until re-initialised by a
> subsequent KVM_ARM_VCPU_INIT operation".

Looks good.

> Can the VMM tell that it needs to do that? I wonder if we should be
> setting 'hardware_entry_failure_reason' to distinguish this case.

The VMM should be able to notice that something is amiss, as any
subsequent KVM_RUN calls will result in -ENOEXEC being returned, and
we document this as "the vcpu hasn't been initialized or the guest
tried to execute instructions from device memory (arm64)".

However, there is another reason to get a "FAILED_ENTRY", and that if
we get an Illegal Exception Return exception when entering the
guest. That one should always be a KVM bug.

So yeah, maybe there is some ground to populate that structure with
the appropriate nastygram (completely untested).

M.

diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 24223adae150..cf50051a9412 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -402,6 +402,10 @@ struct kvm_vcpu_events {
#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED

+/* KVM_EXIT_FAIL_ENTRY reasons */
+#define KVM_ARM64_FAILED_ENTRY_NO_AARCH32_ALLOWED 0xBADBAD32
+#define KVM_ARM64_FAILED_ENTRY_INTERNAL_ERROR 0xE1215BAD
+
#endif

#endif /* __ARM_KVM_H__ */
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 6f48336b1d86..e97cd4de1fa7 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -262,6 +262,10 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
* have been corrupted somehow. Give up.
*/
run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+ run->fail_entry.hardware_entry_failure_reason = (vcpu->arch.target == -1) ?
+ KVM_ARM64_FAILED_ENTRY_NO_AARCH32_ALLOWED :
+ KVM_ARM64_FAILED_ENTRY_INTERNAL_ERROR;
+ run->fail_entry.cpu = vcpu->cpu;
return -EINVAL;
default:
kvm_pr_unimpl("Unsupported exception type: %d",

--
Without deviation from the norm, progress is not possible.