mirror of
https://github.com/torvalds/linux.git
synced 2026-04-24 17:42:27 -04:00
HVCs are taken within the VM when EL2 is in use. Ensure tests use the SMC instruction when running at EL2 to interact with the host. Signed-off-by: Oliver Upton <oliver.upton@linux.dev> Signed-off-by: Marc Zyngier <maz@kernel.org>
71 lines
1.7 KiB
C
71 lines
1.7 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
// Check that nobody has tampered with KVM's UID
|
|
|
|
#include <errno.h>
|
|
#include <linux/arm-smccc.h>
|
|
#include <asm/kvm.h>
|
|
#include <kvm_util.h>
|
|
|
|
#include "processor.h"
|
|
|
|
/*
|
|
* Do NOT redefine these constants, or try to replace them with some
|
|
* "common" version. They are hardcoded here to detect any potential
|
|
* breakage happening in the rest of the kernel.
|
|
*
|
|
* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74
|
|
*/
|
|
#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 0xb66fb428U
|
|
#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 0xe911c52eU
|
|
#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 0x564bcaa9U
|
|
#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3 0x743a004dU
|
|
|
|
static void guest_code(void)
|
|
{
|
|
struct arm_smccc_res res = {};
|
|
|
|
do_smccc(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, 0, 0, 0, 0, 0, 0, 0, &res);
|
|
|
|
__GUEST_ASSERT(res.a0 == ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 &&
|
|
res.a1 == ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 &&
|
|
res.a2 == ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 &&
|
|
res.a3 == ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3,
|
|
"Unexpected KVM-specific UID %lx %lx %lx %lx\n", res.a0, res.a1, res.a2, res.a3);
|
|
GUEST_DONE();
|
|
}
|
|
|
|
int main (int argc, char *argv[])
|
|
{
|
|
struct kvm_vcpu *vcpu;
|
|
struct kvm_vm *vm;
|
|
struct ucall uc;
|
|
bool guest_done = false;
|
|
|
|
vm = vm_create_with_one_vcpu(&vcpu, guest_code);
|
|
|
|
while (!guest_done) {
|
|
vcpu_run(vcpu);
|
|
|
|
switch (get_ucall(vcpu, &uc)) {
|
|
case UCALL_SYNC:
|
|
break;
|
|
case UCALL_DONE:
|
|
guest_done = true;
|
|
break;
|
|
case UCALL_ABORT:
|
|
REPORT_GUEST_ASSERT(uc);
|
|
break;
|
|
case UCALL_PRINTF:
|
|
printf("%s", uc.buffer);
|
|
break;
|
|
default:
|
|
TEST_FAIL("Unexpected guest exit");
|
|
}
|
|
}
|
|
|
|
kvm_vm_free(vm);
|
|
|
|
return 0;
|
|
}
|