// SPDX-License-Identifier: GPL-2.0+

/*
 * Copyright 2018-2019 IBM Corporation.
 */

#define __SANE_USERSPACE_TYPES__

#include <sys/types.h>
#include <stdint.h>
#include <malloc.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/prctl.h>
#include "utils.h"

#include "../pmu/event.h"


extern void pattern_cache_loop(void);
extern void indirect_branch_loop(void);

static int do_count_loop(struct event *events, bool is_p9, s64 *miss_percent)
{
	u64 pred, mpred;

	prctl(PR_TASK_PERF_EVENTS_ENABLE);

	if (is_p9)
		pattern_cache_loop();
	else
		indirect_branch_loop();

	prctl(PR_TASK_PERF_EVENTS_DISABLE);

	event_read(&events[0]);
	event_read(&events[1]);

	// We could scale all the events by running/enabled but we're lazy
	// As long as the PMU is uncontended they should all run
	FAIL_IF(events[0].result.running != events[0].result.enabled);
	FAIL_IF(events[1].result.running != events[1].result.enabled);

	pred =  events[0].result.value;
	mpred = events[1].result.value;

	if (is_p9) {
		event_read(&events[2]);
		event_read(&events[3]);
		FAIL_IF(events[2].result.running != events[2].result.enabled);
		FAIL_IF(events[3].result.running != events[3].result.enabled);

		pred  += events[2].result.value;
		mpred += events[3].result.value;
	}

	*miss_percent = 100 * mpred / pred;

	return 0;
}

static void setup_event(struct event *e, u64 config, char *name)
{
	event_init_named(e, config, name);

	e->attr.disabled = 1;
	e->attr.exclude_kernel = 1;
	e->attr.exclude_hv = 1;
	e->attr.exclude_idle = 1;
}

enum spectre_v2_state {
	VULNERABLE = 0,
	UNKNOWN = 1,		// Works with FAIL_IF()
	NOT_AFFECTED,
	BRANCH_SERIALISATION,
	COUNT_CACHE_DISABLED,
	COUNT_CACHE_FLUSH_SW,
	COUNT_CACHE_FLUSH_HW,
	BTB_FLUSH,
};

static enum spectre_v2_state get_sysfs_state(void)
{
	enum spectre_v2_state state = UNKNOWN;
	char buf[256];
	int len;

	memset(buf, 0, sizeof(buf));
	FAIL_IF(read_sysfs_file("devices/system/cpu/vulnerabilities/spectre_v2", buf, sizeof(buf)));

	// Make sure it's NULL terminated
	buf[sizeof(buf) - 1] = '\0';

	// Trim the trailing newline
	len = strlen(buf);
	FAIL_IF(len < 1);
	buf[len - 1] = '\0';

	printf("sysfs reports: '%s'\n", buf);

	// Order matters
	if (strstr(buf, "Vulnerable"))
		state = VULNERABLE;
	else if (strstr(buf, "Not affected"))
		state = NOT_AFFECTED;
	else if (strstr(buf, "Indirect branch serialisation (kernel only)"))
		state = BRANCH_SERIALISATION;
	else if (strstr(buf, "Indirect branch cache disabled"))
		state = COUNT_CACHE_DISABLED;
	else if (strstr(buf, "Software count cache flush (hardware accelerated)"))
		state = COUNT_CACHE_FLUSH_HW;
	else if (strstr(buf, "Software count cache flush"))
		state = COUNT_CACHE_FLUSH_SW;
	else if (strstr(buf, "Branch predictor state flush"))
		state = BTB_FLUSH;

	return state;
}

#define PM_BR_PRED_CCACHE	0x040a4	// P8 + P9
#define PM_BR_MPRED_CCACHE	0x040ac	// P8 + P9
#define PM_BR_PRED_PCACHE	0x048a0	// P9 only
#define PM_BR_MPRED_PCACHE	0x048b0	// P9 only

#define SPRN_PVR 287

int spectre_v2_test(void)
{
	enum spectre_v2_state state;
	struct event events[4];
	s64 miss_percent;
	bool is_p9;

	// The PMU events we use only work on Power8 or later
	SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07));

	state = get_sysfs_state();
	if (state == UNKNOWN) {
		printf("Error: couldn't determine spectre_v2 mitigation state?\n");
		return -1;
	}

	memset(events, 0, sizeof(events));

	setup_event(&events[0], PM_BR_PRED_CCACHE,  "PM_BR_PRED_CCACHE");
	setup_event(&events[1], PM_BR_MPRED_CCACHE, "PM_BR_MPRED_CCACHE");
	FAIL_IF(event_open(&events[0]));
	FAIL_IF(event_open_with_group(&events[1], events[0].fd) == -1);

	is_p9 = ((mfspr(SPRN_PVR) >>  16) & 0xFFFF) == 0x4e;

	if (is_p9) {
		// Count pattern cache too
		setup_event(&events[2], PM_BR_PRED_PCACHE,  "PM_BR_PRED_PCACHE");
		setup_event(&events[3], PM_BR_MPRED_PCACHE, "PM_BR_MPRED_PCACHE");

		FAIL_IF(event_open_with_group(&events[2], events[0].fd) == -1);
		FAIL_IF(event_open_with_group(&events[3], events[0].fd) == -1);
	}

	FAIL_IF(do_count_loop(events, is_p9, &miss_percent));

	event_report_justified(&events[0], 18, 10);
	event_report_justified(&events[1], 18, 10);
	event_close(&events[0]);
	event_close(&events[1]);

	if (is_p9) {
		event_report_justified(&events[2], 18, 10);
		event_report_justified(&events[3], 18, 10);
		event_close(&events[2]);
		event_close(&events[3]);
	}

	printf("Miss percent %lld %%\n", miss_percent);

	switch (state) {
	case VULNERABLE:
	case NOT_AFFECTED:
	case COUNT_CACHE_FLUSH_SW:
	case COUNT_CACHE_FLUSH_HW:
		// These should all not affect userspace branch prediction
		if (miss_percent > 15) {
			printf("Branch misses > 15%% unexpected in this configuration!\n");
			printf("Possible mis-match between reported & actual mitigation\n");
			/*
			 * Such a mismatch may be caused by a guest system
			 * reporting as vulnerable when the host is mitigated.
			 * Return skip code to avoid detecting this as an error.
			 * We are not vulnerable and reporting otherwise, so
			 * missing such a mismatch is safe.
			 */
			if (miss_percent > 95)
				return 4;

			return 1;
		}
		break;
	case BRANCH_SERIALISATION:
		// This seems to affect userspace branch prediction a bit?
		if (miss_percent > 25) {
			printf("Branch misses > 25%% unexpected in this configuration!\n");
			printf("Possible mis-match between reported & actual mitigation\n");
			return 1;
		}
		break;
	case COUNT_CACHE_DISABLED:
		if (miss_percent < 95) {
			printf("Branch misses < 20%% unexpected in this configuration!\n");
			printf("Possible mis-match between reported & actual mitigation\n");
			return 1;
		}
		break;
	case UNKNOWN:
	case BTB_FLUSH:
		printf("Not sure!\n");
		return 1;
	}

	printf("OK - Measured branch prediction rates match reported spectre v2 mitigation.\n");

	return 0;
}

int main(int argc, char *argv[])
{
	return test_harness(spectre_v2_test, "spectre_v2");
}
