0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/acpi_pmtmr.h>
0012 #include <linux/kernel.h>
0013 #include <linux/reboot.h>
0014 #include <linux/serial_8250.h>
0015 #include <asm/apic.h>
0016 #include <asm/io_apic.h>
0017 #include <asm/acpi.h>
0018 #include <asm/cpu.h>
0019 #include <asm/hypervisor.h>
0020 #include <asm/i8259.h>
0021 #include <asm/irqdomain.h>
0022 #include <asm/pci_x86.h>
0023 #include <asm/reboot.h>
0024 #include <asm/setup.h>
0025 #include <asm/jailhouse_para.h>
0026
0027 static struct jailhouse_setup_data setup_data;
0028 #define SETUP_DATA_V1_LEN (sizeof(setup_data.hdr) + sizeof(setup_data.v1))
0029 #define SETUP_DATA_V2_LEN (SETUP_DATA_V1_LEN + sizeof(setup_data.v2))
0030
0031 static unsigned int precalibrated_tsc_khz;
0032
0033 static void jailhouse_setup_irq(unsigned int irq)
0034 {
0035 struct mpc_intsrc mp_irq = {
0036 .type = MP_INTSRC,
0037 .irqtype = mp_INT,
0038 .irqflag = MP_IRQPOL_ACTIVE_HIGH | MP_IRQTRIG_EDGE,
0039 .srcbusirq = irq,
0040 .dstirq = irq,
0041 };
0042 mp_save_irq(&mp_irq);
0043 }
0044
0045 static uint32_t jailhouse_cpuid_base(void)
0046 {
0047 if (boot_cpu_data.cpuid_level < 0 ||
0048 !boot_cpu_has(X86_FEATURE_HYPERVISOR))
0049 return 0;
0050
0051 return hypervisor_cpuid_base("Jailhouse\0\0\0", 0);
0052 }
0053
0054 static uint32_t __init jailhouse_detect(void)
0055 {
0056 return jailhouse_cpuid_base();
0057 }
0058
0059 static void jailhouse_get_wallclock(struct timespec64 *now)
0060 {
0061 memset(now, 0, sizeof(*now));
0062 }
0063
0064 static void __init jailhouse_timer_init(void)
0065 {
0066 lapic_timer_period = setup_data.v1.apic_khz * (1000 / HZ);
0067 }
0068
0069 static unsigned long jailhouse_get_tsc(void)
0070 {
0071 return precalibrated_tsc_khz;
0072 }
0073
0074 static void __init jailhouse_x2apic_init(void)
0075 {
0076 #ifdef CONFIG_X86_X2APIC
0077 if (!x2apic_enabled())
0078 return;
0079
0080
0081
0082
0083 x2apic_phys = 1;
0084
0085
0086
0087
0088 default_acpi_madt_oem_check("", "");
0089 #endif
0090 }
0091
0092 static void __init jailhouse_get_smp_config(unsigned int early)
0093 {
0094 struct ioapic_domain_cfg ioapic_cfg = {
0095 .type = IOAPIC_DOMAIN_STRICT,
0096 .ops = &mp_ioapic_irqdomain_ops,
0097 };
0098 unsigned int cpu;
0099
0100 jailhouse_x2apic_init();
0101
0102 register_lapic_address(0xfee00000);
0103
0104 for (cpu = 0; cpu < setup_data.v1.num_cpus; cpu++) {
0105 generic_processor_info(setup_data.v1.cpu_ids[cpu],
0106 boot_cpu_apic_version);
0107 }
0108
0109 smp_found_config = 1;
0110
0111 if (setup_data.v1.standard_ioapic) {
0112 mp_register_ioapic(0, 0xfec00000, gsi_top, &ioapic_cfg);
0113
0114 if (IS_ENABLED(CONFIG_SERIAL_8250) &&
0115 setup_data.hdr.version < 2) {
0116
0117 jailhouse_setup_irq(3);
0118 jailhouse_setup_irq(4);
0119 }
0120 }
0121 }
0122
0123 static void jailhouse_no_restart(void)
0124 {
0125 pr_notice("Jailhouse: Restart not supported, halting\n");
0126 machine_halt();
0127 }
0128
0129 static int __init jailhouse_pci_arch_init(void)
0130 {
0131 pci_direct_init(1);
0132
0133
0134
0135
0136
0137
0138 if (pcibios_last_bus < 0)
0139 pcibios_last_bus = 0xff;
0140
0141 #ifdef CONFIG_PCI_MMCONFIG
0142 if (setup_data.v1.pci_mmconfig_base) {
0143 pci_mmconfig_add(0, 0, pcibios_last_bus,
0144 setup_data.v1.pci_mmconfig_base);
0145 pci_mmcfg_arch_init();
0146 }
0147 #endif
0148
0149 return 0;
0150 }
0151
0152 #ifdef CONFIG_SERIAL_8250
0153 static inline bool jailhouse_uart_enabled(unsigned int uart_nr)
0154 {
0155 return setup_data.v2.flags & BIT(uart_nr);
0156 }
0157
0158 static void jailhouse_serial_fixup(int port, struct uart_port *up,
0159 u32 *capabilities)
0160 {
0161 static const u16 pcuart_base[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};
0162 unsigned int n;
0163
0164 for (n = 0; n < ARRAY_SIZE(pcuart_base); n++) {
0165 if (pcuart_base[n] != up->iobase)
0166 continue;
0167
0168 if (jailhouse_uart_enabled(n)) {
0169 pr_info("Enabling UART%u (port 0x%lx)\n", n,
0170 up->iobase);
0171 jailhouse_setup_irq(up->irq);
0172 } else {
0173
0174 up->iobase = 0;
0175 }
0176 break;
0177 }
0178 }
0179
0180 static void __init jailhouse_serial_workaround(void)
0181 {
0182
0183
0184
0185
0186
0187
0188
0189
0190 if (setup_data.hdr.version > 1)
0191 serial8250_set_isa_configurator(jailhouse_serial_fixup);
0192 }
0193 #else
0194 static inline void jailhouse_serial_workaround(void)
0195 {
0196 }
0197 #endif
0198
0199 static void __init jailhouse_init_platform(void)
0200 {
0201 u64 pa_data = boot_params.hdr.setup_data;
0202 unsigned long setup_data_len;
0203 struct setup_data header;
0204 void *mapping;
0205
0206 x86_init.irqs.pre_vector_init = x86_init_noop;
0207 x86_init.timers.timer_init = jailhouse_timer_init;
0208 x86_init.mpparse.get_smp_config = jailhouse_get_smp_config;
0209 x86_init.pci.arch_init = jailhouse_pci_arch_init;
0210
0211 x86_platform.calibrate_cpu = jailhouse_get_tsc;
0212 x86_platform.calibrate_tsc = jailhouse_get_tsc;
0213 x86_platform.get_wallclock = jailhouse_get_wallclock;
0214 x86_platform.legacy.rtc = 0;
0215 x86_platform.legacy.warm_reset = 0;
0216 x86_platform.legacy.i8042 = X86_LEGACY_I8042_PLATFORM_ABSENT;
0217
0218 legacy_pic = &null_legacy_pic;
0219
0220 machine_ops.emergency_restart = jailhouse_no_restart;
0221
0222 while (pa_data) {
0223 mapping = early_memremap(pa_data, sizeof(header));
0224 memcpy(&header, mapping, sizeof(header));
0225 early_memunmap(mapping, sizeof(header));
0226
0227 if (header.type == SETUP_JAILHOUSE)
0228 break;
0229
0230 pa_data = header.next;
0231 }
0232
0233 if (!pa_data)
0234 panic("Jailhouse: No valid setup data found");
0235
0236
0237 if (header.len < sizeof(setup_data.hdr))
0238 goto unsupported;
0239
0240 pa_data += offsetof(struct setup_data, data);
0241 setup_data_len = min_t(unsigned long, sizeof(setup_data),
0242 (unsigned long)header.len);
0243 mapping = early_memremap(pa_data, setup_data_len);
0244 memcpy(&setup_data, mapping, setup_data_len);
0245 early_memunmap(mapping, setup_data_len);
0246
0247 if (setup_data.hdr.version == 0 ||
0248 setup_data.hdr.compatible_version !=
0249 JAILHOUSE_SETUP_REQUIRED_VERSION ||
0250 (setup_data.hdr.version == 1 && header.len < SETUP_DATA_V1_LEN) ||
0251 (setup_data.hdr.version >= 2 && header.len < SETUP_DATA_V2_LEN))
0252 goto unsupported;
0253
0254 pmtmr_ioport = setup_data.v1.pm_timer_address;
0255 pr_debug("Jailhouse: PM-Timer IO Port: %#x\n", pmtmr_ioport);
0256
0257 precalibrated_tsc_khz = setup_data.v1.tsc_khz;
0258 setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
0259
0260 pci_probe = 0;
0261
0262
0263
0264
0265
0266 disable_acpi();
0267
0268 jailhouse_serial_workaround();
0269 return;
0270
0271 unsupported:
0272 panic("Jailhouse: Unsupported setup data structure");
0273 }
0274
0275 bool jailhouse_paravirt(void)
0276 {
0277 return jailhouse_cpuid_base() != 0;
0278 }
0279
0280 static bool __init jailhouse_x2apic_available(void)
0281 {
0282
0283
0284
0285
0286 return x2apic_enabled();
0287 }
0288
0289 const struct hypervisor_x86 x86_hyper_jailhouse __refconst = {
0290 .name = "Jailhouse",
0291 .detect = jailhouse_detect,
0292 .init.init_platform = jailhouse_init_platform,
0293 .init.x2apic_available = jailhouse_x2apic_available,
0294 .ignore_nopv = true,
0295 };