]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.9.28/xen-revert-commits-da72ff5bfcb0-and-72a9b186292d.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.9.28 / xen-revert-commits-da72ff5bfcb0-and-72a9b186292d.patch
1 From 84d582d236dc1f9085e741affc72e9ba061a67c2 Mon Sep 17 00:00:00 2001
2 From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
3 Date: Mon, 24 Apr 2017 15:04:53 -0400
4 Subject: xen: Revert commits da72ff5bfcb0 and 72a9b186292d
5
6 From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
7
8 commit 84d582d236dc1f9085e741affc72e9ba061a67c2 upstream.
9
10 Recent discussion (http://marc.info/?l=xen-devel&m=149192184523741)
11 established that commit 72a9b186292d ("xen: Remove event channel
12 notification through Xen PCI platform device") (and thus commit
13 da72ff5bfcb0 ("partially revert "xen: Remove event channel
14 notification through Xen PCI platform device"")) are unnecessary and,
15 in fact, prevent HVM guests from booting on Xen releases prior to 4.0
16
17 Therefore we revert both of those commits.
18
19 The summary of that discussion is below:
20
21 Here is the brief summary of the current situation:
22
23 Before the offending commit (72a9b186292):
24
25 1) INTx does not work because of the reset_watches path.
26 2) The reset_watches path is only taken if you have Xen > 4.0
27 3) The Linux Kernel by default will use vector inject if the hypervisor
28 support. So even INTx does not work no body running the kernel with
29 Xen > 4.0 would notice. Unless he explicitly disabled this feature
30 either in the kernel or in Xen (and this can only be disabled by
31 modifying the code, not user-supported way to do it).
32
33 After the offending commit (+ partial revert):
34
35 1) INTx is no longer support for HVM (only for PV guests).
36 2) Any HVM guest The kernel will not boot on Xen < 4.0 which does
37 not have vector injection support. Since the only other mode
38 supported is INTx which.
39
40 So based on this summary, I think before commit (72a9b186292) we were
41 in much better position from a user point of view.
42
43 Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
44 Reviewed-by: Juergen Gross <jgross@suse.com>
45 Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
46 Cc: Thomas Gleixner <tglx@linutronix.de>
47 Cc: Ingo Molnar <mingo@redhat.com>
48 Cc: "H. Peter Anvin" <hpa@zytor.com>
49 Cc: x86@kernel.org
50 Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
51 Cc: Bjorn Helgaas <bhelgaas@google.com>
52 Cc: Stefano Stabellini <sstabellini@kernel.org>
53 Cc: Julien Grall <julien.grall@arm.com>
54 Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
55 Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
56 Cc: Ross Lagerwall <ross.lagerwall@citrix.com>
57 Cc: xen-devel@lists.xenproject.org
58 Cc: linux-kernel@vger.kernel.org
59 Cc: linux-pci@vger.kernel.org
60 Cc: Anthony Liguori <aliguori@amazon.com>
61 Cc: KarimAllah Ahmed <karahmed@amazon.de>
62 Signed-off-by: Juergen Gross <jgross@suse.com>
63 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
64
65 ---
66 arch/x86/include/asm/xen/events.h | 11 ++++++
67 arch/x86/pci/xen.c | 2 -
68 arch/x86/xen/enlighten.c | 21 ++++++++----
69 arch/x86/xen/smp.c | 2 +
70 arch/x86/xen/time.c | 5 ++
71 drivers/xen/events/events_base.c | 26 ++++++++++-----
72 drivers/xen/platform-pci.c | 64 ++++++++++++++++++++++++++++++++++++++
73 include/xen/xen.h | 3 +
74 8 files changed, 117 insertions(+), 17 deletions(-)
75
76 --- a/arch/x86/include/asm/xen/events.h
77 +++ b/arch/x86/include/asm/xen/events.h
78 @@ -20,4 +20,15 @@ static inline int xen_irqs_disabled(stru
79 /* No need for a barrier -- XCHG is a barrier on x86. */
80 #define xchg_xen_ulong(ptr, val) xchg((ptr), (val))
81
82 +extern int xen_have_vector_callback;
83 +
84 +/*
85 + * Events delivered via platform PCI interrupts are always
86 + * routed to vcpu 0 and hence cannot be rebound.
87 + */
88 +static inline bool xen_support_evtchn_rebind(void)
89 +{
90 + return (!xen_hvm_domain() || xen_have_vector_callback);
91 +}
92 +
93 #endif /* _ASM_X86_XEN_EVENTS_H */
94 --- a/arch/x86/pci/xen.c
95 +++ b/arch/x86/pci/xen.c
96 @@ -447,7 +447,7 @@ void __init xen_msi_init(void)
97
98 int __init pci_xen_hvm_init(void)
99 {
100 - if (!xen_feature(XENFEAT_hvm_pirqs))
101 + if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs))
102 return 0;
103
104 #ifdef CONFIG_ACPI
105 --- a/arch/x86/xen/enlighten.c
106 +++ b/arch/x86/xen/enlighten.c
107 @@ -137,6 +137,8 @@ struct shared_info xen_dummy_shared_info
108 void *xen_initial_gdt;
109
110 RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
111 +__read_mostly int xen_have_vector_callback;
112 +EXPORT_SYMBOL_GPL(xen_have_vector_callback);
113
114 static int xen_cpu_up_prepare(unsigned int cpu);
115 static int xen_cpu_up_online(unsigned int cpu);
116 @@ -1521,7 +1523,10 @@ static void __init xen_pvh_early_guest_i
117 if (!xen_feature(XENFEAT_auto_translated_physmap))
118 return;
119
120 - BUG_ON(!xen_feature(XENFEAT_hvm_callback_vector));
121 + if (!xen_feature(XENFEAT_hvm_callback_vector))
122 + return;
123 +
124 + xen_have_vector_callback = 1;
125
126 xen_pvh_early_cpu_init(0, false);
127 xen_pvh_set_cr_flags(0);
128 @@ -1860,7 +1865,9 @@ static int xen_cpu_up_prepare(unsigned i
129 xen_vcpu_setup(cpu);
130 }
131
132 - if (xen_pv_domain() || xen_feature(XENFEAT_hvm_safe_pvclock))
133 + if (xen_pv_domain() ||
134 + (xen_have_vector_callback &&
135 + xen_feature(XENFEAT_hvm_safe_pvclock)))
136 xen_setup_timer(cpu);
137
138 rc = xen_smp_intr_init(cpu);
139 @@ -1876,7 +1883,9 @@ static int xen_cpu_dead(unsigned int cpu
140 {
141 xen_smp_intr_free(cpu);
142
143 - if (xen_pv_domain() || xen_feature(XENFEAT_hvm_safe_pvclock))
144 + if (xen_pv_domain() ||
145 + (xen_have_vector_callback &&
146 + xen_feature(XENFEAT_hvm_safe_pvclock)))
147 xen_teardown_timer(cpu);
148
149 return 0;
150 @@ -1915,8 +1924,8 @@ static void __init xen_hvm_guest_init(vo
151
152 xen_panic_handler_init();
153
154 - BUG_ON(!xen_feature(XENFEAT_hvm_callback_vector));
155 -
156 + if (xen_feature(XENFEAT_hvm_callback_vector))
157 + xen_have_vector_callback = 1;
158 xen_hvm_smp_init();
159 WARN_ON(xen_cpuhp_setup());
160 xen_unplug_emulated_devices();
161 @@ -1954,7 +1963,7 @@ bool xen_hvm_need_lapic(void)
162 return false;
163 if (!xen_hvm_domain())
164 return false;
165 - if (xen_feature(XENFEAT_hvm_pirqs))
166 + if (xen_feature(XENFEAT_hvm_pirqs) && xen_have_vector_callback)
167 return false;
168 return true;
169 }
170 --- a/arch/x86/xen/smp.c
171 +++ b/arch/x86/xen/smp.c
172 @@ -765,6 +765,8 @@ static void __init xen_hvm_smp_prepare_c
173
174 void __init xen_hvm_smp_init(void)
175 {
176 + if (!xen_have_vector_callback)
177 + return;
178 smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus;
179 smp_ops.smp_send_reschedule = xen_smp_send_reschedule;
180 smp_ops.cpu_die = xen_cpu_die;
181 --- a/arch/x86/xen/time.c
182 +++ b/arch/x86/xen/time.c
183 @@ -432,6 +432,11 @@ static void xen_hvm_setup_cpu_clockevent
184
185 void __init xen_hvm_init_time_ops(void)
186 {
187 + /* vector callback is needed otherwise we cannot receive interrupts
188 + * on cpu > 0 and at this point we don't know how many cpus are
189 + * available */
190 + if (!xen_have_vector_callback)
191 + return;
192 if (!xen_feature(XENFEAT_hvm_safe_pvclock)) {
193 printk(KERN_INFO "Xen doesn't support pvclock on HVM,"
194 "disable pv timer\n");
195 --- a/drivers/xen/events/events_base.c
196 +++ b/drivers/xen/events/events_base.c
197 @@ -1314,6 +1314,9 @@ static int rebind_irq_to_cpu(unsigned ir
198 if (!VALID_EVTCHN(evtchn))
199 return -1;
200
201 + if (!xen_support_evtchn_rebind())
202 + return -1;
203 +
204 /* Send future instances of this interrupt to other vcpu. */
205 bind_vcpu.port = evtchn;
206 bind_vcpu.vcpu = xen_vcpu_nr(tcpu);
207 @@ -1647,15 +1650,20 @@ void xen_callback_vector(void)
208 {
209 int rc;
210 uint64_t callback_via;
211 -
212 - callback_via = HVM_CALLBACK_VECTOR(HYPERVISOR_CALLBACK_VECTOR);
213 - rc = xen_set_callback_via(callback_via);
214 - BUG_ON(rc);
215 - pr_info("Xen HVM callback vector for event delivery is enabled\n");
216 - /* in the restore case the vector has already been allocated */
217 - if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors))
218 - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
219 - xen_hvm_callback_vector);
220 + if (xen_have_vector_callback) {
221 + callback_via = HVM_CALLBACK_VECTOR(HYPERVISOR_CALLBACK_VECTOR);
222 + rc = xen_set_callback_via(callback_via);
223 + if (rc) {
224 + pr_err("Request for Xen HVM callback vector failed\n");
225 + xen_have_vector_callback = 0;
226 + return;
227 + }
228 + pr_info("Xen HVM callback vector for event delivery is enabled\n");
229 + /* in the restore case the vector has already been allocated */
230 + if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors))
231 + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
232 + xen_hvm_callback_vector);
233 + }
234 }
235 #else
236 void xen_callback_vector(void) {}
237 --- a/drivers/xen/platform-pci.c
238 +++ b/drivers/xen/platform-pci.c
239 @@ -42,6 +42,7 @@
240 static unsigned long platform_mmio;
241 static unsigned long platform_mmio_alloc;
242 static unsigned long platform_mmiolen;
243 +static uint64_t callback_via;
244
245 static unsigned long alloc_xen_mmio(unsigned long len)
246 {
247 @@ -54,6 +55,51 @@ static unsigned long alloc_xen_mmio(unsi
248 return addr;
249 }
250
251 +static uint64_t get_callback_via(struct pci_dev *pdev)
252 +{
253 + u8 pin;
254 + int irq;
255 +
256 + irq = pdev->irq;
257 + if (irq < 16)
258 + return irq; /* ISA IRQ */
259 +
260 + pin = pdev->pin;
261 +
262 + /* We don't know the GSI. Specify the PCI INTx line instead. */
263 + return ((uint64_t)0x01 << 56) | /* PCI INTx identifier */
264 + ((uint64_t)pci_domain_nr(pdev->bus) << 32) |
265 + ((uint64_t)pdev->bus->number << 16) |
266 + ((uint64_t)(pdev->devfn & 0xff) << 8) |
267 + ((uint64_t)(pin - 1) & 3);
268 +}
269 +
270 +static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id)
271 +{
272 + xen_hvm_evtchn_do_upcall();
273 + return IRQ_HANDLED;
274 +}
275 +
276 +static int xen_allocate_irq(struct pci_dev *pdev)
277 +{
278 + return request_irq(pdev->irq, do_hvm_evtchn_intr,
279 + IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
280 + "xen-platform-pci", pdev);
281 +}
282 +
283 +static int platform_pci_resume(struct pci_dev *pdev)
284 +{
285 + int err;
286 + if (xen_have_vector_callback)
287 + return 0;
288 + err = xen_set_callback_via(callback_via);
289 + if (err) {
290 + dev_err(&pdev->dev, "platform_pci_resume failure!\n");
291 + return err;
292 + }
293 + return 0;
294 +}
295 +
296 static int platform_pci_probe(struct pci_dev *pdev,
297 const struct pci_device_id *ent)
298 {
299 @@ -92,6 +138,21 @@ static int platform_pci_probe(struct pci
300 platform_mmio = mmio_addr;
301 platform_mmiolen = mmio_len;
302
303 + if (!xen_have_vector_callback) {
304 + ret = xen_allocate_irq(pdev);
305 + if (ret) {
306 + dev_warn(&pdev->dev, "request_irq failed err=%d\n", ret);
307 + goto out;
308 + }
309 + callback_via = get_callback_via(pdev);
310 + ret = xen_set_callback_via(callback_via);
311 + if (ret) {
312 + dev_warn(&pdev->dev, "Unable to set the evtchn callback "
313 + "err=%d\n", ret);
314 + goto out;
315 + }
316 + }
317 +
318 max_nr_gframes = gnttab_max_grant_frames();
319 grant_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
320 ret = gnttab_setup_auto_xlat_frames(grant_frames);
321 @@ -123,6 +184,9 @@ static struct pci_driver platform_driver
322 .name = DRV_NAME,
323 .probe = platform_pci_probe,
324 .id_table = platform_pci_tbl,
325 +#ifdef CONFIG_PM
326 + .resume_early = platform_pci_resume,
327 +#endif
328 };
329
330 static int __init platform_pci_init(void)
331 --- a/include/xen/xen.h
332 +++ b/include/xen/xen.h
333 @@ -38,7 +38,8 @@ extern enum xen_domain_type xen_domain_t
334 */
335 #include <xen/features.h>
336 #define xen_pvh_domain() (xen_pv_domain() && \
337 - xen_feature(XENFEAT_auto_translated_physmap))
338 + xen_feature(XENFEAT_auto_translated_physmap) && \
339 + xen_have_vector_callback)
340 #else
341 #define xen_pvh_domain() (0)
342 #endif