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

apic.c (4642B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <linux/init.h>
      3#include <linux/thread_info.h>
      4
      5#include <asm/x86_init.h>
      6#include <asm/apic.h>
      7#include <asm/io_apic.h>
      8#include <asm/xen/hypercall.h>
      9
     10#include <xen/xen.h>
     11#include <xen/interface/physdev.h>
     12#include "xen-ops.h"
     13#include "pmu.h"
     14#include "smp.h"
     15
     16static unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
     17{
     18	struct physdev_apic apic_op;
     19	int ret;
     20
     21	apic_op.apic_physbase = mpc_ioapic_addr(apic);
     22	apic_op.reg = reg;
     23	ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
     24	if (!ret)
     25		return apic_op.value;
     26
     27	/* fallback to return an emulated IO_APIC values */
     28	if (reg == 0x1)
     29		return 0x00170020;
     30	else if (reg == 0x0)
     31		return apic << 24;
     32
     33	return 0xfd;
     34}
     35
     36static u32 xen_set_apic_id(unsigned int x)
     37{
     38	WARN_ON(1);
     39	return x;
     40}
     41
     42static unsigned int xen_get_apic_id(unsigned long x)
     43{
     44	return ((x)>>24) & 0xFFu;
     45}
     46
     47static u32 xen_apic_read(u32 reg)
     48{
     49	struct xen_platform_op op = {
     50		.cmd = XENPF_get_cpuinfo,
     51		.interface_version = XENPF_INTERFACE_VERSION,
     52		.u.pcpu_info.xen_cpuid = 0,
     53	};
     54	int ret;
     55
     56	/* Shouldn't need this as APIC is turned off for PV, and we only
     57	 * get called on the bootup processor. But just in case. */
     58	if (!xen_initial_domain() || smp_processor_id())
     59		return 0;
     60
     61	if (reg == APIC_LVR)
     62		return 0x14;
     63	if (reg != APIC_ID)
     64		return 0;
     65
     66	ret = HYPERVISOR_platform_op(&op);
     67	if (ret)
     68		op.u.pcpu_info.apic_id = BAD_APICID;
     69
     70	return op.u.pcpu_info.apic_id << 24;
     71}
     72
     73static void xen_apic_write(u32 reg, u32 val)
     74{
     75	if (reg == APIC_LVTPC) {
     76		(void)pmu_apic_update(reg);
     77		return;
     78	}
     79
     80	/* Warn to see if there's any stray references */
     81	WARN(1,"register: %x, value: %x\n", reg, val);
     82}
     83
     84static u64 xen_apic_icr_read(void)
     85{
     86	return 0;
     87}
     88
     89static void xen_apic_icr_write(u32 low, u32 id)
     90{
     91	/* Warn to see if there's any stray references */
     92	WARN_ON(1);
     93}
     94
     95static u32 xen_safe_apic_wait_icr_idle(void)
     96{
     97        return 0;
     98}
     99
    100static int xen_apic_probe_pv(void)
    101{
    102	if (xen_pv_domain())
    103		return 1;
    104
    105	return 0;
    106}
    107
    108static int xen_madt_oem_check(char *oem_id, char *oem_table_id)
    109{
    110	return xen_pv_domain();
    111}
    112
    113static int xen_id_always_valid(u32 apicid)
    114{
    115	return 1;
    116}
    117
    118static int xen_id_always_registered(void)
    119{
    120	return 1;
    121}
    122
    123static int xen_phys_pkg_id(int initial_apic_id, int index_msb)
    124{
    125	return initial_apic_id >> index_msb;
    126}
    127
    128static void xen_noop(void)
    129{
    130}
    131
    132static void xen_silent_inquire(int apicid)
    133{
    134}
    135
    136static int xen_cpu_present_to_apicid(int cpu)
    137{
    138	if (cpu_present(cpu))
    139		return cpu_data(cpu).apicid;
    140	else
    141		return BAD_APICID;
    142}
    143
    144static struct apic xen_pv_apic = {
    145	.name 				= "Xen PV",
    146	.probe 				= xen_apic_probe_pv,
    147	.acpi_madt_oem_check		= xen_madt_oem_check,
    148	.apic_id_valid 			= xen_id_always_valid,
    149	.apic_id_registered 		= xen_id_always_registered,
    150
    151	/* .delivery_mode and .dest_mode_logical not used by XENPV */
    152
    153	.disable_esr			= 0,
    154
    155	.check_apicid_used		= default_check_apicid_used, /* Used on 32-bit */
    156	.init_apic_ldr			= xen_noop, /* setup_local_APIC calls it */
    157	.ioapic_phys_id_map		= default_ioapic_phys_id_map, /* Used on 32-bit */
    158	.setup_apic_routing		= NULL,
    159	.cpu_present_to_apicid		= xen_cpu_present_to_apicid,
    160	.apicid_to_cpu_present		= physid_set_mask_of_physid, /* Used on 32-bit */
    161	.check_phys_apicid_present	= default_check_phys_apicid_present, /* smp_sanity_check needs it */
    162	.phys_pkg_id			= xen_phys_pkg_id, /* detect_ht */
    163
    164	.get_apic_id 			= xen_get_apic_id,
    165	.set_apic_id 			= xen_set_apic_id, /* Can be NULL on 32-bit. */
    166
    167	.calc_dest_apicid		= apic_flat_calc_apicid,
    168
    169#ifdef CONFIG_SMP
    170	.send_IPI_mask 			= xen_send_IPI_mask,
    171	.send_IPI_mask_allbutself 	= xen_send_IPI_mask_allbutself,
    172	.send_IPI_allbutself 		= xen_send_IPI_allbutself,
    173	.send_IPI_all 			= xen_send_IPI_all,
    174	.send_IPI_self 			= xen_send_IPI_self,
    175#endif
    176	/* .wait_for_init_deassert- used  by AP bootup - smp_callin which we don't use */
    177	.inquire_remote_apic		= xen_silent_inquire,
    178
    179	.read				= xen_apic_read,
    180	.write				= xen_apic_write,
    181	.eoi_write			= xen_apic_write,
    182
    183	.icr_read 			= xen_apic_icr_read,
    184	.icr_write 			= xen_apic_icr_write,
    185	.wait_icr_idle 			= xen_noop,
    186	.safe_wait_icr_idle 		= xen_safe_apic_wait_icr_idle,
    187};
    188
    189static void __init xen_apic_check(void)
    190{
    191	if (apic == &xen_pv_apic)
    192		return;
    193
    194	pr_info("Switched APIC routing from %s to %s.\n", apic->name,
    195		xen_pv_apic.name);
    196	apic = &xen_pv_apic;
    197}
    198void __init xen_init_apic(void)
    199{
    200	x86_apic_ops.io_apic_read = xen_io_apic_read;
    201	/* On PV guests the APIC CPUID bit is disabled so none of the
    202	 * routines end up executing. */
    203	if (!xen_initial_domain())
    204		apic = &xen_pv_apic;
    205
    206	x86_platform.apic_post_init = xen_apic_check;
    207}
    208apic_driver(xen_pv_apic);