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

srat.c (2931B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * ACPI 3.0 based NUMA setup
      4 * Copyright 2004 Andi Kleen, SuSE Labs.
      5 *
      6 * Reads the ACPI SRAT table to figure out what memory belongs to which CPUs.
      7 *
      8 * Called from acpi_numa_init while reading the SRAT and SLIT tables.
      9 * Assumes all memory regions belonging to a single proximity domain
     10 * are in one chunk. Holes between them will be included in the node.
     11 */
     12
     13#include <linux/kernel.h>
     14#include <linux/acpi.h>
     15#include <linux/mmzone.h>
     16#include <linux/bitmap.h>
     17#include <linux/init.h>
     18#include <linux/topology.h>
     19#include <linux/mm.h>
     20#include <asm/proto.h>
     21#include <asm/numa.h>
     22#include <asm/e820/api.h>
     23#include <asm/apic.h>
     24#include <asm/uv/uv.h>
     25
     26/* Callback for Proximity Domain -> x2APIC mapping */
     27void __init
     28acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
     29{
     30	int pxm, node;
     31	int apic_id;
     32
     33	if (srat_disabled())
     34		return;
     35	if (pa->header.length < sizeof(struct acpi_srat_x2apic_cpu_affinity)) {
     36		bad_srat();
     37		return;
     38	}
     39	if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
     40		return;
     41	pxm = pa->proximity_domain;
     42	apic_id = pa->apic_id;
     43	if (!apic->apic_id_valid(apic_id)) {
     44		printk(KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n",
     45			 pxm, apic_id);
     46		return;
     47	}
     48	node = acpi_map_pxm_to_node(pxm);
     49	if (node < 0) {
     50		printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
     51		bad_srat();
     52		return;
     53	}
     54
     55	if (apic_id >= MAX_LOCAL_APIC) {
     56		printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u skipped apicid that is too big\n", pxm, apic_id, node);
     57		return;
     58	}
     59	set_apicid_to_node(apic_id, node);
     60	node_set(node, numa_nodes_parsed);
     61	printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n",
     62	       pxm, apic_id, node);
     63}
     64
     65/* Callback for Proximity Domain -> LAPIC mapping */
     66void __init
     67acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
     68{
     69	int pxm, node;
     70	int apic_id;
     71
     72	if (srat_disabled())
     73		return;
     74	if (pa->header.length != sizeof(struct acpi_srat_cpu_affinity)) {
     75		bad_srat();
     76		return;
     77	}
     78	if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
     79		return;
     80	pxm = pa->proximity_domain_lo;
     81	if (acpi_srat_revision >= 2)
     82		pxm |= *((unsigned int*)pa->proximity_domain_hi) << 8;
     83	node = acpi_map_pxm_to_node(pxm);
     84	if (node < 0) {
     85		printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
     86		bad_srat();
     87		return;
     88	}
     89
     90	if (get_uv_system_type() >= UV_X2APIC)
     91		apic_id = (pa->apic_id << 8) | pa->local_sapic_eid;
     92	else
     93		apic_id = pa->apic_id;
     94
     95	if (apic_id >= MAX_LOCAL_APIC) {
     96		printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u skipped apicid that is too big\n", pxm, apic_id, node);
     97		return;
     98	}
     99
    100	set_apicid_to_node(apic_id, node);
    101	node_set(node, numa_nodes_parsed);
    102	printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u\n",
    103	       pxm, apic_id, node);
    104}
    105
    106int __init x86_acpi_numa_init(void)
    107{
    108	int ret;
    109
    110	ret = acpi_numa_init();
    111	if (ret < 0)
    112		return ret;
    113	return srat_disabled() ? -EINVAL : 0;
    114}