// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2021, Red Hat, Inc.
 *
 * Tests for Hyper-V clocksources
 */
#include "test_util.h"
#include "kvm_util.h"
#include "processor.h"
#include "hyperv.h"

struct ms_hyperv_tsc_page {
	volatile u32 tsc_sequence;
	u32 reserved1;
	volatile u64 tsc_scale;
	volatile s64 tsc_offset;
} __packed;

/* Simplified mul_u64_u64_shr() */
static inline u64 mul_u64_u64_shr64(u64 a, u64 b)
{
	union {
		u64 ll;
		struct {
			u32 low, high;
		} l;
	} rm, rn, rh, a0, b0;
	u64 c;

	a0.ll = a;
	b0.ll = b;

	rm.ll = (u64)a0.l.low * b0.l.high;
	rn.ll = (u64)a0.l.high * b0.l.low;
	rh.ll = (u64)a0.l.high * b0.l.high;

	rh.l.low = c = rm.l.high + rn.l.high + rh.l.low;
	rh.l.high = (c >> 32) + rh.l.high;

	return rh.ll;
}

static inline void nop_loop(void)
{
	int i;

	for (i = 0; i < 100000000; i++)
		asm volatile("nop");
}

static inline void check_tsc_msr_rdtsc(void)
{
	u64 tsc_freq, r1, r2, t1, t2;
	s64 delta_ns;

	tsc_freq = rdmsr(HV_X64_MSR_TSC_FREQUENCY);
	GUEST_ASSERT(tsc_freq > 0);

	/* For increased accuracy, take mean rdtsc() before and after rdmsr() */
	r1 = rdtsc();
	t1 = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
	r1 = (r1 + rdtsc()) / 2;
	nop_loop();
	r2 = rdtsc();
	t2 = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
	r2 = (r2 + rdtsc()) / 2;

	GUEST_ASSERT(r2 > r1 && t2 > t1);

	/* HV_X64_MSR_TIME_REF_COUNT is in 100ns */
	delta_ns = ((t2 - t1) * 100) - ((r2 - r1) * 1000000000 / tsc_freq);
	if (delta_ns < 0)
		delta_ns = -delta_ns;

	/* 1% tolerance */
	GUEST_ASSERT(delta_ns * 100 < (t2 - t1) * 100);
}

static inline u64 get_tscpage_ts(struct ms_hyperv_tsc_page *tsc_page)
{
	return mul_u64_u64_shr64(rdtsc(), tsc_page->tsc_scale) + tsc_page->tsc_offset;
}

static inline void check_tsc_msr_tsc_page(struct ms_hyperv_tsc_page *tsc_page)
{
	u64 r1, r2, t1, t2;

	/* Compare TSC page clocksource with HV_X64_MSR_TIME_REF_COUNT */
	t1 = get_tscpage_ts(tsc_page);
	r1 = rdmsr(HV_X64_MSR_TIME_REF_COUNT);

	/* 10 ms tolerance */
	GUEST_ASSERT(r1 >= t1 && r1 - t1 < 100000);
	nop_loop();

	t2 = get_tscpage_ts(tsc_page);
	r2 = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
	GUEST_ASSERT(r2 >= t1 && r2 - t2 < 100000);
}

static void guest_main(struct ms_hyperv_tsc_page *tsc_page, gpa_t tsc_page_gpa)
{
	u64 tsc_scale, tsc_offset;

	/* Set Guest OS id to enable Hyper-V emulation */
	GUEST_SYNC(1);
	wrmsr(HV_X64_MSR_GUEST_OS_ID, HYPERV_LINUX_OS_ID);
	GUEST_SYNC(2);

	check_tsc_msr_rdtsc();

	GUEST_SYNC(3);

	/* Set up TSC page is disabled state, check that it's clean */
	wrmsr(HV_X64_MSR_REFERENCE_TSC, tsc_page_gpa);
	GUEST_ASSERT(tsc_page->tsc_sequence == 0);
	GUEST_ASSERT(tsc_page->tsc_scale == 0);
	GUEST_ASSERT(tsc_page->tsc_offset == 0);

	GUEST_SYNC(4);

	/* Set up TSC page is enabled state */
	wrmsr(HV_X64_MSR_REFERENCE_TSC, tsc_page_gpa | 0x1);
	GUEST_ASSERT(tsc_page->tsc_sequence != 0);

	GUEST_SYNC(5);

	check_tsc_msr_tsc_page(tsc_page);

	GUEST_SYNC(6);

	tsc_offset = tsc_page->tsc_offset;
	/* Call KVM_SET_CLOCK from userspace, check that TSC page was updated */

	GUEST_SYNC(7);
	/* Sanity check TSC page timestamp, it should be close to 0 */
	GUEST_ASSERT(get_tscpage_ts(tsc_page) < 100000);

	GUEST_ASSERT(tsc_page->tsc_offset != tsc_offset);

	nop_loop();

	/*
	 * Enable Re-enlightenment and check that TSC page stays constant across
	 * KVM_SET_CLOCK.
	 */
	wrmsr(HV_X64_MSR_REENLIGHTENMENT_CONTROL, 0x1 << 16 | 0xff);
	wrmsr(HV_X64_MSR_TSC_EMULATION_CONTROL, 0x1);
	tsc_offset = tsc_page->tsc_offset;
	tsc_scale = tsc_page->tsc_scale;
	GUEST_SYNC(8);
	GUEST_ASSERT(tsc_page->tsc_offset == tsc_offset);
	GUEST_ASSERT(tsc_page->tsc_scale == tsc_scale);

	GUEST_SYNC(9);

	check_tsc_msr_tsc_page(tsc_page);

	/*
	 * Disable re-enlightenment and TSC page, check that KVM doesn't update
	 * it anymore.
	 */
	wrmsr(HV_X64_MSR_REENLIGHTENMENT_CONTROL, 0);
	wrmsr(HV_X64_MSR_TSC_EMULATION_CONTROL, 0);
	wrmsr(HV_X64_MSR_REFERENCE_TSC, 0);
	memset(tsc_page, 0, sizeof(*tsc_page));

	GUEST_SYNC(10);
	GUEST_ASSERT(tsc_page->tsc_sequence == 0);
	GUEST_ASSERT(tsc_page->tsc_offset == 0);
	GUEST_ASSERT(tsc_page->tsc_scale == 0);

	GUEST_DONE();
}

