qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Igor Mammedov <imammedo@redhat.com>
To: Laszlo Ersek <lersek@redhat.com>
Cc: "Eduardo Habkost" <ehabkost@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	qemu-devel@nongnu.org, "Gerd Hoffmann" <kraxel@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@redhat.com>,
	"Richard Henderson" <rth@twiddle.net>
Subject: Re: [RFC 3/3] acpi: cpuhp: add CPHP_GET_CPU_ID_CMD command
Date: Tue, 22 Oct 2019 16:42:32 +0200	[thread overview]
Message-ID: <20191022164232.0d699b45@redhat.com> (raw)
In-Reply-To: <0f2a4b26-b900-08af-aa3e-f9779ae6b55f@redhat.com>

On Tue, 22 Oct 2019 14:39:24 +0200
Laszlo Ersek <lersek@redhat.com> wrote:

> On 10/21/19 15:06, Laszlo Ersek wrote:
> > On 10/18/19 18:18, Igor Mammedov wrote:  
> >> On Thu, 10 Oct 2019 16:56:18 +0200
> >> Laszlo Ersek <lersek@redhat.com> wrote:  
> 
> [...]
> 
> >>> Can I use the following sequence to detect whether the interface is
> >>> available?
> >>>
> >>> 1. Store 0x0 to command register.
> >>> 2. Store 0x0 to selector register.
> >>> 3. Read 'command data' register.
> >>> 4. If value read is 0, the interface is available.  
> >>
> >> By default legacy register block layout is in place
> >> (i.e. present cpus bitmap) where 1st byte is guarantied to be ">0" as it has
> >> at least the boot CPU bit set and writes to legacy bitmap are ignored.
> >>
> >> Currently AML code code does switching to modern interface, see
> >> docs/specs/acpi_cpu_hotplug.txt:
> >> "
> >>   The first DWORD in bitmap is used in write mode to switch from legacy          
> >>   to new CPU hotplug interface, write 0 into it to do switch.
> >> "
> >> related code "if (opts.has_legacy_cphp) {" and cpu_status_write()
> >>
> >> Considering firmware runs the first, it should enable modern interface
> >> on its own
> >>   1. Store 0x0 to selector register (actually it's store into bitmap to attempt switch). 
> >> and to check if interface is present
> >>   2. Store 0x0 to selector register (to ensure valid selector value (otherwise command is ignored))
> >>   3. Store 0x0 to command register (to be able to read back selector from command data)
> >>   4. Store 0x0 to selector register (because #3 can select the a cpu with events if any)
> >>       be aware libvirt may start QEMU in paused mode (hotplug context) and hotplugs extra CPUs
> >>       with device_add and then let guest run. So firmware may see present CPUs with events
> >>       at boot time.
> >>   5. Read 'command data' register.
> >>   6. If value read is 0, the interface is available.  
> > 
> > Perfect!
> > 
> > Basically this is prepending two "write 0 to selector register" steps to
> > what I suspected. I certainly couldn't figure out the "switch to modern"
> > step, and whether initializing the selector to something valid was
> > needed at boot. Now I know. :) Thanks!
> >   
> >>  
> >>> (Because I assume that unmapped IO ports read as all-bits-one. Is that
> >>> right?)  
> >> that's right but ports are mapped to legacy CPU bitmap, you can't count on all-bits-one case here.  
> 
> It seems I rejoiced too soon.
> 
> When we read the command data register in the last step, that is at
> offset 0x8 in the register block. Considering the legacy "CPU present
> bitmap", if no CPU is present in that range, then the firmware could
> read a zero value. I got confused because I thought we were reading at
> offset 0, which would always have bit0 set (for CPU#0).
> 
> Can we detect the modern interface like this:
> 
> 1. store 0x0 to selector register (attempt to switch)
> 2. read one byte at offset 0 in the register block
> 3. if bit#0 is set, the modern interface is unavailable;
>    otherwise (= bit#0 clear), the modern interface is available
> 
> Here's why:
> 
> - if even the legacy interface is missing, then step 2 is an unassigned
>   read, hence the value read is all-bits-one; bit#0 is set
> 
> - if only the legacy interface is available, then bit#0 stands for
>   CPU#0, it will be set
> 
> - if the switch-over in step 1 is successful, then offset 0 is reserved,
>   hence it returns all-bits-zero.
> 
> With this, if we ever assigned offset 0 for reading, then we'd have to
> define it with bit#0 constantly clear.

There is no need to reserve bit#0 if in step #5 we use s/'command data'/'Command data 2'/

Alternatively we can reserve bit#0 and sequentially read upper half from 'Command data'
(one a new flag to show that there is more data to read).
(Upper half currently is not necessary, it's there for future ARM's MPIDR).

One more thing, this behavior is based on artifacts of x86 machine and AllOnes fallback.
Obviously it won't work with arm/virt, do we care about AVMF at this point?

> Thanks,
> Laszlo



  reply	other threads:[~2019-10-22 14:45 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-09 13:22 [RFC 0/3] acpi: cphp: add CPHP_GET_CPU_ID_CMD command to cpu hotplug MMIO interface Igor Mammedov
2019-10-09 13:22 ` [RFC 1/3] acpi: cpuhp: fix 'Command data' description is spec Igor Mammedov
2019-10-10 12:33   ` Laszlo Ersek
2019-10-17 15:41     ` Igor Mammedov
2019-10-18 13:24       ` Laszlo Ersek
2019-10-10 13:31   ` Laszlo Ersek
2019-10-10 13:36     ` Laszlo Ersek
2019-10-22 17:17       ` Christophe de Dinechin
2019-10-22 17:37         ` Laszlo Ersek
2019-10-09 13:22 ` [RFC 2/3] acpi: cpuhp: add typical usecases into spec Igor Mammedov
2019-10-10 13:04   ` Laszlo Ersek
2019-10-10 13:15     ` Laszlo Ersek
2019-10-10 14:13   ` Laszlo Ersek
2019-10-18 14:45     ` Igor Mammedov
2019-10-09 13:22 ` [RFC 3/3] acpi: cpuhp: add CPHP_GET_CPU_ID_CMD command Igor Mammedov
2019-10-10 14:56   ` Laszlo Ersek
2019-10-10 15:06     ` Michael S. Tsirkin
2019-10-10 17:23       ` Igor Mammedov
2019-10-10 17:53       ` Laszlo Ersek
2019-10-10 19:26       ` Eduardo Habkost
2019-10-11  8:07         ` Laszlo Ersek
2019-10-18 16:18     ` Igor Mammedov
2019-10-21 13:06       ` Laszlo Ersek
2019-10-22 12:39         ` Laszlo Ersek
2019-10-22 14:42           ` Igor Mammedov [this message]
2019-10-22 15:49             ` Laszlo Ersek
2019-10-23 14:59               ` Igor Mammedov
2019-10-24 15:07   ` Philippe Mathieu-Daudé
2019-10-10  9:56 ` [RFC 0/3] acpi: cphp: add CPHP_GET_CPU_ID_CMD command to cpu hotplug MMIO interface Michael S. Tsirkin
2019-10-10 13:39   ` Igor Mammedov
2019-10-10 13:59     ` Michael S. Tsirkin
2019-10-10 15:57       ` Igor Mammedov
2019-10-10 18:15         ` Michael S. Tsirkin
2019-10-11  7:41           ` Laszlo Ersek
2019-10-10 19:20         ` Eduardo Habkost
2019-10-11  8:01           ` Laszlo Ersek
2019-10-11 13:00             ` Michael S. Tsirkin
2019-10-11 16:13               ` Laszlo Ersek
2019-10-11 10:47           ` Igor Mammedov
2019-10-11  6:54         ` Laszlo Ersek
2019-10-10 14:16     ` Eduardo Habkost
2019-10-10 14:49       ` Michael S. Tsirkin
2019-10-10 17:09       ` Igor Mammedov

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=20191022164232.0d699b45@redhat.com \
    --to=imammedo@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=lersek@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=philmd@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).