On Fri, Sep 28, 2018 at 07:45:50PM +1000, Paul Mackerras wrote: > This adds code to call the H_IPI and H_EOI hypercalls when we are > running as a nested hypervisor (i.e. without the CPU_FTR_HVMODE cpu > feature) and we would otherwise access the XICS interrupt controller > directly or via an OPAL call. > > Signed-off-by: Paul Mackerras <paulus@xxxxxxxxxx> Reviewed-by: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx> > --- > arch/powerpc/kvm/book3s_hv.c | 7 +++++- > arch/powerpc/kvm/book3s_hv_builtin.c | 44 +++++++++++++++++++++++++++++------- > arch/powerpc/kvm/book3s_hv_rm_xics.c | 8 +++++++ > 3 files changed, 50 insertions(+), 9 deletions(-) > > diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c > index 60adf47..8d2f91f 100644 > --- a/arch/powerpc/kvm/book3s_hv.c > +++ b/arch/powerpc/kvm/book3s_hv.c > @@ -173,6 +173,10 @@ static bool kvmppc_ipi_thread(int cpu) > { > unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER); > > + /* If we're a nested hypervisor, fall back to ordinary IPIs for now */ > + if (kvmhv_on_pseries()) > + return false; > + > /* On POWER9 we can use msgsnd to IPI any cpu */ > if (cpu_has_feature(CPU_FTR_ARCH_300)) { > msg |= get_hard_smp_processor_id(cpu); > @@ -5164,7 +5168,8 @@ static int kvmppc_book3s_init_hv(void) > * indirectly, via OPAL. > */ > #ifdef CONFIG_SMP > - if (!xive_enabled() && !local_paca->kvm_hstate.xics_phys) { > + if (!xive_enabled() && !kvmhv_on_pseries() && > + !local_paca->kvm_hstate.xics_phys) { > struct device_node *np; > > np = of_find_compatible_node(NULL, NULL, "ibm,opal-intc"); > diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c > index ccfea5b..a71e2fc 100644 > --- a/arch/powerpc/kvm/book3s_hv_builtin.c > +++ b/arch/powerpc/kvm/book3s_hv_builtin.c > @@ -231,6 +231,15 @@ void kvmhv_rm_send_ipi(int cpu) > void __iomem *xics_phys; > unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER); > > + /* For a nested hypervisor, use the XICS via hcall */ > + if (kvmhv_on_pseries()) { > + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; > + > + plpar_hcall_raw(H_IPI, retbuf, get_hard_smp_processor_id(cpu), > + IPI_PRIORITY); > + return; > + } > + > /* On POWER9 we can use msgsnd for any destination cpu. */ > if (cpu_has_feature(CPU_FTR_ARCH_300)) { > msg |= get_hard_smp_processor_id(cpu); > @@ -460,12 +469,19 @@ static long kvmppc_read_one_intr(bool *again) > return 1; > > /* Now read the interrupt from the ICP */ > - xics_phys = local_paca->kvm_hstate.xics_phys; > - rc = 0; > - if (!xics_phys) > - rc = opal_int_get_xirr(&xirr, false); > - else > - xirr = __raw_rm_readl(xics_phys + XICS_XIRR); > + if (kvmhv_on_pseries()) { > + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; > + > + rc = plpar_hcall_raw(H_XIRR, retbuf, 0xFF); > + xirr = cpu_to_be32(retbuf[0]); > + } else { > + xics_phys = local_paca->kvm_hstate.xics_phys; > + rc = 0; > + if (!xics_phys) > + rc = opal_int_get_xirr(&xirr, false); > + else > + xirr = __raw_rm_readl(xics_phys + XICS_XIRR); > + } > if (rc < 0) > return 1; > > @@ -494,7 +510,13 @@ static long kvmppc_read_one_intr(bool *again) > */ > if (xisr == XICS_IPI) { > rc = 0; > - if (xics_phys) { > + if (kvmhv_on_pseries()) { > + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; > + > + plpar_hcall_raw(H_IPI, retbuf, > + hard_smp_processor_id(), 0xff); > + plpar_hcall_raw(H_EOI, retbuf, h_xirr); > + } else if (xics_phys) { > __raw_rm_writeb(0xff, xics_phys + XICS_MFRR); > __raw_rm_writel(xirr, xics_phys + XICS_XIRR); > } else { > @@ -520,7 +542,13 @@ static long kvmppc_read_one_intr(bool *again) > /* We raced with the host, > * we need to resend that IPI, bummer > */ > - if (xics_phys) > + if (kvmhv_on_pseries()) { > + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; > + > + plpar_hcall_raw(H_IPI, retbuf, > + hard_smp_processor_id(), > + IPI_PRIORITY); > + } else if (xics_phys) > __raw_rm_writeb(IPI_PRIORITY, > xics_phys + XICS_MFRR); > else > diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c > index 8b9f356..b3f5786 100644 > --- a/arch/powerpc/kvm/book3s_hv_rm_xics.c > +++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c > @@ -767,6 +767,14 @@ static void icp_eoi(struct irq_chip *c, u32 hwirq, __be32 xirr, bool *again) > void __iomem *xics_phys; > int64_t rc; > > + if (kvmhv_on_pseries()) { > + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; > + > + iosync(); > + plpar_hcall_raw(H_EOI, retbuf, hwirq); > + return; > + } > + > rc = pnv_opal_pci_msi_eoi(c, hwirq); > > if (rc) -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Attachment:
signature.asc
Description: PGP signature