All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Igor Mammedov <imammedo@redhat.com>
Cc: kwolf@redhat.com, peter.maydell@linaro.org, aliguori@us.ibm.com,
	ehabkost@redhat.com, mst@redhat.com, jan.kiszka@siemens.com,
	stefano.stabellini@eu.citrix.com, claudio.fontana@huawei.com,
	qemu-devel@nongnu.org, quintela@redhat.com, armbru@redhat.com,
	blauwirbel@gmail.com, yang.z.zhang@intel.com,
	alex.williamson@redhat.com, aderumier@odiso.com,
	kraxel@redhat.com, anthony.perard@citrix.com,
	lcapitulino@redhat.com, afaerber@suse.de, rth@twiddle.net
Subject: Re: [Qemu-devel] [PATCH 10/12] acpi_piix4: add infrastructure to send CPU hot-plug GPE to guest
Date: Wed, 27 Mar 2013 11:47:09 +0100	[thread overview]
Message-ID: <5152CE2D.1090909@redhat.com> (raw)
In-Reply-To: <1363876125-8264-11-git-send-email-imammedo@redhat.com>

Il 21/03/2013 15:28, Igor Mammedov ha scritto:
> * introduce processor status bitmask visible to guest at 0xaf00 addr,
>   where Seabios expects it
> * set bit corresponding to APIC ID in processor status bitmask on
>   receiving CPU hot-plug notification
> * trigger CPU hot-plug SCI, expected by Seabios on receiving CPU
>   hot-plug notification
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/acpi_piix4.c |  107 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 105 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
> index 7a4b712..ddb3981 100644
> --- a/hw/acpi_piix4.c
> +++ b/hw/acpi_piix4.c
> @@ -48,19 +48,28 @@
>  #define PCI_EJ_BASE 0xae08
>  #define PCI_RMV_BASE 0xae0c
>  
> +#define PROC_BASE 0xaf00
> +#define PROC_LEN 32
> +
>  #define PIIX4_PCI_HOTPLUG_STATUS 2
> +#define PIIX4_CPU_HOTPLUG_STATUS 4
>  
>  struct pci_status {
>      uint32_t up; /* deprecated, maintained for migration compatibility */
>      uint32_t down;
>  };
>  
> +struct cpu_status {
> +    uint8_t sts[PROC_LEN];
> +};
> +
>  typedef struct PIIX4PMState {
>      PCIDevice dev;
>  
>      MemoryRegion io;
>      MemoryRegion io_gpe;
>      MemoryRegion io_pci;
> +    MemoryRegion io_cpu;
>      ACPIREGS ar;
>  
>      APMState apm;
> @@ -82,6 +91,9 @@ typedef struct PIIX4PMState {
>      uint8_t disable_s3;
>      uint8_t disable_s4;
>      uint8_t s4_val;
> +
> +    struct cpu_status gpe_cpu;
> +    Notifier cpu_add_notifier;
>  } PIIX4PMState;
>  
>  static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
> @@ -100,8 +112,8 @@ static void pm_update_sci(PIIX4PMState *s)
>                     ACPI_BITMASK_POWER_BUTTON_ENABLE |
>                     ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
>                     ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
> -        (((s->ar.gpe.sts[0] & s->ar.gpe.en[0])
> -          & PIIX4_PCI_HOTPLUG_STATUS) != 0);
> +        (((s->ar.gpe.sts[0] & s->ar.gpe.en[0]) &
> +          (PIIX4_PCI_HOTPLUG_STATUS | PIIX4_CPU_HOTPLUG_STATUS)) != 0);
>  
>      qemu_set_irq(s->irq, sci_level);
>      /* schedule a timer interruption if needed */
> @@ -257,6 +269,17 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id)
>      return ret;
>  }
>  
> +#define VMSTATE_CPU_STATUS_ARRAY(_field, _state)                             \
> + {                                                                           \
> +     .name       = (stringify(_field)),                                      \
> +     .version_id = 0,                                                        \
> +     .num        = PROC_LEN,                                                 \
> +     .info       = &vmstate_info_uint8,                                      \
> +     .size       = sizeof(uint8_t),                                          \
> +     .flags      = VMS_ARRAY,                                                \
> +     .offset     = vmstate_offset_array(_state, _field, uint8_t, PROC_LEN),  \
> + }
> +
>  /* qemu-kvm 1.2 uses version 3 but advertised as 2
>   * To support incoming qemu-kvm 1.2 migration, change version_id
>   * and minimum_version_id to 2 below (which breaks migration from
> @@ -281,6 +304,7 @@ static const VMStateDescription vmstate_acpi = {
>          VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
>          VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status,
>                         struct pci_status),
> +        VMSTATE_CPU_STATUS_ARRAY(gpe_cpu.sts, PIIX4PMState),
>          VMSTATE_END_OF_LIST()
>      }

You need to either bump the version, or add a subsection.   The
subsection is not needed until the first hot-(un)plug action.

>  };
> @@ -585,6 +609,78 @@ static const MemoryRegionOps piix4_pci_ops = {
>      },
>  };
>  
> +static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned width)
> +{
> +    PIIX4PMState *s = opaque;
> +    struct cpu_status *cpus = &s->gpe_cpu;
> +    uint64_t val = cpus->sts[addr];
> +    return val;
> +}
> +
> +static void cpu_status_write(void *opaque, hwaddr addr, uint64_t data,
> +                             unsigned int size)
> +{
> +    /* TODO: implement VCPU removal on guest signal that CPU can be removed */
> +}
> +
> +static const MemoryRegionOps cpu_hotplug_ops = {
> +    .read = cpu_status_read,
> +    .write = cpu_status_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +    .valid = {
> +        .min_access_size = 1,
> +        .max_access_size = 1,
> +    },
> +};
> +
> +typedef enum {
> +    PLUG,
> +    UNPLUG,
> +} HotplugEventType;
> +
> +static void piix4_cpu_hotplug_req(PIIX4PMState *s, uint32_t cpu,
> +                               HotplugEventType action)
> +{
> +    struct cpu_status *g = &s->gpe_cpu;
> +    ACPIGPE *gpe = &s->ar.gpe;
> +
> +    assert(s != NULL);
> +    *gpe->sts = *gpe->sts | PIIX4_CPU_HOTPLUG_STATUS;
> +    if (action == PLUG) {
> +        g->sts[cpu / 8] |= (1 << (cpu % 8));
> +    } else {
> +        g->sts[cpu / 8] &= ~(1 << (cpu % 8));
> +    }
> +    pm_update_sci(s);
> +}
> +
> +static void piix4_cpu_add_req(Notifier *n, void *opaque)
> +{
> +    PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_add_notifier);
> +    piix4_cpu_hotplug_req(s, *(uint32_t *)opaque, PLUG);
> +}
> +
> +static int piix4_init_cpu_status(Object *obj, void *opaque)
> +{
> +    struct cpu_status *g = (struct cpu_status *)opaque;
> +    Object *cpu_obj = object_dynamic_cast(obj, TYPE_CPU);
> +
> +    if (cpu_obj) {
> +        struct Error *error = NULL;
> +        int64_t apic_id = object_property_get_int(cpu_obj, "apic-id", &error);
> +
> +        if (error) {
> +            fprintf(stderr, "failed to initilize CPU status for ACPI: %s\n",
> +                    error_get_pretty(error));
> +            error_free(error);
> +            abort();
> +        }
> +        g_assert((apic_id / 8) < PROC_LEN);
> +        g->sts[apic_id / 8] |= (1 << (apic_id % 8));
> +    }
> +    return object_child_foreach(obj, piix4_init_cpu_status, opaque);
> +}

