// SPDX-License-Identifier: GPL-2.0
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>

#include <linux/sizes.h>

#include <kvm_util.h>
#include <processor.h>

#include "ucall_common.h"

struct kvm_coalesced_io {
	struct kvm_coalesced_mmio_ring *ring;
	u32 ring_size;
	u64 mmio_gpa;
	u64 *mmio;

	/*
	 * x86-only, but define pio_port for all architectures to minimize the
	 * amount of #ifdeffery and complexity, without having to sacrifice
	 * verbose error messages.
	 */
	u8 pio_port;
};

static struct kvm_coalesced_io kvm_builtin_io_ring;

#ifdef __x86_64__
static const int has_pio = 1;
#else
static const int has_pio = 0;
#endif

static void guest_code(struct kvm_coalesced_io *io)
{
	int i, j;

	for (;;) {
		for (j = 0; j < 1 + has_pio; j++) {
			/*
			 * KVM always leaves one free entry, i.e. exits to
			 * userspace before the last entry is filled.
			 */
			for (i = 0; i < io->ring_size - 1; i++) {
#ifdef __x86_64__
				if (i & 1)
					outl(io->pio_port, io->pio_port + i);
				else
#endif
					WRITE_ONCE(*io->mmio, io->mmio_gpa + i);
			}
#ifdef __x86_64__
			if (j & 1)
				outl(io->pio_port, io->pio_port + i);
			else
#endif
				WRITE_ONCE(*io->mmio, io->mmio_gpa + i);
		}
		GUEST_SYNC(0);

		WRITE_ONCE(*io->mmio, io->mmio_gpa + i);
#ifdef __x86_64__
		outl(io->pio_port, io->pio_port + i);
#endif
	}
}

static void vcpu_run_and_verify_io_exit(struct kvm_vcpu *vcpu,
					struct kvm_coalesced_io *io,
					u32 ring_start,
					u32 expected_exit)
{
	const bool want_pio = expected_exit == KVM_EXIT_IO;
	struct kvm_coalesced_mmio_ring *ring = io->ring;
	struct kvm_run *run = vcpu->run;
	u32 pio_value;

	WRITE_ONCE(ring->first, ring_start);
	WRITE_ONCE(ring->last, ring_start);

	vcpu_run(vcpu);

	/*
	 * Annoyingly, reading PIO data is safe only for PIO exits, otherwise
	 * data_offset is garbage, e.g. an MMIO gpa.
	 */
	if (run->exit_reason == KVM_EXIT_IO)
		pio_value = *(u32 *)((void *)run + run->io.data_offset);
	else
		pio_value = 0;

	TEST_ASSERT((!want_pio && (run->exit_reason == KVM_EXIT_MMIO && run->mmio.is_write &&
				   run->mmio.phys_addr == io->mmio_gpa && run->mmio.len == 8 &&
				   *(u64 *)run->mmio.data == io->mmio_gpa + io->ring_size - 1)) ||
		    (want_pio  && (run->exit_reason == KVM_EXIT_IO && run->io.port == io->pio_port &&
				   run->io.direction == KVM_EXIT_IO_OUT && run->io.count == 1 &&
				   pio_value == io->pio_port + io->ring_size - 1)),
		    "For start = %u, expected exit on %u-byte %s write 0x%llx = %lx, got exit_reason = %u (%s)\n  "
		    "(MMIO addr = 0x%llx, write = %u, len = %u, data = %lx)\n  "
		    "(PIO port = 0x%x, write = %u, len = %u, count = %u, data = %x",
		    ring_start, want_pio ? 4 : 8, want_pio ? "PIO" : "MMIO",
		    want_pio ? (unsigned long long)io->pio_port : io->mmio_gpa,
		    (want_pio ? io->pio_port : io->mmio_gpa) + io->ring_size - 1, run->exit_reason,
		    run->exit_reason == KVM_EXIT_MMIO ? "MMIO" : run->exit_reason == KVM_EXIT_IO ? "PIO" : "other",
		    run->mmio.phys_addr, run->mmio.is_write, run->mmio.len, *(u64 *)run->mmio.data,
		    run->io.port, run->io.direction, run->io.size, run->io.count, pio_value);
}

