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 Radim Krčmář:
"ARM:
- Fix for timer setup on VHE machines
- Drop spurious warning when the timer races against the vcpu running
again
- Prevent a vgic deadlock when the initialization fails (for stable)

s390:
- Fix a kernel memory exposure (for stable)

x86:
- Fix exception injection when hypercall instruction cannot be
patched"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
KVM: s390: do not expose random data via facility bitmap
KVM: x86: fix fixing of hypercalls
KVM: arm/arm64: vgic: Fix deadlock on error handling
KVM: arm64: Access CNTHCTL_EL2 bit fields correctly on VHE systems
KVM: arm/arm64: Fix occasional warning from the timer work function

+79 -27
+5
arch/arm/include/asm/virt.h
··· 80 80 return false; 81 81 } 82 82 83 + static inline bool has_vhe(void) 84 + { 85 + return false; 86 + } 87 + 83 88 /* The section containing the hypervisor idmap text */ 84 89 extern char __hyp_idmap_text_start[]; 85 90 extern char __hyp_idmap_text_end[];
+3
arch/arm/kvm/arm.c
··· 1099 1099 __cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr); 1100 1100 __cpu_init_stage2(); 1101 1101 1102 + if (is_kernel_in_hyp_mode()) 1103 + kvm_timer_init_vhe(); 1104 + 1102 1105 kvm_arm_init_debug(); 1103 1106 } 1104 1107
+9
arch/arm64/include/asm/virt.h
··· 47 47 #include <asm/ptrace.h> 48 48 #include <asm/sections.h> 49 49 #include <asm/sysreg.h> 50 + #include <asm/cpufeature.h> 50 51 51 52 /* 52 53 * __boot_cpu_mode records what mode CPUs were booted in. ··· 79 78 static inline bool is_kernel_in_hyp_mode(void) 80 79 { 81 80 return read_sysreg(CurrentEL) == CurrentEL_EL2; 81 + } 82 + 83 + static inline bool has_vhe(void) 84 + { 85 + if (cpus_have_const_cap(ARM64_HAS_VIRT_HOST_EXTN)) 86 + return true; 87 + 88 + return false; 82 89 } 83 90 84 91 #ifdef CONFIG_ARM64_VHE
+2 -2
arch/s390/kvm/kvm-s390.c
··· 916 916 memcpy(&mach->fac_mask, kvm->arch.model.fac_mask, 917 917 S390_ARCH_FAC_LIST_SIZE_BYTE); 918 918 memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list, 919 - S390_ARCH_FAC_LIST_SIZE_BYTE); 919 + sizeof(S390_lowcore.stfle_fac_list)); 920 920 if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach))) 921 921 ret = -EFAULT; 922 922 kfree(mach); ··· 1437 1437 1438 1438 /* Populate the facility mask initially. */ 1439 1439 memcpy(kvm->arch.model.fac_mask, S390_lowcore.stfle_fac_list, 1440 - S390_ARCH_FAC_LIST_SIZE_BYTE); 1440 + sizeof(S390_lowcore.stfle_fac_list)); 1441 1441 for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) { 1442 1442 if (i < kvm_s390_fac_list_mask_size()) 1443 1443 kvm->arch.model.fac_mask[i] &= kvm_s390_fac_list_mask[i];
+2 -1
arch/x86/kvm/x86.c
··· 6171 6171 6172 6172 kvm_x86_ops->patch_hypercall(vcpu, instruction); 6173 6173 6174 - return emulator_write_emulated(ctxt, rip, instruction, 3, NULL); 6174 + return emulator_write_emulated(ctxt, rip, instruction, 3, 6175 + &ctxt->exception); 6175 6176 } 6176 6177 6177 6178 static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu)
+1
include/kvm/arm_arch_timer.h
··· 76 76 77 77 void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu); 78 78 79 + void kvm_timer_init_vhe(void); 79 80 #endif
+23 -3
virt/kvm/arm/arch_timer.c
··· 24 24 25 25 #include <clocksource/arm_arch_timer.h> 26 26 #include <asm/arch_timer.h> 27 + #include <asm/kvm_hyp.h> 27 28 28 29 #include <kvm/arm_vgic.h> 29 30 #include <kvm/arm_arch_timer.h> ··· 90 89 struct kvm_vcpu *vcpu; 91 90 92 91 vcpu = container_of(work, struct kvm_vcpu, arch.timer_cpu.expired); 93 - vcpu->arch.timer_cpu.armed = false; 94 - 95 - WARN_ON(!kvm_timer_should_fire(vcpu)); 96 92 97 93 /* 98 94 * If the vcpu is blocked we want to wake it up so that it will see ··· 509 511 void kvm_timer_init(struct kvm *kvm) 510 512 { 511 513 kvm->arch.timer.cntvoff = kvm_phys_timer_read(); 514 + } 515 + 516 + /* 517 + * On VHE system, we only need to configure trap on physical timer and counter 518 + * accesses in EL0 and EL1 once, not for every world switch. 519 + * The host kernel runs at EL2 with HCR_EL2.TGE == 1, 520 + * and this makes those bits have no effect for the host kernel execution. 521 + */ 522 + void kvm_timer_init_vhe(void) 523 + { 524 + /* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */ 525 + u32 cnthctl_shift = 10; 526 + u64 val; 527 + 528 + /* 529 + * Disallow physical timer access for the guest. 530 + * Physical counter access is allowed. 531 + */ 532 + val = read_sysreg(cnthctl_el2); 533 + val &= ~(CNTHCTL_EL1PCEN << cnthctl_shift); 534 + val |= (CNTHCTL_EL1PCTEN << cnthctl_shift); 535 + write_sysreg(val, cnthctl_el2); 512 536 }
+21 -12
virt/kvm/arm/hyp/timer-sr.c
··· 35 35 /* Disable the virtual timer */ 36 36 write_sysreg_el0(0, cntv_ctl); 37 37 38 - /* Allow physical timer/counter access for the host */ 39 - val = read_sysreg(cnthctl_el2); 40 - val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN; 41 - write_sysreg(val, cnthctl_el2); 38 + /* 39 + * We don't need to do this for VHE since the host kernel runs in EL2 40 + * with HCR_EL2.TGE ==1, which makes those bits have no impact. 41 + */ 42 + if (!has_vhe()) { 43 + /* Allow physical timer/counter access for the host */ 44 + val = read_sysreg(cnthctl_el2); 45 + val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN; 46 + write_sysreg(val, cnthctl_el2); 47 + } 42 48 43 49 /* Clear cntvoff for the host */ 44 50 write_sysreg(0, cntvoff_el2); ··· 56 50 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 57 51 u64 val; 58 52 59 - /* 60 - * Disallow physical timer access for the guest 61 - * Physical counter access is allowed 62 - */ 63 - val = read_sysreg(cnthctl_el2); 64 - val &= ~CNTHCTL_EL1PCEN; 65 - val |= CNTHCTL_EL1PCTEN; 66 - write_sysreg(val, cnthctl_el2); 53 + /* Those bits are already configured at boot on VHE-system */ 54 + if (!has_vhe()) { 55 + /* 56 + * Disallow physical timer access for the guest 57 + * Physical counter access is allowed 58 + */ 59 + val = read_sysreg(cnthctl_el2); 60 + val &= ~CNTHCTL_EL1PCEN; 61 + val |= CNTHCTL_EL1PCTEN; 62 + write_sysreg(val, cnthctl_el2); 63 + } 67 64 68 65 if (timer->enabled) { 69 66 write_sysreg(kvm->arch.timer.cntvoff, cntvoff_el2);
+13 -5
virt/kvm/arm/vgic/vgic-init.c
··· 268 268 { 269 269 struct vgic_dist *dist = &kvm->arch.vgic; 270 270 271 - mutex_lock(&kvm->lock); 272 - 273 271 dist->ready = false; 274 272 dist->initialized = false; 275 273 276 274 kfree(dist->spis); 277 275 dist->nr_spis = 0; 278 - 279 - mutex_unlock(&kvm->lock); 280 276 } 281 277 282 278 void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) ··· 282 286 INIT_LIST_HEAD(&vgic_cpu->ap_list_head); 283 287 } 284 288 285 - void kvm_vgic_destroy(struct kvm *kvm) 289 + /* To be called with kvm->lock held */ 290 + static void __kvm_vgic_destroy(struct kvm *kvm) 286 291 { 287 292 struct kvm_vcpu *vcpu; 288 293 int i; ··· 292 295 293 296 kvm_for_each_vcpu(i, vcpu, kvm) 294 297 kvm_vgic_vcpu_destroy(vcpu); 298 + } 299 + 300 + void kvm_vgic_destroy(struct kvm *kvm) 301 + { 302 + mutex_lock(&kvm->lock); 303 + __kvm_vgic_destroy(kvm); 304 + mutex_unlock(&kvm->lock); 295 305 } 296 306 297 307 /** ··· 352 348 ret = vgic_v2_map_resources(kvm); 353 349 else 354 350 ret = vgic_v3_map_resources(kvm); 351 + 352 + if (ret) 353 + __kvm_vgic_destroy(kvm); 354 + 355 355 out: 356 356 mutex_unlock(&kvm->lock); 357 357 return ret;
-2
virt/kvm/arm/vgic/vgic-v2.c
··· 293 293 dist->ready = true; 294 294 295 295 out: 296 - if (ret) 297 - kvm_vgic_destroy(kvm); 298 296 return ret; 299 297 } 300 298
-2
virt/kvm/arm/vgic/vgic-v3.c
··· 302 302 dist->ready = true; 303 303 304 304 out: 305 - if (ret) 306 - kvm_vgic_destroy(kvm); 307 305 return ret; 308 306 } 309 307