mirror of
https://github.com/torvalds/linux.git
synced 2026-04-21 08:13:56 -04:00
Tinkering with UUIDs is a perilious task, and the KVM UUID gets broken at times. In order to spot this early enough, add a selftest that will shout if the expected value isn't found. Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Sebastian Ott <sebott@redhat.com> Link: https://lore.kernel.org/r/20250721130558.50823-1-jackabt.amazon@gmail.com Link: https://lore.kernel.org/r/20250806171341.1521210-1-maz@kernel.org Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
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 = {};
|
|
|
|
smccc_hvc(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;
|
|
}
|