qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC qom-cpu v4 09/10] piix4: implement function cpu_st


From: Vasilis Liaskovitis
Subject: Re: [Qemu-devel] [RFC qom-cpu v4 09/10] piix4: implement function cpu_status_write() for vcpu ejection
Date: Fri, 22 Nov 2013 09:02:27 +0100
User-agent: Mutt/1.5.21 (2010-09-15)

Hi,

On Wed, Oct 09, 2013 at 05:43:17PM +0800, Chen Fan wrote:
> When OS eject a vcpu (like: echo 1 > /sys/bus/acpi/devices/LNXCPUXX/eject),
> it will call acpi EJ0 method, the firmware will write the new cpumap, QEMU
> will know which vcpu need to be ejected.

I think that the _EJ0 callback (CPEJ method in 
hw/i386/acpi-dsdt-cpu-hotplug.dsl)
currently does not write the new cpumap, it only sleeps. So cpu_state_write is
never called on ejection, and the cpu objects remain allocated in qemu. Is there
an updated version of the patchseries with a CPEJ that writes the new cpumap?

thanks,

- Vasilis
> 
> Signed-off-by: Chen Fan <address@hidden>
> ---
>  hw/acpi/piix4.c | 37 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 36 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> index dc506bf..fd27001 100644
> --- a/hw/acpi/piix4.c
> +++ b/hw/acpi/piix4.c
> @@ -61,6 +61,7 @@ struct pci_status {
>  
>  typedef struct CPUStatus {
>      uint8_t sts[PIIX4_PROC_LEN];
> +    uint8_t old_sts[PIIX4_PROC_LEN];
>  } CPUStatus;
>  
>  typedef struct PIIX4PMState {
> @@ -611,6 +612,12 @@ static const MemoryRegionOps piix4_pci_ops = {
>      },
>  };
>  
> +static void acpi_piix_eject_vcpu(int64_t cpuid)
> +{
> +    /* TODO: eject a vcpu, release allocated vcpu and exit the vcpu pthread. 
>  */
> +    PIIX4_DPRINTF("vcpu: %" PRIu64 " need to be ejected.\n", cpuid);
> +}
> +
>  static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size)
>  {
>      PIIX4PMState *s = opaque;
> @@ -623,7 +630,27 @@ static uint64_t cpu_status_read(void *opaque, hwaddr 
> addr, unsigned int size)
>  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 
> */
> +    PIIX4PMState *s = opaque;
> +    CPUStatus *cpus = &s->gpe_cpu;
> +    uint8_t val;
> +    int i;
> +    int64_t cpuid = 0;
> +
> +    val = cpus->old_sts[addr] ^ data;
> +
> +    if (val == 0) {
> +        return;
> +    }
> +
> +    for (i = 0; i < 8; i++) {
> +        if (val & 1 << i) {
> +            cpuid = 8 * addr + i;
> +        }
> +    }
> +
> +    if (cpuid != 0) {
> +        acpi_piix_eject_vcpu(cpuid);
> +    }
>  }
>  
>  static const MemoryRegionOps cpu_hotplug_ops = {
> @@ -643,13 +670,20 @@ static void piix4_cpu_hotplug_req(PIIX4PMState *s, 
> CPUState *cpu,
>      ACPIGPE *gpe = &s->ar.gpe;
>      CPUClass *k = CPU_GET_CLASS(cpu);
>      int64_t cpu_id;
> +    int i;
>  
>      assert(s != NULL);
>  
>      *gpe->sts = *gpe->sts | PIIX4_CPU_HOTPLUG_STATUS;
>      cpu_id = k->get_arch_id(CPU(cpu));
> +
> +    for (i = 0; i < PIIX4_PROC_LEN; i++) {
> +        g->old_sts[i] = g->sts[i];
> +    }
> +
>      if (action == PLUG) {
>          g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
> +        g->old_sts[cpu_id / 8] |= (1 << (cpu_id % 8));
>      } else {
>          g->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
>      }
> @@ -688,6 +722,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
> *parent,
>  
>          g_assert((id / 8) < PIIX4_PROC_LEN);
>          s->gpe_cpu.sts[id / 8] |= (1 << (id % 8));
> +        s->gpe_cpu.old_sts[id / 8] |= (1 << (id % 8));
>      }
>      memory_region_init_io(&s->io_cpu, OBJECT(s), &cpu_hotplug_ops, s,
>                            "acpi-cpu-hotplug", PIIX4_PROC_LEN);
> -- 
> 1.8.1.4
> 
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]