qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: Igor Mammedov <imammedo@redhat.com>
Cc: qemu devel list <qemu-devel@nongnu.org>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v4 5/7] hw/isa/lpc_ich9: add SMI feature negotiation via fw_cfg
Date: Fri, 2 Dec 2016 13:00:09 +0100	[thread overview]
Message-ID: <b35ddc6b-3065-06fb-dcc2-a7299cd0fd3d@redhat.com> (raw)
In-Reply-To: <20161202125412.2423360d@nial.brq.redhat.com>

On 12/02/16 12:54, Igor Mammedov wrote:
> On Thu,  1 Dec 2016 18:06:22 +0100
> Laszlo Ersek <lersek@redhat.com> wrote:
> 
>> Introduce the following fw_cfg files:
>>
>> - "etc/smi/host-features": a little endian uint64_t feature bitmap,
>>   presenting the features known by the host to the guest. Read-only for
>>   the guest.
> 'host' here is a little bit confusing, I'd suggest 'supported-features'
> instead.
> 
>  
>>   The content of this file is calculated by QEMU at startup (the
>>   calculation will be added later). The same machine type is supposed to
>>   expose the same SMI features regardless of QEMU version, hence this file
>>   is not migrated.
>>
>> - "etc/smi/guest-features": a little endian uint64_t feature bitmap,
>>   representing the features the guest would like to request. Read-write
>>   for the guest.
> and to match above 'requested-features'

The names were supposed to follow virtio 1.0, which calls these things
"device features" and "driver features".

Not a big deal anyway, I can update the file names as you suggest.

