Skip to content

Commit 2001825

Browse files
aikpaulusmack
authored andcommitted
KVM: PPC: Book3S HV: Avoid lockdep debugging in TCE realmode handlers
The kvmppc_tce_to_ua() helper is called from real and virtual modes and it works fine as long as CONFIG_DEBUG_LOCKDEP is not enabled. However if the lockdep debugging is on, the lockdep will most likely break in kvm_memslots() because of srcu_dereference_check() so we need to use PPC-own kvm_memslots_raw() which uses realmode safe rcu_dereference_raw_notrace(). This creates a realmode copy of kvmppc_tce_to_ua() which replaces kvm_memslots() with kvm_memslots_raw(). Since kvmppc_rm_tce_to_ua() becomes static and can only be used inside HV KVM, this moves it earlier under CONFIG_KVM_BOOK3S_HV_POSSIBLE. This moves truly virtual-mode kvmppc_tce_to_ua() to where it belongs and drops the prmap parameter which was never used in the virtual mode. Fixes: d3695aa ("KVM: PPC: Add support for multiple-TCE hcalls", 2016-02-15) Signed-off-by: Alexey Kardashevskiy <[email protected]> Signed-off-by: Paul Mackerras <[email protected]>
1 parent 3309bec commit 2001825

File tree

3 files changed

+44
-33
lines changed

3 files changed

+44
-33
lines changed

arch/powerpc/include/asm/kvm_ppc.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,6 @@ extern struct kvmppc_spapr_tce_table *kvmppc_find_table(
197197
(iommu_tce_check_ioba((stt)->page_shift, (stt)->offset, \
198198
(stt)->size, (ioba), (npages)) ? \
199199
H_PARAMETER : H_SUCCESS)
200-
extern long kvmppc_tce_to_ua(struct kvm *kvm, unsigned long tce,
201-
unsigned long *ua, unsigned long **prmap);
202200
extern void kvmppc_tce_put(struct kvmppc_spapr_tce_table *tt,
203201
unsigned long idx, unsigned long tce);
204202
extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,

arch/powerpc/kvm/book3s_64_vio.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,22 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
363363
return ret;
364364
}
365365

366+
static long kvmppc_tce_to_ua(struct kvm *kvm, unsigned long tce,
367+
unsigned long *ua)
368+
{
369+
unsigned long gfn = tce >> PAGE_SHIFT;
370+
struct kvm_memory_slot *memslot;
371+
372+
memslot = search_memslots(kvm_memslots(kvm), gfn);
373+
if (!memslot)
374+
return -EINVAL;
375+
376+
*ua = __gfn_to_hva_memslot(memslot, gfn) |
377+
(tce & ~(PAGE_MASK | TCE_PCI_READ | TCE_PCI_WRITE));
378+
379+
return 0;
380+
}
381+
366382
static long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *stt,
367383
unsigned long tce)
368384
{
@@ -378,7 +394,7 @@ static long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *stt,
378394
if (iommu_tce_check_gpa(stt->page_shift, gpa))
379395
return H_TOO_HARD;
380396

381-
if (kvmppc_tce_to_ua(stt->kvm, tce, &ua, NULL))
397+
if (kvmppc_tce_to_ua(stt->kvm, tce, &ua))
382398
return H_TOO_HARD;
383399

384400
list_for_each_entry_rcu(stit, &stt->iommu_tables, next) {
@@ -551,7 +567,7 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
551567

552568
dir = iommu_tce_direction(tce);
553569

554-
if ((dir != DMA_NONE) && kvmppc_tce_to_ua(vcpu->kvm, tce, &ua, NULL)) {
570+
if ((dir != DMA_NONE) && kvmppc_tce_to_ua(vcpu->kvm, tce, &ua)) {
555571
ret = H_PARAMETER;
556572
goto unlock_exit;
557573
}
@@ -612,7 +628,7 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
612628
return ret;
613629

614630
idx = srcu_read_lock(&vcpu->kvm->srcu);
615-
if (kvmppc_tce_to_ua(vcpu->kvm, tce_list, &ua, NULL)) {
631+
if (kvmppc_tce_to_ua(vcpu->kvm, tce_list, &ua)) {
616632
ret = H_TOO_HARD;
617633
goto unlock_exit;
618634
}
@@ -647,7 +663,7 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
647663
}
648664
tce = be64_to_cpu(tce);
649665

650-
if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua, NULL))
666+
if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua))
651667
return H_PARAMETER;
652668

