Skip to content

Commit ab0a97c

Browse files
committed
Merge tag 'powerpc-6.8-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: - Fix a crash when hot adding a PCI device to an LPAR since recent changes - Fix nested KVM level-2 guest reboot failure due to empty 'arch_compat' Thanks to Amit Machhiwal, Aneesh Kumar K.V (IBM), Brian King, Gaurav Batra, and Vaibhav Jain. * tag 'powerpc-6.8-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: KVM: PPC: Book3S HV: Fix L2 guest reboot failure due to empty 'arch_compat' powerpc/pseries/iommu: DLPAR add doesn't completely initialize pci_controller
2 parents 91403d5 + 20c8c4d commit ab0a97c

File tree

5 files changed

+73
-10
lines changed

5 files changed

+73
-10
lines changed

arch/powerpc/include/asm/ppc-pci.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ void *pci_traverse_device_nodes(struct device_node *start,
3030
void *data);
3131
extern void pci_devs_phb_init_dynamic(struct pci_controller *phb);
3232

33+
#if defined(CONFIG_IOMMU_API) && (defined(CONFIG_PPC_PSERIES) || \
34+
defined(CONFIG_PPC_POWERNV))
35+
extern void ppc_iommu_register_device(struct pci_controller *phb);
36+
extern void ppc_iommu_unregister_device(struct pci_controller *phb);
37+
#else
38+
static inline void ppc_iommu_register_device(struct pci_controller *phb) { }
39+
static inline void ppc_iommu_unregister_device(struct pci_controller *phb) { }
40+
#endif
41+
42+
3343
/* From rtas_pci.h */
3444
extern void init_pci_config_tokens (void);
3545
extern unsigned long get_phb_buid (struct device_node *);

arch/powerpc/kernel/iommu.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,7 +1360,7 @@ static struct iommu_device *spapr_tce_iommu_probe_device(struct device *dev)
13601360
struct pci_controller *hose;
13611361

13621362
if (!dev_is_pci(dev))
1363-
return ERR_PTR(-EPERM);
1363+
return ERR_PTR(-ENODEV);
13641364

13651365
pdev = to_pci_dev(dev);
13661366
hose = pdev->bus->sysdata;
@@ -1409,6 +1409,21 @@ static const struct attribute_group *spapr_tce_iommu_groups[] = {
14091409
NULL,
14101410
};
14111411

1412+
void ppc_iommu_register_device(struct pci_controller *phb)
1413+
{
1414+
iommu_device_sysfs_add(&phb->iommu, phb->parent,
1415+
spapr_tce_iommu_groups, "iommu-phb%04x",
1416+
phb->global_number);
1417+
iommu_device_register(&phb->iommu, &spapr_tce_iommu_ops,
1418+
phb->parent);
1419+
}
1420+
1421+
void ppc_iommu_unregister_device(struct pci_controller *phb)
1422+
{
1423+
iommu_device_unregister(&phb->iommu);
1424+
iommu_device_sysfs_remove(&phb->iommu);
1425+
}
1426+
14121427
/*
14131428
* This registers IOMMU devices of PHBs. This needs to happen
14141429
* after core_initcall(iommu_init) + postcore_initcall(pci_driver_init) and
@@ -1419,11 +1434,7 @@ static int __init spapr_tce_setup_phb_iommus_initcall(void)
14191434
struct pci_controller *hose;
14201435

14211436
list_for_each_entry(hose, &hose_list, list_node) {
1422-
iommu_device_sysfs_add(&hose->iommu, hose->parent,
1423-
spapr_tce_iommu_groups, "iommu-phb%04x",
1424-
hose->global_number);
1425-
iommu_device_register(&hose->iommu, &spapr_tce_iommu_ops,
1426-
hose->parent);
1437+
ppc_iommu_register_device(hose);
14271438
}
14281439
return 0;
14291440
}

arch/powerpc/kvm/book3s_hv.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,24 @@ static void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 pvr)
391391
/* Dummy value used in computing PCR value below */
392392
#define PCR_ARCH_31 (PCR_ARCH_300 << 1)
393393