acpi_piix4 is also used for MIPS.  Be careful.

There is already a cpu_index field in CPU.  I think you should add a
get_firmware_id method to CPU, or something like that, and override it
in X86CPU to return the APIC id.  Similarly, some of the functions you
added in target-i386/ could become class methods on CPU.

Paolo


>  static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
>                                  PCIHotplugState state);
>  
> @@ -600,6 +696,13 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
>      memory_region_add_subregion(parent, PCI_HOTPLUG_ADDR,
>                                  &s->io_pci);
>      pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
> +
> +    piix4_init_cpu_status(qdev_get_machine(), &s->gpe_cpu);
> +    memory_region_init_io(&s->io_cpu, &cpu_hotplug_ops, s, "apci-cpu-hotplug",
> +                          PROC_LEN);
> +    memory_region_add_subregion(parent, PROC_BASE, &s->io_cpu);
> +    s->cpu_add_notifier.notify = piix4_cpu_add_req;
> +    qemu_register_cpu_add_notifier(&s->cpu_add_notifier);
>  }
>  
>  static void enable_device(PIIX4PMState *s, int slot)
> 

  reply	other threads:[~2013-03-27 10:47 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-21 14:28 [Qemu-devel] [RFC 00/12] target-i386: CPU hot-add with cpu_set QMP command Igor Mammedov
2013-03-21 14:28 ` [Qemu-devel] [PATCH 01/12] target-i386: consolidate error propagation in x86_cpu_realizefn() Igor Mammedov
2013-03-27 10:21   ` Paolo Bonzini
2013-04-01 20:00   ` Eduardo Habkost
2013-03-21 14:28 ` [Qemu-devel] [PATCH 02/12] target-i386: split APIC creation from initialization " Igor Mammedov
2013-04-04  8:59   ` Andreas Färber
2013-04-04  9:56     ` Igor Mammedov
2013-03-21 14:28 ` [Qemu-devel] [PATCH 03/12] target-i386: split out CPU creation and features parsing into cpu_x86_create() Igor Mammedov
2013-03-21 14:28 ` [Qemu-devel] [PATCH 04/12] target-i386: introduce apic-id property Igor Mammedov
2013-03-21 14:28 ` [Qemu-devel] [PATCH 05/12] target-i386: push hot-plugged VCPU state to KVM and unstop it Igor Mammedov
2013-03-27 11:01   ` Paolo Bonzini
2013-03-27 12:12     ` Igor Mammedov
2013-03-27 12:17       ` Andreas Färber
2013-03-27 13:27         ` Igor Mammedov
2013-03-27 14:30           ` Andreas Färber
2013-03-27 15:16             ` Igor Mammedov
2013-03-27 15:20               ` Paolo Bonzini
2013-03-27 19:46                 ` Igor Mammedov
2013-03-27 19:51                 ` [Qemu-devel] [PATCH 05/14] cpu: Pass CPUState to *cpu_synchronize_post*() Igor Mammedov
2013-03-27 19:51                 ` [Qemu-devel] [PATCH 06/14] cpu: call cpu_synchronize_post_init() from CPUClass.realize() if hotplugged Igor Mammedov
2013-03-27 19:51                 ` [Qemu-devel] [PATCH 07/14] cpu: introduce CPUClass.resume() method Igor Mammedov
2013-03-21 14:28 ` [Qemu-devel] [PATCH 06/12] target-i386: replace FROM_SYSBUS() with QOM type cast Igor Mammedov
2013-03-27 10:22   ` Paolo Bonzini
2013-04-04  9:03   ` Andreas Färber
2013-04-04  9:59     ` Igor Mammedov
2013-04-04 10:05       ` Andreas Färber
2013-04-04 10:22         ` Igor Mammedov
2013-03-21 14:28 ` [Qemu-devel] [PATCH 07/12] target-i386: Add ICC_BUS and attach apic, kvmvapic and cpu to it Igor Mammedov
2013-03-27 10:57   ` Paolo Bonzini
2013-03-28 10:55   ` Igor Mammedov
2013-03-29  7:22     ` li guang
2013-03-29  8:12       ` Igor Mammedov
2013-04-04 11:10     ` Andreas Färber
2013-04-04 12:52       ` Igor Mammedov
2013-03-21 14:28 ` [Qemu-devel] [PATCH 08/12] introduce CPU hot-plug notifier Igor Mammedov
2013-03-27 11:06   ` Paolo Bonzini
2013-03-27 15:24     ` Igor Mammedov
2013-03-27 15:36       ` Paolo Bonzini
2013-03-21 14:28 ` [Qemu-devel] [PATCH 09/12] rtc: update rtc_cmos on CPU hot-plug Igor Mammedov
2013-03-21 14:28 ` [Qemu-devel] [PATCH 10/12] acpi_piix4: add infrastructure to send CPU hot-plug GPE to guest Igor Mammedov
2013-03-27 10:47   ` Paolo Bonzini [this message]
2013-03-21 14:28 ` [Qemu-devel] [PATCH 11/12] qmp: add cpu_set qmp command Igor Mammedov
2013-03-22  2:44   ` Eric Blake
2013-03-25 15:35     ` [Qemu-devel] [PATCH 11/12 v2] qmp: add cpu-set " Igor Mammedov
2013-03-25 20:09       ` Luiz Capitulino
2013-03-25 20:22         ` Eric Blake
2013-03-26 13:43           ` Igor Mammedov
2013-03-26 14:02             ` Luiz Capitulino
2013-03-26 14:38             ` Eric Blake
2013-03-27 10:36   ` [Qemu-devel] [PATCH 11/12] qmp: add cpu_set " Paolo Bonzini
2013-03-21 14:28 ` [Qemu-devel] [PATCH 12/12] target-i386: implement CPU hot-add Igor Mammedov
2013-03-22  2:46   ` Eric Blake
2013-03-25 15:31     ` Igor Mammedov
2013-03-27 11:19   ` Paolo Bonzini
2013-04-03 17:58     ` Igor Mammedov
2013-04-03 18:10       ` Eduardo Habkost
2013-04-03 18:59         ` Igor Mammedov
2013-04-03 19:27           ` Eduardo Habkost
2013-04-03 20:09             ` Igor Mammedov
2013-04-03 20:57               ` Eduardo Habkost
2013-04-03 18:22       ` Andreas Färber
2013-04-03 19:01         ` Igor Mammedov
2013-03-21 14:44 ` [Qemu-devel] [RFC 00/12] target-i386: CPU hot-add with cpu_set QMP command Eric Blake
2013-03-21 15:38   ` 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=5152CE2D.1090909@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=aderumier@odiso.com \
    --cc=afaerber@suse.de \
    --cc=alex.williamson@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=anthony.perard@citrix.com \
    --cc=armbru@redhat.com \
    --cc=blauwirbel@gmail.com \
    --cc=claudio.fontana@huawei.com \
    --cc=ehabkost@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=jan.kiszka@siemens.com \
    --cc=kraxel@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=lcapitulino@redhat.com \
    --cc=mst@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=rth@twiddle.net \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=yang.z.zhang@intel.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 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.