aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-03-04 14:36:19 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-03-04 14:36:19 -0500
commit2d62e0768d3c28536d4cfe4c40ba1e5e8e442a93 (patch)
tree333f8cbcdb3b650813d758711a9e4ceee7b6fbce
parentbe834aafdf5f8a37c191e697ac8ee6d53ab5020c (diff)
parent16ce771b93ab569490fd27415694132a7ade0d79 (diff)
Merge tag 'kvm-4.11-2' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull more KVM updates from Radim Krčmář: "Second batch of KVM changes for the 4.11 merge window: PPC: - correct assumption about ASDR on POWER9 - fix MMIO emulation on POWER9 x86: - add a simple test for ioperm - cleanup TSS (going through KVM tree as the whole undertaking was caused by VMX's use of TSS) - fix nVMX interrupt delivery - fix some performance counters in the guest ... and two cleanup patches" * tag 'kvm-4.11-2' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: nVMX: Fix pending events injection x86/kvm/vmx: remove unused variable in segment_base() selftests/x86: Add a basic selftest for ioperm x86/asm: Tidy up TSS limit code kvm: convert kvm.users_count from atomic_t to refcount_t KVM: x86: never specify a sample period for virtualized in_tx_cp counters KVM: PPC: Book3S HV: Don't use ASDR for real-mode HPT faults on POWER9 KVM: PPC: Book3S HV: Fix software walk of guest process page tables
-rw-r--r--arch/powerpc/include/asm/book3s/64/mmu.h3
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_radix.c5
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S8
-rw-r--r--arch/x86/include/asm/desc.h18
-rw-r--r--arch/x86/kernel/ioport.c8
-rw-r--r--arch/x86/kernel/process.c6
-rw-r--r--arch/x86/kvm/pmu.c13
-rw-r--r--arch/x86/kvm/vmx.c9
-rw-r--r--include/linux/kvm_host.h3
-rw-r--r--tools/testing/selftests/x86/Makefile2
-rw-r--r--tools/testing/selftests/x86/ioperm.c170
-rw-r--r--virt/kvm/kvm_main.c8
12 files changed, 223 insertions, 30 deletions
diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
index 1145dc8e726d..805d4105e9bb 100644
--- a/arch/powerpc/include/asm/book3s/64/mmu.h
+++ b/arch/powerpc/include/asm/book3s/64/mmu.h
@@ -46,7 +46,7 @@ extern struct patb_entry *partition_tb;
46 46
47/* Bits in patb0 field */ 47/* Bits in patb0 field */
48#define PATB_HR (1UL << 63) 48#define PATB_HR (1UL << 63)
49#define RPDB_MASK 0x0ffffffffffff00fUL 49#define RPDB_MASK 0x0fffffffffffff00UL
50#define RPDB_SHIFT (1UL << 8) 50#define RPDB_SHIFT (1UL << 8)
51#define RTS1_SHIFT 61 /* top 2 bits of radix tree size */ 51#define RTS1_SHIFT 61 /* top 2 bits of radix tree size */
52#define RTS1_MASK (3UL << RTS1_SHIFT) 52#define RTS1_MASK (3UL << RTS1_SHIFT)
@@ -57,6 +57,7 @@ extern struct patb_entry *partition_tb;
57/* Bits in patb1 field */ 57/* Bits in patb1 field */
58#define PATB_GR (1UL << 63) /* guest uses radix; must match HR */ 58#define PATB_GR (1UL << 63) /* guest uses radix; must match HR */
59#define PRTS_MASK 0x1f /* process table size field */ 59#define PRTS_MASK 0x1f /* process table size field */
60#define PRTB_MASK 0x0ffffffffffff000UL
60 61
61/* 62/*
62 * Limit process table to PAGE_SIZE table. This 63 * Limit process table to PAGE_SIZE table. This
diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c
index 4344651f408c..f6b3e67c5762 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_radix.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c
@@ -32,6 +32,7 @@ int kvmppc_mmu_radix_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
32 u32 pid; 32 u32 pid;
33 int ret, level, ps; 33 int ret, level, ps;
34 __be64 prte, rpte; 34 __be64 prte, rpte;
35 unsigned long ptbl;
35 unsigned long root, pte, index; 36 unsigned long root, pte, index;
36 unsigned long rts, bits, offset; 37 unsigned long rts, bits, offset;
37 unsigned long gpa; 38 unsigned long gpa;
@@ -53,8 +54,8 @@ int kvmppc_mmu_radix_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
53 return -EINVAL; 54 return -EINVAL;
54 55
55 /* Read partition table to find root of tree for effective PID */ 56 /* Read partition table to find root of tree for effective PID */
56 ret = kvm_read_guest(kvm, kvm->arch.process_table + pid * 16, 57 ptbl = (kvm->arch.process_table & PRTB_MASK) + (pid * 16);
57 &prte, sizeof(prte)); 58 ret = kvm_read_guest(kvm, ptbl, &prte, sizeof(prte));
58 if (ret) 59 if (ret)
59 return ret; 60 return ret;
60 61
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 47414a6fe2dd..7c6477d1840a 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1787,12 +1787,12 @@ kvmppc_hdsi:
1787 /* HPTE not found fault or protection fault? */ 1787 /* HPTE not found fault or protection fault? */
1788 andis. r0, r6, (DSISR_NOHPTE | DSISR_PROTFAULT)@h 1788 andis. r0, r6, (DSISR_NOHPTE | DSISR_PROTFAULT)@h
1789 beq 1f /* if not, send it to the guest */ 1789 beq 1f /* if not, send it to the guest */
1790 andi. r0, r11, MSR_DR /* data relocation enabled? */
1791 beq 3f
1790BEGIN_FTR_SECTION 1792BEGIN_FTR_SECTION
1791 mfspr r5, SPRN_ASDR /* on POWER9, use ASDR to get VSID */ 1793 mfspr r5, SPRN_ASDR /* on POWER9, use ASDR to get VSID */
1792 b 4f 1794 b 4f
1793END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) 1795END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
1794 andi. r0, r11, MSR_DR /* data relocation enabled? */
1795 beq 3f
1796 clrrdi r0, r4, 28 1796 clrrdi r0, r4, 28
1797 PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */ 1797 PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */
1798 li r0, BOOK3S_INTERRUPT_DATA_SEGMENT 1798 li r0, BOOK3S_INTERRUPT_DATA_SEGMENT
@@ -1879,12 +1879,12 @@ kvmppc_hisi:
1879 bne .Lradix_hisi /* for radix, just save ASDR */ 1879 bne .Lradix_hisi /* for radix, just save ASDR */
1880 andis. r0, r11, SRR1_ISI_NOPT@h 1880 andis. r0, r11, SRR1_ISI_NOPT@h
1881 beq 1f 1881 beq 1f
1882 andi. r0, r11, MSR_IR /* instruction relocation enabled? */
1883 beq 3f
1882BEGIN_FTR_SECTION 1884BEGIN_FTR_SECTION
1883 mfspr r5, SPRN_ASDR /* on POWER9, use ASDR to get VSID */ 1885 mfspr r5, SPRN_ASDR /* on POWER9, use ASDR to get VSID */
1884 b 4f 1886 b 4f
1885END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) 1887END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
1886 andi. r0, r11, MSR_IR /* instruction relocation enabled? */
1887 beq 3f
1888 clrrdi r0, r10, 28 1888 clrrdi r0, r10, 28
1889 PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */ 1889 PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */
1890 li r0, BOOK3S_INTERRUPT_INST_SEGMENT 1890 li r0, BOOK3S_INTERRUPT_INST_SEGMENT
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index cb8f9149f6c8..1548ca92ad3f 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -205,6 +205,8 @@ static inline void native_load_tr_desc(void)
205 asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8)); 205 asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
206} 206}
207 207
208DECLARE_PER_CPU(bool, __tss_limit_invalid);
209
208static inline void force_reload_TR(void) 210static inline void force_reload_TR(void)
209{ 211{
210 struct desc_struct *d = get_cpu_gdt_table(smp_processor_id()); 212 struct desc_struct *d = get_cpu_gdt_table(smp_processor_id());
@@ -220,18 +222,20 @@ static inline void force_reload_TR(void)
220 write_gdt_entry(d, GDT_ENTRY_TSS, &tss, DESC_TSS); 222 write_gdt_entry(d, GDT_ENTRY_TSS, &tss, DESC_TSS);
221 223
222 load_TR_desc(); 224 load_TR_desc();
225 this_cpu_write(__tss_limit_invalid, false);
223} 226}
224 227
225DECLARE_PER_CPU(bool, need_tr_refresh); 228/*
226 229 * Call this if you need the TSS limit to be correct, which should be the case
227static inline void refresh_TR(void) 230 * if and only if you have TIF_IO_BITMAP set or you're switching to a task
231 * with TIF_IO_BITMAP set.
232 */
233static inline void refresh_tss_limit(void)
228{ 234{
229 DEBUG_LOCKS_WARN_ON(preemptible()); 235 DEBUG_LOCKS_WARN_ON(preemptible());
230 236
231 if (unlikely(this_cpu_read(need_tr_refresh))) { 237 if (unlikely(this_cpu_read(__tss_limit_invalid)))
232 force_reload_TR(); 238 force_reload_TR();
233 this_cpu_write(need_tr_refresh, false);
234 }
235} 239}
236 240
237/* 241/*
@@ -250,7 +254,7 @@ static inline void invalidate_tss_limit(void)
250 if (unlikely(test_thread_flag(TIF_IO_BITMAP))) 254 if (unlikely(test_thread_flag(TIF_IO_BITMAP)))
251 force_reload_TR(); 255 force_reload_TR();
252 else 256 else
253 this_cpu_write(need_tr_refresh, true); 257 this_cpu_write(__tss_limit_invalid, true);
254} 258}
255 259
256static inline void native_load_gdt(const struct desc_ptr *dtr) 260static inline void native_load_gdt(const struct desc_ptr *dtr)
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
index ca49bab3e467..9c3cf0944bce 100644
--- a/arch/x86/kernel/ioport.c
+++ b/arch/x86/kernel/ioport.c
@@ -48,8 +48,14 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
48 t->io_bitmap_ptr = bitmap; 48 t->io_bitmap_ptr = bitmap;
49 set_thread_flag(TIF_IO_BITMAP); 49 set_thread_flag(TIF_IO_BITMAP);
50 50
51 /*
52 * Now that we have an IO bitmap, we need our TSS limit to be
53 * correct. It's fine if we are preempted after doing this:
54 * with TIF_IO_BITMAP set, context switches will keep our TSS
55 * limit correct.
56 */
51 preempt_disable(); 57 preempt_disable();
52 refresh_TR(); 58 refresh_tss_limit();
53 preempt_enable(); 59 preempt_enable();
54 } 60 }
55 61
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 56b059486c3b..f67591561711 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -69,8 +69,8 @@ __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = {
69}; 69};
70EXPORT_PER_CPU_SYMBOL(cpu_tss); 70EXPORT_PER_CPU_SYMBOL(cpu_tss);
71 71
72DEFINE_PER_CPU(bool, need_tr_refresh); 72DEFINE_PER_CPU(bool, __tss_limit_invalid);
73EXPORT_PER_CPU_SYMBOL_GPL(need_tr_refresh); 73EXPORT_PER_CPU_SYMBOL_GPL(__tss_limit_invalid);
74 74
75/* 75/*
76 * this gets called so that we can store lazy state into memory and copy the 76 * this gets called so that we can store lazy state into memory and copy the
@@ -222,7 +222,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
222 * Make sure that the TSS limit is correct for the CPU 222 * Make sure that the TSS limit is correct for the CPU
223 * to notice the IO bitmap. 223 * to notice the IO bitmap.
224 */ 224 */
225 refresh_TR(); 225 refresh_tss_limit();
226 } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) { 226 } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) {
227 /* 227 /*
228 * Clear any possible leftover bits: 228 * Clear any possible leftover bits:
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 06ce377dcbc9..026db42a86c3 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -113,12 +113,19 @@ static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type,
113 .config = config, 113 .config = config,
114 }; 114 };
115 115
116 attr.sample_period = (-pmc->counter) & pmc_bitmask(pmc);
117
116 if (in_tx) 118 if (in_tx)
117 attr.config |= HSW_IN_TX; 119 attr.config |= HSW_IN_TX;
118 if (in_tx_cp) 120 if (in_tx_cp) {
121 /*
122 * HSW_IN_TX_CHECKPOINTED is not supported with nonzero
123 * period. Just clear the sample period so at least
124 * allocating the counter doesn't fail.
125 */
126 attr.sample_period = 0;
119 attr.config |= HSW_IN_TX_CHECKPOINTED; 127 attr.config |= HSW_IN_TX_CHECKPOINTED;
120 128 }
121 attr.sample_period = (-pmc->counter) & pmc_bitmask(pmc);
122 129
123 event = perf_event_create_kernel_counter(&attr, -1, current, 130 event = perf_event_create_kernel_counter(&attr, -1, current,
124 intr ? kvm_perf_overflow_intr : 131 intr ? kvm_perf_overflow_intr :
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ef4ba71dbb66..283aa8601833 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2053,7 +2053,6 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
2053static unsigned long segment_base(u16 selector) 2053static unsigned long segment_base(u16 selector)
2054{ 2054{
2055 struct desc_ptr *gdt = this_cpu_ptr(&host_gdt); 2055 struct desc_ptr *gdt = this_cpu_ptr(&host_gdt);
2056 struct desc_struct *d;
2057 struct desc_struct *table; 2056 struct desc_struct *table;
2058 unsigned long v; 2057 unsigned long v;
2059 2058
@@ -10642,6 +10641,11 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
10642{ 10641{
10643 struct vcpu_vmx *vmx = to_vmx(vcpu); 10642 struct vcpu_vmx *vmx = to_vmx(vcpu);
10644 10643
10644 if (vcpu->arch.exception.pending ||
10645 vcpu->arch.nmi_injected ||
10646 vcpu->arch.interrupt.pending)
10647 return -EBUSY;
10648
10645 if (nested_cpu_has_preemption_timer(get_vmcs12(vcpu)) && 10649 if (nested_cpu_has_preemption_timer(get_vmcs12(vcpu)) &&
10646 vmx->nested.preemption_timer_expired) { 10650 vmx->nested.preemption_timer_expired) {
10647 if (vmx->nested.nested_run_pending) 10651 if (vmx->nested.nested_run_pending)
@@ -10651,8 +10655,7 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
10651 } 10655 }
10652 10656
10653 if (vcpu->arch.nmi_pending && nested_exit_on_nmi(vcpu)) { 10657 if (vcpu->arch.nmi_pending && nested_exit_on_nmi(vcpu)) {
10654 if (vmx->nested.nested_run_pending || 10658 if (vmx->nested.nested_run_pending)
10655 vcpu->arch.interrupt.pending)
10656 return -EBUSY; 10659 return -EBUSY;
10657 nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI, 10660 nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI,
10658 NMI_VECTOR | INTR_TYPE_NMI_INTR | 10661 NMI_VECTOR | INTR_TYPE_NMI_INTR |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 8d69d5150748..2c14ad9809da 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -26,6 +26,7 @@
26#include <linux/context_tracking.h> 26#include <linux/context_tracking.h>
27#include <linux/irqbypass.h> 27#include <linux/irqbypass.h>
28#include <linux/swait.h> 28#include <linux/swait.h>
29#include <linux/refcount.h>
29#include <asm/signal.h> 30#include <asm/signal.h>
30 31
31#include <linux/kvm.h> 32#include <linux/kvm.h>
@@ -401,7 +402,7 @@ struct kvm {
401#endif 402#endif
402 struct kvm_vm_stat stat; 403 struct kvm_vm_stat stat;
403 struct kvm_arch arch; 404 struct kvm_arch arch;
404 atomic_t users_count; 405 refcount_t users_count;
405#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET 406#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
406 struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; 407 struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
407 spinlock_t ring_lock; 408 spinlock_t ring_lock;
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index 3a5ebae5303e..38e0a9ca5d71 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -5,7 +5,7 @@ include ../lib.mk
5.PHONY: all all_32 all_64 warn_32bit_failure clean 5.PHONY: all all_32 all_64 warn_32bit_failure clean
6 6
7TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ 7TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \
8 check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test \ 8 check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test ioperm \
9 protection_keys test_vdso 9 protection_keys test_vdso
10TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ 10TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \
11 test_FCMOV test_FCOMI test_FISTTP \ 11 test_FCMOV test_FCOMI test_FISTTP \
diff --git a/tools/testing/selftests/x86/ioperm.c b/tools/testing/selftests/x86/ioperm.c
new file mode 100644
index 000000000000..b77313ba2ab1
--- /dev/null
+++ b/tools/testing/selftests/x86/ioperm.c
@@ -0,0 +1,170 @@
1/*
2 * ioperm.c - Test case for ioperm(2)
3 * Copyright (c) 2015 Andrew Lutomirski
4 */
5
6#define _GNU_SOURCE
7#include <err.h>
8#include <stdio.h>
9#include <stdint.h>
10#include <signal.h>
11#include <setjmp.h>
12#include <stdlib.h>
13#include <string.h>
14#include <errno.h>
15#include <unistd.h>
16#include <sys/types.h>
17#include <sys/wait.h>
18#include <stdbool.h>
19#include <sched.h>
20#include <sys/io.h>
21
22static int nerrs = 0;
23
24static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
25 int flags)
26{
27 struct sigaction sa;
28 memset(&sa, 0, sizeof(sa));
29 sa.sa_sigaction = handler;
30 sa.sa_flags = SA_SIGINFO | flags;
31 sigemptyset(&sa.sa_mask);
32 if (sigaction(sig, &sa, 0))
33 err(1, "sigaction");
34
35}
36
37static void clearhandler(int sig)
38{
39 struct sigaction sa;
40 memset(&sa, 0, sizeof(sa));
41 sa.sa_handler = SIG_DFL;
42 sigemptyset(&sa.sa_mask);
43 if (sigaction(sig, &sa, 0))
44 err(1, "sigaction");
45}
46
47static jmp_buf jmpbuf;
48
49static void sigsegv(int sig, siginfo_t *si, void *ctx_void)
50{
51 siglongjmp(jmpbuf, 1);
52}
53
54static bool try_outb(unsigned short port)
55{
56 sethandler(SIGSEGV, sigsegv, SA_RESETHAND);
57 if (sigsetjmp(jmpbuf, 1) != 0) {
58 return false;
59 } else {
60 asm volatile ("outb %%al, %w[port]"
61 : : [port] "Nd" (port), "a" (0));
62 return true;
63 }
64 clearhandler(SIGSEGV);
65}
66
67static void expect_ok(unsigned short port)
68{
69 if (!try_outb(port)) {
70 printf("[FAIL]\toutb to 0x%02hx failed\n", port);
71 exit(1);
72 }
73
74 printf("[OK]\toutb to 0x%02hx worked\n", port);
75}
76
77static void expect_gp(unsigned short port)
78{
79 if (try_outb(port)) {
80 printf("[FAIL]\toutb to 0x%02hx worked\n", port);
81 exit(1);
82 }
83
84 printf("[OK]\toutb to 0x%02hx failed\n", port);
85}
86
87int main(void)
88{
89 cpu_set_t cpuset;
90 CPU_ZERO(&cpuset);
91 CPU_SET(0, &cpuset);
92 if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0)
93 err(1, "sched_setaffinity to CPU 0");
94
95 expect_gp(0x80);
96 expect_gp(0xed);
97
98 /*
99 * Probe for ioperm support. Note that clearing ioperm bits
100 * works even as nonroot.
101 */
102 printf("[RUN]\tenable 0x80\n");
103 if (ioperm(0x80, 1, 1) != 0) {
104 printf("[OK]\tioperm(0x80, 1, 1) failed (%d) -- try running as root\n",
105 errno);
106 return 0;
107 }
108 expect_ok(0x80);
109 expect_gp(0xed);
110
111 printf("[RUN]\tdisable 0x80\n");
112 if (ioperm(0x80, 1, 0) != 0) {
113 printf("[FAIL]\tioperm(0x80, 1, 0) failed (%d)", errno);
114 return 1;
115 }
116 expect_gp(0x80);
117 expect_gp(0xed);
118
119 /* Make sure that fork() preserves ioperm. */
120 if (ioperm(0x80, 1, 1) != 0) {
121 printf("[FAIL]\tioperm(0x80, 1, 0) failed (%d)", errno);
122 return 1;
123 }
124
125 pid_t child = fork();
126 if (child == -1)
127 err(1, "fork");
128
129 if (child == 0) {
130 printf("[RUN]\tchild: check that we inherited permissions\n");
131 expect_ok(0x80);
132 expect_gp(0xed);
133 return 0;
134 } else {
135 int status;
136 if (waitpid(child, &status, 0) != child ||
137 !WIFEXITED(status)) {
138 printf("[FAIL]\tChild died\n");
139 nerrs++;
140 } else if (WEXITSTATUS(status) != 0) {
141 printf("[FAIL]\tChild failed\n");
142 nerrs++;
143 } else {
144 printf("[OK]\tChild succeeded\n");
145 }
146 }
147
148 /* Test the capability checks. */
149
150 printf("\tDrop privileges\n");
151 if (setresuid(1, 1, 1) != 0) {
152 printf("[WARN]\tDropping privileges failed\n");
153 return 0;
154 }
155
156 printf("[RUN]\tdisable 0x80\n");
157 if (ioperm(0x80, 1, 0) != 0) {
158 printf("[FAIL]\tioperm(0x80, 1, 0) failed (%d)", errno);
159 return 1;
160 }
161 printf("[OK]\tit worked\n");
162
163 printf("[RUN]\tenable 0x80 again\n");
164 if (ioperm(0x80, 1, 1) == 0) {
165 printf("[FAIL]\tit succeeded but should have failed.\n");
166 return 1;
167 }
168 printf("[OK]\tit failed\n");
169 return 0;
170}
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 799499417f5b..a17d78759727 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -619,7 +619,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
619 mutex_init(&kvm->lock); 619 mutex_init(&kvm->lock);
620 mutex_init(&kvm->irq_lock); 620 mutex_init(&kvm->irq_lock);
621 mutex_init(&kvm->slots_lock); 621 mutex_init(&kvm->slots_lock);
622 atomic_set(&kvm->users_count, 1); 622 refcount_set(&kvm->users_count, 1);
623 INIT_LIST_HEAD(&kvm->devices); 623 INIT_LIST_HEAD(&kvm->devices);
624 624
625 r = kvm_arch_init_vm(kvm, type); 625 r = kvm_arch_init_vm(kvm, type);
@@ -749,13 +749,13 @@ static void kvm_destroy_vm(struct kvm *kvm)
749 749
750void kvm_get_kvm(struct kvm *kvm) 750void kvm_get_kvm(struct kvm *kvm)
751{ 751{
752 atomic_inc(&kvm->users_count); 752 refcount_inc(&kvm->users_count);
753} 753}
754EXPORT_SYMBOL_GPL(kvm_get_kvm); 754EXPORT_SYMBOL_GPL(kvm_get_kvm);
755 755
756void kvm_put_kvm(struct kvm *kvm) 756void kvm_put_kvm(struct kvm *kvm)
757{ 757{
758 if (atomic_dec_and_test(&kvm->users_count)) 758 if (refcount_dec_and_test(&kvm->users_count))
759 kvm_destroy_vm(kvm); 759 kvm_destroy_vm(kvm);
760} 760}
761EXPORT_SYMBOL_GPL(kvm_put_kvm); 761EXPORT_SYMBOL_GPL(kvm_put_kvm);
@@ -3641,7 +3641,7 @@ static int kvm_debugfs_open(struct inode *inode, struct file *file,
3641 * To avoid the race between open and the removal of the debugfs 3641 * To avoid the race between open and the removal of the debugfs
3642 * directory we test against the users count. 3642 * directory we test against the users count.
3643 */ 3643 */
3644 if (!atomic_add_unless(&stat_data->kvm->users_count, 1, 0)) 3644 if (!refcount_inc_not_zero(&stat_data->kvm->users_count))
3645 return -ENOENT; 3645 return -ENOENT;
3646 3646
3647 if (simple_attr_open(inode, file, get, set, fmt)) { 3647 if (simple_attr_open(inode, file, get, set, fmt)) {