root/arch/x86/xen/apic.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xen_io_apic_read
  2. xen_set_apic_id
  3. xen_get_apic_id
  4. xen_apic_read
  5. xen_apic_write
  6. xen_apic_icr_read
  7. xen_apic_icr_write
  8. xen_safe_apic_wait_icr_idle
  9. xen_apic_probe_pv
  10. xen_madt_oem_check
  11. xen_id_always_valid
  12. xen_id_always_registered
  13. xen_phys_pkg_id
  14. xen_x86_32_early_logical_apicid
  15. xen_noop
  16. xen_silent_inquire
  17. xen_cpu_present_to_apicid
  18. xen_apic_check
  19. xen_init_apic

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

/* [<][>][^][v][top][bottom][index][help] */