394+
static inline unsigned long map_pcr_to_cap(unsigned long pcr)
395+
{
396+
unsigned long cap = 0;
397+
398+
switch (pcr) {
399+
case PCR_ARCH_300:
400+
cap = H_GUEST_CAP_POWER9;
401+
break;
402+
case PCR_ARCH_31:
403+
cap = H_GUEST_CAP_POWER10;
404+
break;
405+
default:
406+
break;
407+
}
408+
409+
return cap;
410+
}
411+
394412
static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
395413
{
396414
unsigned long host_pcr_bit = 0, guest_pcr_bit = 0, cap = 0;
@@ -424,11 +442,9 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
424442
break;
425443
case PVR_ARCH_300:
426444
guest_pcr_bit = PCR_ARCH_300;
427-
cap = H_GUEST_CAP_POWER9;
428445
break;
429446
case PVR_ARCH_31:
430447
guest_pcr_bit = PCR_ARCH_31;
431-
cap = H_GUEST_CAP_POWER10;
432448
break;
433449
default:
434450
return -EINVAL;
@@ -440,6 +456,12 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
440456
return -EINVAL;
441457

442458
if (kvmhv_on_pseries() && kvmhv_is_nestedv2()) {
459+
/*
460+
* 'arch_compat == 0' would mean the guest should default to
461+
* L1's compatibility. In this case, the guest would pick
462+
* host's PCR and evaluate the corresponding capabilities.
463+
*/
464+
cap = map_pcr_to_cap(guest_pcr_bit);
443465
if (!(cap & nested_capabilities))
444466
return -EINVAL;
445467
}

arch/powerpc/kvm/book3s_hv_nestedv2.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ static int gs_msg_ops_vcpu_fill_info(struct kvmppc_gs_buff *gsb,
138138
vector128 v;
139139
int rc, i;
140140
u16 iden;
141+
u32 arch_compat = 0;
141142

142143
vcpu = gsm->data;
143144

@@ -347,8 +348,23 @@ static int gs_msg_ops_vcpu_fill_info(struct kvmppc_gs_buff *gsb,
347348
break;
348349
}
349350
case KVMPPC_GSID_LOGICAL_PVR:
350-
rc = kvmppc_gse_put_u32(gsb, iden,
351-
vcpu->arch.vcore->arch_compat);
351+
/*
352+
* Though 'arch_compat == 0' would mean the default
353+
* compatibility, arch_compat, being a Guest Wide
354+
* Element, cannot be filled with a value of 0 in GSB
355+
* as this would result into a kernel trap.
356+
* Hence, when `arch_compat == 0`, arch_compat should
357+
* default to L1's PVR.
358+
*/
359+
if (!vcpu->arch.vcore->arch_compat) {
360+
if (cpu_has_feature(CPU_FTR_ARCH_31))
361+
arch_compat = PVR_ARCH_31;
362+
else if (cpu_has_feature(CPU_FTR_ARCH_300))
363+
arch_compat = PVR_ARCH_300;
364+
} else {
365+
arch_compat = vcpu->arch.vcore->arch_compat;
366+
}
367+
rc = kvmppc_gse_put_u32(gsb, iden, arch_compat);
352368
break;
353369
}
354370

arch/powerpc/platforms/pseries/pci_dlpar.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn)
3535

3636
pseries_msi_allocate_domains(phb);
3737

38+
ppc_iommu_register_device(phb);
39+
3840
/* Create EEH devices for the PHB */
3941
eeh_phb_pe_create(phb);
4042

@@ -76,6 +78,8 @@ int remove_phb_dynamic(struct pci_controller *phb)
7678
}
7779
}
7880

81+
ppc_iommu_unregister_device(phb);
82+
7983
pseries_msi_free_domains(phb);
8084

8185
/* Keep a reference so phb isn't freed yet */

0 commit comments

Comments
 (0)