Skip to content

Commit 46dd083

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Paolo Bonzini: "The PPC folks had a large amount of changes queued for 3.13, and now they are fixing the bugs" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: PPC: Book3S HV: Don't drop low-order page address bits powerpc: book3s: kvm: Don't abuse host r2 in exit path powerpc/kvm/booke: Fix build break due to stack frame size warning KVM: PPC: Book3S: PR: Enable interrupts earlier KVM: PPC: Book3S: PR: Make svcpu -> vcpu store preempt savvy KVM: PPC: Book3S: PR: Export kvmppc_copy_to|from_svcpu KVM: PPC: Book3S: PR: Don't clobber our exit handler id powerpc: kvm: fix rare but potential deadlock scene KVM: PPC: Book3S HV: Take SRCU read lock around kvm_read_guest() call KVM: PPC: Book3S HV: Make tbacct_lock irq-safe KVM: PPC: Book3S HV: Refine barriers in guest entry/exit KVM: PPC: Book3S HV: Fix physical address calculations
2 parents 597d795 + 5e6d26c commit 46dd083

File tree

13 files changed

+112
-62
lines changed

13 files changed

+112
-62
lines changed

arch/powerpc/include/asm/kvm_book3s.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ extern void kvmppc_load_up_vsx(void);
192192
extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst);
193193
extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst);
194194
extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd);
195+
extern void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu,
196+
struct kvm_vcpu *vcpu);
197+
extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu,
198+
struct kvmppc_book3s_shadow_vcpu *svcpu);
195199

