Re: [PATCH v2 1/2] LoongArch: Fix AP booting issue in VM mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Aug 28, 2024 at 9:34 AM maobibo <maobibo@xxxxxxxxxxx> wrote:
>
> ping.
Queued, thanks.

Huacai

>
>
> On 2024/8/15 下午3:15, Bibo Mao wrote:
> > Native IPI is used for AP booting, it is booting interface between
> > OS and BIOS firmware. The paravirt ipi is only used inside OS, native
> > IPI is necessary to boot AP.
> >
> > When booting AP, BP writes kernel entry address in the HW mailbox of
> > AP and send IPI interrupt to AP. AP executes idle instruction and
> > waits for interrupt or SW events, and clears IPI interrupt and jumps
> > to kernel entry from HW mailbox.
> >
> > Between BP writes HW mailbox and is ready to send IPI to AP, AP is woken
> > up by SW events and jumps to kernel entry, so ACTION_BOOT_CPU IPI
> > interrupt will keep pending during AP booting. And native IPI interrupt
> > handler needs be registered so that it can clear pending native IPI, else
> > there will be endless IRQ handling during AP booting stage.
> >
> > Here native ipi interrupt is initialized even if paravirt IPI is used.
> >
> > Fixes: 74c16b2e2b0c ("LoongArch: KVM: Add PV IPI support on guest side")
> >
> > Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx>
> > ---
> >   arch/loongarch/kernel/paravirt.c | 19 +++++++++++++++++++
> >   1 file changed, 19 insertions(+)
> >
> > diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
> > index 9c9b75b76f62..348920b25460 100644
> > --- a/arch/loongarch/kernel/paravirt.c
> > +++ b/arch/loongarch/kernel/paravirt.c
> > @@ -13,6 +13,9 @@ static int has_steal_clock;
> >   struct static_key paravirt_steal_enabled;
> >   struct static_key paravirt_steal_rq_enabled;
> >   static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64);
> > +#ifdef CONFIG_SMP
> > +static struct smp_ops old_ops;
> > +#endif
> >
> >   static u64 native_steal_clock(int cpu)
> >   {
> > @@ -55,6 +58,11 @@ static void pv_send_ipi_single(int cpu, unsigned int action)
> >       int min, old;
> >       irq_cpustat_t *info = &per_cpu(irq_stat, cpu);
> >
> > +     if (unlikely(action == ACTION_BOOT_CPU)) {
> > +             old_ops.send_ipi_single(cpu, action);
> > +             return;
> > +     }
> > +
> >       old = atomic_fetch_or(BIT(action), &info->message);
> >       if (old)
> >               return;
> > @@ -71,6 +79,12 @@ static void pv_send_ipi_mask(const struct cpumask *mask, unsigned int action)
> >       __uint128_t bitmap = 0;
> >       irq_cpustat_t *info;
> >
> > +     if (unlikely(action == ACTION_BOOT_CPU)) {
> > +             /* Use native IPI to boot AP */
> > +             old_ops.send_ipi_mask(mask, action);
> > +             return;
> > +     }
> > +
> >       if (cpumask_empty(mask))
> >               return;
> >
> > @@ -141,6 +155,8 @@ static void pv_init_ipi(void)
> >   {
> >       int r, swi;
> >
> > +     /* Init native ipi irq since AP booting uses it */
> > +     old_ops.init_ipi();
> >       swi = get_percpu_irq(INT_SWI0);
> >       if (swi < 0)
> >               panic("SWI0 IRQ mapping failed\n");
> > @@ -179,6 +195,9 @@ int __init pv_ipi_init(void)
> >               return 0;
> >
> >   #ifdef CONFIG_SMP
> > +     old_ops.init_ipi        = mp_ops.init_ipi;
> > +     old_ops.send_ipi_single = mp_ops.send_ipi_single;
> > +     old_ops.send_ipi_mask   = mp_ops.send_ipi_mask;
> >       mp_ops.init_ipi         = pv_init_ipi;
> >       mp_ops.send_ipi_single  = pv_send_ipi_single;
> >       mp_ops.send_ipi_mask    = pv_send_ipi_mask;
> >
>
>





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux