All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rafael@kernel.org>
To: "Kuppuswamy,
	Sathyanarayanan"  <sathyanarayanan.kuppuswamy@linux.intel.com>
Cc: Rafael J Wysocki <rjw@rjwysocki.net>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H . Peter Anvin" <hpa@zytor.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Len Brown <lenb@kernel.org>,
	Robert Moore <robert.moore@intel.com>,
	Erik Kaneda <erik.kaneda@intel.com>,
	ACPI Devel Maling List <linux-acpi@vger.kernel.org>,
	"open list:ACPI COMPONENT ARCHITECTURE (ACPICA)"
	<devel@acpica.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	"the arch/x86 maintainers" <x86@kernel.org>,
	Sean Christopherson <sean.j.christopherson@intel.com>,
	Andi Kleen <ak@linux.intel.com>
Subject: Re: [PATCH v3 3/3] x86/acpi, x86/boot: Add multiprocessor wake-up support
Date: Mon, 10 May 2021 18:55:14 +0200	[thread overview]
Message-ID: <CAJZ5v0gsqyXSr+Kw603333PZ=gnsBizNhyLAcu588OChEHT=AQ@mail.gmail.com> (raw)
In-Reply-To: <97e14cdc-ea98-18b8-0c89-db52440a7716@linux.intel.com>

On Mon, May 10, 2021 at 6:33 PM Kuppuswamy, Sathyanarayanan
<sathyanarayanan.kuppuswamy@linux.intel.com> wrote:
>
> Hi Rafael/Thomas,
>
> On 4/25/21 7:39 PM, Kuppuswamy Sathyanarayanan wrote:
> > As per ACPI specification r6.4, sec 5.2.12.19, a new sub
> > structure – multiprocessor wake-up structure - is added to the
> > ACPI Multiple APIC Description Table (MADT) to describe the
> > information of the mailbox. If a platform firmware produces the
> > multiprocessor wake-up structure, then OS may use this new
> > mailbox-based mechanism to wake up the APs.
> >
> > Add ACPI MADT wake table parsing support for x86 platform and if
> > MADT wake table is present, update apic->wakeup_secondary_cpu with
> > new API which uses MADT wake mailbox to wake-up CPU.
>
> Gentle ping. Any comments on this patch? I think I have addressed
> the concerns raised by you in previous version.
>
> >
> > Co-developed-by: Sean Christopherson <sean.j.christopherson@intel.com>
> > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> > Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> > Reviewed-by: Andi Kleen <ak@linux.intel.com>
> > ---
> >   arch/x86/include/asm/apic.h |  3 ++
> >   arch/x86/kernel/acpi/boot.c | 79 +++++++++++++++++++++++++++++++++++++
> >   arch/x86/kernel/apic/apic.c |  8 ++++
> >   3 files changed, 90 insertions(+)
> >
> > diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
> > index 412b51e059c8..3e94e1f402ea 100644
> > --- a/arch/x86/include/asm/apic.h
> > +++ b/arch/x86/include/asm/apic.h
> > @@ -487,6 +487,9 @@ static inline unsigned int read_apic_id(void)
> >       return apic->get_apic_id(reg);
> >   }
> >
> > +typedef int (*wakeup_cpu_handler)(int apicid, unsigned long start_eip);
> > +extern void acpi_wake_cpu_handler_update(wakeup_cpu_handler handler);
> > +
> >   extern int default_apic_id_valid(u32 apicid);
> >   extern int default_acpi_madt_oem_check(char *, char *);
> >   extern void default_setup_apic_routing(void);
> > diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
> > index 14cd3186dc77..fce2aa7d718f 100644
> > --- a/arch/x86/kernel/acpi/boot.c
> > +++ b/arch/x86/kernel/acpi/boot.c
> > @@ -65,6 +65,9 @@ int acpi_fix_pin2_polarity __initdata;
> >   static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
> >   #endif
> >
> > +static struct acpi_madt_multiproc_wakeup_mailbox *acpi_mp_wake_mailbox;
> > +static u64 acpi_mp_wake_mailbox_paddr;
> > +
> >   #ifdef CONFIG_X86_IO_APIC
> >   /*
> >    * Locks related to IOAPIC hotplug
> > @@ -329,6 +332,52 @@ acpi_parse_lapic_nmi(union acpi_subtable_headers * header, const unsigned long e
> >       return 0;
> >   }
> >
> > +static void acpi_mp_wake_mailbox_init(void)
> > +{
> > +     if (acpi_mp_wake_mailbox)
> > +             return;
> > +
> > +     acpi_mp_wake_mailbox = memremap(acpi_mp_wake_mailbox_paddr,
> > +                     sizeof(*acpi_mp_wake_mailbox), MEMREMAP_WB);
> > +}
> > +
> > +static int acpi_wakeup_cpu(int apicid, unsigned long start_ip)
> > +{
> > +     u8 timeout = 0xFF;
> > +
> > +     acpi_mp_wake_mailbox_init();
> > +
> > +     if (!acpi_mp_wake_mailbox)
> > +             return -EINVAL;
> > +
> > +     /*
> > +      * Mailbox memory is shared between firmware and OS. Firmware will
> > +      * listen on mailbox command address, and once it receives the wakeup
> > +      * command, CPU associated with the given apicid will be booted. So,
> > +      * the value of apic_id and wakeup_vector has to be set before updating
> > +      * the wakeup command. So use WRITE_ONCE to let the compiler know about
> > +      * it and preserve the order of writes.
> > +      */
> > +     WRITE_ONCE(acpi_mp_wake_mailbox->apic_id, apicid);
> > +     WRITE_ONCE(acpi_mp_wake_mailbox->wakeup_vector, start_ip);
> > +     WRITE_ONCE(acpi_mp_wake_mailbox->command, ACPI_MP_WAKE_COMMAND_WAKEUP);
> > +
> > +     /*
> > +      * After writing wakeup command, wait for maximum timeout of 0xFF
> > +      * for firmware to reset the command address back zero to indicate
> > +      * the successful reception of command.
> > +      * NOTE: 255 as timeout value is decided based on our experiments.
> > +      *
> > +      * XXX: Change the timeout once ACPI specification comes up with
> > +      *      standard maximum timeout value.
> > +      */
> > +     while (READ_ONCE(acpi_mp_wake_mailbox->command) && timeout--)
> > +             cpu_relax();
> > +
> > +     /* If timedout, return error */
> > +     return timeout ? 0 : -EIO;