196200
static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
197201
{

arch/powerpc/include/asm/kvm_book3s_asm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct kvmppc_host_state {
7979
ulong vmhandler;
8080
ulong scratch0;
8181
ulong scratch1;
82+
ulong scratch2;
8283
u8 in_guest;
8384
u8 restore_hid5;
8485
u8 napping;
@@ -106,6 +107,7 @@ struct kvmppc_host_state {
106107
};
107108

108109
struct kvmppc_book3s_shadow_vcpu {
110+
bool in_use;
109111
ulong gpr[14];
110112
u32 cr;
111113
u32 xer;

arch/powerpc/include/asm/switch_to.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ extern void giveup_vsx(struct task_struct *);
3535
extern void enable_kernel_spe(void);
3636
extern void giveup_spe(struct task_struct *);
3737
extern void load_up_spe(struct task_struct *);
38-
extern void switch_booke_debug_regs(struct thread_struct *new_thread);
38+
extern void switch_booke_debug_regs(struct debug_reg *new_debug);
3939

4040
#ifndef CONFIG_SMP
4141
extern void discard_lazy_cpu_state(void);

arch/powerpc/kernel/asm-offsets.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,7 @@ int main(void)
576576
HSTATE_FIELD(HSTATE_VMHANDLER, vmhandler);
577577
HSTATE_FIELD(HSTATE_SCRATCH0, scratch0);
578578
HSTATE_FIELD(HSTATE_SCRATCH1, scratch1);
579+
HSTATE_FIELD(HSTATE_SCRATCH2, scratch2);
579580
HSTATE_FIELD(HSTATE_IN_GUEST, in_guest);
580581
HSTATE_FIELD(HSTATE_RESTORE_HID5, restore_hid5);
581582
HSTATE_FIELD(HSTATE_NAPPING, napping);

arch/powerpc/kernel/process.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ static void set_debug_reg_defaults(struct thread_struct *thread)
339339
#endif
340340
}
341341

342-
static void prime_debug_regs(struct thread_struct *thread)
342+
static void prime_debug_regs(struct debug_reg *debug)
343343
{
344344
/*
345345
* We could have inherited MSR_DE from userspace, since
@@ -348,34 +348,34 @@ static void prime_debug_regs(struct thread_struct *thread)
348348
*/
349349
mtmsr(mfmsr() & ~MSR_DE);
350350

351-
mtspr(SPRN_IAC1, thread->debug.iac1);
352-
mtspr(SPRN_IAC2, thread->debug.iac2);
351+
mtspr(SPRN_IAC1, debug->iac1);
352+
mtspr(SPRN_IAC2, debug->iac2);
353353
#if CONFIG_PPC_ADV_DEBUG_IACS > 2
354-
mtspr(SPRN_IAC3, thread->debug.iac3);
355-
mtspr(SPRN_IAC4, thread->debug.iac4);
354+
mtspr(SPRN_IAC3, debug->iac3);
355+
mtspr(SPRN_IAC4, debug->iac4);
356356
#endif
357-
mtspr(SPRN_DAC1, thread->debug.dac1);
358-
mtspr(SPRN_DAC2, thread->debug.dac2);
357+
mtspr(SPRN_DAC1, debug->dac1);
358+
mtspr(SPRN_DAC2, debug->dac2);
359359
#if CONFIG_PPC_ADV_DEBUG_DVCS > 0
360-
mtspr(SPRN_DVC1, thread->debug.dvc1);
361-
mtspr(SPRN_DVC2, thread->debug.dvc2);
360+
mtspr(SPRN_DVC1, debug->dvc1);
361+
mtspr(SPRN_DVC2, debug->dvc2);
362362
#endif
363-
mtspr(SPRN_DBCR0, thread->debug.dbcr0);
364-
mtspr(SPRN_DBCR1, thread->debug.dbcr1);
363+
mtspr(SPRN_DBCR0, debug->dbcr0);
364+
mtspr(SPRN_DBCR1, debug->dbcr1);
365365
#ifdef CONFIG_BOOKE
366-
mtspr(SPRN_DBCR2, thread->debug.dbcr2);
366+
mtspr(SPRN_DBCR2, debug->dbcr2);
367367
#endif
368368
}
369369
/*
370370
* Unless neither the old or new thread are making use of the
371371
* debug registers, set the debug registers from the values
372372
* stored in the new thread.
373373
*/
374-
void switch_booke_debug_regs(struct thread_struct *new_thread)
374+
void switch_booke_debug_regs(struct debug_reg *new_debug)
375375
{
376376
if ((current->thread.debug.dbcr0 & DBCR0_IDM)
377-
|| (new_thread->debug.dbcr0 & DBCR0_IDM))
378-
prime_debug_regs(new_thread);
377+
|| (new_debug->dbcr0 & DBCR0_IDM))
378+
prime_debug_regs(new_debug);
379379
}
380380
EXPORT_SYMBOL_GPL(switch_booke_debug_regs);
381381
#else /* !CONFIG_PPC_ADV_DEBUG_REGS */
@@ -683,7 +683,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
683683
#endif /* CONFIG_SMP */
684684

685685
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
686-
switch_booke_debug_regs(&new->thread);
686+
switch_booke_debug_regs(&new->thread.debug);
687687
#else
688688
/*
689689
* For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would

arch/powerpc/kvm/book3s_64_mmu_hv.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -469,18 +469,22 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
469469
slb_v = vcpu->kvm->arch.vrma_slb_v;
470470
}
471471

472+
preempt_disable();
472473
/* Find the HPTE in the hash table */
473474
index = kvmppc_hv_find_lock_hpte(kvm, eaddr, slb_v,
474475
HPTE_V_VALID | HPTE_V_ABSENT);
475-
if (index < 0)
476+
if (index < 0) {
477+
preempt_enable();
476478
return -ENOENT;
479+
}
477480
hptep = (unsigned long *)(kvm->arch.hpt_virt + (index << 4));
478481
v = hptep[0] & ~HPTE_V_HVLOCK;
479482
gr = kvm->arch.revmap[index].guest_rpte;
480483

481484
/* Unlock the HPTE */
482485
asm volatile("lwsync" : : : "memory");
483486
hptep[0] = v;
487+
preempt_enable();
484488

485489
gpte->eaddr = eaddr;
486490
gpte->vpage = ((v & HPTE_V_AVPN) << 4) | ((eaddr >> 12) & 0xfff);
@@ -665,6 +669,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
665669
return -EFAULT;
666670
} else {
667671
page = pages[0];
672+
pfn = page_to_pfn(page);
668673
if (PageHuge(page)) {
669674
page = compound_head(page);
670675
pte_size <<= compound_order(page);
@@ -689,7 +694,6 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
689694
}
690695
rcu_read_unlock_sched();
691696
}
692-
pfn = page_to_pfn(page);
693697
}
694698

