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

bigsmp_32.c (4381B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * APIC driver for "bigsmp" xAPIC machines with more than 8 virtual CPUs.
      4 *
      5 * Drives the local APIC in "clustered mode".
      6 */
      7#include <linux/cpumask.h>
      8#include <linux/dmi.h>
      9#include <linux/smp.h>
     10
     11#include <asm/apic.h>
     12#include <asm/io_apic.h>
     13
     14#include "local.h"
     15
     16static unsigned bigsmp_get_apic_id(unsigned long x)
     17{
     18	return (x >> 24) & 0xFF;
     19}
     20
     21static int bigsmp_apic_id_registered(void)
     22{
     23	return 1;
     24}
     25
     26static bool bigsmp_check_apicid_used(physid_mask_t *map, int apicid)
     27{
     28	return false;
     29}
     30
     31static int bigsmp_early_logical_apicid(int cpu)
     32{
     33	/* on bigsmp, logical apicid is the same as physical */
     34	return early_per_cpu(x86_cpu_to_apicid, cpu);
     35}
     36
     37/*
     38 * bigsmp enables physical destination mode
     39 * and doesn't use LDR and DFR
     40 */
     41static void bigsmp_init_apic_ldr(void)
     42{
     43}
     44
     45static void bigsmp_setup_apic_routing(void)
     46{
     47	printk(KERN_INFO
     48		"Enabling APIC mode:  Physflat.  Using %d I/O APICs\n",
     49		nr_ioapics);
     50}
     51
     52static int bigsmp_cpu_present_to_apicid(int mps_cpu)
     53{
     54	if (mps_cpu < nr_cpu_ids)
     55		return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu);
     56
     57	return BAD_APICID;
     58}
     59
     60static void bigsmp_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
     61{
     62	/* For clustered we don't have a good way to do this yet - hack */
     63	physids_promote(0xFFL, retmap);
     64}
     65
     66static int bigsmp_check_phys_apicid_present(int phys_apicid)
     67{
     68	return 1;
     69}
     70
     71static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
     72{
     73	return cpuid_apic >> index_msb;
     74}
     75
     76static void bigsmp_send_IPI_allbutself(int vector)
     77{
     78	default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
     79}
     80
     81static void bigsmp_send_IPI_all(int vector)
     82{
     83	default_send_IPI_mask_sequence_phys(cpu_online_mask, vector);
     84}
     85
     86static int dmi_bigsmp; /* can be set by dmi scanners */
     87
     88static int hp_ht_bigsmp(const struct dmi_system_id *d)
     89{
     90	printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
     91	dmi_bigsmp = 1;
     92
     93	return 0;
     94}
     95
     96
     97static const struct dmi_system_id bigsmp_dmi_table[] = {
     98	{ hp_ht_bigsmp, "HP ProLiant DL760 G2",
     99		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
    100			DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
    101		}
    102	},
    103
    104	{ hp_ht_bigsmp, "HP ProLiant DL740",
    105		{	DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
    106			DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
    107		}
    108	},
    109	{ } /* NULL entry stops DMI scanning */
    110};
    111
    112static int probe_bigsmp(void)
    113{
    114	if (def_to_bigsmp)
    115		dmi_bigsmp = 1;
    116	else
    117		dmi_check_system(bigsmp_dmi_table);
    118
    119	return dmi_bigsmp;
    120}
    121
    122static struct apic apic_bigsmp __ro_after_init = {
    123
    124	.name				= "bigsmp",
    125	.probe				= probe_bigsmp,
    126	.acpi_madt_oem_check		= NULL,
    127	.apic_id_valid			= default_apic_id_valid,
    128	.apic_id_registered		= bigsmp_apic_id_registered,
    129
    130	.delivery_mode			= APIC_DELIVERY_MODE_FIXED,
    131	.dest_mode_logical		= false,
    132
    133	.disable_esr			= 1,
    134
    135	.check_apicid_used		= bigsmp_check_apicid_used,
    136	.init_apic_ldr			= bigsmp_init_apic_ldr,
    137	.ioapic_phys_id_map		= bigsmp_ioapic_phys_id_map,
    138	.setup_apic_routing		= bigsmp_setup_apic_routing,
    139	.cpu_present_to_apicid		= bigsmp_cpu_present_to_apicid,
    140	.apicid_to_cpu_present		= physid_set_mask_of_physid,
    141	.check_phys_apicid_present	= bigsmp_check_phys_apicid_present,
    142	.phys_pkg_id			= bigsmp_phys_pkg_id,
    143
    144	.get_apic_id			= bigsmp_get_apic_id,
    145	.set_apic_id			= NULL,
    146
    147	.calc_dest_apicid		= apic_default_calc_apicid,
    148
    149	.send_IPI			= default_send_IPI_single_phys,
    150	.send_IPI_mask			= default_send_IPI_mask_sequence_phys,
    151	.send_IPI_mask_allbutself	= NULL,
    152	.send_IPI_allbutself		= bigsmp_send_IPI_allbutself,
    153	.send_IPI_all			= bigsmp_send_IPI_all,
    154	.send_IPI_self			= default_send_IPI_self,
    155
    156	.inquire_remote_apic		= default_inquire_remote_apic,
    157
    158	.read				= native_apic_mem_read,
    159	.write				= native_apic_mem_write,
    160	.eoi_write			= native_apic_mem_write,
    161	.icr_read			= native_apic_icr_read,
    162	.icr_write			= native_apic_icr_write,
    163	.wait_icr_idle			= native_apic_wait_icr_idle,
    164	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
    165
    166	.x86_32_early_logical_apicid	= bigsmp_early_logical_apicid,
    167};
    168
    169void __init generic_bigsmp_probe(void)
    170{
    171	unsigned int cpu;
    172
    173	if (!probe_bigsmp())
    174		return;
    175
    176	apic = &apic_bigsmp;
    177
    178	for_each_possible_cpu(cpu) {
    179		if (early_per_cpu(x86_cpu_to_logical_apicid,
    180				  cpu) == BAD_APICID)
    181			continue;
    182		early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
    183			bigsmp_early_logical_apicid(cpu);
    184	}
    185
    186	pr_info("Overriding APIC driver with %s\n", apic_bigsmp.name);
    187}
    188
    189apic_driver(apic_bigsmp);