Commit ab0a97cf authored by Linus Torvalds's avatar Linus Torvalds

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
parents 91403d50 20c8c4da
......@@ -30,6 +30,16 @@ void *pci_traverse_device_nodes(struct device_node *start,
void *data);
extern void pci_devs_phb_init_dynamic(struct pci_controller *phb);
#if defined(CONFIG_IOMMU_API) && (defined(CONFIG_PPC_PSERIES) || \
defined(CONFIG_PPC_POWERNV))
extern void ppc_iommu_register_device(struct pci_controller *phb);
extern void ppc_iommu_unregister_device(struct pci_controller *phb);
#else
static inline void ppc_iommu_register_device(struct pci_controller *phb) { }
static inline void ppc_iommu_unregister_device(struct pci_controller *phb) { }
#endif
/* From rtas_pci.h */
extern void init_pci_config_tokens (void);
extern unsigned long get_phb_buid (struct device_node *);
......
......@@ -1360,7 +1360,7 @@ static struct iommu_device *spapr_tce_iommu_probe_device(struct device *dev)
struct pci_controller *hose;
if (!dev_is_pci(dev))
return ERR_PTR(-EPERM);
return ERR_PTR(-ENODEV);
pdev = to_pci_dev(dev);
hose = pdev->bus->sysdata;
......@@ -1409,6 +1409,21 @@ static const struct attribute_group *spapr_tce_iommu_groups[] = {
NULL,
};
void ppc_iommu_register_device(struct pci_controller *phb)
{
iommu_device_sysfs_add(&phb->iommu, phb->parent,
spapr_tce_iommu_groups, "iommu-phb%04x",
phb->global_number);
iommu_device_register(&phb->iommu, &spapr_tce_iommu_ops,
phb->parent);
}
void ppc_iommu_unregister_device(struct pci_controller *phb)
{
iommu_device_unregister(&phb->iommu);
iommu_device_sysfs_remove(&phb->iommu);
}
/*
* This registers IOMMU devices of PHBs. This needs to happen
* 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)
struct pci_controller *hose;
list_for_each_entry(hose, &hose_list, list_node) {
iommu_device_sysfs_add(&hose->iommu, hose->parent,
spapr_tce_iommu_groups, "iommu-phb%04x",
hose->global_number);
iommu_device_register(&hose->iommu, &spapr_tce_iommu_ops,
hose->parent);
ppc_iommu_register_device(hose);
}
return 0;
}
......
......@@ -391,6 +391,24 @@ static void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 pvr)
/* Dummy value used in computing PCR value below */
#define PCR_ARCH_31 (PCR_ARCH_300 << 1)
static inline unsigned long map_pcr_to_cap(unsigned long pcr)
{
unsigned long cap = 0;
switch (pcr) {
case PCR_ARCH_300:
cap = H_GUEST_CAP_POWER9;
break;
case PCR_ARCH_31:
cap = H_GUEST_CAP_POWER10;
break;
default:
break;
}
return cap;
}
static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
{
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)
break;
case PVR_ARCH_300:
guest_pcr_bit = PCR_ARCH_300;
cap = H_GUEST_CAP_POWER9;
break;
case PVR_ARCH_31:
guest_pcr_bit = PCR_ARCH_31;
cap = H_GUEST_CAP_POWER10;
break;
default:
return -EINVAL;
......@@ -440,6 +456,12 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
return -EINVAL;
if (kvmhv_on_pseries() && kvmhv_is_nestedv2()) {
/*
* 'arch_compat == 0' would mean the guest should default to
* L1's compatibility. In this case, the guest would pick
* host's PCR and evaluate the corresponding capabilities.
*/
cap = map_pcr_to_cap(guest_pcr_bit);
if (!(cap & nested_capabilities))
return -EINVAL;
}
......
......@@ -138,6 +138,7 @@ static int gs_msg_ops_vcpu_fill_info(struct kvmppc_gs_buff *gsb,
vector128 v;
int rc, i;
u16 iden;
u32 arch_compat = 0;
vcpu = gsm->data;
......@@ -347,8 +348,23 @@ static int gs_msg_ops_vcpu_fill_info(struct kvmppc_gs_buff *gsb,
break;
}
case KVMPPC_GSID_LOGICAL_PVR:
rc = kvmppc_gse_put_u32(gsb, iden,
vcpu->arch.vcore->arch_compat);
/*
* Though 'arch_compat == 0' would mean the default
* compatibility, arch_compat, being a Guest Wide
* Element, cannot be filled with a value of 0 in GSB
* as this would result into a kernel trap.
* Hence, when `arch_compat == 0`, arch_compat should
* default to L1's PVR.
*/
if (!vcpu->arch.vcore->arch_compat) {
if (cpu_has_feature(CPU_FTR_ARCH_31))
arch_compat = PVR_ARCH_31;
else if (cpu_has_feature(CPU_FTR_ARCH_300))
arch_compat = PVR_ARCH_300;
} else {
arch_compat = vcpu->arch.vcore->arch_compat;
}
rc = kvmppc_gse_put_u32(gsb, iden, arch_compat);
break;
}
......
......@@ -35,6 +35,8 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn)
pseries_msi_allocate_domains(phb);
ppc_iommu_register_device(phb);
/* Create EEH devices for the PHB */
eeh_phb_pe_create(phb);
......@@ -76,6 +78,8 @@ int remove_phb_dynamic(struct pci_controller *phb)
}
}
ppc_iommu_unregister_device(phb);
pseries_msi_free_domains(phb);
/* Keep a reference so phb isn't freed yet */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment