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