From: Igor Mammedov <imammedo@redhat.com>
To: Salil Mehta <salil.mehta@opnsrc.net>
Cc: Salil Mehta <salil.mehta@huawei.com>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
"qemu-arm@nongnu.org" <qemu-arm@nongnu.org>,
"mst@redhat.com" <mst@redhat.com>,
"maz@kernel.org" <maz@kernel.org>,
"jean-philippe@linaro.org" <jean-philippe@linaro.org>,
Jonathan Cameron <jonathan.cameron@huawei.com>,
"lpieralisi@kernel.org" <lpieralisi@kernel.org>,
"peter.maydell@linaro.org" <peter.maydell@linaro.org>,
"richard.henderson@linaro.org" <richard.henderson@linaro.org>,
"armbru@redhat.com" <armbru@redhat.com>,
"andrew.jones@linux.dev" <andrew.jones@linux.dev>,
"david@redhat.com" <david@redhat.com>,
"philmd@linaro.org" <philmd@linaro.org>,
"eric.auger@redhat.com" <eric.auger@redhat.com>,
"will@kernel.org" <will@kernel.org>,
"ardb@kernel.org" <ardb@kernel.org>,
"oliver.upton@linux.dev" <oliver.upton@linux.dev>,
"pbonzini@redhat.com" <pbonzini@redhat.com>,
"gshan@redhat.com" <gshan@redhat.com>,
"rafael@kernel.org" <rafael@kernel.org>,
"borntraeger@linux.ibm.com" <borntraeger@linux.ibm.com>,
"alex.bennee@linaro.org" <alex.bennee@linaro.org>,
"gustavo.romero@linaro.org" <gustavo.romero@linaro.org>,
"npiggin@gmail.com" <npiggin@gmail.com>,
"harshpb@linux.ibm.com" <harshpb@linux.ibm.com>,
"linux@armlinux.org.uk" <linux@armlinux.org.uk>,
"darren@os.amperecomputing.com" <darren@os.amperecomputing.com>,
"ilkka@os.amperecomputing.com" <ilkka@os.amperecomputing.com>,
"vishnu@os.amperecomputing.com" <vishnu@os.amperecomputing.com>,
"gankulkarni@os.amperecomputing.com"
<gankulkarni@os.amperecomputing.com>,
"karl.heubaum@oracle.com" <karl.heubaum@oracle.com>,
"miguel.luis@oracle.com" <miguel.luis@oracle.com>,
zhukeqian <zhukeqian1@huawei.com>,
"wangxiongfeng (C)" <wangxiongfeng2@huawei.com>,
"wangyanan (Y)" <wangyanan55@huawei.com>,
"Wangzhou (B)" <wangzhou1@hisilicon.com>,
Linuxarm <linuxarm@huawei.com>,
"jiakernel2@gmail.com" <jiakernel2@gmail.com>,
"maobibo@loongson.cn" <maobibo@loongson.cn>,
"lixianglai@loongson.cn" <lixianglai@loongson.cn>,
"shahuang@redhat.com" <shahuang@redhat.com>,
"zhao1.liu@intel.com" <zhao1.liu@intel.com>
Subject: Re: [PATCH RFC V6 14/24] arm/acpi: Introduce dedicated CPU OSPM interface for ARM-like platforms
Date: Wed, 12 Nov 2025 17:55:40 +0100 [thread overview]
Message-ID: <20251112175540.7407860a@fedora> (raw)
In-Reply-To: <CAJ7pxebaqZusZAF7y=881=3dA+YVNeYUZ8BCKb_tQPvn7BbNww@mail.gmail.com>
On Fri, 10 Oct 2025 03:00:15 +0000
Salil Mehta <salil.mehta@opnsrc.net> wrote:
> Hi Igor,
>
> On Tue, Oct 7, 2025 at 12:06 PM Igor Mammedov <imammedo@redhat.com> wrote:
>
> > On Tue, 7 Oct 2025 11:15:47 +0000
> > Salil Mehta <salil.mehta@huawei.com> wrote:
> >
> > > Hi Igor,
> > >
> > > Thanks for the reviews and sorry for the late reply. Please find my
> > replies inline.
> > >
> > >
> > > > From: Igor Mammedov <imammedo@redhat.com>
> > > > Sent: Friday, October 3, 2025 3:58 PM
> > > >
> > > > On Wed, 1 Oct 2025 01:01:17 +0000
> > > > salil.mehta@opnsrc.net wrote:
> > > >
> > > > > From: Salil Mehta <salil.mehta@huawei.com>
> > > > >
> > > > > The existing ACPI CPU hotplug interface is built for x86 platforms
> > > > > where CPUs can be inserted or removed and resources are allocated
> > > > > dynamically. On ARM, CPUs are never hotpluggable: resources are
> > > > > allocated at boot and QOM vCPU objects always exist. Instead, CPUs
> > are
> > > > > administratively managed by toggling ACPI _STA to enable or disable
> > > > > them, which gives a hotplug-like effect but does not match the x86
> > model.
> > > > >
> > > > > Reusing the x86 hotplug AML code would complicate maintenance since
> > > > > much of its logic relies on toggling the _STA.Present bit to notify
> > > > > OSPM about CPU insertion or removal. Such usage is not
> > architecturally
> > > > > valid on ARM, where CPUs cannot appear or disappear at runtime.
> > Mixing
> > > > > both models in one interface would increase complexity and make the
> > > > > AML harder to extend. A separate path is therefore required. The new
> > > > > design is heavily inspired by the CPU hotplug interface but avoids
> > its
> > > > unsuitable semantics.
> > > >
> > > > Let me ask how much existing CPUHP AML code will become, if you reuse
> > it
> > > > and add handling of 'enabled' bit there?
> > > >
> > > > Would it be the same 700LOC as in this patch, which is basically
> > duplication of
> > > > existing CPUHP ACPI interface?
> > >
> > >
> > > It is by design as we have adopted non-hotplug approach now and closely
> > aligned
> > > ourselves with what PSCI standard perceives to be the definition of CPU
> > hotplug on ARM
> > > platforms - at least, as of today! And it is *NOT* what 'CPU hotplug'
> > means on x86 platform.
> >
> > There is no argument that they are different but,
> > Could you point to PSCI specific parts in this patch?
> >
>
> Yes, sure.
>
> https://lore.kernel.org/qemu-devel/20251001010127.3092631-1-salil.mehta@opnsrc.net/T/#m926978ce8b91a1f2cca88b5b579a8aedd9e62d2c
> https://lore.kernel.org/qemu-devel/20251001010127.3092631-1-salil.mehta@opnsrc.net/T/#mb96b36ebf68b0455b657ce495cac2aee9fbf0f67
>
>
>
> >
> > > In crux, this means,
> > > 1. Dropping any hotplug/unplug infrastructure and its related
> > paraphernalia from the
> > > ARM implementation till the time the meaning of physical CPU hotplug
> > is not clear as
> > > per the specification. We do not want to model in Qemu something
> > which does not
> > > exist or defined, especially for the CPU hotplug case.
> >
> > there is 'opts' config struct that lets user to opt in/out from specific
> > AML
> > being generated. You could use that to disable some hotplug only bits of
> > AML.
> > Other bits that are more generic/reusable, just refactor/rename them to a
> > more
> > generic names.
> >
>
> Sure, but what you are suggesting is a code reuse strategy not a design
> problem.
> We can take this as a cleanup activity later on or even in parallel. I've
> no reservations
> about that. Why hold ARM patches hostage to these benign optimizations?
Let me use anology:
if QOM doesn't suite purpose / too complex and someone duplicates it dropping
some parts of it along the way, the request to merge it (even temporarily) very
likely will get hard refusal.
It's ok to do this for RFC/POC to play around but it's not ok to merge
such code into mainline.
> BTW, that 'opt' is one of the ugliest parts of this function. Why do other
> architectures
> have to worry about initializing legacy bits of x86 in the common code
> before calling
> AML function?
it's a price of unification.
If there is a better idea to deal with it, patches are welcome.
>
>
> > > 2. This also means *NOT* enabling the ACPI_CPU_HOTPLUG compilation
> > switch to
> > > preserve the sanctity of the clean design.
> >
> > that's semantics, I'd suggest renaming that to ACPI_CPU.
> >
>
>
> It is not about this. To make it hotplug agnostic we would need to start
> with new minimal
> code and then add on top of it what is present in acpi/cpu.c incrementally.
> This can be
> done in parallel by
>
> 1. accepting the minimal new code. This will keep the ball rolling for ARM
> 2. adding the x86 stuff incrementally over that minimal new AML file (with
> other name)
> 3. Testing a new file doesn't break x86 functionality
> 4. replacing the old file acpi/cpus.c with a new common file.
Typically duplicating a huge chunk of code is frowned upon,
there might be exceptions in case of putting out fires and we need to get
a fix quickly in (even then it's not likely to be merged),
but this series is very much not the case.
On top of that, I'd say double no to duplicating guest ABI that
the copied code exposes to guest and than trying to reconcile it later.
So, please reuse/refactor existing code.
> >
> > > 3. Yes, there is a code duplicity for now but that’s a case of further
> > optimization and
> > > cleanup not a design issue. Some of them are:
> > > (1) ACPI device-check and eject-request handling code can be
> > extracted and
> > > made generic for all devices not just for CPUs.
> >
> > make it more generic in acpi/cpu.c, instead of copying.
> > I don't have any objections to refactoring existing code if it makes sense
> > and
> > we can share the code.
> >
>
> In principle I agree with your point about carving a common code that works
> for all.
> I'm only requesting how this could be done in a non-disrupting way by not
> holding
> the current patches of ARM for this change. This change will require time
> and most
> importantly testing across many architectures.
>
>
> >
> > > (2) Right now, acpi/cpu.c is assuming that resources and templates
> > should be
> > > same for all the CPUs using CPUs AML described in it. There is no
> > need for
> > > such a restriction. Every platform should be free to choose the way
> > it wants to
> > > manage the resources and the interpretation of the fields inside it.
> >
> > be more specific why you'd need different resources/MMIO layout for this
> > series?
> >
>
> IIRC in RFC V5, you object to adding 'enabled' bit as it was breaking x86
> ABI
> because of some backward compatibility issue?
>
>
> >
> > The thing is if we copied every time when we needed something that's a bit
> > different,
> > we would end up with unsupportable/bloated QEMU.
> >
>
> For sure. I totally agree with it but it was an informed decision here
> internally to keep
> the ACPI part separate for this series because of the past review comments
> and the
> difficulty in dealing with very minimalistic changes we proposed for ACPI
> part.
>
>
> >
> > > (3) Call backs used with GED makes an assumption of HOTPLUG
> > interface etc.
> > > (4) In fact, the prototype of the GED event handler makes a similar
> > mistake of
> > > assuming that GED is only meant for devices supporting hotplug when
> > this is not
> > > the case even as per the ACPI specification.
> > please be more specific and point to problematic code.
> >
>
> void build_ged_aml(Aml *table, const char *name, HotplugHandler
> *hotplug_dev,
> uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base)
>
>
> GED is not just for hotplug handling.
It's not clear what you are trying to say/point out.
If I'd guess, you've meant arg "HotplugHandler *hotplug_dev".
For one, HotplugHandler long overgrown its name, it's more like PlugHandler,
meant to wire things up. One can rename it if necessary.
Also suggest a better way/prototype for build_ged_aml() if it doesn't work
for you.
>
> >
> > current acpi/cpu.c might be compiled under ACPI_CPU_HOTPLUG knob but it's
> > not really
> > limited to hotplug, the reason for being compiled as such is that hotplug
> > was
> > the sole reason for building CPUs AML at all.
> >
>
> Got it. so as you rightly suggested it needs refactoring. The only request
> I'm making is
> let us do it parallely and incrementally without holding ARM patches for
> this change.
in cover letter review, I've suggested a way how to split the series in
a digestible parts some of which could be done in parallel.
wrt this patch see my comments above.
>
> >
> > What I see in the patch is simplifying current code somewhat by dropping
> > some hotplug related bits and a bunch of renaming.
> > Otherwise it's pretty much duplicating current acpi/cpu.c.
> >
> > Beside that simplification, I don't see any reason why duplicating such
> > amount is good idea.
> > Consider making exiting acpi/cpu.c more generic instead.
> >
>
> Intial idea was to make it generic enough for any device which uses
> device-check
> and eject-request for adding/removing the device but we left it for later
> discussions.
>
>
> > > RFC V5 was an attempt to implement this feature using the hotplug
> > infrastructure
> > > and this RFC V6 is a deviation from previous approach towards
> > non-hotplug. We do
> > > not want a hotchpotch approach because that’s a recipe for future
> > disaster.
> > >
> > >
> > > Many Thanks!
> > > Salil.
> > >
> > >
> > > >
> > > > >
> > > > > This patch adds a dedicated CPU OSPM (Operating System Power
> > > > > Management) interface. It provides a memory-mapped control region
> > with
> > > > > selector, flags, command, and data fields, and AML methods for
> > > > > device-check, eject request, and _OST reporting. OSPM is notified
> > > > > through GED events and can coordinate CPU events directly with QEMU.
> > > > > Other ARM-like architectures may also use this interface.
> > > > >
> > > > > Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
> > > > > ---
> > > > > hw/acpi/Kconfig | 3 +
> > > > > hw/acpi/acpi-cpu-ospm-interface-stub.c | 41 ++
> > > > > hw/acpi/cpu_ospm_interface.c | 747
> > > > +++++++++++++++++++++++++
> > > > > hw/acpi/meson.build | 2 +
> > > > > hw/acpi/trace-events | 17 +
> > > > > hw/arm/Kconfig | 1 +
> > > > > include/hw/acpi/cpu_ospm_interface.h | 78 +++
> > > > > 7 files changed, 889 insertions(+)
> > > > > create mode 100644 hw/acpi/acpi-cpu-ospm-interface-stub.c
> > > > > create mode 100644 hw/acpi/cpu_ospm_interface.c create mode 100644
> > > > > include/hw/acpi/cpu_ospm_interface.h
> > > > >
> > > > > diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig index
> > > > > 1d4e9f0845..aa52f0468f 100644
> > > > > --- a/hw/acpi/Kconfig
> > > > > +++ b/hw/acpi/Kconfig
> > > > > @@ -21,6 +21,9 @@ config ACPI_ICH9
> > > > > config ACPI_CPU_HOTPLUG
> > > > > bool
> > > > >
> > > > > +config ACPI_CPU_OSPM_INTERFACE
> > > > > + bool
> > > > > +
> > > > > config ACPI_MEMORY_HOTPLUG
> > > > > bool
> > > > > select MEM_DEVICE
> > > > > diff --git a/hw/acpi/acpi-cpu-ospm-interface-stub.c
> > > > > b/hw/acpi/acpi-cpu-ospm-interface-stub.c
> > > > > new file mode 100644
> > > > > index 0000000000..f6f333f641
> > > > > --- /dev/null
> > > > > +++ b/hw/acpi/acpi-cpu-ospm-interface-stub.c
> > > > > @@ -0,0 +1,41 @@
> > > > > +/*
> > > > > + * ACPI CPU OSPM Interface Handling.
> > > > > + *
> > > > > + * Copyright (c) 2025 Huawei Technologies R&D (UK) Ltd.
> > > > > + *
> > > > > + * Author: Salil Mehta <salil.mehta@huawei.com>
> > > > > + *
> > > > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > > > + *
> > > > > + * This program is free software; you can redistribute it and/or
> > > > > +modify
> > > > > + * it under the terms of the GNU General Public License as published
> > > > > +by
> > > > > + * the Free Software Foundation; either version 2 of the License, or
> > > > > + * (at your option) any later version.
> > > > > + */
> > > > > +
> > > > > +#include "qemu/osdep.h"
> > > > > +#include "hw/acpi/cpu_ospm_interface.h"
> > > > > +
> > > > > +void acpi_cpu_device_check_cb(AcpiCpuOspmState *cpu_st,
> > DeviceState
> > > > *dev,
> > > > > + uint32_t event_st, Error **errp) { }
> > > > > +
> > > > > +void acpi_cpu_eject_request_cb(AcpiCpuOspmState *cpu_st,
> > > > DeviceState *dev,
> > > > > + uint32_t event_st, Error **errp) { }
> > > > > +
> > > > > +void acpi_cpu_eject_cb(AcpiCpuOspmState *cpu_st, DeviceState *dev,
> > > > > +Error **errp) { }
> > > > > +
> > > > > +void acpi_cpu_ospm_state_interface_init(MemoryRegion *as, Object
> > > > *owner,
> > > > > + AcpiCpuOspmState *state,
> > > > > + hwaddr base_addr) { }
> > > > > +
> > > > > +void acpi_cpus_ospm_status(AcpiCpuOspmState *cpu_st,
> > > > ACPIOSTInfoList
> > > > > +***list) { }
> > > > > diff --git a/hw/acpi/cpu_ospm_interface.c
> > > > > b/hw/acpi/cpu_ospm_interface.c new file mode 100644 index
> > > > > 0000000000..61aab8a793
> > > > > --- /dev/null
> > > > > +++ b/hw/acpi/cpu_ospm_interface.c
> > > > > @@ -0,0 +1,747 @@
> > > > > +/*
> > > > > + * ACPI CPU OSPM Interface Handling.
> > > > > + *
> > > > > + * Copyright (c) 2025 Huawei Technologies R&D (UK) Ltd.
> > > > > + *
> > > > > + * Author: Salil Mehta <salil.mehta@huawei.com>
> > > > > + *
> > > > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > > > + *
> > > > > + * This program is free software; you can redistribute it and/or
> > > > > +modify
> > > > > + * it under the terms of the GNU General Public License as published
> > > > > +by
> > > > > + * the Free Software Foundation; either version 2 of the License, or
> > > > > + * (at your option) any later version.
> > > > > + */
> > > > > +
> > > > > +#include "qemu/osdep.h"
> > > > > +#include "migration/vmstate.h"
> > > > > +#include "hw/core/cpu.h"
> > > > > +#include "qapi/error.h"
> > > > > +#include "trace.h"
> > > > > +#include "qapi/qapi-events-acpi.h"
> > > > > +#include "hw/acpi/cpu_ospm_interface.h"
> > > > > +
> > > > > +/* CPU identifier and resource device */
> > > > > +#define CPU_NAME_FMT "C%.03X" /* CPU name format (e.g., C001)
> > > > */
> > > > > +#define CPU_RES_DEVICE "CPUR" /* CPU resource device name */
> > > > > +#define CPU_DEVICE "CPUS" /* CPUs device name */
> > > > > +#define CPU_LOCK "CPLK" /* CPU lock object */
> > > > > +/* ACPI method(_STA, _EJ0, etc.) handlers */
> > > > > +#define CPU_STS_METHOD "CSTA" /* CPU status method
> > > > (_STA.Enabled) */
> > > > > +#define CPU_SCAN_METHOD "CSCN" /* CPU scan method for
> > > > enumeration */
> > > > > +#define CPU_NOTIFY_METHOD "CTFY" /* Notify method for CPU events
> > > > */
> > > > > +#define CPU_EJECT_METHOD "CEJ0" /* CPU eject method (_EJ0) */
> > > > > +#define CPU_OST_METHOD "COST" /* OSPM status reporting (_OST) */
> > > > > +/* CPU MMIO region fields (in PRST region) */
> > > > > +#define CPU_SELECTOR "CSEL" /* CPU selector index (WO) */
> > > > > +#define CPU_ENABLED_F "CPEN" /* Flag: CPU enabled status(_STA)
> > > > (RO) */
> > > > > +#define CPU_DEVCHK_F "CDCK" /* Flag: Device-check event (RW) */
> > > > > +#define CPU_EJECTRQ_F "CEJR" /* Flag: Eject-request event (RW)*/
> > > > > +#define CPU_EJECT_F "CEJ0" /* Flag: Ejection trigger (WO) */
> > > > > +#define CPU_COMMAND "CCMD" /* Command register (RW) */
> > > > > +#define CPU_DATA "CDAT" /* Data register (RW) */
> > > > > +
> > > > > + /*
> > > > > + * CPU OSPM Interface MMIO Layout (Total: 16 bytes)
> > > > > + *
> > > > > + *
> > > > > +
> > +--------+--------+--------+--------+--------+--------+--------+----
> > > > > + ----+
> > > > > + * | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 |
> > > > > + 0x07 |
> > > > > + *
> > +--------+--------+--------+--------+--------+--------+--------+--------+
> > > > > + * | Selector (DWord, write-only) | Flags |Command
> > |Reserved|
> > > > > + * | | (RO/RW)| (WO)
> > |(2B pad)|
> > > > > + * | 4 bytes (32 bits) | 1B | 1B |
> > 2B |
> > > > > + *
> > > > > +
> > +-------------------------------------------------------------------
> > > > > + ----+
> > > > > + * | 0x08 | 0x09 | 0x0A | 0x0B | 0x0C | 0x0D | 0x0E |
> > > > > + 0x0F |
> > > > > + *
> > +--------+--------+--------+--------+--------+--------+--------+--------+
> > > > > + * | Data (QWord, read/write)
> > |
> > > > > + * | Used by CPU scan and _OST methods (64 bits)
> > |
> > > > > + *
> > > > > +
> > +-------------------------------------------------------------------
> > > > > + ----+
> > > > > + *
> > > > > + * Field Overview:
> > > > > + *
> > > > > + * - Selector: 4 bytes @0x00 (DWord, WO)
> > > > > + * - Selects target CPU index for the current
> > operation.
> > > > > + * - Flags: 1 byte @0x04 (RO/RW)
> > > > > + * - Bit 0: ENABLED – CPU is powered on (RO)
> > > > > + * - Bit 1: DEVCHK – Device-check completed (RW)
> > > > > + * - Bit 2: EJECTRQ – Guest requests CPU eject (RW)
> > > > > + * - Bit 3: EJECT – Trigger CPU ejection (WO)
> > > > > + * - Bits 4–7: Reserved (write 0)
> > > > > + * - Command: 1 byte @0x05 (WO)
> > > > > + * - Specifies control operation (e.g., scan, _OST,
> > eject).
> > > > > + * - Reserved: 2 bytes @0x06–0x07
> > > > > + * - Alignment padding; must be zero on write.
> > > > > + * - Data: 8 bytes @0x08 (QWord, RW)
> > > > > + * - Input/output for command-specific data.
> > > > > + * - Used by CPU scan or _OST.
> > > > > + */
> > > > > +
> > > > > +/*
> > > > > + * Macros defining the CPU MMIO region layout. Change field sizes
> > > > > +here to
> > > > > + * alter the overall MMIO region size.
> > > > > + */
> > > > > +/* Sub-Field sizes (in bytes) */
> > > > > +#define ACPI_CPU_MR_SELECTOR_SIZE 4 /* Write-only (DWord access)
> > > > */
> > > > > +#define ACPI_CPU_MR_FLAGS_SIZE 1 /* Read-write (Byte access) */
> > > > > +#define ACPI_CPU_MR_RES_FLAGS_SIZE 0 /* Reserved padding */
> > > > > +#define ACPI_CPU_MR_CMD_SIZE 1 /* Write-only (Byte access) */
> > > > > +#define ACPI_CPU_MR_RES_CMD_SIZE 2 /* Reserved padding */
> > > > > +#define ACPI_CPU_MR_CMD_DATA_SIZE 8 /* Read-write (QWord
> > > > access) */
> > > > > +
> > > > > +#define ACPI_CPU_OSPM_IF_MAX_FIELD_SIZE \
> > > > > + MAX_CONST(ACPI_CPU_MR_CMD_DATA_SIZE, \
> > > > > + MAX_CONST(ACPI_CPU_MR_SELECTOR_SIZE, \
> > > > > + MAX_CONST(ACPI_CPU_MR_CMD_SIZE,
> > > > ACPI_CPU_MR_FLAGS_SIZE)))
> > > > > +
> > > > > +/* Validate layout against exported total length */
> > > > > +_Static_assert(ACPI_CPU_OSPM_IF_REG_LEN ==
> > > > > + (ACPI_CPU_MR_SELECTOR_SIZE +
> > > > > + ACPI_CPU_MR_FLAGS_SIZE +
> > > > > + ACPI_CPU_MR_RES_FLAGS_SIZE +
> > > > > + ACPI_CPU_MR_CMD_SIZE +
> > > > > + ACPI_CPU_MR_RES_CMD_SIZE +
> > > > > + ACPI_CPU_MR_CMD_DATA_SIZE),
> > > > > + "ACPI_CPU_OSPM_IF_REG_LEN mismatch with internal MMIO
> > > > > +layout");
> > > > > +
> > > > > +/* Sub-Field sizes (in bits) */
> > > > > +#define ACPI_CPU_MR_SELECTOR_SIZE_BITS \
> > > > > + (ACPI_CPU_MR_SELECTOR_SIZE * BITS_PER_BYTE) /* Write-only
> > > > (DWord
> > > > > +Acc) */ #define ACPI_CPU_MR_FLAGS_SIZE_BITS \
> > > > > + (ACPI_CPU_MR_FLAGS_SIZE * BITS_PER_BYTE) /* Read-write
> > (Byte
> > > > Acc) */
> > > > > +#define ACPI_CPU_MR_RES_FLAGS_SIZE_BITS \
> > > > > + (ACPI_CPU_MR_RES_FLAGS_SIZE * BITS_PER_BYTE) /* Reserved
> > > > padding
> > > > > +*/ #define ACPI_CPU_MR_CMD_SIZE_BITS \
> > > > > + (ACPI_CPU_MR_CMD_SIZE * BITS_PER_BYTE) /* Write-only
> > (Byte
> > > > Acc) */
> > > > > +#define ACPI_CPU_MR_RES_CMD_SIZE_BITS \
> > > > > + (ACPI_CPU_MR_RES_CMD_SIZE * BITS_PER_BYTE) /* Reserved
> > > > padding */
> > > > > +#define ACPI_CPU_MR_CMD_DATA_SIZE_BITS \
> > > > > + (ACPI_CPU_MR_CMD_DATA_SIZE * BITS_PER_BYTE) /* Read-write
> > > > (QWord
> > > > > +Acc) */
> > > > > +
> > > > > +/* Field offsets (in bytes) */
> > > > > +#define ACPI_CPU_MR_SELECTOR_OFFSET_WO 0 #define
> > > > > +ACPI_CPU_MR_FLAGS_OFFSET_RW \
> > > > > + (ACPI_CPU_MR_SELECTOR_OFFSET_WO + \
> > > > > + ACPI_CPU_MR_SELECTOR_SIZE)
> > > > > +#define ACPI_CPU_MR_CMD_OFFSET_WO \
> > > > > + (ACPI_CPU_MR_FLAGS_OFFSET_RW + \
> > > > > + ACPI_CPU_MR_FLAGS_SIZE + \
> > > > > + ACPI_CPU_MR_RES_FLAGS_SIZE)
> > > > > +#define ACPI_CPU_MR_CMD_DATA_OFFSET_RW \
> > > > > + (ACPI_CPU_MR_CMD_OFFSET_WO + \
> > > > > + ACPI_CPU_MR_CMD_SIZE + \
> > > > > + ACPI_CPU_MR_RES_CMD_SIZE)
> > > > > +
> > > > > +/* ensure all offsets are at their natural size alignment
> > boundaries */
> > > > > +#define STATIC_ASSERT_FIELD_ALIGNMENT(offset, type, field_name)
> > > > \
> > > > > + _Static_assert((offset) % sizeof(type) == 0,
> > \
> > > > > + field_name " is not aligned to its natural
> > > > > +boundary")
> > > > > +
> > > > >
> > > > +STATIC_ASSERT_FIELD_ALIGNMENT(ACPI_CPU_MR_SELECTOR_OFFSET_W
> > > > O,
> > > > > + uint32_t, "Selector");
> > > > > +STATIC_ASSERT_FIELD_ALIGNMENT(ACPI_CPU_MR_FLAGS_OFFSET_RW,
> > > > > + uint8_t, "Flags");
> > > > > +STATIC_ASSERT_FIELD_ALIGNMENT(ACPI_CPU_MR_CMD_OFFSET_WO,
> > > > > + uint8_t, "Command");
> > > > >
> > > > +STATIC_ASSERT_FIELD_ALIGNMENT(ACPI_CPU_MR_CMD_DATA_OFFSET_
> > > > RW,
> > > > > + uint64_t, "Command Data");
> > > > > +
> > > > > +/* Flag bit positions (used within 'flags' subfield) */ #define
> > > > > +ACPI_CPU_FLAGS_USED_BITS 4 #define
> > > > ACPI_CPU_MR_FLAGS_BIT_ENABLED
> > > > > +BIT(0) #define ACPI_CPU_MR_FLAGS_BIT_DEVCHK BIT(1) #define
> > > > > +ACPI_CPU_MR_FLAGS_BIT_EJECTRQ BIT(2)
> > > > > +#define ACPI_CPU_MR_FLAGS_BIT_EJECT
> > > > BIT(ACPI_CPU_FLAGS_USED_BITS - 1)
> > > > > +
> > > > > +#define ACPI_CPU_MR_RES_FLAG_BITS (BITS_PER_BYTE -
> > > > > +ACPI_CPU_FLAGS_USED_BITS)
> > > > > +
> > > > > +enum {
> > > > > + ACPI_GET_NEXT_CPU_WITH_EVENT_CMD = 0,
> > > > > + ACPI_OST_EVENT_CMD = 1,
> > > > > + ACPI_OST_STATUS_CMD = 2,
> > > > > + ACPI_CMD_MAX
> > > > > +};
> > > > > +
> > > > > +#define AML_APPEND_MR_RESVD_FIELD(mr_field, size_bits) \
> > > > > + do { \
> > > > > + if ((size_bits) != 0) { \
> > > > > + aml_append((mr_field), aml_reserved_field(size_bits)); \
> > > > > + } \
> > > > > + } while (0)
> > > > > +
> > > > > +#define AML_APPEND_MR_NAMED_FIELD(mr_field, name, size_bits) \
> > > > > + do { \
> > > > > + if ((size_bits) != 0) { \
> > > > > + aml_append((mr_field), aml_named_field((name),
> > (size_bits))); \
> > > > > + } \
> > > > > + } while (0)
> > > > > +
> > > > > +#define AML_CPU_RES_DEV(base, field) \
> > > > > + aml_name("%s.%s.%s", (base), CPU_RES_DEVICE, (field))
> > > > > +
> > > > > +static ACPIOSTInfo *
> > > > > +acpi_cpu_ospm_ost_status(int idx, AcpiCpuOspmStateStatus *cdev) {
> > > > > + ACPIOSTInfo *info = g_new0(ACPIOSTInfo, 1);
> > > > > +
> > > > > + info->source = cdev->ost_event;
> > > > > + info->status = cdev->ost_status;
> > > > > + if (cdev->cpu) {
> > > > > + DeviceState *dev = DEVICE(cdev->cpu);
> > > > > + if (dev->id) {
> > > > > + info->device = g_strdup(dev->id);
> > > > > + }
> > > > > + }
> > > > > + return info;
> > > > > +}
> > > > > +
> > > > > +void acpi_cpus_ospm_status(AcpiCpuOspmState *cpu_st,
> > > > ACPIOSTInfoList
> > > > > +***list) {
> > > > > + ACPIOSTInfoList ***tail = list;
> > > > > + int i;
> > > > > +
> > > > > + for (i = 0; i < cpu_st->dev_count; i++) {
> > > > > + QAPI_LIST_APPEND(*tail, acpi_cpu_ospm_ost_status(i, &cpu_st-
> > > > >devs[i]));
> > > > > + }
> > > > > +}
> > > > > +
> > > > > +static uint64_t
> > > > > +acpi_cpu_ospm_intf_mr_read(void *opaque, hwaddr addr, unsigned
> > > > size)
> > > > > +{
> > > > > + AcpiCpuOspmState *cpu_st = opaque;
> > > > > + AcpiCpuOspmStateStatus *cdev;
> > > > > + uint64_t val = 0;
> > > > > +
> > > > > + if (cpu_st->selector >= cpu_st->dev_count) {
> > > > > + return val;
> > > > > + }
> > > > > + cdev = &cpu_st->devs[cpu_st->selector];
> > > > > + switch (addr) {
> > > > > + case ACPI_CPU_MR_FLAGS_OFFSET_RW:
> > > > > + val |= qdev_check_enabled(DEVICE(cdev->cpu)) ?
> > > > > + ACPI_CPU_MR_FLAGS_BIT_ENABLED : 0;
> > > > > + val |= cdev->devchk_pending ? ACPI_CPU_MR_FLAGS_BIT_DEVCHK
> > :
> > > > 0;
> > > > > + val |= cdev->ejrqst_pending ? ACPI_CPU_MR_FLAGS_BIT_EJECTRQ
> > :
> > > > 0;
> > > > > + trace_acpi_cpuos_if_read_flags(cpu_st->selector, val);
> > > > > + break;
> > > > > + case ACPI_CPU_MR_CMD_DATA_OFFSET_RW:
> > > > > + switch (cpu_st->command) {
> > > > > + case ACPI_GET_NEXT_CPU_WITH_EVENT_CMD:
> > > > > + val = cpu_st->selector;
> > > > > + break;
> > > > > + default:
> > > > > +
> > trace_acpi_cpuos_if_read_invalid_cmd_data(cpu_st->selector,
> > > > > +
> > cpu_st->command);
> > > > > + break;
> > > > > + }
> > > > > + trace_acpi_cpuos_if_read_cmd_data(cpu_st->selector, val);
> > > > > + break;
> > > > > + default:
> > > > > + break;
> > > > > + }
> > > > > + return val;
> > > > > +}
> > > > > +
> > > > > +static void
> > > > > +acpi_cpu_ospm_intf_mr_write(void *opaque, hwaddr addr, uint64_t
> > > > data,
> > > > > + unsigned int size) {
> > > > > + AcpiCpuOspmState *cpu_st = opaque;
> > > > > + AcpiCpuOspmStateStatus *cdev;
> > > > > + ACPIOSTInfo *info;
> > > > > +
> > > > > + assert(cpu_st->dev_count);
> > > > > + if (addr) {
> > > > > + if (cpu_st->selector >= cpu_st->dev_count) {
> > > > > +
> > trace_acpi_cpuos_if_invalid_idx_selected(cpu_st->selector);
> > > > > + return;
> > > > > + }
> > > > > + }
> > > > > +
> > > > > + switch (addr) {
> > > > > + case ACPI_CPU_MR_SELECTOR_OFFSET_WO: /* current CPU selector
> > > > */
> > > > > + cpu_st->selector = data;
> > > > > + trace_acpi_cpuos_if_write_idx(cpu_st->selector);
> > > > > + break;
> > > > > + case ACPI_CPU_MR_FLAGS_OFFSET_RW: /* set is_* fields */
> > > > > + cdev = &cpu_st->devs[cpu_st->selector];
> > > > > + if (data & ACPI_CPU_MR_FLAGS_BIT_DEVCHK) {
> > > > > + /* clear device-check pending event */
> > > > > + cdev->devchk_pending = false;
> > > > > + trace_acpi_cpuos_if_clear_devchk_evt(cpu_st->selector);
> > > > > + } else if (data & ACPI_CPU_MR_FLAGS_BIT_EJECTRQ) {
> > > > > + /* clear eject-request pending event */
> > > > > + cdev->ejrqst_pending = false;
> > > > > + trace_acpi_cpuos_if_clear_ejrqst_evt(cpu_st->selector);
> > > > > + } else if (data & ACPI_CPU_MR_FLAGS_BIT_EJECT) {
> > > > > + DeviceState *dev = NULL;
> > > > > + if (!cdev->cpu || cdev->cpu == first_cpu) {
> > > > > +
> > trace_acpi_cpuos_if_ejecting_invalid_cpu(cpu_st->selector);
> > > > > + break;
> > > > > + }
> > > > > + /*
> > > > > + * OSPM has returned with eject. Hence, it is now safe
> > to put the
> > > > > + * cpu device on powered-off state.
> > > > > + */
> > > > > + trace_acpi_cpuos_if_ejecting_cpu(cpu_st->selector);
> > > > > + dev = DEVICE(cdev->cpu);
> > > > > + qdev_sync_disable(dev, &error_fatal);
> > > > > + }
> > > > > + break;
> > > > > + case ACPI_CPU_MR_CMD_OFFSET_WO:
> > > > > + trace_acpi_cpuos_if_write_cmd(cpu_st->selector, data);
> > > > > + if (data < ACPI_CMD_MAX) {
> > > > > + cpu_st->command = data;
> > > > > + if (cpu_st->command ==
> > > > ACPI_GET_NEXT_CPU_WITH_EVENT_CMD) {
> > > > > + uint32_t iter = cpu_st->selector;
> > > > > +
> > > > > + do {
> > > > > + cdev = &cpu_st->devs[iter];
> > > > > + if (cdev->devchk_pending ||
> > cdev->ejrqst_pending) {
> > > > > + cpu_st->selector = iter;
> > > > > +
> > trace_acpi_cpuos_if_cpu_has_events(cpu_st->selector,
> > > > > + cdev->devchk_pending,
> > cdev->ejrqst_pending);
> > > > > + break;
> > > > > + }
> > > > > + iter = iter + 1 < cpu_st->dev_count ? iter + 1
> > : 0;
> > > > > + } while (iter != cpu_st->selector);
> > > > > + }
> > > > > + }
> > > > > + break;
> > > > > + case ACPI_CPU_MR_CMD_DATA_OFFSET_RW:
> > > > > + switch (cpu_st->command) {
> > > > > + case ACPI_OST_EVENT_CMD: {
> > > > > + cdev = &cpu_st->devs[cpu_st->selector];
> > > > > + cdev->ost_event = data;
> > > > > + trace_acpi_cpuos_if_write_ost_ev(cpu_st->selector, cdev-
> > > > >ost_event);
> > > > > + break;
> > > > > + }
> > > > > + case ACPI_OST_STATUS_CMD: {
> > > > > + cdev = &cpu_st->devs[cpu_st->selector];
> > > > > + cdev->ost_status = data;
> > > > > + info = acpi_cpu_ospm_ost_status(cpu_st->selector, cdev);
> > > > > + qapi_event_send_acpi_device_ost(info);
> > > > > + qapi_free_ACPIOSTInfo(info);
> > > > > + trace_acpi_cpuos_if_write_ost_status(cpu_st->selector,
> > > > > + cdev->ost_status);
> > > > > + break;
> > > > > + }
> > > > > + default:
> > > > > + trace_acpi_cpuos_if_write_invalid_cmd(cpu_st->selector,
> > > > > + cpu_st->command);
> > > > > + break;
> > > > > + }
> > > > > + break;
> > > > > + default:
> > > > > + trace_acpi_cpuos_if_write_invalid_offset(cpu_st->selector,
> > addr);
> > > > > + break;
> > > > > + }
> > > > > +}
> > > > > +
> > > > > +static const MemoryRegionOps cpu_common_mr_ops = {
> > > > > + .read = acpi_cpu_ospm_intf_mr_read,
> > > > > + .write = acpi_cpu_ospm_intf_mr_write,
> > > > > + .endianness = DEVICE_LITTLE_ENDIAN,
> > > > > + .valid = {
> > > > > + .min_access_size = 1,
> > > > > + .max_access_size = ACPI_CPU_OSPM_IF_MAX_FIELD_SIZE,
> > > > > + },
> > > > > + .impl = {
> > > > > + .min_access_size = 1,
> > > > > + .max_access_size = ACPI_CPU_OSPM_IF_MAX_FIELD_SIZE,
> > > > > + .unaligned = false,
> > > > > + },
> > > > > +};
> > > > > +
> > > > > +void acpi_cpu_ospm_state_interface_init(MemoryRegion *as, Object
> > > > *owner,
> > > > > + AcpiCpuOspmState *state,
> > > > > + hwaddr base_addr) {
> > > > > + MachineState *machine = MACHINE(qdev_get_machine());
> > > > > + MachineClass *mc = MACHINE_GET_CLASS(machine);
> > > > > + const CPUArchIdList *id_list;
> > > > > + int i;
> > > > > +
> > > > > + assert(mc->possible_cpu_arch_ids);
> > > > > + id_list = mc->possible_cpu_arch_ids(machine);
> > > > > + state->dev_count = id_list->len;
> > > > > + state->devs = g_new0(typeof(*state->devs), state->dev_count);
> > > > > + for (i = 0; i < id_list->len; i++) {
> > > > > + state->devs[i].cpu = CPU(id_list->cpus[i].cpu);
> > > > > + state->devs[i].arch_id = id_list->cpus[i].arch_id;
> > > > > + }
> > > > > + memory_region_init_io(&state->ctrl_reg, owner,
> > > > &cpu_common_mr_ops, state,
> > > > > + "ACPI CPU OSPM State Interface Memory
> > Region",
> > > > > + ACPI_CPU_OSPM_IF_REG_LEN);
> > > > > + memory_region_add_subregion(as, base_addr, &state->ctrl_reg); }
> > > > > +
> > > > > +static AcpiCpuOspmStateStatus *
> > > > > +acpi_get_cpu_status(AcpiCpuOspmState *cpu_st, DeviceState *dev) {
> > > > > + CPUClass *k = CPU_GET_CLASS(dev);
> > > > > + uint64_t cpu_arch_id = k->get_arch_id(CPU(dev));
> > > > > + int i;
> > > > > +
> > > > > + for (i = 0; i < cpu_st->dev_count; i++) {
> > > > > + if (cpu_arch_id == cpu_st->devs[i].arch_id) {
> > > > > + return &cpu_st->devs[i];
> > > > > + }
> > > > > + }
> > > > > + return NULL;
> > > > > +}
> > > > > +
> > > > > +void acpi_cpu_device_check_cb(AcpiCpuOspmState *cpu_st,
> > DeviceState
> > > > *dev,
> > > > > + uint32_t event_st, Error **errp) {
> > > > > + AcpiCpuOspmStateStatus *cdev;
> > > > > + cdev = acpi_get_cpu_status(cpu_st, dev);
> > > > > + if (!cdev) {
> > > > > + return;
> > > > > + }
> > > > > + assert(cdev->cpu);
> > > > > +
> > > > > + /*
> > > > > + * Tell OSPM via GED IRQ(GSI) that a powered-off cpu is being
> > powered-
> > > > on.
> > > > > + * Also, mark 'device-check' event pending for this cpu. This
> > will
> > > > > + * eventually result in OSPM evaluating the ACPI _EVT method
> > and scan
> > > > of
> > > > > + * cpus
> > > > > + */
> > > > > + cdev->devchk_pending = true;
> > > > > + acpi_send_event(cpu_st->acpi_dev, event_st); }
> > > > > +
> > > > > +void acpi_cpu_eject_request_cb(AcpiCpuOspmState *cpu_st,
> > > > DeviceState *dev,
> > > > > + uint32_t event_st, Error **errp) {
> > > > > + AcpiCpuOspmStateStatus *cdev;
> > > > > + cdev = acpi_get_cpu_status(cpu_st, dev);
> > > > > + if (!cdev) {
> > > > > + return;
> > > > > + }
> > > > > + assert(cdev->cpu);
> > > > > +
> > > > > + /*
> > > > > + * Tell OSPM via GED IRQ(GSI) that a cpu wants to power-off or
> > go on
> > > > standby
> > > > > + * Also,mark 'eject-request' event pending for this cpu.
> > (graceful
> > > > shutdown)
> > > > > + */
> > > > > + cdev->ejrqst_pending = true;
> > > > > + acpi_send_event(cpu_st->acpi_dev, event_st); }
> > > > > +
> > > > > +void
> > > > > +acpi_cpu_eject_cb(AcpiCpuOspmState *cpu_st, DeviceState *dev, Error
> > > > > +**errp) {
> > > > > + /* TODO: possible handling here */ }
> > > > > +
> > > > > +static const VMStateDescription vmstate_cpu_ospm_state_sts = {
> > > > > + .name = "CPU OSPM state status",
> > > > > + .version_id = 1,
> > > > > + .minimum_version_id = 1,
> > > > > + .fields = (const VMStateField[]) {
> > > > > + VMSTATE_BOOL(devchk_pending, AcpiCpuOspmStateStatus),
> > > > > + VMSTATE_BOOL(ejrqst_pending, AcpiCpuOspmStateStatus),
> > > > > + VMSTATE_UINT32(ost_event, AcpiCpuOspmStateStatus),
> > > > > + VMSTATE_UINT32(ost_status, AcpiCpuOspmStateStatus),
> > > > > + VMSTATE_END_OF_LIST()
> > > > > + }
> > > > > +};
> > > > > +
> > > > > +const VMStateDescription vmstate_cpu_ospm_state = {
> > > > > + .name = "CPU OSPM state",
> > > > > + .version_id = 1,
> > > > > + .minimum_version_id = 1,
> > > > > + .fields = (const VMStateField[]) {
> > > > > + VMSTATE_UINT32(selector, AcpiCpuOspmState),
> > > > > + VMSTATE_UINT8(command, AcpiCpuOspmState),
> > > > > + VMSTATE_STRUCT_VARRAY_POINTER_UINT32(devs,
> > > > AcpiCpuOspmState,
> > > > > + dev_count,
> > > > > +
> > vmstate_cpu_ospm_state_sts,
> > > > > +
> > AcpiCpuOspmStateStatus),
> > > > > + VMSTATE_END_OF_LIST()
> > > > > + }
> > > > > +};
> > > > > +
> > > > > +void acpi_build_cpus_aml(Aml *table, hwaddr base_addr, const char
> > > > *root,
> > > > > + const char *event_handler_method) {
> > > > > + MachineState *machine = MACHINE(qdev_get_machine());
> > > > > + MachineClass *mc = MACHINE_GET_CLASS(machine);
> > > > > + const CPUArchIdList *arch_ids =
> > mc->possible_cpu_arch_ids(machine);
> > > > > + Aml *sb_scope = aml_scope("_SB"); /* System Bus Scope */
> > > > > + Aml *ifctx, *field, *method, *cpu_res_dev, *cpus_dev;
> > > > > + Aml *zero = aml_int(0);
> > > > > + Aml *one = aml_int(1);
> > > > > +
> > > > > + cpu_res_dev = aml_device("%s.%s", root, CPU_RES_DEVICE);
> > > > > + {
> > > > > + Aml *crs;
> > > > > +
> > > > > + aml_append(cpu_res_dev,
> > > > > + aml_name_decl("_HID", aml_eisaid("PNP0A06")));
> > > > > + aml_append(cpu_res_dev,
> > > > > + aml_name_decl("_UID", aml_string("CPU OSPM Interface
> > > > resources")));
> > > > > + aml_append(cpu_res_dev, aml_mutex(CPU_LOCK, 0));
> > > > > +
> > > > > + crs = aml_resource_template();
> > > > > + aml_append(crs, aml_memory32_fixed(base_addr,
> > > > ACPI_CPU_OSPM_IF_REG_LEN,
> > > > > + AML_READ_WRITE));
> > > > > +
> > > > > + aml_append(cpu_res_dev, aml_name_decl("_CRS", crs));
> > > > > +
> > > > > + /* declare CPU OSPM Interface MMIO region related access
> > fields */
> > > > > + aml_append(cpu_res_dev,
> > > > > + aml_operation_region("PRST", AML_SYSTEM_MEMORY,
> > > > > + aml_int(base_addr),
> > > > > + ACPI_CPU_OSPM_IF_REG_LEN));
> > > > > +
> > > > > + /*
> > > > > + * define named fields within PRST region with 'Byte'
> > access widths
> > > > > + * and reserve fields with other access width
> > > > > + */
> > > > > + field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
> > > > AML_PRESERVE);
> > > > > + /* reserve CPU 'selector' field (size in bits) */
> > > > > + AML_APPEND_MR_RESVD_FIELD(field,
> > > > ACPI_CPU_MR_SELECTOR_SIZE_BITS);
> > > > > + /* Flag::Enabled Bit(RO) - Read '1' if enabled */
> > > > > + AML_APPEND_MR_NAMED_FIELD(field, CPU_ENABLED_F, 1);
> > > > > + /* Flag::Devchk Bit(RW) - Read '1', has a event. Write '1',
> > to clear */
> > > > > + AML_APPEND_MR_NAMED_FIELD(field, CPU_DEVCHK_F, 1);
> > > > > + /* Flag::Ejectrq Bit(RW) - Read 1, has event. Write 1 to
> > clear */
> > > > > + AML_APPEND_MR_NAMED_FIELD(field, CPU_EJECTRQ_F, 1);
> > > > > + /* Flag::Eject Bit(WO) - OSPM evals _EJx, initiates CPU
> > Eject in
> > > > Qemu*/
> > > > > + AML_APPEND_MR_NAMED_FIELD(field, CPU_EJECT_F, 1);
> > > > > + /* Flag::Bit(ACPI_CPU_FLAGS_USED_BITS)-Bit(7) - Reserve
> > left over
> > > > bits*/
> > > > > + AML_APPEND_MR_RESVD_FIELD(field,
> > > > ACPI_CPU_MR_RES_FLAG_BITS);
> > > > > + /* Reserved space: padding after flags */
> > > > > + AML_APPEND_MR_RESVD_FIELD(field,
> > > > ACPI_CPU_MR_RES_FLAGS_SIZE_BITS);
> > > > > + /* Command field written by OSPM */
> > > > > + AML_APPEND_MR_NAMED_FIELD(field, CPU_COMMAND,
> > > > > + ACPI_CPU_MR_CMD_SIZE_BITS);
> > > > > + /* Reserved space: padding after command field */
> > > > > + AML_APPEND_MR_RESVD_FIELD(field,
> > > > ACPI_CPU_MR_RES_CMD_SIZE_BITS);
> > > > > + /* Command data: 64-bit payload associated with command */
> > > > > + AML_APPEND_MR_RESVD_FIELD(field,
> > > > ACPI_CPU_MR_CMD_DATA_SIZE_BITS);
> > > > > + aml_append(cpu_res_dev, field);
> > > > > +
> > > > > + /*
> > > > > + * define named fields with 'Dword' access widths and
> > reserve fields
> > > > > + * with other access width
> > > > > + */
> > > > > + field = aml_field("PRST", AML_DWORD_ACC, AML_NOLOCK,
> > > > AML_PRESERVE);
> > > > > + /* CPU selector, write only */
> > > > > + AML_APPEND_MR_NAMED_FIELD(field, CPU_SELECTOR,
> > > > > + ACPI_CPU_MR_SELECTOR_SIZE_BITS);
> > > > > + aml_append(cpu_res_dev, field);
> > > > > +
> > > > > + /*
> > > > > + * define named fields with 'Qword' access widths and
> > reserve fields
> > > > > + * with other access width
> > > > > + */
> > > > > + field = aml_field("PRST", AML_QWORD_ACC, AML_NOLOCK,
> > > > AML_PRESERVE);
> > > > > + /*
> > > > > + * Reserve space: selector, flags, reserved flags, command,
> > reserved
> > > > > + * command for Qword alignment.
> > > > > + */
> > > > > + AML_APPEND_MR_RESVD_FIELD(field,
> > > > ACPI_CPU_MR_SELECTOR_SIZE_BITS +
> > > > > +
> > ACPI_CPU_MR_FLAGS_SIZE_BITS +
> > > > > +
> > ACPI_CPU_MR_RES_FLAGS_SIZE_BITS +
> > > > > +
> > ACPI_CPU_MR_CMD_SIZE_BITS +
> > > > > +
> > ACPI_CPU_MR_RES_CMD_SIZE_BITS);
> > > > > + /* Command data accessible via Qword */
> > > > > + AML_APPEND_MR_NAMED_FIELD(field, CPU_DATA,
> > > > > + ACPI_CPU_MR_CMD_DATA_SIZE_BITS);
> > > > > + aml_append(cpu_res_dev, field);
> > > > > + }
> > > > > + aml_append(sb_scope, cpu_res_dev);
> > > > > +
> > > > > + cpus_dev = aml_device("%s.%s", root, CPU_DEVICE);
> > > > > + {
> > > > > + Aml *ctrl_lock = AML_CPU_RES_DEV(root, CPU_LOCK);
> > > > > + Aml *cpu_selector = AML_CPU_RES_DEV(root, CPU_SELECTOR);
> > > > > + Aml *is_enabled = AML_CPU_RES_DEV(root, CPU_ENABLED_F);
> > > > > + Aml *dvchk_evt = AML_CPU_RES_DEV(root, CPU_DEVCHK_F);
> > > > > + Aml *ejrq_evt = AML_CPU_RES_DEV(root, CPU_EJECTRQ_F);
> > > > > + Aml *ej_evt = AML_CPU_RES_DEV(root, CPU_EJECT_F);
> > > > > + Aml *cpu_cmd = AML_CPU_RES_DEV(root, CPU_COMMAND);
> > > > > + Aml *cpu_data = AML_CPU_RES_DEV(root, CPU_DATA);
> > > > > + int i;
> > > > > +
> > > > > + aml_append(cpus_dev, aml_name_decl("_HID",
> > > > aml_string("ACPI0010")));
> > > > > + aml_append(cpus_dev, aml_name_decl("_CID",
> > > > > + aml_eisaid("PNP0A05")));
> > > > > +
> > > > > + method = aml_method(CPU_NOTIFY_METHOD, 2,
> > > > AML_NOTSERIALIZED);
> > > > > + for (i = 0; i < arch_ids->len; i++) {
> > > > > + Aml *cpu = aml_name(CPU_NAME_FMT, i);
> > > > > + Aml *uid = aml_arg(0);
> > > > > + Aml *event = aml_arg(1);
> > > > > +
> > > > > + ifctx = aml_if(aml_equal(uid, aml_int(i)));
> > > > > + {
> > > > > + aml_append(ifctx, aml_notify(cpu, event));
> > > > > + }
> > > > > + aml_append(method, ifctx);
> > > > > + }
> > > > > + aml_append(cpus_dev, method);
> > > > > +
> > > > > + method = aml_method(CPU_STS_METHOD, 1, AML_SERIALIZED);
> > > > > + {
> > > > > + Aml *idx = aml_arg(0);
> > > > > + Aml *sta = aml_local(0);
> > > > > + Aml *else_ctx;
> > > > > +
> > > > > + aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
> > > > > + aml_append(method, aml_store(idx, cpu_selector));
> > > > > + aml_append(method, aml_store(zero, sta));
> > > > > + ifctx = aml_if(aml_equal(is_enabled, one));
> > > > > + {
> > > > > + /* cpu is present and enabled */
> > > > > + aml_append(ifctx, aml_store(aml_int(0xF), sta));
> > > > > + }
> > > > > + aml_append(method, ifctx);
> > > > > + else_ctx = aml_else();
> > > > > + {
> > > > > + /* cpu is present but disabled */
> > > > > + aml_append(else_ctx, aml_store(aml_int(0xD), sta));
> > > > > + }
> > > > > + aml_append(method, else_ctx);
> > > > > + aml_append(method, aml_release(ctrl_lock));
> > > > > + aml_append(method, aml_return(sta));
> > > > > + }
> > > > > + aml_append(cpus_dev, method);
> > > > > +
> > > > > + method = aml_method(CPU_EJECT_METHOD, 1, AML_SERIALIZED);
> > > > > + {
> > > > > + Aml *idx = aml_arg(0);
> > > > > +
> > > > > + aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
> > > > > + aml_append(method, aml_store(idx, cpu_selector));
> > > > > + aml_append(method, aml_store(one, ej_evt));
> > > > > + aml_append(method, aml_release(ctrl_lock));
> > > > > + }
> > > > > + aml_append(cpus_dev, method);
> > > > > +
> > > > > + method = aml_method(CPU_SCAN_METHOD, 0, AML_SERIALIZED);
> > > > > + {
> > > > > + Aml *has_event = aml_local(0); /* Local0: Loop control
> > flag */
> > > > > + Aml *uid = aml_local(1); /* Local1: Current CPU UID */
> > > > > + /* Constants */
> > > > > + Aml *dev_chk = aml_int(1); /* Notify: device check to
> > enable */
> > > > > + Aml *eject_req = aml_int(3); /* Notify: eject for
> > removal */
> > > > > + Aml *next_cpu_cmd =
> > > > > + aml_int(ACPI_GET_NEXT_CPU_WITH_EVENT_CMD);
> > > > > +
> > > > > + /* Acquire CPU lock */
> > > > > + aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
> > > > > +
> > > > > + /* Initialize loop */
> > > > > + aml_append(method, aml_store(zero, uid));
> > > > > + aml_append(method, aml_store(one, has_event));
> > > > > +
> > > > > + Aml *while_ctx = aml_while(aml_land(
> > > > > + aml_equal(has_event, one),
> > > > > + aml_lless(uid, aml_int(arch_ids->len))
> > > > > + ));
> > > > > + {
> > > > > + aml_append(while_ctx, aml_store(zero, has_event));
> > > > > + /*
> > > > > + * Issue scan cmd: QEMU will return next CPU with
> > event in
> > > > > + * cpu_data
> > > > > + */
> > > > > + aml_append(while_ctx, aml_store(uid, cpu_selector));
> > > > > + aml_append(while_ctx, aml_store(next_cpu_cmd,
> > > > > + cpu_cmd));
> > > > > +
> > > > > + /* If scan wrapped around to an earlier UID, exit
> > loop */
> > > > > + Aml *wrap_check = aml_if(aml_lless(cpu_data, uid));
> > > > > + aml_append(wrap_check, aml_break());
> > > > > + aml_append(while_ctx, wrap_check);
> > > > > +
> > > > > + /* Set UID to scanned result */
> > > > > + aml_append(while_ctx, aml_store(cpu_data, uid));
> > > > > +
> > > > > + /* send CPU device-check(resume) event to OSPM */
> > > > > + Aml *if_devchk = aml_if(aml_equal(dvchk_evt, one));
> > > > > + {
> > > > > + aml_append(if_devchk,
> > > > > + aml_call2(CPU_NOTIFY_METHOD, uid, dev_chk));
> > > > > + /* clear local device-check event sent flag */
> > > > > + aml_append(if_devchk, aml_store(one,
> > dvchk_evt));
> > > > > + aml_append(if_devchk, aml_store(one,
> > has_event));
> > > > > + }
> > > > > + aml_append(while_ctx, if_devchk);
> > > > > +
> > > > > + /*
> > > > > + * send CPU eject-request event to OSPM to
> > gracefully handle
> > > > > + * OSPM related tasks running on this CPU
> > > > > + */
> > > > > + Aml *else_ctx = aml_else();
> > > > > + Aml *if_ejrq = aml_if(aml_equal(ejrq_evt, one));
> > > > > + {
> > > > > + aml_append(if_ejrq,
> > > > > + aml_call2(CPU_NOTIFY_METHOD, uid,
> > eject_req));
> > > > > + /* clear local eject-request event sent flag */
> > > > > + aml_append(if_ejrq, aml_store(one, ejrq_evt));
> > > > > + aml_append(if_ejrq, aml_store(one, has_event));
> > > > > + }
> > > > > + aml_append(else_ctx, if_ejrq);
> > > > > + aml_append(while_ctx, else_ctx);
> > > > > +
> > > > > + /* Increment UID */
> > > > > + aml_append(while_ctx, aml_increment(uid));
> > > > > + }
> > > > > + aml_append(method, while_ctx);
> > > > > +
> > > > > + /* Release cpu lock */
> > > > > + aml_append(method, aml_release(ctrl_lock));
> > > > > + }
> > > > > + aml_append(cpus_dev, method);
> > > > > +
> > > > > + method = aml_method(CPU_OST_METHOD, 4, AML_SERIALIZED);
> > > > > + {
> > > > > + Aml *uid = aml_arg(0);
> > > > > + Aml *ev_cmd = aml_int(ACPI_OST_EVENT_CMD);
> > > > > + Aml *st_cmd = aml_int(ACPI_OST_STATUS_CMD);
> > > > > +
> > > > > + aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
> > > > > + aml_append(method, aml_store(uid, cpu_selector));
> > > > > + aml_append(method, aml_store(ev_cmd, cpu_cmd));
> > > > > + aml_append(method, aml_store(aml_arg(1), cpu_data));
> > > > > + aml_append(method, aml_store(st_cmd, cpu_cmd));
> > > > > + aml_append(method, aml_store(aml_arg(2), cpu_data));
> > > > > + aml_append(method, aml_release(ctrl_lock));
> > > > > + }
> > > > > + aml_append(cpus_dev, method);
> > > > > +
> > > > > + /* build Processor object for each processor */
> > > > > + for (i = 0; i < arch_ids->len; i++) {
> > > > > + Aml *dev;
> > > > > + Aml *uid = aml_int(i);
> > > > > +
> > > > > + dev = aml_device(CPU_NAME_FMT, i);
> > > > > + aml_append(dev, aml_name_decl("_HID",
> > > > aml_string("ACPI0007")));
> > > > > + aml_append(dev, aml_name_decl("_UID", uid));
> > > > > +
> > > > > + method = aml_method("_STA", 0, AML_SERIALIZED);
> > > > > + aml_append(method,
> > aml_return(aml_call1(CPU_STS_METHOD,
> > > > uid)));
> > > > > + aml_append(dev, method);
> > > > > +
> > > > > + if (CPU(arch_ids->cpus[i].cpu) != first_cpu) {
> > > > > + method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
> > > > > + aml_append(method, aml_call1(CPU_EJECT_METHOD,
> > uid));
> > > > > + aml_append(dev, method);
> > > > > + }
> > > > > +
> > > > > + method = aml_method("_OST", 3, AML_SERIALIZED);
> > > > > + aml_append(method,
> > > > > + aml_call4(CPU_OST_METHOD, uid, aml_arg(0),
> > > > > + aml_arg(1), aml_arg(2))
> > > > > + );
> > > > > + aml_append(dev, method);
> > > > > + aml_append(cpus_dev, dev);
> > > > > + }
> > > > > + }
> > > > > + aml_append(sb_scope, cpus_dev);
> > > > > + aml_append(table, sb_scope);
> > > > > +
> > > > > + method = aml_method(event_handler_method, 0,
> > > > AML_NOTSERIALIZED);
> > > > > + aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD));
> > > > > + aml_append(table, method);
> > > > > +}
> > > > > diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build index
> > > > > 73f02b9691..6d83396ab4 100644
> > > > > --- a/hw/acpi/meson.build
> > > > > +++ b/hw/acpi/meson.build
> > > > > @@ -8,6 +8,8 @@ acpi_ss.add(files(
> > > > > ))
> > > > > acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_true: files('cpu.c',
> > > > > 'cpu_hotplug.c'))
> > > > > acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_false:
> > > > > files('acpi-cpu-hotplug-stub.c'))
> > > > > +acpi_ss.add(when: 'CONFIG_ACPI_CPU_OSPM_INTERFACE', if_true:
> > > > > +files('cpu_ospm_interface.c'))
> > > > > +acpi_ss.add(when: 'CONFIG_ACPI_CPU_OSPM_INTERFACE', if_false:
> > > > > +files('acpi-cpu-ospm-interface-stub.c'))
> > > > > acpi_ss.add(when: 'CONFIG_ACPI_MEMORY_HOTPLUG', if_true:
> > > > > files('memory_hotplug.c'))
> > > > > acpi_ss.add(when: 'CONFIG_ACPI_MEMORY_HOTPLUG', if_false:
> > > > > files('acpi-mem-hotplug-stub.c'))
> > > > > acpi_ss.add(when: 'CONFIG_ACPI_NVDIMM', if_true: files('nvdimm.c'))
> > > > > diff --git a/hw/acpi/trace-events b/hw/acpi/trace-events index
> > > > > edc93e703c..c0ecbdd48f 100644
> > > > > --- a/hw/acpi/trace-events
> > > > > +++ b/hw/acpi/trace-events
> > > > > @@ -40,6 +40,23 @@ cpuhp_acpi_fw_remove_cpu(uint32_t idx)
> > > > "0x%"PRIx32
> > > > > cpuhp_acpi_write_ost_ev(uint32_t slot, uint32_t ev) "idx[0x%"PRIx32"]
> > > > > OST EVENT: 0x%"PRIx32 cpuhp_acpi_write_ost_status(uint32_t slot,
> > > > > uint32_t st) "idx[0x%"PRIx32"] OST STATUS: 0x%"PRIx32
> > > > >
> > > > > +#cpu_ospm_interface.c
> > > > > +acpi_cpuos_if_invalid_idx_selected(uint32_t idx) "selector
> > > > idx[0x%"PRIx32"]"
> > > > > +acpi_cpuos_if_read_flags(uint32_t idx, uint8_t flags) "cpu
> > > > > +idx[0x%"PRIx32"] flags: 0x%"PRIx8 acpi_cpuos_if_write_idx(uint32_t
> > > > > +idx) "set active cpu idx: 0x%"PRIx32
> > acpi_cpuos_if_write_cmd(uint32_t
> > > > > +idx, uint8_t cmd) "cpu idx[0x%"PRIx32"] cmd: 0x%"PRIx8
> > > > > +acpi_cpuos_if_write_invalid_cmd(uint32_t idx, uint8_t cmd) "cpu
> > > > > +idx[0x%"PRIx32"] invalid cmd: 0x%"PRIx8
> > > > > +acpi_cpuos_if_write_invalid_offset(uint32_t idx, uint64_t addr) "cpu
> > > > > +idx[0x%"PRIx32"] invalid offset: 0x%"PRIx64
> > > > acpi_cpuos_if_read_cmd_data(uint32_t idx, uint32_t data) "cpu
> > > > idx[0x%"PRIx32"] data: 0x%"PRIx32
> > > > acpi_cpuos_if_read_invalid_cmd_data(uint32_t idx, uint8_t cmd) "cpu
> > > > idx[0x%"PRIx32"] invalid cmd: 0x%"PRIx8
> > > > acpi_cpuos_if_cpu_has_events(uint32_t idx, bool devchk, bool ejrqst)
> > "cpu
> > > > idx[0x%"PRIx32"] device-check pending: %d, eject-request pending: %d"
> > > > > +acpi_cpuos_if_clear_devchk_evt(uint32_t idx) "cpu idx[0x%"PRIx32"]"
> > > > > +acpi_cpuos_if_clear_ejrqst_evt(uint32_t idx) "cpu idx[0x%"PRIx32"]"
> > > > > +acpi_cpuos_if_ejecting_invalid_cpu(uint32_t idx) "invalid cpu
> > > > idx[0x%"PRIx32"]"
> > > > > +acpi_cpuos_if_ejecting_cpu(uint32_t idx) "cpu idx[0x%"PRIx32"]"
> > > > > +acpi_cpuos_if_write_ost_ev(uint32_t idx, uint32_t ev) "cpu
> > > > > +idx[0x%"PRIx32"] OST Event: 0x%"PRIx32
> > > > > +acpi_cpuos_if_write_ost_status(uint32_t idx, uint32_t st) "cpu
> > > > > +idx[0x%"PRIx32"] OST Status: 0x%"PRIx32
> > > > > +
> > > > > # pcihp.c
> > > > > acpi_pci_eject_slot(unsigned bsel, unsigned slot) "bsel: %u slot:
> > %u"
> > > > > acpi_pci_unplug(int bsel, int slot) "bsel: %d slot: %d"
> > > > > diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index
> > > > > 2aa4b5d778..c9991e00c7 100644
> > > > > --- a/hw/arm/Kconfig
> > > > > +++ b/hw/arm/Kconfig
> > > > > @@ -39,6 +39,7 @@ config ARM_VIRT
> > > > > select VIRTIO_MEM_SUPPORTED
> > > > > select ACPI_CXL
> > > > > select ACPI_HMAT
> > > > > + select ACPI_CPU_OSPM_INTERFACE
> > > > >
> > > > > config CUBIEBOARD
> > > > > bool
> > > > > diff --git a/include/hw/acpi/cpu_ospm_interface.h
> > > > > b/include/hw/acpi/cpu_ospm_interface.h
> > > > > new file mode 100644
> > > > > index 0000000000..5dda327a34
> > > > > --- /dev/null
> > > > > +++ b/include/hw/acpi/cpu_ospm_interface.h
> > > > > @@ -0,0 +1,78 @@
> > > > > +/*
> > > > > + * ACPI CPU OSPM Interface Handling.
> > > > > + *
> > > > > + * Copyright (c) 2025 Huawei Technologies R&D (UK) Ltd.
> > > > > + *
> > > > > + * Author: Salil Mehta <salil.mehta@huawei.com>
> > > > > + *
> > > > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > > > + *
> > > > > + * This program is free software; you can redistribute it and/or
> > > > > +modify
> > > > > + * it under the terms of the GNU General Public License as published
> > > > > +by
> > > > > + * the ree Software Foundation; either version 2 of the License, or
> > > > > + * (at your option) any later version.
> > > > > + */
> > > > > +#ifndef CPU_OSPM_INTERFACE_H
> > > > > +#define CPU_OSPM_INTERFACE_H
> > > > > +
> > > > > +#include "qapi/qapi-types-acpi.h"
> > > > > +#include "hw/qdev-core.h"
> > > > > +#include "hw/acpi/acpi.h"
> > > > > +#include "hw/acpi/aml-build.h"
> > > > > +#include "hw/boards.h"
> > > > > +
> > > > > +/**
> > > > > + * Total size (in bytes) of the ACPI CPU OSPM Interface MMIO region.
> > > > > + *
> > > > > + * This region contains control and status fields such as CPU
> > > > > +selector,
> > > > > + * flags, command register, and data register. It must exactly match
> > > > > +the
> > > > > + * layout defined in the AML code and the memory region
> > > > implementation.
> > > > > + *
> > > > > + * Any mismatch between this definition and the AML layout may
> > result
> > > > > +in
> > > > > + * runtime errors or build-time assertion failures (e.g.,
> > > > > +_Static_assert),
> > > > > + * breaking correct device emulation and guest OS coordination.
> > > > > + */
> > > > > +#define ACPI_CPU_OSPM_IF_REG_LEN 16
> > > > > +
> > > > > +typedef struct {
> > > > > + CPUState *cpu;
> > > > > + uint64_t arch_id;
> > > > > + bool devchk_pending; /* device-check pending */
> > > > > + bool ejrqst_pending; /* eject-request pending */
> > > > > + uint32_t ost_event;
> > > > > + uint32_t ost_status;
> > > > > +} AcpiCpuOspmStateStatus;
> > > > > +
> > > > > +typedef struct AcpiCpuOspmState {
> > > > > + DeviceState *acpi_dev;
> > > > > + MemoryRegion ctrl_reg;
> > > > > + uint32_t selector;
> > > > > + uint8_t command;
> > > > > + uint32_t dev_count;
> > > > > + AcpiCpuOspmStateStatus *devs;
> > > > > +} AcpiCpuOspmState;
> > > > > +
> > > > > +void acpi_cpu_device_check_cb(AcpiCpuOspmState *cpu_st,
> > DeviceState
> > > > *dev,
> > > > > + uint32_t event_st, Error **errp);
> > > > > +
> > > > > +void acpi_cpu_eject_request_cb(AcpiCpuOspmState *cpu_st,
> > > > DeviceState *dev,
> > > > > + uint32_t event_st, Error **errp);
> > > > > +
> > > > > +void acpi_cpu_eject_cb(AcpiCpuOspmState *cpu_st, DeviceState *dev,
> > > > > + Error **errp);
> > > > > +
> > > > > +void acpi_cpu_ospm_state_interface_init(MemoryRegion *as, Object
> > > > *owner,
> > > > > + AcpiCpuOspmState *state,
> > > > > + hwaddr base_addr);
> > > > > +
> > > > > +void acpi_build_cpus_aml(Aml *table, hwaddr base_addr, const char
> > > > *root,
> > > > > + const char *event_handler_method);
> > > > > +
> > > > > +void acpi_cpus_ospm_status(AcpiCpuOspmState *cpu_st,
> > > > > + ACPIOSTInfoList ***list);
> > > > > +
> > > > > +extern const VMStateDescription vmstate_cpu_ospm_state; #define
> > > > > +VMSTATE_CPU_OSPM_STATE(cpuospm, state) \
> > > > > + VMSTATE_STRUCT(cpuospm, state, 1, \
> > > > > + vmstate_cpu_ospm_state, AcpiCpuOspmState) #endif
> > > > > +/* CPU_OSPM_INTERFACE_H */
> > > >
> > >
> >
> >
next prev parent reply other threads:[~2025-11-12 16:56 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-01 1:01 [PATCH RFC V6 00/24] Support of Virtual CPU Hotplug-like Feature for ARMv8+ Arch salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 01/24] hw/core: Introduce administrative power-state property and its accessors salil.mehta
2025-10-09 10:48 ` Miguel Luis
2025-10-01 1:01 ` [PATCH RFC V6 02/24] hw/core, qemu-options.hx: Introduce 'disabledcpus' SMP parameter salil.mehta
2025-10-09 11:28 ` Miguel Luis
2025-10-09 13:17 ` Igor Mammedov
2025-10-09 11:51 ` Markus Armbruster
2025-10-28 5:48 ` Gavin Shan
2025-10-01 1:01 ` [PATCH RFC V6 03/24] hw/arm/virt: Clamp 'maxcpus' as-per machine's vCPU deferred online-capability salil.mehta
2025-10-09 12:32 ` Miguel Luis
2025-10-09 13:11 ` Igor Mammedov
2025-10-01 1:01 ` [PATCH RFC V6 04/24] arm/virt, target/arm: Add new ARMCPU {socket, cluster, core, thread}-id property salil.mehta
2025-10-28 6:24 ` [PATCH RFC V6 04/24] arm/virt,target/arm: Add new ARMCPU {socket,cluster,core,thread}-id property Gavin Shan
2025-10-01 1:01 ` [PATCH RFC V6 05/24] arm/virt, kvm: Pre-create KVM vCPUs for 'disabled' QOM vCPUs at machine init salil.mehta
2025-10-22 10:36 ` [PATCH RFC V6 05/24] arm/virt,kvm: " Gavin Shan
2025-10-22 18:18 ` Salil Mehta
2025-10-22 18:50 ` Salil Mehta
2025-10-23 0:14 ` Gavin Shan
2025-10-23 0:35 ` Salil Mehta
2025-10-23 1:29 ` Salil Mehta
2025-10-23 4:14 ` Gavin Shan
2025-10-23 11:27 ` Salil Mehta
2025-10-23 1:58 ` Gavin Shan
2025-10-23 11:17 ` Salil Mehta
2025-10-01 1:01 ` [PATCH RFC V6 06/24] arm/virt, gicv3: Pre-size GIC with possible " salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 07/24] arm/gicv3: Refactor CPU interface init for shared TCG/KVM use salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 08/24] arm/virt, gicv3: Guard CPU interface access for admin disabled vCPUs salil.mehta
2025-10-24 4:07 ` Gavin Shan
2025-10-28 11:59 ` Gavin Shan
2025-10-01 1:01 ` [PATCH RFC V6 09/24] hw/intc/arm_gicv3_common: Migrate & check 'GICv3CPUState' accessibility mismatch salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 10/24] arm/virt: Init PMU at host for all present vCPUs salil.mehta
2025-10-03 15:02 ` Igor Mammedov
2025-10-01 1:01 ` [PATCH RFC V6 11/24] hw/arm/acpi: MADT change to size the guest with possible vCPUs salil.mehta
2025-10-03 15:09 ` Igor Mammedov
[not found] ` <0175e40f70424dd9a29389b8a4f16c42@huawei.com>
2025-10-07 12:20 ` Igor Mammedov
2025-10-10 3:15 ` Salil Mehta
2025-10-01 1:01 ` [PATCH RFC V6 12/24] hw/core: Introduce generic device power-state handler interface salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 13/24] qdev: make admin power state changes trigger platform transitions via ACPI salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 14/24] arm/acpi: Introduce dedicated CPU OSPM interface for ARM-like platforms salil.mehta
2025-10-03 14:58 ` Igor Mammedov
[not found] ` <7da6a9c470684754810414f0abd23a62@huawei.com>
2025-10-07 12:06 ` Igor Mammedov
2025-10-10 3:00 ` Salil Mehta
2025-11-12 16:55 ` Igor Mammedov [this message]
2025-10-24 4:47 ` Gavin Shan
2025-10-01 1:01 ` [PATCH RFC V6 15/24] acpi/ged: Notify OSPM of CPU administrative state changes via GED salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 16/24] arm/virt/acpi: Update ACPI DSDT Tbl to include 'Online-Capable' CPUs AML salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 17/24] hw/arm/virt, acpi/ged: Add PowerStateHandler hooks for runtime CPU state changes salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 18/24] target/arm/kvm, tcg: Handle SMCCC hypercall exits in VMM during PSCI_CPU_{ON, OFF} salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 19/24] target/arm/cpu: Add the Accessor hook to fetch ARM CPU arch-id salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 20/24] target/arm/kvm: Write vCPU's state back to KVM on cold-reset salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 21/24] hw/intc/arm-gicv3-kvm: Pause all vCPUs & cache ICC_CTLR_EL1 for userspace PSCI CPU_ON salil.mehta
2025-10-01 1:01 ` [PATCH RFC V6 22/24] monitor, qdev: Introduce 'device_set' to change admin state of existing devices salil.mehta
2025-10-09 8:55 ` [PATCH RFC V6 22/24] monitor,qdev: " Markus Armbruster
2025-10-09 12:51 ` Igor Mammedov
2025-10-09 14:03 ` Daniel P. Berrangé
2025-10-09 14:55 ` Markus Armbruster
2025-10-09 15:19 ` Peter Maydell
2025-10-10 4:59 ` Markus Armbruster
2025-10-17 14:50 ` Igor Mammedov
2025-10-20 11:22 ` Markus Armbruster
2025-10-29 10:08 ` Igor Mammedov
2025-10-29 11:38 ` Markus Armbruster
2025-11-03 8:27 ` Igor Mammedov
2025-11-07 13:10 ` Markus Armbruster
2025-10-01 1:01 ` [PATCH RFC V6 23/24] monitor, qapi: add 'info cpus-powerstate' and QMP query (Admin + Oper states) salil.mehta
2025-10-09 11:53 ` [PATCH RFC V6 23/24] monitor,qapi: " Markus Armbruster
2025-10-01 1:01 ` [PATCH RFC V6 24/24] tcg: Defer TB flush for 'lazy realized' vCPUs on first region alloc salil.mehta
2025-10-01 21:34 ` Richard Henderson
2025-10-02 12:27 ` Salil Mehta via
2025-10-02 15:41 ` Richard Henderson
2025-10-07 10:14 ` Salil Mehta via
2025-10-06 14:00 ` [PATCH RFC V6 00/24] Support of Virtual CPU Hotplug-like Feature for ARMv8+ Arch Igor Mammedov
2025-10-13 0:34 ` Gavin Shan
2025-10-22 10:07 ` Gavin Shan
2025-10-24 6:55 ` Gavin Shan
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=20251112175540.7407860a@fedora \
--to=imammedo@redhat.com \
--cc=alex.bennee@linaro.org \
--cc=andrew.jones@linux.dev \
--cc=ardb@kernel.org \
--cc=armbru@redhat.com \
--cc=borntraeger@linux.ibm.com \
--cc=darren@os.amperecomputing.com \
--cc=david@redhat.com \
--cc=eric.auger@redhat.com \
--cc=gankulkarni@os.amperecomputing.com \
--cc=gshan@redhat.com \
--cc=gustavo.romero@linaro.org \
--cc=harshpb@linux.ibm.com \
--cc=ilkka@os.amperecomputing.com \
--cc=jean-philippe@linaro.org \
--cc=jiakernel2@gmail.com \
--cc=jonathan.cameron@huawei.com \
--cc=karl.heubaum@oracle.com \
--cc=linux@armlinux.org.uk \
--cc=linuxarm@huawei.com \
--cc=lixianglai@loongson.cn \
--cc=lpieralisi@kernel.org \
--cc=maobibo@loongson.cn \
--cc=maz@kernel.org \
--cc=miguel.luis@oracle.com \
--cc=mst@redhat.com \
--cc=npiggin@gmail.com \
--cc=oliver.upton@linux.dev \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=rafael@kernel.org \
--cc=richard.henderson@linaro.org \
--cc=salil.mehta@huawei.com \
--cc=salil.mehta@opnsrc.net \
--cc=shahuang@redhat.com \
--cc=vishnu@os.amperecomputing.com \
--cc=wangxiongfeng2@huawei.com \
--cc=wangyanan55@huawei.com \
--cc=wangzhou1@hisilicon.com \
--cc=will@kernel.org \
--cc=zhao1.liu@intel.com \
--cc=zhukeqian1@huawei.com \
/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).