// SPDX-License-Identifier: GPL-2.0
/*
 * A test for GUEST_PRINTF
 *
 * Copyright 2022, Google, Inc. and/or its affiliates.
 */
#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"

struct guest_vals {
	uint64_t a;
	uint64_t b;
	uint64_t type;
};

static struct guest_vals vals;

/* GUEST_PRINTF()/GUEST_ASSERT_FMT() does not support float or double. */
#define TYPE_LIST					\
TYPE(test_type_i64,  I64,  "%ld",   int64_t)		\
TYPE(test_type_u64,  U64u, "%lu",   uint64_t)		\
TYPE(test_type_x64,  U64x, "0x%lx", uint64_t)		\
TYPE(test_type_X64,  U64X, "0x%lX", uint64_t)		\
TYPE(test_type_u32,  U32u, "%u",    uint32_t)		\
TYPE(test_type_x32,  U32x, "0x%x",  uint32_t)		\
TYPE(test_type_X32,  U32X, "0x%X",  uint32_t)		\
TYPE(test_type_int,  INT,  "%d",    int)		\
TYPE(test_type_char, CHAR, "%c",    char)		\
TYPE(test_type_str,  STR,  "'%s'",  const char *)	\
TYPE(test_type_ptr,  PTR,  "%p",    uintptr_t)

enum args_type {
#define TYPE(fn, ext, fmt_t, T) TYPE_##ext,
	TYPE_LIST
#undef TYPE
};

static void run_test(struct kvm_vcpu *vcpu, const char *expected_printf,
		     const char *expected_assert);