static void vcpu_run_and_verify_coalesced_io(struct kvm_vcpu *vcpu,
					     struct kvm_coalesced_io *io,
					     u32 ring_start,
					     u32 expected_exit)
{
	struct kvm_coalesced_mmio_ring *ring = io->ring;
	int i;

	vcpu_run_and_verify_io_exit(vcpu, io, ring_start, expected_exit);

	TEST_ASSERT((ring->last + 1) % io->ring_size == ring->first,
		    "Expected ring to be full (minus 1), first = %u, last = %u, max = %u, start = %u",
		    ring->first, ring->last, io->ring_size, ring_start);

	for (i = 0; i < io->ring_size - 1; i++) {
		u32 idx = (ring->first + i) % io->ring_size;
		struct kvm_coalesced_mmio *entry = &ring->coalesced_mmio[idx];

#ifdef __x86_64__
		if (i & 1)
			TEST_ASSERT(entry->phys_addr == io->pio_port &&
				    entry->len == 4 && entry->pio &&
				    *(u32 *)entry->data == io->pio_port + i,
				    "Wanted 4-byte port I/O 0x%x = 0x%x in entry %u, got %u-byte %s 0x%llx = 0x%x",
				    io->pio_port, io->pio_port + i, i,
				    entry->len, entry->pio ? "PIO" : "MMIO",
				    entry->phys_addr, *(u32 *)entry->data);
		else
#endif
			TEST_ASSERT(entry->phys_addr == io->mmio_gpa &&
				    entry->len == 8 && !entry->pio,
				    "Wanted 8-byte MMIO to 0x%lx = %lx in entry %u, got %u-byte %s 0x%llx = 0x%lx",
				    io->mmio_gpa, io->mmio_gpa + i, i,
				    entry->len, entry->pio ? "PIO" : "MMIO",
				    entry->phys_addr, *(u64 *)entry->data);
	}
}

static void test_coalesced_io(struct kvm_vcpu *vcpu,
			      struct kvm_coalesced_io *io, u32 ring_start)
{
	struct kvm_coalesced_mmio_ring *ring = io->ring;

	kvm_vm_register_coalesced_io(vcpu->vm, io->mmio_gpa, 8, false /* pio */);
#ifdef __x86_64__
	kvm_vm_register_coalesced_io(vcpu->vm, io->pio_port, 8, true /* pio */);
#endif

	vcpu_run_and_verify_coalesced_io(vcpu, io, ring_start, KVM_EXIT_MMIO);
#ifdef __x86_64__
	vcpu_run_and_verify_coalesced_io(vcpu, io, ring_start, KVM_EXIT_IO);
#endif

	/*
	 * Verify ucall, which may use non-coalesced MMIO or PIO, generates an
	 * immediate exit.
	 */
	WRITE_ONCE(ring->first, ring_start);
	WRITE_ONCE(ring->last, ring_start);
	vcpu_run(vcpu);
	TEST_ASSERT_EQ(get_ucall(vcpu, NULL), UCALL_SYNC);
	TEST_ASSERT_EQ(ring->first, ring_start);
	TEST_ASSERT_EQ(ring->last, ring_start);

	/* Verify that non-coalesced MMIO/PIO generates an exit to userspace. */
	kvm_vm_unregister_coalesced_io(vcpu->vm, io->mmio_gpa, 8, false /* pio */);
	vcpu_run_and_verify_io_exit(vcpu, io, ring_start, KVM_EXIT_MMIO);

#ifdef __x86_64__
	kvm_vm_unregister_coalesced_io(vcpu->vm, io->pio_port, 8, true /* pio */);
	vcpu_run_and_verify_io_exit(vcpu, io, ring_start, KVM_EXIT_IO);
#endif
}

int main(int argc, char *argv[])
{
	struct kvm_vcpu *vcpu;
	struct kvm_vm *vm;
	int i;

	TEST_REQUIRE(kvm_has_cap(KVM_CAP_COALESCED_MMIO));

#ifdef __x86_64__
	TEST_REQUIRE(kvm_has_cap(KVM_CAP_COALESCED_PIO));
#endif

	vm = vm_create_with_one_vcpu(&vcpu, guest_code);

	kvm_builtin_io_ring = (struct kvm_coalesced_io) {
		/*
		 * The I/O ring is a kernel-allocated page whose address is
		 * relative to each vCPU's run page, with the page offset
		 * provided by KVM in the return of KVM_CAP_COALESCED_MMIO.
		 */
		.ring = (void *)vcpu->run +
			(kvm_check_cap(KVM_CAP_COALESCED_MMIO) * getpagesize()),

		/*
		 * The size of the I/O ring is fixed, but KVM defines the sized
		 * based on the kernel's PAGE_SIZE.  Thus, userspace must query
		 * the host's page size at runtime to compute the ring size.
		 */
		.ring_size = (getpagesize() - sizeof(struct kvm_coalesced_mmio_ring)) /
			     sizeof(struct kvm_coalesced_mmio),

		/*
		 * Arbitrary address+port (MMIO mustn't overlap memslots), with
		 * the MMIO GPA identity mapped in the guest.
		 */
		.mmio_gpa = 4ull * SZ_1G,
		.mmio = (u64 *)(4ull * SZ_1G),
		.pio_port = 0x80,
	};

	virt_map(vm, (u64)kvm_builtin_io_ring.mmio, kvm_builtin_io_ring.mmio_gpa, 1);

	sync_global_to_guest(vm, kvm_builtin_io_ring);
	vcpu_args_set(vcpu, 1, &kvm_builtin_io_ring);

	for (i = 0; i < kvm_builtin_io_ring.ring_size; i++)
		test_coalesced_io(vcpu, &kvm_builtin_io_ring, i);

	kvm_vm_free(vm);
	return 0;
}