695699
ret = -EFAULT;
@@ -707,8 +711,14 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
707711
r = (r & ~(HPTE_R_W|HPTE_R_I|HPTE_R_G)) | HPTE_R_M;
708712
}
709713

710-
/* Set the HPTE to point to pfn */
711-
r = (r & ~(HPTE_R_PP0 - pte_size)) | (pfn << PAGE_SHIFT);
714+
/*
715+
* Set the HPTE to point to pfn.
716+
* Since the pfn is at PAGE_SIZE granularity, make sure we
717+
* don't mask out lower-order bits if psize < PAGE_SIZE.
718+
*/
719+
if (psize < PAGE_SIZE)
720+
psize = PAGE_SIZE;
721+
r = (r & ~(HPTE_R_PP0 - psize)) | ((pfn << PAGE_SHIFT) & ~(psize - 1));
712722
if (hpte_is_writable(r) && !write_ok)
713723
r = hpte_make_readonly(r);
714724
ret = RESUME_GUEST;

arch/powerpc/kvm/book3s_hv.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)
131131
static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu)
132132
{
133133
struct kvmppc_vcore *vc = vcpu->arch.vcore;
134+
unsigned long flags;
134135

135-
spin_lock(&vcpu->arch.tbacct_lock);
136+
spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags);
136137
if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE &&
137138
vc->preempt_tb != TB_NIL) {
138139
vc->stolen_tb += mftb() - vc->preempt_tb;
@@ -143,19 +144,20 @@ static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu)
143144
vcpu->arch.busy_stolen += mftb() - vcpu->arch.busy_preempt;
144145
vcpu->arch.busy_preempt = TB_NIL;
145146
}
146-
spin_unlock(&vcpu->arch.tbacct_lock);
147+
spin_unlock_irqrestore(&vcpu->arch.tbacct_lock, flags);
147148
}
148149

149150
static void kvmppc_core_vcpu_put_hv(struct kvm_vcpu *vcpu)
150151
{
151152
struct kvmppc_vcore *vc = vcpu->arch.vcore;
153+
unsigned long flags;
152154

153-
spin_lock(&vcpu->arch.tbacct_lock);
155+
spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags);
154156
if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE)
155157
vc->preempt_tb = mftb();
156158
if (vcpu->arch.state == KVMPPC_VCPU_BUSY_IN_HOST)
157159
vcpu->arch.busy_preempt = mftb();
158-
spin_unlock(&vcpu->arch.tbacct_lock);
160+
spin_unlock_irqrestore(&vcpu->arch.tbacct_lock, flags);
159161
}
160162

