cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mdesc.c (30980B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* mdesc.c: Sun4V machine description handling.
      3 *
      4 * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
      5 */
      6#include <linux/kernel.h>
      7#include <linux/types.h>
      8#include <linux/log2.h>
      9#include <linux/list.h>
     10#include <linux/slab.h>
     11#include <linux/mm.h>
     12#include <linux/miscdevice.h>
     13#include <linux/memblock.h>
     14#include <linux/export.h>
     15#include <linux/refcount.h>
     16
     17#include <asm/cpudata.h>
     18#include <asm/hypervisor.h>
     19#include <asm/mdesc.h>
     20#include <asm/prom.h>
     21#include <linux/uaccess.h>
     22#include <asm/oplib.h>
     23#include <asm/smp.h>
     24#include <asm/adi.h>
     25
     26/* Unlike the OBP device tree, the machine description is a full-on
     27 * DAG.  An arbitrary number of ARCs are possible from one
     28 * node to other nodes and thus we can't use the OBP device_node
     29 * data structure to represent these nodes inside of the kernel.
     30 *
     31 * Actually, it isn't even a DAG, because there are back pointers
     32 * which create cycles in the graph.
     33 *
     34 * mdesc_hdr and mdesc_elem describe the layout of the data structure
     35 * we get from the Hypervisor.
     36 */
     37struct mdesc_hdr {
     38	u32	version; /* Transport version */
     39	u32	node_sz; /* node block size */
     40	u32	name_sz; /* name block size */
     41	u32	data_sz; /* data block size */
     42	char	data[];
     43} __attribute__((aligned(16)));
     44
     45struct mdesc_elem {
     46	u8	tag;
     47#define MD_LIST_END	0x00
     48#define MD_NODE		0x4e
     49#define MD_NODE_END	0x45
     50#define MD_NOOP		0x20
     51#define MD_PROP_ARC	0x61
     52#define MD_PROP_VAL	0x76
     53#define MD_PROP_STR	0x73
     54#define MD_PROP_DATA	0x64
     55	u8	name_len;
     56	u16	resv;
     57	u32	name_offset;
     58	union {
     59		struct {
     60			u32	data_len;
     61			u32	data_offset;
     62		} data;
     63		u64	val;
     64	} d;
     65};
     66
     67struct mdesc_mem_ops {
     68	struct mdesc_handle *(*alloc)(unsigned int mdesc_size);
     69	void (*free)(struct mdesc_handle *handle);
     70};
     71
     72struct mdesc_handle {
     73	struct list_head	list;
     74	struct mdesc_mem_ops	*mops;
     75	void			*self_base;
     76	refcount_t		refcnt;
     77	unsigned int		handle_size;
     78	struct mdesc_hdr	mdesc;
     79};
     80
     81typedef int (*mdesc_node_info_get_f)(struct mdesc_handle *, u64,
     82				     union md_node_info *);
     83typedef void (*mdesc_node_info_rel_f)(union md_node_info *);
     84typedef bool (*mdesc_node_match_f)(union md_node_info *, union md_node_info *);
     85
     86struct md_node_ops {
     87	char			*name;
     88	mdesc_node_info_get_f	get_info;
     89	mdesc_node_info_rel_f	rel_info;
     90	mdesc_node_match_f	node_match;
     91};
     92
     93static int get_vdev_port_node_info(struct mdesc_handle *md, u64 node,
     94				   union md_node_info *node_info);
     95static void rel_vdev_port_node_info(union md_node_info *node_info);
     96static bool vdev_port_node_match(union md_node_info *a_node_info,
     97				 union md_node_info *b_node_info);
     98
     99static int get_ds_port_node_info(struct mdesc_handle *md, u64 node,
    100				 union md_node_info *node_info);
    101static void rel_ds_port_node_info(union md_node_info *node_info);
    102static bool ds_port_node_match(union md_node_info *a_node_info,
    103			       union md_node_info *b_node_info);
    104
    105/* supported node types which can be registered */
    106static struct md_node_ops md_node_ops_table[] = {
    107	{"virtual-device-port", get_vdev_port_node_info,
    108	 rel_vdev_port_node_info, vdev_port_node_match},
    109	{"domain-services-port", get_ds_port_node_info,
    110	 rel_ds_port_node_info, ds_port_node_match},
    111	{NULL, NULL, NULL, NULL}
    112};
    113
    114static void mdesc_get_node_ops(const char *node_name,
    115			       mdesc_node_info_get_f *get_info_f,
    116			       mdesc_node_info_rel_f *rel_info_f,
    117			       mdesc_node_match_f *match_f)
    118{
    119	int i;
    120
    121	if (get_info_f)
    122		*get_info_f = NULL;
    123
    124	if (rel_info_f)
    125		*rel_info_f = NULL;
    126
    127	if (match_f)
    128		*match_f = NULL;
    129
    130	if (!node_name)
    131		return;
    132
    133	for (i = 0; md_node_ops_table[i].name != NULL; i++) {
    134		if (strcmp(md_node_ops_table[i].name, node_name) == 0) {
    135			if (get_info_f)
    136				*get_info_f = md_node_ops_table[i].get_info;
    137
    138			if (rel_info_f)
    139				*rel_info_f = md_node_ops_table[i].rel_info;
    140
    141			if (match_f)
    142				*match_f = md_node_ops_table[i].node_match;
    143
    144			break;
    145		}
    146	}
    147}
    148
    149static void mdesc_handle_init(struct mdesc_handle *hp,
    150			      unsigned int handle_size,
    151			      void *base)
    152{
    153	BUG_ON(((unsigned long)&hp->mdesc) & (16UL - 1));
    154
    155	memset(hp, 0, handle_size);
    156	INIT_LIST_HEAD(&hp->list);
    157	hp->self_base = base;
    158	refcount_set(&hp->refcnt, 1);
    159	hp->handle_size = handle_size;
    160}
    161
    162static struct mdesc_handle * __init mdesc_memblock_alloc(unsigned int mdesc_size)
    163{
    164	unsigned int handle_size, alloc_size;
    165	struct mdesc_handle *hp;
    166	unsigned long paddr;
    167
    168	handle_size = (sizeof(struct mdesc_handle) -
    169		       sizeof(struct mdesc_hdr) +
    170		       mdesc_size);
    171	alloc_size = PAGE_ALIGN(handle_size);
    172
    173	paddr = memblock_phys_alloc(alloc_size, PAGE_SIZE);
    174
    175	hp = NULL;
    176	if (paddr) {
    177		hp = __va(paddr);
    178		mdesc_handle_init(hp, handle_size, hp);
    179	}
    180	return hp;
    181}
    182
    183static void __init mdesc_memblock_free(struct mdesc_handle *hp)
    184{
    185	unsigned int alloc_size;
    186	unsigned long start;
    187
    188	BUG_ON(refcount_read(&hp->refcnt) != 0);
    189	BUG_ON(!list_empty(&hp->list));
    190
    191	alloc_size = PAGE_ALIGN(hp->handle_size);
    192	start = __pa(hp);
    193	memblock_free_late(start, alloc_size);
    194}
    195
    196static struct mdesc_mem_ops memblock_mdesc_ops = {
    197	.alloc = mdesc_memblock_alloc,
    198	.free  = mdesc_memblock_free,
    199};
    200
    201static struct mdesc_handle *mdesc_kmalloc(unsigned int mdesc_size)
    202{
    203	unsigned int handle_size;
    204	struct mdesc_handle *hp;
    205	unsigned long addr;
    206	void *base;
    207
    208	handle_size = (sizeof(struct mdesc_handle) -
    209		       sizeof(struct mdesc_hdr) +
    210		       mdesc_size);
    211	base = kmalloc(handle_size + 15, GFP_KERNEL | __GFP_RETRY_MAYFAIL);
    212	if (!base)
    213		return NULL;
    214
    215	addr = (unsigned long)base;
    216	addr = (addr + 15UL) & ~15UL;
    217	hp = (struct mdesc_handle *) addr;
    218
    219	mdesc_handle_init(hp, handle_size, base);
    220
    221	return hp;
    222}
    223
    224static void mdesc_kfree(struct mdesc_handle *hp)
    225{
    226	BUG_ON(refcount_read(&hp->refcnt) != 0);
    227	BUG_ON(!list_empty(&hp->list));
    228
    229	kfree(hp->self_base);
    230}
    231
    232static struct mdesc_mem_ops kmalloc_mdesc_memops = {
    233	.alloc = mdesc_kmalloc,
    234	.free  = mdesc_kfree,
    235};
    236
    237static struct mdesc_handle *mdesc_alloc(unsigned int mdesc_size,
    238					struct mdesc_mem_ops *mops)
    239{
    240	struct mdesc_handle *hp = mops->alloc(mdesc_size);
    241
    242	if (hp)
    243		hp->mops = mops;
    244
    245	return hp;
    246}
    247
    248static void mdesc_free(struct mdesc_handle *hp)
    249{
    250	hp->mops->free(hp);
    251}
    252
    253static struct mdesc_handle *cur_mdesc;
    254static LIST_HEAD(mdesc_zombie_list);
    255static DEFINE_SPINLOCK(mdesc_lock);
    256
    257struct mdesc_handle *mdesc_grab(void)
    258{
    259	struct mdesc_handle *hp;
    260	unsigned long flags;
    261
    262	spin_lock_irqsave(&mdesc_lock, flags);
    263	hp = cur_mdesc;
    264	if (hp)
    265		refcount_inc(&hp->refcnt);
    266	spin_unlock_irqrestore(&mdesc_lock, flags);
    267
    268	return hp;
    269}
    270EXPORT_SYMBOL(mdesc_grab);
    271
    272void mdesc_release(struct mdesc_handle *hp)
    273{
    274	unsigned long flags;
    275
    276	spin_lock_irqsave(&mdesc_lock, flags);
    277	if (refcount_dec_and_test(&hp->refcnt)) {
    278		list_del_init(&hp->list);
    279		hp->mops->free(hp);
    280	}
    281	spin_unlock_irqrestore(&mdesc_lock, flags);
    282}
    283EXPORT_SYMBOL(mdesc_release);
    284
    285static DEFINE_MUTEX(mdesc_mutex);
    286static struct mdesc_notifier_client *client_list;
    287
    288void mdesc_register_notifier(struct mdesc_notifier_client *client)
    289{
    290	bool supported = false;
    291	u64 node;
    292	int i;
    293
    294	mutex_lock(&mdesc_mutex);
    295
    296	/* check to see if the node is supported for registration */
    297	for (i = 0; md_node_ops_table[i].name != NULL; i++) {
    298		if (strcmp(md_node_ops_table[i].name, client->node_name) == 0) {
    299			supported = true;
    300			break;
    301		}
    302	}
    303
    304	if (!supported) {
    305		pr_err("MD: %s node not supported\n", client->node_name);
    306		mutex_unlock(&mdesc_mutex);
    307		return;
    308	}
    309
    310	client->next = client_list;
    311	client_list = client;
    312
    313	mdesc_for_each_node_by_name(cur_mdesc, node, client->node_name)
    314		client->add(cur_mdesc, node, client->node_name);
    315
    316	mutex_unlock(&mdesc_mutex);
    317}
    318
    319static const u64 *parent_cfg_handle(struct mdesc_handle *hp, u64 node)
    320{
    321	const u64 *id;
    322	u64 a;
    323
    324	id = NULL;
    325	mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) {
    326		u64 target;
    327
    328		target = mdesc_arc_target(hp, a);
    329		id = mdesc_get_property(hp, target,
    330					"cfg-handle", NULL);
    331		if (id)
    332			break;
    333	}
    334
    335	return id;
    336}
    337
    338static int get_vdev_port_node_info(struct mdesc_handle *md, u64 node,
    339				   union md_node_info *node_info)
    340{
    341	const u64 *parent_cfg_hdlp;
    342	const char *name;
    343	const u64 *idp;
    344
    345	/*
    346	 * Virtual device nodes are distinguished by:
    347	 * 1. "id" property
    348	 * 2. "name" property
    349	 * 3. parent node "cfg-handle" property
    350	 */
    351	idp = mdesc_get_property(md, node, "id", NULL);
    352	name = mdesc_get_property(md, node, "name", NULL);
    353	parent_cfg_hdlp = parent_cfg_handle(md, node);
    354
    355	if (!idp || !name || !parent_cfg_hdlp)
    356		return -1;
    357
    358	node_info->vdev_port.id = *idp;
    359	node_info->vdev_port.name = kstrdup_const(name, GFP_KERNEL);
    360	if (!node_info->vdev_port.name)
    361		return -1;
    362	node_info->vdev_port.parent_cfg_hdl = *parent_cfg_hdlp;
    363
    364	return 0;
    365}
    366
    367static void rel_vdev_port_node_info(union md_node_info *node_info)
    368{
    369	if (node_info && node_info->vdev_port.name) {
    370		kfree_const(node_info->vdev_port.name);
    371		node_info->vdev_port.name = NULL;
    372	}
    373}
    374
    375static bool vdev_port_node_match(union md_node_info *a_node_info,
    376				 union md_node_info *b_node_info)
    377{
    378	if (a_node_info->vdev_port.id != b_node_info->vdev_port.id)
    379		return false;
    380
    381	if (a_node_info->vdev_port.parent_cfg_hdl !=
    382	    b_node_info->vdev_port.parent_cfg_hdl)
    383		return false;
    384
    385	if (strncmp(a_node_info->vdev_port.name,
    386		    b_node_info->vdev_port.name, MDESC_MAX_STR_LEN) != 0)
    387		return false;
    388
    389	return true;
    390}
    391
    392static int get_ds_port_node_info(struct mdesc_handle *md, u64 node,
    393				 union md_node_info *node_info)
    394{
    395	const u64 *idp;
    396
    397	/* DS port nodes use the "id" property to distinguish them */
    398	idp = mdesc_get_property(md, node, "id", NULL);
    399	if (!idp)
    400		return -1;
    401
    402	node_info->ds_port.id = *idp;
    403
    404	return 0;
    405}
    406
    407static void rel_ds_port_node_info(union md_node_info *node_info)
    408{
    409}
    410
    411static bool ds_port_node_match(union md_node_info *a_node_info,
    412			       union md_node_info *b_node_info)
    413{
    414	if (a_node_info->ds_port.id != b_node_info->ds_port.id)
    415		return false;
    416
    417	return true;
    418}
    419
    420/* Run 'func' on nodes which are in A but not in B.  */
    421static void invoke_on_missing(const char *name,
    422			      struct mdesc_handle *a,
    423			      struct mdesc_handle *b,
    424			      void (*func)(struct mdesc_handle *, u64,
    425					   const char *node_name))
    426{
    427	mdesc_node_info_get_f get_info_func;
    428	mdesc_node_info_rel_f rel_info_func;
    429	mdesc_node_match_f node_match_func;
    430	union md_node_info a_node_info;
    431	union md_node_info b_node_info;
    432	bool found;
    433	u64 a_node;
    434	u64 b_node;
    435	int rv;
    436
    437	/*
    438	 * Find the get_info, rel_info and node_match ops for the given
    439	 * node name
    440	 */
    441	mdesc_get_node_ops(name, &get_info_func, &rel_info_func,
    442			   &node_match_func);
    443
    444	/* If we didn't find a match, the node type is not supported */
    445	if (!get_info_func || !rel_info_func || !node_match_func) {
    446		pr_err("MD: %s node type is not supported\n", name);
    447		return;
    448	}
    449
    450	mdesc_for_each_node_by_name(a, a_node, name) {
    451		found = false;
    452
    453		rv = get_info_func(a, a_node, &a_node_info);
    454		if (rv != 0) {
    455			pr_err("MD: Cannot find 1 or more required match properties for %s node.\n",
    456			       name);
    457			continue;
    458		}
    459
    460		/* Check each node in B for node matching a_node */
    461		mdesc_for_each_node_by_name(b, b_node, name) {
    462			rv = get_info_func(b, b_node, &b_node_info);
    463			if (rv != 0)
    464				continue;
    465
    466			if (node_match_func(&a_node_info, &b_node_info)) {
    467				found = true;
    468				rel_info_func(&b_node_info);
    469				break;
    470			}
    471
    472			rel_info_func(&b_node_info);
    473		}
    474
    475		rel_info_func(&a_node_info);
    476
    477		if (!found)
    478			func(a, a_node, name);
    479	}
    480}
    481
    482static void notify_one(struct mdesc_notifier_client *p,
    483		       struct mdesc_handle *old_hp,
    484		       struct mdesc_handle *new_hp)
    485{
    486	invoke_on_missing(p->node_name, old_hp, new_hp, p->remove);
    487	invoke_on_missing(p->node_name, new_hp, old_hp, p->add);
    488}
    489
    490static void mdesc_notify_clients(struct mdesc_handle *old_hp,
    491				 struct mdesc_handle *new_hp)
    492{
    493	struct mdesc_notifier_client *p = client_list;
    494
    495	while (p) {
    496		notify_one(p, old_hp, new_hp);
    497		p = p->next;
    498	}
    499}
    500
    501void mdesc_update(void)
    502{
    503	unsigned long len, real_len, status;
    504	struct mdesc_handle *hp, *orig_hp;
    505	unsigned long flags;
    506
    507	mutex_lock(&mdesc_mutex);
    508
    509	(void) sun4v_mach_desc(0UL, 0UL, &len);
    510
    511	hp = mdesc_alloc(len, &kmalloc_mdesc_memops);
    512	if (!hp) {
    513		printk(KERN_ERR "MD: mdesc alloc fails\n");
    514		goto out;
    515	}
    516
    517	status = sun4v_mach_desc(__pa(&hp->mdesc), len, &real_len);
    518	if (status != HV_EOK || real_len > len) {
    519		printk(KERN_ERR "MD: mdesc reread fails with %lu\n",
    520		       status);
    521		refcount_dec(&hp->refcnt);
    522		mdesc_free(hp);
    523		goto out;
    524	}
    525
    526	spin_lock_irqsave(&mdesc_lock, flags);
    527	orig_hp = cur_mdesc;
    528	cur_mdesc = hp;
    529	spin_unlock_irqrestore(&mdesc_lock, flags);
    530
    531	mdesc_notify_clients(orig_hp, hp);
    532
    533	spin_lock_irqsave(&mdesc_lock, flags);
    534	if (refcount_dec_and_test(&orig_hp->refcnt))
    535		mdesc_free(orig_hp);
    536	else
    537		list_add(&orig_hp->list, &mdesc_zombie_list);
    538	spin_unlock_irqrestore(&mdesc_lock, flags);
    539
    540out:
    541	mutex_unlock(&mdesc_mutex);
    542}
    543
    544u64 mdesc_get_node(struct mdesc_handle *hp, const char *node_name,
    545		   union md_node_info *node_info)
    546{
    547	mdesc_node_info_get_f get_info_func;
    548	mdesc_node_info_rel_f rel_info_func;
    549	mdesc_node_match_f node_match_func;
    550	union md_node_info hp_node_info;
    551	u64 hp_node;
    552	int rv;
    553
    554	if (hp == NULL || node_name == NULL || node_info == NULL)
    555		return MDESC_NODE_NULL;
    556
    557	/* Find the ops for the given node name */
    558	mdesc_get_node_ops(node_name, &get_info_func, &rel_info_func,
    559			   &node_match_func);
    560
    561	/* If we didn't find ops for the given node name, it is not supported */
    562	if (!get_info_func || !rel_info_func || !node_match_func) {
    563		pr_err("MD: %s node is not supported\n", node_name);
    564		return -EINVAL;
    565	}
    566
    567	mdesc_for_each_node_by_name(hp, hp_node, node_name) {
    568		rv = get_info_func(hp, hp_node, &hp_node_info);
    569		if (rv != 0)
    570			continue;
    571
    572		if (node_match_func(node_info, &hp_node_info))
    573			break;
    574
    575		rel_info_func(&hp_node_info);
    576	}
    577
    578	rel_info_func(&hp_node_info);
    579
    580	return hp_node;
    581}
    582EXPORT_SYMBOL(mdesc_get_node);
    583
    584int mdesc_get_node_info(struct mdesc_handle *hp, u64 node,
    585			const char *node_name, union md_node_info *node_info)
    586{
    587	mdesc_node_info_get_f get_info_func;
    588	int rv;
    589
    590	if (hp == NULL || node == MDESC_NODE_NULL ||
    591	    node_name == NULL || node_info == NULL)
    592		return -EINVAL;
    593
    594	/* Find the get_info op for the given node name */
    595	mdesc_get_node_ops(node_name, &get_info_func, NULL, NULL);
    596
    597	/* If we didn't find a get_info_func, the node name is not supported */
    598	if (get_info_func == NULL) {
    599		pr_err("MD: %s node is not supported\n", node_name);
    600		return -EINVAL;
    601	}
    602
    603	rv = get_info_func(hp, node, node_info);
    604	if (rv != 0) {
    605		pr_err("MD: Cannot find 1 or more required match properties for %s node.\n",
    606		       node_name);
    607		return -1;
    608	}
    609
    610	return 0;
    611}
    612EXPORT_SYMBOL(mdesc_get_node_info);
    613
    614static struct mdesc_elem *node_block(struct mdesc_hdr *mdesc)
    615{
    616	return (struct mdesc_elem *) mdesc->data;
    617}
    618
    619static void *name_block(struct mdesc_hdr *mdesc)
    620{
    621	return ((void *) node_block(mdesc)) + mdesc->node_sz;
    622}
    623
    624static void *data_block(struct mdesc_hdr *mdesc)
    625{
    626	return ((void *) name_block(mdesc)) + mdesc->name_sz;
    627}
    628
    629u64 mdesc_node_by_name(struct mdesc_handle *hp,
    630		       u64 from_node, const char *name)
    631{
    632	struct mdesc_elem *ep = node_block(&hp->mdesc);
    633	const char *names = name_block(&hp->mdesc);
    634	u64 last_node = hp->mdesc.node_sz / 16;
    635	u64 ret;
    636
    637	if (from_node == MDESC_NODE_NULL) {
    638		ret = from_node = 0;
    639	} else if (from_node >= last_node) {
    640		return MDESC_NODE_NULL;
    641	} else {
    642		ret = ep[from_node].d.val;
    643	}
    644
    645	while (ret < last_node) {
    646		if (ep[ret].tag != MD_NODE)
    647			return MDESC_NODE_NULL;
    648		if (!strcmp(names + ep[ret].name_offset, name))
    649			break;
    650		ret = ep[ret].d.val;
    651	}
    652	if (ret >= last_node)
    653		ret = MDESC_NODE_NULL;
    654	return ret;
    655}
    656EXPORT_SYMBOL(mdesc_node_by_name);
    657
    658const void *mdesc_get_property(struct mdesc_handle *hp, u64 node,
    659			       const char *name, int *lenp)
    660{
    661	const char *names = name_block(&hp->mdesc);
    662	u64 last_node = hp->mdesc.node_sz / 16;
    663	void *data = data_block(&hp->mdesc);
    664	struct mdesc_elem *ep;
    665
    666	if (node == MDESC_NODE_NULL || node >= last_node)
    667		return NULL;
    668
    669	ep = node_block(&hp->mdesc) + node;
    670	ep++;
    671	for (; ep->tag != MD_NODE_END; ep++) {
    672		void *val = NULL;
    673		int len = 0;
    674
    675		switch (ep->tag) {
    676		case MD_PROP_VAL:
    677			val = &ep->d.val;
    678			len = 8;
    679			break;
    680
    681		case MD_PROP_STR:
    682		case MD_PROP_DATA:
    683			val = data + ep->d.data.data_offset;
    684			len = ep->d.data.data_len;
    685			break;
    686
    687		default:
    688			break;
    689		}
    690		if (!val)
    691			continue;
    692
    693		if (!strcmp(names + ep->name_offset, name)) {
    694			if (lenp)
    695				*lenp = len;
    696			return val;
    697		}
    698	}
    699
    700	return NULL;
    701}
    702EXPORT_SYMBOL(mdesc_get_property);
    703
    704u64 mdesc_next_arc(struct mdesc_handle *hp, u64 from, const char *arc_type)
    705{
    706	struct mdesc_elem *ep, *base = node_block(&hp->mdesc);
    707	const char *names = name_block(&hp->mdesc);
    708	u64 last_node = hp->mdesc.node_sz / 16;
    709
    710	if (from == MDESC_NODE_NULL || from >= last_node)
    711		return MDESC_NODE_NULL;
    712
    713	ep = base + from;
    714
    715	ep++;
    716	for (; ep->tag != MD_NODE_END; ep++) {
    717		if (ep->tag != MD_PROP_ARC)
    718			continue;
    719
    720		if (strcmp(names + ep->name_offset, arc_type))
    721			continue;
    722
    723		return ep - base;
    724	}
    725
    726	return MDESC_NODE_NULL;
    727}
    728EXPORT_SYMBOL(mdesc_next_arc);
    729
    730u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc)
    731{
    732	struct mdesc_elem *ep, *base = node_block(&hp->mdesc);
    733
    734	ep = base + arc;
    735
    736	return ep->d.val;
    737}
    738EXPORT_SYMBOL(mdesc_arc_target);
    739
    740const char *mdesc_node_name(struct mdesc_handle *hp, u64 node)
    741{
    742	struct mdesc_elem *ep, *base = node_block(&hp->mdesc);
    743	const char *names = name_block(&hp->mdesc);
    744	u64 last_node = hp->mdesc.node_sz / 16;
    745
    746	if (node == MDESC_NODE_NULL || node >= last_node)
    747		return NULL;
    748
    749	ep = base + node;
    750	if (ep->tag != MD_NODE)
    751		return NULL;
    752
    753	return names + ep->name_offset;
    754}
    755EXPORT_SYMBOL(mdesc_node_name);
    756
    757static u64 max_cpus = 64;
    758
    759static void __init report_platform_properties(void)
    760{
    761	struct mdesc_handle *hp = mdesc_grab();
    762	u64 pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "platform");
    763	const char *s;
    764	const u64 *v;
    765
    766	if (pn == MDESC_NODE_NULL) {
    767		prom_printf("No platform node in machine-description.\n");
    768		prom_halt();
    769	}
    770
    771	s = mdesc_get_property(hp, pn, "banner-name", NULL);
    772	printk("PLATFORM: banner-name [%s]\n", s);
    773	s = mdesc_get_property(hp, pn, "name", NULL);
    774	printk("PLATFORM: name [%s]\n", s);
    775
    776	v = mdesc_get_property(hp, pn, "hostid", NULL);
    777	if (v)
    778		printk("PLATFORM: hostid [%08llx]\n", *v);
    779	v = mdesc_get_property(hp, pn, "serial#", NULL);
    780	if (v)
    781		printk("PLATFORM: serial# [%08llx]\n", *v);
    782	v = mdesc_get_property(hp, pn, "stick-frequency", NULL);
    783	printk("PLATFORM: stick-frequency [%08llx]\n", *v);
    784	v = mdesc_get_property(hp, pn, "mac-address", NULL);
    785	if (v)
    786		printk("PLATFORM: mac-address [%llx]\n", *v);
    787	v = mdesc_get_property(hp, pn, "watchdog-resolution", NULL);
    788	if (v)
    789		printk("PLATFORM: watchdog-resolution [%llu ms]\n", *v);
    790	v = mdesc_get_property(hp, pn, "watchdog-max-timeout", NULL);
    791	if (v)
    792		printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v);
    793	v = mdesc_get_property(hp, pn, "max-cpus", NULL);
    794	if (v) {
    795		max_cpus = *v;
    796		printk("PLATFORM: max-cpus [%llu]\n", max_cpus);
    797	}
    798
    799#ifdef CONFIG_SMP
    800	{
    801		int max_cpu, i;
    802
    803		if (v) {
    804			max_cpu = *v;
    805			if (max_cpu > NR_CPUS)
    806				max_cpu = NR_CPUS;
    807		} else {
    808			max_cpu = NR_CPUS;
    809		}
    810		for (i = 0; i < max_cpu; i++)
    811			set_cpu_possible(i, true);
    812	}
    813#endif
    814
    815	mdesc_release(hp);
    816}
    817
    818static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp)
    819{
    820	const u64 *level = mdesc_get_property(hp, mp, "level", NULL);
    821	const u64 *size = mdesc_get_property(hp, mp, "size", NULL);
    822	const u64 *line_size = mdesc_get_property(hp, mp, "line-size", NULL);
    823	const char *type;
    824	int type_len;
    825
    826	type = mdesc_get_property(hp, mp, "type", &type_len);
    827
    828	switch (*level) {
    829	case 1:
    830		if (of_find_in_proplist(type, "instn", type_len)) {
    831			c->icache_size = *size;
    832			c->icache_line_size = *line_size;
    833		} else if (of_find_in_proplist(type, "data", type_len)) {
    834			c->dcache_size = *size;
    835			c->dcache_line_size = *line_size;
    836		}
    837		break;
    838
    839	case 2:
    840		c->ecache_size = *size;
    841		c->ecache_line_size = *line_size;
    842		break;
    843
    844	default:
    845		break;
    846	}
    847
    848	if (*level == 1) {
    849		u64 a;
    850
    851		mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
    852			u64 target = mdesc_arc_target(hp, a);
    853			const char *name = mdesc_node_name(hp, target);
    854
    855			if (!strcmp(name, "cache"))
    856				fill_in_one_cache(c, hp, target);
    857		}
    858	}
    859}
    860
    861static void find_back_node_value(struct mdesc_handle *hp, u64 node,
    862				 char *srch_val,
    863				 void (*func)(struct mdesc_handle *, u64, int),
    864				 u64 val, int depth)
    865{
    866	u64 arc;
    867
    868	/* Since we have an estimate of recursion depth, do a sanity check. */
    869	if (depth == 0)
    870		return;
    871
    872	mdesc_for_each_arc(arc, hp, node, MDESC_ARC_TYPE_BACK) {
    873		u64 n = mdesc_arc_target(hp, arc);
    874		const char *name = mdesc_node_name(hp, n);
    875
    876		if (!strcmp(srch_val, name))
    877			(*func)(hp, n, val);
    878
    879		find_back_node_value(hp, n, srch_val, func, val, depth-1);
    880	}
    881}
    882
    883static void __mark_core_id(struct mdesc_handle *hp, u64 node,
    884			   int core_id)
    885{
    886	const u64 *id = mdesc_get_property(hp, node, "id", NULL);
    887
    888	if (*id < num_possible_cpus())
    889		cpu_data(*id).core_id = core_id;
    890}
    891
    892static void __mark_max_cache_id(struct mdesc_handle *hp, u64 node,
    893				int max_cache_id)
    894{
    895	const u64 *id = mdesc_get_property(hp, node, "id", NULL);
    896
    897	if (*id < num_possible_cpus()) {
    898		cpu_data(*id).max_cache_id = max_cache_id;
    899
    900		/**
    901		 * On systems without explicit socket descriptions socket
    902		 * is max_cache_id
    903		 */
    904		cpu_data(*id).sock_id = max_cache_id;
    905	}
    906}
    907
    908static void mark_core_ids(struct mdesc_handle *hp, u64 mp,
    909			  int core_id)
    910{
    911	find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10);
    912}
    913
    914static void mark_max_cache_ids(struct mdesc_handle *hp, u64 mp,
    915			       int max_cache_id)
    916{
    917	find_back_node_value(hp, mp, "cpu", __mark_max_cache_id,
    918			     max_cache_id, 10);
    919}
    920
    921static void set_core_ids(struct mdesc_handle *hp)
    922{
    923	int idx;
    924	u64 mp;
    925
    926	idx = 1;
    927
    928	/* Identify unique cores by looking for cpus backpointed to by
    929	 * level 1 instruction caches.
    930	 */
    931	mdesc_for_each_node_by_name(hp, mp, "cache") {
    932		const u64 *level;
    933		const char *type;
    934		int len;
    935
    936		level = mdesc_get_property(hp, mp, "level", NULL);
    937		if (*level != 1)
    938			continue;
    939
    940		type = mdesc_get_property(hp, mp, "type", &len);
    941		if (!of_find_in_proplist(type, "instn", len))
    942			continue;
    943
    944		mark_core_ids(hp, mp, idx);
    945		idx++;
    946	}
    947}
    948
    949static int set_max_cache_ids_by_cache(struct mdesc_handle *hp, int level)
    950{
    951	u64 mp;
    952	int idx = 1;
    953	int fnd = 0;
    954
    955	/**
    956	 * Identify unique highest level of shared cache by looking for cpus
    957	 * backpointed to by shared level N caches.
    958	 */
    959	mdesc_for_each_node_by_name(hp, mp, "cache") {
    960		const u64 *cur_lvl;
    961
    962		cur_lvl = mdesc_get_property(hp, mp, "level", NULL);
    963		if (*cur_lvl != level)
    964			continue;
    965		mark_max_cache_ids(hp, mp, idx);
    966		idx++;
    967		fnd = 1;
    968	}
    969	return fnd;
    970}
    971
    972static void set_sock_ids_by_socket(struct mdesc_handle *hp, u64 mp)
    973{
    974	int idx = 1;
    975
    976	mdesc_for_each_node_by_name(hp, mp, "socket") {
    977		u64 a;
    978
    979		mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
    980			u64 t = mdesc_arc_target(hp, a);
    981			const char *name;
    982			const u64 *id;
    983
    984			name = mdesc_node_name(hp, t);
    985			if (strcmp(name, "cpu"))
    986				continue;
    987
    988			id = mdesc_get_property(hp, t, "id", NULL);
    989			if (*id < num_possible_cpus())
    990				cpu_data(*id).sock_id = idx;
    991		}
    992		idx++;
    993	}
    994}
    995
    996static void set_sock_ids(struct mdesc_handle *hp)
    997{
    998	u64 mp;
    999
   1000	/**
   1001	 * Find the highest level of shared cache which pre-T7 is also
   1002	 * the socket.
   1003	 */
   1004	if (!set_max_cache_ids_by_cache(hp, 3))
   1005		set_max_cache_ids_by_cache(hp, 2);
   1006
   1007	/* If machine description exposes sockets data use it.*/
   1008	mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets");
   1009	if (mp != MDESC_NODE_NULL)
   1010		set_sock_ids_by_socket(hp, mp);
   1011}
   1012
   1013static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)
   1014{
   1015	u64 a;
   1016
   1017	mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) {
   1018		u64 t = mdesc_arc_target(hp, a);
   1019		const char *name;
   1020		const u64 *id;
   1021
   1022		name = mdesc_node_name(hp, t);
   1023		if (strcmp(name, "cpu"))
   1024			continue;
   1025
   1026		id = mdesc_get_property(hp, t, "id", NULL);
   1027		if (*id < NR_CPUS)
   1028			cpu_data(*id).proc_id = proc_id;
   1029	}
   1030}
   1031
   1032static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)
   1033{
   1034	int idx;
   1035	u64 mp;
   1036
   1037	idx = 0;
   1038	mdesc_for_each_node_by_name(hp, mp, exec_unit_name) {
   1039		const char *type;
   1040		int len;
   1041
   1042		type = mdesc_get_property(hp, mp, "type", &len);
   1043		if (!of_find_in_proplist(type, "int", len) &&
   1044		    !of_find_in_proplist(type, "integer", len))
   1045			continue;
   1046
   1047		mark_proc_ids(hp, mp, idx);
   1048		idx++;
   1049	}
   1050}
   1051
   1052static void set_proc_ids(struct mdesc_handle *hp)
   1053{
   1054	__set_proc_ids(hp, "exec_unit");
   1055	__set_proc_ids(hp, "exec-unit");
   1056}
   1057
   1058static void get_one_mondo_bits(const u64 *p, unsigned int *mask,
   1059			       unsigned long def, unsigned long max)
   1060{
   1061	u64 val;
   1062
   1063	if (!p)
   1064		goto use_default;
   1065	val = *p;
   1066
   1067	if (!val || val >= 64)
   1068		goto use_default;
   1069
   1070	if (val > max)
   1071		val = max;
   1072
   1073	*mask = ((1U << val) * 64U) - 1U;
   1074	return;
   1075
   1076use_default:
   1077	*mask = ((1U << def) * 64U) - 1U;
   1078}
   1079
   1080static void get_mondo_data(struct mdesc_handle *hp, u64 mp,
   1081			   struct trap_per_cpu *tb)
   1082{
   1083	static int printed;
   1084	const u64 *val;
   1085
   1086	val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL);
   1087	get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7, ilog2(max_cpus * 2));
   1088
   1089	val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL);
   1090	get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7, 8);
   1091
   1092	val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL);
   1093	get_one_mondo_bits(val, &tb->resum_qmask, 6, 7);
   1094
   1095	val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL);
   1096	get_one_mondo_bits(val, &tb->nonresum_qmask, 2, 2);
   1097	if (!printed++) {
   1098		pr_info("SUN4V: Mondo queue sizes "
   1099			"[cpu(%u) dev(%u) r(%u) nr(%u)]\n",
   1100			tb->cpu_mondo_qmask + 1,
   1101			tb->dev_mondo_qmask + 1,
   1102			tb->resum_qmask + 1,
   1103			tb->nonresum_qmask + 1);
   1104	}
   1105}
   1106
   1107static void *mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask)
   1108{
   1109	struct mdesc_handle *hp = mdesc_grab();
   1110	void *ret = NULL;
   1111	u64 mp;
   1112
   1113	mdesc_for_each_node_by_name(hp, mp, "cpu") {
   1114		const u64 *id = mdesc_get_property(hp, mp, "id", NULL);
   1115		int cpuid = *id;
   1116
   1117#ifdef CONFIG_SMP
   1118		if (cpuid >= NR_CPUS) {
   1119			printk(KERN_WARNING "Ignoring CPU %d which is "
   1120			       ">= NR_CPUS (%d)\n",
   1121			       cpuid, NR_CPUS);
   1122			continue;
   1123		}
   1124		if (!cpumask_test_cpu(cpuid, mask))
   1125			continue;
   1126#endif
   1127
   1128		ret = func(hp, mp, cpuid, arg);
   1129		if (ret)
   1130			goto out;
   1131	}
   1132out:
   1133	mdesc_release(hp);
   1134	return ret;
   1135}
   1136
   1137static void *record_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid,
   1138			    void *arg)
   1139{
   1140	ncpus_probed++;
   1141#ifdef CONFIG_SMP
   1142	set_cpu_present(cpuid, true);
   1143#endif
   1144	return NULL;
   1145}
   1146
   1147void mdesc_populate_present_mask(cpumask_t *mask)
   1148{
   1149	if (tlb_type != hypervisor)
   1150		return;
   1151
   1152	ncpus_probed = 0;
   1153	mdesc_iterate_over_cpus(record_one_cpu, NULL, mask);
   1154}
   1155
   1156static void * __init check_one_pgsz(struct mdesc_handle *hp, u64 mp, int cpuid, void *arg)
   1157{
   1158	const u64 *pgsz_prop = mdesc_get_property(hp, mp, "mmu-page-size-list", NULL);
   1159	unsigned long *pgsz_mask = arg;
   1160	u64 val;
   1161
   1162	val = (HV_PGSZ_MASK_8K | HV_PGSZ_MASK_64K |
   1163	       HV_PGSZ_MASK_512K | HV_PGSZ_MASK_4MB);
   1164	if (pgsz_prop)
   1165		val = *pgsz_prop;
   1166
   1167	if (!*pgsz_mask)
   1168		*pgsz_mask = val;
   1169	else
   1170		*pgsz_mask &= val;
   1171	return NULL;
   1172}
   1173
   1174void __init mdesc_get_page_sizes(cpumask_t *mask, unsigned long *pgsz_mask)
   1175{
   1176	*pgsz_mask = 0;
   1177	mdesc_iterate_over_cpus(check_one_pgsz, pgsz_mask, mask);
   1178}
   1179
   1180static void *fill_in_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid,
   1181			     void *arg)
   1182{
   1183	const u64 *cfreq = mdesc_get_property(hp, mp, "clock-frequency", NULL);
   1184	struct trap_per_cpu *tb;
   1185	cpuinfo_sparc *c;
   1186	u64 a;
   1187
   1188#ifndef CONFIG_SMP
   1189	/* On uniprocessor we only want the values for the
   1190	 * real physical cpu the kernel booted onto, however
   1191	 * cpu_data() only has one entry at index 0.
   1192	 */
   1193	if (cpuid != real_hard_smp_processor_id())
   1194		return NULL;
   1195	cpuid = 0;
   1196#endif
   1197
   1198	c = &cpu_data(cpuid);
   1199	c->clock_tick = *cfreq;
   1200
   1201	tb = &trap_block[cpuid];
   1202	get_mondo_data(hp, mp, tb);
   1203
   1204	mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
   1205		u64 j, t = mdesc_arc_target(hp, a);
   1206		const char *t_name;
   1207
   1208		t_name = mdesc_node_name(hp, t);
   1209		if (!strcmp(t_name, "cache")) {
   1210			fill_in_one_cache(c, hp, t);
   1211			continue;
   1212		}
   1213
   1214		mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_FWD) {
   1215			u64 n = mdesc_arc_target(hp, j);
   1216			const char *n_name;
   1217
   1218			n_name = mdesc_node_name(hp, n);
   1219			if (!strcmp(n_name, "cache"))
   1220				fill_in_one_cache(c, hp, n);
   1221		}
   1222	}
   1223
   1224	c->core_id = 0;
   1225	c->proc_id = -1;
   1226
   1227	return NULL;
   1228}
   1229
   1230void mdesc_fill_in_cpu_data(cpumask_t *mask)
   1231{
   1232	struct mdesc_handle *hp;
   1233
   1234	mdesc_iterate_over_cpus(fill_in_one_cpu, NULL, mask);
   1235
   1236	hp = mdesc_grab();
   1237
   1238	set_core_ids(hp);
   1239	set_proc_ids(hp);
   1240	set_sock_ids(hp);
   1241
   1242	mdesc_release(hp);
   1243
   1244	smp_fill_in_sib_core_maps();
   1245}
   1246
   1247/* mdesc_open() - Grab a reference to mdesc_handle when /dev/mdesc is
   1248 * opened. Hold this reference until /dev/mdesc is closed to ensure
   1249 * mdesc data structure is not released underneath us. Store the
   1250 * pointer to mdesc structure in private_data for read and seek to use
   1251 */
   1252static int mdesc_open(struct inode *inode, struct file *file)
   1253{
   1254	struct mdesc_handle *hp = mdesc_grab();
   1255
   1256	if (!hp)
   1257		return -ENODEV;
   1258
   1259	file->private_data = hp;
   1260
   1261	return 0;
   1262}
   1263
   1264static ssize_t mdesc_read(struct file *file, char __user *buf,
   1265			  size_t len, loff_t *offp)
   1266{
   1267	struct mdesc_handle *hp = file->private_data;
   1268	unsigned char *mdesc;
   1269	int bytes_left, count = len;
   1270
   1271	if (*offp >= hp->handle_size)
   1272		return 0;
   1273
   1274	bytes_left = hp->handle_size - *offp;
   1275	if (count > bytes_left)
   1276		count = bytes_left;
   1277
   1278	mdesc = (unsigned char *)&hp->mdesc;
   1279	mdesc += *offp;
   1280	if (!copy_to_user(buf, mdesc, count)) {
   1281		*offp += count;
   1282		return count;
   1283	} else {
   1284		return -EFAULT;
   1285	}
   1286}
   1287
   1288static loff_t mdesc_llseek(struct file *file, loff_t offset, int whence)
   1289{
   1290	struct mdesc_handle *hp = file->private_data;
   1291
   1292	return no_seek_end_llseek_size(file, offset, whence, hp->handle_size);
   1293}
   1294
   1295/* mdesc_close() - /dev/mdesc is being closed, release the reference to
   1296 * mdesc structure.
   1297 */
   1298static int mdesc_close(struct inode *inode, struct file *file)
   1299{
   1300	mdesc_release(file->private_data);
   1301	return 0;
   1302}
   1303
   1304static const struct file_operations mdesc_fops = {
   1305	.open    = mdesc_open,
   1306	.read	 = mdesc_read,
   1307	.llseek  = mdesc_llseek,
   1308	.release = mdesc_close,
   1309	.owner	 = THIS_MODULE,
   1310};
   1311
   1312static struct miscdevice mdesc_misc = {
   1313	.minor	= MISC_DYNAMIC_MINOR,
   1314	.name	= "mdesc",
   1315	.fops	= &mdesc_fops,
   1316};
   1317
   1318static int __init mdesc_misc_init(void)
   1319{
   1320	return misc_register(&mdesc_misc);
   1321}
   1322
   1323__initcall(mdesc_misc_init);
   1324
   1325void __init sun4v_mdesc_init(void)
   1326{
   1327	struct mdesc_handle *hp;
   1328	unsigned long len, real_len, status;
   1329
   1330	(void) sun4v_mach_desc(0UL, 0UL, &len);
   1331
   1332	printk("MDESC: Size is %lu bytes.\n", len);
   1333
   1334	hp = mdesc_alloc(len, &memblock_mdesc_ops);
   1335	if (hp == NULL) {
   1336		prom_printf("MDESC: alloc of %lu bytes failed.\n", len);
   1337		prom_halt();
   1338	}
   1339
   1340	status = sun4v_mach_desc(__pa(&hp->mdesc), len, &real_len);
   1341	if (status != HV_EOK || real_len > len) {
   1342		prom_printf("sun4v_mach_desc fails, err(%lu), "
   1343			    "len(%lu), real_len(%lu)\n",
   1344			    status, len, real_len);
   1345		mdesc_free(hp);
   1346		prom_halt();
   1347	}
   1348
   1349	cur_mdesc = hp;
   1350
   1351	mdesc_adi_init();
   1352	report_platform_properties();
   1353}