History

Merge tag 'for-linus-6.11-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen updates from Juergen Gross: - some trivial cleanups - a fix for the Xen timer - add boot time selectable debug capability to the Xen multicall handling - two fixes for the recently added Xen irqfd handling * tag 'for-linus-6.11-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: x86/xen: remove deprecated xen_nopvspin boot parameter x86/xen: eliminate some private header files x86/xen: make some functions static xen: make multicall debug boot time selectable xen/arm: Convert comma to semicolon xen: privcmd: Fix possible access to a freed kirqfd instance xen: privcmd: Switch from mutex to spinlock for irqfds xen: add missing MODULE_DESCRIPTION() macros x86/xen: Convert comma to semicolon x86/xen/time: Reduce Xen timer tick xen/manage: Constify struct shutdown_handler

Linus Torvalds committed 2 years ago

Commit f83e38f2 parents e55037c 9fe6a8c33 files · +305 −276Browse files

Unified · Split

33 files
  1. Documentation/admin-guide/kernel-parameters.txt +6 −5
  2. arch/arm/xen/p2m.c +1 −1
  3. arch/x86/xen/apic.c +0 −2
  4. arch/x86/xen/debugfs.c +1 −1
  5. arch/x86/xen/debugfs.h +0 −7
  6. arch/x86/xen/enlighten.c +0 −2
  7. arch/x86/xen/enlighten_hvm.c +0 −2
  8. arch/x86/xen/enlighten_pv.c +0 −4
  9. arch/x86/xen/mmu.c +1 −2
  10. arch/x86/xen/mmu.h +0 −28
  11. arch/x86/xen/mmu_hvm.c +1 −1
  12. arch/x86/xen/mmu_pv.c +7 −8
  13. arch/x86/xen/multicalls.c +103 −25
  14. arch/x86/xen/multicalls.h +0 −69
  15. arch/x86/xen/p2m.c +2 −4
  16. arch/x86/xen/pmu.c +0 −1
  17. arch/x86/xen/pmu.h +0 −22
  18. arch/x86/xen/setup.c +0 −1
  19. arch/x86/xen/smp.c +0 −1
  20. arch/x86/xen/smp.h +0 −51
  21. arch/x86/xen/smp_hvm.c +0 −2
  22. arch/x86/xen/smp_pv.c +0 −3
  23. arch/x86/xen/spinlock.c +5 −15
  24. arch/x86/xen/suspend.c +0 −2
  25. arch/x86/xen/time.c +1 −1
  26. arch/x86/xen/xen-ops.h +145 −3
  27. drivers/xen/evtchn.c +1 −0
  28. drivers/xen/manage.c +1 −1
  29. drivers/xen/privcmd-buf.c +1 −0
  30. drivers/xen/privcmd.c +25 −11
  31. drivers/xen/xen-pciback/pci_stub.c +1 −0
  32. include/xen/events.h +2 −0
  33. kernel/locking/qspinlock.c +1 −1
