Skip to content

Commit 8155469

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Paolo Bonzini: "s390: - SRCU fix PPC: - host crash fixes x86: - bugfixes, including making nested posted interrupts really work Generic: - tweaks to kvm_stat and to uevents" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: LAPIC: Fix reentrancy issues with preempt notifiers tools/kvm_stat: add '-f help' to get the available event list tools/kvm_stat: use variables instead of hard paths in help output KVM: nVMX: Fix loss of L2's NMI blocking state KVM: nVMX: Fix posted intr delivery when vcpu is in guest mode x86: irq: Define a global vector for nested posted interrupts KVM: x86: do mask out upper bits of PAE CR3 KVM: make pid available for uevents without debugfs KVM: s390: take srcu lock when getting/setting storage keys KVM: VMX: remove unused field KVM: PPC: Book3S HV: Fix host crash on changing HPT size KVM: PPC: Book3S HV: Enable TM before accessing TM registers
2 parents 8562e89 + 7b5e0a4 commit 8155469

File tree

16 files changed

+99
-49
lines changed

16 files changed

+99
-49
lines changed

arch/powerpc/kvm/book3s_64_mmu_hv.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,10 @@ long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order)
164164
goto out;
165165
}
166166

167-
if (kvm->arch.hpt.virt)
167+
if (kvm->arch.hpt.virt) {
168168
kvmppc_free_hpt(&kvm->arch.hpt);
169+
kvmppc_rmap_reset(kvm);
170+
}
169171

170172
err = kvmppc_allocate_hpt(&info, order);
171173
if (err < 0)

arch/powerpc/kvm/book3s_hv.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3211,6 +3211,8 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
32113211
run->fail_entry.hardware_entry_failure_reason = 0;
32123212
return -EINVAL;
32133213
}
3214+
/* Enable TM so we can read the TM SPRs */
3215+
mtmsr(mfmsr() | MSR_TM);
32143216
current->thread.tm_tfhar = mfspr(SPRN_TFHAR);
32153217
current->thread.tm_tfiar = mfspr(SPRN_TFIAR);
32163218
current->thread.tm_texasr = mfspr(SPRN_TEXASR);

