diff options
-rw-r--r-- | arch/x86/xen/apic.c | 180 | ||||
-rw-r--r-- | arch/x86/xen/enlighten.c | 90 |
2 files changed, 181 insertions, 89 deletions
diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c index 7005ced5d1ad..5e0ecaf4c336 100644 --- a/arch/x86/xen/apic.c +++ b/arch/x86/xen/apic.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <xen/xen.h> | 7 | #include <xen/xen.h> |
8 | #include <xen/interface/physdev.h> | 8 | #include <xen/interface/physdev.h> |
9 | #include "xen-ops.h" | 9 | #include "xen-ops.h" |
10 | #include "smp.h" | ||
10 | 11 | ||
11 | static unsigned int xen_io_apic_read(unsigned apic, unsigned reg) | 12 | static unsigned int xen_io_apic_read(unsigned apic, unsigned reg) |
12 | { | 13 | { |
@@ -28,7 +29,186 @@ static unsigned int xen_io_apic_read(unsigned apic, unsigned reg) | |||
28 | return 0xfd; | 29 | return 0xfd; |
29 | } | 30 | } |
30 | 31 | ||
32 | static unsigned long xen_set_apic_id(unsigned int x) | ||
33 | { | ||
34 | WARN_ON(1); | ||
35 | return x; | ||
36 | } | ||
37 | |||
38 | static unsigned int xen_get_apic_id(unsigned long x) | ||
39 | { | ||
40 | return ((x)>>24) & 0xFFu; | ||
41 | } | ||
42 | |||
43 | static u32 xen_apic_read(u32 reg) | ||
44 | { | ||
45 | struct xen_platform_op op = { | ||
46 | .cmd = XENPF_get_cpuinfo, | ||
47 | .interface_version = XENPF_INTERFACE_VERSION, | ||
48 | .u.pcpu_info.xen_cpuid = 0, | ||
49 | }; | ||
50 | int ret = 0; | ||
51 | |||
52 | /* Shouldn't need this as APIC is turned off for PV, and we only | ||
53 | * get called on the bootup processor. But just in case. */ | ||
54 | if (!xen_initial_domain() || smp_processor_id()) | ||
55 | return 0; | ||
56 | |||
57 | if (reg == APIC_LVR) | ||
58 | return 0x10; | ||
59 | #ifdef CONFIG_X86_32 | ||
60 | if (reg == APIC_LDR) | ||
61 | return SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); | ||
62 | #endif | ||
63 | if (reg != APIC_ID) | ||
64 | return 0; | ||
65 | |||
66 | ret = HYPERVISOR_dom0_op(&op); | ||
67 | if (ret) | ||
68 | return 0; | ||
69 | |||
70 | return op.u.pcpu_info.apic_id << 24; | ||
71 | } | ||
72 | |||
73 | static void xen_apic_write(u32 reg, u32 val) | ||
74 | { | ||
75 | /* Warn to see if there's any stray references */ | ||
76 | WARN_ON(1); | ||
77 | } | ||
78 | |||
79 | static u64 xen_apic_icr_read(void) | ||
80 | { | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static void xen_apic_icr_write(u32 low, u32 id) | ||
85 | { | ||
86 | /* Warn to see if there's any stray references */ | ||
87 | WARN_ON(1); | ||
88 | } | ||
89 | |||
90 | static u32 xen_safe_apic_wait_icr_idle(void) | ||
91 | { | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static int xen_apic_probe_pv(void) | ||
96 | { | ||
97 | if (xen_pv_domain()) | ||
98 | return 1; | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int xen_madt_oem_check(char *oem_id, char *oem_table_id) | ||
104 | { | ||
105 | return xen_pv_domain(); | ||
106 | } | ||
107 | |||
108 | static int xen_id_always_valid(int apicid) | ||
109 | { | ||
110 | return 1; | ||
111 | } | ||
112 | |||
113 | static int xen_id_always_registered(void) | ||
114 | { | ||
115 | return 1; | ||
116 | } | ||
117 | |||
118 | static int xen_phys_pkg_id(int initial_apic_id, int index_msb) | ||
119 | { | ||
120 | return initial_apic_id >> index_msb; | ||
121 | } | ||
122 | |||
123 | #ifdef CONFIG_X86_32 | ||
124 | static int xen_x86_32_early_logical_apicid(int cpu) | ||
125 | { | ||
126 | /* Match with APIC_LDR read. Otherwise setup_local_APIC complains. */ | ||
127 | return 1 << cpu; | ||
128 | } | ||
129 | #endif | ||
130 | |||
131 | static void xen_noop(void) | ||
132 | { | ||
133 | } | ||
134 | |||
135 | static void xen_silent_inquire(int apicid) | ||
136 | { | ||
137 | } | ||
138 | |||
139 | static struct apic xen_pv_apic = { | ||
140 | .name = "Xen PV", | ||
141 | .probe = xen_apic_probe_pv, | ||
142 | .acpi_madt_oem_check = xen_madt_oem_check, | ||
143 | .apic_id_valid = xen_id_always_valid, | ||
144 | .apic_id_registered = xen_id_always_registered, | ||
145 | |||
146 | /* .irq_delivery_mode - used in native_compose_msi_msg only */ | ||
147 | /* .irq_dest_mode - used in native_compose_msi_msg only */ | ||
148 | |||
149 | .target_cpus = default_target_cpus, | ||
150 | .disable_esr = 0, | ||
151 | /* .dest_logical - default_send_IPI_ use it but we use our own. */ | ||
152 | .check_apicid_used = default_check_apicid_used, /* Used on 32-bit */ | ||
153 | |||
154 | .vector_allocation_domain = flat_vector_allocation_domain, | ||
155 | .init_apic_ldr = xen_noop, /* setup_local_APIC calls it */ | ||
156 | |||
157 | .ioapic_phys_id_map = default_ioapic_phys_id_map, /* Used on 32-bit */ | ||
158 | .setup_apic_routing = NULL, | ||
159 | .cpu_present_to_apicid = default_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 | .apic_id_mask = 0xFF << 24, /* Used by verify_local_APIC. Match with what xen_get_apic_id does. */ | ||
167 | |||
168 | .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, | ||
169 | |||
170 | #ifdef CONFIG_SMP | ||
171 | .send_IPI_mask = xen_send_IPI_mask, | ||
172 | .send_IPI_mask_allbutself = xen_send_IPI_mask_allbutself, | ||
173 | .send_IPI_allbutself = xen_send_IPI_allbutself, | ||
174 | .send_IPI_all = xen_send_IPI_all, | ||
175 | .send_IPI_self = xen_send_IPI_self, | ||
176 | #endif | ||
177 | /* .wait_for_init_deassert- used by AP bootup - smp_callin which we don't use */ | ||
178 | .inquire_remote_apic = xen_silent_inquire, | ||
179 | |||
180 | .read = xen_apic_read, | ||
181 | .write = xen_apic_write, | ||
182 | .eoi_write = xen_apic_write, | ||
183 | |||
184 | .icr_read = xen_apic_icr_read, | ||
185 | .icr_write = xen_apic_icr_write, | ||
186 | .wait_icr_idle = xen_noop, | ||
187 | .safe_wait_icr_idle = xen_safe_apic_wait_icr_idle, | ||
188 | |||
189 | #ifdef CONFIG_X86_32 | ||
190 | /* generic_processor_info and setup_local_APIC. */ | ||
191 | .x86_32_early_logical_apicid = xen_x86_32_early_logical_apicid, | ||
192 | #endif | ||
193 | }; | ||
194 | |||
195 | static void __init xen_apic_check(void) | ||
196 | { | ||
197 | if (apic == &xen_pv_apic) | ||
198 | return; | ||
199 | |||
200 | pr_info("Switched APIC routing from %s to %s.\n", apic->name, | ||
201 | xen_pv_apic.name); | ||
202 | apic = &xen_pv_apic; | ||
203 | } | ||
31 | void __init xen_init_apic(void) | 204 | void __init xen_init_apic(void) |
32 | { | 205 | { |
33 | x86_io_apic_ops.read = xen_io_apic_read; | 206 | x86_io_apic_ops.read = xen_io_apic_read; |
207 | /* On PV guests the APIC CPUID bit is disabled so none of the | ||
208 | * routines end up executing. */ | ||
209 | if (!xen_initial_domain()) | ||
210 | apic = &xen_pv_apic; | ||
211 | |||
212 | x86_platform.apic_post_init = xen_apic_check; | ||
34 | } | 213 | } |
214 | apic_driver(xen_pv_apic); | ||
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 5240f563076d..b9a227284149 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -927,92 +927,6 @@ static void xen_io_delay(void) | |||
927 | { | 927 | { |
928 | } | 928 | } |
929 | 929 | ||
930 | #ifdef CONFIG_X86_LOCAL_APIC | ||
931 | static unsigned long xen_set_apic_id(unsigned int x) | ||
932 | { | ||
933 | WARN_ON(1); | ||
934 | return x; | ||
935 | } | ||
936 | static unsigned int xen_get_apic_id(unsigned long x) | ||
937 | { | ||
938 | return ((x)>>24) & 0xFFu; | ||
939 | } | ||
940 | static u32 xen_apic_read(u32 reg) | ||
941 | { | ||
942 | struct xen_platform_op op = { | ||
943 | .cmd = XENPF_get_cpuinfo, | ||
944 | .interface_version = XENPF_INTERFACE_VERSION, | ||
945 | .u.pcpu_info.xen_cpuid = 0, | ||
946 | }; | ||
947 | int ret = 0; | ||
948 | |||
949 | /* Shouldn't need this as APIC is turned off for PV, and we only | ||
950 | * get called on the bootup processor. But just in case. */ | ||
951 | if (!xen_initial_domain() || smp_processor_id()) | ||
952 | return 0; | ||
953 | |||
954 | if (reg == APIC_LVR) | ||
955 | return 0x10; | ||
956 | |||
957 | if (reg != APIC_ID) | ||
958 | return 0; | ||
959 | |||
960 | ret = HYPERVISOR_dom0_op(&op); | ||
961 | if (ret) | ||
962 | return 0; | ||
963 | |||
964 | return op.u.pcpu_info.apic_id << 24; | ||
965 | } | ||
966 | |||
967 | static void xen_apic_write(u32 reg, u32 val) | ||
968 | { | ||
969 | /* Warn to see if there's any stray references */ | ||
970 | WARN_ON(1); | ||
971 | } | ||
972 | |||
973 | static u64 xen_apic_icr_read(void) | ||
974 | { | ||
975 | return 0; | ||
976 | } | ||
977 | |||
978 | static void xen_apic_icr_write(u32 low, u32 id) | ||
979 | { | ||
980 | /* Warn to see if there's any stray references */ | ||
981 | WARN_ON(1); | ||
982 | } | ||
983 | |||
984 | static void xen_apic_wait_icr_idle(void) | ||
985 | { | ||
986 | return; | ||
987 | } | ||
988 | |||
989 | static u32 xen_safe_apic_wait_icr_idle(void) | ||
990 | { | ||
991 | return 0; | ||
992 | } | ||
993 | |||
994 | static void set_xen_basic_apic_ops(void) | ||
995 | { | ||
996 | apic->read = xen_apic_read; | ||
997 | apic->write = xen_apic_write; | ||
998 | apic->icr_read = xen_apic_icr_read; | ||
999 | apic->icr_write = xen_apic_icr_write; | ||
1000 | apic->wait_icr_idle = xen_apic_wait_icr_idle; | ||
1001 | apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle; | ||
1002 | apic->set_apic_id = xen_set_apic_id; | ||
1003 | apic->get_apic_id = xen_get_apic_id; | ||
1004 | |||
1005 | #ifdef CONFIG_SMP | ||
1006 | apic->send_IPI_allbutself = xen_send_IPI_allbutself; | ||
1007 | apic->send_IPI_mask_allbutself = xen_send_IPI_mask_allbutself; | ||
1008 | apic->send_IPI_mask = xen_send_IPI_mask; | ||
1009 | apic->send_IPI_all = xen_send_IPI_all; | ||
1010 | apic->send_IPI_self = xen_send_IPI_self; | ||
1011 | #endif | ||
1012 | } | ||
1013 | |||
1014 | #endif | ||
1015 | |||
1016 | static void xen_clts(void) | 930 | static void xen_clts(void) |
1017 | { | 931 | { |
1018 | struct multicall_space mcs; | 932 | struct multicall_space mcs; |
@@ -1618,7 +1532,7 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
1618 | /* | 1532 | /* |
1619 | * set up the basic apic ops. | 1533 | * set up the basic apic ops. |
1620 | */ | 1534 | */ |
1621 | set_xen_basic_apic_ops(); | 1535 | xen_init_apic(); |
1622 | #endif | 1536 | #endif |
1623 | 1537 | ||
1624 | if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) { | 1538 | if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) { |
@@ -1731,8 +1645,6 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
1731 | if (HYPERVISOR_dom0_op(&op) == 0) | 1645 | if (HYPERVISOR_dom0_op(&op) == 0) |
1732 | boot_params.kbd_status = op.u.firmware_info.u.kbd_shift_flags; | 1646 | boot_params.kbd_status = op.u.firmware_info.u.kbd_shift_flags; |
1733 | 1647 | ||
1734 | xen_init_apic(); | ||
1735 | |||
1736 | /* Make sure ACS will be enabled */ | 1648 | /* Make sure ACS will be enabled */ |
1737 | pci_request_acs(); | 1649 | pci_request_acs(); |
1738 | 1650 | ||