static void host_check_tsc_msr_rdtsc(struct kvm_vcpu *vcpu)
{
	u64 tsc_freq, r1, r2, t1, t2;
	s64 delta_ns;

	tsc_freq = vcpu_get_msr(vcpu, HV_X64_MSR_TSC_FREQUENCY);
	TEST_ASSERT(tsc_freq > 0, "TSC frequency must be nonzero");

	/* For increased accuracy, take mean rdtsc() before and after ioctl */
	r1 = rdtsc();
	t1 = vcpu_get_msr(vcpu, HV_X64_MSR_TIME_REF_COUNT);
	r1 = (r1 + rdtsc()) / 2;
	nop_loop();
	r2 = rdtsc();
	t2 = vcpu_get_msr(vcpu, HV_X64_MSR_TIME_REF_COUNT);
	r2 = (r2 + rdtsc()) / 2;

	TEST_ASSERT(t2 > t1, "Time reference MSR is not monotonic (%ld <= %ld)", t1, t2);

	/* HV_X64_MSR_TIME_REF_COUNT is in 100ns */
	delta_ns = ((t2 - t1) * 100) - ((r2 - r1) * 1000000000 / tsc_freq);
	if (delta_ns < 0)
		delta_ns = -delta_ns;

	/* 1% tolerance */
	TEST_ASSERT(delta_ns * 100 < (t2 - t1) * 100,
		    "Elapsed time does not match (MSR=%ld, TSC=%ld)",
		    (t2 - t1) * 100, (r2 - r1) * 1000000000 / tsc_freq);
}

int main(void)
{
	struct kvm_vcpu *vcpu;
	struct kvm_vm *vm;
	struct ucall uc;
	gva_t tsc_page_gva;
	int stage;

	TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_TIME));
	TEST_REQUIRE(sys_clocksource_is_based_on_tsc());

	vm = vm_create_with_one_vcpu(&vcpu, guest_main);

	vcpu_set_hv_cpuid(vcpu);

	tsc_page_gva = vm_alloc_page(vm);
	memset(addr_gva2hva(vm, tsc_page_gva), 0x0, getpagesize());
	TEST_ASSERT((addr_gva2gpa(vm, tsc_page_gva) & (getpagesize() - 1)) == 0,
		"TSC page has to be page aligned");
	vcpu_args_set(vcpu, 2, tsc_page_gva, addr_gva2gpa(vm, tsc_page_gva));

	host_check_tsc_msr_rdtsc(vcpu);

	for (stage = 1;; stage++) {
		vcpu_run(vcpu);
		TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);

		switch (get_ucall(vcpu, &uc)) {
		case UCALL_ABORT:
			REPORT_GUEST_ASSERT(uc);
			/* NOT REACHED */
		case UCALL_SYNC:
			break;
		case UCALL_DONE:
			/* Keep in sync with guest_main() */
			TEST_ASSERT(stage == 11, "Testing ended prematurely, stage %d",
				    stage);
			goto out;
		default:
			TEST_FAIL("Unknown ucall %lu", uc.cmd);
		}

		TEST_ASSERT(!strcmp((const char *)uc.args[0], "hello") &&
			    uc.args[1] == stage,
			    "Stage %d: Unexpected register values vmexit, got %lx",
			    stage, (ulong)uc.args[1]);

		/* Reset kvmclock triggering TSC page update */
		if (stage == 7 || stage == 8 || stage == 10) {
			struct kvm_clock_data clock = {0};

			vm_ioctl(vm, KVM_SET_CLOCK, &clock);
		}
	}

out:
	kvm_vm_free(vm);
}
