Commit 4383fa7c authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging



virtio, vhost, pc: fixes, features

writeable fw cfg blobs which will be used for guest to host
communication
fixes and cleanups all over the place

Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Thu 19 Jan 2017 21:08:04 GMT
# gpg:                using RSA key 0x281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* remotes/mst/tags/for_upstream:
  virtio: force VIRTIO_F_IOMMU_PLATFORM
  virtio: fix up max size checks
  vhost: drop VHOST_F_DEVICE_IOTLB
  update-linux-headers.sh: support __bitwise
  virtio_crypto: header update
  pci_regs: update to latest linux
  virtio-mmio: switch to linux headers
  virtio_mmio: add standard header file
  virtio: drop an obsolete comment
  fw-cfg: bump "x-file-slots" to 0x20 for 2.9+ machine types
  pc: Add 2.9 machine-types
  fw-cfg: turn FW_CFG_FILE_SLOTS into a device property
  fw-cfg: support writeable blobs
  vhost_net: device IOTLB support
  virtio: disable notifications again after poll succeeded
  Revert "virtio: turn vq->notification into a nested counter"
  virtio-net: enable ioeventfd even if vhost=off

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 6ffefe7f 2943b53f
Loading
Loading
Loading
Loading
+27 −9
Original line number Diff line number Diff line
@@ -33,6 +33,10 @@ the selector value is between 0x4000-0x7fff or 0xc000-0xffff.
NOTE: As of QEMU v2.4, writes to the fw_cfg data register are no
      longer supported, and will be ignored (treated as no-ops)!

NOTE: As of QEMU v2.9, writes are reinstated, but only through the DMA
      interface (see below). Furthermore, writeability of any specific item is
      governed independently of Bit14 in the selector key value.

Bit15 of the selector register indicates whether the configuration
setting is architecture specific. A value of 0 means the item is a
generic configuration item. A value of 1 means the item is specific
@@ -43,7 +47,7 @@ value between 0x8000-0xffff.

== Data Register ==

* Read/Write (writes ignored as of QEMU v2.4)
* Read/Write (writes ignored as of QEMU v2.4, but see the DMA interface)
* Location: platform dependent (IOport [*] or MMIO)
* Width: 8-bit (if IOport), 8/16/32/64-bit (if MMIO)
* Endianness: string-preserving
@@ -134,8 +138,8 @@ struct FWCfgFile { /* an individual file entry, 64 bytes total */

=== All Other Data Items ===

Please consult the QEMU source for the most up-to-date and authoritative
list of selector keys and their respective items' purpose and format.
Please consult the QEMU source for the most up-to-date and authoritative list
of selector keys and their respective items' purpose, format and writeability.

=== Ranges ===

@@ -144,13 +148,15 @@ items, and up to 0x4000 architecturally specific ones.

Selector Reg.    Range Usage
---------------  -----------
0x0000 - 0x3fff  Generic (0x0000 - 0x3fff, RO)
0x0000 - 0x3fff  Generic (0x0000 - 0x3fff, generally RO, possibly RW through
                          the DMA interface in QEMU v2.9+)
0x4000 - 0x7fff  Generic (0x0000 - 0x3fff, RW, ignored in QEMU v2.4+)
0x8000 - 0xbfff  Arch. Specific (0x0000 - 0x3fff, RO)
0x8000 - 0xbfff  Arch. Specific (0x0000 - 0x3fff, generally RO, possibly RW
                                 through the DMA interface in QEMU v2.9+)
0xc000 - 0xffff  Arch. Specific (0x0000 - 0x3fff, RW, ignored in v2.4+)

In practice, the number of allowed firmware configuration items is given
by the value of FW_CFG_MAX_ENTRY (see fw_cfg.h).
In practice, the number of allowed firmware configuration items depends on the
machine type/version.

= Guest-side DMA Interface =

@@ -182,6 +188,7 @@ The "control" field has the following bits:
 - Bit 1: Read
 - Bit 2: Skip
 - Bit 3: Select. The upper 16 bits are the selected index.
 - Bit 4: Write

When an operation is triggered, if the "control" field has bit 3 set, the
upper 16 bits are interpreted as an index of a firmware configuration item.
@@ -191,8 +198,17 @@ If the "control" field has bit 1 set, a read operation will be performed.
"length" bytes for the current selector and offset will be copied into the
physical RAM address specified by the "address" field.

If the "control" field has bit 2 set (and not bit 1), a skip operation will be
performed. The offset for the current selector will be advanced "length" bytes.
If the "control" field has bit 4 set (and not bit 1), a write operation will be
performed. "length" bytes will be copied from the physical RAM address
specified by the "address" field to the current selector and offset. QEMU
prevents starting or finishing the write beyond the end of the item associated
with the current selector (i.e., the item cannot be resized). Truncated writes
are dropped entirely. Writes to read-only items are also rejected. All of these
write errors set bit 0 (the error bit) in the "control" field.

If the "control" field has bit 2 set (and neither bit 1 nor bit 4), a skip
operation will be performed. The offset for the current selector will be
advanced "length" bytes.

To check the result, read the "control" field:
   error bit set        ->  something went wrong.
@@ -234,3 +250,5 @@ Prefix "opt/org.qemu/" is reserved for QEMU itself.

Use of names not beginning with "opt/" is potentially dangerous and
entirely unsupported.  QEMU will warn if you try.

All externally provided fw_cfg items are read-only to the guest.
+1 −1
Original line number Diff line number Diff line
@@ -842,7 +842,7 @@ static MemoryRegion *acpi_add_rom_blob(AcpiBuildState *build_state,
                                       uint64_t max_size)
{
    return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1,
                        name, virt_acpi_build_update, build_state, NULL);
                        name, virt_acpi_build_update, build_state, NULL, true);
}

