tools/testing/selftests/kvm/arm64/psci_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/arm64/psci_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/arm64/psci_test.c
Extension
.c
Size
7499 bytes
Lines
290
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * psci_test - Tests relating to KVM's PSCI implementation.
 *
 * Copyright (c) 2021 Google LLC.
 *
 * This test includes:
 *  - A regression test for a race between KVM servicing the PSCI CPU_ON call
 *    and userspace reading the targeted vCPU's registers.
 *  - A test for KVM's handling of PSCI SYSTEM_SUSPEND and the associated
 *    KVM_SYSTEM_EVENT_SUSPEND UAPI.
 */

#include <linux/kernel.h>
#include <linux/psci.h>
#include <asm/cputype.h>

#include "kvm_util.h"
#include "processor.h"
#include "test_util.h"

#define CPU_ON_ENTRY_ADDR 0xfeedf00dul
#define CPU_ON_CONTEXT_ID 0xdeadc0deul

static u64 psci_cpu_on(u64 target_cpu, u64 entry_addr, u64 context_id)
{
	struct arm_smccc_res res;

	do_smccc(PSCI_0_2_FN64_CPU_ON, target_cpu, entry_addr, context_id,
		  0, 0, 0, 0, &res);

	return res.a0;
}

static u64 psci_affinity_info(u64 target_affinity, u64 lowest_affinity_level)
{
	struct arm_smccc_res res;

	do_smccc(PSCI_0_2_FN64_AFFINITY_INFO, target_affinity, lowest_affinity_level,
		  0, 0, 0, 0, 0, &res);

	return res.a0;
}

static u64 psci_system_suspend(u64 entry_addr, u64 context_id)
{
	struct arm_smccc_res res;

	do_smccc(PSCI_1_0_FN64_SYSTEM_SUSPEND, entry_addr, context_id,
		  0, 0, 0, 0, 0, &res);

	return res.a0;
}

static u64 psci_system_off2(u64 type, u64 cookie)
{
	struct arm_smccc_res res;

	do_smccc(PSCI_1_3_FN64_SYSTEM_OFF2, type, cookie, 0, 0, 0, 0, 0, &res);

	return res.a0;
}

static u64 psci_features(u32 func_id)
{
	struct arm_smccc_res res;

	do_smccc(PSCI_1_0_FN_PSCI_FEATURES, func_id, 0, 0, 0, 0, 0, 0, &res);

	return res.a0;
}

static void vcpu_power_off(struct kvm_vcpu *vcpu)
{
	struct kvm_mp_state mp_state = {
		.mp_state = KVM_MP_STATE_STOPPED,
	};

	vcpu_mp_state_set(vcpu, &mp_state);
}

static struct kvm_vm *setup_vm(void *guest_code, struct kvm_vcpu **source,
			       struct kvm_vcpu **target)
{
	struct kvm_vcpu_init init;
	struct kvm_vm *vm;

	vm = vm_create(2);

	kvm_get_default_vcpu_target(vm, &init);

Annotation

Implementation Notes