// 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 (state == VULNERABLE)
				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");
}