static const VMStateDescription vmstate_virt_acpi_build = {
+11 −7
Original line number Diff line number Diff line
@@ -853,7 +853,7 @@ static void fw_cfg_resized(const char *id, uint64_t length, void *host)
    }
}

static void *rom_set_mr(Rom *rom, Object *owner, const char *name)
static void *rom_set_mr(Rom *rom, Object *owner, const char *name, bool ro)
{
    void *data;

@@ -862,7 +862,7 @@ static void *rom_set_mr(Rom *rom, Object *owner, const char *name)
                                      rom->datasize, rom->romsize,
                                      fw_cfg_resized,
                                      &error_fatal);
    memory_region_set_readonly(rom->mr, true);
    memory_region_set_readonly(rom->mr, ro);
    vmstate_register_ram_global(rom->mr);

    data = memory_region_get_ram_ptr(rom->mr);
@@ -942,7 +942,7 @@ int rom_add_file(const char *file, const char *fw_dir,
        snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);

        if ((!option_rom || mc->option_rom_has_mr) && mc->rom_file_has_mr) {
            data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
            data = rom_set_mr(rom, OBJECT(fw_cfg), devpath, true);
        } else {
            data = rom->data;
        }
@@ -979,7 +979,7 @@ err:
MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
                   size_t max_len, hwaddr addr, const char *fw_file_name,
                   FWCfgReadCallback fw_callback, void *callback_opaque,
                   AddressSpace *as)
                   AddressSpace *as, bool read_only)
{
    MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
    Rom *rom;
@@ -998,10 +998,14 @@ MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
        char devpath[100];
        void *data;

        if (read_only) {
            snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
        } else {
            snprintf(devpath, sizeof(devpath), "/ram@%s", fw_file_name);
        }

        if (mc->rom_file_has_mr) {
            data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
            data = rom_set_mr(rom, OBJECT(fw_cfg), devpath, read_only);
            mr = rom->mr;
        } else {
            data = rom->data;
@@ -1009,7 +1013,7 @@ MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,

        fw_cfg_add_file_callback(fw_cfg, fw_file_name,
                                 fw_callback, callback_opaque,
                                 data, rom->datasize);
                                 data, rom->datasize, read_only);
    }
    return mr;
}
+2 −2
Original line number Diff line number Diff line
@@ -2806,7 +2806,7 @@ static MemoryRegion *acpi_add_rom_blob(AcpiBuildState *build_state,
                                       uint64_t max_size)
{
    return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1,
                        name, acpi_build_update, build_state, NULL);
                        name, acpi_build_update, build_state, NULL, true);
}

static const VMStateDescription vmstate_acpi_build = {
@@ -2872,7 +2872,7 @@ void acpi_setup(void)
        build_state->rsdp = g_memdup(tables.rsdp->data, rsdp_size);
        fw_cfg_add_file_callback(pcms->fw_cfg, ACPI_BUILD_RSDP_FILE,
                                 acpi_build_update, build_state,
                                 build_state->rsdp, rsdp_size);
                                 build_state->rsdp, rsdp_size, true);
        build_state->rsdp_mr = NULL;
    } else {
        build_state->rsdp = NULL;
+12 −3
Original line number Diff line number Diff line
@@ -437,13 +437,24 @@ static void pc_i440fx_machine_options(MachineClass *m)
    m->default_display = "std";
}

static void pc_i440fx_2_8_machine_options(MachineClass *m)
static void pc_i440fx_2_9_machine_options(MachineClass *m)
{
    pc_i440fx_machine_options(m);
    m->alias = "pc";
    m->is_default = 1;
}

DEFINE_I440FX_MACHINE(v2_9, "pc-i440fx-2.9", NULL,
                      pc_i440fx_2_9_machine_options);

static void pc_i440fx_2_8_machine_options(MachineClass *m)
{
    pc_i440fx_2_9_machine_options(m);
    m->is_default = 0;
    m->alias = NULL;
    SET_MACHINE_COMPAT(m, PC_COMPAT_2_8);
}

DEFINE_I440FX_MACHINE(v2_8, "pc-i440fx-2.8", NULL,
                      pc_i440fx_2_8_machine_options);

@@ -451,8 +462,6 @@ DEFINE_I440FX_MACHINE(v2_8, "pc-i440fx-2.8", NULL,
static void pc_i440fx_2_7_machine_options(MachineClass *m)
{
    pc_i440fx_2_8_machine_options(m);
    m->is_default = 0;
    m->alias = NULL;
    SET_MACHINE_COMPAT(m, PC_COMPAT_2_7);
}

Loading