aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-10-02 16:59:21 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-10-02 16:59:21 +0100
commitc0b520dfb8890294a9f8879f4759172900585995 (patch)
tree71cbe19275db1592c3ce2e2ec8ecb1502526fe3c /hw
parent945507d6bcde334f42b00cae134b4d47301d1821 (diff)
parent6fdac09370530be0cc6fe9e8d425c0670ba994b1 (diff)
downloadqemu-c0b520dfb8890294a9f8879f4759172900585995.zip
qemu-c0b520dfb8890294a9f8879f4759172900585995.tar.gz
qemu-c0b520dfb8890294a9f8879f4759172900585995.tar.bz2
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio,pc features, fixes New features: guest RAM buffer overrun mitigation RAM physical address gaps for memory hotplug (except refactoring which got some review comments) Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Fri 02 Oct 2015 15:04:56 BST using RSA key ID D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" * remotes/mst/tags/for_upstream: vhost-user-test: fix predictable filename on tmpfs vhost-user-test: use tmpfs by default pc: memhp: force gaps between DIMM's GPA memhp: extend address auto assignment to support gaps vhost-user: unit test for new messages vhost-user-test: do not reinvent glib-compat.h virtio: Notice when the system doesn't support MSIx at all pc: Add a comment explaining why pc_compat_2_4() doesn't exist exec: allocate PROT_NONE pages on top of RAM oslib: allocate PROT_NONE pages on top of RAM oslib: rework anonimous RAM allocation virtio-net: correctly drop truncated packets virtio: introduce virtqueue_discard() virtio: introduce virtqueue_unmap_sg() Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/i386/pc.c5
-rw-r--r--hw/i386/pc_piix.c8
-rw-r--r--hw/i386/pc_q35.c8
-rw-r--r--hw/mem/pc-dimm.c15
-rw-r--r--hw/net/virtio-net.c8
-rw-r--r--hw/ppc/spapr.c2
-rw-r--r--hw/virtio/virtio-pci.c17
-rw-r--r--hw/virtio/virtio.c21
8 files changed, 59 insertions, 25 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 461c128..efbd41a 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1629,6 +1629,7 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
HotplugHandlerClass *hhc;
Error *local_err = NULL;
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
MemoryRegion *mr = ddc->get_memory_region(dimm);
@@ -1644,7 +1645,8 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
goto out;
}
- pc_dimm_memory_plug(dev, &pcms->hotplug_memory, mr, align, &local_err);
+ pc_dimm_memory_plug(dev, &pcms->hotplug_memory, mr, align,
+ pcmc->inter_dimm_gap, &local_err);
if (local_err) {
goto out;
}
@@ -1945,6 +1947,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
PCMachineClass *pcmc = PC_MACHINE_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
+ pcmc->inter_dimm_gap = true;
pcmc->get_hotplug_handler = mc->get_hotplug_handler;
mc->get_hotplug_handler = pc_get_hotpug_handler;
mc->cpu_index_to_socket_id = pc_cpu_index_to_socket_id;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 3ffb05f..4514cd1 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -301,6 +301,13 @@ static void pc_init1(MachineState *machine,
}
}
+/* Looking for a pc_compat_2_4() function? It doesn't exist.
+ * pc_compat_*() functions that run on machine-init time and
+ * change global QEMU state are deprecated. Please don't create
+ * one, and implement any pc-*-2.4 (and newer) compat code in
+ * HW_COMPAT_*, PC_COMPAT_*, or * pc_*_machine_options().
+ */
+
static void pc_compat_2_3(MachineState *machine)
{
PCMachineState *pcms = PC_MACHINE(machine);
@@ -482,6 +489,7 @@ static void pc_i440fx_2_4_machine_options(MachineClass *m)
m->alias = NULL;
m->is_default = 0;
pcmc->broken_reserved_end = true;
+ pcmc->inter_dimm_gap = false;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_4);
}
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 1b7d3b6..1f100b1 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -284,6 +284,13 @@ static void pc_q35_init(MachineState *machine)
}
}
+/* Looking for a pc_compat_2_4() function? It doesn't exist.
+ * pc_compat_*() functions that run on machine-init time and
+ * change global QEMU state are deprecated. Please don't create
+ * one, and implement any pc-*-2.4 (and newer) compat code in
+ * HW_COMPAT_*, PC_COMPAT_*, or * pc_*_machine_options().
+ */
+
static void pc_compat_2_3(MachineState *machine)
{
PCMachineState *pcms = PC_MACHINE(machine);
@@ -385,6 +392,7 @@ static void pc_q35_2_4_machine_options(MachineClass *m)
pc_q35_2_5_machine_options(m);
m->alias = NULL;
pcmc->broken_reserved_end = true;
+ pcmc->inter_dimm_gap = false;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_4);
}
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index bb04862..6cc6ac3 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -32,7 +32,8 @@ typedef struct pc_dimms_capacity {
} pc_dimms_capacity;
void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
- MemoryRegion *mr, uint64_t align, Error **errp)
+ MemoryRegion *mr, uint64_t align, bool gap,
+ Error **errp)
{
int slot;
MachineState *machine = MACHINE(qdev_get_machine());
@@ -48,7 +49,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
addr = pc_dimm_get_free_addr(hpms->base,
memory_region_size(&hpms->mr),
- !addr ? NULL : &addr, align,
+ !addr ? NULL : &addr, align, gap,
memory_region_size(mr), &local_err);
if (local_err) {
goto out;
@@ -287,8 +288,8 @@ static int pc_dimm_built_list(Object *obj, void *opaque)
uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
uint64_t address_space_size,
- uint64_t *hint, uint64_t align, uint64_t size,
- Error **errp)
+ uint64_t *hint, uint64_t align, bool gap,
+ uint64_t size, Error **errp)
{
GSList *list = NULL, *item;
uint64_t new_addr, ret = 0;
@@ -333,13 +334,15 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
goto out;
}
- if (ranges_overlap(dimm->addr, dimm_size, new_addr, size)) {
+ if (ranges_overlap(dimm->addr, dimm_size, new_addr,
+ size + (gap ? 1 : 0))) {
if (hint) {
DeviceState *d = DEVICE(dimm);
error_setg(errp, "address range conflicts with '%s'", d->id);
goto out;
}
- new_addr = QEMU_ALIGN_UP(dimm->addr + dimm_size, align);
+ new_addr = QEMU_ALIGN_UP(dimm->addr + dimm_size + (gap ? 1 : 0),
+ align);
}
}
ret = new_addr;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index d388c55..a877614 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1094,13 +1094,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
* must have consumed the complete packet.
* Otherwise, drop it. */
if (!n->mergeable_rx_bufs && offset < size) {
-#if 0
- error_report("virtio-net truncated non-mergeable packet: "
- "i %zd mergeable %d offset %zd, size %zd, "
- "guest hdr len %zd, host hdr len %zd",
- i, n->mergeable_rx_bufs,
- offset, size, n->guest_hdr_len, n->host_hdr_len);
-#endif
+ virtqueue_discard(q->rx_vq, &elem, total);
return size;
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a9b5f2a..d1b0e53 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2096,7 +2096,7 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
goto out;
}
- pc_dimm_memory_plug(dev, &ms->hotplug_memory, mr, align, &local_err);
+ pc_dimm_memory_plug(dev, &ms->hotplug_memory, mr, align, false, &local_err);
if (local_err) {
goto out;
}
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index eda8205..6703806 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1491,12 +1491,17 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
pci_set_long(cfg_mask->pci_cfg_data, ~0x0);
}
- if (proxy->nvectors &&
- msix_init_exclusive_bar(&proxy->pci_dev, proxy->nvectors,
- proxy->msix_bar)) {
- error_report("unable to init msix vectors to %" PRIu32,
- proxy->nvectors);
- proxy->nvectors = 0;
+ if (proxy->nvectors) {
+ int err = msix_init_exclusive_bar(&proxy->pci_dev, proxy->nvectors,
+ proxy->msix_bar);
+ if (err) {
+ /* Notice when a system that supports MSIx can't initialize it. */
+ if (err != -ENOTSUP) {
+ error_report("unable to init msix vectors to %" PRIu32,
+ proxy->nvectors);
+ }
+ proxy->nvectors = 0;
+ }
}
proxy->pci_dev.config_write = virtio_write_config;
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 7504f8b..d0bc72e 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -244,14 +244,12 @@ int virtio_queue_empty(VirtQueue *vq)
return vring_avail_idx(vq) == vq->last_avail_idx;
}
-void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
- unsigned int len, unsigned int idx)
+static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
+ unsigned int len)
{
unsigned int offset;
int i;
- trace_virtqueue_fill(vq, elem, len, idx);
-
offset = 0;
for (i = 0; i < elem->in_num; i++) {
size_t size = MIN(len - offset, elem->in_sg[i].iov_len);
@@ -267,6 +265,21 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
cpu_physical_memory_unmap(elem->out_sg[i].iov_base,
elem->out_sg[i].iov_len,
0, elem->out_sg[i].iov_len);
+}
+
+void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
+ unsigned int len)
+{
+ vq->last_avail_idx--;
+ virtqueue_unmap_sg(vq, elem, len);
+}
+
+void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
+ unsigned int len, unsigned int idx)
+{
+ trace_virtqueue_fill(vq, elem, len, idx);
+
+ virtqueue_unmap_sg(vq, elem, len);
idx = (idx + vring_used_idx(vq)) % vq->vring.num;