// SPDX-License-Identifier: GPL-2.0
/*
 * Linux Guest Relocation (LGR) detection
 *
 * Copyright IBM Corp. 2012
 * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
 */

#include <linux/init.h>
#include <linux/export.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <asm/facility.h>
#include <asm/sysinfo.h>
#include <asm/ebcdic.h>
#include <asm/debug.h>
#include <asm/ipl.h>

#define LGR_TIMER_INTERVAL_SECS (30 * 60)
#define VM_LEVEL_MAX 2 /* Maximum is 8, but we only record two levels */

/*
 * LGR info: Contains stfle and stsi data
 */
struct lgr_info {
	/* Bit field with facility information: 4 DWORDs are stored */
	u64 stfle_fac_list[4];
	/* Level of system (1 = CEC, 2 = LPAR, 3 = z/VM */
	u32 level;
	/* Level 1: CEC info (stsi 1.1.1) */
	char manufacturer[16];
	char type[4];
	char sequence[16];
	char plant[4];
	char model[16];
	/* Level 2: LPAR info (stsi 2.2.2) */
	u16 lpar_number;
	char name[8];
	/* Level 3: VM info (stsi 3.2.2) */
	u8 vm_count;
	struct {
		char name[8];
		char cpi[16];
	} vm[VM_LEVEL_MAX];
} __packed __aligned(8);

/*
 * LGR globals
 */
static char lgr_page[PAGE_SIZE] __aligned(PAGE_SIZE);
static struct lgr_info lgr_info_last;
static struct lgr_info lgr_info_cur;
static struct debug_info *lgr_dbf;

/*
 * Copy buffer and then convert it to ASCII
 */
static void cpascii(char *dst, char *src, int size)
{
	memcpy(dst, src, size);
	EBCASC(dst, size);
}

/*
 * Fill LGR info with 1.1.1 stsi data
 */
static void lgr_stsi_1_1_1(struct lgr_info *lgr_info)
{
	struct sysinfo_1_1_1 *si = (void *) lgr_page;

	if (stsi(si, 1, 1, 1))
		return;
	cpascii(lgr_info->manufacturer, si->manufacturer,
		sizeof(si->manufacturer));
	cpascii(lgr_info->type, si->type, sizeof(si->type));
	cpascii(lgr_info->model, si->model, sizeof(si->model));
	cpascii(lgr_info->sequence, si->sequence, sizeof(si->sequence));
	cpascii(lgr_info->plant, si->plant, sizeof(si->plant));
}

/*
 * Fill LGR info with 2.2.2 stsi data
 */
static void lgr_stsi_2_2_2(struct lgr_info *lgr_info)
{
	struct sysinfo_2_2_2 *si = (void *) lgr_page;

	if (stsi(si, 2, 2, 2))
		return;
	cpascii(lgr_info->name, si->name, sizeof(si->name));
	memcpy(&lgr_info->lpar_number, &si->lpar_number,
	       sizeof(lgr_info->lpar_number));
}

/*
 * Fill LGR info with 3.2.2 stsi data
 */
static void lgr_stsi_3_2_2(struct lgr_info *lgr_info)
{
	struct sysinfo_3_2_2 *si = (void *) lgr_page;
	int i;

	if (stsi(si, 3, 2, 2))
		return;
	for (i = 0; i < min_t(u8, si->count, VM_LEVEL_MAX); i++) {
		cpascii(lgr_info->vm[i].name, si->vm[i].name,
			sizeof(si->vm[i].name));
		cpascii(lgr_info->vm[i].cpi, si->vm[i].cpi,
			sizeof(si->vm[i].cpi));
	}
	lgr_info->vm_count = si->count;
}

/*
 * Fill LGR info with current data
 */
static void lgr_info_get(struct lgr_info *lgr_info)
{
	int level;

	memset(lgr_info, 0, sizeof(*lgr_info));
	stfle(lgr_info->stfle_fac_list, ARRAY_SIZE(lgr_info->stfle_fac_list));
	level = stsi(NULL, 0, 0, 0);
	lgr_info->level = level;
	if (level >= 1)
		lgr_stsi_1_1_1(lgr_info);
	if (level >= 2)
		lgr_stsi_2_2_2(lgr_info);
	if (level >= 3)
		lgr_stsi_3_2_2(lgr_info);
}

/*
 * Check if LGR info has changed and if yes log new LGR info to s390dbf
 */
void lgr_info_log(void)
{
	static DEFINE_SPINLOCK(lgr_info_lock);
	unsigned long flags;

	if (!spin_trylock_irqsave(&lgr_info_lock, flags))
		return;
	lgr_info_get(&lgr_info_cur);
	if (memcmp(&lgr_info_last, &lgr_info_cur, sizeof(lgr_info_cur)) != 0) {
		debug_event(lgr_dbf, 1, &lgr_info_cur, sizeof(lgr_info_cur));
		lgr_info_last = lgr_info_cur;
	}
	spin_unlock_irqrestore(&lgr_info_lock, flags);
}
EXPORT_SYMBOL_GPL(lgr_info_log);

static void lgr_timer_set(void);

/*
 * LGR timer callback
 */
static void lgr_timer_fn(struct timer_list *unused)
{
	lgr_info_log();
	lgr_timer_set();
}

static struct timer_list lgr_timer;

/*
 * Setup next LGR timer
 */
static void lgr_timer_set(void)
{
	mod_timer(&lgr_timer, jiffies + msecs_to_jiffies(LGR_TIMER_INTERVAL_SECS * MSEC_PER_SEC));
}

/*
 * Initialize LGR: Add s390dbf, write initial lgr_info and setup timer
 */
static int __init lgr_init(void)
{
	lgr_dbf = debug_register("lgr", 1, 1, sizeof(struct lgr_info));
	if (!lgr_dbf)
		return -ENOMEM;
	debug_register_view(lgr_dbf, &debug_hex_ascii_view);
	lgr_info_get(&lgr_info_last);
	debug_event(lgr_dbf, 1, &lgr_info_last, sizeof(lgr_info_last));
	timer_setup(&lgr_timer, lgr_timer_fn, TIMER_DEFERRABLE);
	lgr_timer_set();
	return 0;
}
device_initcall(lgr_init);
