x86/asm: Add DB flag to 32-bit percpu GDT entry
[linux-2.6-microblaze.git] / arch / x86 / kernel / apic / probe_32.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Default generic APIC driver. This handles up to 8 CPUs.
4  *
5  * Copyright 2003 Andi Kleen, SuSE Labs.
6  *
7  * Generic x86 APIC driver probe layer.
8  */
9 #include <linux/export.h>
10 #include <linux/errno.h>
11 #include <linux/smp.h>
12
13 #include <xen/xen.h>
14
15 #include <asm/io_apic.h>
16 #include <asm/apic.h>
17 #include <asm/acpi.h>
18
19 #include "local.h"
20
21 static u32 default_phys_pkg_id(u32 cpuid_apic, int index_msb)
22 {
23         return cpuid_apic >> index_msb;
24 }
25
26 static u32 default_get_apic_id(u32 x)
27 {
28         unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
29
30         if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID))
31                 return (x >> 24) & 0xFF;
32         else
33                 return (x >> 24) & 0x0F;
34 }
35
36 /* should be called last. */
37 static int probe_default(void)
38 {
39         return 1;
40 }
41
42 static struct apic apic_default __ro_after_init = {
43
44         .name                           = "default",
45         .probe                          = probe_default,
46         .apic_id_registered             = default_apic_id_registered,
47
48         .delivery_mode                  = APIC_DELIVERY_MODE_FIXED,
49         .dest_mode_logical              = true,
50
51         .disable_esr                    = 0,
52
53         .check_apicid_used              = default_check_apicid_used,
54         .init_apic_ldr                  = default_init_apic_ldr,
55         .ioapic_phys_id_map             = default_ioapic_phys_id_map,
56         .cpu_present_to_apicid          = default_cpu_present_to_apicid,
57         .phys_pkg_id                    = default_phys_pkg_id,
58
59         .max_apic_id                    = 0xFE,
60         .get_apic_id                    = default_get_apic_id,
61
62         .calc_dest_apicid               = apic_flat_calc_apicid,
63
64         .send_IPI                       = default_send_IPI_single,
65         .send_IPI_mask                  = default_send_IPI_mask_logical,
66         .send_IPI_mask_allbutself       = default_send_IPI_mask_allbutself_logical,
67         .send_IPI_allbutself            = default_send_IPI_allbutself,
68         .send_IPI_all                   = default_send_IPI_all,
69         .send_IPI_self                  = default_send_IPI_self,
70
71         .read                           = native_apic_mem_read,
72         .write                          = native_apic_mem_write,
73         .eoi                            = native_apic_mem_eoi,
74         .icr_read                       = native_apic_icr_read,
75         .icr_write                      = native_apic_icr_write,
76         .wait_icr_idle                  = apic_mem_wait_icr_idle,
77         .safe_wait_icr_idle             = apic_mem_wait_icr_idle_timeout,
78 };
79
80 apic_driver(apic_default);
81
82 struct apic *apic __ro_after_init = &apic_default;
83 EXPORT_SYMBOL_GPL(apic);
84
85 static int cmdline_apic __initdata;
86 static int __init parse_apic(char *arg)
87 {
88         struct apic **drv;
89
90         if (!arg)
91                 return -EINVAL;
92
93         for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
94                 if (!strcmp((*drv)->name, arg)) {
95                         apic_install_driver(*drv);
96                         cmdline_apic = 1;
97                         return 0;
98                 }
99         }
100
101         /* Parsed again by __setup for debug/verbose */
102         return 0;
103 }
104 early_param("apic", parse_apic);
105
106 void __init x86_32_probe_bigsmp_early(void)
107 {
108         if (nr_cpu_ids <= 8 || xen_pv_domain())
109                 return;
110
111         if (IS_ENABLED(CONFIG_X86_BIGSMP)) {
112                 switch (boot_cpu_data.x86_vendor) {
113                 case X86_VENDOR_INTEL:
114                         if (!APIC_XAPIC(boot_cpu_apic_version))
115                                 break;
116                         /* P4 and above */
117                         fallthrough;
118                 case X86_VENDOR_HYGON:
119                 case X86_VENDOR_AMD:
120                         if (apic_bigsmp_possible(cmdline_apic))
121                                 return;
122                         break;
123                 }
124         }
125         pr_info("Limiting to 8 possible CPUs\n");
126         set_nr_cpu_ids(8);
127 }
128
129 void __init x86_32_install_bigsmp(void)
130 {
131         if (nr_cpu_ids > 8 && !xen_pv_domain())
132                 apic_bigsmp_force();
133 }
134
135 void __init x86_32_probe_apic(void)
136 {
137         if (!cmdline_apic) {
138                 struct apic **drv;
139
140                 for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
141                         if ((*drv)->probe()) {
142                                 apic_install_driver(*drv);
143                                 break;
144                         }
145                 }
146                 /* Not visible without early console */
147                 if (drv == __apicdrivers_end)
148                         panic("Didn't find an APIC driver");
149         }
150 }