>>   The guest can freely (re)write this file, it has no direct consequence.
>>   Initial value is zero. A nonzero value causes the SMI-related fw_cfg
>>   files and fields that are under guest influence to be migrated.
>>
>> - "etc/smi/features-ok": contains a uint8_t value, and it is read-only for
>>   the guest. When the guest selects the associated fw_cfg key, the guest
>>   features are validated against the host features. In case of error, the
>>   negotiation doesn't proceed, and the features-ok file remains zero. In
>>   case of success, the features-ok file becomes (uint8_t)1, and the
>>   negotiated features are locked down internally (to which no further
>>   changes are possible until reset).
>>
>>   The initial value is zero.  A nonzero value causes the SMI-related
>>   fw_cfg files and fields that are under guest influence to be migrated.
>>
>> The C-language fields backing the host-features and guest-features files
>> are uint8_t arrays. This is because they carry guest-side representation
>> (our choice is little endian), while VMSTATE_UINT64() assumes / implies
>> host-side endianness for any uint64_t fields. If we migrate a guest
>> between hosts with different endiannesses (which is possible with TCG),
>> then the host-side value is preserved, and the host-side representation is
>> translated. This would be visible to the guest through fw_cfg, unless we
>> used plain byte arrays. So we do.
>>
>> Cc: "Michael S. Tsirkin" <mst@redhat.com>
>> Cc: Gerd Hoffmann <kraxel@redhat.com>
>> Cc: Igor Mammedov <imammedo@redhat.com>
>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
>> ---
>>  include/hw/i386/ich9.h | 12 +++++++-
>>  hw/i386/pc_q35.c       |  2 +-
>>  hw/isa/lpc_ich9.c      | 83 +++++++++++++++++++++++++++++++++++++++++++++++++-
>>  3 files changed, 94 insertions(+), 3 deletions(-)
>>
>> diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
>> index 5fd7e97d2347..33142eb37252 100644
>> --- a/include/hw/i386/ich9.h
>> +++ b/include/hw/i386/ich9.h
>> @@ -15,11 +15,12 @@
>>  #include "hw/pci/pci_bus.h"
>>  
>>  void ich9_lpc_set_irq(void *opaque, int irq_num, int level);
>>  int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx);
>>  PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin);
>> -void ich9_lpc_pm_init(PCIDevice *pci_lpc, bool smm_enabled);
>> +void ich9_lpc_pm_init(PCIDevice *pci_lpc, bool smm_enabled,
>> +                      uint64_t smi_host_features);
>>  I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
>>  
>>  void ich9_generate_smi(void);
>>  void ich9_generate_nmi(void);
>>  
>> @@ -62,10 +63,19 @@ typedef struct ICH9LPCState {
>>       * register contents and IO memory region
>>       */
>>      uint8_t rst_cnt;
>>      MemoryRegion rst_cnt_mem;
>>  
>> +    /* SMI feature negotiation via fw_cfg */
>> +    uint8_t smi_host_features[8];     /* guest-visible, read-only, little
>> +                                       * endian uint64_t */
>> +    uint8_t smi_guest_features[8];    /* guest-visible, read-write, little
>> +                                       * endian uint64_t */
> how about adding _le suffix to 2 above fields?
> that way it would be easier to read usage places without chance to misinterpret content

Good idea, I will do that.

Thanks!
Laszlo

> 
>> +    uint8_t smi_features_ok;          /* guest-visible, read-only; selecting it
>> +                                       * triggers feature lockdown */
>> +    uint64_t smi_negotiated_features; /* guest-invisible, host endian */
>> +
>>      /* isa bus */
>>      ISABus *isa_bus;
>>      MemoryRegion rcrb_mem; /* root complex register block */
>>      Notifier machine_ready;
>>  
>> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
>> index 7fa40e7cbe0e..eb0953bb6b16 100644
>> --- a/hw/i386/pc_q35.c
>> +++ b/hw/i386/pc_q35.c
>> @@ -228,11 +228,11 @@ static void pc_q35_init(MachineState *machine)
>>      /* init basic PC hardware */
>>      pc_basic_device_init(isa_bus, pcms->gsi, &rtc_state, !mc->no_floppy,
>>                           (pcms->vmport != ON_OFF_AUTO_ON), 0xff0104);
>>  
>>      /* connect pm stuff to lpc */
>> -    ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pcms));
>> +    ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pcms), 0);
>>  
>>      /* ahci and SATA device, for q35 1 ahci controller is built-in */
>>      ahci = pci_create_simple_multifunction(host_bus,
>>                                             PCI_DEVFN(ICH9_SATA1_DEV,
>>                                                       ICH9_SATA1_FUNC),
>> diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
>> index 10d1ee8b9310..ee1fa553bfee 100644
>> --- a/hw/isa/lpc_ich9.c
>> +++ b/hw/isa/lpc_ich9.c
>> @@ -46,10 +46,12 @@
>>  #include "hw/acpi/ich9.h"
>>  #include "hw/pci/pci_bus.h"
>>  #include "exec/address-spaces.h"
>>  #include "sysemu/sysemu.h"
>>  #include "qom/cpu.h"
>> +#include "hw/nvram/fw_cfg.h"
>> +#include "qemu/cutils.h"
>>  
>>  /*****************************************************************************/
>>  /* ICH9 LPC PCI to ISA bridge */
>>  
>>  static void ich9_lpc_reset(DeviceState *qdev);
>> @@ -358,17 +360,68 @@ static void ich9_set_sci(void *opaque, int irq_num, int level)
>>      } else {
>>          ich9_lpc_update_pic(lpc, irq);
>>      }
>>  }
>>  
>> -void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled)
>> +static void smi_features_ok_callback(void *opaque)
>> +{
>> +    ICH9LPCState *lpc = opaque;
>> +    uint64_t host_features, guest_features;
>> +
>> +    if (lpc->smi_features_ok) {
>> +        /* negotiation already complete, features locked */
>> +        return;
>> +    }
>> +
>> +    memcpy(&host_features, lpc->smi_host_features, sizeof host_features);
>> +    memcpy(&guest_features, lpc->smi_guest_features, sizeof guest_features);
>> +    le64_to_cpus(&host_features);
>> +    le64_to_cpus(&guest_features);
>> +
>> +    if (guest_features & ~host_features) {
>> +        /* guest requests invalid features, leave @features_ok at zero */
>> +        return;
>> +    }
>> +
>> +    /* valid feature subset requested, lock it down, report success */
>> +    lpc->smi_negotiated_features = guest_features;
>> +    lpc->smi_features_ok = 1;
>> +}
>> +
>> +void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled,
>> +                      uint64_t smi_host_features)
>>  {
>>      ICH9LPCState *lpc = ICH9_LPC_DEVICE(lpc_pci);
>>      qemu_irq sci_irq;
>> +    FWCfgState *fw_cfg = fw_cfg_find();
>>  
>>      sci_irq = qemu_allocate_irq(ich9_set_sci, lpc, 0);
>>      ich9_pm_init(lpc_pci, &lpc->pm, smm_enabled, sci_irq);
>> +
>> +    if (smi_host_features && fw_cfg) {
>> +        cpu_to_le64s(&smi_host_features);
>> +        memcpy(lpc->smi_host_features, &smi_host_features,
>> +               sizeof smi_host_features);
>> +        fw_cfg_add_file(fw_cfg, "etc/smi/host-features",
>> +                        lpc->smi_host_features,
>> +                        sizeof lpc->smi_host_features);
>> +
>> +        /* The other two guest-visible fields are cleared on device reset, we
>> +         * just link them into fw_cfg here.
>> +         */
>> +        fw_cfg_add_file_callback(fw_cfg, "etc/smi/guest-features",
>> +                                 NULL, NULL,
>> +                                 lpc->smi_guest_features,
>> +                                 sizeof lpc->smi_guest_features,
>> +                                 false);
>> +        fw_cfg_add_file_callback(fw_cfg, "etc/smi/features-ok",
>> +                                 smi_features_ok_callback, lpc,
>> +                                 &lpc->smi_features_ok,
>> +                                 sizeof lpc->smi_features_ok,
>> +                                 true);
>> +    }
>> +
>>      ich9_lpc_reset(&lpc->d.qdev);
>>  }
>>  
>>  /* APM */
>>  
>> @@ -505,10 +558,14 @@ static void ich9_lpc_reset(DeviceState *qdev)
>>      ich9_lpc_pmbase_sci_update(lpc);
>>      ich9_lpc_rcba_update(lpc, rcba_old);
>>  
>>      lpc->sci_level = 0;
>>      lpc->rst_cnt = 0;
>> +
>> +    memset(lpc->smi_guest_features, 0, sizeof lpc->smi_guest_features);
>> +    lpc->smi_features_ok = 0;
>> +    lpc->smi_negotiated_features = 0;
>>  }
>>  
>>  /* root complex register block is mapped into memory space */
>>  static const MemoryRegionOps rcrb_mmio_ops = {
>>      .read = ich9_cc_read,
>> @@ -666,10 +723,33 @@ static const VMStateDescription vmstate_ich9_rst_cnt = {
>>          VMSTATE_UINT8(rst_cnt, ICH9LPCState),
>>          VMSTATE_END_OF_LIST()
>>      }
>>  };
>>  
>> +static bool ich9_smi_feat_needed(void *opaque)
>> +{
>> +    ICH9LPCState *lpc = opaque;
>> +
>> +    return !buffer_is_zero(lpc->smi_guest_features,
>> +                           sizeof lpc->smi_guest_features) ||
>> +           lpc->smi_features_ok;
>> +}
>> +
>> +static const VMStateDescription vmstate_ich9_smi_feat = {
>> +    .name = "ICH9LPC/smi_feat",
>> +    .version_id = 1,
>> +    .minimum_version_id = 1,
>> +    .needed = ich9_smi_feat_needed,
>> +    .fields = (VMStateField[]) {
>> +        VMSTATE_UINT8_ARRAY(smi_guest_features, ICH9LPCState,
>> +                            sizeof(uint64_t)),
>> +        VMSTATE_UINT8(smi_features_ok, ICH9LPCState),
>> +        VMSTATE_UINT64(smi_negotiated_features, ICH9LPCState),
>> +        VMSTATE_END_OF_LIST()
>> +    }
>> +};
>> +
>>  static const VMStateDescription vmstate_ich9_lpc = {
>>      .name = "ICH9LPC",
>>      .version_id = 1,
>>      .minimum_version_id = 1,
>>      .post_load = ich9_lpc_post_load,
>> @@ -681,10 +761,11 @@ static const VMStateDescription vmstate_ich9_lpc = {
>>          VMSTATE_UINT32(sci_level, ICH9LPCState),
>>          VMSTATE_END_OF_LIST()
>>      },
>>      .subsections = (const VMStateDescription*[]) {
>>          &vmstate_ich9_rst_cnt,
>> +        &vmstate_ich9_smi_feat,
>>          NULL
>>      }
>>  };
>>  
>>  static Property ich9_lpc_properties[] = {
> 

  reply	other threads:[~2016-12-02 12:00 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-01 17:06 [Qemu-devel] [PATCH v4 0/7] q35: add negotiable broadcast SMI Laszlo Ersek
2016-12-01 17:06 ` [Qemu-devel] [PATCH v4 1/7] fw-cfg: support writeable blobs Laszlo Ersek
2016-12-20 15:58   ` Marcel Apfelbaum
2017-01-10 13:33     ` Laszlo Ersek
2016-12-01 17:06 ` [Qemu-devel] [PATCH v4 2/7] fw-cfg: turn FW_CFG_FILE_SLOTS into a device property Laszlo Ersek
2016-12-02 11:10   ` Gerd Hoffmann
2016-12-02 11:48     ` Laszlo Ersek
2016-12-02 12:47       ` Gerd Hoffmann
2016-12-06 10:50   ` Igor Mammedov
2016-12-06 11:43     ` Laszlo Ersek
2016-12-06 12:02       ` Igor Mammedov
2016-12-06 16:22         ` Laszlo Ersek
2017-01-10 15:02   ` Michael S. Tsirkin
2016-12-01 17:06 ` [Qemu-devel] [PATCH v4 3/7] fw-cfg: expose "file_slots" parameter in fw_cfg_init_io_dma() Laszlo Ersek
2016-12-06 11:49   ` Igor Mammedov
2016-12-06 16:46     ` Laszlo Ersek
2016-12-06 16:52       ` Laszlo Ersek
2016-12-06 23:21         ` David Gibson
2016-12-06 18:09       ` Igor Mammedov
2016-12-06 19:29         ` Stefano Stabellini
2017-01-10 15:02   ` Michael S. Tsirkin
2016-12-01 17:06 ` [Qemu-devel] [PATCH v4 4/7] hw/i386/pc: introduce 2.9 machine types with 0x20 fw_cfg file slots Laszlo Ersek
2016-12-01 17:06 ` [Qemu-devel] [PATCH v4 5/7] hw/isa/lpc_ich9: add SMI feature negotiation via fw_cfg Laszlo Ersek
2016-12-02 11:54   ` Igor Mammedov
2016-12-02 12:00     ` Laszlo Ersek [this message]
2016-12-01 17:06 ` [Qemu-devel] [PATCH v4 6/7] hw/isa/lpc_ich9: add broadcast SMI feature Laszlo Ersek
2016-12-01 17:06 ` [Qemu-devel] [PATCH v4 7/7] hw/i386/pc_q35: advertise broadcast SMI if VCPU hotplug is turned off Laszlo Ersek
2016-12-01 19:13   ` Eduardo Habkost
2016-12-01 20:42     ` Laszlo Ersek
2016-12-01 20:53       ` Eduardo Habkost
2016-12-02 12:18       ` Igor Mammedov
2016-12-02 19:32         ` Laszlo Ersek
2016-12-20 23:01 ` [Qemu-devel] [PATCH v4 0/7] q35: add negotiable broadcast SMI no-reply
2016-12-21 15:22   ` [Qemu-devel] checkpatch.pl false positive (was Re: [PATCH v4 0/7] q35: add negotiable broadcast SMI) Eduardo Habkost
2016-12-21 17:47     ` Paolo Bonzini
2016-12-21 18:01       ` Eduardo Habkost
2016-12-21 18:08         ` Paolo Bonzini
2016-12-21 18:19           ` Eduardo Habkost
2017-01-10 15:06 ` [Qemu-devel] [PATCH v4 0/7] q35: add negotiable broadcast SMI Michael S. Tsirkin
2017-01-10 15:23   ` Laszlo Ersek
2017-01-10 16:05     ` Michael S. Tsirkin
2017-01-10 16:19       ` Laszlo Ersek
2017-01-10 16:21     ` Igor Mammedov
2017-01-10 16:30       ` Laszlo Ersek

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=b35ddc6b-3065-06fb-dcc2-a7299cd0fd3d@redhat.com \
    --to=lersek@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.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 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).