Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull kvm fixes from Paolo Bonzini:
"x86:

- Do not register IRQ bypass consumer if posted interrupts not
supported

- Fix missed device interrupt due to non-atomic update of IRR

- Use GFP_KERNEL_ACCOUNT for pid_table in ipiv

- Make VMREAD error path play nice with noinstr

- x86: Acquire SRCU read lock when handling fastpath MSR writes

- Support linking rseq tests statically against glibc 2.35+

- Fix reference count for stats file descriptors

- Detect userspace setting invalid CR0

Non-KVM:

- Remove coccinelle script that has caused multiple confusion
("debugfs, coccinelle: check for obsolete DEFINE_SIMPLE_ATTRIBUTE()
usage", acked by Greg)"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (21 commits)
KVM: selftests: Expand x86's sregs test to cover illegal CR0 values
KVM: VMX: Don't fudge CR0 and CR4 for restricted L2 guest
KVM: x86: Disallow KVM_SET_SREGS{2} if incoming CR0 is invalid
Revert "debugfs, coccinelle: check for obsolete DEFINE_SIMPLE_ATTRIBUTE() usage"
KVM: selftests: Verify stats fd is usable after VM fd has been closed
KVM: selftests: Verify stats fd can be dup()'d and read
KVM: selftests: Verify userspace can create "redundant" binary stats files
KVM: selftests: Explicitly free vcpus array in binary stats test
KVM: selftests: Clean up stats fd in common stats_test() helper
KVM: selftests: Use pread() to read binary stats header
KVM: Grab a reference to KVM for VM and vCPU stats file descriptors
selftests/rseq: Play nice with binaries statically linked against glibc 2.35+
Revert "KVM: SVM: Skip WRMSR fastpath on VM-Exit if next RIP isn't valid"
KVM: x86: Acquire SRCU read lock when handling fastpath MSR writes
KVM: VMX: Use vmread_error() to report VM-Fail in "goto" path
KVM: VMX: Make VMREAD error path play nice with noinstr
KVM: x86/irq: Conditionally register IRQ bypass consumer again
KVM: X86: Use GFP_KERNEL_ACCOUNT for pid_table in ipiv
KVM: x86: check the kvm_cpu_get_interrupt result before using it
KVM: x86: VMX: set irr_pending in kvm_apic_update_irr
...

+256 -187
+1
arch/x86/include/asm/kvm-x86-ops.h
··· 37 37 KVM_X86_OP(get_cpl) 38 38 KVM_X86_OP(set_segment) 39 39 KVM_X86_OP(get_cs_db_l_bits) 40 + KVM_X86_OP(is_valid_cr0) 40 41 KVM_X86_OP(set_cr0) 41 42 KVM_X86_OP_OPTIONAL(post_set_cr3) 42 43 KVM_X86_OP(is_valid_cr4)
+2 -1
arch/x86/include/asm/kvm_host.h
··· 1566 1566 void (*set_segment)(struct kvm_vcpu *vcpu, 1567 1567 struct kvm_segment *var, int seg); 1568 1568 void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); 1569 + bool (*is_valid_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); 1569 1570 void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); 1570 1571 void (*post_set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3); 1571 - bool (*is_valid_cr4)(struct kvm_vcpu *vcpu, unsigned long cr0); 1572 + bool (*is_valid_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4); 1572 1573 void (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4); 1573 1574 int (*set_efer)(struct kvm_vcpu *vcpu, u64 efer); 1574 1575 void (*get_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt);
+17 -8
arch/x86/kvm/lapic.c
··· 637 637 *max_irr = -1; 638 638 639 639 for (i = vec = 0; i <= 7; i++, vec += 32) { 640 + u32 *p_irr = (u32 *)(regs + APIC_IRR + i * 0x10); 641 + 642 + irr_val = *p_irr; 640 643 pir_val = READ_ONCE(pir[i]); 641 - irr_val = *((u32 *)(regs + APIC_IRR + i * 0x10)); 644 + 642 645 if (pir_val) { 646 + pir_val = xchg(&pir[i], 0); 647 + 643 648 prev_irr_val = irr_val; 644 - irr_val |= xchg(&pir[i], 0); 645 - *((u32 *)(regs + APIC_IRR + i * 0x10)) = irr_val; 646 - if (prev_irr_val != irr_val) { 647 - max_updated_irr = 648 - __fls(irr_val ^ prev_irr_val) + vec; 649 - } 649 + do { 650 + irr_val = prev_irr_val | pir_val; 651 + } while (prev_irr_val != irr_val && 652 + !try_cmpxchg(p_irr, &prev_irr_val, irr_val)); 653 + 654 + if (prev_irr_val != irr_val) 655 + max_updated_irr = __fls(irr_val ^ prev_irr_val) + vec; 650 656 } 651 657 if (irr_val) 652 658 *max_irr = __fls(irr_val) + vec; ··· 666 660 bool kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir, int *max_irr) 667 661 { 668 662 struct kvm_lapic *apic = vcpu->arch.apic; 663 + bool irr_updated = __kvm_apic_update_irr(pir, apic->regs, max_irr); 669 664 670 - return __kvm_apic_update_irr(pir, apic->regs, max_irr); 665 + if (unlikely(!apic->apicv_active && irr_updated)) 666 + apic->irr_pending = true; 667 + return irr_updated; 671 668 } 672 669 EXPORT_SYMBOL_GPL(kvm_apic_update_irr); 673 670
+8 -8
arch/x86/kvm/svm/svm.c
··· 1786 1786 } 1787 1787 } 1788 1788 1789 + static bool svm_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) 1790 + { 1791 + return true; 1792 + } 1793 + 1789 1794 void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) 1790 1795 { 1791 1796 struct vcpu_svm *svm = to_svm(vcpu); ··· 3991 3986 3992 3987 static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu) 3993 3988 { 3994 - struct vmcb_control_area *control = &to_svm(vcpu)->vmcb->control; 3995 - 3996 - /* 3997 - * Note, the next RIP must be provided as SRCU isn't held, i.e. KVM 3998 - * can't read guest memory (dereference memslots) to decode the WRMSR. 3999 - */ 4000 - if (control->exit_code == SVM_EXIT_MSR && control->exit_info_1 && 4001 - nrips && control->next_rip) 3989 + if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR && 3990 + to_svm(vcpu)->vmcb->control.exit_info_1) 4002 3991 return handle_fastpath_set_msr_irqoff(vcpu); 4003 3992 4004 3993 return EXIT_FASTPATH_NONE; ··· 4814 4815 .set_segment = svm_set_segment, 4815 4816 .get_cpl = svm_get_cpl, 4816 4817 .get_cs_db_l_bits = svm_get_cs_db_l_bits, 4818 + .is_valid_cr0 = svm_is_valid_cr0, 4817 4819 .set_cr0 = svm_set_cr0, 4818 4820 .post_set_cr3 = sev_post_set_cr3, 4819 4821 .is_valid_cr4 = svm_is_valid_cr4,
+4 -4
arch/x86/kvm/vmx/vmenter.S
··· 303 303 VMX_DO_EVENT_IRQOFF call asm_exc_nmi_kvm_vmx 304 304 SYM_FUNC_END(vmx_do_nmi_irqoff) 305 305 306 - 307 - .section .text, "ax" 308 - 309 306 #ifndef CONFIG_CC_HAS_ASM_GOTO_OUTPUT 307 + 310 308 /** 311 309 * vmread_error_trampoline - Trampoline from inline asm to vmread_error() 312 310 * @field: VMCS field encoding that failed ··· 333 335 mov 3*WORD_SIZE(%_ASM_BP), %_ASM_ARG2 334 336 mov 2*WORD_SIZE(%_ASM_BP), %_ASM_ARG1 335 337 336 - call vmread_error 338 + call vmread_error_trampoline2 337 339 338 340 /* Zero out @fault, which will be popped into the result register. */ 339 341 _ASM_MOV $0, 3*WORD_SIZE(%_ASM_BP) ··· 354 356 RET 355 357 SYM_FUNC_END(vmread_error_trampoline) 356 358 #endif 359 + 360 + .section .text, "ax" 357 361 358 362 SYM_FUNC_START(vmx_do_interrupt_irqoff) 359 363 VMX_DO_EVENT_IRQOFF CALL_NOSPEC _ASM_ARG1
+47 -17
arch/x86/kvm/vmx/vmx.c
··· 441 441 pr_warn_ratelimited(fmt); \ 442 442 } while (0) 443 443 444 - void vmread_error(unsigned long field, bool fault) 444 + noinline void vmread_error(unsigned long field) 445 445 { 446 - if (fault) 447 - kvm_spurious_fault(); 448 - else 449 - vmx_insn_failed("vmread failed: field=%lx\n", field); 446 + vmx_insn_failed("vmread failed: field=%lx\n", field); 450 447 } 448 + 449 + #ifndef CONFIG_CC_HAS_ASM_GOTO_OUTPUT 450 + noinstr void vmread_error_trampoline2(unsigned long field, bool fault) 451 + { 452 + if (fault) { 453 + kvm_spurious_fault(); 454 + } else { 455 + instrumentation_begin(); 456 + vmread_error(field); 457 + instrumentation_end(); 458 + } 459 + } 460 + #endif 451 461 452 462 noinline void vmwrite_error(unsigned long field, unsigned long value) 453 463 { ··· 1513 1503 struct vcpu_vmx *vmx = to_vmx(vcpu); 1514 1504 unsigned long old_rflags; 1515 1505 1506 + /* 1507 + * Unlike CR0 and CR4, RFLAGS handling requires checking if the vCPU 1508 + * is an unrestricted guest in order to mark L2 as needing emulation 1509 + * if L1 runs L2 as a restricted guest. 1510 + */ 1516 1511 if (is_unrestricted_guest(vcpu)) { 1517 1512 kvm_register_mark_available(vcpu, VCPU_EXREG_RFLAGS); 1518 1513 vmx->rflags = rflags; ··· 3052 3037 struct vcpu_vmx *vmx = to_vmx(vcpu); 3053 3038 struct kvm_vmx *kvm_vmx = to_kvm_vmx(vcpu->kvm); 3054 3039 3040 + /* 3041 + * KVM should never use VM86 to virtualize Real Mode when L2 is active, 3042 + * as using VM86 is unnecessary if unrestricted guest is enabled, and 3043 + * if unrestricted guest is disabled, VM-Enter (from L1) with CR0.PG=0 3044 + * should VM-Fail and KVM should reject userspace attempts to stuff 3045 + * CR0.PG=0 when L2 is active. 3046 + */ 3047 + WARN_ON_ONCE(is_guest_mode(vcpu)); 3048 + 3055 3049 vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_TR], VCPU_SREG_TR); 3056 3050 vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_ES], VCPU_SREG_ES); 3057 3051 vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_DS], VCPU_SREG_DS); ··· 3250 3226 #define CR3_EXITING_BITS (CPU_BASED_CR3_LOAD_EXITING | \ 3251 3227 CPU_BASED_CR3_STORE_EXITING) 3252 3228 3229 + static bool vmx_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) 3230 + { 3231 + if (is_guest_mode(vcpu)) 3232 + return nested_guest_cr0_valid(vcpu, cr0); 3233 + 3234 + if (to_vmx(vcpu)->nested.vmxon) 3235 + return nested_host_cr0_valid(vcpu, cr0); 3236 + 3237 + return true; 3238 + } 3239 + 3253 3240 void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) 3254 3241 { 3255 3242 struct vcpu_vmx *vmx = to_vmx(vcpu); ··· 3270 3235 old_cr0_pg = kvm_read_cr0_bits(vcpu, X86_CR0_PG); 3271 3236 3272 3237 hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF); 3273 - if (is_unrestricted_guest(vcpu)) 3238 + if (enable_unrestricted_guest) 3274 3239 hw_cr0 |= KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST; 3275 3240 else { 3276 3241 hw_cr0 |= KVM_VM_CR0_ALWAYS_ON; ··· 3298 3263 } 3299 3264 #endif 3300 3265 3301 - if (enable_ept && !is_unrestricted_guest(vcpu)) { 3266 + if (enable_ept && !enable_unrestricted_guest) { 3302 3267 /* 3303 3268 * Ensure KVM has an up-to-date snapshot of the guest's CR3. If 3304 3269 * the below code _enables_ CR3 exiting, vmx_cache_reg() will ··· 3429 3394 * this bit, even if host CR4.MCE == 0. 3430 3395 */ 3431 3396 hw_cr4 = (cr4_read_shadow() & X86_CR4_MCE) | (cr4 & ~X86_CR4_MCE); 3432 - if (is_unrestricted_guest(vcpu)) 3397 + if (enable_unrestricted_guest) 3433 3398 hw_cr4 |= KVM_VM_CR4_ALWAYS_ON_UNRESTRICTED_GUEST; 3434 3399 else if (vmx->rmode.vm86_active) 3435 3400 hw_cr4 |= KVM_RMODE_VM_CR4_ALWAYS_ON; ··· 3449 3414 vcpu->arch.cr4 = cr4; 3450 3415 kvm_register_mark_available(vcpu, VCPU_EXREG_CR4); 3451 3416 3452 - if (!is_unrestricted_guest(vcpu)) { 3417 + if (!enable_unrestricted_guest) { 3453 3418 if (enable_ept) { 3454 3419 if (!is_paging(vcpu)) { 3455 3420 hw_cr4 &= ~X86_CR4_PAE; ··· 4686 4651 if (kvm_vmx->pid_table) 4687 4652 return 0; 4688 4653 4689 - pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, vmx_get_pid_table_order(kvm)); 4654 + pages = alloc_pages(GFP_KERNEL_ACCOUNT | __GFP_ZERO, 4655 + vmx_get_pid_table_order(kvm)); 4690 4656 if (!pages) 4691 4657 return -ENOMEM; 4692 4658 ··· 5400 5364 val = (val & ~vmcs12->cr0_guest_host_mask) | 5401 5365 (vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask); 5402 5366 5403 - if (!nested_guest_cr0_valid(vcpu, val)) 5404 - return 1; 5405 - 5406 5367 if (kvm_set_cr0(vcpu, val)) 5407 5368 return 1; 5408 5369 vmcs_writel(CR0_READ_SHADOW, orig_val); 5409 5370 return 0; 5410 5371 } else { 5411 - if (to_vmx(vcpu)->nested.vmxon && 5412 - !nested_host_cr0_valid(vcpu, val)) 5413 - return 1; 5414 - 5415 5372 return kvm_set_cr0(vcpu, val); 5416 5373 } 5417 5374 } ··· 8232 8203 .set_segment = vmx_set_segment, 8233 8204 .get_cpl = vmx_get_cpl, 8234 8205 .get_cs_db_l_bits = vmx_get_cs_db_l_bits, 8206 + .is_valid_cr0 = vmx_is_valid_cr0, 8235 8207 .set_cr0 = vmx_set_cr0, 8236 8208 .is_valid_cr4 = vmx_is_valid_cr4, 8237 8209 .set_cr4 = vmx_set_cr4,
+9 -3
arch/x86/kvm/vmx/vmx_ops.h
··· 10 10 #include "vmcs.h" 11 11 #include "../x86.h" 12 12 13 - void vmread_error(unsigned long field, bool fault); 13 + void vmread_error(unsigned long field); 14 14 void vmwrite_error(unsigned long field, unsigned long value); 15 15 void vmclear_error(struct vmcs *vmcs, u64 phys_addr); 16 16 void vmptrld_error(struct vmcs *vmcs, u64 phys_addr); ··· 31 31 * void vmread_error_trampoline(unsigned long field, bool fault); 32 32 */ 33 33 extern unsigned long vmread_error_trampoline; 34 + 35 + /* 36 + * The second VMREAD error trampoline, called from the assembly trampoline, 37 + * exists primarily to enable instrumentation for the VM-Fail path. 38 + */ 39 + void vmread_error_trampoline2(unsigned long field, bool fault); 40 + 34 41 #endif 35 42 36 43 static __always_inline void vmcs_check16(unsigned long field) ··· 108 101 109 102 do_fail: 110 103 instrumentation_begin(); 111 - WARN_ONCE(1, KBUILD_MODNAME ": vmread failed: field=%lx\n", field); 112 - pr_warn_ratelimited(KBUILD_MODNAME ": vmread failed: field=%lx\n", field); 104 + vmread_error(field); 113 105 instrumentation_end(); 114 106 return 0; 115 107
+34 -16
arch/x86/kvm/x86.c
··· 906 906 } 907 907 EXPORT_SYMBOL_GPL(load_pdptrs); 908 908 909 + static bool kvm_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) 910 + { 911 + #ifdef CONFIG_X86_64 912 + if (cr0 & 0xffffffff00000000UL) 913 + return false; 914 + #endif 915 + 916 + if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) 917 + return false; 918 + 919 + if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) 920 + return false; 921 + 922 + return static_call(kvm_x86_is_valid_cr0)(vcpu, cr0); 923 + } 924 + 909 925 void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0) 910 926 { 911 927 /* ··· 968 952 { 969 953 unsigned long old_cr0 = kvm_read_cr0(vcpu); 970 954 955 + if (!kvm_is_valid_cr0(vcpu, cr0)) 956 + return 1; 957 + 971 958 cr0 |= X86_CR0_ET; 972 959 973 - #ifdef CONFIG_X86_64 974 - if (cr0 & 0xffffffff00000000UL) 975 - return 1; 976 - #endif 977 - 960 + /* Write to CR0 reserved bits are ignored, even on Intel. */ 978 961 cr0 &= ~CR0_RESERVED_BITS; 979 - 980 - if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) 981 - return 1; 982 - 983 - if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) 984 - return 1; 985 962 986 963 #ifdef CONFIG_X86_64 987 964 if ((vcpu->arch.efer & EFER_LME) && !is_paging(vcpu) && ··· 2181 2172 u64 data; 2182 2173 fastpath_t ret = EXIT_FASTPATH_NONE; 2183 2174 2175 + kvm_vcpu_srcu_read_lock(vcpu); 2176 + 2184 2177 switch (msr) { 2185 2178 case APIC_BASE_MSR + (APIC_ICR >> 4): 2186 2179 data = kvm_read_edx_eax(vcpu); ··· 2204 2193 2205 2194 if (ret != EXIT_FASTPATH_NONE) 2206 2195 trace_kvm_msr_write(msr, data); 2196 + 2197 + kvm_vcpu_srcu_read_unlock(vcpu); 2207 2198 2208 2199 return ret; 2209 2200 } ··· 10216 10203 if (r < 0) 10217 10204 goto out; 10218 10205 if (r) { 10219 - kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), false); 10220 - static_call(kvm_x86_inject_irq)(vcpu, false); 10221 - WARN_ON(static_call(kvm_x86_interrupt_allowed)(vcpu, true) < 0); 10206 + int irq = kvm_cpu_get_interrupt(vcpu); 10207 + 10208 + if (!WARN_ON_ONCE(irq == -1)) { 10209 + kvm_queue_interrupt(vcpu, irq, false); 10210 + static_call(kvm_x86_inject_irq)(vcpu, false); 10211 + WARN_ON(static_call(kvm_x86_interrupt_allowed)(vcpu, true) < 0); 10212 + } 10222 10213 } 10223 10214 if (kvm_cpu_has_injectable_intr(vcpu)) 10224 10215 static_call(kvm_x86_enable_irq_window)(vcpu); ··· 11477 11460 return false; 11478 11461 } 11479 11462 11480 - return kvm_is_valid_cr4(vcpu, sregs->cr4); 11463 + return kvm_is_valid_cr4(vcpu, sregs->cr4) && 11464 + kvm_is_valid_cr0(vcpu, sregs->cr0); 11481 11465 } 11482 11466 11483 11467 static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs, ··· 13203 13185 13204 13186 bool kvm_arch_has_irq_bypass(void) 13205 13187 { 13206 - return true; 13188 + return enable_apicv && irq_remapping_cap(IRQ_POSTING_CAP); 13207 13189 } 13208 13190 13209 13191 int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
-68
scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /// Use DEFINE_DEBUGFS_ATTRIBUTE rather than DEFINE_SIMPLE_ATTRIBUTE 3 - /// for debugfs files. 4 - /// 5 - //# Rationale: DEFINE_SIMPLE_ATTRIBUTE + debugfs_create_file() 6 - //# imposes some significant overhead as compared to 7 - //# DEFINE_DEBUGFS_ATTRIBUTE + debugfs_create_file_unsafe(). 8 - // 9 - // Copyright (C): 2016 Nicolai Stange 10 - // Options: --no-includes 11 - // 12 - 13 - virtual context 14 - virtual patch 15 - virtual org 16 - virtual report 17 - 18 - @dsa@ 19 - declarer name DEFINE_SIMPLE_ATTRIBUTE; 20 - identifier dsa_fops; 21 - expression dsa_get, dsa_set, dsa_fmt; 22 - position p; 23 - @@ 24 - DEFINE_SIMPLE_ATTRIBUTE@p(dsa_fops, dsa_get, dsa_set, dsa_fmt); 25 - 26 - @dcf@ 27 - expression name, mode, parent, data; 28 - identifier dsa.dsa_fops; 29 - @@ 30 - debugfs_create_file(name, mode, parent, data, &dsa_fops) 31 - 32 - 33 - @context_dsa depends on context && dcf@ 34 - declarer name DEFINE_DEBUGFS_ATTRIBUTE; 35 - identifier dsa.dsa_fops; 36 - expression dsa.dsa_get, dsa.dsa_set, dsa.dsa_fmt; 37 - @@ 38 - * DEFINE_SIMPLE_ATTRIBUTE(dsa_fops, dsa_get, dsa_set, dsa_fmt); 39 - 40 - 41 - @patch_dcf depends on patch expression@ 42 - expression name, mode, parent, data; 43 - identifier dsa.dsa_fops; 44 - @@ 45 - - debugfs_create_file(name, mode, parent, data, &dsa_fops) 46 - + debugfs_create_file_unsafe(name, mode, parent, data, &dsa_fops) 47 - 48 - @patch_dsa depends on patch_dcf && patch@ 49 - identifier dsa.dsa_fops; 50 - expression dsa.dsa_get, dsa.dsa_set, dsa.dsa_fmt; 51 - @@ 52 - - DEFINE_SIMPLE_ATTRIBUTE(dsa_fops, dsa_get, dsa_set, dsa_fmt); 53 - + DEFINE_DEBUGFS_ATTRIBUTE(dsa_fops, dsa_get, dsa_set, dsa_fmt); 54 - 55 - 56 - @script:python depends on org && dcf@ 57 - fops << dsa.dsa_fops; 58 - p << dsa.p; 59 - @@ 60 - msg="%s should be defined with DEFINE_DEBUGFS_ATTRIBUTE" % (fops) 61 - coccilib.org.print_todo(p[0], msg) 62 - 63 - @script:python depends on report && dcf@ 64 - fops << dsa.dsa_fops; 65 - p << dsa.p; 66 - @@ 67 - msg="WARNING: %s should be defined with DEFINE_DEBUGFS_ATTRIBUTE" % (fops) 68 - coccilib.report.print_report(p[0], msg)
+4 -2
tools/testing/selftests/kvm/include/kvm_util_base.h
··· 362 362 { 363 363 ssize_t ret; 364 364 365 - ret = read(stats_fd, header, sizeof(*header)); 366 - TEST_ASSERT(ret == sizeof(*header), "Read stats header"); 365 + ret = pread(stats_fd, header, sizeof(*header), 0); 366 + TEST_ASSERT(ret == sizeof(*header), 367 + "Failed to read '%lu' header bytes, ret = '%ld'", 368 + sizeof(*header), ret); 367 369 } 368 370 369 371 struct kvm_stats_desc *read_stats_descriptors(int stats_fd,
+45 -23
tools/testing/selftests/kvm/kvm_binary_stats_test.c
··· 43 43 id = malloc(header.name_size); 44 44 TEST_ASSERT(id, "Allocate memory for id string"); 45 45 46 - ret = read(stats_fd, id, header.name_size); 47 - TEST_ASSERT(ret == header.name_size, "Read id string"); 46 + ret = pread(stats_fd, id, header.name_size, sizeof(header)); 47 + TEST_ASSERT(ret == header.name_size, 48 + "Expected header size '%u', read '%lu' bytes", 49 + header.name_size, ret); 48 50 49 51 /* Check id string, that should start with "kvm" */ 50 52 TEST_ASSERT(!strncmp(id, "kvm", 3) && strlen(id) < header.name_size, ··· 167 165 free(stats_data); 168 166 free(stats_desc); 169 167 free(id); 170 - } 171 168 172 - 173 - static void vm_stats_test(struct kvm_vm *vm) 174 - { 175 - int stats_fd = vm_get_stats_fd(vm); 176 - 177 - stats_test(stats_fd); 178 - close(stats_fd); 179 - TEST_ASSERT(fcntl(stats_fd, F_GETFD) == -1, "Stats fd not freed"); 180 - } 181 - 182 - static void vcpu_stats_test(struct kvm_vcpu *vcpu) 183 - { 184 - int stats_fd = vcpu_get_stats_fd(vcpu); 185 - 186 - stats_test(stats_fd); 187 169 close(stats_fd); 188 170 TEST_ASSERT(fcntl(stats_fd, F_GETFD) == -1, "Stats fd not freed"); 189 171 } ··· 185 199 186 200 int main(int argc, char *argv[]) 187 201 { 202 + int vm_stats_fds, *vcpu_stats_fds; 188 203 int i, j; 189 204 struct kvm_vcpu **vcpus; 190 205 struct kvm_vm **vms; ··· 218 231 vcpus = malloc(sizeof(struct kvm_vcpu *) * max_vm * max_vcpu); 219 232 TEST_ASSERT(vcpus, "Allocate memory for storing vCPU pointers"); 220 233 234 + /* 235 + * Not per-VM as the array is populated, used, and invalidated within a 236 + * single for-loop iteration. 237 + */ 238 + vcpu_stats_fds = calloc(max_vm, sizeof(*vcpu_stats_fds)); 239 + TEST_ASSERT(vcpu_stats_fds, "Allocate memory for VM stats fds"); 240 + 221 241 for (i = 0; i < max_vm; ++i) { 222 242 vms[i] = vm_create_barebones(); 223 243 for (j = 0; j < max_vcpu; ++j) 224 244 vcpus[i * max_vcpu + j] = __vm_vcpu_add(vms[i], j); 225 245 } 226 246 227 - /* Check stats read for every VM and VCPU */ 247 + /* 248 + * Check stats read for every VM and vCPU, with a variety of flavors. 249 + * Note, stats_test() closes the passed in stats fd. 250 + */ 228 251 for (i = 0; i < max_vm; ++i) { 229 - vm_stats_test(vms[i]); 252 + /* 253 + * Verify that creating multiple userspace references to a 254 + * single stats file works and doesn't cause explosions. 255 + */ 256 + vm_stats_fds = vm_get_stats_fd(vms[i]); 257 + stats_test(dup(vm_stats_fds)); 258 + 259 + /* Verify userspace can instantiate multiple stats files. */ 260 + stats_test(vm_get_stats_fd(vms[i])); 261 + 262 + for (j = 0; j < max_vcpu; ++j) { 263 + vcpu_stats_fds[j] = vcpu_get_stats_fd(vcpus[i * max_vcpu + j]); 264 + stats_test(dup(vcpu_stats_fds[j])); 265 + stats_test(vcpu_get_stats_fd(vcpus[i * max_vcpu + j])); 266 + } 267 + 268 + /* 269 + * Close the VM fd and redo the stats tests. KVM should gift a 270 + * reference (to the VM) to each stats fd, i.e. stats should 271 + * still be accessible even after userspace has put its last 272 + * _direct_ reference to the VM. 273 + */ 274 + kvm_vm_free(vms[i]); 275 + 276 + stats_test(vm_stats_fds); 230 277 for (j = 0; j < max_vcpu; ++j) 231 - vcpu_stats_test(vcpus[i * max_vcpu + j]); 278 + stats_test(vcpu_stats_fds[j]); 279 + 232 280 ksft_test_result_pass("vm%i\n", i); 233 281 } 234 282 235 - for (i = 0; i < max_vm; ++i) 236 - kvm_vm_free(vms[i]); 237 283 free(vms); 284 + free(vcpus); 285 + free(vcpu_stats_fds); 238 286 239 287 ksft_finished(); /* Print results and exit() accordingly */ 240 288 }
+39 -31
tools/testing/selftests/kvm/x86_64/set_sregs_test.c
··· 22 22 #include "kvm_util.h" 23 23 #include "processor.h" 24 24 25 - static void test_cr4_feature_bit(struct kvm_vcpu *vcpu, struct kvm_sregs *orig, 26 - uint64_t feature_bit) 27 - { 28 - struct kvm_sregs sregs; 29 - int rc; 30 - 31 - /* Skip the sub-test, the feature is supported. */ 32 - if (orig->cr4 & feature_bit) 33 - return; 34 - 35 - memcpy(&sregs, orig, sizeof(sregs)); 36 - sregs.cr4 |= feature_bit; 37 - 38 - rc = _vcpu_sregs_set(vcpu, &sregs); 39 - TEST_ASSERT(rc, "KVM allowed unsupported CR4 bit (0x%lx)", feature_bit); 40 - 41 - /* Sanity check that KVM didn't change anything. */ 42 - vcpu_sregs_get(vcpu, &sregs); 43 - TEST_ASSERT(!memcmp(&sregs, orig, sizeof(sregs)), "KVM modified sregs"); 44 - } 25 + #define TEST_INVALID_CR_BIT(vcpu, cr, orig, bit) \ 26 + do { \ 27 + struct kvm_sregs new; \ 28 + int rc; \ 29 + \ 30 + /* Skip the sub-test, the feature/bit is supported. */ \ 31 + if (orig.cr & bit) \ 32 + break; \ 33 + \ 34 + memcpy(&new, &orig, sizeof(sregs)); \ 35 + new.cr |= bit; \ 36 + \ 37 + rc = _vcpu_sregs_set(vcpu, &new); \ 38 + TEST_ASSERT(rc, "KVM allowed invalid " #cr " bit (0x%lx)", bit); \ 39 + \ 40 + /* Sanity check that KVM didn't change anything. */ \ 41 + vcpu_sregs_get(vcpu, &new); \ 42 + TEST_ASSERT(!memcmp(&new, &orig, sizeof(new)), "KVM modified sregs"); \ 43 + } while (0) 45 44 46 45 static uint64_t calc_supported_cr4_feature_bits(void) 47 46 { ··· 79 80 struct kvm_vcpu *vcpu; 80 81 struct kvm_vm *vm; 81 82 uint64_t cr4; 82 - int rc; 83 + int rc, i; 83 84 84 85 /* 85 86 * Create a dummy VM, specifically to avoid doing KVM_SET_CPUID2, and ··· 91 92 92 93 vcpu_sregs_get(vcpu, &sregs); 93 94 95 + sregs.cr0 = 0; 94 96 sregs.cr4 |= calc_supported_cr4_feature_bits(); 95 97 cr4 = sregs.cr4; 96 98 ··· 103 103 sregs.cr4, cr4); 104 104 105 105 /* Verify all unsupported features are rejected by KVM. */ 106 - test_cr4_feature_bit(vcpu, &sregs, X86_CR4_UMIP); 107 - test_cr4_feature_bit(vcpu, &sregs, X86_CR4_LA57); 108 - test_cr4_feature_bit(vcpu, &sregs, X86_CR4_VMXE); 109 - test_cr4_feature_bit(vcpu, &sregs, X86_CR4_SMXE); 110 - test_cr4_feature_bit(vcpu, &sregs, X86_CR4_FSGSBASE); 111 - test_cr4_feature_bit(vcpu, &sregs, X86_CR4_PCIDE); 112 - test_cr4_feature_bit(vcpu, &sregs, X86_CR4_OSXSAVE); 113 - test_cr4_feature_bit(vcpu, &sregs, X86_CR4_SMEP); 114 - test_cr4_feature_bit(vcpu, &sregs, X86_CR4_SMAP); 115 - test_cr4_feature_bit(vcpu, &sregs, X86_CR4_PKE); 106 + TEST_INVALID_CR_BIT(vcpu, cr4, sregs, X86_CR4_UMIP); 107 + TEST_INVALID_CR_BIT(vcpu, cr4, sregs, X86_CR4_LA57); 108 + TEST_INVALID_CR_BIT(vcpu, cr4, sregs, X86_CR4_VMXE); 109 + TEST_INVALID_CR_BIT(vcpu, cr4, sregs, X86_CR4_SMXE); 110 + TEST_INVALID_CR_BIT(vcpu, cr4, sregs, X86_CR4_FSGSBASE); 111 + TEST_INVALID_CR_BIT(vcpu, cr4, sregs, X86_CR4_PCIDE); 112 + TEST_INVALID_CR_BIT(vcpu, cr4, sregs, X86_CR4_OSXSAVE); 113 + TEST_INVALID_CR_BIT(vcpu, cr4, sregs, X86_CR4_SMEP); 114 + TEST_INVALID_CR_BIT(vcpu, cr4, sregs, X86_CR4_SMAP); 115 + TEST_INVALID_CR_BIT(vcpu, cr4, sregs, X86_CR4_PKE); 116 + 117 + for (i = 32; i < 64; i++) 118 + TEST_INVALID_CR_BIT(vcpu, cr0, sregs, BIT(i)); 119 + 120 + /* NW without CD is illegal, as is PG without PE. */ 121 + TEST_INVALID_CR_BIT(vcpu, cr0, sregs, X86_CR0_NW); 122 + TEST_INVALID_CR_BIT(vcpu, cr0, sregs, X86_CR0_PG); 123 + 116 124 kvm_vm_free(vm); 117 125 118 126 /* Create a "real" VM and verify APIC_BASE can be set. */
+22 -6
tools/testing/selftests/rseq/rseq.c
··· 34 34 #include "../kselftest.h" 35 35 #include "rseq.h" 36 36 37 - static const ptrdiff_t *libc_rseq_offset_p; 38 - static const unsigned int *libc_rseq_size_p; 39 - static const unsigned int *libc_rseq_flags_p; 37 + /* 38 + * Define weak versions to play nice with binaries that are statically linked 39 + * against a libc that doesn't support registering its own rseq. 40 + */ 41 + __weak ptrdiff_t __rseq_offset; 42 + __weak unsigned int __rseq_size; 43 + __weak unsigned int __rseq_flags; 44 + 45 + static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset; 46 + static const unsigned int *libc_rseq_size_p = &__rseq_size; 47 + static const unsigned int *libc_rseq_flags_p = &__rseq_flags; 40 48 41 49 /* Offset from the thread pointer to the rseq area. */ 42 50 ptrdiff_t rseq_offset; ··· 163 155 static __attribute__((constructor)) 164 156 void rseq_init(void) 165 157 { 166 - libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset"); 167 - libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size"); 168 - libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags"); 158 + /* 159 + * If the libc's registered rseq size isn't already valid, it may be 160 + * because the binary is dynamically linked and not necessarily due to 161 + * libc not having registered a restartable sequence. Try to find the 162 + * symbols if that's the case. 163 + */ 164 + if (!*libc_rseq_size_p) { 165 + libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset"); 166 + libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size"); 167 + libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags"); 168 + } 169 169 if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p && 170 170 *libc_rseq_size_p != 0) { 171 171 /* rseq registration owned by glibc */
+24
virt/kvm/kvm_main.c
··· 4035 4035 sizeof(vcpu->stat), user_buffer, size, offset); 4036 4036 } 4037 4037 4038 + static int kvm_vcpu_stats_release(struct inode *inode, struct file *file) 4039 + { 4040 + struct kvm_vcpu *vcpu = file->private_data; 4041 + 4042 + kvm_put_kvm(vcpu->kvm); 4043 + return 0; 4044 + } 4045 + 4038 4046 static const struct file_operations kvm_vcpu_stats_fops = { 4039 4047 .read = kvm_vcpu_stats_read, 4048 + .release = kvm_vcpu_stats_release, 4040 4049 .llseek = noop_llseek, 4041 4050 }; 4042 4051 ··· 4066 4057 put_unused_fd(fd); 4067 4058 return PTR_ERR(file); 4068 4059 } 4060 + 4061 + kvm_get_kvm(vcpu->kvm); 4062 + 4069 4063 file->f_mode |= FMODE_PREAD; 4070 4064 fd_install(fd, file); 4071 4065 ··· 4713 4701 sizeof(kvm->stat), user_buffer, size, offset); 4714 4702 } 4715 4703 4704 + static int kvm_vm_stats_release(struct inode *inode, struct file *file) 4705 + { 4706 + struct kvm *kvm = file->private_data; 4707 + 4708 + kvm_put_kvm(kvm); 4709 + return 0; 4710 + } 4711 + 4716 4712 static const struct file_operations kvm_vm_stats_fops = { 4717 4713 .read = kvm_vm_stats_read, 4714 + .release = kvm_vm_stats_release, 4718 4715 .llseek = noop_llseek, 4719 4716 }; 4720 4717 ··· 4742 4721 put_unused_fd(fd); 4743 4722 return PTR_ERR(file); 4744 4723 } 4724 + 4725 + kvm_get_kvm(kvm); 4726 + 4745 4727 file->f_mode |= FMODE_PREAD; 4746 4728 fd_install(fd, file); 4747 4729