Documentation/admin-guide/kernel-parameters.txt+6−5
@@ -7420,17 +7420,18 @@ · 7419 unmodified lines
7420 Crash from Xen panic notifier, without executing late7420 Crash from Xen panic notifier, without executing late
7421 panic() code such as dumping handler.7421 panic() code such as dumping handler.
7422 7422
7423 xen_mc_debug [X86,XEN,EARLY]
7424 Enable multicall debugging when running as a Xen PV guest.
7425 Enabling this feature will reduce performance a little
7426 bit, so it should only be enabled for obtaining extended
7427 debug data in case of multicall errors.
7428
7423 xen_msr_safe= [X86,XEN,EARLY]7429 xen_msr_safe= [X86,XEN,EARLY]
7424 Format: <bool>7430 Format: <bool>
7425 Select whether to always use non-faulting (safe) MSR7431 Select whether to always use non-faulting (safe) MSR
7426 access functions when running as Xen PV guest. The7432 access functions when running as Xen PV guest. The
7427 default value is controlled by CONFIG_XEN_PV_MSR_SAFE.7433 default value is controlled by CONFIG_XEN_PV_MSR_SAFE.
7428 7434
7429 xen_nopvspin [X86,XEN,EARLY]
7430 Disables the qspinlock slowpath using Xen PV optimizations.
7431 This parameter is obsoleted by "nopvspin" parameter, which
7432 has equivalent effect for XEN platform.
7433
7434 xen_nopv [X86]7435 xen_nopv [X86]
7435 Disables the PV optimizations forcing the HVM guest to7436 Disables the PV optimizations forcing the HVM guest to
7436 run as generic HVM guest with no PV drivers.7437 run as generic HVM guest with no PV drivers.
arch/arm/xen/p2m.c+1−1
@@ -109,7 +109,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, · 108 unmodified lines
109 * immediate unmapping.109 * immediate unmapping.
110 */110 */
111 map_ops[i].status = GNTST_general_error;111 map_ops[i].status = GNTST_general_error;
112 unmap.host_addr = map_ops[i].host_addr,112 unmap.host_addr = map_ops[i].host_addr;
113 unmap.handle = map_ops[i].handle;113 unmap.handle = map_ops[i].handle;
114 map_ops[i].handle = INVALID_GRANT_HANDLE;114 map_ops[i].handle = INVALID_GRANT_HANDLE;
115 if (map_ops[i].flags & GNTMAP_device_map)115 if (map_ops[i].flags & GNTMAP_device_map)
arch/x86/xen/apic.c+0−2
@@ -10,8 +10,6 @@ · 9 unmodified lines
10#include <xen/xen.h>10#include <xen/xen.h>
11#include <xen/interface/physdev.h>11#include <xen/interface/physdev.h>
12#include "xen-ops.h"12#include "xen-ops.h"
13#include "pmu.h"
14#include "smp.h"
15 13
16static unsigned int xen_io_apic_read(unsigned apic, unsigned reg)14static unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
17{15{
arch/x86/xen/debugfs.c+1−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
3#include <linux/debugfs.h>3#include <linux/debugfs.h>
4#include <linux/slab.h>4#include <linux/slab.h>
5 5
6#include "debugfs.h"6#include "xen-ops.h"
7 7
8static struct dentry *d_xen_debug;8static struct dentry *d_xen_debug;
9 9
arch/x86/xen/debugfs.h+0−7
@@ -1,7 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _XEN_DEBUGFS_H
3#define _XEN_DEBUGFS_H
4
5struct dentry * __init xen_init_debugfs(void);
6
7#endif /* _XEN_DEBUGFS_H */
arch/x86/xen/enlighten.c+0−2
@@ -20,8 +20,6 @@ · 19 unmodified lines
20#include <asm/setup.h>20#include <asm/setup.h>
21 21
22#include "xen-ops.h"22#include "xen-ops.h"
23#include "smp.h"
24#include "pmu.h"
25 23
26EXPORT_SYMBOL_GPL(hypercall_page);24EXPORT_SYMBOL_GPL(hypercall_page);
27 25
arch/x86/xen/enlighten_hvm.c+0−2
@@ -28,8 +28,6 @@ · 27 unmodified lines
28#include <asm/xen/page.h>28#include <asm/xen/page.h>
29 29
30#include "xen-ops.h"30#include "xen-ops.h"
31#include "mmu.h"
32#include "smp.h"
33 31
34static unsigned long shared_info_pfn;32static unsigned long shared_info_pfn;
35 33
arch/x86/xen/enlighten_pv.c+0−4
@@ -85,10 +85,6 @@ · 84 unmodified lines
85#endif85#endif
86 86
87#include "xen-ops.h"87#include "xen-ops.h"
88#include "mmu.h"
89#include "smp.h"
90#include "multicalls.h"
91#include "pmu.h"
92 88
93#include "../kernel/cpu/cpu.h" /* get_cpu_cap() */89#include "../kernel/cpu/cpu.h" /* get_cpu_cap() */
94 90
arch/x86/xen/mmu.c+1−2
@@ -5,8 +5,7 @@ · 4 unmodified lines
5#include <asm/xen/hypercall.h>5#include <asm/xen/hypercall.h>
6#include <xen/interface/memory.h>6#include <xen/interface/memory.h>
7 7
8#include "multicalls.h"8#include "xen-ops.h"
9#include "mmu.h"
10 9
11unsigned long arbitrary_virt_to_mfn(void *vaddr)10unsigned long arbitrary_virt_to_mfn(void *vaddr)
12{11{
arch/x86/xen/mmu.h+0−28
@@ -1,28 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _XEN_MMU_H
3
4#include <linux/linkage.h>
5#include <asm/page.h>
6
7enum pt_level {
8 PT_PGD,
9 PT_P4D,
10 PT_PUD,
11 PT_PMD,
12 PT_PTE
13};
14
15
16bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
17
18void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
19
20pte_t xen_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
21void xen_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr,
22 pte_t *ptep, pte_t pte);
23
24unsigned long xen_read_cr2_direct(void);
25
26extern void xen_init_mmu_ops(void);
27extern void xen_hvm_init_mmu_ops(void);
28#endif /* _XEN_MMU_H */
arch/x86/xen/mmu_hvm.c+1−1
@@ -5,7 +5,7 @@ · 4 unmodified lines
5#include <xen/interface/xen.h>5#include <xen/interface/xen.h>
6#include <xen/hvm.h>6#include <xen/hvm.h>
7 7
8#include "mmu.h"8#include "xen-ops.h"
9 9
10#ifdef CONFIG_PROC_VMCORE10#ifdef CONFIG_PROC_VMCORE
11/*11/*
arch/x86/xen/mmu_pv.c+7−8
@@ -82,9 +82,7 @@ · 81 unmodified lines
82#include <xen/hvc-console.h>82#include <xen/hvc-console.h>
83#include <xen/swiotlb-xen.h>83#include <xen/swiotlb-xen.h>
84 84
85#include "multicalls.h"85#include "xen-ops.h"
86#include "mmu.h"
87#include "debugfs.h"
88 86
89/*87/*
90 * Prototypes for functions called via PV_CALLEE_SAVE_REGS_THUNK() in order88 * Prototypes for functions called via PV_CALLEE_SAVE_REGS_THUNK() in order
@@ -128,7 +126,7 @@ static DEFINE_SPINLOCK(xen_reservation_lock); · 37 unmodified lines
128 * looking at another vcpu's cr3 value, it should use this variable.126 * looking at another vcpu's cr3 value, it should use this variable.
129 */127 */
130DEFINE_PER_CPU(unsigned long, xen_cr3); /* cr3 stored as physaddr */128DEFINE_PER_CPU(unsigned long, xen_cr3); /* cr3 stored as physaddr */
131DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */129static DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */
132 130
133static phys_addr_t xen_pt_base, xen_pt_size __initdata;131static phys_addr_t xen_pt_base, xen_pt_size __initdata;
134 132
@@ -305,16 +303,17 @@ static void xen_set_pte(pte_t *ptep, pte_t pteval) · 170 unmodified lines
305 __xen_set_pte(ptep, pteval);303 __xen_set_pte(ptep, pteval);
306}304}
307 305
308pte_t xen_ptep_modify_prot_start(struct vm_area_struct *vma,306static pte_t xen_ptep_modify_prot_start(struct vm_area_struct *vma,
309 unsigned long addr, pte_t *ptep)307 unsigned long addr, pte_t *ptep)
310{308{
311 /* Just return the pte as-is. We preserve the bits on commit */309 /* Just return the pte as-is. We preserve the bits on commit */
312 trace_xen_mmu_ptep_modify_prot_start(vma->vm_mm, addr, ptep, *ptep);310 trace_xen_mmu_ptep_modify_prot_start(vma->vm_mm, addr, ptep, *ptep);
313 return *ptep;311 return *ptep;
314}312}
315 313
316void xen_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr,314static void xen_ptep_modify_prot_commit(struct vm_area_struct *vma,
317 pte_t *ptep, pte_t pte)315 unsigned long addr,
316 pte_t *ptep, pte_t pte)
318{317{
319 struct mmu_update u;318 struct mmu_update u;
320 319
arch/x86/xen/multicalls.c+103−25
@@ -23,26 +23,21 @@ · 22 unmodified lines
23#include <linux/percpu.h>23#include <linux/percpu.h>
24#include <linux/hardirq.h>24#include <linux/hardirq.h>
25#include <linux/debugfs.h>25#include <linux/debugfs.h>
26#include <linux/jump_label.h>
27#include <linux/printk.h>
26 28
27#include <asm/xen/hypercall.h>29#include <asm/xen/hypercall.h>
28 30
29#include "multicalls.h"31#include "xen-ops.h"
30#include "debugfs.h"
31 32
32#define MC_BATCH 3233#define MC_BATCH 32
33 34
34#define MC_DEBUG 0
35
36#define MC_ARGS (MC_BATCH * 16)35#define MC_ARGS (MC_BATCH * 16)
37 36
38 37
39struct mc_buffer {38struct mc_buffer {
40 unsigned mcidx, argidx, cbidx;39 unsigned mcidx, argidx, cbidx;
41 struct multicall_entry entries[MC_BATCH];40 struct multicall_entry entries[MC_BATCH];
42#if MC_DEBUG
43 struct multicall_entry debug[MC_BATCH];
44 void *caller[MC_BATCH];
45#endif
46 unsigned char args[MC_ARGS];41 unsigned char args[MC_ARGS];
47 struct callback {42 struct callback {
48 void (*fn)(void *);43 void (*fn)(void *);
@@ -50,13 +45,98 @@ struct mc_buffer { · 1 unmodified line
50 } callbacks[MC_BATCH];45 } callbacks[MC_BATCH];
51};46};
52 47
48struct mc_debug_data {
49 struct multicall_entry entries[MC_BATCH];
50 void *caller[MC_BATCH];
51 size_t argsz[MC_BATCH];
52 unsigned long *args[MC_BATCH];
53};
54
53static DEFINE_PER_CPU(struct mc_buffer, mc_buffer);55static DEFINE_PER_CPU(struct mc_buffer, mc_buffer);
56static struct mc_debug_data mc_debug_data_early __initdata;
57static struct mc_debug_data __percpu *mc_debug_data __refdata =
58 &mc_debug_data_early;
54DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags);59DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags);
55 60
61static struct static_key mc_debug __ro_after_init;
62static bool mc_debug_enabled __initdata;
63
64static int __init xen_parse_mc_debug(char *arg)
65{
66 mc_debug_enabled = true;
67 static_key_slow_inc(&mc_debug);
68
69 return 0;
70}
71early_param("xen_mc_debug", xen_parse_mc_debug);
72
73static int __init mc_debug_enable(void)
74{
75 struct mc_debug_data __percpu *mcdb;
76 unsigned long flags;
77
78 if (!mc_debug_enabled)
79 return 0;
80
81 mcdb = alloc_percpu(struct mc_debug_data);
82 if (!mcdb) {
83 pr_err("xen_mc_debug inactive\n");
84 static_key_slow_dec(&mc_debug);
85 return -ENOMEM;
86 }
87
88 /* Be careful when switching to percpu debug data. */
89 local_irq_save(flags);
90 xen_mc_flush();
91 mc_debug_data = mcdb;
92 local_irq_restore(flags);
93
94 pr_info("xen_mc_debug active\n");
95
96 return 0;
97}
98early_initcall(mc_debug_enable);
99
100/* Number of parameters of hypercalls used via multicalls. */
101static const uint8_t hpcpars[] = {
102 [__HYPERVISOR_mmu_update] = 4,
103 [__HYPERVISOR_stack_switch] = 2,
104 [__HYPERVISOR_fpu_taskswitch] = 1,
105 [__HYPERVISOR_update_descriptor] = 2,
106 [__HYPERVISOR_update_va_mapping] = 3,
107 [__HYPERVISOR_mmuext_op] = 4,
108};
109
110static void print_debug_data(struct mc_buffer *b, struct mc_debug_data *mcdb,
111 int idx)
112{
113 unsigned int arg;
114 unsigned int opidx = mcdb->entries[idx].op & 0xff;
115 unsigned int pars = 0;
116
117 pr_err(" call %2d: op=%lu result=%ld caller=%pS ", idx + 1,
118 mcdb->entries[idx].op, b->entries[idx].result,
119 mcdb->caller[idx]);
120 if (opidx < ARRAY_SIZE(hpcpars))
121 pars = hpcpars[opidx];
122 if (pars) {
123 pr_cont("pars=");
124 for (arg = 0; arg < pars; arg++)
125 pr_cont("%lx ", mcdb->entries[idx].args[arg]);
126 }
127 if (mcdb->argsz[idx]) {
128 pr_cont("args=");
129 for (arg = 0; arg < mcdb->argsz[idx] / 8; arg++)
130 pr_cont("%lx ", mcdb->args[idx][arg]);
131 }
132 pr_cont("\n");
133}
134
56void xen_mc_flush(void)135void xen_mc_flush(void)
57{136{
58 struct mc_buffer *b = this_cpu_ptr(&mc_buffer);137 struct mc_buffer *b = this_cpu_ptr(&mc_buffer);
59 struct multicall_entry *mc;138 struct multicall_entry *mc;
139 struct mc_debug_data *mcdb = NULL;
60 int ret = 0;140 int ret = 0;
61 unsigned long flags;141 unsigned long flags;
62 int i;142 int i;
@@ -69,10 +149,11 @@ void xen_mc_flush(void) · 6 unmodified lines
69 149
70 trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx);150 trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx);
71 151
72#if MC_DEBUG152 if (static_key_false(&mc_debug)) {
73 memcpy(b->debug, b->entries,153 mcdb = this_cpu_ptr(mc_debug_data);
74 b->mcidx * sizeof(struct multicall_entry));154 memcpy(mcdb->entries, b->entries,
75#endif155 b->mcidx * sizeof(struct multicall_entry));
156 }
76 157
77 switch (b->mcidx) {158 switch (b->mcidx) {
78 case 0:159 case 0:
@@ -103,21 +184,14 @@ void xen_mc_flush(void) · 24 unmodified lines
103 pr_err("%d of %d multicall(s) failed: cpu %d\n",184 pr_err("%d of %d multicall(s) failed: cpu %d\n",
104 ret, b->mcidx, smp_processor_id());185 ret, b->mcidx, smp_processor_id());
105 for (i = 0; i < b->mcidx; i++) {186 for (i = 0; i < b->mcidx; i++) {
106 if (b->entries[i].result < 0) {187 if (static_key_false(&mc_debug)) {
107#if MC_DEBUG188 print_debug_data(b, mcdb, i);
108 pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\t%pS\n",189 } else if (b->entries[i].result < 0) {
109 i + 1,
110 b->debug[i].op,
111 b->debug[i].args[0],
112 b->entries[i].result,
113 b->caller[i]);
114#else
115 pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\n",190 pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\n",
116 i + 1,191 i + 1,
117 b->entries[i].op,192 b->entries[i].op,
118 b->entries[i].args[0],193 b->entries[i].args[0],
119 b->entries[i].result);194 b->entries[i].result);
120#endif
121 }195 }
122 }196 }
123 }197 }
@@ -155,9 +229,13 @@ struct multicall_space __xen_mc_entry(size_t args) · 31 unmodified lines
155 }229 }
156 230
157 ret.mc = &b->entries[b->mcidx];231 ret.mc = &b->entries[b->mcidx];
158#if MC_DEBUG232 if (static_key_false(&mc_debug)) {
159 b->caller[b->mcidx] = __builtin_return_address(0);233 struct mc_debug_data *mcdb = this_cpu_ptr(mc_debug_data);
160#endif234
235 mcdb->caller[b->mcidx] = __builtin_return_address(0);
236 mcdb->argsz[b->mcidx] = args;
237 mcdb->args[b->mcidx] = (unsigned long *)(&b->args[argidx]);
238 }
161 b->mcidx++;239 b->mcidx++;
162 ret.args = &b->args[argidx];240 ret.args = &b->args[argidx];
163 b->argidx = argidx + args;241 b->argidx = argidx + args;
arch/x86/xen/multicalls.h+0−69
@@ -1,69 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _XEN_MULTICALLS_H
3#define _XEN_MULTICALLS_H
4
5#include <trace/events/xen.h>
6
7#include "xen-ops.h"
8
9/* Multicalls */
10struct multicall_space
11{
12 struct multicall_entry *mc;
13 void *args;
14};
15
16/* Allocate room for a multicall and its args */
17struct multicall_space __xen_mc_entry(size_t args);
18
19DECLARE_PER_CPU(unsigned long, xen_mc_irq_flags);
20
21/* Call to start a batch of multiple __xen_mc_entry()s. Must be
22 paired with xen_mc_issue() */
23static inline void xen_mc_batch(void)
24{
25 unsigned long flags;
26
27 /* need to disable interrupts until this entry is complete */
28 local_irq_save(flags);
29 trace_xen_mc_batch(xen_get_lazy_mode());
30 __this_cpu_write(xen_mc_irq_flags, flags);
31}
32
33static inline struct multicall_space xen_mc_entry(size_t args)
34{
35 xen_mc_batch();
36 return __xen_mc_entry(args);
37}
38
39/* Flush all pending multicalls */
40void xen_mc_flush(void);
41
42/* Issue a multicall if we're not in a lazy mode */
43static inline void xen_mc_issue(unsigned mode)
44{
45 trace_xen_mc_issue(mode);
46
47 if ((xen_get_lazy_mode() & mode) == 0)
48 xen_mc_flush();
49
50 /* restore flags saved in xen_mc_batch */
51 local_irq_restore(this_cpu_read(xen_mc_irq_flags));
52}
53
54/* Set up a callback to be called when the current batch is flushed */
55void xen_mc_callback(void (*fn)(void *), void *data);
56
57/*
58 * Try to extend the arguments of the previous multicall command. The
59 * previous command's op must match. If it does, then it attempts to
60 * extend the argument space allocated to the multicall entry by
61 * arg_size bytes.
62 *
63 * The returned multicall_space will return with mc pointing to the
64 * command on success, or NULL on failure, and args pointing to the
65 * newly allocated space.
66 */
67struct multicall_space xen_mc_extend_args(unsigned long op, size_t arg_size);
68
69#endif /* _XEN_MULTICALLS_H */
arch/x86/xen/p2m.c+2−4
@@ -81,7 +81,6 @@ · 80 unmodified lines
81#include <xen/balloon.h>81#include <xen/balloon.h>
82#include <xen/grant_table.h>82#include <xen/grant_table.h>
83 83
84#include "multicalls.h"
85#include "xen-ops.h"84#include "xen-ops.h"
86 85
87#define P2M_MID_PER_PAGE (PAGE_SIZE / sizeof(unsigned long *))86#define P2M_MID_PER_PAGE (PAGE_SIZE / sizeof(unsigned long *))
@@ -730,7 +729,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, · 642 unmodified lines
730 * immediate unmapping.729 * immediate unmapping.
731 */730 */
732 map_ops[i].status = GNTST_general_error;731 map_ops[i].status = GNTST_general_error;
733 unmap[0].host_addr = map_ops[i].host_addr,732 unmap[0].host_addr = map_ops[i].host_addr;
734 unmap[0].handle = map_ops[i].handle;733 unmap[0].handle = map_ops[i].handle;
735 map_ops[i].handle = INVALID_GRANT_HANDLE;734 map_ops[i].handle = INVALID_GRANT_HANDLE;
736 if (map_ops[i].flags & GNTMAP_device_map)735 if (map_ops[i].flags & GNTMAP_device_map)
@@ -740,7 +739,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, · 3 unmodified lines
740 739
741 if (kmap_ops) {740 if (kmap_ops) {
742 kmap_ops[i].status = GNTST_general_error;741 kmap_ops[i].status = GNTST_general_error;
743 unmap[1].host_addr = kmap_ops[i].host_addr,742 unmap[1].host_addr = kmap_ops[i].host_addr;
744 unmap[1].handle = kmap_ops[i].handle;743 unmap[1].handle = kmap_ops[i].handle;
745 kmap_ops[i].handle = INVALID_GRANT_HANDLE;744 kmap_ops[i].handle = INVALID_GRANT_HANDLE;
746 if (kmap_ops[i].flags & GNTMAP_device_map)745 if (kmap_ops[i].flags & GNTMAP_device_map)
@@ -795,7 +794,6 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, · 48 unmodified lines
795 794
796#ifdef CONFIG_XEN_DEBUG_FS795#ifdef CONFIG_XEN_DEBUG_FS
797#include <linux/debugfs.h>796#include <linux/debugfs.h>
798#include "debugfs.h"
799static int p2m_dump_show(struct seq_file *m, void *v)797static int p2m_dump_show(struct seq_file *m, void *v)
800{798{
801 static const char * const type_name[] = {799 static const char * const type_name[] = {
arch/x86/xen/pmu.c+0−1
@@ -10,7 +10,6 @@ · 9 unmodified lines
10#include <xen/interface/xenpmu.h>10#include <xen/interface/xenpmu.h>
11 11
12#include "xen-ops.h"12#include "xen-ops.h"
13#include "pmu.h"
14 13
15/* x86_pmu.handle_irq definition */14/* x86_pmu.handle_irq definition */
16#include "../events/perf_event.h"15#include "../events/perf_event.h"
arch/x86/xen/pmu.h+0−22
@@ -1,22 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __XEN_PMU_H
3#define __XEN_PMU_H
4
5#include <xen/interface/xenpmu.h>
6
7extern bool is_xen_pmu;
8
9irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id);
10#ifdef CONFIG_XEN_HAVE_VPMU
11void xen_pmu_init(int cpu);
12void xen_pmu_finish(int cpu);
13#else
14static inline void xen_pmu_init(int cpu) {}
15static inline void xen_pmu_finish(int cpu) {}
16#endif
17bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err);
18bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t high, int *err);
19int pmu_apic_update(uint32_t reg);
20unsigned long long xen_read_pmc(int counter);
21
22#endif /* __XEN_PMU_H */
arch/x86/xen/setup.c+0−1
@@ -34,7 +34,6 @@ · 33 unmodified lines
34#include <xen/features.h>34#include <xen/features.h>
35#include <xen/hvc-console.h>35#include <xen/hvc-console.h>
36#include "xen-ops.h"36#include "xen-ops.h"
37#include "mmu.h"
38 37
39#define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024)38#define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024)
40 39
arch/x86/xen/smp.c+0−1
@@ -9,7 +9,6 @@ · 8 unmodified lines
9 9
10#include <xen/hvc-console.h>10#include <xen/hvc-console.h>
11#include "xen-ops.h"11#include "xen-ops.h"
12#include "smp.h"
13 12
14static DEFINE_PER_CPU(struct xen_common_irq, xen_resched_irq) = { .irq = -1 };13static DEFINE_PER_CPU(struct xen_common_irq, xen_resched_irq) = { .irq = -1 };
15static DEFINE_PER_CPU(struct xen_common_irq, xen_callfunc_irq) = { .irq = -1 };14static DEFINE_PER_CPU(struct xen_common_irq, xen_callfunc_irq) = { .irq = -1 };
arch/x86/xen/smp.h+0−51
@@ -1,51 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _XEN_SMP_H
3
4#ifdef CONFIG_SMP
5
6void asm_cpu_bringup_and_idle(void);
7asmlinkage void cpu_bringup_and_idle(void);
8
9extern void xen_send_IPI_mask(const struct cpumask *mask,
10 int vector);
11extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
12 int vector);
13extern void xen_send_IPI_allbutself(int vector);
14extern void xen_send_IPI_all(int vector);
15extern void xen_send_IPI_self(int vector);
16
17extern int xen_smp_intr_init(unsigned int cpu);
18extern void xen_smp_intr_free(unsigned int cpu);
19int xen_smp_intr_init_pv(unsigned int cpu);
20void xen_smp_intr_free_pv(unsigned int cpu);
21
22void xen_smp_count_cpus(void);
23void xen_smp_cpus_done(unsigned int max_cpus);
24
25void xen_smp_send_reschedule(int cpu);
26void xen_smp_send_call_function_ipi(const struct cpumask *mask);
27void xen_smp_send_call_function_single_ipi(int cpu);
28
29void __noreturn xen_cpu_bringup_again(unsigned long stack);
30
31struct xen_common_irq {
32 int irq;
33 char *name;
34};
35#else /* CONFIG_SMP */
36
37static inline int xen_smp_intr_init(unsigned int cpu)
38{
39 return 0;
40}
41static inline void xen_smp_intr_free(unsigned int cpu) {}
42
43static inline int xen_smp_intr_init_pv(unsigned int cpu)
44{
45 return 0;
46}
47static inline void xen_smp_intr_free_pv(unsigned int cpu) {}
48static inline void xen_smp_count_cpus(void) { }
49#endif /* CONFIG_SMP */
50
51#endif
arch/x86/xen/smp_hvm.c+0−2
@@ -5,8 +5,6 @@ · 4 unmodified lines
5#include <xen/events.h>5#include <xen/events.h>
6 6
7#include "xen-ops.h"7#include "xen-ops.h"
8#include "smp.h"
9
10 8
11static void __init xen_hvm_smp_prepare_boot_cpu(void)9static void __init xen_hvm_smp_prepare_boot_cpu(void)
12{10{
arch/x86/xen/smp_pv.c+0−3
@@ -46,9 +46,6 @@ · 45 unmodified lines
46 46
47#include <xen/hvc-console.h>47#include <xen/hvc-console.h>
48#include "xen-ops.h"48#include "xen-ops.h"
49#include "mmu.h"
50#include "smp.h"
51#include "pmu.h"
52 49
53cpumask_var_t xen_cpu_initialized_map;50cpumask_var_t xen_cpu_initialized_map;
54 51
arch/x86/xen/spinlock.c+5−15
@@ -18,7 +18,6 @@ · 17 unmodified lines
18static DEFINE_PER_CPU(int, lock_kicker_irq) = -1;18static DEFINE_PER_CPU(int, lock_kicker_irq) = -1;
19static DEFINE_PER_CPU(char *, irq_name);19static DEFINE_PER_CPU(char *, irq_name);
20static DEFINE_PER_CPU(atomic_t, xen_qlock_wait_nest);20static DEFINE_PER_CPU(atomic_t, xen_qlock_wait_nest);
21static bool xen_pvspin = true;
22 21
23static void xen_qlock_kick(int cpu)22static void xen_qlock_kick(int cpu)
24{23{
@@ -68,7 +67,7 @@ void xen_init_lock_cpu(int cpu) · 43 unmodified lines
68 int irq;67 int irq;
69 char *name;68 char *name;
70 69
71 if (!xen_pvspin)70 if (nopvspin)
72 return;71 return;
73 72
74 WARN(per_cpu(lock_kicker_irq, cpu) >= 0, "spinlock on CPU%d exists on IRQ%d!\n",73 WARN(per_cpu(lock_kicker_irq, cpu) >= 0, "spinlock on CPU%d exists on IRQ%d!\n",
@@ -95,7 +94,7 @@ void xen_uninit_lock_cpu(int cpu) · 20 unmodified lines
95{94{
96 int irq;95 int irq;
97 96
98 if (!xen_pvspin)97 if (nopvspin)
99 return;98 return;
100 99
101 kfree(per_cpu(irq_name, cpu));100 kfree(per_cpu(irq_name, cpu));
@@ -125,10 +124,10 @@ PV_CALLEE_SAVE_REGS_THUNK(xen_vcpu_stolen); · 23 unmodified lines
125void __init xen_init_spinlocks(void)124void __init xen_init_spinlocks(void)
126{125{
127 /* Don't need to use pvqspinlock code if there is only 1 vCPU. */126 /* Don't need to use pvqspinlock code if there is only 1 vCPU. */
128 if (num_possible_cpus() == 1 || nopvspin)127 if (num_possible_cpus() == 1)
129 xen_pvspin = false;128 nopvspin = true;
130 129
131 if (!xen_pvspin) {130 if (nopvspin) {
132 printk(KERN_DEBUG "xen: PV spinlocks disabled\n");131 printk(KERN_DEBUG "xen: PV spinlocks disabled\n");
133 static_branch_disable(&virt_spin_lock_key);132 static_branch_disable(&virt_spin_lock_key);
134 return;133 return;
@@ -143,12 +142,3 @@ void __init xen_init_spinlocks(void) · 8 unmodified lines
143 pv_ops.lock.kick = xen_qlock_kick;142 pv_ops.lock.kick = xen_qlock_kick;
144 pv_ops.lock.vcpu_is_preempted = PV_CALLEE_SAVE(xen_vcpu_stolen);143 pv_ops.lock.vcpu_is_preempted = PV_CALLEE_SAVE(xen_vcpu_stolen);
145}144}
146
147static __init int xen_parse_nopvspin(char *arg)
148{
149 pr_notice("\"xen_nopvspin\" is deprecated, please use \"nopvspin\" instead\n");
150 xen_pvspin = false;
151 return 0;
152}
153early_param("xen_nopvspin", xen_parse_nopvspin);
154
arch/x86/xen/suspend.c+0−2
@@ -15,8 +15,6 @@ · 14 unmodified lines
15#include <asm/fixmap.h>15#include <asm/fixmap.h>
16 16
17#include "xen-ops.h"17#include "xen-ops.h"
18#include "mmu.h"
19#include "pmu.h"
20 18
21static DEFINE_PER_CPU(u64, spec_ctrl);19static DEFINE_PER_CPU(u64, spec_ctrl);
22 20
arch/x86/xen/time.c+1−1
@@ -30,7 +30,7 @@ · 29 unmodified lines
30#include "xen-ops.h"30#include "xen-ops.h"
31 31
32/* Minimum amount of time until next clock event fires */32/* Minimum amount of time until next clock event fires */
33#define TIMER_SLOP 10000033#define TIMER_SLOP 1
34 34
35static u64 xen_sched_clock_offset __read_mostly;35static u64 xen_sched_clock_offset __read_mostly;
36 36
arch/x86/xen/xen-ops.h+145−3
@@ -5,8 +5,15 @@ · 4 unmodified lines
5#include <linux/init.h>5#include <linux/init.h>
6#include <linux/clocksource.h>6#include <linux/clocksource.h>
7#include <linux/irqreturn.h>7#include <linux/irqreturn.h>
8#include <linux/linkage.h>
9
10#include <xen/interface/xenpmu.h>
8#include <xen/xen-ops.h>11#include <xen/xen-ops.h>
9 12
13#include <asm/page.h>
14
15#include <trace/events/xen.h>
16
10/* These are code, but not functions. Defined in entry.S */17/* These are code, but not functions. Defined in entry.S */
11extern const char xen_failsafe_callback[];18extern const char xen_failsafe_callback[];
12 19
@@ -23,14 +30,11 @@ void xen_copy_trap_info(struct trap_info *traps); · 10 unmodified lines
23 30
24DECLARE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info);31DECLARE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info);
25DECLARE_PER_CPU(unsigned long, xen_cr3);32DECLARE_PER_CPU(unsigned long, xen_cr3);
26DECLARE_PER_CPU(unsigned long, xen_current_cr3);
27 33
28extern struct start_info *xen_start_info;34extern struct start_info *xen_start_info;
29extern struct shared_info xen_dummy_shared_info;35extern struct shared_info xen_dummy_shared_info;
30extern struct shared_info *HYPERVISOR_shared_info;36extern struct shared_info *HYPERVISOR_shared_info;
31 37
32extern bool xen_fifo_events;
33
34void xen_setup_mfn_list_list(void);38void xen_setup_mfn_list_list(void);
35void xen_build_mfn_list_list(void);39void xen_build_mfn_list_list(void);
36void xen_setup_machphys_mapping(void);40void xen_setup_machphys_mapping(void);
@@ -177,4 +181,142 @@ static inline void xen_hvm_post_suspend(int suspend_cancelled) {} · 140 unmodified lines
177 181
178void xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns);182void xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns);
179 183
184struct dentry * __init xen_init_debugfs(void);
185
186enum pt_level {
187 PT_PGD,
188 PT_P4D,
189 PT_PUD,
190 PT_PMD,
191 PT_PTE
192};
193
194bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
195void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
196unsigned long xen_read_cr2_direct(void);
197void xen_init_mmu_ops(void);
198void xen_hvm_init_mmu_ops(void);
199
200/* Multicalls */
201struct multicall_space
202{
203 struct multicall_entry *mc;
204 void *args;
205};
206
207/* Allocate room for a multicall and its args */
208struct multicall_space __xen_mc_entry(size_t args);
209
210DECLARE_PER_CPU(unsigned long, xen_mc_irq_flags);
211
212/* Call to start a batch of multiple __xen_mc_entry()s. Must be
213 paired with xen_mc_issue() */
214static inline void xen_mc_batch(void)
215{
216 unsigned long flags;
217
218 /* need to disable interrupts until this entry is complete */
219 local_irq_save(flags);
220 trace_xen_mc_batch(xen_get_lazy_mode());
221 __this_cpu_write(xen_mc_irq_flags, flags);
222}
223
224static inline struct multicall_space xen_mc_entry(size_t args)
225{
226 xen_mc_batch();
227 return __xen_mc_entry(args);
228}
229
230/* Flush all pending multicalls */
231void xen_mc_flush(void);
232
233/* Issue a multicall if we're not in a lazy mode */
234static inline void xen_mc_issue(unsigned mode)
235{
236 trace_xen_mc_issue(mode);
237
238 if ((xen_get_lazy_mode() & mode) == 0)
239 xen_mc_flush();
240
241 /* restore flags saved in xen_mc_batch */
242 local_irq_restore(this_cpu_read(xen_mc_irq_flags));
243}
244
245/* Set up a callback to be called when the current batch is flushed */
246void xen_mc_callback(void (*fn)(void *), void *data);
247
248/*
249 * Try to extend the arguments of the previous multicall command. The
250 * previous command's op must match. If it does, then it attempts to
251 * extend the argument space allocated to the multicall entry by
252 * arg_size bytes.
253 *
254 * The returned multicall_space will return with mc pointing to the
255 * command on success, or NULL on failure, and args pointing to the
256 * newly allocated space.
257 */
258struct multicall_space xen_mc_extend_args(unsigned long op, size_t arg_size);
259
260extern bool is_xen_pmu;
261
262irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id);
263#ifdef CONFIG_XEN_HAVE_VPMU
264void xen_pmu_init(int cpu);
265void xen_pmu_finish(int cpu);
266#else
267static inline void xen_pmu_init(int cpu) {}
268static inline void xen_pmu_finish(int cpu) {}
269#endif
270bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err);
271bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t high, int *err);
272int pmu_apic_update(uint32_t reg);
273unsigned long long xen_read_pmc(int counter);
274
275#ifdef CONFIG_SMP
276
277void asm_cpu_bringup_and_idle(void);
278asmlinkage void cpu_bringup_and_idle(void);
279
280extern void xen_send_IPI_mask(const struct cpumask *mask,
281 int vector);
282extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
283 int vector);
284extern void xen_send_IPI_allbutself(int vector);
285extern void xen_send_IPI_all(int vector);
286extern void xen_send_IPI_self(int vector);
287
288extern int xen_smp_intr_init(unsigned int cpu);
289extern void xen_smp_intr_free(unsigned int cpu);
290int xen_smp_intr_init_pv(unsigned int cpu);
291void xen_smp_intr_free_pv(unsigned int cpu);
292
293void xen_smp_count_cpus(void);
294void xen_smp_cpus_done(unsigned int max_cpus);
295
296void xen_smp_send_reschedule(int cpu);
297void xen_smp_send_call_function_ipi(const struct cpumask *mask);
298void xen_smp_send_call_function_single_ipi(int cpu);
299
300void __noreturn xen_cpu_bringup_again(unsigned long stack);
301
302struct xen_common_irq {
303 int irq;
304 char *name;
305};
306#else /* CONFIG_SMP */
307
308static inline int xen_smp_intr_init(unsigned int cpu)
309{
310 return 0;
311}
312static inline void xen_smp_intr_free(unsigned int cpu) {}
313
314static inline int xen_smp_intr_init_pv(unsigned int cpu)
315{
316 return 0;
317}
318static inline void xen_smp_intr_free_pv(unsigned int cpu) {}
319static inline void xen_smp_count_cpus(void) { }
320#endif /* CONFIG_SMP */
321
180#endif /* XEN_OPS_H */322#endif /* XEN_OPS_H */
drivers/xen/evtchn.c+1−0
@@ -729,4 +729,5 @@ static void __exit evtchn_cleanup(void) · 728 unmodified lines
729module_init(evtchn_init);729module_init(evtchn_init);
730module_exit(evtchn_cleanup);730module_exit(evtchn_cleanup);
731 731
732MODULE_DESCRIPTION("Xen /dev/xen/evtchn device driver");
732MODULE_LICENSE("GPL");733MODULE_LICENSE("GPL");
drivers/xen/manage.c+1−1
@@ -208,7 +208,7 @@ static void do_reboot(void) · 207 unmodified lines
208 orderly_reboot();208 orderly_reboot();
209}209}
210 210
211static struct shutdown_handler shutdown_handlers[] = {211static const struct shutdown_handler shutdown_handlers[] = {
212 { "poweroff", true, do_poweroff },212 { "poweroff", true, do_poweroff },
213 { "halt", false, do_poweroff },213 { "halt", false, do_poweroff },
214 { "reboot", true, do_reboot },214 { "reboot", true, do_reboot },
drivers/xen/privcmd-buf.c+1−0
@@ -19,6 +19,7 @@ · 18 unmodified lines
19 19
20#include "privcmd.h"20#include "privcmd.h"
21 21
22MODULE_DESCRIPTION("Xen Mmap of hypercall buffers");
22MODULE_LICENSE("GPL");23MODULE_LICENSE("GPL");
23 24
24struct privcmd_buf_private {25struct privcmd_buf_private {
drivers/xen/privcmd.c+25−11
@@ -17,6 +17,7 @@ · 16 unmodified lines
17#include <linux/poll.h>17#include <linux/poll.h>
18#include <linux/sched.h>18#include <linux/sched.h>
19#include <linux/slab.h>19#include <linux/slab.h>
20#include <linux/srcu.h>
20#include <linux/string.h>21#include <linux/string.h>
21#include <linux/workqueue.h>22#include <linux/workqueue.h>
22#include <linux/errno.h>23#include <linux/errno.h>
@@ -48,6 +49,7 @@ · 25 unmodified lines
48 49
49#include "privcmd.h"50#include "privcmd.h"
50 51
52MODULE_DESCRIPTION("Xen hypercall passthrough driver");
51MODULE_LICENSE("GPL");53MODULE_LICENSE("GPL");
52 54
53#define PRIV_VMA_LOCKED ((void *)1)55#define PRIV_VMA_LOCKED ((void *)1)
@@ -845,7 +847,8 @@ out: · 791 unmodified lines
845#ifdef CONFIG_XEN_PRIVCMD_EVENTFD847#ifdef CONFIG_XEN_PRIVCMD_EVENTFD
846/* Irqfd support */848/* Irqfd support */
847static struct workqueue_struct *irqfd_cleanup_wq;849static struct workqueue_struct *irqfd_cleanup_wq;
848static DEFINE_MUTEX(irqfds_lock);850static DEFINE_SPINLOCK(irqfds_lock);
851DEFINE_STATIC_SRCU(irqfds_srcu);
849static LIST_HEAD(irqfds_list);852static LIST_HEAD(irqfds_list);
850 853
851struct privcmd_kernel_irqfd {854struct privcmd_kernel_irqfd {
@@ -873,6 +876,9 @@ static void irqfd_shutdown(struct work_struct *work) · 21 unmodified lines
873 container_of(work, struct privcmd_kernel_irqfd, shutdown);876 container_of(work, struct privcmd_kernel_irqfd, shutdown);
874 u64 cnt;877 u64 cnt;
875 878
879 /* Make sure irqfd has been initialized in assign path */
880 synchronize_srcu(&irqfds_srcu);
881
876 eventfd_ctx_remove_wait_queue(kirqfd->eventfd, &kirqfd->wait, &cnt);882 eventfd_ctx_remove_wait_queue(kirqfd->eventfd, &kirqfd->wait, &cnt);
877 eventfd_ctx_put(kirqfd->eventfd);883 eventfd_ctx_put(kirqfd->eventfd);
878 kfree(kirqfd);884 kfree(kirqfd);
@@ -909,9 +915,11 @@ irqfd_wakeup(wait_queue_entry_t *wait, unsigned int mode, int sync, void *key) · 30 unmodified lines
909 irqfd_inject(kirqfd);915 irqfd_inject(kirqfd);
910 916
911 if (flags & EPOLLHUP) {917 if (flags & EPOLLHUP) {
912 mutex_lock(&irqfds_lock);918 unsigned long flags;
919
920 spin_lock_irqsave(&irqfds_lock, flags);
913 irqfd_deactivate(kirqfd);921 irqfd_deactivate(kirqfd);
914 mutex_unlock(&irqfds_lock);922 spin_unlock_irqrestore(&irqfds_lock, flags);
915 }923 }
916 924
917 return 0;925 return 0;
@@ -929,10 +937,11 @@ irqfd_poll_func(struct file *file, wait_queue_head_t *wqh, poll_table *pt) · 11 unmodified lines
929static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)937static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
930{938{
931 struct privcmd_kernel_irqfd *kirqfd, *tmp;939 struct privcmd_kernel_irqfd *kirqfd, *tmp;
940 unsigned long flags;
932 __poll_t events;941 __poll_t events;
933 struct fd f;942 struct fd f;
934 void *dm_op;943 void *dm_op;
935 int ret;944 int ret, idx;
936 945
937 kirqfd = kzalloc(sizeof(*kirqfd) + irqfd->size, GFP_KERNEL);946 kirqfd = kzalloc(sizeof(*kirqfd) + irqfd->size, GFP_KERNEL);
938 if (!kirqfd)947 if (!kirqfd)
@@ -968,18 +977,19 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) · 29 unmodified lines
968 init_waitqueue_func_entry(&kirqfd->wait, irqfd_wakeup);977 init_waitqueue_func_entry(&kirqfd->wait, irqfd_wakeup);
969 init_poll_funcptr(&kirqfd->pt, irqfd_poll_func);978 init_poll_funcptr(&kirqfd->pt, irqfd_poll_func);
970 979
971 mutex_lock(&irqfds_lock);980 spin_lock_irqsave(&irqfds_lock, flags);
972 981
973 list_for_each_entry(tmp, &irqfds_list, list) {982 list_for_each_entry(tmp, &irqfds_list, list) {
974 if (kirqfd->eventfd == tmp->eventfd) {983 if (kirqfd->eventfd == tmp->eventfd) {
975 ret = -EBUSY;984 ret = -EBUSY;
976 mutex_unlock(&irqfds_lock);985 spin_unlock_irqrestore(&irqfds_lock, flags);
977 goto error_eventfd;986 goto error_eventfd;
978 }987 }
979 }988 }
980 989
990 idx = srcu_read_lock(&irqfds_srcu);
981 list_add_tail(&kirqfd->list, &irqfds_list);991 list_add_tail(&kirqfd->list, &irqfds_list);
982 mutex_unlock(&irqfds_lock);992 spin_unlock_irqrestore(&irqfds_lock, flags);
983 993
984 /*994 /*
985 * Check if there was an event already pending on the eventfd before we995 * Check if there was an event already pending on the eventfd before we
@@ -989,6 +999,8 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) · 3 unmodified lines
989 if (events & EPOLLIN)999 if (events & EPOLLIN)
990 irqfd_inject(kirqfd);1000 irqfd_inject(kirqfd);
991 1001
1002 srcu_read_unlock(&irqfds_srcu, idx);
1003
992 /*1004 /*
993 * Do not drop the file until the kirqfd is fully initialized, otherwise1005 * Do not drop the file until the kirqfd is fully initialized, otherwise
994 * we might race against the EPOLLHUP.1006 * we might race against the EPOLLHUP.
@@ -1011,12 +1023,13 @@ static int privcmd_irqfd_deassign(struct privcmd_irqfd *irqfd) · 16 unmodified lines
1011{1023{
1012 struct privcmd_kernel_irqfd *kirqfd;1024 struct privcmd_kernel_irqfd *kirqfd;
1013 struct eventfd_ctx *eventfd;1025 struct eventfd_ctx *eventfd;
1026 unsigned long flags;
1014 1027
1015 eventfd = eventfd_ctx_fdget(irqfd->fd);1028 eventfd = eventfd_ctx_fdget(irqfd->fd);
1016 if (IS_ERR(eventfd))1029 if (IS_ERR(eventfd))
1017 return PTR_ERR(eventfd);1030 return PTR_ERR(eventfd);
1018 1031
1019 mutex_lock(&irqfds_lock);1032 spin_lock_irqsave(&irqfds_lock, flags);
1020 1033
1021 list_for_each_entry(kirqfd, &irqfds_list, list) {1034 list_for_each_entry(kirqfd, &irqfds_list, list) {
1022 if (kirqfd->eventfd == eventfd) {1035 if (kirqfd->eventfd == eventfd) {
@@ -1025,7 +1038,7 @@ static int privcmd_irqfd_deassign(struct privcmd_irqfd *irqfd) · 2 unmodified lines
1025 }1038 }
1026 }1039 }
1027 1040
1028 mutex_unlock(&irqfds_lock);1041 spin_unlock_irqrestore(&irqfds_lock, flags);
1029 1042
1030 eventfd_ctx_put(eventfd);1043 eventfd_ctx_put(eventfd);
1031 1044
@@ -1073,13 +1086,14 @@ static int privcmd_irqfd_init(void) · 41 unmodified lines
1073static void privcmd_irqfd_exit(void)1086static void privcmd_irqfd_exit(void)
1074{1087{
1075 struct privcmd_kernel_irqfd *kirqfd, *tmp;1088 struct privcmd_kernel_irqfd *kirqfd, *tmp;
1089 unsigned long flags;
1076 1090
1077 mutex_lock(&irqfds_lock);1091 spin_lock_irqsave(&irqfds_lock, flags);
1078 1092
1079 list_for_each_entry_safe(kirqfd, tmp, &irqfds_list, list)1093 list_for_each_entry_safe(kirqfd, tmp, &irqfds_list, list)
1080 irqfd_deactivate(kirqfd);1094 irqfd_deactivate(kirqfd);
1081 1095
1082 mutex_unlock(&irqfds_lock);1096 spin_unlock_irqrestore(&irqfds_lock, flags);
1083 1097
1084 destroy_workqueue(irqfd_cleanup_wq);1098 destroy_workqueue(irqfd_cleanup_wq);
1085}1099}
drivers/xen/xen-pciback/pci_stub.c+1−0
@@ -1708,5 +1708,6 @@ static void __exit xen_pcibk_cleanup(void) · 1707 unmodified lines
1708module_init(xen_pcibk_init);1708module_init(xen_pcibk_init);
1709module_exit(xen_pcibk_cleanup);1709module_exit(xen_pcibk_cleanup);
1710 1710
1711MODULE_DESCRIPTION("Xen PCI-device stub driver");
1711MODULE_LICENSE("Dual BSD/GPL");1712MODULE_LICENSE("Dual BSD/GPL");
1712MODULE_ALIAS("xen-backend:pci");1713MODULE_ALIAS("xen-backend:pci");
include/xen/events.h+2−0
@@ -144,4 +144,6 @@ static inline void xen_evtchn_close(evtchn_port_t port) · 143 unmodified lines
144 BUG();144 BUG();
145}145}
146 146
147extern bool xen_fifo_events;
148
147#endif /* _XEN_EVENTS_H */149#endif /* _XEN_EVENTS_H */
kernel/locking/qspinlock.c+1−1
@@ -583,7 +583,7 @@ EXPORT_SYMBOL(queued_spin_lock_slowpath); · 582 unmodified lines
583#include "qspinlock_paravirt.h"583#include "qspinlock_paravirt.h"
584#include "qspinlock.c"584#include "qspinlock.c"
585 585
586bool nopvspin __initdata;586bool nopvspin;
587static __init int parse_nopvspin(char *arg)587static __init int parse_nopvspin(char *arg)
588{588{
589 nopvspin = true;589 nopvspin = true;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t