From b4f4d54812624581ce429c805e5179c78222c707 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 26 Mar 2014 12:31:31 +0200 Subject: [PATCH 1/4] acpi: make SSDT 1.0 spec compliant when possible The ACPI specification says: The ASL compiler can emit two different AML opcodes for a Package declaration, either PackageOp or VarPackageOp. For small, fixed-length packages, the PackageOp is used and this opcode is compatible with ACPI 1.0. A VarPackageOp will be emitted if any of the following conditions are true: . The NumElements argument is a TermArg that can only be resolved at runtime. . At compile time, NumElements resolves to a constant that is larger than 255. . The PackageList contains more than 255 initializer elements. Note: The ability to create variable-sized packages was first introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages with up to 255 elements. So the spec seems to say a fixed value up to 255 must always be used with PackageOp and not VarPackageOp, and some guests (windows up to win2k8) seem to interpret it like this. Let's do just this, choosing the encoding depending on the number of elements. Fixes 9bcc80cd71892df42605e0c097d85c0237ff45d1 (i386/acpi-build: allow more than 255 elements in CPON). https://bugs.launchpad.net/bugs/1297651 Reported-by: Robert Hu Cc: Laszlo Ersek Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index f1054dd831..7597517b97 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1055,9 +1055,21 @@ build_ssdt(GArray *table_data, GArray *linker, { GArray *package = build_alloc_array(); - uint8_t op = 0x13; /* VarPackageOp */ + uint8_t op; + + /* + * Note: The ability to create variable-sized packages was first introduced in ACPI 2.0. ACPI 1.0 only + * allowed fixed-size packages with up to 255 elements. + * Windows guests up to win2k8 fail when VarPackageOp is used. + */ + if (acpi_cpus <= 255) { + op = 0x12; /* PackageOp */ + build_append_byte(package, acpi_cpus); /* NumElements */ + } else { + op = 0x13; /* VarPackageOp */ + build_append_int(package, acpi_cpus); /* VarNumElements */ + } - build_append_int(package, acpi_cpus); /* VarNumElements */ for (i = 0; i < acpi_cpus; i++) { uint8_t b = test_bit(i, cpu->found_cpus) ? 0x01 : 0x00; build_append_byte(package, b); From 53a786acac7b4d53288d603504021d928f734513 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 26 Mar 2014 12:42:31 +0200 Subject: [PATCH 2/4] Revert "acpi-test: rebuild SSDT" This reverts commit d07e0e9cddf02dd2abedbbf7ab0e069c8f5dabfd. Since commit b4f4d54812624581ce429c805e5179c78222c707 acpi: make SSDT 1.0 spec compliant when possible We are back to old encoding. Signed-off-by: Michael S. Tsirkin --- tests/acpi-test-data/pc/SSDT | Bin 2261 -> 2261 bytes tests/acpi-test-data/q35/SSDT | Bin 550 -> 550 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/acpi-test-data/pc/SSDT b/tests/acpi-test-data/pc/SSDT index 727853eece80ef2d163730506f987de181f69d5e..6444f60ce786da7000d23b11d796cca579747f0c 100644 GIT binary patch delta 26 icmcaAcvX-qIM^lRDhC4t Date: Wed, 26 Mar 2014 18:29:52 +0800 Subject: [PATCH 3/4] virtio-net: Do not filter VLANs without F_CTRL_VLAN If VIRTIO_NET_F_CTRL_VLAN is not negotiated, do not filter out all VLAN-tagged packets but send them to the guest. This fixes VLANs with OpenBSD guests (and probably NetBSD, too, because the OpenBSD driver started as a port from NetBSD). Signed-off-by: Stefan Fritsch Signed-off-by: Amos Kong Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/virtio-net.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index fd23c4627e..33fb7992c6 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -514,6 +514,12 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features) } vhost_net_ack_features(tap_get_vhost_net(nc->peer), features); } + + if ((1 << VIRTIO_NET_F_CTRL_VLAN) & features) { + memset(n->vlans, 0, MAX_VLAN >> 3); + } else { + memset(n->vlans, 0xff, MAX_VLAN >> 3); + } } static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd, From f7bc8ef8091229a4bec0e2a40af90abb8dcb3834 Mon Sep 17 00:00:00 2001 From: Amos Kong Date: Wed, 26 Mar 2014 08:19:43 +0800 Subject: [PATCH 4/4] virtio-net: add vlan receive state to RxFilterInfo Stefan Fritsch just fixed a virtio-net driver bug [1], virtio-net won't filter out VLAN-tagged packets if VIRTIO_NET_F_CTRL_VLAN isn't negotiated. This patch added a new field to @RxFilterInfo to indicate vlan receive state ('normal', 'none', 'all'). If VIRTIO_NET_F_CTRL_VLAN isn't negotiated, vlan receive state will be 'all', then all VLAN-tagged packets will be received by guest. This patch also fixed a boundary issue in visiting vlan table. [1] http://lists.nongnu.org/archive/html/qemu-devel/2014-02/msg02604.html Signed-off-by: Amos Kong Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Eric Blake --- hw/net/virtio-net.c | 42 +++++++++++++++++++++++++++++------------- qapi-schema.json | 3 +++ qmp-commands.hx | 2 ++ 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 33fb7992c6..439477b954 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -222,13 +222,33 @@ static char *mac_strdup_printf(const uint8_t *mac) mac[1], mac[2], mac[3], mac[4], mac[5]); } +static intList *get_vlan_table(VirtIONet *n) +{ + intList *list, *entry; + int i, j; + + list = NULL; + for (i = 0; i < MAX_VLAN >> 5; i++) { + for (j = 0; n->vlans[i] && j <= 0x1f; j++) { + if (n->vlans[i] & (1U << j)) { + entry = g_malloc0(sizeof(*entry)); + entry->value = (i << 5) + j; + entry->next = list; + list = entry; + } + } + } + + return list; +} + static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc) { VirtIONet *n = qemu_get_nic_opaque(nc); + VirtIODevice *vdev = VIRTIO_DEVICE(n); RxFilterInfo *info; strList *str_list, *entry; - intList *int_list, *int_entry; - int i, j; + int i; info = g_malloc0(sizeof(*info)); info->name = g_strdup(nc->name); @@ -273,19 +293,15 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc) str_list = entry; } info->multicast_table = str_list; + info->vlan_table = get_vlan_table(n); - int_list = NULL; - for (i = 0; i < MAX_VLAN >> 5; i++) { - for (j = 0; n->vlans[i] && j < 0x1f; j++) { - if (n->vlans[i] & (1U << j)) { - int_entry = g_malloc0(sizeof(*int_entry)); - int_entry->value = (i << 5) + j; - int_entry->next = int_list; - int_list = int_entry; - } - } + if (!((1 << VIRTIO_NET_F_CTRL_VLAN) & vdev->guest_features)) { + info->vlan = RX_STATE_ALL; + } else if (!info->vlan_table) { + info->vlan = RX_STATE_NONE; + } else { + info->vlan = RX_STATE_NORMAL; } - info->vlan_table = int_list; /* enable event notification after query */ nc->rxfilter_notify_enabled = 1; diff --git a/qapi-schema.json b/qapi-schema.json index b68cd44ebd..391356fe29 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4184,6 +4184,8 @@ # # @unicast: unicast receive state # +# @vlan: vlan receive state (Since 2.0) +# # @broadcast-allowed: whether to receive broadcast # # @multicast-overflow: multicast table is overflowed or not @@ -4207,6 +4209,7 @@ 'promiscuous': 'bool', 'multicast': 'RxState', 'unicast': 'RxState', + 'vlan': 'RxState', 'broadcast-allowed': 'bool', 'multicast-overflow': 'bool', 'unicast-overflow': 'bool', diff --git a/qmp-commands.hx b/qmp-commands.hx index a22621fd44..ed3ab9225b 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3407,6 +3407,7 @@ Each array entry contains the following: - "promiscuous": promiscuous mode is enabled (json-bool) - "multicast": multicast receive state (one of 'normal', 'none', 'all') - "unicast": unicast receive state (one of 'normal', 'none', 'all') +- "vlan": vlan receive state (one of 'normal', 'none', 'all') (Since 2.0) - "broadcast-allowed": allow to receive broadcast (json-bool) - "multicast-overflow": multicast table is overflowed (json-bool) - "unicast-overflow": unicast table is overflowed (json-bool) @@ -3424,6 +3425,7 @@ Example: "name": "vnet0", "main-mac": "52:54:00:12:34:56", "unicast": "normal", + "vlan": "normal", "vlan-table": [ 4, 0