// SPDX-License-Identifier: GPL-2.0
/*
 * Test that KVM_SET_BOOT_CPU_ID works as intended
 *
 * Copyright (C) 2020, Red Hat, Inc.
 */
#define _GNU_SOURCE /* for program_invocation_name */
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>

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

static void guest_bsp_vcpu(void *arg)
{
	GUEST_SYNC(1);

	GUEST_ASSERT_NE(get_bsp_flag(), 0);

	GUEST_DONE();
}

static void guest_not_bsp_vcpu(void *arg)
{
	GUEST_SYNC(1);

	GUEST_ASSERT_EQ(get_bsp_flag(), 0);

	GUEST_DONE();
}

static void test_set_bsp_busy(struct kvm_vcpu *vcpu, const char *msg)
{
	int r = __vm_ioctl(vcpu->vm, KVM_SET_BOOT_CPU_ID,
			   (void *)(unsigned long)vcpu->id);

	TEST_ASSERT(r == -1 && errno == EBUSY, "KVM_SET_BOOT_CPU_ID set %s", msg);
}

static void run_vcpu(struct kvm_vcpu *vcpu)
{
	struct ucall uc;
	int stage;

	for (stage = 0; stage < 2; stage++) {

		vcpu_run(vcpu);

		switch (get_ucall(vcpu, &uc)) {
		case UCALL_SYNC:
			TEST_ASSERT(!strcmp((const char *)uc.args[0], "hello") &&
					uc.args[1] == stage + 1,
					"Stage %d: Unexpected register values vmexit, got %lx",
					stage + 1, (ulong)uc.args[1]);
			test_set_bsp_busy(vcpu, "while running vm");
			break;
		case UCALL_DONE:
			TEST_ASSERT(stage == 1,
					"Expected GUEST_DONE in stage 2, got stage %d",
					stage);
			break;
		case UCALL_ABORT:
			REPORT_GUEST_ASSERT(uc);
		default:
			TEST_ASSERT(false, "Unexpected exit: %s",
				    exit_reason_str(vcpu->run->exit_reason));
		}
	}
}

static struct kvm_vm *create_vm(uint32_t nr_vcpus, uint32_t bsp_vcpu_id,
				struct kvm_vcpu *vcpus[])
{
	struct kvm_vm *vm;
	uint32_t i;

	vm = vm_create(nr_vcpus);

	vm_ioctl(vm, KVM_SET_BOOT_CPU_ID, (void *)(unsigned long)bsp_vcpu_id);

	for (i = 0; i < nr_vcpus; i++)
		vcpus[i] = vm_vcpu_add(vm, i, i == bsp_vcpu_id ? guest_bsp_vcpu :
								 guest_not_bsp_vcpu);
	return vm;
}

static void run_vm_bsp(uint32_t bsp_vcpu_id)
{
	struct kvm_vcpu *vcpus[2];
	struct kvm_vm *vm;

	vm = create_vm(ARRAY_SIZE(vcpus), bsp_vcpu_id, vcpus);

	run_vcpu(vcpus[0]);
	run_vcpu(vcpus[1]);

	kvm_vm_free(vm);
}

static void check_set_bsp_busy(void)
{
	struct kvm_vcpu *vcpus[2];
	struct kvm_vm *vm;

	vm = create_vm(ARRAY_SIZE(vcpus), 0, vcpus);

	test_set_bsp_busy(vcpus[1], "after adding vcpu");

	run_vcpu(vcpus[0]);
	run_vcpu(vcpus[1]);

	test_set_bsp_busy(vcpus[1], "to a terminated vcpu");

	kvm_vm_free(vm);
}

int main(int argc, char *argv[])
{
	TEST_REQUIRE(kvm_has_cap(KVM_CAP_SET_BOOT_CPU_ID));

	run_vm_bsp(0);
	run_vm_bsp(1);
	run_vm_bsp(0);

	check_set_bsp_busy();
}
