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 | Crash from Xen panic notifier, without executing late | 7420 | 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) MSR | 7431 | Select whether to always use non-faulting (safe) MSR |
| 7426 | access functions when running as Xen PV guest. The | 7432 | 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 to | 7436 | 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. |
| @@ -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) |
| @@ -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 | ||
| 16 | static unsigned int xen_io_apic_read(unsigned apic, unsigned reg) | 14 | static unsigned int xen_io_apic_read(unsigned apic, unsigned reg) |
| 17 | { | 15 | { |
| @@ -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 | ||
| 8 | static struct dentry *d_xen_debug; | 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 | #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 | ||
| 26 | EXPORT_SYMBOL_GPL(hypercall_page); | 24 | EXPORT_SYMBOL_GPL(hypercall_page); |
| 27 | 25 | ||
| @@ -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 | ||
| 34 | static unsigned long shared_info_pfn; | 32 | static unsigned long shared_info_pfn; |
| 35 | 33 | ||
| @@ -85,10 +85,6 @@ · 84 unmodified lines | |||
| 85 | #endif | 85 | #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 | ||
| @@ -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 | ||
| 11 | unsigned long arbitrary_virt_to_mfn(void *vaddr) | 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 | #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_VMCORE | 10 | #ifdef CONFIG_PROC_VMCORE |
| 11 | /* | 11 | /* |
| @@ -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 order | 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 | * 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 | */ |
| 130 | DEFINE_PER_CPU(unsigned long, xen_cr3); /* cr3 stored as physaddr */ | 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 | static phys_addr_t xen_pt_base, xen_pt_size __initdata; | 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 | __xen_set_pte(ptep, pteval); | 303 | __xen_set_pte(ptep, pteval); |
| 306 | } | 304 | } |
| 307 | 305 | ||
| 308 | pte_t xen_ptep_modify_prot_start(struct vm_area_struct *vma, | 306 | static 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 | ||
| 316 | void xen_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, | 314 | static 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 | ||
| @@ -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 32 | 33 | #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 | ||
| 39 | struct mc_buffer { | 38 | struct 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 | ||
| 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 | static DEFINE_PER_CPU(struct mc_buffer, mc_buffer); | 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 | DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags); | 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 | void xen_mc_flush(void) | 135 | void 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_DEBUG | 152 | 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 | #endif | 155 | 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_DEBUG | 188 | 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_DEBUG | 232 | 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 | #endif | 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 | 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; |
| @@ -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 | #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_FS | 795 | #ifdef CONFIG_XEN_DEBUG_FS |
| 797 | #include <linux/debugfs.h> | 796 | #include <linux/debugfs.h> |
| 798 | #include "debugfs.h" | ||
| 799 | static int p2m_dump_show(struct seq_file *m, void *v) | 797 | static 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[] = { |
| @@ -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" |
| @@ -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 | #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 | ||
| @@ -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 | ||
| 14 | static DEFINE_PER_CPU(struct xen_common_irq, xen_resched_irq) = { .irq = -1 }; | 13 | static DEFINE_PER_CPU(struct xen_common_irq, xen_resched_irq) = { .irq = -1 }; |
| 15 | static DEFINE_PER_CPU(struct xen_common_irq, xen_callfunc_irq) = { .irq = -1 }; | 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 | #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 | ||
| 11 | static void __init xen_hvm_smp_prepare_boot_cpu(void) | 9 | static void __init xen_hvm_smp_prepare_boot_cpu(void) |
| 12 | { | 10 | { |
| @@ -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 | ||
| 53 | cpumask_var_t xen_cpu_initialized_map; | 50 | cpumask_var_t xen_cpu_initialized_map; |
| 54 | 51 | ||
| @@ -18,7 +18,6 @@ · 17 unmodified lines | |||
| 18 | static DEFINE_PER_CPU(int, lock_kicker_irq) = -1; | 18 | static DEFINE_PER_CPU(int, lock_kicker_irq) = -1; |
| 19 | static DEFINE_PER_CPU(char *, irq_name); | 19 | static DEFINE_PER_CPU(char *, irq_name); |
| 20 | static DEFINE_PER_CPU(atomic_t, xen_qlock_wait_nest); | 20 | static DEFINE_PER_CPU(atomic_t, xen_qlock_wait_nest); |
| 21 | static bool xen_pvspin = true; | ||
| 22 | 21 | ||
| 23 | static void xen_qlock_kick(int cpu) | 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 | 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 | |||
| 125 | void __init xen_init_spinlocks(void) | 124 | void __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 | |||
| 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 | #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 | ||
| 21 | static DEFINE_PER_CPU(u64, spec_ctrl); | 19 | static DEFINE_PER_CPU(u64, spec_ctrl); |
| 22 | 20 | ||
| @@ -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 100000 | 33 | #define TIMER_SLOP 1 |
| 34 | 34 | ||
| 35 | static u64 xen_sched_clock_offset __read_mostly; | 35 | static u64 xen_sched_clock_offset __read_mostly; |
| 36 | 36 | ||
| @@ -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 */ |
| 11 | extern const char xen_failsafe_callback[]; | 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 | DECLARE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info); | 31 | DECLARE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info); |
| 25 | DECLARE_PER_CPU(unsigned long, xen_cr3); | 32 | DECLARE_PER_CPU(unsigned long, xen_cr3); |
| 26 | DECLARE_PER_CPU(unsigned long, xen_current_cr3); | ||
| 27 | 33 | ||
| 28 | extern struct start_info *xen_start_info; | 34 | extern struct start_info *xen_start_info; |
| 29 | extern struct shared_info xen_dummy_shared_info; | 35 | extern struct shared_info xen_dummy_shared_info; |
| 30 | extern struct shared_info *HYPERVISOR_shared_info; | 36 | extern struct shared_info *HYPERVISOR_shared_info; |
| 31 | 37 | ||
| 32 | extern bool xen_fifo_events; | ||
| 33 | |||
| 34 | void xen_setup_mfn_list_list(void); | 38 | void xen_setup_mfn_list_list(void); |
| 35 | void xen_build_mfn_list_list(void); | 39 | void xen_build_mfn_list_list(void); |
| 36 | void xen_setup_machphys_mapping(void); | 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 | void xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns); | 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 | #endif /* XEN_OPS_H */ | 322 | #endif /* XEN_OPS_H */ |
| @@ -729,4 +729,5 @@ static void __exit evtchn_cleanup(void) · 728 unmodified lines | |||
| 729 | module_init(evtchn_init); | 729 | module_init(evtchn_init); |
| 730 | module_exit(evtchn_cleanup); | 730 | module_exit(evtchn_cleanup); |
| 731 | 731 | ||
| 732 | MODULE_DESCRIPTION("Xen /dev/xen/evtchn device driver"); | ||
| 732 | MODULE_LICENSE("GPL"); | 733 | MODULE_LICENSE("GPL"); |
| @@ -208,7 +208,7 @@ static void do_reboot(void) · 207 unmodified lines | |||
| 208 | orderly_reboot(); | 208 | orderly_reboot(); |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | static struct shutdown_handler shutdown_handlers[] = { | 211 | static 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 }, |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | #include "privcmd.h" | 20 | #include "privcmd.h" |
| 21 | 21 | ||
| 22 | MODULE_DESCRIPTION("Xen Mmap of hypercall buffers"); | ||
| 22 | MODULE_LICENSE("GPL"); | 23 | MODULE_LICENSE("GPL"); |
| 23 | 24 | ||
| 24 | struct privcmd_buf_private { | 25 | struct privcmd_buf_private { |
| @@ -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 | ||
| 52 | MODULE_DESCRIPTION("Xen hypercall passthrough driver"); | ||
| 51 | MODULE_LICENSE("GPL"); | 53 | MODULE_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_EVENTFD | 847 | #ifdef CONFIG_XEN_PRIVCMD_EVENTFD |
| 846 | /* Irqfd support */ | 848 | /* Irqfd support */ |
| 847 | static struct workqueue_struct *irqfd_cleanup_wq; | 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 | static LIST_HEAD(irqfds_list); | 852 | static LIST_HEAD(irqfds_list); |
| 850 | 853 | ||
| 851 | struct privcmd_kernel_irqfd { | 854 | struct 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 | |||
| 929 | static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) | 937 | static 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 we | 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 | 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, otherwise | 1005 | * 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 | |||
| 1073 | static void privcmd_irqfd_exit(void) | 1086 | static 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 | } |
| @@ -1708,5 +1708,6 @@ static void __exit xen_pcibk_cleanup(void) · 1707 unmodified lines | |||
| 1708 | module_init(xen_pcibk_init); | 1708 | module_init(xen_pcibk_init); |
| 1709 | module_exit(xen_pcibk_cleanup); | 1709 | module_exit(xen_pcibk_cleanup); |
| 1710 | 1710 | ||
| 1711 | MODULE_DESCRIPTION("Xen PCI-device stub driver"); | ||
| 1711 | MODULE_LICENSE("Dual BSD/GPL"); | 1712 | MODULE_LICENSE("Dual BSD/GPL"); |
| 1712 | MODULE_ALIAS("xen-backend:pci"); | 1713 | MODULE_ALIAS("xen-backend:pci"); |
| @@ -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 | ||
| 147 | extern bool xen_fifo_events; | ||
| 148 | |||
| 147 | #endif /* _XEN_EVENTS_H */ | 149 | #endif /* _XEN_EVENTS_H */ |
| @@ -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 | ||
| 586 | bool nopvspin __initdata; | 586 | bool nopvspin; |
| 587 | static __init int parse_nopvspin(char *arg) | 587 | static __init int parse_nopvspin(char *arg) |
| 588 | { | 588 | { |
| 589 | nopvspin = true; | 589 | nopvspin = true; |