arch/s390/kvm/kvm-s390.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
13241324
{
13251325
uint8_t *keys;
13261326
uint64_t hva;
1327-
int i, r = 0;
1327+
int srcu_idx, i, r = 0;
13281328

13291329
if (args->flags != 0)
13301330
return -EINVAL;
@@ -1342,6 +1342,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
13421342
return -ENOMEM;
13431343

13441344
down_read(&current->mm->mmap_sem);
1345+
srcu_idx = srcu_read_lock(&kvm->srcu);
13451346
for (i = 0; i < args->count; i++) {
13461347
hva = gfn_to_hva(kvm, args->start_gfn + i);
13471348
if (kvm_is_error_hva(hva)) {
@@ -1353,6 +1354,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
13531354
if (r)
13541355
break;
13551356
}
1357+
srcu_read_unlock(&kvm->srcu, srcu_idx);
13561358
up_read(&current->mm->mmap_sem);
13571359

13581360
if (!r) {
@@ -1370,7 +1372,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
13701372
{
13711373
uint8_t *keys;
13721374
uint64_t hva;
1373-
int i, r = 0;
1375+
int srcu_idx, i, r = 0;
13741376

13751377
if (args->flags != 0)
13761378
return -EINVAL;
@@ -1396,6 +1398,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
13961398
goto out;
13971399

13981400
down_read(&current->mm->mmap_sem);
1401+
srcu_idx = srcu_read_lock(&kvm->srcu);
13991402
for (i = 0; i < args->count; i++) {
14001403
hva = gfn_to_hva(kvm, args->start_gfn + i);
14011404
if (kvm_is_error_hva(hva)) {
@@ -1413,6 +1416,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
14131416
if (r)
14141417
break;
14151418
}
1419+
srcu_read_unlock(&kvm->srcu, srcu_idx);
14161420
up_read(&current->mm->mmap_sem);
14171421
out:
14181422
kvfree(keys);

arch/x86/entry/entry_64.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,7 @@ apicinterrupt X86_PLATFORM_IPI_VECTOR x86_platform_ipi smp_x86_platform_ipi
705705
#ifdef CONFIG_HAVE_KVM
706706
apicinterrupt3 POSTED_INTR_VECTOR kvm_posted_intr_ipi smp_kvm_posted_intr_ipi
707707
apicinterrupt3 POSTED_INTR_WAKEUP_VECTOR kvm_posted_intr_wakeup_ipi smp_kvm_posted_intr_wakeup_ipi
708+
apicinterrupt3 POSTED_INTR_NESTED_VECTOR kvm_posted_intr_nested_ipi smp_kvm_posted_intr_nested_ipi
708709
#endif
709710

710711
#ifdef CONFIG_X86_MCE_THRESHOLD

arch/x86/include/asm/entry_arch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR,
2525
smp_kvm_posted_intr_ipi)
2626
BUILD_INTERRUPT3(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR,
2727
smp_kvm_posted_intr_wakeup_ipi)
28+
BUILD_INTERRUPT3(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR,
29+
smp_kvm_posted_intr_nested_ipi)
2830
#endif
2931

3032
/*

arch/x86/include/asm/hardirq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ typedef struct {
1515
#ifdef CONFIG_HAVE_KVM
1616
unsigned int kvm_posted_intr_ipis;
1717
unsigned int kvm_posted_intr_wakeup_ipis;
18+
unsigned int kvm_posted_intr_nested_ipis;
1819
#endif
1920
unsigned int x86_platform_ipis; /* arch dependent */
2021
unsigned int apic_perf_irqs;

arch/x86/include/asm/hw_irq.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ extern asmlinkage void apic_timer_interrupt(void);
3030
extern asmlinkage void x86_platform_ipi(void);
3131
extern asmlinkage void kvm_posted_intr_ipi(void);
3232
extern asmlinkage void kvm_posted_intr_wakeup_ipi(void);
33+
extern asmlinkage void kvm_posted_intr_nested_ipi(void);
3334
extern asmlinkage void error_interrupt(void);
3435
extern asmlinkage void irq_work_interrupt(void);
3536

@@ -62,6 +63,7 @@ extern void trace_call_function_single_interrupt(void);
6263
#define trace_reboot_interrupt reboot_interrupt
6364
#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
6465
#define trace_kvm_posted_intr_wakeup_ipi kvm_posted_intr_wakeup_ipi
66+
#define trace_kvm_posted_intr_nested_ipi kvm_posted_intr_nested_ipi
6567
#endif /* CONFIG_TRACING */
6668

6769
#ifdef CONFIG_X86_LOCAL_APIC

arch/x86/include/asm/irq_vectors.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@
8383
*/
8484
#define X86_PLATFORM_IPI_VECTOR 0xf7
8585

86-
#define POSTED_INTR_WAKEUP_VECTOR 0xf1
8786
/*
8887
* IRQ work vector:
8988
*/
@@ -98,6 +97,8 @@
9897
/* Vector for KVM to deliver posted interrupt IPI */
9998
#ifdef CONFIG_HAVE_KVM
10099
#define POSTED_INTR_VECTOR 0xf2
100+
#define POSTED_INTR_WAKEUP_VECTOR 0xf1
101+
#define POSTED_INTR_NESTED_VECTOR 0xf0
101102
#endif
102103

103104
/*

arch/x86/kernel/irq.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@ int arch_show_interrupts(struct seq_file *p, int prec)
155155
seq_printf(p, "%10u ", irq_stats(j)->kvm_posted_intr_ipis);
156156
seq_puts(p, " Posted-interrupt notification event\n");
157157

158+
seq_printf(p, "%*s: ", prec, "NPI");
159+
for_each_online_cpu(j)
160+
seq_printf(p, "%10u ",
161+
irq_stats(j)->kvm_posted_intr_nested_ipis);
162+
seq_puts(p, " Nested posted-interrupt event\n");
163+
158164
seq_printf(p, "%*s: ", prec, "PIW");
159165
for_each_online_cpu(j)
160166
seq_printf(p, "%10u ",
@@ -313,6 +319,19 @@ __visible void smp_kvm_posted_intr_wakeup_ipi(struct pt_regs *regs)
313319
exiting_irq();
314320
set_irq_regs(old_regs);
315321
}
322+
323+
/*
324+
* Handler for POSTED_INTERRUPT_NESTED_VECTOR.
325+
*/
326+
__visible void smp_kvm_posted_intr_nested_ipi(struct pt_regs *regs)
327+
{
328+
struct pt_regs *old_regs = set_irq_regs(regs);
329+
330+
entering_ack_irq();
331+
inc_irq_stat(kvm_posted_intr_nested_ipis);
332+
exiting_irq();
333+
set_irq_regs(old_regs);
334+
}
316335
#endif
317336

318337
__visible void __irq_entry smp_trace_x86_platform_ipi(struct pt_regs *regs)

arch/x86/kernel/irqinit.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ static void __init apic_intr_init(void)
150150
alloc_intr_gate(POSTED_INTR_VECTOR, kvm_posted_intr_ipi);
151151
/* IPI for KVM to deliver interrupt to wake up tasks */
152152
alloc_intr_gate(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi);
153+
/* IPI for KVM to deliver nested posted interrupt */
154+
alloc_intr_gate(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi);
153155
#endif
154156

155157
/* IPI vectors for APIC spurious and error interrupts */

arch/x86/kvm/lapic.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,18 +1495,18 @@ EXPORT_SYMBOL_GPL(kvm_lapic_hv_timer_in_use);
14951495

14961496
static void cancel_hv_timer(struct kvm_lapic *apic)
14971497
{
1498+
WARN_ON(preemptible());
14981499
WARN_ON(!apic->lapic_timer.hv_timer_in_use);
1499-
preempt_disable();
15001500
kvm_x86_ops->cancel_hv_timer(apic->vcpu);
15011501
apic->lapic_timer.hv_timer_in_use = false;
1502-
preempt_enable();
15031502
}
15041503

15051504
static bool start_hv_timer(struct kvm_lapic *apic)
15061505
{
15071506
struct kvm_timer *ktimer = &apic->lapic_timer;
15081507
int r;
15091508

1509+
WARN_ON(preemptible());
15101510
if (!kvm_x86_ops->set_hv_timer)
15111511
return false;
15121512

@@ -1538,6 +1538,8 @@ static bool start_hv_timer(struct kvm_lapic *apic)
15381538
static void start_sw_timer(struct kvm_lapic *apic)
15391539
{
15401540
struct kvm_timer *ktimer = &apic->lapic_timer;
1541+
1542+
WARN_ON(preemptible());
15411543
if (apic->lapic_timer.hv_timer_in_use)
15421544
cancel_hv_timer(apic);
15431545
if (!apic_lvtt_period(apic) && atomic_read(&ktimer->pending))
@@ -1552,15 +1554,20 @@ static void start_sw_timer(struct kvm_lapic *apic)
15521554

15531555
static void restart_apic_timer(struct kvm_lapic *apic)
15541556
{
1557+
preempt_disable();
15551558
if (!start_hv_timer(apic))
15561559
start_sw_timer(apic);
1560+
preempt_enable();
15571561
}
15581562

15591563
void kvm_lapic_expired_hv_timer(struct kvm_vcpu *vcpu)
15601564
{
15611565
struct kvm_lapic *apic = vcpu->arch.apic;
15621566

1563-
WARN_ON(!apic->lapic_timer.hv_timer_in_use);
1567+
preempt_disable();
1568+
/* If the preempt notifier has already run, it also called apic_timer_expired */
1569+
if (!apic->lapic_timer.hv_timer_in_use)
1570+
goto out;
15641571
WARN_ON(swait_active(&vcpu->wq));
15651572
cancel_hv_timer(apic);
15661573
apic_timer_expired(apic);
@@ -1569,6 +1576,8 @@ void kvm_lapic_expired_hv_timer(struct kvm_vcpu *vcpu)
15691576
advance_periodic_target_expiration(apic);
15701577
restart_apic_timer(apic);
15711578
}
1579+
out:
1580+
preempt_enable();
15721581
}
15731582
EXPORT_SYMBOL_GPL(kvm_lapic_expired_hv_timer);
15741583

@@ -1582,9 +1591,11 @@ void kvm_lapic_switch_to_sw_timer(struct kvm_vcpu *vcpu)
15821591
{
15831592
struct kvm_lapic *apic = vcpu->arch.apic;
15841593

1594+
preempt_disable();
15851595
/* Possibly the TSC deadline timer is not enabled yet */
15861596
if (apic->lapic_timer.hv_timer_in_use)
15871597
start_sw_timer(apic);
1598+
preempt_enable();
15881599
}
15891600
EXPORT_SYMBOL_GPL(kvm_lapic_switch_to_sw_timer);
15901601

arch/x86/kvm/vmx.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,6 @@ struct vcpu_vmx {
563563
struct kvm_vcpu vcpu;
564564
unsigned long host_rsp;
565565
u8 fail;
566-
bool nmi_known_unmasked;
567566
u32 exit_intr_info;
568567
u32 idt_vectoring_info;
569568
ulong rflags;
@@ -4988,9 +4987,12 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
49884987
}
49894988
}
49904989

4991-
static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
4990+
static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu,
4991+
bool nested)
49924992
{
49934993
#ifdef CONFIG_SMP
4994+
int pi_vec = nested ? POSTED_INTR_NESTED_VECTOR : POSTED_INTR_VECTOR;
4995+
49944996
if (vcpu->mode == IN_GUEST_MODE) {
49954997
struct vcpu_vmx *vmx = to_vmx(vcpu);
49964998

@@ -5008,8 +5010,7 @@ static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
50085010
*/
50095011
WARN_ON_ONCE(pi_test_sn(&vmx->pi_desc));
50105012

5011-
apic->send_IPI_mask(get_cpu_mask(vcpu->cpu),
5012-
POSTED_INTR_VECTOR);
5013+
apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), pi_vec);
50135014
return true;
50145015
}
50155016
#endif
@@ -5024,7 +5025,7 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu,
50245025
if (is_guest_mode(vcpu) &&
50255026
vector == vmx->nested.posted_intr_nv) {
50265027
/* the PIR and ON have been set by L1. */
5027-
kvm_vcpu_trigger_posted_interrupt(vcpu);
5028+
kvm_vcpu_trigger_posted_interrupt(vcpu, true);
50285029
/*
50295030
* If a posted intr is not recognized by hardware,
50305031
* we will accomplish it in the next vmentry.
@@ -5058,7 +5059,7 @@ static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
50585059
if (pi_test_and_set_on(&vmx->pi_desc))
50595060
return;
50605061

5061-
if (!kvm_vcpu_trigger_posted_interrupt(vcpu))
5062+
if (!kvm_vcpu_trigger_posted_interrupt(vcpu, false))
50625063
kvm_vcpu_kick(vcpu);
50635064
}
50645065

@@ -10041,6 +10042,8 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
1004110042
vmcs12->vm_entry_instruction_len);
1004210043
vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
1004310044
vmcs12->guest_interruptibility_info);
10045+
vmx->loaded_vmcs->nmi_known_unmasked =
10046+
!(vmcs12->guest_interruptibility_info & GUEST_INTR_STATE_NMI);
1004410047
} else {
1004510048
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0);
1004610049
}
@@ -10065,13 +10068,9 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
1006510068

1006610069
/* Posted interrupts setting is only taken from vmcs12. */
1006710070
if (nested_cpu_has_posted_intr(vmcs12)) {
10068-
/*
10069-
* Note that we use L0's vector here and in
10070-
* vmx_deliver_nested_posted_interrupt.
10071-
*/
1007210071
vmx->nested.posted_intr_nv = vmcs12->posted_intr_nv;
1007310072
vmx->nested.pi_pending = false;
10074-
vmcs_write16(POSTED_INTR_NV, POSTED_INTR_VECTOR);
10073+
vmcs_write16(POSTED_INTR_NV, POSTED_INTR_NESTED_VECTOR);
1007510074
} else {
1007610075
exec_control &= ~PIN_BASED_POSTED_INTR;
1007710076
}
@@ -10942,7 +10941,9 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
1094210941
*/
1094310942
vmx_flush_tlb(vcpu);
1094410943
}
10945-
10944+
/* Restore posted intr vector. */
10945+
if (nested_cpu_has_posted_intr(vmcs12))
10946+
vmcs_write16(POSTED_INTR_NV, POSTED_INTR_VECTOR);
1094610947

1094710948
vmcs_write32(GUEST_SYSENTER_CS, vmcs12->host_ia32_sysenter_cs);
1094810949
vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->host_ia32_sysenter_esp);

arch/x86/kvm/x86.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,8 +597,8 @@ bool pdptrs_changed(struct kvm_vcpu *vcpu)
597597
(unsigned long *)&vcpu->arch.regs_avail))
598598
return true;
599599

600-
gfn = (kvm_read_cr3(vcpu) & ~31ul) >> PAGE_SHIFT;
601-
offset = (kvm_read_cr3(vcpu) & ~31ul) & (PAGE_SIZE - 1);
600+
gfn = (kvm_read_cr3(vcpu) & 0xffffffe0ul) >> PAGE_SHIFT;
601+
offset = (kvm_read_cr3(vcpu) & 0xffffffe0ul) & (PAGE_SIZE - 1);
602602
r = kvm_read_nested_guest_page(vcpu, gfn, pdpte, offset, sizeof(pdpte),
603603
PFERR_USER_MASK | PFERR_WRITE_MASK);
604604
if (r < 0)

include/linux/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ struct kvm {
445445
struct kvm_stat_data **debugfs_stat_data;
446446
struct srcu_struct srcu;
447447
struct srcu_struct irq_srcu;
448+
pid_t userspace_pid;
448449
};
449450

450451
#define kvm_err(fmt, ...) \

0 commit comments

Comments
 (0)