161163
static void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr)
@@ -486,11 +488,11 @@ static u64 vcore_stolen_time(struct kvmppc_vcore *vc, u64 now)
486488
*/
487489
if (vc->vcore_state != VCORE_INACTIVE &&
488490
vc->runner->arch.run_task != current) {
489-
spin_lock(&vc->runner->arch.tbacct_lock);
491+
spin_lock_irq(&vc->runner->arch.tbacct_lock);
490492
p = vc->stolen_tb;
491493
if (vc->preempt_tb != TB_NIL)
492494
p += now - vc->preempt_tb;
493-
spin_unlock(&vc->runner->arch.tbacct_lock);
495+
spin_unlock_irq(&vc->runner->arch.tbacct_lock);
494496
} else {
495497
p = vc->stolen_tb;
496498
}
@@ -512,10 +514,10 @@ static void kvmppc_create_dtl_entry(struct kvm_vcpu *vcpu,
512514
core_stolen = vcore_stolen_time(vc, now);
513515
stolen = core_stolen - vcpu->arch.stolen_logged;
514516
vcpu->arch.stolen_logged = core_stolen;
515-
spin_lock(&vcpu->arch.tbacct_lock);
517+
spin_lock_irq(&vcpu->arch.tbacct_lock);
516518
stolen += vcpu->arch.busy_stolen;
517519
vcpu->arch.busy_stolen = 0;
518-
spin_unlock(&vcpu->arch.tbacct_lock);
520+
spin_unlock_irq(&vcpu->arch.tbacct_lock);
519521
if (!dt || !vpa)
520522
return;
521523
memset(dt, 0, sizeof(struct dtl_entry));
@@ -589,7 +591,9 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
589591
if (list_empty(&vcpu->kvm->arch.rtas_tokens))
590592
return RESUME_HOST;
591593

594+
idx = srcu_read_lock(&vcpu->kvm->srcu);
592595
rc = kvmppc_rtas_hcall(vcpu);
596+
srcu_read_unlock(&vcpu->kvm->srcu, idx);
593597

594598
if (rc == -ENOENT)
595599
return RESUME_HOST;
@@ -1115,13 +1119,13 @@ static void kvmppc_remove_runnable(struct kvmppc_vcore *vc,
11151119

11161120
if (vcpu->arch.state != KVMPPC_VCPU_RUNNABLE)
11171121
return;
1118-
spin_lock(&vcpu->arch.tbacct_lock);
1122+
spin_lock_irq(&vcpu->arch.tbacct_lock);
11191123
now = mftb();
11201124
vcpu->arch.busy_stolen += vcore_stolen_time(vc, now) -
11211125
vcpu->arch.stolen_logged;
11221126
vcpu->arch.busy_preempt = now;
11231127
vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST;
1124-
spin_unlock(&vcpu->arch.tbacct_lock);
1128+
spin_unlock_irq(&vcpu->arch.tbacct_lock);
11251129
--vc->n_runnable;
11261130
list_del(&vcpu->arch.run_list);
11271131
}

arch/powerpc/kvm/book3s_hv_rm_mmu.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
225225
is_io = pa & (HPTE_R_I | HPTE_R_W);
226226
pte_size = PAGE_SIZE << (pa & KVMPPC_PAGE_ORDER_MASK);
227227
pa &= PAGE_MASK;
228+
pa |= gpa & ~PAGE_MASK;
228229
} else {
229230
/* Translate to host virtual address */
230231
hva = __gfn_to_hva_memslot(memslot, gfn);
@@ -238,13 +239,13 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
238239
ptel = hpte_make_readonly(ptel);
239240
is_io = hpte_cache_bits(pte_val(pte));
240241
pa = pte_pfn(pte) << PAGE_SHIFT;
242+
pa |= hva & (pte_size - 1);
243+
pa |= gpa & ~PAGE_MASK;
241244
}
242245
}
243246

244247
if (pte_size < psize)
245248
return H_PARAMETER;
246-
if (pa && pte_size > psize)
247-
pa |= gpa & (pte_size - 1);
248249

249250
ptel &= ~(HPTE_R_PP0 - psize);
250251
ptel |= pa;
@@ -749,6 +750,10 @@ static int slb_base_page_shift[4] = {
749750
20, /* 1M, unsupported */
750751
};
751752

