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
Unified · Split
| @@ -7420,17 +7420,18 @@ · 7419 unmodified lines | ||
| 7420 | 7420 | Crash from Xen panic notifier, without executing late |
| 7421 | 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 | 7429 | xen_msr_safe= [X86,XEN,EARLY] |
| 7424 | 7430 | Format: <bool> |
| 7425 | 7431 | Select whether to always use non-faulting (safe) MSR |
| 7426 | 7432 | access functions when running as Xen PV guest. The |
| 7427 | 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 | 7435 | xen_nopv [X86] |
| 7435 | 7436 | Disables the PV optimizations forcing the HVM guest to |
| 7436 | 7437 | run as generic HVM guest with no PV drivers. |
| @@ -109,7 +109,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, · 108 unmodified lines | ||
| 109 | 109 | * immediate unmapping. |
| 110 | 110 | */ |
| 111 | 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 | 113 | unmap.handle = map_ops[i].handle; |
| 114 | 114 | map_ops[i].handle = INVALID_GRANT_HANDLE; |
| 115 | 115 | if (map_ops[i].flags & GNTMAP_device_map) |
| @@ -10,8 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <xen/xen.h> |
| 11 | 11 | #include <xen/interface/physdev.h> |
| 12 | 12 | #include "xen-ops.h" |
| 13 | −#include "pmu.h" | |
| 14 | −#include "smp.h" | |
| 15 | 13 | |
| 16 | 14 | static unsigned int xen_io_apic_read(unsigned apic, unsigned reg) |
| 17 | 15 | { |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <linux/debugfs.h> |
| 4 | 4 | #include <linux/slab.h> |
| 5 | 5 | |
| 6 | −#include "debugfs.h" | |
| 6 | +#include "xen-ops.h" | |
| 7 | 7 | |
| 8 | 8 | static struct dentry *d_xen_debug; |
| 9 | 9 | |
| @@ -1,7 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | −#ifndef _XEN_DEBUGFS_H | |
| 3 | −#define _XEN_DEBUGFS_H | |
| 4 | − | |
| 5 | −struct dentry * __init xen_init_debugfs(void); | |
| 6 | − | |
| 7 | −#endif /* _XEN_DEBUGFS_H */ | |
| @@ -20,8 +20,6 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <asm/setup.h> |
| 21 | 21 | |
| 22 | 22 | #include "xen-ops.h" |
| 23 | −#include "smp.h" | |
| 24 | −#include "pmu.h" | |
| 25 | 23 | |
| 26 | 24 | EXPORT_SYMBOL_GPL(hypercall_page); |
| 27 | 25 | |
| @@ -28,8 +28,6 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <asm/xen/page.h> |
| 29 | 29 | |
| 30 | 30 | #include "xen-ops.h" |
| 31 | −#include "mmu.h" | |
| 32 | −#include "smp.h" | |
| 33 | 31 | |
| 34 | 32 | static unsigned long shared_info_pfn; |
| 35 | 33 | |
| @@ -85,10 +85,6 @@ · 84 unmodified lines | ||
| 85 | 85 | #endif |
| 86 | 86 | |
| 87 | 87 | #include "xen-ops.h" |
| 88 | −#include "mmu.h" | |
| 89 | −#include "smp.h" | |
| 90 | −#include "multicalls.h" | |
| 91 | −#include "pmu.h" | |
| 92 | 88 | |
| 93 | 89 | #include "../kernel/cpu/cpu.h" /* get_cpu_cap() */ |
| 94 | 90 | |
| @@ -5,8 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <asm/xen/hypercall.h> |
| 6 | 6 | #include <xen/interface/memory.h> |
| 7 | 7 | |
| 8 | −#include "multicalls.h" | |
| 9 | −#include "mmu.h" | |
| 8 | +#include "xen-ops.h" | |
| 10 | 9 | |
| 11 | 10 | unsigned long arbitrary_virt_to_mfn(void *vaddr) |
| 12 | 11 | { |
| @@ -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 | − | |
| 7 | −enum pt_level { | |
| 8 | − PT_PGD, | |
| 9 | − PT_P4D, | |
| 10 | − PT_PUD, | |
| 11 | − PT_PMD, | |
| 12 | − PT_PTE | |
| 13 | −}; | |
| 14 | − | |
| 15 | − | |
| 16 | −bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); | |
| 17 | − | |
| 18 | −void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); | |
| 19 | − | |
| 20 | −pte_t xen_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); | |
| 21 | −void xen_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, | |
| 22 | − pte_t *ptep, pte_t pte); | |
| 23 | − | |
| 24 | −unsigned long xen_read_cr2_direct(void); | |
| 25 | − | |
| 26 | −extern void xen_init_mmu_ops(void); | |
| 27 | −extern void xen_hvm_init_mmu_ops(void); | |
| 28 | −#endif /* _XEN_MMU_H */ | |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <xen/interface/xen.h> |
| 6 | 6 | #include <xen/hvm.h> |
| 7 | 7 | |
| 8 | −#include "mmu.h" | |
| 8 | +#include "xen-ops.h" | |
| 9 | 9 | |
| 10 | 10 | #ifdef CONFIG_PROC_VMCORE |
| 11 | 11 | /* |
| @@ -82,9 +82,7 @@ · 81 unmodified lines | ||
| 82 | 82 | #include <xen/hvc-console.h> |
| 83 | 83 | #include <xen/swiotlb-xen.h> |
| 84 | 84 | |
| 85 | −#include "multicalls.h" | |
| 86 | −#include "mmu.h" | |
| 87 | −#include "debugfs.h" | |
| 85 | +#include "xen-ops.h" | |
| 88 | 86 | |
| 89 | 87 | /* |
| 90 | 88 | * 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 | 126 | * looking at another vcpu's cr3 value, it should use this variable. |
| 129 | 127 | */ |
| 130 | 128 | DEFINE_PER_CPU(unsigned long, xen_cr3); /* cr3 stored as physaddr */ |
| 131 | −DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */ | |
| 129 | +static DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */ | |
| 132 | 130 | |
| 133 | 131 | static 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 | 303 | __xen_set_pte(ptep, pteval); |
| 306 | 304 | } |
| 307 | 305 | |
| 308 | −pte_t xen_ptep_modify_prot_start(struct vm_area_struct *vma, | |
| 309 | − unsigned long addr, pte_t *ptep) | |
| 306 | +static pte_t xen_ptep_modify_prot_start(struct vm_area_struct *vma, | |
| 307 | + unsigned long addr, pte_t *ptep) | |
| 310 | 308 | { |
| 311 | 309 | /* Just return the pte as-is. We preserve the bits on commit */ |
| 312 | 310 | trace_xen_mmu_ptep_modify_prot_start(vma->vm_mm, addr, ptep, *ptep); |
| 313 | 311 | return *ptep; |
| 314 | 312 | } |
| 315 | 313 | |
| 316 | −void xen_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, | |
| 317 | − pte_t *ptep, pte_t pte) | |
| 314 | +static void xen_ptep_modify_prot_commit(struct vm_area_struct *vma, | |
| 315 | + unsigned long addr, | |
| 316 | + pte_t *ptep, pte_t pte) | |
| 318 | 317 | { |
| 319 | 318 | struct mmu_update u; |
| 320 | 319 | |
| @@ -23,26 +23,21 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/percpu.h> |
| 24 | 24 | #include <linux/hardirq.h> |
| 25 | 25 | #include <linux/debugfs.h> |
| 26 | +#include <linux/jump_label.h> | |
| 27 | +#include <linux/printk.h> | |
| 26 | 28 | |
| 27 | 29 | #include <asm/xen/hypercall.h> |
| 28 | 30 | |
| 29 | −#include "multicalls.h" | |
| 30 | −#include "debugfs.h" | |
| 31 | +#include "xen-ops.h" | |
| 31 | 32 | |
| 32 | 33 | #define MC_BATCH 32 |
| 33 | 34 | |
| 34 | −#define MC_DEBUG 0 | |
| 35 | − | |
| 36 | 35 | #define MC_ARGS (MC_BATCH * 16) |
| 37 | 36 | |
| 38 | 37 | |
| 39 | 38 | struct mc_buffer { |
| 40 | 39 | unsigned mcidx, argidx, cbidx; |
| 41 | 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 | 41 | unsigned char args[MC_ARGS]; |
| 47 | 42 | struct callback { |
| 48 | 43 | void (*fn)(void *); |
| @@ -50,13 +45,98 @@ struct mc_buffer { · 1 unmodified line | ||
| 50 | 45 | } callbacks[MC_BATCH]; |
| 51 | 46 | }; |
| 52 | 47 | |
| 48 | +struct 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 | + | |
| 53 | 55 | static DEFINE_PER_CPU(struct mc_buffer, mc_buffer); |
| 56 | +static struct mc_debug_data mc_debug_data_early __initdata; | |
| 57 | +static struct mc_debug_data __percpu *mc_debug_data __refdata = | |
| 58 | + &mc_debug_data_early; | |
| 54 | 59 | DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags); |
| 55 | 60 | |
| 61 | +static struct static_key mc_debug __ro_after_init; | |
| 62 | +static bool mc_debug_enabled __initdata; | |
| 63 | + | |
| 64 | +static 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 | +} | |
| 71 | +early_param("xen_mc_debug", xen_parse_mc_debug); | |
| 72 | + | |
| 73 | +static 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 | +} | |
| 98 | +early_initcall(mc_debug_enable); | |
| 99 | + | |
| 100 | +/* Number of parameters of hypercalls used via multicalls. */ | |
| 101 | +static 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 | + | |
| 110 | +static 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 | + | |
| 56 | 135 | void xen_mc_flush(void) |
| 57 | 136 | { |
| 58 | 137 | struct mc_buffer *b = this_cpu_ptr(&mc_buffer); |
| 59 | 138 | struct multicall_entry *mc; |
| 139 | + struct mc_debug_data *mcdb = NULL; | |
| 60 | 140 | int ret = 0; |
| 61 | 141 | unsigned long flags; |
| 62 | 142 | int i; |
| @@ -69,10 +149,11 @@ void xen_mc_flush(void) · 6 unmodified lines | ||
| 69 | 149 | |
| 70 | 150 | trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx); |
| 71 | 151 | |
| 72 | −#if MC_DEBUG | |
| 73 | − memcpy(b->debug, b->entries, | |
| 74 | − b->mcidx * sizeof(struct multicall_entry)); | |
| 75 | −#endif | |
| 152 | + if (static_key_false(&mc_debug)) { | |
| 153 | + mcdb = this_cpu_ptr(mc_debug_data); | |
| 154 | + memcpy(mcdb->entries, b->entries, | |
| 155 | + b->mcidx * sizeof(struct multicall_entry)); | |
| 156 | + } | |
| 76 | 157 | |
| 77 | 158 | switch (b->mcidx) { |
| 78 | 159 | case 0: |
| @@ -103,21 +184,14 @@ void xen_mc_flush(void) · 24 unmodified lines | ||
| 103 | 184 | pr_err("%d of %d multicall(s) failed: cpu %d\n", |
| 104 | 185 | ret, b->mcidx, smp_processor_id()); |
| 105 | 186 | for (i = 0; i < b->mcidx; i++) { |
| 106 | − if (b->entries[i].result < 0) { | |
| 107 | −#if MC_DEBUG | |
| 108 | − pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\t%pS\n", | |
| 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 | |
| 187 | + if (static_key_false(&mc_debug)) { | |
| 188 | + print_debug_data(b, mcdb, i); | |
| 189 | + } else if (b->entries[i].result < 0) { | |
| 115 | 190 | pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\n", |
| 116 | 191 | i + 1, |
| 117 | 192 | b->entries[i].op, |
| 118 | 193 | b->entries[i].args[0], |
| 119 | 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 | 231 | ret.mc = &b->entries[b->mcidx]; |
| 158 | −#if MC_DEBUG | |
| 159 | − b->caller[b->mcidx] = __builtin_return_address(0); | |
| 160 | −#endif | |
| 232 | + if (static_key_false(&mc_debug)) { | |
| 233 | + struct mc_debug_data *mcdb = this_cpu_ptr(mc_debug_data); | |
| 234 | + | |
| 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 | 239 | b->mcidx++; |
| 162 | 240 | ret.args = &b->args[argidx]; |
| 163 | 241 | b->argidx = argidx + args; |
| @@ -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 */ | |
| 10 | −struct multicall_space | |
| 11 | −{ | |
| 12 | − struct multicall_entry *mc; | |
| 13 | − void *args; | |
| 14 | −}; | |
| 15 | − | |
| 16 | −/* Allocate room for a multicall and its args */ | |
| 17 | −struct multicall_space __xen_mc_entry(size_t args); | |
| 18 | − | |
| 19 | −DECLARE_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() */ | |
| 23 | −static 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 | − | |
| 33 | −static 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 */ | |
| 40 | −void xen_mc_flush(void); | |
| 41 | − | |
| 42 | −/* Issue a multicall if we're not in a lazy mode */ | |
| 43 | −static 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 */ | |
| 55 | −void 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 | − */ | |
| 67 | −struct multicall_space xen_mc_extend_args(unsigned long op, size_t arg_size); | |
| 68 | − | |
| 69 | −#endif /* _XEN_MULTICALLS_H */ | |
| @@ -81,7 +81,6 @@ · 80 unmodified lines | ||
| 81 | 81 | #include <xen/balloon.h> |
| 82 | 82 | #include <xen/grant_table.h> |
| 83 | 83 | |
| 84 | −#include "multicalls.h" | |
| 85 | 84 | #include "xen-ops.h" |
| 86 | 85 | |
| 87 | 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 | 729 | * immediate unmapping. |
| 731 | 730 | */ |
| 732 | 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 | 733 | unmap[0].handle = map_ops[i].handle; |
| 735 | 734 | map_ops[i].handle = INVALID_GRANT_HANDLE; |
| 736 | 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 | 740 | if (kmap_ops) { |
| 742 | 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 | 743 | unmap[1].handle = kmap_ops[i].handle; |
| 745 | 744 | kmap_ops[i].handle = INVALID_GRANT_HANDLE; |
| 746 | 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 | 795 | #ifdef CONFIG_XEN_DEBUG_FS |
| 797 | 796 | #include <linux/debugfs.h> |
| 798 | −#include "debugfs.h" | |
| 799 | 797 | static int p2m_dump_show(struct seq_file *m, void *v) |
| 800 | 798 | { |
| 801 | 799 | static const char * const type_name[] = { |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <xen/interface/xenpmu.h> |
| 11 | 11 | |
| 12 | 12 | #include "xen-ops.h" |
| 13 | −#include "pmu.h" | |
| 14 | 13 | |
| 15 | 14 | /* x86_pmu.handle_irq definition */ |
| 16 | 15 | #include "../events/perf_event.h" |
| @@ -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 | − | |
| 7 | −extern bool is_xen_pmu; | |
| 8 | − | |
| 9 | −irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id); | |
| 10 | −#ifdef CONFIG_XEN_HAVE_VPMU | |
| 11 | −void xen_pmu_init(int cpu); | |
| 12 | −void xen_pmu_finish(int cpu); | |
| 13 | −#else | |
| 14 | −static inline void xen_pmu_init(int cpu) {} | |
| 15 | −static inline void xen_pmu_finish(int cpu) {} | |
| 16 | −#endif | |
| 17 | −bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err); | |
| 18 | −bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t high, int *err); | |
| 19 | −int pmu_apic_update(uint32_t reg); | |
| 20 | −unsigned long long xen_read_pmc(int counter); | |
| 21 | − | |
| 22 | −#endif /* __XEN_PMU_H */ | |
| @@ -34,7 +34,6 @@ · 33 unmodified lines | ||
| 34 | 34 | #include <xen/features.h> |
| 35 | 35 | #include <xen/hvc-console.h> |
| 36 | 36 | #include "xen-ops.h" |
| 37 | −#include "mmu.h" | |
| 38 | 37 | |
| 39 | 38 | #define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024) |
| 40 | 39 | |
| @@ -9,7 +9,6 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #include <xen/hvc-console.h> |
| 11 | 11 | #include "xen-ops.h" |
| 12 | −#include "smp.h" | |
| 13 | 12 | |
| 14 | 13 | static DEFINE_PER_CPU(struct xen_common_irq, xen_resched_irq) = { .irq = -1 }; |
| 15 | 14 | static DEFINE_PER_CPU(struct xen_common_irq, xen_callfunc_irq) = { .irq = -1 }; |
| @@ -1,51 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | −#ifndef _XEN_SMP_H | |
| 3 | − | |
| 4 | −#ifdef CONFIG_SMP | |
| 5 | − | |
| 6 | −void asm_cpu_bringup_and_idle(void); | |
| 7 | −asmlinkage void cpu_bringup_and_idle(void); | |
| 8 | − | |
| 9 | −extern void xen_send_IPI_mask(const struct cpumask *mask, | |
| 10 | − int vector); | |
| 11 | −extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask, | |
| 12 | − int vector); | |
| 13 | −extern void xen_send_IPI_allbutself(int vector); | |
| 14 | −extern void xen_send_IPI_all(int vector); | |
| 15 | −extern void xen_send_IPI_self(int vector); | |
| 16 | − | |
| 17 | −extern int xen_smp_intr_init(unsigned int cpu); | |
| 18 | −extern void xen_smp_intr_free(unsigned int cpu); | |
| 19 | −int xen_smp_intr_init_pv(unsigned int cpu); | |
| 20 | −void xen_smp_intr_free_pv(unsigned int cpu); | |
| 21 | − | |
| 22 | −void xen_smp_count_cpus(void); | |
| 23 | −void xen_smp_cpus_done(unsigned int max_cpus); | |
| 24 | − | |
| 25 | −void xen_smp_send_reschedule(int cpu); | |
| 26 | −void xen_smp_send_call_function_ipi(const struct cpumask *mask); | |
| 27 | −void xen_smp_send_call_function_single_ipi(int cpu); | |
| 28 | − | |
| 29 | −void __noreturn xen_cpu_bringup_again(unsigned long stack); | |
| 30 | − | |
| 31 | −struct xen_common_irq { | |
| 32 | − int irq; | |
| 33 | − char *name; | |
| 34 | −}; | |
| 35 | −#else /* CONFIG_SMP */ | |
| 36 | − | |
| 37 | −static inline int xen_smp_intr_init(unsigned int cpu) | |
| 38 | −{ | |
| 39 | − return 0; | |
| 40 | −} | |
| 41 | −static inline void xen_smp_intr_free(unsigned int cpu) {} | |
| 42 | − | |
| 43 | −static inline int xen_smp_intr_init_pv(unsigned int cpu) | |
| 44 | −{ | |
| 45 | − return 0; | |
| 46 | −} | |
| 47 | −static inline void xen_smp_intr_free_pv(unsigned int cpu) {} | |
| 48 | −static inline void xen_smp_count_cpus(void) { } | |
| 49 | −#endif /* CONFIG_SMP */ | |
| 50 | − | |
| 51 | −#endif | |
| @@ -5,8 +5,6 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <xen/events.h> |
| 6 | 6 | |
| 7 | 7 | #include "xen-ops.h" |
| 8 | −#include "smp.h" | |
| 9 | − | |
| 10 | 8 | |
| 11 | 9 | static void __init xen_hvm_smp_prepare_boot_cpu(void) |
| 12 | 10 | { |
| @@ -46,9 +46,6 @@ · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | #include <xen/hvc-console.h> |
| 48 | 48 | #include "xen-ops.h" |
| 49 | −#include "mmu.h" | |
| 50 | −#include "smp.h" | |
| 51 | −#include "pmu.h" | |
| 52 | 49 | |
| 53 | 50 | cpumask_var_t xen_cpu_initialized_map; |
| 54 | 51 | |
| @@ -18,7 +18,6 @@ · 17 unmodified lines | ||
| 18 | 18 | static DEFINE_PER_CPU(int, lock_kicker_irq) = -1; |
| 19 | 19 | static DEFINE_PER_CPU(char *, irq_name); |
| 20 | 20 | static DEFINE_PER_CPU(atomic_t, xen_qlock_wait_nest); |
| 21 | −static bool xen_pvspin = true; | |
| 22 | 21 | |
| 23 | 22 | static void xen_qlock_kick(int cpu) |
| 24 | 23 | { |
| @@ -68,7 +67,7 @@ void xen_init_lock_cpu(int cpu) · 43 unmodified lines | ||
| 68 | 67 | int irq; |
| 69 | 68 | char *name; |
| 70 | 69 | |
| 71 | − if (!xen_pvspin) | |
| 70 | + if (nopvspin) | |
| 72 | 71 | return; |
| 73 | 72 | |
| 74 | 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 | 95 | int irq; |
| 97 | 96 | |
| 98 | − if (!xen_pvspin) | |
| 97 | + if (nopvspin) | |
| 99 | 98 | return; |
| 100 | 99 | |
| 101 | 100 | kfree(per_cpu(irq_name, cpu)); |
| @@ -125,10 +124,10 @@ PV_CALLEE_SAVE_REGS_THUNK(xen_vcpu_stolen); · 23 unmodified lines | ||
| 125 | 124 | void __init xen_init_spinlocks(void) |
| 126 | 125 | { |
| 127 | 126 | /* Don't need to use pvqspinlock code if there is only 1 vCPU. */ |
| 128 | − if (num_possible_cpus() == 1 || nopvspin) | |
| 129 | − xen_pvspin = false; | |
| 127 | + if (num_possible_cpus() == 1) | |
| 128 | + nopvspin = true; | |
| 130 | 129 | |
| 131 | − if (!xen_pvspin) { | |
| 130 | + if (nopvspin) { | |
| 132 | 131 | printk(KERN_DEBUG "xen: PV spinlocks disabled\n"); |
| 133 | 132 | static_branch_disable(&virt_spin_lock_key); |
| 134 | 133 | return; |
| @@ -143,12 +142,3 @@ void __init xen_init_spinlocks(void) · 8 unmodified lines | ||
| 143 | 142 | pv_ops.lock.kick = xen_qlock_kick; |
| 144 | 143 | pv_ops.lock.vcpu_is_preempted = PV_CALLEE_SAVE(xen_vcpu_stolen); |
| 145 | 144 | } |
| 146 | − | |
| 147 | −static __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 | −} | |
| 153 | −early_param("xen_nopvspin", xen_parse_nopvspin); | |
| 154 | − | |
| @@ -15,8 +15,6 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <asm/fixmap.h> |
| 16 | 16 | |
| 17 | 17 | #include "xen-ops.h" |
| 18 | −#include "mmu.h" | |
| 19 | −#include "pmu.h" | |
| 20 | 18 | |
| 21 | 19 | static DEFINE_PER_CPU(u64, spec_ctrl); |
| 22 | 20 | |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #include "xen-ops.h" |
| 31 | 31 | |
| 32 | 32 | /* Minimum amount of time until next clock event fires */ |
| 33 | −#define TIMER_SLOP 100000 | |
| 33 | +#define TIMER_SLOP 1 | |
| 34 | 34 | |
| 35 | 35 | static u64 xen_sched_clock_offset __read_mostly; |
| 36 | 36 | |
| @@ -5,8 +5,15 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <linux/init.h> |
| 6 | 6 | #include <linux/clocksource.h> |
| 7 | 7 | #include <linux/irqreturn.h> |
| 8 | +#include <linux/linkage.h> | |
| 9 | + | |
| 10 | +#include <xen/interface/xenpmu.h> | |
| 8 | 11 | #include <xen/xen-ops.h> |
| 9 | 12 | |
| 13 | +#include <asm/page.h> | |
| 14 | + | |
| 15 | +#include <trace/events/xen.h> | |
| 16 | + | |
| 10 | 17 | /* These are code, but not functions. Defined in entry.S */ |
| 11 | 18 | extern 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 | |
| 24 | 31 | DECLARE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info); |
| 25 | 32 | DECLARE_PER_CPU(unsigned long, xen_cr3); |
| 26 | −DECLARE_PER_CPU(unsigned long, xen_current_cr3); | |
| 27 | 33 | |
| 28 | 34 | extern struct start_info *xen_start_info; |
| 29 | 35 | extern struct shared_info xen_dummy_shared_info; |
| 30 | 36 | extern struct shared_info *HYPERVISOR_shared_info; |
| 31 | 37 | |
| 32 | −extern bool xen_fifo_events; | |
| 33 | − | |
| 34 | 38 | void xen_setup_mfn_list_list(void); |
| 35 | 39 | void xen_build_mfn_list_list(void); |
| 36 | 40 | void xen_setup_machphys_mapping(void); |
| @@ -177,4 +181,142 @@ static inline void xen_hvm_post_suspend(int suspend_cancelled) {} · 140 unmodified lines | ||
| 177 | 181 | |
| 178 | 182 | void xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns); |
| 179 | 183 | |
| 184 | +struct dentry * __init xen_init_debugfs(void); | |
| 185 | + | |
| 186 | +enum pt_level { | |
| 187 | + PT_PGD, | |
| 188 | + PT_P4D, | |
| 189 | + PT_PUD, | |
| 190 | + PT_PMD, | |
| 191 | + PT_PTE | |
| 192 | +}; | |
| 193 | + | |
| 194 | +bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); | |
| 195 | +void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); | |
| 196 | +unsigned long xen_read_cr2_direct(void); | |
| 197 | +void xen_init_mmu_ops(void); | |
| 198 | +void xen_hvm_init_mmu_ops(void); | |
| 199 | + | |
| 200 | +/* Multicalls */ | |
| 201 | +struct multicall_space | |
| 202 | +{ | |
| 203 | + struct multicall_entry *mc; | |
| 204 | + void *args; | |
| 205 | +}; | |
| 206 | + | |
| 207 | +/* Allocate room for a multicall and its args */ | |
| 208 | +struct multicall_space __xen_mc_entry(size_t args); | |
| 209 | + | |
| 210 | +DECLARE_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() */ | |
| 214 | +static 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 | + | |
| 224 | +static 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 */ | |
| 231 | +void xen_mc_flush(void); | |
| 232 | + | |
| 233 | +/* Issue a multicall if we're not in a lazy mode */ | |
| 234 | +static 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 */ | |
| 246 | +void 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 | + */ | |
| 258 | +struct multicall_space xen_mc_extend_args(unsigned long op, size_t arg_size); | |
| 259 | + | |
| 260 | +extern bool is_xen_pmu; | |
| 261 | + | |
| 262 | +irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id); | |
| 263 | +#ifdef CONFIG_XEN_HAVE_VPMU | |
| 264 | +void xen_pmu_init(int cpu); | |
| 265 | +void xen_pmu_finish(int cpu); | |
| 266 | +#else | |
| 267 | +static inline void xen_pmu_init(int cpu) {} | |
| 268 | +static inline void xen_pmu_finish(int cpu) {} | |
| 269 | +#endif | |
| 270 | +bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err); | |
| 271 | +bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t high, int *err); | |
| 272 | +int pmu_apic_update(uint32_t reg); | |
| 273 | +unsigned long long xen_read_pmc(int counter); | |
| 274 | + | |
| 275 | +#ifdef CONFIG_SMP | |
| 276 | + | |
| 277 | +void asm_cpu_bringup_and_idle(void); | |
| 278 | +asmlinkage void cpu_bringup_and_idle(void); | |
| 279 | + | |
| 280 | +extern void xen_send_IPI_mask(const struct cpumask *mask, | |
| 281 | + int vector); | |
| 282 | +extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask, | |
| 283 | + int vector); | |
| 284 | +extern void xen_send_IPI_allbutself(int vector); | |
| 285 | +extern void xen_send_IPI_all(int vector); | |
| 286 | +extern void xen_send_IPI_self(int vector); | |
| 287 | + | |
| 288 | +extern int xen_smp_intr_init(unsigned int cpu); | |
| 289 | +extern void xen_smp_intr_free(unsigned int cpu); | |
| 290 | +int xen_smp_intr_init_pv(unsigned int cpu); | |
| 291 | +void xen_smp_intr_free_pv(unsigned int cpu); | |
| 292 | + | |
| 293 | +void xen_smp_count_cpus(void); | |
| 294 | +void xen_smp_cpus_done(unsigned int max_cpus); | |
| 295 | + | |
| 296 | +void xen_smp_send_reschedule(int cpu); | |
| 297 | +void xen_smp_send_call_function_ipi(const struct cpumask *mask); | |
| 298 | +void xen_smp_send_call_function_single_ipi(int cpu); | |
| 299 | + | |
| 300 | +void __noreturn xen_cpu_bringup_again(unsigned long stack); | |
| 301 | + | |
| 302 | +struct xen_common_irq { | |
| 303 | + int irq; | |
| 304 | + char *name; | |
| 305 | +}; | |
| 306 | +#else /* CONFIG_SMP */ | |
| 307 | + | |
| 308 | +static inline int xen_smp_intr_init(unsigned int cpu) | |
| 309 | +{ | |
| 310 | + return 0; | |
| 311 | +} | |
| 312 | +static inline void xen_smp_intr_free(unsigned int cpu) {} | |
| 313 | + | |
| 314 | +static inline int xen_smp_intr_init_pv(unsigned int cpu) | |
| 315 | +{ | |
| 316 | + return 0; | |
| 317 | +} | |
| 318 | +static inline void xen_smp_intr_free_pv(unsigned int cpu) {} | |
| 319 | +static inline void xen_smp_count_cpus(void) { } | |
| 320 | +#endif /* CONFIG_SMP */ | |
| 321 | + | |
| 180 | 322 | #endif /* XEN_OPS_H */ |
| @@ -729,4 +729,5 @@ static void __exit evtchn_cleanup(void) · 728 unmodified lines | ||
| 729 | 729 | module_init(evtchn_init); |
| 730 | 730 | module_exit(evtchn_cleanup); |
| 731 | 731 | |
| 732 | +MODULE_DESCRIPTION("Xen /dev/xen/evtchn device driver"); | |
| 732 | 733 | MODULE_LICENSE("GPL"); |
| @@ -208,7 +208,7 @@ static void do_reboot(void) · 207 unmodified lines | ||
| 208 | 208 | orderly_reboot(); |
| 209 | 209 | } |
| 210 | 210 | |
| 211 | −static struct shutdown_handler shutdown_handlers[] = { | |
| 211 | +static const struct shutdown_handler shutdown_handlers[] = { | |
| 212 | 212 | { "poweroff", true, do_poweroff }, |
| 213 | 213 | { "halt", false, do_poweroff }, |
| 214 | 214 | { "reboot", true, do_reboot }, |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | #include "privcmd.h" |
| 21 | 21 | |
| 22 | +MODULE_DESCRIPTION("Xen Mmap of hypercall buffers"); | |
| 22 | 23 | MODULE_LICENSE("GPL"); |
| 23 | 24 | |
| 24 | 25 | struct privcmd_buf_private { |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/poll.h> |
| 18 | 18 | #include <linux/sched.h> |
| 19 | 19 | #include <linux/slab.h> |
| 20 | +#include <linux/srcu.h> | |
| 20 | 21 | #include <linux/string.h> |
| 21 | 22 | #include <linux/workqueue.h> |
| 22 | 23 | #include <linux/errno.h> |
| @@ -48,6 +49,7 @@ · 25 unmodified lines | ||
| 48 | 49 | |
| 49 | 50 | #include "privcmd.h" |
| 50 | 51 | |
| 52 | +MODULE_DESCRIPTION("Xen hypercall passthrough driver"); | |
| 51 | 53 | MODULE_LICENSE("GPL"); |
| 52 | 54 | |
| 53 | 55 | #define PRIV_VMA_LOCKED ((void *)1) |
| @@ -845,7 +847,8 @@ out: · 791 unmodified lines | ||
| 845 | 847 | #ifdef CONFIG_XEN_PRIVCMD_EVENTFD |
| 846 | 848 | /* Irqfd support */ |
| 847 | 849 | static struct workqueue_struct *irqfd_cleanup_wq; |
| 848 | −static DEFINE_MUTEX(irqfds_lock); | |
| 850 | +static DEFINE_SPINLOCK(irqfds_lock); | |
| 851 | +DEFINE_STATIC_SRCU(irqfds_srcu); | |
| 849 | 852 | static LIST_HEAD(irqfds_list); |
| 850 | 853 | |
| 851 | 854 | struct privcmd_kernel_irqfd { |
| @@ -873,6 +876,9 @@ static void irqfd_shutdown(struct work_struct *work) · 21 unmodified lines | ||
| 873 | 876 | container_of(work, struct privcmd_kernel_irqfd, shutdown); |
| 874 | 877 | u64 cnt; |
| 875 | 878 | |
| 879 | + /* Make sure irqfd has been initialized in assign path */ | |
| 880 | + synchronize_srcu(&irqfds_srcu); | |
| 881 | + | |
| 876 | 882 | eventfd_ctx_remove_wait_queue(kirqfd->eventfd, &kirqfd->wait, &cnt); |
| 877 | 883 | eventfd_ctx_put(kirqfd->eventfd); |
| 878 | 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 | 915 | irqfd_inject(kirqfd); |
| 910 | 916 | |
| 911 | 917 | if (flags & EPOLLHUP) { |
| 912 | − mutex_lock(&irqfds_lock); | |
| 918 | + unsigned long flags; | |
| 919 | + | |
| 920 | + spin_lock_irqsave(&irqfds_lock, flags); | |
| 913 | 921 | irqfd_deactivate(kirqfd); |
| 914 | − mutex_unlock(&irqfds_lock); | |
| 922 | + spin_unlock_irqrestore(&irqfds_lock, flags); | |
| 915 | 923 | } |
| 916 | 924 | |
| 917 | 925 | return 0; |
| @@ -929,10 +937,11 @@ irqfd_poll_func(struct file *file, wait_queue_head_t *wqh, poll_table *pt) · 11 unmodified lines | ||
| 929 | 937 | static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) |
| 930 | 938 | { |
| 931 | 939 | struct privcmd_kernel_irqfd *kirqfd, *tmp; |
| 940 | + unsigned long flags; | |
| 932 | 941 | __poll_t events; |
| 933 | 942 | struct fd f; |
| 934 | 943 | void *dm_op; |
| 935 | − int ret; | |
| 944 | + int ret, idx; | |
| 936 | 945 | |
| 937 | 946 | kirqfd = kzalloc(sizeof(*kirqfd) + irqfd->size, GFP_KERNEL); |
| 938 | 947 | if (!kirqfd) |
| @@ -968,18 +977,19 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) · 29 unmodified lines | ||
| 968 | 977 | init_waitqueue_func_entry(&kirqfd->wait, irqfd_wakeup); |
| 969 | 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 | 982 | list_for_each_entry(tmp, &irqfds_list, list) { |
| 974 | 983 | if (kirqfd->eventfd == tmp->eventfd) { |
| 975 | 984 | ret = -EBUSY; |
| 976 | − mutex_unlock(&irqfds_lock); | |
| 985 | + spin_unlock_irqrestore(&irqfds_lock, flags); | |
| 977 | 986 | goto error_eventfd; |
| 978 | 987 | } |
| 979 | 988 | } |
| 980 | 989 | |
| 990 | + idx = srcu_read_lock(&irqfds_srcu); | |
| 981 | 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 | 995 | * 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 | 999 | if (events & EPOLLIN) |
| 990 | 1000 | irqfd_inject(kirqfd); |
| 991 | 1001 | |
| 1002 | + srcu_read_unlock(&irqfds_srcu, idx); | |
| 1003 | + | |
| 992 | 1004 | /* |
| 993 | 1005 | * Do not drop the file until the kirqfd is fully initialized, otherwise |
| 994 | 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 | 1024 | struct privcmd_kernel_irqfd *kirqfd; |
| 1013 | 1025 | struct eventfd_ctx *eventfd; |
| 1026 | + unsigned long flags; | |
| 1014 | 1027 | |
| 1015 | 1028 | eventfd = eventfd_ctx_fdget(irqfd->fd); |
| 1016 | 1029 | if (IS_ERR(eventfd)) |
| 1017 | 1030 | return PTR_ERR(eventfd); |
| 1018 | 1031 | |
| 1019 | − mutex_lock(&irqfds_lock); | |
| 1032 | + spin_lock_irqsave(&irqfds_lock, flags); | |
| 1020 | 1033 | |
| 1021 | 1034 | list_for_each_entry(kirqfd, &irqfds_list, list) { |
| 1022 | 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 | 1043 | eventfd_ctx_put(eventfd); |
| 1031 | 1044 | |
| @@ -1073,13 +1086,14 @@ static int privcmd_irqfd_init(void) · 41 unmodified lines | ||
| 1073 | 1086 | static void privcmd_irqfd_exit(void) |
| 1074 | 1087 | { |
| 1075 | 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 | 1093 | list_for_each_entry_safe(kirqfd, tmp, &irqfds_list, list) |
| 1080 | 1094 | irqfd_deactivate(kirqfd); |
| 1081 | 1095 | |
| 1082 | − mutex_unlock(&irqfds_lock); | |
| 1096 | + spin_unlock_irqrestore(&irqfds_lock, flags); | |
| 1083 | 1097 | |
| 1084 | 1098 | destroy_workqueue(irqfd_cleanup_wq); |
| 1085 | 1099 | } |
| @@ -1708,5 +1708,6 @@ static void __exit xen_pcibk_cleanup(void) · 1707 unmodified lines | ||
| 1708 | 1708 | module_init(xen_pcibk_init); |
| 1709 | 1709 | module_exit(xen_pcibk_cleanup); |
| 1710 | 1710 | |
| 1711 | +MODULE_DESCRIPTION("Xen PCI-device stub driver"); | |
| 1711 | 1712 | MODULE_LICENSE("Dual BSD/GPL"); |
| 1712 | 1713 | MODULE_ALIAS("xen-backend:pci"); |
| @@ -144,4 +144,6 @@ static inline void xen_evtchn_close(evtchn_port_t port) · 143 unmodified lines | ||
| 144 | 144 | BUG(); |
| 145 | 145 | } |
| 146 | 146 | |
| 147 | +extern bool xen_fifo_events; | |
| 148 | + | |
| 147 | 149 | #endif /* _XEN_EVENTS_H */ |
| @@ -583,7 +583,7 @@ EXPORT_SYMBOL(queued_spin_lock_slowpath); · 582 unmodified lines | ||
| 583 | 583 | #include "qspinlock_paravirt.h" |
| 584 | 584 | #include "qspinlock.c" |
| 585 | 585 | |
| 586 | −bool nopvspin __initdata; | |
| 586 | +bool nopvspin; | |
| 587 | 587 | static __init int parse_nopvspin(char *arg) |
| 588 | 588 | { |
| 589 | 589 | nopvspin = true; |