653669
list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {

arch/powerpc/kvm/book3s_64_vio_hv.c

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,25 @@ struct kvmppc_spapr_tce_table *kvmppc_find_table(struct kvm *kvm,
8888
EXPORT_SYMBOL_GPL(kvmppc_find_table);
8989

9090
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
91+
static long kvmppc_rm_tce_to_ua(struct kvm *kvm, unsigned long tce,
92+
unsigned long *ua, unsigned long **prmap)
93+
{
94+
unsigned long gfn = tce >> PAGE_SHIFT;
95+
struct kvm_memory_slot *memslot;
96+
97+
memslot = search_memslots(kvm_memslots_raw(kvm), gfn);
98+
if (!memslot)
99+
return -EINVAL;
100+
101+
*ua = __gfn_to_hva_memslot(memslot, gfn) |
102+
(tce & ~(PAGE_MASK | TCE_PCI_READ | TCE_PCI_WRITE));
103+
104+
if (prmap)
105+
*prmap = &memslot->arch.rmap[gfn - memslot->base_gfn];
106+
107+
return 0;
108+
}
109+
91110
/*
92111
* Validates TCE address.
93112
* At the moment flags and page mask are validated.
@@ -111,7 +130,7 @@ static long kvmppc_rm_tce_validate(struct kvmppc_spapr_tce_table *stt,
111130
if (iommu_tce_check_gpa(stt->page_shift, gpa))
112131
return H_PARAMETER;
113132

114-
if (kvmppc_tce_to_ua(stt->kvm, tce, &ua, NULL))
133+
if (kvmppc_rm_tce_to_ua(stt->kvm, tce, &ua, NULL))
115134
return H_TOO_HARD;
116135

117136
list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
@@ -181,28 +200,6 @@ void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
181200
}
182201
EXPORT_SYMBOL_GPL(kvmppc_tce_put);
183202

184-
long kvmppc_tce_to_ua(struct kvm *kvm, unsigned long tce,
185-
unsigned long *ua, unsigned long **prmap)
186-
{
187-
unsigned long gfn = tce >> PAGE_SHIFT;
188-
struct kvm_memory_slot *memslot;
189-
190-
memslot = search_memslots(kvm_memslots(kvm), gfn);
191-
if (!memslot)
192-
return -EINVAL;
193-
194-
*ua = __gfn_to_hva_memslot(memslot, gfn) |
195-
(tce & ~(PAGE_MASK | TCE_PCI_READ | TCE_PCI_WRITE));
196-
197-
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
198-
if (prmap)
199-
*prmap = &memslot->arch.rmap[gfn - memslot->base_gfn];
200-
#endif
201-
202-
return 0;
203-
}
204-
EXPORT_SYMBOL_GPL(kvmppc_tce_to_ua);
205-
206203
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
207204
static long iommu_tce_xchg_rm(struct mm_struct *mm, struct iommu_table *tbl,
208205
unsigned long entry, unsigned long *hpa,
@@ -390,7 +387,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
390387
return ret;
391388

392389
dir = iommu_tce_direction(tce);
393-
if ((dir != DMA_NONE) && kvmppc_tce_to_ua(vcpu->kvm, tce, &ua, NULL))
390+
if ((dir != DMA_NONE) && kvmppc_rm_tce_to_ua(vcpu->kvm, tce, &ua, NULL))
394391
return H_PARAMETER;
395392

396393
entry = ioba >> stt->page_shift;
@@ -492,7 +489,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
492489
*/
493490
struct mm_iommu_table_group_mem_t *mem;
494491

495-
if (kvmppc_tce_to_ua(vcpu->kvm, tce_list, &ua, NULL))
492+
if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce_list, &ua, NULL))
496493
return H_TOO_HARD;
497494

498495
mem = mm_iommu_lookup_rm(vcpu->kvm->mm, ua, IOMMU_PAGE_SIZE_4K);
@@ -508,7 +505,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
508505
* We do not require memory to be preregistered in this case
509506
* so lock rmap and do __find_linux_pte_or_hugepte().
510507
*/
511-
if (kvmppc_tce_to_ua(vcpu->kvm, tce_list, &ua, &rmap))
508+
if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce_list, &ua, &rmap))
512509
return H_TOO_HARD;
513510

514511
rmap = (void *) vmalloc_to_phys(rmap);
@@ -542,7 +539,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
542539
unsigned long tce = be64_to_cpu(((u64 *)tces)[i]);
543540

544541
ua = 0;
545-
if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua, NULL))
542+
if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce, &ua, NULL))
546543
return H_PARAMETER;
547544

548545
list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {

0 commit comments

Comments
 (0)