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

x2apic_phys.c (4701B)


      1// SPDX-License-Identifier: GPL-2.0
      2
      3#include <linux/cpumask.h>
      4#include <linux/acpi.h>
      5
      6#include "local.h"
      7
      8int x2apic_phys;
      9
     10static struct apic apic_x2apic_phys;
     11static u32 x2apic_max_apicid __ro_after_init;
     12
     13void __init x2apic_set_max_apicid(u32 apicid)
     14{
     15	x2apic_max_apicid = apicid;
     16}
     17
     18static int __init set_x2apic_phys_mode(char *arg)
     19{
     20	x2apic_phys = 1;
     21	return 0;
     22}
     23early_param("x2apic_phys", set_x2apic_phys_mode);
     24
     25static bool x2apic_fadt_phys(void)
     26{
     27#ifdef CONFIG_ACPI
     28	if ((acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) &&
     29		(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) {
     30		printk(KERN_DEBUG "System requires x2apic physical mode\n");
     31		return true;
     32	}
     33#endif
     34	return false;
     35}
     36
     37static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
     38{
     39	return x2apic_enabled() && (x2apic_phys || x2apic_fadt_phys());
     40}
     41
     42static void x2apic_send_IPI(int cpu, int vector)
     43{
     44	u32 dest = per_cpu(x86_cpu_to_apicid, cpu);
     45
     46	/* x2apic MSRs are special and need a special fence: */
     47	weak_wrmsr_fence();
     48	__x2apic_send_IPI_dest(dest, vector, APIC_DEST_PHYSICAL);
     49}
     50
     51static void
     52__x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest)
     53{
     54	unsigned long query_cpu;
     55	unsigned long this_cpu;
     56	unsigned long flags;
     57
     58	/* x2apic MSRs are special and need a special fence: */
     59	weak_wrmsr_fence();
     60
     61	local_irq_save(flags);
     62
     63	this_cpu = smp_processor_id();
     64	for_each_cpu(query_cpu, mask) {
     65		if (apic_dest == APIC_DEST_ALLBUT && this_cpu == query_cpu)
     66			continue;
     67		__x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu),
     68				       vector, APIC_DEST_PHYSICAL);
     69	}
     70	local_irq_restore(flags);
     71}
     72
     73static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
     74{
     75	__x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLINC);
     76}
     77
     78static void
     79 x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector)
     80{
     81	__x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT);
     82}
     83
     84static void x2apic_send_IPI_allbutself(int vector)
     85{
     86	__x2apic_send_IPI_shorthand(vector, APIC_DEST_ALLBUT);
     87}
     88
     89static void x2apic_send_IPI_all(int vector)
     90{
     91	__x2apic_send_IPI_shorthand(vector, APIC_DEST_ALLINC);
     92}
     93
     94static void init_x2apic_ldr(void)
     95{
     96}
     97
     98static int x2apic_phys_probe(void)
     99{
    100	if (x2apic_mode && (x2apic_phys || x2apic_fadt_phys()))
    101		return 1;
    102
    103	return apic == &apic_x2apic_phys;
    104}
    105
    106/* Common x2apic functions, also used by x2apic_cluster */
    107int x2apic_apic_id_valid(u32 apicid)
    108{
    109	if (x2apic_max_apicid && apicid > x2apic_max_apicid)
    110		return 0;
    111
    112	return 1;
    113}
    114
    115int x2apic_apic_id_registered(void)
    116{
    117	return 1;
    118}
    119
    120void __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest)
    121{
    122	unsigned long cfg = __prepare_ICR(0, vector, dest);
    123	native_x2apic_icr_write(cfg, apicid);
    124}
    125
    126void __x2apic_send_IPI_shorthand(int vector, u32 which)
    127{
    128	unsigned long cfg = __prepare_ICR(which, vector, 0);
    129
    130	/* x2apic MSRs are special and need a special fence: */
    131	weak_wrmsr_fence();
    132	native_x2apic_icr_write(cfg, 0);
    133}
    134
    135unsigned int x2apic_get_apic_id(unsigned long id)
    136{
    137	return id;
    138}
    139
    140u32 x2apic_set_apic_id(unsigned int id)
    141{
    142	return id;
    143}
    144
    145int x2apic_phys_pkg_id(int initial_apicid, int index_msb)
    146{
    147	return initial_apicid >> index_msb;
    148}
    149
    150void x2apic_send_IPI_self(int vector)
    151{
    152	apic_write(APIC_SELF_IPI, vector);
    153}
    154
    155static struct apic apic_x2apic_phys __ro_after_init = {
    156
    157	.name				= "physical x2apic",
    158	.probe				= x2apic_phys_probe,
    159	.acpi_madt_oem_check		= x2apic_acpi_madt_oem_check,
    160	.apic_id_valid			= x2apic_apic_id_valid,
    161	.apic_id_registered		= x2apic_apic_id_registered,
    162
    163	.delivery_mode			= APIC_DELIVERY_MODE_FIXED,
    164	.dest_mode_logical		= false,
    165
    166	.disable_esr			= 0,
    167
    168	.check_apicid_used		= NULL,
    169	.init_apic_ldr			= init_x2apic_ldr,
    170	.ioapic_phys_id_map		= NULL,
    171	.setup_apic_routing		= NULL,
    172	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
    173	.apicid_to_cpu_present		= NULL,
    174	.check_phys_apicid_present	= default_check_phys_apicid_present,
    175	.phys_pkg_id			= x2apic_phys_pkg_id,
    176
    177	.get_apic_id			= x2apic_get_apic_id,
    178	.set_apic_id			= x2apic_set_apic_id,
    179
    180	.calc_dest_apicid		= apic_default_calc_apicid,
    181
    182	.send_IPI			= x2apic_send_IPI,
    183	.send_IPI_mask			= x2apic_send_IPI_mask,
    184	.send_IPI_mask_allbutself	= x2apic_send_IPI_mask_allbutself,
    185	.send_IPI_allbutself		= x2apic_send_IPI_allbutself,
    186	.send_IPI_all			= x2apic_send_IPI_all,
    187	.send_IPI_self			= x2apic_send_IPI_self,
    188
    189	.inquire_remote_apic		= NULL,
    190
    191	.read				= native_apic_msr_read,
    192	.write				= native_apic_msr_write,
    193	.eoi_write			= native_apic_msr_eoi_write,
    194	.icr_read			= native_x2apic_icr_read,
    195	.icr_write			= native_x2apic_icr_write,
    196	.wait_icr_idle			= native_x2apic_wait_icr_idle,
    197	.safe_wait_icr_idle		= native_safe_x2apic_wait_icr_idle,
    198};
    199
    200apic_driver(apic_x2apic_phys);