#define BUILD_TYPE_STRINGS_AND_HELPER(fn, ext, fmt_t, T)		     \
const char *PRINTF_FMT_##ext = "Got params a = " fmt_t " and b = " fmt_t;    \
const char *ASSERT_FMT_##ext = "Expected " fmt_t ", got " fmt_t " instead";  \
static void fn(struct kvm_vcpu *vcpu, T a, T b)				     \
{									     \
	char expected_printf[UCALL_BUFFER_LEN];				     \
	char expected_assert[UCALL_BUFFER_LEN];				     \
									     \
	snprintf(expected_printf, UCALL_BUFFER_LEN, PRINTF_FMT_##ext, a, b); \
	snprintf(expected_assert, UCALL_BUFFER_LEN, ASSERT_FMT_##ext, a, b); \
	vals = (struct guest_vals){ (uint64_t)a, (uint64_t)b, TYPE_##ext };  \
	sync_global_to_guest(vcpu->vm, vals);				     \
	run_test(vcpu, expected_printf, expected_assert);		     \
}

#define TYPE(fn, ext, fmt_t, T) \
		BUILD_TYPE_STRINGS_AND_HELPER(fn, ext, fmt_t, T)
	TYPE_LIST
#undef TYPE

static void guest_code(void)
{
	while (1) {
		switch (vals.type) {
#define TYPE(fn, ext, fmt_t, T)							\
		case TYPE_##ext:						\
			GUEST_PRINTF(PRINTF_FMT_##ext, vals.a, vals.b);		\
			__GUEST_ASSERT(vals.a == vals.b,			\
				       ASSERT_FMT_##ext, vals.a, vals.b);	\
			break;
		TYPE_LIST
#undef TYPE
		default:
			GUEST_SYNC(vals.type);
		}

		GUEST_DONE();
	}
}

/*
 * Unfortunately this gets a little messy because 'assert_msg' doesn't
 * just contains the matching string, it also contains additional assert
 * info.  Fortunately the part that matches should be at the very end of
 * 'assert_msg'.
 */
static void ucall_abort(const char *assert_msg, const char *expected_assert_msg)
{
	int len_str = strlen(assert_msg);
	int len_substr = strlen(expected_assert_msg);
	int offset = len_str - len_substr;

	TEST_ASSERT(len_substr <= len_str,
		    "Expected '%s' to be a substring of '%s'\n",
		    assert_msg, expected_assert_msg);

	TEST_ASSERT(strcmp(&assert_msg[offset], expected_assert_msg) == 0,
		    "Unexpected mismatch. Expected: '%s', got: '%s'",
		    expected_assert_msg, &assert_msg[offset]);
}

static void run_test(struct kvm_vcpu *vcpu, const char *expected_printf,
		     const char *expected_assert)
{
	struct kvm_run *run = vcpu->run;
	struct ucall uc;

	while (1) {
		vcpu_run(vcpu);

		TEST_ASSERT(run->exit_reason == UCALL_EXIT_REASON,
			    "Unexpected exit reason: %u (%s),\n",
			    run->exit_reason, exit_reason_str(run->exit_reason));

		switch (get_ucall(vcpu, &uc)) {
		case UCALL_SYNC:
			TEST_FAIL("Unknown 'args_type' = %lu", uc.args[1]);
			break;
		case UCALL_PRINTF:
			TEST_ASSERT(strcmp(uc.buffer, expected_printf) == 0,
				    "Unexpected mismatch. Expected: '%s', got: '%s'",
				    expected_printf, uc.buffer);
			break;
		case UCALL_ABORT:
			ucall_abort(uc.buffer, expected_assert);
			break;
		case UCALL_DONE:
			return;
		default:
			TEST_FAIL("Unknown ucall %lu", uc.cmd);
		}
	}
}

static void guest_code_limits(void)
{
	char test_str[UCALL_BUFFER_LEN + 10];

	memset(test_str, 'a', sizeof(test_str));
	test_str[sizeof(test_str) - 1] = 0;

	GUEST_PRINTF("%s", test_str);
}

static void test_limits(void)
{
	struct kvm_vcpu *vcpu;
	struct kvm_run *run;
	struct kvm_vm *vm;
	struct ucall uc;

	vm = vm_create_with_one_vcpu(&vcpu, guest_code_limits);
	run = vcpu->run;
	vcpu_run(vcpu);

	TEST_ASSERT(run->exit_reason == UCALL_EXIT_REASON,
		    "Unexpected exit reason: %u (%s),\n",
		    run->exit_reason, exit_reason_str(run->exit_reason));

	TEST_ASSERT(get_ucall(vcpu, &uc) == UCALL_ABORT,
		    "Unexpected ucall command: %lu,  Expected: %u (UCALL_ABORT)\n",
		    uc.cmd, UCALL_ABORT);

	kvm_vm_free(vm);
}

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

	vm = vm_create_with_one_vcpu(&vcpu, guest_code);

	test_type_i64(vcpu, -1, -1);
	test_type_i64(vcpu, -1,  1);
	test_type_i64(vcpu, 0x1234567890abcdef, 0x1234567890abcdef);
	test_type_i64(vcpu, 0x1234567890abcdef, 0x1234567890abcdee);

	test_type_u64(vcpu, 0x1234567890abcdef, 0x1234567890abcdef);
	test_type_u64(vcpu, 0x1234567890abcdef, 0x1234567890abcdee);
	test_type_x64(vcpu, 0x1234567890abcdef, 0x1234567890abcdef);
	test_type_x64(vcpu, 0x1234567890abcdef, 0x1234567890abcdee);
	test_type_X64(vcpu, 0x1234567890abcdef, 0x1234567890abcdef);
	test_type_X64(vcpu, 0x1234567890abcdef, 0x1234567890abcdee);

	test_type_u32(vcpu, 0x90abcdef, 0x90abcdef);
	test_type_u32(vcpu, 0x90abcdef, 0x90abcdee);
	test_type_x32(vcpu, 0x90abcdef, 0x90abcdef);
	test_type_x32(vcpu, 0x90abcdef, 0x90abcdee);
	test_type_X32(vcpu, 0x90abcdef, 0x90abcdef);
	test_type_X32(vcpu, 0x90abcdef, 0x90abcdee);

	test_type_int(vcpu, -1, -1);
	test_type_int(vcpu, -1,  1);
	test_type_int(vcpu,  1,  1);

	test_type_char(vcpu, 'a', 'a');
	test_type_char(vcpu, 'a', 'A');
	test_type_char(vcpu, 'a', 'b');

	test_type_str(vcpu, "foo", "foo");
	test_type_str(vcpu, "foo", "bar");

	test_type_ptr(vcpu, 0x1234567890abcdef, 0x1234567890abcdef);
	test_type_ptr(vcpu, 0x1234567890abcdef, 0x1234567890abcdee);

	kvm_vm_free(vm);

	test_limits();

	return 0;
}