I'm not sure how my comment regarding the fact that for a given CPU
this function is only usable once has been addressed.

While it may not be a practical concern in the use case that you are
after (TDX), this is a generic mechanism and it needs to cover other
possible usage scenarios.

> > +}
> > +
> >   #endif                              /*CONFIG_X86_LOCAL_APIC */
> >
> >   #ifdef CONFIG_X86_IO_APIC
> > @@ -1086,6 +1135,30 @@ static int __init acpi_parse_madt_lapic_entries(void)
> >       }
> >       return 0;
> >   }
> > +
> > +static int __init acpi_parse_mp_wake(union acpi_subtable_headers *header,
> > +                                   const unsigned long end)
> > +{
> > +     struct acpi_madt_multiproc_wakeup *mp_wake;
> > +
> > +     if (acpi_mp_wake_mailbox)
> > +             return -EINVAL;
> > +
> > +     if (!IS_ENABLED(CONFIG_SMP))
> > +             return -ENODEV;
> > +
> > +     mp_wake = (struct acpi_madt_multiproc_wakeup *) header;
> > +     if (BAD_MADT_ENTRY(mp_wake, end))
> > +             return -EINVAL;
> > +
> > +     acpi_table_print_madt_entry(&header->common);
> > +
> > +     acpi_mp_wake_mailbox_paddr = mp_wake->base_address;
> > +
> > +     acpi_wake_cpu_handler_update(acpi_wakeup_cpu);
> > +
> > +     return 0;
> > +}
> >   #endif                              /* CONFIG_X86_LOCAL_APIC */
> >
> >   #ifdef      CONFIG_X86_IO_APIC
> > @@ -1284,6 +1357,12 @@ static void __init acpi_process_madt(void)
> >
> >                               smp_found_config = 1;
> >                       }
> > +
> > +                     /*
> > +                      * Parse MADT MP Wake entry.
> > +                      */
> > +                     acpi_table_parse_madt(ACPI_MADT_TYPE_MULTIPROC_WAKEUP,
> > +                                           acpi_parse_mp_wake, 1);
> >               }
> >               if (error == -EINVAL) {
> >                       /*
> > diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
> > index 4f26700f314d..f1b90a4b89e8 100644
> > --- a/arch/x86/kernel/apic/apic.c
> > +++ b/arch/x86/kernel/apic/apic.c
> > @@ -2554,6 +2554,14 @@ u32 x86_msi_msg_get_destid(struct msi_msg *msg, bool extid)
> >   }
> >   EXPORT_SYMBOL_GPL(x86_msi_msg_get_destid);
> >
> > +void __init acpi_wake_cpu_handler_update(wakeup_cpu_handler handler)
> > +{
> > +     struct apic **drv;
> > +
> > +     for (drv = __apicdrivers; drv < __apicdrivers_end; drv++)
> > +             (*drv)->wakeup_secondary_cpu = handler;
> > +}
> > +
> >   /*
> >    * Override the generic EOI implementation with an optimized version.
> >    * Only called during early boot when only one CPU is active and with
> >
>
> --
> Sathyanarayanan Kuppuswamy
> Linux Kernel Developer

WARNING: multiple messages have this Message-ID (diff)
From: Rafael J. Wysocki <rafael at kernel.org>
To: devel@acpica.org
Subject: [Devel] Re: [PATCH v3 3/3] x86/acpi, x86/boot: Add multiprocessor wake-up support
Date: Mon, 10 May 2021 18:55:14 +0200	[thread overview]
Message-ID: <CAJZ5v0gsqyXSr+Kw603333PZ=gnsBizNhyLAcu588OChEHT=AQ@mail.gmail.com> (raw)
In-Reply-To: 97e14cdc-ea98-18b8-0c89-db52440a7716@linux.intel.com

[-- Attachment #1: Type: text/plain, Size: 7488 bytes --]

On Mon, May 10, 2021 at 6:33 PM Kuppuswamy, Sathyanarayanan
<sathyanarayanan.kuppuswamy(a)linux.intel.com> wrote:
>
> Hi Rafael/Thomas,
>
> On 4/25/21 7:39 PM, Kuppuswamy Sathyanarayanan wrote:
> > As per ACPI specification r6.4, sec 5.2.12.19, a new sub
> > structure – multiprocessor wake-up structure - is added to the
> > ACPI Multiple APIC Description Table (MADT) to describe the
> > information of the mailbox. If a platform firmware produces the
> > multiprocessor wake-up structure, then OS may use this new
> > mailbox-based mechanism to wake up the APs.
> >
> > Add ACPI MADT wake table parsing support for x86 platform and if
> > MADT wake table is present, update apic->wakeup_secondary_cpu with
> > new API which uses MADT wake mailbox to wake-up CPU.
>
> Gentle ping. Any comments on this patch? I think I have addressed
> the concerns raised by you in previous version.
>
> >
> > Co-developed-by: Sean Christopherson <sean.j.christopherson(a)intel.com>
> > Signed-off-by: Sean Christopherson <sean.j.christopherson(a)intel.com>
> > Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy(a)linux.intel.com>
> > Reviewed-by: Andi Kleen <ak(a)linux.intel.com>
> > ---
> >   arch/x86/include/asm/apic.h |  3 ++
> >   arch/x86/kernel/acpi/boot.c | 79 +++++++++++++++++++++++++++++++++++++
> >   arch/x86/kernel/apic/apic.c |  8 ++++
> >   3 files changed, 90 insertions(+)
> >
> > diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
> > index 412b51e059c8..3e94e1f402ea 100644
> > --- a/arch/x86/include/asm/apic.h
> > +++ b/arch/x86/include/asm/apic.h
> > @@ -487,6 +487,9 @@ static inline unsigned int read_apic_id(void)
> >       return apic->get_apic_id(reg);
> >   }
> >
> > +typedef int (*wakeup_cpu_handler)(int apicid, unsigned long start_eip);
> > +extern void acpi_wake_cpu_handler_update(wakeup_cpu_handler handler);
> > +
> >   extern int default_apic_id_valid(u32 apicid);
> >   extern int default_acpi_madt_oem_check(char *, char *);
> >   extern void default_setup_apic_routing(void);
> > diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
> > index 14cd3186dc77..fce2aa7d718f 100644
> > --- a/arch/x86/kernel/acpi/boot.c
> > +++ b/arch/x86/kernel/acpi/boot.c
> > @@ -65,6 +65,9 @@ int acpi_fix_pin2_polarity __initdata;
> >   static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
> >   #endif
> >
> > +static struct acpi_madt_multiproc_wakeup_mailbox *acpi_mp_wake_mailbox;
> > +static u64 acpi_mp_wake_mailbox_paddr;
> > +
> >   #ifdef CONFIG_X86_IO_APIC
> >   /*
> >    * Locks related to IOAPIC hotplug
> > @@ -329,6 +332,52 @@ acpi_parse_lapic_nmi(union acpi_subtable_headers * header, const unsigned long e
> >       return 0;
> >   }
> >
> > +static void acpi_mp_wake_mailbox_init(void)
> > +{
> > +     if (acpi_mp_wake_mailbox)
> > +             return;
> > +
> > +     acpi_mp_wake_mailbox = memremap(acpi_mp_wake_mailbox_paddr,
> > +                     sizeof(*acpi_mp_wake_mailbox), MEMREMAP_WB);
> > +}
> > +
> > +static int acpi_wakeup_cpu(int apicid, unsigned long start_ip)
> > +{
> > +     u8 timeout = 0xFF;
> > +
> > +     acpi_mp_wake_mailbox_init();
> > +
> > +     if (!acpi_mp_wake_mailbox)
> > +             return -EINVAL;
> > +
> > +     /*
> > +      * Mailbox memory is shared between firmware and OS. Firmware will
> > +      * listen on mailbox command address, and once it receives the wakeup
> > +      * command, CPU associated with the given apicid will be booted. So,
> > +      * the value of apic_id and wakeup_vector has to be set before updating
> > +      * the wakeup command. So use WRITE_ONCE to let the compiler know about
> > +      * it and preserve the order of writes.
> > +      */
> > +     WRITE_ONCE(acpi_mp_wake_mailbox->apic_id, apicid);
> > +     WRITE_ONCE(acpi_mp_wake_mailbox->wakeup_vector, start_ip);
> > +     WRITE_ONCE(acpi_mp_wake_mailbox->command, ACPI_MP_WAKE_COMMAND_WAKEUP);
> > +
> > +     /*
> > +      * After writing wakeup command, wait for maximum timeout of 0xFF
> > +      * for firmware to reset the command address back zero to indicate
> > +      * the successful reception of command.
> > +      * NOTE: 255 as timeout value is decided based on our experiments.
> > +      *
> > +      * XXX: Change the timeout once ACPI specification comes up with
> > +      *      standard maximum timeout value.
> > +      */
> > +     while (READ_ONCE(acpi_mp_wake_mailbox->command) && timeout--)
> > +             cpu_relax();
> > +
> > +     /* If timedout, return error */
> > +     return timeout ? 0 : -EIO;

I'm not sure how my comment regarding the fact that for a given CPU
this function is only usable once has been addressed.

While it may not be a practical concern in the use case that you are
after (TDX), this is a generic mechanism and it needs to cover other
possible usage scenarios.

> > +}
> > +
> >   #endif                              /*CONFIG_X86_LOCAL_APIC */
> >
> >   #ifdef CONFIG_X86_IO_APIC
> > @@ -1086,6 +1135,30 @@ static int __init acpi_parse_madt_lapic_entries(void)
> >       }
> >       return 0;
> >   }
> > +
> > +static int __init acpi_parse_mp_wake(union acpi_subtable_headers *header,
> > +                                   const unsigned long end)
> > +{
> > +     struct acpi_madt_multiproc_wakeup *mp_wake;
> > +
> > +     if (acpi_mp_wake_mailbox)
> > +             return -EINVAL;
> > +
> > +     if (!IS_ENABLED(CONFIG_SMP))
> > +             return -ENODEV;
> > +
> > +     mp_wake = (struct acpi_madt_multiproc_wakeup *) header;
> > +     if (BAD_MADT_ENTRY(mp_wake, end))
> > +             return -EINVAL;
> > +
> > +     acpi_table_print_madt_entry(&header->common);
> > +
> > +     acpi_mp_wake_mailbox_paddr = mp_wake->base_address;
> > +
> > +     acpi_wake_cpu_handler_update(acpi_wakeup_cpu);
> > +
> > +     return 0;
> > +}
> >   #endif                              /* CONFIG_X86_LOCAL_APIC */
> >
> >   #ifdef      CONFIG_X86_IO_APIC
> > @@ -1284,6 +1357,12 @@ static void __init acpi_process_madt(void)
> >
> >                               smp_found_config = 1;
> >                       }
> > +
> > +                     /*
> > +                      * Parse MADT MP Wake entry.
> > +                      */
> > +                     acpi_table_parse_madt(ACPI_MADT_TYPE_MULTIPROC_WAKEUP,
> > +                                           acpi_parse_mp_wake, 1);
> >               }
> >               if (error == -EINVAL) {
> >                       /*
> > diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
> > index 4f26700f314d..f1b90a4b89e8 100644
> > --- a/arch/x86/kernel/apic/apic.c
> > +++ b/arch/x86/kernel/apic/apic.c
> > @@ -2554,6 +2554,14 @@ u32 x86_msi_msg_get_destid(struct msi_msg *msg, bool extid)
> >   }
> >   EXPORT_SYMBOL_GPL(x86_msi_msg_get_destid);
> >
> > +void __init acpi_wake_cpu_handler_update(wakeup_cpu_handler handler)
> > +{
> > +     struct apic **drv;
> > +
> > +     for (drv = __apicdrivers; drv < __apicdrivers_end; drv++)
> > +             (*drv)->wakeup_secondary_cpu = handler;
> > +}
> > +
> >   /*
> >    * Override the generic EOI implementation with an optimized version.
> >    * Only called during early boot when only one CPU is active and with
> >
>
> --
> Sathyanarayanan Kuppuswamy
> Linux Kernel Developer

  reply	other threads:[~2021-05-10 16:55 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-26  2:39 [PATCH v3 0/3] Add multiprocessor wake-up support Kuppuswamy Sathyanarayanan
2021-04-26  2:39 ` [PATCH v3 1/3] ACPICA: ACPI 6.4: MADT: add Multiprocessor Wakeup Mailbox Structure Kuppuswamy Sathyanarayanan
2021-04-26  2:39 ` [PATCH v3 2/3] ACPI/table: Print MADT Wake table information Kuppuswamy Sathyanarayanan
2021-04-26  2:39 ` [PATCH v3 3/3] x86/acpi, x86/boot: Add multiprocessor wake-up support Kuppuswamy Sathyanarayanan
2021-05-10 16:32   ` Kuppuswamy, Sathyanarayanan
2021-05-10 16:55     ` Rafael J. Wysocki [this message]
2021-05-10 16:55       ` [Devel] " Rafael J. Wysocki
2021-05-10 17:10       ` Kuppuswamy, Sathyanarayanan
2021-05-10 17:22         ` Andi Kleen
2021-05-10 17:24           ` Rafael J. Wysocki
2021-05-10 17:24             ` [Devel] " Rafael J. Wysocki
2021-05-10 21:15             ` Kuppuswamy, Sathyanarayanan
2021-05-11 10:45               ` Rafael J. Wysocki
2021-05-11 10:45                 ` [Devel] " Rafael J. Wysocki
2021-05-13 21:37                 ` [PATCH v4 1/1] " Kuppuswamy Sathyanarayanan
2021-05-21 14:18                   ` Kuppuswamy, Sathyanarayanan
2021-05-21 14:45                   ` Peter Zijlstra
2021-05-21 15:14                     ` Kuppuswamy, Sathyanarayanan
2021-05-24  6:02                       ` [PATCH v5 " Kuppuswamy Sathyanarayanan
2021-05-24  6:40                         ` Mika Penttilä
2021-05-24 13:42                           ` Kuppuswamy, Sathyanarayanan
2021-05-24 14:51                         ` Rafael J. Wysocki
2021-05-24 15:35                           ` Kuppuswamy, Sathyanarayanan
2021-05-10 17:23         ` [PATCH v3 3/3] " Rafael J. Wysocki
2021-05-10 17:23           ` [Devel] " Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJZ5v0gsqyXSr+Kw603333PZ=gnsBizNhyLAcu588OChEHT=AQ@mail.gmail.com' \
    --to=rafael@kernel.org \
    --cc=ak@linux.intel.com \
    --cc=devel@acpica.org \
    --cc=erik.kaneda@intel.com \
    --cc=hpa@zytor.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rjw@rjwysocki.net \
    --cc=robert.moore@intel.com \
    --cc=sathyanarayanan.kuppuswamy@linux.intel.com \
    --cc=sean.j.christopherson@intel.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.