753+
/* When called from virtmode, this func should be protected by
754+
* preempt_disable(), otherwise, the holding of HPTE_V_HVLOCK
755+
* can trigger deadlock issue.
756+
*/
752757
long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v,
753758
unsigned long valid)
754759
{

arch/powerpc/kvm/book3s_hv_rmhandlers.S

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
153153

154154
13: b machine_check_fwnmi
155155

156-
157156
/*
158157
* We come in here when wakened from nap mode on a secondary hw thread.
159158
* Relocation is off and most register values are lost.
@@ -224,6 +223,11 @@ kvm_start_guest:
224223
/* Clear our vcpu pointer so we don't come back in early */
225224
li r0, 0
226225
std r0, HSTATE_KVM_VCPU(r13)
226+
/*
227+
* Make sure we clear HSTATE_KVM_VCPU(r13) before incrementing
228+
* the nap_count, because once the increment to nap_count is
229+
* visible we could be given another vcpu.
230+
*/
227231
lwsync
228232
/* Clear any pending IPI - we're an offline thread */
229233
ld r5, HSTATE_XICS_PHYS(r13)
@@ -241,7 +245,6 @@ kvm_start_guest:
241245
/* increment the nap count and then go to nap mode */
242246
ld r4, HSTATE_KVM_VCORE(r13)
243247
addi r4, r4, VCORE_NAP_COUNT
244-
lwsync /* make previous updates visible */
245248
51: lwarx r3, 0, r4
246249
addi r3, r3, 1
247250
stwcx. r3, 0, r4
@@ -751,15 +754,14 @@ kvmppc_interrupt_hv:
751754
* guest CR, R12 saved in shadow VCPU SCRATCH1/0
752755
* guest R13 saved in SPRN_SCRATCH0
753756
*/
754-
/* abuse host_r2 as third scratch area; we get r2 from PACATOC(r13) */
755-
std r9, HSTATE_HOST_R2(r13)
757+
std r9, HSTATE_SCRATCH2(r13)
756758

757759
lbz r9, HSTATE_IN_GUEST(r13)
758760
cmpwi r9, KVM_GUEST_MODE_HOST_HV
759761
beq kvmppc_bad_host_intr
760762
#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
761763
cmpwi r9, KVM_GUEST_MODE_GUEST
762-
ld r9, HSTATE_HOST_R2(r13)
764+
ld r9, HSTATE_SCRATCH2(r13)
763765
beq kvmppc_interrupt_pr
764766
#endif
765767
/* We're now back in the host but in guest MMU context */
@@ -779,7 +781,7 @@ kvmppc_interrupt_hv:
779781
std r6, VCPU_GPR(R6)(r9)
780782
std r7, VCPU_GPR(R7)(r9)
781783
std r8, VCPU_GPR(R8)(r9)
782-
ld r0, HSTATE_HOST_R2(r13)
784+
ld r0, HSTATE_SCRATCH2(r13)
783785
std r0, VCPU_GPR(R9)(r9)
784786
std r10, VCPU_GPR(R10)(r9)
785787
std r11, VCPU_GPR(R11)(r9)
@@ -990,14 +992,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
990992
*/
991993
/* Increment the threads-exiting-guest count in the 0xff00
992994
bits of vcore->entry_exit_count */
993-
lwsync
994995
ld r5,HSTATE_KVM_VCORE(r13)
995996
addi r6,r5,VCORE_ENTRY_EXIT
996997
41: lwarx r3,0,r6
997998
addi r0,r3,0x100
998999
stwcx. r0,0,r6
9991000
bne 41b
1000-
lwsync
1001+
isync /* order stwcx. vs. reading napping_threads */
10011002

10021003
/*
10031004
* At this point we have an interrupt that we have to pass
@@ -1030,6 +1031,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
10301031
sld r0,r0,r4
10311032
andc. r3,r3,r0 /* no sense IPI'ing ourselves */
10321033
beq 43f
1034+
/* Order entry/exit update vs. IPIs */
1035+
sync
10331036
mulli r4,r4,PACA_SIZE /* get paca for thread 0 */
10341037
subf r6,r4,r13
10351038
42: andi. r0,r3,1
@@ -1638,10 +1641,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
16381641
bge kvm_cede_exit
16391642
stwcx. r4,0,r6
16401643
bne 31b
1644+
/* order napping_threads update vs testing entry_exit_count */
1645+
isync
16411646
li r0,1
16421647
stb r0,HSTATE_NAPPING(r13)
1643-
/* order napping_threads update vs testing entry_exit_count */
1644-
lwsync
16451648
mr r4,r3
16461649
lwz r7,VCORE_ENTRY_EXIT(r5)
16471650
cmpwi r7,0x100

0 commit comments

Comments
 (0)