diff options
author | Jason Unovitch <junovitch@FreeBSD.org> | 2015-08-17 13:55:06 +0000 |
---|---|---|
committer | Jason Unovitch <junovitch@FreeBSD.org> | 2015-08-17 13:55:06 +0000 |
commit | 5c08f16d47ccff07072343b2962629fce51934ee (patch) | |
tree | ba31218bc5a7467bdd9c7f2e896abe29864c65c9 /sysutils/xen-tools | |
parent | 906f4181a0c7d64c69d9223904678b32e9442d3b (diff) | |
download | ports-5c08f16d47ccff07072343b2962629fce51934ee.tar.gz ports-5c08f16d47ccff07072343b2962629fce51934ee.zip |
Notes
Diffstat (limited to 'sysutils/xen-tools')
42 files changed, 699 insertions, 3039 deletions
diff --git a/sysutils/xen-tools/Makefile b/sysutils/xen-tools/Makefile index 711bf6569fc7..db35da71e0e0 100644 --- a/sysutils/xen-tools/Makefile +++ b/sysutils/xen-tools/Makefile @@ -1,12 +1,11 @@ # $FreeBSD$ PORTNAME= xen -PKGNAMESUFFIX= -tools -PORTVERSION= 4.5.0 -PORTREVISION= 9 +PORTVERSION= 4.5.1 CATEGORIES= sysutils emulators MASTER_SITES= http://bits.xensource.com/oss-xen/release/${PORTVERSION}/ \ http://code.coreboot.org/p/seabios/downloads/get/:seabios +PKGNAMESUFFIX= -tools MAINTAINER= bapt@FreeBSD.org COMMENT= Xen management tool, based on LibXenlight @@ -14,13 +13,13 @@ COMMENT= Xen management tool, based on LibXenlight LICENSE= GPLv2 LGPL3 LICENSE_COMB= multi -OPTIONS_DEFINE= DOCS - LIB_DEPENDS= libyajl.so:${PORTSDIR}/devel/yajl \ liblzo2.so:${PORTSDIR}/archivers/lzo2 \ libpixman-1.so:${PORTSDIR}/x11/pixman BUILD_DEPENDS= dev86>0:${PORTSDIR}/devel/dev86 +OPTIONS_DEFINE= DOCS + ONLY_FOR_ARCHS= amd64 ONLY_FOR_ARCHS_REASON= "not yet ported to anything other than amd64" @@ -30,8 +29,9 @@ DISTFILES+= ${DISTNAME}.tar.gz \ WRKSRC= ${WRKDIR}/xen-${PORTVERSION} -USES= cpe gmake perl5 python shebangfix libtool pkgconfig +USES= cpe gmake libtool perl5 pkgconfig python shebangfix USE_GNOME= glib20 +USE_LDCONFIG= yes GNU_CONFIGURE= yes CONFIGURE_ENV= HOSTCC="${CC}" CC="${CC}" \ ac_cv_path_BASH=${TRUE} \ @@ -47,10 +47,7 @@ QEMU_ARGS= --disable-gtk \ --disable-curl \ --cxx=c++ -EXTRA_PATCHES= ${FILESDIR}/xsa119-unstable.patch:-p1 \ - ${FILESDIR}/xsa125.patch:-p1 \ - ${FILESDIR}/xsa137.patch:-p1 \ - ${FILESDIR}/0001-libelf-fix-elf_parse_bsdsyms-call.patch:-p1 \ +EXTRA_PATCHES= ${FILESDIR}/xsa137.patch:-p1 \ ${FILESDIR}/0002-libxc-fix-xc_dom_load_elf_symtab.patch:-p1 CONFIGURE_ARGS+= --with-extra-qemuu-configure-args="${QEMU_ARGS}" @@ -63,7 +60,7 @@ INSTALL_TARGET= install-tools install-docs .include <bsd.port.options.mk> .if ${OPSYS} != FreeBSD -IGNORE= Only supported on FreeBSD +IGNORE= only supported on FreeBSD .endif post-extract: @@ -80,11 +77,11 @@ post-patch: ${WRKSRC}/docs/man/* @for p in ${FILESDIR}/*qemut*.patch; do \ ${ECHO_CMD} "====> Applying $${p##*/}" ; \ - patch -s -p1 -i $${p} -d ${WRKSRC}/tools/qemu-xen-traditional ; \ + ${PATCH} -s -p1 -i $${p} -d ${WRKSRC}/tools/qemu-xen-traditional ; \ done @for p in ${FILESDIR}/*qemuu*.patch; do \ ${ECHO_CMD} "====> Applying $${p##*/}" ; \ - patch -s -p1 -i $${p} -d ${WRKSRC}/tools/qemu-xen ; \ + ${PATCH} -s -p1 -i $${p} -d ${WRKSRC}/tools/qemu-xen ; \ done post-install: diff --git a/sysutils/xen-tools/distinfo b/sysutils/xen-tools/distinfo index c1f31aeabb20..b89ed9e1923a 100644 --- a/sysutils/xen-tools/distinfo +++ b/sysutils/xen-tools/distinfo @@ -1,4 +1,4 @@ -SHA256 (xen-4.5.0.tar.gz) = 5bdb40e2b28d2eeb541bd71a9777f40cbe2ae444b987521d33f099541a006f3b -SIZE (xen-4.5.0.tar.gz) = 18404933 +SHA256 (xen-4.5.1.tar.gz) = 668c11d4fca67ac44329e369f810356eacd37b28d28fb96e66aac77f3c5e1371 +SIZE (xen-4.5.1.tar.gz) = 18410400 SHA256 (seabios-1.8.1.tar.gz) = 283bd848f5ce9d4bc52add973a856347e02c9ce89a9e6bc92c99359b87c9871d SIZE (seabios-1.8.1.tar.gz) = 537712 diff --git a/sysutils/xen-tools/files/0001-libelf-fix-elf_parse_bsdsyms-call.patch b/sysutils/xen-tools/files/0001-libelf-fix-elf_parse_bsdsyms-call.patch deleted file mode 100644 index ddab05badaed..000000000000 --- a/sysutils/xen-tools/files/0001-libelf-fix-elf_parse_bsdsyms-call.patch +++ /dev/null @@ -1,36 +0,0 @@ -From c2da83662498a5cd66512c684a0af178228f9d5a Mon Sep 17 00:00:00 2001 -From: Roger Pau Monne <roger.pau@citrix.com> -Date: Thu, 11 Jun 2015 17:08:26 +0200 -Subject: [PATCH 1/2] libelf: fix elf_parse_bsdsyms call -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -elf_parse_bsdsyms expects the second paramater to be a physical address, not -a virtual one. - -Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> -Cc: Ian Campbell <ian.campbell@citrix.com> -Cc: Ian Jackson <ian.jackson@eu.citrix.com> -Cc: Jan Beulich <jbeulich@suse.com> -Cc: Tim Deegan <tim@xen.org> ---- - xen/common/libelf/libelf-dominfo.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c -index 6120dd4..86403b9 100644 ---- a/xen/common/libelf/libelf-dominfo.c -+++ b/xen/common/libelf/libelf-dominfo.c -@@ -438,7 +438,7 @@ static elf_errorstatus elf_xen_addr_calc_check(struct elf_binary *elf, - - if ( parms->bsd_symtab ) - { -- elf_parse_bsdsyms(elf, parms->virt_kend); -+ elf_parse_bsdsyms(elf, elf->pend); - if ( elf->bsd_symtab_pend ) - parms->virt_kend = elf->bsd_symtab_pend + parms->virt_offset; - } --- -1.9.5 (Apple Git-50.3) - diff --git a/sysutils/xen-tools/files/xsa119-unstable.patch b/sysutils/xen-tools/files/xsa119-unstable.patch deleted file mode 100644 index f696eb5b6eb6..000000000000 --- a/sysutils/xen-tools/files/xsa119-unstable.patch +++ /dev/null @@ -1,99 +0,0 @@ -From f433bfafbaf7d8a41c4c27aa3e8e78b1ab900b69 Mon Sep 17 00:00:00 2001 -From: Ian Campbell <ian.campbell@citrix.com> -Date: Fri, 20 Feb 2015 14:41:09 +0000 -Subject: [PATCH] tools: libxl: Explicitly disable graphics backends on qemu - cmdline - -By default qemu will try to create some sort of backend for the -emulated VGA device, either SDL or VNC. - -However when the user specifies sdl=0 and vnc=0 in their configuration -libxl was not explicitly disabling either backend, which could lead to -one unexpectedly running. - -If either sdl=1 or vnc=1 is configured then both before and after this -change only the backends which are explicitly enabled are configured, -i.e. this issue only occurs when all backends are supposed to have -been disabled. - -This affects qemu-xen and qemu-xen-traditional differently. - -If qemu-xen was compiled with SDL support then this would result in an -SDL window being opened if $DISPLAY is valid, or a failure to start -the guest if not. Passing "-display none" to qemu before any further --sdl options disables this default behaviour and ensures that SDL is -only started if the libxl configuration demands it. - -If qemu-xen was compiled without SDL support then qemu would instead -start a VNC server listening on ::1 (IPv6 localhost) or 127.0.0.1 -(IPv4 localhost) with IPv6 preferred if available. Explicitly pass -"-vnc none" when vnc is not enabled in the libxl configuration to -remove this possibility. - -qemu-xen-traditional would never start a vnc backend unless asked. -However by default it will start an SDL backend, the way to disable -this is to pass a -vnc option. In other words passing "-vnc none" will -disable both vnc and sdl by default. sdl can then be reenabled if -configured by subsequent use of the -sdl option. - -Tested with both qemu-xen and qemu-xen-traditional built with SDL -support and: - xl cr # defaults - xl cr sdl=0 vnc=0 - xl cr sdl=1 vnc=0 - xl cr sdl=0 vnc=1 - xl cr sdl=0 vnc=0 vga=\"none\" - xl cr sdl=0 vnc=0 nographic=1 -with both valid and invalid $DISPLAY. - -This is XSA-119. - -Reported-by: Sander Eikelenboom <linux@eikelenboom.it> -Signed-off-by: Ian Campbell <ian.campbell@citrix.com> -Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> ---- - tools/libxl/libxl_dm.c | 21 +++++++++++++++++++-- - 1 file changed, 19 insertions(+), 2 deletions(-) - -diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c -index 8599a6a..3b918c6 100644 ---- a/tools/libxl/libxl_dm.c -+++ b/tools/libxl/libxl_dm.c -@@ -180,7 +180,14 @@ static char ** libxl__build_device_model_args_old(libxl__gc *gc, - if (libxl_defbool_val(vnc->findunused)) { - flexarray_append(dm_args, "-vncunused"); - } -- } -+ } else -+ /* -+ * VNC is not enabled by default by qemu-xen-traditional, -+ * however passing -vnc none causes SDL to not be -+ * (unexpectedly) enabled by default. This is overridden by -+ * explicitly passing -sdl below as required. -+ */ -+ flexarray_append_pair(dm_args, "-vnc", "none"); - - if (sdl) { - flexarray_append(dm_args, "-sdl"); -@@ -522,7 +529,17 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc, - } - - flexarray_append(dm_args, vncarg); -- } -+ } else -+ /* -+ * Ensure that by default no vnc server is created. -+ */ -+ flexarray_append_pair(dm_args, "-vnc", "none"); -+ -+ /* -+ * Ensure that by default no display backend is created. Further -+ * options given below might then enable more. -+ */ -+ flexarray_append_pair(dm_args, "-display", "none"); - - if (sdl) { - flexarray_append(dm_args, "-sdl"); --- -2.1.4 - diff --git a/sysutils/xen-tools/files/xsa125.patch b/sysutils/xen-tools/files/xsa125.patch deleted file mode 100644 index ad5dbb31c204..000000000000 --- a/sysutils/xen-tools/files/xsa125.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 98670acc98cad5aee0e0714694a64d3b96675c36 Mon Sep 17 00:00:00 2001 -From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> -Date: Wed, 19 Nov 2014 12:57:11 -0500 -Subject: [PATCH] Limit XEN_DOMCTL_memory_mapping hypercall to only process up - to 64 GFNs (or less) - -Said hypercall for large BARs can take quite a while. As such -we can require that the hypercall MUST break up the request -in smaller values. - -Another approach is to add preemption to it - whether we do the -preemption using hypercall_create_continuation or returning -EAGAIN to userspace (and have it re-invocate the call) - either -way the issue we cannot easily solve is that in 'map_mmio_regions' -if we encounter an error we MUST call 'unmap_mmio_regions' for the -whole BAR region. - -Since the preemption would re-use input fields such as nr_mfns, -first_gfn, first_mfn - we would lose the original values - -and only undo what was done in the current round (i.e. ignoring -anything that was done prior to earlier preemptions). - -Unless we re-used the return value as 'EAGAIN|nr_mfns_done<<10' but -that puts a limit (since the return value is a long) on the amount -of nr_mfns that can provided. - -This patch sidesteps this problem by: - - Setting an hard limit of nr_mfns having to be 64 or less. - - Toolstack adjusts correspondingly to the nr_mfn limit. - - If the there is an error when adding the toolstack will call the - remove operation to remove the whole region. - -The need to break this hypercall down is for large BARs can take -more than the guest (initial domain usually) time-slice. This has -the negative result in that the guest is locked out for a long -duration and is unable to act on any pending events. - -We also augment the code to return zero if nr_mfns instead -of trying to the hypercall. - -Suggested-by: Jan Beulich <jbeulich@suse.com> -Acked-by: Jan Beulich <jbeulich@suse.com> -Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> -Acked-by: Ian Campbell <ian.campbell@citrix.com> ---- -[v50: Simplify loop] -[v51: If max_batch_sz 1 (or less) we would return zero. Fix that] -[v52: Handle nr_mfns being zero] -[v53: Fix up return value] ---- - tools/libxc/xc_domain.c | 46 +++++++++++++++++++++++++++++++++++++++++---- - xen/common/domctl.c | 5 +++++ - xen/include/public/domctl.h | 1 + - 3 files changed, 48 insertions(+), 4 deletions(-) - -diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c -index 845d1d7..bba7672 100644 ---- a/tools/libxc/xc_domain.c -+++ b/tools/libxc/xc_domain.c -@@ -1988,6 +1988,8 @@ int xc_domain_memory_mapping( - { - DECLARE_DOMCTL; - xc_dominfo_t info; -+ int ret = 0, err; -+ unsigned long done = 0, nr, max_batch_sz; - - if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 || - info.domid != domid ) -@@ -1998,14 +2000,50 @@ int xc_domain_memory_mapping( - if ( !xc_core_arch_auto_translated_physmap(&info) ) - return 0; - -+ if ( !nr_mfns ) -+ return 0; -+ - domctl.cmd = XEN_DOMCTL_memory_mapping; - domctl.domain = domid; -- domctl.u.memory_mapping.first_gfn = first_gfn; -- domctl.u.memory_mapping.first_mfn = first_mfn; -- domctl.u.memory_mapping.nr_mfns = nr_mfns; - domctl.u.memory_mapping.add_mapping = add_mapping; -+ max_batch_sz = nr_mfns; -+ do -+ { -+ nr = min(nr_mfns - done, max_batch_sz); -+ domctl.u.memory_mapping.nr_mfns = nr; -+ domctl.u.memory_mapping.first_gfn = first_gfn + done; -+ domctl.u.memory_mapping.first_mfn = first_mfn + done; -+ err = do_domctl(xch, &domctl); -+ if ( err && errno == E2BIG ) -+ { -+ if ( max_batch_sz <= 1 ) -+ break; -+ max_batch_sz >>= 1; -+ continue; -+ } -+ /* Save the first error... */ -+ if ( !ret ) -+ ret = err; -+ /* .. and ignore the rest of them when removing. */ -+ if ( err && add_mapping != DPCI_REMOVE_MAPPING ) -+ break; - -- return do_domctl(xch, &domctl); -+ done += nr; -+ } while ( done < nr_mfns ); -+ -+ /* -+ * Undo what we have done unless unmapping, by unmapping the entire region. -+ * Errors here are ignored. -+ */ -+ if ( ret && add_mapping != DPCI_REMOVE_MAPPING ) -+ xc_domain_memory_mapping(xch, domid, first_gfn, first_mfn, nr_mfns, -+ DPCI_REMOVE_MAPPING); -+ -+ /* We might get E2BIG so many times that we never advance. */ -+ if ( !done && !ret ) -+ ret = -1; -+ -+ return ret; - } - - int xc_domain_ioport_mapping( -diff --git a/xen/common/domctl.c b/xen/common/domctl.c -index d396cc4..c2e60a7 100644 ---- a/xen/common/domctl.c -+++ b/xen/common/domctl.c -@@ -1027,6 +1027,11 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) - (gfn + nr_mfns - 1) < gfn ) /* wrap? */ - break; - -+ ret = -E2BIG; -+ /* Must break hypercall up as this could take a while. */ -+ if ( nr_mfns > 64 ) -+ break; -+ - ret = -EPERM; - if ( !iomem_access_permitted(current->domain, mfn, mfn_end) || - !iomem_access_permitted(d, mfn, mfn_end) ) -diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h -index ca0e51e..0c9f474 100644 ---- a/xen/include/public/domctl.h -+++ b/xen/include/public/domctl.h -@@ -543,6 +543,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_pt_irq_t); - - - /* Bind machine I/O address range -> HVM address range. */ -+/* If this returns -E2BIG lower nr_mfns value. */ - /* XEN_DOMCTL_memory_mapping */ - #define DPCI_ADD_MAPPING 1 - #define DPCI_REMOVE_MAPPING 0 --- -2.1.0 - diff --git a/sysutils/xen-tools/files/xsa126-qemut.patch b/sysutils/xen-tools/files/xsa126-qemut.patch deleted file mode 100644 index 599ff172e485..000000000000 --- a/sysutils/xen-tools/files/xsa126-qemut.patch +++ /dev/null @@ -1,151 +0,0 @@ -xen: limit guest control of PCI command register - -Otherwise the guest can abuse that control to cause e.g. PCIe -Unsupported Request responses (by disabling memory and/or I/O decoding -and subsequently causing [CPU side] accesses to the respective address -ranges), which (depending on system configuration) may be fatal to the -host. - -This is CVE-2015-2756 / XSA-126. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> -Acked-by: Ian Campbell <ian.campbell@citrix.com> - ---- a/hw/pass-through.c -+++ b/hw/pass-through.c -@@ -172,9 +172,6 @@ static int pt_word_reg_read(struct pt_de - static int pt_long_reg_read(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint32_t *value, uint32_t valid_mask); --static int pt_cmd_reg_read(struct pt_dev *ptdev, -- struct pt_reg_tbl *cfg_entry, -- uint16_t *value, uint16_t valid_mask); - static int pt_bar_reg_read(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint32_t *value, uint32_t valid_mask); -@@ -286,9 +283,9 @@ static struct pt_reg_info_tbl pt_emu_reg - .size = 2, - .init_val = 0x0000, - .ro_mask = 0xF880, -- .emu_mask = 0x0740, -+ .emu_mask = 0x0743, - .init = pt_common_reg_init, -- .u.w.read = pt_cmd_reg_read, -+ .u.w.read = pt_word_reg_read, - .u.w.write = pt_cmd_reg_write, - .u.w.restore = pt_cmd_reg_restore, - }, -@@ -1905,7 +1902,7 @@ static int pt_dev_is_virtfn(struct pci_d - return rc; - } - --static int pt_register_regions(struct pt_dev *assigned_device) -+static int pt_register_regions(struct pt_dev *assigned_device, uint16_t *cmd) - { - int i = 0; - uint32_t bar_data = 0; -@@ -1925,17 +1922,26 @@ static int pt_register_regions(struct pt - - /* Register current region */ - if ( pci_dev->base_addr[i] & PCI_ADDRESS_SPACE_IO ) -+ { - pci_register_io_region((PCIDevice *)assigned_device, i, - (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_IO, - pt_ioport_map); -+ *cmd |= PCI_COMMAND_IO; -+ } - else if ( pci_dev->base_addr[i] & PCI_ADDRESS_SPACE_MEM_PREFETCH ) -+ { - pci_register_io_region((PCIDevice *)assigned_device, i, - (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM_PREFETCH, - pt_iomem_map); -+ *cmd |= PCI_COMMAND_MEMORY; -+ } - else -+ { - pci_register_io_region((PCIDevice *)assigned_device, i, - (uint32_t)pci_dev->size[i], PCI_ADDRESS_SPACE_MEM, - pt_iomem_map); -+ *cmd |= PCI_COMMAND_MEMORY; -+ } - - PT_LOG("IO region registered (size=0x%08x base_addr=0x%08x)\n", - (uint32_t)(pci_dev->size[i]), -@@ -3263,27 +3269,6 @@ static int pt_long_reg_read(struct pt_de - return 0; - } - --/* read Command register */ --static int pt_cmd_reg_read(struct pt_dev *ptdev, -- struct pt_reg_tbl *cfg_entry, -- uint16_t *value, uint16_t valid_mask) --{ -- struct pt_reg_info_tbl *reg = cfg_entry->reg; -- uint16_t valid_emu_mask = 0; -- uint16_t emu_mask = reg->emu_mask; -- -- if ( ptdev->is_virtfn ) -- emu_mask |= PCI_COMMAND_MEMORY; -- if ( pt_is_iomul(ptdev) ) -- emu_mask |= PCI_COMMAND_IO; -- -- /* emulate word register */ -- valid_emu_mask = emu_mask & valid_mask; -- *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); -- -- return 0; --} -- - /* read BAR */ - static int pt_bar_reg_read(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, -@@ -3418,19 +3403,13 @@ static int pt_cmd_reg_write(struct pt_de - uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; - uint16_t wr_value = *value; -- uint16_t emu_mask = reg->emu_mask; -- -- if ( ptdev->is_virtfn ) -- emu_mask |= PCI_COMMAND_MEMORY; -- if ( pt_is_iomul(ptdev) ) -- emu_mask |= PCI_COMMAND_IO; - - /* modify emulate register */ - writable_mask = ~reg->ro_mask & valid_mask; - cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~emu_mask & valid_mask; -+ throughable_mask = ~reg->emu_mask & valid_mask; - - if (*value & PCI_COMMAND_DISABLE_INTx) - { -@@ -4211,6 +4190,7 @@ static struct pt_dev * register_real_dev - struct pt_dev *assigned_device = NULL; - struct pci_dev *pci_dev; - uint8_t e_device, e_intx; -+ uint16_t cmd = 0; - char *key, *val; - int msi_translate, power_mgmt; - -@@ -4300,7 +4280,7 @@ static struct pt_dev * register_real_dev - assigned_device->dev.config[i] = pci_read_byte(pci_dev, i); - - /* Handle real device's MMIO/PIO BARs */ -- pt_register_regions(assigned_device); -+ pt_register_regions(assigned_device, &cmd); - - /* Setup VGA bios for passthroughed gfx */ - if ( setup_vga_pt(assigned_device) < 0 ) -@@ -4378,6 +4358,10 @@ static struct pt_dev * register_real_dev - } - - out: -+ if (cmd) -+ pci_write_word(pci_dev, PCI_COMMAND, -+ *(uint16_t *)(&assigned_device->dev.config[PCI_COMMAND]) | cmd); -+ - PT_LOG("Real physical device %02x:%02x.%x registered successfuly!\n" - "IRQ type = %s\n", r_bus, r_dev, r_func, - assigned_device->msi_trans_en? "MSI-INTx":"INTx"); diff --git a/sysutils/xen-tools/files/xsa126-qemuu.patch b/sysutils/xen-tools/files/xsa126-qemuu.patch deleted file mode 100644 index 21805a43be51..000000000000 --- a/sysutils/xen-tools/files/xsa126-qemuu.patch +++ /dev/null @@ -1,128 +0,0 @@ -xen: limit guest control of PCI command register - -Otherwise the guest can abuse that control to cause e.g. PCIe -Unsupported Request responses (by disabling memory and/or I/O decoding -and subsequently causing [CPU side] accesses to the respective address -ranges), which (depending on system configuration) may be fatal to the -host. - -This is CVE-2015-2756 / XSA-126. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> -Acked-by: Ian Campbell <ian.campbell@citrix.com> - ---- a/hw/xen/xen_pt.c -+++ b/hw/xen/xen_pt.c -@@ -388,7 +388,7 @@ static const MemoryRegionOps ops = { - .write = xen_pt_bar_write, - }; - --static int xen_pt_register_regions(XenPCIPassthroughState *s) -+static int xen_pt_register_regions(XenPCIPassthroughState *s, uint16_t *cmd) - { - int i = 0; - XenHostPCIDevice *d = &s->real_device; -@@ -406,6 +406,7 @@ static int xen_pt_register_regions(XenPC - - if (r->type & XEN_HOST_PCI_REGION_TYPE_IO) { - type = PCI_BASE_ADDRESS_SPACE_IO; -+ *cmd |= PCI_COMMAND_IO; - } else { - type = PCI_BASE_ADDRESS_SPACE_MEMORY; - if (r->type & XEN_HOST_PCI_REGION_TYPE_PREFETCH) { -@@ -414,6 +415,7 @@ static int xen_pt_register_regions(XenPC - if (r->type & XEN_HOST_PCI_REGION_TYPE_MEM_64) { - type |= PCI_BASE_ADDRESS_MEM_TYPE_64; - } -+ *cmd |= PCI_COMMAND_MEMORY; - } - - memory_region_init_io(&s->bar[i], OBJECT(s), &ops, &s->dev, -@@ -638,6 +640,7 @@ static int xen_pt_initfn(PCIDevice *d) - XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d); - int rc = 0; - uint8_t machine_irq = 0; -+ uint16_t cmd = 0; - int pirq = XEN_PT_UNASSIGNED_PIRQ; - - /* register real device */ -@@ -672,7 +675,7 @@ static int xen_pt_initfn(PCIDevice *d) - s->io_listener = xen_pt_io_listener; - - /* Handle real device's MMIO/PIO BARs */ -- xen_pt_register_regions(s); -+ xen_pt_register_regions(s, &cmd); - - /* reinitialize each config register to be emulated */ - if (xen_pt_config_init(s)) { -@@ -736,6 +739,11 @@ static int xen_pt_initfn(PCIDevice *d) - } - - out: -+ if (cmd) { -+ xen_host_pci_set_word(&s->real_device, PCI_COMMAND, -+ pci_get_word(d->config + PCI_COMMAND) | cmd); -+ } -+ - memory_listener_register(&s->memory_listener, &address_space_memory); - memory_listener_register(&s->io_listener, &address_space_io); - XEN_PT_LOG(d, ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -286,23 +286,6 @@ static int xen_pt_irqpin_reg_init(XenPCI - } - - /* Command register */ --static int xen_pt_cmd_reg_read(XenPCIPassthroughState *s, XenPTReg *cfg_entry, -- uint16_t *value, uint16_t valid_mask) --{ -- XenPTRegInfo *reg = cfg_entry->reg; -- uint16_t valid_emu_mask = 0; -- uint16_t emu_mask = reg->emu_mask; -- -- if (s->is_virtfn) { -- emu_mask |= PCI_COMMAND_MEMORY; -- } -- -- /* emulate word register */ -- valid_emu_mask = emu_mask & valid_mask; -- *value = XEN_PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); -- -- return 0; --} - static int xen_pt_cmd_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry, - uint16_t *val, uint16_t dev_value, - uint16_t valid_mask) -@@ -310,18 +293,13 @@ static int xen_pt_cmd_reg_write(XenPCIPa - XenPTRegInfo *reg = cfg_entry->reg; - uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; -- uint16_t emu_mask = reg->emu_mask; -- -- if (s->is_virtfn) { -- emu_mask |= PCI_COMMAND_MEMORY; -- } - - /* modify emulate register */ - writable_mask = ~reg->ro_mask & valid_mask; - cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~emu_mask & valid_mask; -+ throughable_mask = ~reg->emu_mask & valid_mask; - - if (*val & PCI_COMMAND_INTX_DISABLE) { - throughable_mask |= PCI_COMMAND_INTX_DISABLE; -@@ -605,9 +583,9 @@ static XenPTRegInfo xen_pt_emu_reg_heade - .size = 2, - .init_val = 0x0000, - .ro_mask = 0xF880, -- .emu_mask = 0x0740, -+ .emu_mask = 0x0743, - .init = xen_pt_common_reg_init, -- .u.w.read = xen_pt_cmd_reg_read, -+ .u.w.read = xen_pt_word_reg_read, - .u.w.write = xen_pt_cmd_reg_write, - }, - /* Capabilities Pointer reg */ diff --git a/sysutils/xen-tools/files/xsa128-qemut.patch b/sysutils/xen-tools/files/xsa128-qemut.patch deleted file mode 100644 index 7530690bdfc4..000000000000 --- a/sysutils/xen-tools/files/xsa128-qemut.patch +++ /dev/null @@ -1,125 +0,0 @@ -xen: properly gate host writes of modified PCI CFG contents - -The old logic didn't work as intended when an access spanned multiple -fields (for example a 32-bit access to the location of the MSI Message -Data field with the high 16 bits not being covered by any known field). -Remove it and derive which fields not to write to from the accessed -fields' emulation masks: When they're all ones, there's no point in -doing any host write. - -This fixes a secondary issue at once: We obviously shouldn't make any -host write attempt when already the host read failed. - -This is XSA-128. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/pass-through.c -+++ b/hw/pass-through.c -@@ -454,7 +454,7 @@ static struct pt_reg_info_tbl pt_emu_reg - .offset = PCI_INTEL_OPREGION, - .size = 4, - .init_val = 0, -- .no_wb = 1, -+ .emu_mask = 0xFFFFFFFF, - .u.dw.read = pt_intel_opregion_read, - .u.dw.write = pt_intel_opregion_write, - .u.dw.restore = NULL, -@@ -657,7 +657,6 @@ static struct pt_reg_info_tbl pt_emu_reg - .init_val = 0x00000000, - .ro_mask = 0x00000003, - .emu_mask = 0xFFFFFFFF, -- .no_wb = 1, - .init = pt_common_reg_init, - .u.dw.read = pt_long_reg_read, - .u.dw.write = pt_msgaddr32_reg_write, -@@ -670,7 +669,6 @@ static struct pt_reg_info_tbl pt_emu_reg - .init_val = 0x00000000, - .ro_mask = 0x00000000, - .emu_mask = 0xFFFFFFFF, -- .no_wb = 1, - .init = pt_msgaddr64_reg_init, - .u.dw.read = pt_long_reg_read, - .u.dw.write = pt_msgaddr64_reg_write, -@@ -683,7 +681,6 @@ static struct pt_reg_info_tbl pt_emu_reg - .init_val = 0x0000, - .ro_mask = 0x0000, - .emu_mask = 0xFFFF, -- .no_wb = 1, - .init = pt_msgdata_reg_init, - .u.w.read = pt_word_reg_read, - .u.w.write = pt_msgdata_reg_write, -@@ -696,7 +693,6 @@ static struct pt_reg_info_tbl pt_emu_reg - .init_val = 0x0000, - .ro_mask = 0x0000, - .emu_mask = 0xFFFF, -- .no_wb = 1, - .init = pt_msgdata_reg_init, - .u.w.read = pt_word_reg_read, - .u.w.write = pt_msgdata_reg_write, -@@ -1524,7 +1520,7 @@ static void pt_pci_write_config(PCIDevic - uint32_t find_addr = address; - uint32_t real_offset = 0; - uint32_t valid_mask = 0xFFFFFFFF; -- uint32_t read_val = 0; -+ uint32_t read_val = 0, wb_mask; - uint8_t *ptr_val = NULL; - int emul_len = 0; - int index = 0; -@@ -1597,7 +1593,10 @@ static void pt_pci_write_config(PCIDevic - { - PT_LOG("Error: pci_read_block failed. return value[%d].\n", ret); - memset((uint8_t *)&read_val, 0xff, len); -+ wb_mask = 0; - } -+ else -+ wb_mask = 0xFFFFFFFF >> ((4 - len) << 3); - - /* pass directly to libpci for passthrough type register group */ - if (reg_grp_entry == NULL) -@@ -1620,6 +1619,11 @@ static void pt_pci_write_config(PCIDevic - valid_mask = (0xFFFFFFFF >> ((4 - emul_len) << 3)); - valid_mask <<= ((find_addr - real_offset) << 3); - ptr_val = ((uint8_t *)&val + (real_offset & 3)); -+ if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { -+ wb_mask &= ~((reg->emu_mask -+ >> ((find_addr - real_offset) << 3)) -+ << ((len - emul_len) << 3)); -+ } - - /* do emulation depend on register size */ - switch (reg->size) { -@@ -1677,8 +1681,19 @@ static void pt_pci_write_config(PCIDevic - val >>= ((address & 3) << 3); - - out: -- if (!(reg && reg->no_wb)) { /* unknown regs are passed through */ -- ret = pci_write_block(pci_dev, address, (uint8_t *)&val, len); -+ for (index = 0; wb_mask; index += len) { -+ /* unknown regs are passed through */ -+ while (!(wb_mask & 0xff)) { -+ index++; -+ wb_mask >>= 8; -+ } -+ len = 0; -+ do { -+ len++; -+ wb_mask >>= 8; -+ } while (wb_mask & 0xff); -+ ret = pci_write_block(pci_dev, address + index, -+ (uint8_t *)&val + index, len); - - if (!ret) - PT_LOG("Error: pci_write_block failed. return value[%d].\n", ret); ---- a/hw/pass-through.h -+++ b/hw/pass-through.h -@@ -372,8 +372,6 @@ struct pt_reg_info_tbl { - uint32_t ro_mask; - /* reg emulate field mask (ON:emu, OFF:passthrough) */ - uint32_t emu_mask; -- /* no write back allowed */ -- uint32_t no_wb; - /* emul reg initialize method */ - conf_reg_init init; - union { diff --git a/sysutils/xen-tools/files/xsa128-qemuu.patch b/sysutils/xen-tools/files/xsa128-qemuu.patch deleted file mode 100644 index d551c6244a76..000000000000 --- a/sysutils/xen-tools/files/xsa128-qemuu.patch +++ /dev/null @@ -1,118 +0,0 @@ -xen: properly gate host writes of modified PCI CFG contents - -The old logic didn't work as intended when an access spanned multiple -fields (for example a 32-bit access to the location of the MSI Message -Data field with the high 16 bits not being covered by any known field). -Remove it and derive which fields not to write to from the accessed -fields' emulation masks: When they're all ones, there's no point in -doing any host write. - -This fixes a secondary issue at once: We obviously shouldn't make any -host write attempt when already the host read failed. - -This is XSA-128. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/xen/xen_pt.c -+++ b/hw/xen/xen_pt.c -@@ -234,7 +234,7 @@ static void xen_pt_pci_write_config(PCID - int index = 0; - XenPTRegGroup *reg_grp_entry = NULL; - int rc = 0; -- uint32_t read_val = 0; -+ uint32_t read_val = 0, wb_mask; - int emul_len = 0; - XenPTReg *reg_entry = NULL; - uint32_t find_addr = addr; -@@ -271,6 +271,9 @@ static void xen_pt_pci_write_config(PCID - if (rc < 0) { - XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc); - memset(&read_val, 0xff, len); -+ wb_mask = 0; -+ } else { -+ wb_mask = 0xFFFFFFFF >> ((4 - len) << 3); - } - - /* pass directly to the real device for passthrough type register group */ -@@ -298,6 +301,11 @@ static void xen_pt_pci_write_config(PCID - - valid_mask <<= (find_addr - real_offset) << 3; - ptr_val = (uint8_t *)&val + (real_offset & 3); -+ if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { -+ wb_mask &= ~((reg->emu_mask -+ >> ((find_addr - real_offset) << 3)) -+ << ((len - emul_len) << 3)); -+ } - - /* do emulation based on register size */ - switch (reg->size) { -@@ -350,10 +358,19 @@ static void xen_pt_pci_write_config(PCID - memory_region_transaction_commit(); - - out: -- if (!(reg && reg->no_wb)) { -+ for (index = 0; wb_mask; index += len) { - /* unknown regs are passed through */ -- rc = xen_host_pci_set_block(&s->real_device, addr, -- (uint8_t *)&val, len); -+ while (!(wb_mask & 0xff)) { -+ index++; -+ wb_mask >>= 8; -+ } -+ len = 0; -+ do { -+ len++; -+ wb_mask >>= 8; -+ } while (wb_mask & 0xff); -+ rc = xen_host_pci_set_block(&s->real_device, addr + index, -+ (uint8_t *)&val + index, len); - - if (rc < 0) { - XEN_PT_ERR(d, "pci_write_block failed. return value: %d.\n", rc); ---- a/hw/xen/xen_pt.h -+++ b/hw/xen/xen_pt.h -@@ -105,8 +105,6 @@ struct XenPTRegInfo { - uint32_t ro_mask; - /* reg emulate field mask (ON:emu, OFF:passthrough) */ - uint32_t emu_mask; -- /* no write back allowed */ -- uint32_t no_wb; - xen_pt_conf_reg_init init; - /* read/write function pointer - * for double_word/word/byte size */ ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -1281,7 +1281,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] - .init_val = 0x00000000, - .ro_mask = 0x00000003, - .emu_mask = 0xFFFFFFFF, -- .no_wb = 1, - .init = xen_pt_common_reg_init, - .u.dw.read = xen_pt_long_reg_read, - .u.dw.write = xen_pt_msgaddr32_reg_write, -@@ -1293,7 +1292,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] - .init_val = 0x00000000, - .ro_mask = 0x00000000, - .emu_mask = 0xFFFFFFFF, -- .no_wb = 1, - .init = xen_pt_msgaddr64_reg_init, - .u.dw.read = xen_pt_long_reg_read, - .u.dw.write = xen_pt_msgaddr64_reg_write, -@@ -1305,7 +1303,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] - .init_val = 0x0000, - .ro_mask = 0x0000, - .emu_mask = 0xFFFF, -- .no_wb = 1, - .init = xen_pt_msgdata_reg_init, - .u.w.read = xen_pt_word_reg_read, - .u.w.write = xen_pt_msgdata_reg_write, -@@ -1317,7 +1314,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] - .init_val = 0x0000, - .ro_mask = 0x0000, - .emu_mask = 0xFFFF, -- .no_wb = 1, - .init = xen_pt_msgdata_reg_init, - .u.w.read = xen_pt_word_reg_read, - .u.w.write = xen_pt_msgdata_reg_write, diff --git a/sysutils/xen-tools/files/xsa129-qemut.patch b/sysutils/xen-tools/files/xsa129-qemut.patch deleted file mode 100644 index 005efa5dd83d..000000000000 --- a/sysutils/xen-tools/files/xsa129-qemut.patch +++ /dev/null @@ -1,142 +0,0 @@ -xen: don't allow guest to control MSI mask register - -It's being used by the hypervisor. For now simply mimic a device not -capable of masking, and fully emulate any accesses a guest may issue -nevertheless as simple reads/writes without side effects. - -This is XSA-129. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/pass-through.c -+++ b/hw/pass-through.c -@@ -147,6 +147,10 @@ static uint32_t pt_msgaddr64_reg_init(st - struct pt_reg_info_tbl *reg, uint32_t real_offset); - static uint32_t pt_msgdata_reg_init(struct pt_dev *ptdev, - struct pt_reg_info_tbl *reg, uint32_t real_offset); -+static uint32_t pt_mask_reg_init(struct pt_dev *ptdev, -+ struct pt_reg_info_tbl *reg, uint32_t real_offset); -+static uint32_t pt_pending_reg_init(struct pt_dev *ptdev, -+ struct pt_reg_info_tbl *reg, uint32_t real_offset); - static uint32_t pt_msixctrl_reg_init(struct pt_dev *ptdev, - struct pt_reg_info_tbl *reg, uint32_t real_offset); - static uint32_t pt_header_type_reg_init(struct pt_dev *ptdev, -@@ -644,7 +648,7 @@ static struct pt_reg_info_tbl pt_emu_reg - .size = 2, - .init_val = 0x0000, - .ro_mask = 0xFF8E, -- .emu_mask = 0x007F, -+ .emu_mask = 0x017F, - .init = pt_msgctrl_reg_init, - .u.w.read = pt_word_reg_read, - .u.w.write = pt_msgctrl_reg_write, -@@ -698,6 +702,50 @@ static struct pt_reg_info_tbl pt_emu_reg - .u.w.write = pt_msgdata_reg_write, - .u.w.restore = NULL, - }, -+ /* Mask reg (if PCI_MSI_FLAGS_MASK_BIT set, for 32-bit devices) */ -+ { -+ .offset = PCI_MSI_MASK_32, -+ .size = 4, -+ .init_val = 0x00000000, -+ .ro_mask = 0xFFFFFFFF, -+ .emu_mask = 0xFFFFFFFF, -+ .init = pt_mask_reg_init, -+ .u.dw.read = pt_long_reg_read, -+ .u.dw.write = pt_long_reg_write, -+ }, -+ /* Mask reg (if PCI_MSI_FLAGS_MASK_BIT set, for 64-bit devices) */ -+ { -+ .offset = PCI_MSI_MASK_64, -+ .size = 4, -+ .init_val = 0x00000000, -+ .ro_mask = 0xFFFFFFFF, -+ .emu_mask = 0xFFFFFFFF, -+ .init = pt_mask_reg_init, -+ .u.dw.read = pt_long_reg_read, -+ .u.dw.write = pt_long_reg_write, -+ }, -+ /* Pending reg (if PCI_MSI_FLAGS_MASK_BIT set, for 32-bit devices) */ -+ { -+ .offset = PCI_MSI_MASK_32 + 4, -+ .size = 4, -+ .init_val = 0x00000000, -+ .ro_mask = 0xFFFFFFFF, -+ .emu_mask = 0x00000000, -+ .init = pt_pending_reg_init, -+ .u.dw.read = pt_long_reg_read, -+ .u.dw.write = pt_long_reg_write, -+ }, -+ /* Pending reg (if PCI_MSI_FLAGS_MASK_BIT set, for 64-bit devices) */ -+ { -+ .offset = PCI_MSI_MASK_64 + 4, -+ .size = 4, -+ .init_val = 0x00000000, -+ .ro_mask = 0xFFFFFFFF, -+ .emu_mask = 0x00000000, -+ .init = pt_pending_reg_init, -+ .u.dw.read = pt_long_reg_read, -+ .u.dw.write = pt_long_reg_write, -+ }, - { - .size = 0, - }, -@@ -3023,6 +3071,42 @@ static uint32_t pt_msgdata_reg_init(stru - return PT_INVALID_REG; - } - -+/* this function will be called twice (for 32 bit and 64 bit type) */ -+/* initialize Mask register */ -+static uint32_t pt_mask_reg_init(struct pt_dev *ptdev, -+ struct pt_reg_info_tbl *reg, uint32_t real_offset) -+{ -+ uint32_t flags = ptdev->msi->flags; -+ uint32_t offset = reg->offset; -+ -+ if (!(flags & PCI_MSI_FLAGS_MASK_BIT)) -+ return PT_INVALID_REG; -+ -+ if (offset == (flags & PCI_MSI_FLAGS_64BIT ? -+ PCI_MSI_MASK_64 : PCI_MSI_MASK_32)) -+ return reg->init_val; -+ -+ return PT_INVALID_REG; -+} -+ -+/* this function will be called twice (for 32 bit and 64 bit type) */ -+/* initialize Pending register */ -+static uint32_t pt_pending_reg_init(struct pt_dev *ptdev, -+ struct pt_reg_info_tbl *reg, uint32_t real_offset) -+{ -+ uint32_t flags = ptdev->msi->flags; -+ uint32_t offset = reg->offset; -+ -+ if (!(flags & PCI_MSI_FLAGS_MASK_BIT)) -+ return PT_INVALID_REG; -+ -+ if (offset == (flags & PCI_MSI_FLAGS_64BIT ? -+ PCI_MSI_MASK_64 + 4 : PCI_MSI_MASK_32 + 4)) -+ return reg->init_val; -+ -+ return PT_INVALID_REG; -+} -+ - /* initialize Message Control register for MSI-X */ - static uint32_t pt_msixctrl_reg_init(struct pt_dev *ptdev, - struct pt_reg_info_tbl *reg, uint32_t real_offset) ---- a/hw/pass-through.h -+++ b/hw/pass-through.h -@@ -84,6 +84,12 @@ - #define PCI_MSI_FLAGS_MASK_BIT 0x0100 - #endif - -+#ifndef PCI_MSI_MASK_32 -+/* interrupt masking register */ -+#define PCI_MSI_MASK_32 12 -+#define PCI_MSI_MASK_64 16 -+#endif -+ - #ifndef PCI_EXP_TYPE_PCIE_BRIDGE - /* PCI/PCI-X to PCIE Bridge */ - #define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 diff --git a/sysutils/xen-tools/files/xsa129-qemuu.patch b/sysutils/xen-tools/files/xsa129-qemuu.patch deleted file mode 100644 index 96715a68d372..000000000000 --- a/sysutils/xen-tools/files/xsa129-qemuu.patch +++ /dev/null @@ -1,172 +0,0 @@ -xen: don't allow guest to control MSI mask register - -It's being used by the hypervisor. For now simply mimic a device not -capable of masking, and fully emulate any accesses a guest may issue -nevertheless as simple reads/writes without side effects. - -This is XSA-129. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/pci/msi.c -+++ b/hw/pci/msi.c -@@ -21,10 +21,6 @@ - #include "hw/pci/msi.h" - #include "qemu/range.h" - --/* Eventually those constants should go to Linux pci_regs.h */ --#define PCI_MSI_PENDING_32 0x10 --#define PCI_MSI_PENDING_64 0x14 -- - /* PCI_MSI_ADDRESS_LO */ - #define PCI_MSI_ADDRESS_LO_MASK (~0x3) - ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -1018,13 +1018,9 @@ static XenPTRegInfo xen_pt_emu_reg_pm[] - */ - - /* Helper */ --static bool xen_pt_msgdata_check_type(uint32_t offset, uint16_t flags) --{ -- /* check the offset whether matches the type or not */ -- bool is_32 = (offset == PCI_MSI_DATA_32) && !(flags & PCI_MSI_FLAGS_64BIT); -- bool is_64 = (offset == PCI_MSI_DATA_64) && (flags & PCI_MSI_FLAGS_64BIT); -- return is_32 || is_64; --} -+#define xen_pt_msi_check_type(offset, flags, what) \ -+ ((offset) == ((flags) & PCI_MSI_FLAGS_64BIT ? \ -+ PCI_MSI_##what##_64 : PCI_MSI_##what##_32)) - - /* Message Control register */ - static int xen_pt_msgctrl_reg_init(XenPCIPassthroughState *s, -@@ -1136,7 +1132,45 @@ static int xen_pt_msgdata_reg_init(XenPC - uint32_t offset = reg->offset; - - /* check the offset whether matches the type or not */ -- if (xen_pt_msgdata_check_type(offset, flags)) { -+ if (xen_pt_msi_check_type(offset, flags, DATA)) { -+ *data = reg->init_val; -+ } else { -+ *data = XEN_PT_INVALID_REG; -+ } -+ return 0; -+} -+ -+/* this function will be called twice (for 32 bit and 64 bit type) */ -+/* initialize Mask register */ -+static int xen_pt_mask_reg_init(XenPCIPassthroughState *s, -+ XenPTRegInfo *reg, uint32_t real_offset, -+ uint32_t *data) -+{ -+ uint32_t flags = s->msi->flags; -+ -+ /* check the offset whether matches the type or not */ -+ if (!(flags & PCI_MSI_FLAGS_MASKBIT)) { -+ *data = XEN_PT_INVALID_REG; -+ } else if (xen_pt_msi_check_type(reg->offset, flags, MASK)) { -+ *data = reg->init_val; -+ } else { -+ *data = XEN_PT_INVALID_REG; -+ } -+ return 0; -+} -+ -+/* this function will be called twice (for 32 bit and 64 bit type) */ -+/* initialize Pending register */ -+static int xen_pt_pending_reg_init(XenPCIPassthroughState *s, -+ XenPTRegInfo *reg, uint32_t real_offset, -+ uint32_t *data) -+{ -+ uint32_t flags = s->msi->flags; -+ -+ /* check the offset whether matches the type or not */ -+ if (!(flags & PCI_MSI_FLAGS_MASKBIT)) { -+ *data = XEN_PT_INVALID_REG; -+ } else if (xen_pt_msi_check_type(reg->offset, flags, PENDING)) { - *data = reg->init_val; - } else { - *data = XEN_PT_INVALID_REG; -@@ -1224,7 +1258,7 @@ static int xen_pt_msgdata_reg_write(XenP - uint32_t offset = reg->offset; - - /* check the offset whether matches the type or not */ -- if (!xen_pt_msgdata_check_type(offset, msi->flags)) { -+ if (!xen_pt_msi_check_type(offset, msi->flags, DATA)) { - /* exit I/O emulator */ - XEN_PT_ERR(&s->dev, "the offset does not match the 32/64 bit type!\n"); - return -1; -@@ -1269,7 +1303,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] - .size = 2, - .init_val = 0x0000, - .ro_mask = 0xFF8E, -- .emu_mask = 0x007F, -+ .emu_mask = 0x017F, - .init = xen_pt_msgctrl_reg_init, - .u.w.read = xen_pt_word_reg_read, - .u.w.write = xen_pt_msgctrl_reg_write, -@@ -1318,6 +1352,50 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] - .u.w.read = xen_pt_word_reg_read, - .u.w.write = xen_pt_msgdata_reg_write, - }, -+ /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */ -+ { -+ .offset = PCI_MSI_MASK_32, -+ .size = 4, -+ .init_val = 0x00000000, -+ .ro_mask = 0xFFFFFFFF, -+ .emu_mask = 0xFFFFFFFF, -+ .init = xen_pt_mask_reg_init, -+ .u.dw.read = xen_pt_long_reg_read, -+ .u.dw.write = xen_pt_long_reg_write, -+ }, -+ /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */ -+ { -+ .offset = PCI_MSI_MASK_64, -+ .size = 4, -+ .init_val = 0x00000000, -+ .ro_mask = 0xFFFFFFFF, -+ .emu_mask = 0xFFFFFFFF, -+ .init = xen_pt_mask_reg_init, -+ .u.dw.read = xen_pt_long_reg_read, -+ .u.dw.write = xen_pt_long_reg_write, -+ }, -+ /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */ -+ { -+ .offset = PCI_MSI_MASK_32 + 4, -+ .size = 4, -+ .init_val = 0x00000000, -+ .ro_mask = 0xFFFFFFFF, -+ .emu_mask = 0x00000000, -+ .init = xen_pt_pending_reg_init, -+ .u.dw.read = xen_pt_long_reg_read, -+ .u.dw.write = xen_pt_long_reg_write, -+ }, -+ /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */ -+ { -+ .offset = PCI_MSI_MASK_64 + 4, -+ .size = 4, -+ .init_val = 0x00000000, -+ .ro_mask = 0xFFFFFFFF, -+ .emu_mask = 0x00000000, -+ .init = xen_pt_pending_reg_init, -+ .u.dw.read = xen_pt_long_reg_read, -+ .u.dw.write = xen_pt_long_reg_write, -+ }, - { - .size = 0, - }, ---- a/include/hw/pci/pci_regs.h -+++ b/include/hw/pci/pci_regs.h -@@ -298,8 +298,10 @@ - #define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */ - #define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */ - #define PCI_MSI_MASK_32 12 /* Mask bits register for 32-bit devices */ -+#define PCI_MSI_PENDING_32 16 /* Pending bits register for 32-bit devices */ - #define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ - #define PCI_MSI_MASK_64 16 /* Mask bits register for 64-bit devices */ -+#define PCI_MSI_PENDING_64 20 /* Pending bits register for 32-bit devices */ - - /* MSI-X registers */ - #define PCI_MSIX_FLAGS 2 diff --git a/sysutils/xen-tools/files/xsa130-qemut.patch b/sysutils/xen-tools/files/xsa130-qemut.patch deleted file mode 100644 index 75af778b0172..000000000000 --- a/sysutils/xen-tools/files/xsa130-qemut.patch +++ /dev/null @@ -1,21 +0,0 @@ -xen/MSI-X: disable logging by default - -... to avoid allowing the guest to cause the control domain's disk to -fill. - -This is XSA-130. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/pass-through.h -+++ b/hw/pass-through.h -@@ -27,7 +27,7 @@ - #include "qemu-timer.h" - - /* Log acesss */ --#define PT_LOGGING_ENABLED -+/* #define PT_LOGGING_ENABLED */ - - /* Print errors even if logging is disabled */ - #define PT_ERR(_f, _a...) fprintf(logfile, "%s: " _f, __func__, ##_a) diff --git a/sysutils/xen-tools/files/xsa130-qemuu.patch b/sysutils/xen-tools/files/xsa130-qemuu.patch deleted file mode 100644 index c2f35bd0b902..000000000000 --- a/sysutils/xen-tools/files/xsa130-qemuu.patch +++ /dev/null @@ -1,71 +0,0 @@ -xen/MSI-X: limit error messages resulting from bad guest behavior - -... to avoid allowing the guest to cause the control domain's disk to -fill. - -The first message in pci_msix_write() can simply be deleted, as this -is indeed bad guest behavior, but such out of bounds writes don't -really need to be logged. - -The second one is more problematic, as there guest behavior may only -appear to be wrong: For one, the old logic didn't take the mask-all bit -into account. And then this shouldn't depend on host device state (i.e. -the host may have masked the entry without the guest having done so). -Plus these writes shouldn't be dropped even when an entry is unmasked. -Instead, if they can't be made take effect right away, they should take -effect on the next unmasking or enabling operation - the specification -explicitly describes such caching behavior. Until we can validly drop -the message (implementing such caching/latching behavior), issue the -message just once per MSI-X table entry. - -Note that the log message in pci_msix_read() similar to the one being -removed here is not an issue: "addr" being of unsigned type, and the -maximum size of the MSI-X table being 32k, entry_nr simply can't be -negative and hence the conditonal guarding issuing of the message will -never be true. - -This is XSA-130. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/xen/xen_pt.h -+++ b/hw/xen/xen_pt.h -@@ -175,6 +175,7 @@ typedef struct XenPTMSIXEntry { - uint32_t data; - uint32_t vector_ctrl; - bool updated; /* indicate whether MSI ADDR or DATA is updated */ -+ bool warned; /* avoid issuing (bogus) warning more than once */ - } XenPTMSIXEntry; - typedef struct XenPTMSIX { - uint32_t ctrl_offset; ---- a/hw/xen/xen_pt_msi.c -+++ b/hw/xen/xen_pt_msi.c -@@ -434,11 +434,10 @@ static void pci_msix_write(void *opaque, - XenPCIPassthroughState *s = opaque; - XenPTMSIX *msix = s->msix; - XenPTMSIXEntry *entry; -- int entry_nr, offset; -+ unsigned int entry_nr, offset; - - entry_nr = addr / PCI_MSIX_ENTRY_SIZE; -- if (entry_nr < 0 || entry_nr >= msix->total_entries) { -- XEN_PT_ERR(&s->dev, "asked MSI-X entry '%i' invalid!\n", entry_nr); -+ if (entry_nr >= msix->total_entries) { - return; - } - entry = &msix->msix_entry[entry_nr]; -@@ -460,8 +459,11 @@ static void pci_msix_write(void *opaque, - + PCI_MSIX_ENTRY_VECTOR_CTRL; - - if (msix->enabled && !(*vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT)) { -- XEN_PT_ERR(&s->dev, "Can't update msix entry %d since MSI-X is" -- " already enabled.\n", entry_nr); -+ if (!entry->warned) { -+ entry->warned = true; -+ XEN_PT_ERR(&s->dev, "Can't update msix entry %d since MSI-X is" -+ " already enabled.\n", entry_nr); -+ } - return; - } - diff --git a/sysutils/xen-tools/files/xsa131-qemut-1.patch b/sysutils/xen-tools/files/xsa131-qemut-1.patch deleted file mode 100644 index 3bfe23698261..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemut-1.patch +++ /dev/null @@ -1,60 +0,0 @@ -xen/MSI: don't open-code pass-through of enable bit modifications - -Without this the actual XSA-131 fix would cause the enable bit to not -get set anymore (due to the write back getting suppressed there based -on the OR of emu_mask, ro_mask, and res_mask). - -Note that the fiddling with the enable bit shouldn't really be done by -qemu, but making this work right (via libxc and the hypervisor) will -require more extensive changes, which can be postponed until after the -security issue got addressed. - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/pass-through.c -+++ b/hw/pass-through.c -@@ -648,7 +648,7 @@ static struct pt_reg_info_tbl pt_emu_reg - .size = 2, - .init_val = 0x0000, - .ro_mask = 0xFF8E, -- .emu_mask = 0x017F, -+ .emu_mask = 0x017E, - .init = pt_msgctrl_reg_init, - .u.w.read = pt_word_reg_read, - .u.w.write = pt_msgctrl_reg_write, -@@ -3901,6 +3901,9 @@ static int pt_msgctrl_reg_write(struct p - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; -+ /* also emulate MSI_ENABLE bit for MSI-INTx translation */ -+ if (ptdev->msi_trans_en) -+ writable_mask |= PCI_MSI_FLAGS_ENABLE & valid_mask; - cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); - /* update the msi_info too */ - ptdev->msi->flags |= cfg_entry->data & -@@ -3909,6 +3912,9 @@ static int pt_msgctrl_reg_write(struct p - /* create value for writing to I/O device register */ - val = *value; - throughable_mask = ~reg->emu_mask & valid_mask; -+ /* don't pass through MSI_ENABLE bit for MSI-INTx translation */ -+ if (ptdev->msi_trans_en) -+ throughable_mask &= ~PCI_MSI_FLAGS_ENABLE; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); - - /* update MSI */ -@@ -3952,12 +3958,6 @@ static int pt_msgctrl_reg_write(struct p - } - } - -- /* pass through MSI_ENABLE bit when no MSI-INTx translation */ -- if (!ptdev->msi_trans_en) { -- *value &= ~PCI_MSI_FLAGS_ENABLE; -- *value |= val & PCI_MSI_FLAGS_ENABLE; -- } -- - return 0; - } - diff --git a/sysutils/xen-tools/files/xsa131-qemut-2.patch b/sysutils/xen-tools/files/xsa131-qemut-2.patch deleted file mode 100644 index cb2c7b9b2094..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemut-2.patch +++ /dev/null @@ -1,140 +0,0 @@ -xen/pt: consolidate PM capability emu_mask - -There's no point in xen_pt_pmcsr_reg_{read,write}() each ORing -PCI_PM_CTRL_STATE_MASK and PCI_PM_CTRL_NO_SOFT_RESET into a local -emu_mask variable - we can have the same effect by setting the field -descriptor's emu_mask member suitably right away. Note that -xen_pt_pmcsr_reg_write() is being retained in order to allow later -patches to be less intrusive. - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> -Acked-by: Ian Campbell <ian.campbell@citrix.com> - ---- a/hw/pass-through.c -+++ b/hw/pass-through.c -@@ -179,9 +179,6 @@ static int pt_long_reg_read(struct pt_de - static int pt_bar_reg_read(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint32_t *value, uint32_t valid_mask); --static int pt_pmcsr_reg_read(struct pt_dev *ptdev, -- struct pt_reg_tbl *cfg_entry, -- uint16_t *value, uint16_t valid_mask); - static int pt_byte_reg_write(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint8_t *value, uint8_t dev_value, uint8_t valid_mask); -@@ -494,7 +491,7 @@ static struct pt_reg_info_tbl pt_emu_reg - .u.w.write = pt_word_reg_write, - .u.w.restore = NULL, - }, -- /* PCI Power Management Control/Status reg */ -+ /* PCI Power Management Control/Status reg (->power_mgmt on) */ - { - .offset = PCI_PM_CTRL, - .size = 2, -@@ -502,7 +499,19 @@ static struct pt_reg_info_tbl pt_emu_reg - .ro_mask = 0xE1FC, - .emu_mask = 0x8100, - .init = pt_pmcsr_reg_init, -- .u.w.read = pt_pmcsr_reg_read, -+ .u.w.read = pt_word_reg_read, -+ .u.w.write = pt_pmcsr_reg_write, -+ .u.w.restore = pt_pmcsr_reg_restore, -+ }, -+ /* PCI Power Management Control/Status reg (->power_mgmt off) */ -+ { -+ .offset = PCI_PM_CTRL, -+ .size = 2, -+ .init_val = 0x0008, -+ .ro_mask = 0xE1FC, -+ .emu_mask = 0x810B, -+ .init = pt_pmcsr_reg_init, -+ .u.w.read = pt_word_reg_read, - .u.w.write = pt_pmcsr_reg_write, - .u.w.restore = pt_pmcsr_reg_restore, - }, -@@ -2919,6 +2928,7 @@ static uint32_t pt_pmc_reg_init(struct p - return reg->init_val; - } - -+/* this function will be called twice (for ->power_mgmt on and off cases) */ - /* initialize PCI Power Management Control/Status register */ - static uint32_t pt_pmcsr_reg_init(struct pt_dev *ptdev, - struct pt_reg_info_tbl *reg, uint32_t real_offset) -@@ -2926,8 +2936,23 @@ static uint32_t pt_pmcsr_reg_init(struct - PCIDevice *d = &ptdev->dev; - uint16_t cap_ver = 0; - -- if (!ptdev->power_mgmt) -- return reg->init_val; -+ switch (reg->emu_mask & (PCI_PM_CTRL_STATE_MASK | -+ PCI_PM_CTRL_NO_SOFT_RESET)) -+ { -+ case 0: -+ if (!ptdev->power_mgmt) -+ return PT_INVALID_REG; -+ break; -+ case PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET: -+ if (!ptdev->power_mgmt) -+ return reg->init_val; -+ return PT_INVALID_REG; -+ default: -+ /* exit I/O emulator */ -+ PT_LOG("Internal error: Invalid PMCSR emulation mask %04x." -+ " I/O emulator exit.\n", reg->emu_mask); -+ exit(1); -+ } - - /* check PCI Power Management support version */ - cap_ver = ptdev->pm_state->pmc_field & PCI_PM_CAP_VER_MASK; -@@ -3417,24 +3442,6 @@ static int pt_bar_reg_read(struct pt_dev - } - - --/* read Power Management Control/Status register */ --static int pt_pmcsr_reg_read(struct pt_dev *ptdev, -- struct pt_reg_tbl *cfg_entry, -- uint16_t *value, uint16_t valid_mask) --{ -- struct pt_reg_info_tbl *reg = cfg_entry->reg; -- uint16_t valid_emu_mask = reg->emu_mask; -- -- if (!ptdev->power_mgmt) -- valid_emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET; -- -- valid_emu_mask = valid_emu_mask & valid_mask ; -- *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); -- -- return 0; --} -- -- - /* write byte size emulate register */ - static int pt_byte_reg_write(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, -@@ -3768,21 +3775,17 @@ static int pt_pmcsr_reg_write(struct pt_ - { - struct pt_reg_info_tbl *reg = cfg_entry->reg; - PCIDevice *d = &ptdev->dev; -- uint16_t emu_mask = reg->emu_mask; - uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; - struct pt_pm_info *pm_state = ptdev->pm_state; - uint16_t read_val = 0; - -- if (!ptdev->power_mgmt) -- emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET; -- - /* modify emulate register */ -- writable_mask = emu_mask & ~reg->ro_mask & valid_mask; -+ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~emu_mask & valid_mask; -+ throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); - - if (!ptdev->power_mgmt) diff --git a/sysutils/xen-tools/files/xsa131-qemut-3.patch b/sysutils/xen-tools/files/xsa131-qemut-3.patch deleted file mode 100644 index a50b2392b7ac..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemut-3.patch +++ /dev/null @@ -1,22 +0,0 @@ -xen/pt: correctly handle PM status bit - -xen_pt_pmcsr_reg_write() needs an adjustment to deal with the RW1C -nature of the not passed through bit 15 (PCI_PM_CTRL_PME_STATUS). - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/pass-through.c -+++ b/hw/pass-through.c -@@ -3786,7 +3786,8 @@ static int pt_pmcsr_reg_write(struct pt_ - - /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; -- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); -+ *value = PT_MERGE_VALUE(*value, dev_value & ~PCI_PM_CTRL_PME_STATUS, -+ throughable_mask); - - if (!ptdev->power_mgmt) - return 0; diff --git a/sysutils/xen-tools/files/xsa131-qemut-4.patch b/sysutils/xen-tools/files/xsa131-qemut-4.patch deleted file mode 100644 index 95a7f517003f..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemut-4.patch +++ /dev/null @@ -1,266 +0,0 @@ -xen/pt: split out calculation of throughable mask in PCI config space handling - -This is just to avoid having to adjust that calculation later in -multiple places. - -Note that including ->ro_mask in get_throughable_mask()'s calculation -is only an apparent (i.e. benign) behavioral change: For r/o fields it -doesn't matter > whether they get passed through - either the same flag -is also set in emu_mask (then there's no change at all) or the field is -r/o in hardware (and hence a write won't change it anyway). - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> -Reviewed-by: Anthony PERARD <anthony.perard@citrix.com> - ---- a/hw/pass-through.c -+++ b/hw/pass-through.c -@@ -3442,6 +3442,15 @@ static int pt_bar_reg_read(struct pt_dev - } - - -+static uint32_t get_throughable_mask(const struct pt_dev *ptdev, -+ const struct pt_reg_info_tbl *reg, -+ uint32_t valid_mask) -+{ -+ uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); -+ -+ return throughable_mask & valid_mask; -+} -+ - /* write byte size emulate register */ - static int pt_byte_reg_write(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, -@@ -3449,14 +3458,13 @@ static int pt_byte_reg_write(struct pt_d - { - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint8_t writable_mask = 0; -- uint8_t throughable_mask = 0; -+ uint8_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); - - return 0; -@@ -3469,14 +3477,13 @@ static int pt_word_reg_write(struct pt_d - { - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; -+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); - - return 0; -@@ -3489,14 +3496,13 @@ static int pt_long_reg_write(struct pt_d - { - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint32_t writable_mask = 0; -- uint32_t throughable_mask = 0; -+ uint32_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); - - return 0; -@@ -3509,7 +3515,7 @@ static int pt_cmd_reg_write(struct pt_de - { - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; -+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); - uint16_t wr_value = *value; - - /* modify emulate register */ -@@ -3517,8 +3523,6 @@ static int pt_cmd_reg_write(struct pt_de - cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; -- - if (*value & PCI_COMMAND_DISABLE_INTx) - { - if (ptdev->msi_trans_en) -@@ -3564,7 +3568,6 @@ static int pt_bar_reg_write(struct pt_de - PCIDevice *d = (PCIDevice *)&ptdev->dev; - PCIIORegion *r; - uint32_t writable_mask = 0; -- uint32_t throughable_mask = 0; - uint32_t bar_emu_mask = 0; - uint32_t bar_ro_mask = 0; - uint32_t new_addr, last_addr; -@@ -3691,8 +3694,7 @@ static int pt_bar_reg_write(struct pt_de - - exit: - /* create value for writing to I/O device register */ -- throughable_mask = ~bar_emu_mask & valid_mask; -- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); -+ *value = PT_MERGE_VALUE(*value, dev_value, 0); - - /* After BAR reg update, we need to remap BAR*/ - reg_grp_entry = pt_find_reg_grp(ptdev, PCI_COMMAND); -@@ -3719,9 +3721,8 @@ static int pt_exp_rom_bar_reg_write(stru - PCIDevice *d = (PCIDevice *)&ptdev->dev; - PCIIORegion *r; - uint32_t writable_mask = 0; -- uint32_t throughable_mask = 0; -+ uint32_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); - uint32_t r_size = 0; -- uint32_t bar_emu_mask = 0; - uint32_t bar_ro_mask = 0; - - r = &d->io_regions[PCI_ROM_SLOT]; -@@ -3731,7 +3732,6 @@ static int pt_exp_rom_bar_reg_write(stru - PT_GET_EMUL_SIZE(base->bar_flag, r_size); - - /* set emulate mask and read-only mask */ -- bar_emu_mask = reg->emu_mask; - bar_ro_mask = (reg->ro_mask | (r_size - 1)) & ~PCI_ROM_ADDRESS_ENABLE; - - /* modify emulate register */ -@@ -3751,7 +3751,6 @@ static int pt_exp_rom_bar_reg_write(stru - r->addr = cfg_entry->data; - - /* create value for writing to I/O device register */ -- throughable_mask = ~bar_emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); - - /* After BAR reg update, we need to remap BAR*/ -@@ -3776,7 +3775,7 @@ static int pt_pmcsr_reg_write(struct pt_ - struct pt_reg_info_tbl *reg = cfg_entry->reg; - PCIDevice *d = &ptdev->dev; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; -+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); - struct pt_pm_info *pm_state = ptdev->pm_state; - uint16_t read_val = 0; - -@@ -3785,7 +3784,6 @@ static int pt_pmcsr_reg_write(struct pt_ - cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value & ~PCI_PM_CTRL_PME_STATUS, - throughable_mask); - -@@ -3894,7 +3892,7 @@ static int pt_msgctrl_reg_write(struct p - { - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; -+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); - uint16_t old_ctrl = cfg_entry->data; - PCIDevice *pd = (PCIDevice *)ptdev; - uint16_t val; -@@ -3906,8 +3904,10 @@ static int pt_msgctrl_reg_write(struct p - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - /* also emulate MSI_ENABLE bit for MSI-INTx translation */ -- if (ptdev->msi_trans_en) -+ if (ptdev->msi_trans_en) { - writable_mask |= PCI_MSI_FLAGS_ENABLE & valid_mask; -+ throughable_mask &= ~PCI_MSI_FLAGS_ENABLE; -+ } - cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); - /* update the msi_info too */ - ptdev->msi->flags |= cfg_entry->data & -@@ -3915,10 +3915,6 @@ static int pt_msgctrl_reg_write(struct p - - /* create value for writing to I/O device register */ - val = *value; -- throughable_mask = ~reg->emu_mask & valid_mask; -- /* don't pass through MSI_ENABLE bit for MSI-INTx translation */ -- if (ptdev->msi_trans_en) -- throughable_mask &= ~PCI_MSI_FLAGS_ENABLE; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); - - /* update MSI */ -@@ -3972,7 +3968,6 @@ static int pt_msgaddr32_reg_write(struct - { - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint32_t writable_mask = 0; -- uint32_t throughable_mask = 0; - uint32_t old_addr = cfg_entry->data; - - /* modify emulate register */ -@@ -3982,8 +3977,7 @@ static int pt_msgaddr32_reg_write(struct - ptdev->msi->addr_lo = cfg_entry->data; - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; -- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); -+ *value = PT_MERGE_VALUE(*value, dev_value, 0); - - /* update MSI */ - if (cfg_entry->data != old_addr) -@@ -4002,7 +3996,6 @@ static int pt_msgaddr64_reg_write(struct - { - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint32_t writable_mask = 0; -- uint32_t throughable_mask = 0; - uint32_t old_addr = cfg_entry->data; - - /* check whether the type is 64 bit or not */ -@@ -4020,8 +4013,7 @@ static int pt_msgaddr64_reg_write(struct - ptdev->msi->addr_hi = cfg_entry->data; - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; -- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); -+ *value = PT_MERGE_VALUE(*value, dev_value, 0); - - /* update MSI */ - if (cfg_entry->data != old_addr) -@@ -4041,7 +4033,6 @@ static int pt_msgdata_reg_write(struct p - { - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; - uint16_t old_data = cfg_entry->data; - uint32_t flags = ptdev->msi->flags; - uint32_t offset = reg->offset; -@@ -4062,8 +4053,7 @@ static int pt_msgdata_reg_write(struct p - ptdev->msi->data = cfg_entry->data; - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; -- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); -+ *value = PT_MERGE_VALUE(*value, dev_value, 0); - - /* update MSI */ - if (cfg_entry->data != old_data) -@@ -4082,7 +4072,7 @@ static int pt_msixctrl_reg_write(struct - { - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; -+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask); - uint16_t old_ctrl = cfg_entry->data; - - /* modify emulate register */ -@@ -4090,7 +4080,6 @@ static int pt_msixctrl_reg_write(struct - cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); - - /* update MSI-X */ diff --git a/sysutils/xen-tools/files/xsa131-qemut-5.patch b/sysutils/xen-tools/files/xsa131-qemut-5.patch deleted file mode 100644 index fb5c4d403d8d..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemut-5.patch +++ /dev/null @@ -1,22 +0,0 @@ -xen/pt: mark all PCIe capability bits read-only - -xen_pt_emu_reg_pcie[]'s PCI_EXP_DEVCAP needs to cover all bits as read- -only to avoid unintended write-back (just a precaution, the field ought -to be read-only in hardware). - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/pass-through.c -+++ b/hw/pass-through.c -@@ -577,7 +577,7 @@ static struct pt_reg_info_tbl pt_emu_reg - .offset = PCI_EXP_DEVCAP, - .size = 4, - .init_val = 0x00000000, -- .ro_mask = 0x1FFCFFFF, -+ .ro_mask = 0xFFFFFFFF, - .emu_mask = 0x10000000, - .init = pt_common_reg_init, - .u.dw.read = pt_long_reg_read, diff --git a/sysutils/xen-tools/files/xsa131-qemut-6.patch b/sysutils/xen-tools/files/xsa131-qemut-6.patch deleted file mode 100644 index 02d175d424e8..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemut-6.patch +++ /dev/null @@ -1,85 +0,0 @@ -xen/pt: mark reserved bits in PCI config space fields - -The adjustments are solely to make the subsequent patches work right -(and hence make the patch set consistent), namely if permissive mode -(introduced by the last patch) gets used (as both reserved registers -and reserved fields must be similarly protected from guest access in -default mode, but the guest should be allowed access to them in -permissive mode). - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> - ---- a/hw/pass-through.c -+++ b/hw/pass-through.c -@@ -283,7 +283,7 @@ static struct pt_reg_info_tbl pt_emu_reg - .offset = PCI_COMMAND, - .size = 2, - .init_val = 0x0000, -- .ro_mask = 0xF880, -+ .res_mask = 0xF880, - .emu_mask = 0x0743, - .init = pt_common_reg_init, - .u.w.read = pt_word_reg_read, -@@ -310,7 +310,8 @@ static struct pt_reg_info_tbl pt_emu_reg - .offset = PCI_STATUS, - .size = 2, - .init_val = 0x0000, -- .ro_mask = 0x06FF, -+ .res_mask = 0x0007, -+ .ro_mask = 0x06F8, - .emu_mask = 0x0010, - .init = pt_status_reg_init, - .u.w.read = pt_word_reg_read, -@@ -496,7 +497,8 @@ static struct pt_reg_info_tbl pt_emu_reg - .offset = PCI_PM_CTRL, - .size = 2, - .init_val = 0x0008, -- .ro_mask = 0xE1FC, -+ .res_mask = 0x00F0, -+ .ro_mask = 0xE10C, - .emu_mask = 0x8100, - .init = pt_pmcsr_reg_init, - .u.w.read = pt_word_reg_read, -@@ -508,7 +510,8 @@ static struct pt_reg_info_tbl pt_emu_reg - .offset = PCI_PM_CTRL, - .size = 2, - .init_val = 0x0008, -- .ro_mask = 0xE1FC, -+ .res_mask = 0x00F0, -+ .ro_mask = 0xE10C, - .emu_mask = 0x810B, - .init = pt_pmcsr_reg_init, - .u.w.read = pt_word_reg_read, -@@ -656,7 +659,8 @@ static struct pt_reg_info_tbl pt_emu_reg - .offset = PCI_MSI_FLAGS, // 2 - .size = 2, - .init_val = 0x0000, -- .ro_mask = 0xFF8E, -+ .res_mask = 0xFE00, -+ .ro_mask = 0x018E, - .emu_mask = 0x017E, - .init = pt_msgctrl_reg_init, - .u.w.read = pt_word_reg_read, -@@ -779,7 +783,8 @@ static struct pt_reg_info_tbl pt_emu_reg - .offset = PCI_MSI_FLAGS, // 2 - .size = 2, - .init_val = 0x0000, -- .ro_mask = 0x3FFF, -+ .res_mask = 0x3800, -+ .ro_mask = 0x07FF, - .emu_mask = 0x0000, - .init = pt_msixctrl_reg_init, - .u.w.read = pt_word_reg_read, ---- a/hw/pass-through.h -+++ b/hw/pass-through.h -@@ -376,6 +376,8 @@ struct pt_reg_info_tbl { - uint32_t size; - /* reg initial value */ - uint32_t init_val; -+ /* reg reserved field mask (ON:reserved, OFF:defined) */ -+ uint32_t res_mask; - /* reg read only field mask (ON:RO/ROS, OFF:other) */ - uint32_t ro_mask; - /* reg emulate field mask (ON:emu, OFF:passthrough) */ diff --git a/sysutils/xen-tools/files/xsa131-qemut-7.patch b/sysutils/xen-tools/files/xsa131-qemut-7.patch deleted file mode 100644 index b2430b5143a1..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemut-7.patch +++ /dev/null @@ -1,81 +0,0 @@ -xen/pt: add a few PCI config space field descriptions - -Since the next patch will turn all not explicitly described fields -read-only by default, those fields that have guest writable bits need -to be given explicit descriptors. - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> - ---- a/hw/pass-through.c -+++ b/hw/pass-through.c -@@ -538,6 +538,16 @@ static struct pt_reg_info_tbl pt_emu_reg - .u.b.restore = NULL, - }, - { -+ .offset = PCI_VPD_ADDR, -+ .size = 2, -+ .ro_mask = 0x0003, -+ .emu_mask = 0x0003, -+ .init = pt_common_reg_init, -+ .u.w.read = pt_word_reg_read, -+ .u.w.write = pt_word_reg_write, -+ .u.w.restore = pt_word_reg_restore, -+ }, -+ { - .size = 0, - }, - }; -@@ -599,6 +609,17 @@ static struct pt_reg_info_tbl pt_emu_reg - .u.w.write = pt_word_reg_write, - .u.w.restore = pt_word_reg_restore, - }, -+ /* Device Status reg */ -+ { -+ .offset = PCI_EXP_DEVSTA, -+ .size = 2, -+ .res_mask = 0xFFC0, -+ .ro_mask = 0x0030, -+ .init = pt_common_reg_init, -+ .u.w.read = pt_word_reg_read, -+ .u.w.write = pt_word_reg_write, -+ .u.w.restore = pt_word_reg_restore, -+ }, - /* Link Control reg */ - { - .offset = PCI_EXP_LNKCTL, -@@ -611,6 +632,16 @@ static struct pt_reg_info_tbl pt_emu_reg - .u.w.write = pt_word_reg_write, - .u.w.restore = pt_word_reg_restore, - }, -+ /* Link Status reg */ -+ { -+ .offset = PCI_EXP_LNKSTA, -+ .size = 2, -+ .ro_mask = 0x3FFF, -+ .init = pt_common_reg_init, -+ .u.w.read = pt_word_reg_read, -+ .u.w.write = pt_word_reg_write, -+ .u.w.restore = pt_word_reg_restore, -+ }, - /* Device Control 2 reg */ - { - .offset = 0x28, ---- a/hw/pass-through.h -+++ b/hw/pass-through.h -@@ -105,6 +105,14 @@ - #define PCI_EXP_TYPE_ROOT_EC 0xa - #endif - -+#ifndef PCI_VPD_ADDR -+/* Vital Product Data */ -+#define PCI_VPD_ADDR 2 /* Address to access (15 bits!) */ -+#define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */ -+#define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */ -+#define PCI_VPD_DATA 4 /* 32-bits of data returned here */ -+#endif -+ - #ifndef PCI_ERR_UNCOR_MASK - /* Uncorrectable Error Mask */ - #define PCI_ERR_UNCOR_MASK 8 diff --git a/sysutils/xen-tools/files/xsa131-qemut-8.patch b/sysutils/xen-tools/files/xsa131-qemut-8.patch deleted file mode 100644 index 875ae9646f56..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemut-8.patch +++ /dev/null @@ -1,139 +0,0 @@ -xen/pt: unknown PCI config space fields should be read-only - -... by default. Add a per-device "permissive" mode similar to pciback's -to allow restoring previous behavior (and hence break security again, -i.e. should be used only for trusted guests). - -This is part of XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> -Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>) - ---- a/hw/pass-through.c -+++ b/hw/pass-through.c -@@ -1613,10 +1613,10 @@ static void pt_pci_write_config(PCIDevic - uint32_t find_addr = address; - uint32_t real_offset = 0; - uint32_t valid_mask = 0xFFFFFFFF; -- uint32_t read_val = 0, wb_mask; -+ uint32_t read_val = 0, wb_mask, wp_mask; - uint8_t *ptr_val = NULL; - int emul_len = 0; -- int index = 0; -+ int index = 0, wp_flag = 0; - int ret = 0; - - #ifdef PT_DEBUG_PCI_CONFIG_ACCESS -@@ -1695,7 +1695,14 @@ static void pt_pci_write_config(PCIDevic - - /* pass directly to libpci for passthrough type register group */ - if (reg_grp_entry == NULL) -+ { -+ if (!assigned_device->permissive) -+ { -+ wb_mask = 0; -+ wp_flag = 1; -+ } - goto out; -+ } - - /* adjust the read and write value to appropriate CFC-CFF window */ - read_val <<= ((address & 3) << 3); -@@ -1714,11 +1721,12 @@ static void pt_pci_write_config(PCIDevic - valid_mask = (0xFFFFFFFF >> ((4 - emul_len) << 3)); - valid_mask <<= ((find_addr - real_offset) << 3); - ptr_val = ((uint8_t *)&val + (real_offset & 3)); -- if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { -- wb_mask &= ~((reg->emu_mask -- >> ((find_addr - real_offset) << 3)) -+ wp_mask = reg->emu_mask | reg->ro_mask; -+ if (!assigned_device->permissive) -+ wp_mask |= reg->res_mask; -+ if (wp_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) -+ wb_mask &= ~((wp_mask >> ((find_addr - real_offset) << 3)) - << ((len - emul_len) << 3)); -- } - - /* do emulation depend on register size */ - switch (reg->size) { -@@ -1767,6 +1775,16 @@ static void pt_pci_write_config(PCIDevic - /* nothing to do with passthrough type register, - * continue to find next byte - */ -+ if (!assigned_device->permissive) -+ { -+ wb_mask &= ~(0xff << ((len - emul_len) << 3)); -+ /* Unused BARs will make it here, but we don't want to issue -+ * warnings for writes to them (bogus writes get dealt with -+ * above). -+ */ -+ if (index < 0) -+ wp_flag = 1; -+ } - emul_len--; - find_addr++; - } -@@ -1776,6 +1794,15 @@ static void pt_pci_write_config(PCIDevic - val >>= ((address & 3) << 3); - - out: -+ if (wp_flag && !assigned_device->permissive_warned) -+ { -+ assigned_device->permissive_warned = 1; -+ PT_LOG("Write-back to unknown field 0x%02x (partially) inhibited (0x%0*x)\n", -+ addr, len * 2, wb_mask); -+ PT_LOG("If device %02x:%02x.%o doesn't work, try enabling permissive\n", -+ pci_bus_num(d->bus), PCI_SLOT(d->devfn), PCI_FUNC(d->devfn)); -+ PT_LOG("mode (unsafe) and if it helps report the problem to xen-devel\n"); -+ } - for (index = 0; wb_mask; index += len) { - /* unknown regs are passed through */ - while (!(wb_mask & 0xff)) { -@@ -3484,6 +3511,9 @@ static uint32_t get_throughable_mask(con - { - uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); - -+ if (!ptdev->permissive) -+ throughable_mask &= ~reg->res_mask; -+ - return throughable_mask & valid_mask; - } - -@@ -4322,7 +4352,7 @@ static struct pt_dev * register_real_dev - uint8_t e_device, e_intx; - uint16_t cmd = 0; - char *key, *val; -- int msi_translate, power_mgmt; -+ int msi_translate, power_mgmt, permissive = 0; - - PT_LOG("Assigning real physical device %02x:%02x.%x ...\n", - r_bus, r_dev, r_func); -@@ -4366,6 +4396,8 @@ static struct pt_dev * register_real_dev - else - PT_LOG("Error: unrecognized value for msitranslate=\n"); - } -+ else if (strcmp(key, "permissive") == 0) -+ permissive = 1; - else if (strcmp(key, "power_mgmt") == 0) - { - if (strcmp(val, "0") == 0) -@@ -4403,6 +4435,7 @@ static struct pt_dev * register_real_dev - assigned_device->msi_trans_cap = msi_translate; - assigned_device->power_mgmt = power_mgmt; - assigned_device->is_virtfn = pt_dev_is_virtfn(pci_dev); -+ assigned_device->permissive = permissive; - pt_iomul_init(assigned_device, r_bus, r_dev, r_func); - - /* Initialize virtualized PCI configuration (Extended 256 Bytes) */ ---- a/hw/pass-through.h -+++ b/hw/pass-through.h -@@ -242,6 +242,8 @@ struct pt_dev { - unsigned power_mgmt:1; - struct pt_pm_info *pm_state; /* PM virtualization */ - unsigned is_virtfn:1; -+ unsigned permissive:1; -+ unsigned permissive_warned:1; - - /* io port multiplexing */ - #define PCI_IOMUL_INVALID_FD (-1) diff --git a/sysutils/xen-tools/files/xsa131-qemuu-1.patch b/sysutils/xen-tools/files/xsa131-qemuu-1.patch deleted file mode 100644 index ece230bb381d..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemuu-1.patch +++ /dev/null @@ -1,60 +0,0 @@ -xen/MSI: don't open-code pass-through of enable bit modifications - -Without this the actual XSA-131 fix would cause the enable bit to not -get set anymore (due to the write back getting suppressed there based -on the OR of emu_mask, ro_mask, and res_mask). - -Note that the fiddling with the enable bit shouldn't really be done by -qemu, but making this work right (via libxc and the hypervisor) will -require more extensive changes, which can be postponed until after the -security issue got addressed. - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -1059,7 +1059,6 @@ static int xen_pt_msgctrl_reg_write(XenP - XenPTMSI *msi = s->msi; - uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; -- uint16_t raw_val; - - /* Currently no support for multi-vector */ - if (*val & PCI_MSI_FLAGS_QSIZE) { -@@ -1072,12 +1071,11 @@ static int xen_pt_msgctrl_reg_write(XenP - msi->flags |= cfg_entry->data & ~PCI_MSI_FLAGS_ENABLE; - - /* create value for writing to I/O device register */ -- raw_val = *val; - throughable_mask = ~reg->emu_mask & valid_mask; - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); - - /* update MSI */ -- if (raw_val & PCI_MSI_FLAGS_ENABLE) { -+ if (*val & PCI_MSI_FLAGS_ENABLE) { - /* setup MSI pirq for the first time */ - if (!msi->initialized) { - /* Init physical one */ -@@ -1105,10 +1103,6 @@ static int xen_pt_msgctrl_reg_write(XenP - xen_pt_msi_disable(s); - } - -- /* pass through MSI_ENABLE bit */ -- *val &= ~PCI_MSI_FLAGS_ENABLE; -- *val |= raw_val & PCI_MSI_FLAGS_ENABLE; -- - return 0; - } - -@@ -1311,7 +1305,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] - .size = 2, - .init_val = 0x0000, - .ro_mask = 0xFF8E, -- .emu_mask = 0x017F, -+ .emu_mask = 0x017E, - .init = xen_pt_msgctrl_reg_init, - .u.w.read = xen_pt_word_reg_read, - .u.w.write = xen_pt_msgctrl_reg_write, diff --git a/sysutils/xen-tools/files/xsa131-qemuu-2.patch b/sysutils/xen-tools/files/xsa131-qemuu-2.patch deleted file mode 100644 index fc547f493e10..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemuu-2.patch +++ /dev/null @@ -1,70 +0,0 @@ -xen/pt: consolidate PM capability emu_mask - -There's no point in xen_pt_pmcsr_reg_{read,write}() each ORing -PCI_PM_CTRL_STATE_MASK and PCI_PM_CTRL_NO_SOFT_RESET into a local -emu_mask variable - we can have the same effect by setting the field -descriptor's emu_mask member suitably right away. Note that -xen_pt_pmcsr_reg_write() is being retained in order to allow later -patches to be less intrusive. - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> -Acked-by: Ian Campbell <ian.campbell@citrix.com> - ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -935,38 +935,21 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[ - * Power Management Capability - */ - --/* read Power Management Control/Status register */ --static int xen_pt_pmcsr_reg_read(XenPCIPassthroughState *s, XenPTReg *cfg_entry, -- uint16_t *value, uint16_t valid_mask) --{ -- XenPTRegInfo *reg = cfg_entry->reg; -- uint16_t valid_emu_mask = reg->emu_mask; -- -- valid_emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET; -- -- valid_emu_mask = valid_emu_mask & valid_mask; -- *value = XEN_PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); -- -- return 0; --} - /* write Power Management Control/Status register */ - static int xen_pt_pmcsr_reg_write(XenPCIPassthroughState *s, - XenPTReg *cfg_entry, uint16_t *val, - uint16_t dev_value, uint16_t valid_mask) - { - XenPTRegInfo *reg = cfg_entry->reg; -- uint16_t emu_mask = reg->emu_mask; - uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; - -- emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET; -- - /* modify emulate register */ -- writable_mask = emu_mask & ~reg->ro_mask & valid_mask; -+ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~emu_mask & valid_mask; -+ throughable_mask = ~reg->emu_mask & valid_mask; - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); - - return 0; -@@ -1002,9 +985,9 @@ static XenPTRegInfo xen_pt_emu_reg_pm[] - .size = 2, - .init_val = 0x0008, - .ro_mask = 0xE1FC, -- .emu_mask = 0x8100, -+ .emu_mask = 0x810B, - .init = xen_pt_common_reg_init, -- .u.w.read = xen_pt_pmcsr_reg_read, -+ .u.w.read = xen_pt_word_reg_read, - .u.w.write = xen_pt_pmcsr_reg_write, - }, - { diff --git a/sysutils/xen-tools/files/xsa131-qemuu-3.patch b/sysutils/xen-tools/files/xsa131-qemuu-3.patch deleted file mode 100644 index f62a4f804503..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemuu-3.patch +++ /dev/null @@ -1,22 +0,0 @@ -xen/pt: correctly handle PM status bit - -xen_pt_pmcsr_reg_write() needs an adjustment to deal with the RW1C -nature of the not passed through bit 15 (PCI_PM_CTRL_PME_STATUS). - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -950,7 +950,8 @@ static int xen_pt_pmcsr_reg_write(XenPCI - - /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; -- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); -+ *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~PCI_PM_CTRL_PME_STATUS, -+ throughable_mask); - - return 0; - } diff --git a/sysutils/xen-tools/files/xsa131-qemuu-4.patch b/sysutils/xen-tools/files/xsa131-qemuu-4.patch deleted file mode 100644 index c36669beeebf..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemuu-4.patch +++ /dev/null @@ -1,248 +0,0 @@ -xen/pt: split out calculation of throughable mask in PCI config space handling - -This is just to avoid having to adjust that calculation later in -multiple places. - -Note that including ->ro_mask in get_throughable_mask()'s calculation -is only an apparent (i.e. benign) behavioral change: For r/o fields it -doesn't matter > whether they get passed through - either the same flag -is also set in emu_mask (then there's no change at all) or the field is -r/o in hardware (and hence a write won't change it anyway). - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> -Reviewed-by: Anthony PERARD <anthony.perard@citrix.com> - ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -95,6 +95,14 @@ XenPTReg *xen_pt_find_reg(XenPTRegGroup - return NULL; - } - -+static uint32_t get_throughable_mask(const XenPCIPassthroughState *s, -+ const XenPTRegInfo *reg, -+ uint32_t valid_mask) -+{ -+ uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); -+ -+ return throughable_mask & valid_mask; -+} - - /**************** - * general register functions -@@ -157,14 +165,13 @@ static int xen_pt_byte_reg_write(XenPCIP - { - XenPTRegInfo *reg = cfg_entry->reg; - uint8_t writable_mask = 0; -- uint8_t throughable_mask = 0; -+ uint8_t throughable_mask = get_throughable_mask(s, reg, valid_mask); - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); - - return 0; -@@ -175,14 +182,13 @@ static int xen_pt_word_reg_write(XenPCIP - { - XenPTRegInfo *reg = cfg_entry->reg; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; -+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); - - return 0; -@@ -193,14 +199,13 @@ static int xen_pt_long_reg_write(XenPCIP - { - XenPTRegInfo *reg = cfg_entry->reg; - uint32_t writable_mask = 0; -- uint32_t throughable_mask = 0; -+ uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask); - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); - - return 0; -@@ -292,15 +297,13 @@ static int xen_pt_cmd_reg_write(XenPCIPa - { - XenPTRegInfo *reg = cfg_entry->reg; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; -+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); - - /* modify emulate register */ - writable_mask = ~reg->ro_mask & valid_mask; - cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; -- - if (*val & PCI_COMMAND_INTX_DISABLE) { - throughable_mask |= PCI_COMMAND_INTX_DISABLE; - } else { -@@ -456,7 +459,6 @@ static int xen_pt_bar_reg_write(XenPCIPa - PCIDevice *d = &s->dev; - const PCIIORegion *r; - uint32_t writable_mask = 0; -- uint32_t throughable_mask = 0; - uint32_t bar_emu_mask = 0; - uint32_t bar_ro_mask = 0; - uint32_t r_size = 0; -@@ -513,8 +515,7 @@ static int xen_pt_bar_reg_write(XenPCIPa - } - - /* create value for writing to I/O device register */ -- throughable_mask = ~bar_emu_mask & valid_mask; -- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); -+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); - - return 0; - } -@@ -528,9 +529,8 @@ static int xen_pt_exp_rom_bar_reg_write( - XenPTRegion *base = NULL; - PCIDevice *d = (PCIDevice *)&s->dev; - uint32_t writable_mask = 0; -- uint32_t throughable_mask = 0; -+ uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask); - pcibus_t r_size = 0; -- uint32_t bar_emu_mask = 0; - uint32_t bar_ro_mask = 0; - - r_size = d->io_regions[PCI_ROM_SLOT].size; -@@ -539,7 +539,6 @@ static int xen_pt_exp_rom_bar_reg_write( - r_size = xen_pt_get_emul_size(base->bar_flag, r_size); - - /* set emulate mask and read-only mask */ -- bar_emu_mask = reg->emu_mask; - bar_ro_mask = (reg->ro_mask | (r_size - 1)) & ~PCI_ROM_ADDRESS_ENABLE; - - /* modify emulate register */ -@@ -547,7 +546,6 @@ static int xen_pt_exp_rom_bar_reg_write( - cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~bar_emu_mask & valid_mask; - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); - - return 0; -@@ -942,14 +940,13 @@ static int xen_pt_pmcsr_reg_write(XenPCI - { - XenPTRegInfo *reg = cfg_entry->reg; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; -+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; - *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~PCI_PM_CTRL_PME_STATUS, - throughable_mask); - -@@ -1042,7 +1039,7 @@ static int xen_pt_msgctrl_reg_write(XenP - XenPTRegInfo *reg = cfg_entry->reg; - XenPTMSI *msi = s->msi; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; -+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); - - /* Currently no support for multi-vector */ - if (*val & PCI_MSI_FLAGS_QSIZE) { -@@ -1055,7 +1052,6 @@ static int xen_pt_msgctrl_reg_write(XenP - msi->flags |= cfg_entry->data & ~PCI_MSI_FLAGS_ENABLE; - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); - - /* update MSI */ -@@ -1171,7 +1167,6 @@ static int xen_pt_msgaddr32_reg_write(Xe - { - XenPTRegInfo *reg = cfg_entry->reg; - uint32_t writable_mask = 0; -- uint32_t throughable_mask = 0; - uint32_t old_addr = cfg_entry->data; - - /* modify emulate register */ -@@ -1180,8 +1175,7 @@ static int xen_pt_msgaddr32_reg_write(Xe - s->msi->addr_lo = cfg_entry->data; - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; -- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); -+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); - - /* update MSI */ - if (cfg_entry->data != old_addr) { -@@ -1199,7 +1193,6 @@ static int xen_pt_msgaddr64_reg_write(Xe - { - XenPTRegInfo *reg = cfg_entry->reg; - uint32_t writable_mask = 0; -- uint32_t throughable_mask = 0; - uint32_t old_addr = cfg_entry->data; - - /* check whether the type is 64 bit or not */ -@@ -1216,8 +1209,7 @@ static int xen_pt_msgaddr64_reg_write(Xe - s->msi->addr_hi = cfg_entry->data; - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; -- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); -+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); - - /* update MSI */ - if (cfg_entry->data != old_addr) { -@@ -1239,7 +1231,6 @@ static int xen_pt_msgdata_reg_write(XenP - XenPTRegInfo *reg = cfg_entry->reg; - XenPTMSI *msi = s->msi; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; - uint16_t old_data = cfg_entry->data; - uint32_t offset = reg->offset; - -@@ -1257,8 +1248,7 @@ static int xen_pt_msgdata_reg_write(XenP - msi->data = cfg_entry->data; - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; -- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); -+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); - - /* update MSI */ - if (cfg_entry->data != old_data) { -@@ -1420,7 +1410,7 @@ static int xen_pt_msixctrl_reg_write(Xen - { - XenPTRegInfo *reg = cfg_entry->reg; - uint16_t writable_mask = 0; -- uint16_t throughable_mask = 0; -+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); - int debug_msix_enabled_old; - - /* modify emulate register */ -@@ -1428,7 +1418,6 @@ static int xen_pt_msixctrl_reg_write(Xen - cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); - - /* create value for writing to I/O device register */ -- throughable_mask = ~reg->emu_mask & valid_mask; - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); - - /* update MSI-X */ diff --git a/sysutils/xen-tools/files/xsa131-qemuu-5.patch b/sysutils/xen-tools/files/xsa131-qemuu-5.patch deleted file mode 100644 index aed87c638a95..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemuu-5.patch +++ /dev/null @@ -1,22 +0,0 @@ -xen/pt: mark all PCIe capability bits read-only - -xen_pt_emu_reg_pcie[]'s PCI_EXP_DEVCAP needs to cover all bits as read- -only to avoid unintended write-back (just a precaution, the field ought -to be read-only in hardware). - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> - ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -873,7 +873,7 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[ - .offset = PCI_EXP_DEVCAP, - .size = 4, - .init_val = 0x00000000, -- .ro_mask = 0x1FFCFFFF, -+ .ro_mask = 0xFFFFFFFF, - .emu_mask = 0x10000000, - .init = xen_pt_common_reg_init, - .u.dw.read = xen_pt_long_reg_read, diff --git a/sysutils/xen-tools/files/xsa131-qemuu-6.patch b/sysutils/xen-tools/files/xsa131-qemuu-6.patch deleted file mode 100644 index 98313d07275c..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemuu-6.patch +++ /dev/null @@ -1,75 +0,0 @@ -xen/pt: mark reserved bits in PCI config space fields - -The adjustments are solely to make the subsequent patches work right -(and hence make the patch set consistent), namely if permissive mode -(introduced by the last patch) gets used (as both reserved registers -and reserved fields must be similarly protected from guest access in -default mode, but the guest should be allowed access to them in -permissive mode). - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> - ---- a/hw/xen/xen_pt.h -+++ b/hw/xen/xen_pt.h -@@ -101,6 +101,8 @@ struct XenPTRegInfo { - uint32_t offset; - uint32_t size; - uint32_t init_val; -+ /* reg reserved field mask (ON:reserved, OFF:defined) */ -+ uint32_t res_mask; - /* reg read only field mask (ON:RO/ROS, OFF:other) */ - uint32_t ro_mask; - /* reg emulate field mask (ON:emu, OFF:passthrough) */ ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -580,7 +580,7 @@ static XenPTRegInfo xen_pt_emu_reg_heade - .offset = PCI_COMMAND, - .size = 2, - .init_val = 0x0000, -- .ro_mask = 0xF880, -+ .res_mask = 0xF880, - .emu_mask = 0x0743, - .init = xen_pt_common_reg_init, - .u.w.read = xen_pt_word_reg_read, -@@ -605,7 +605,8 @@ static XenPTRegInfo xen_pt_emu_reg_heade - .offset = PCI_STATUS, - .size = 2, - .init_val = 0x0000, -- .ro_mask = 0x06FF, -+ .res_mask = 0x0007, -+ .ro_mask = 0x06F8, - .emu_mask = 0x0010, - .init = xen_pt_status_reg_init, - .u.w.read = xen_pt_word_reg_read, -@@ -982,7 +983,8 @@ static XenPTRegInfo xen_pt_emu_reg_pm[] - .offset = PCI_PM_CTRL, - .size = 2, - .init_val = 0x0008, -- .ro_mask = 0xE1FC, -+ .res_mask = 0x00F0, -+ .ro_mask = 0xE10C, - .emu_mask = 0x810B, - .init = xen_pt_common_reg_init, - .u.w.read = xen_pt_word_reg_read, -@@ -1278,7 +1280,8 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] - .offset = PCI_MSI_FLAGS, - .size = 2, - .init_val = 0x0000, -- .ro_mask = 0xFF8E, -+ .res_mask = 0xFE00, -+ .ro_mask = 0x018E, - .emu_mask = 0x017E, - .init = xen_pt_msgctrl_reg_init, - .u.w.read = xen_pt_word_reg_read, -@@ -1456,7 +1459,8 @@ static XenPTRegInfo xen_pt_emu_reg_msix[ - .offset = PCI_MSI_FLAGS, - .size = 2, - .init_val = 0x0000, -- .ro_mask = 0x3FFF, -+ .res_mask = 0x3800, -+ .ro_mask = 0x07FF, - .emu_mask = 0x0000, - .init = xen_pt_msixctrl_reg_init, - .u.w.read = xen_pt_word_reg_read, diff --git a/sysutils/xen-tools/files/xsa131-qemuu-7.patch b/sysutils/xen-tools/files/xsa131-qemuu-7.patch deleted file mode 100644 index fa27fec84479..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemuu-7.patch +++ /dev/null @@ -1,70 +0,0 @@ -xen/pt: add a few PCI config space field descriptions - -Since the next patch will turn all not explicitly described fields -read-only by default, those fields that have guest writable bits need -to be given explicit descriptors. - -This is a preparatory patch for XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> ---- -Notes: -- blindly allowing all VPD reads may still be a problem (out of bounds - addresses aren't allowed, but the spec doesn't say what the effect - would be) ==> also an issue in pciback? -- Vendor Specific cap regs aren't in the table (will become r/o by - default with this change) -- many PCIe cap regs aren't in the table (will again become r/o) -- same for PM cap regs at offsets 6 and 7 - ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -756,6 +756,15 @@ static XenPTRegInfo xen_pt_emu_reg_vpd[] - .u.b.write = xen_pt_byte_reg_write, - }, - { -+ .offset = PCI_VPD_ADDR, -+ .size = 2, -+ .ro_mask = 0x0003, -+ .emu_mask = 0x0003, -+ .init = xen_pt_common_reg_init, -+ .u.w.read = xen_pt_word_reg_read, -+ .u.w.write = xen_pt_word_reg_write, -+ }, -+ { - .size = 0, - }, - }; -@@ -891,6 +900,16 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[ - .u.w.read = xen_pt_word_reg_read, - .u.w.write = xen_pt_word_reg_write, - }, -+ /* Device Status reg */ -+ { -+ .offset = PCI_EXP_DEVSTA, -+ .size = 2, -+ .res_mask = 0xFFC0, -+ .ro_mask = 0x0030, -+ .init = xen_pt_common_reg_init, -+ .u.w.read = xen_pt_word_reg_read, -+ .u.w.write = xen_pt_word_reg_write, -+ }, - /* Link Control reg */ - { - .offset = PCI_EXP_LNKCTL, -@@ -902,6 +921,15 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[ - .u.w.read = xen_pt_word_reg_read, - .u.w.write = xen_pt_word_reg_write, - }, -+ /* Link Status reg */ -+ { -+ .offset = PCI_EXP_LNKSTA, -+ .size = 2, -+ .ro_mask = 0x3FFF, -+ .init = xen_pt_common_reg_init, -+ .u.w.read = xen_pt_word_reg_read, -+ .u.w.write = xen_pt_word_reg_write, -+ }, - /* Device Control 2 reg */ - { - .offset = 0x28, diff --git a/sysutils/xen-tools/files/xsa131-qemuu-8.patch b/sysutils/xen-tools/files/xsa131-qemuu-8.patch deleted file mode 100644 index 9537baf27d50..000000000000 --- a/sysutils/xen-tools/files/xsa131-qemuu-8.patch +++ /dev/null @@ -1,122 +0,0 @@ -xen/pt: unknown PCI config space fields should be read-only - -... by default. Add a per-device "permissive" mode similar to pciback's -to allow restoring previous behavior (and hence break security again, -i.e. should be used only for trusted guests). - -This is part of XSA-131. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> -Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>) ---- -Notes: -- What purpose does xen_pt_header_type_reg_init() serve (with .emu_mask - being zero)? -- In the qemu-trad case no equivalent logic to that setting/using - direct_pci_{msi_translate,power_mgmt} is being added, as that logic - seems broken (setting globals from device 0 xenstore settings). - ---- a/hw/xen/xen_pt.c -+++ b/hw/xen/xen_pt.c -@@ -239,6 +239,7 @@ static void xen_pt_pci_write_config(PCID - XenPTReg *reg_entry = NULL; - uint32_t find_addr = addr; - XenPTRegInfo *reg = NULL; -+ bool wp_flag = false; - - if (xen_pt_pci_config_access_check(d, addr, len)) { - return; -@@ -280,6 +281,10 @@ static void xen_pt_pci_write_config(PCID - - /* pass directly to the real device for passthrough type register group */ - if (reg_grp_entry == NULL) { -+ if (!s->permissive) { -+ wb_mask = 0; -+ wp_flag = true; -+ } - goto out; - } - -@@ -300,12 +305,15 @@ static void xen_pt_pci_write_config(PCID - uint32_t real_offset = reg_grp_entry->base_offset + reg->offset; - uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3); - uint8_t *ptr_val = NULL; -+ uint32_t wp_mask = reg->emu_mask | reg->ro_mask; - - valid_mask <<= (find_addr - real_offset) << 3; - ptr_val = (uint8_t *)&val + (real_offset & 3); -- if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { -- wb_mask &= ~((reg->emu_mask -- >> ((find_addr - real_offset) << 3)) -+ if (!s->permissive) { -+ wp_mask |= reg->res_mask; -+ } -+ if (wp_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { -+ wb_mask &= ~((wp_mask >> ((find_addr - real_offset) << 3)) - << ((len - emul_len) << 3)); - } - -@@ -349,6 +357,16 @@ static void xen_pt_pci_write_config(PCID - } else { - /* nothing to do with passthrough type register, - * continue to find next byte */ -+ if (!s->permissive) { -+ wb_mask &= ~(0xff << ((len - emul_len) << 3)); -+ /* Unused BARs will make it here, but we don't want to issue -+ * warnings for writes to them (bogus writes get dealt with -+ * above). -+ */ -+ if (index < 0) { -+ wp_flag = true; -+ } -+ } - emul_len--; - find_addr++; - } -@@ -360,6 +378,13 @@ static void xen_pt_pci_write_config(PCID - memory_region_transaction_commit(); - - out: -+ if (wp_flag && !s->permissive_warned) { -+ s->permissive_warned = true; -+ xen_pt_log(d, "Write-back to unknown field 0x%02x (partially) inhibited (0x%0*x)\n", -+ addr, len * 2, wb_mask); -+ xen_pt_log(d, "If the device doesn't work, try enabling permissive mode\n"); -+ xen_pt_log(d, "(unsafe) and if it helps report the problem to xen-devel\n"); -+ } - for (index = 0; wb_mask; index += len) { - /* unknown regs are passed through */ - while (!(wb_mask & 0xff)) { -@@ -821,6 +846,7 @@ static void xen_pt_unregister_device(PCI - - static Property xen_pci_passthrough_properties[] = { - DEFINE_PROP_PCI_HOST_DEVADDR("hostaddr", XenPCIPassthroughState, hostaddr), -+ DEFINE_PROP_BOOL("permissive", XenPCIPassthroughState, permissive, false), - DEFINE_PROP_END_OF_LIST(), - }; - ---- a/hw/xen/xen_pt.h -+++ b/hw/xen/xen_pt.h -@@ -197,6 +197,8 @@ struct XenPCIPassthroughState { - - PCIHostDeviceAddress hostaddr; - bool is_virtfn; -+ bool permissive; -+ bool permissive_warned; - XenHostPCIDevice real_device; - XenPTRegion bases[PCI_NUM_REGIONS]; /* Access regions */ - QLIST_HEAD(, XenPTRegGroup) reg_grps; ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -101,6 +101,10 @@ static uint32_t get_throughable_mask(con - { - uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); - -+ if (!s->permissive) { -+ throughable_mask &= ~reg->res_mask; -+ } -+ - return throughable_mask & valid_mask; - } - diff --git a/sysutils/xen-tools/files/xsa133-qemut.patch b/sysutils/xen-tools/files/xsa133-qemut.patch deleted file mode 100644 index e1b77117df16..000000000000 --- a/sysutils/xen-tools/files/xsa133-qemut.patch +++ /dev/null @@ -1,80 +0,0 @@ -From ac7ddbe342d7aa2303c39ca731cc6229dbbd739b Mon Sep 17 00:00:00 2001 -From: Petr Matousek <pmatouse@redhat.com> -Date: Wed, 6 May 2015 09:48:59 +0200 -Subject: [PATCH] fdc: force the fifo access to be in bounds of the allocated buffer - -During processing of certain commands such as FD_CMD_READ_ID and -FD_CMD_DRIVE_SPECIFICATION_COMMAND the fifo memory access could -get out of bounds leading to memory corruption with values coming -from the guest. - -Fix this by making sure that the index is always bounded by the -allocated memory. - -This is CVE-2015-3456. - -Signed-off-by: Petr Matousek <pmatouse@redhat.com> -Reviewed-by: John Snow <jsnow@redhat.com> ---- - hw/fdc.c | 17 +++++++++++------ - 1 file changed, 11 insertions(+), 6 deletions(-) - -diff --git a/hw/fdc.c b/hw/fdc.c -index b00a4ec..aba02e4 100644 ---- a/hw/fdc.c -+++ b/hw/fdc.c -@@ -1318,7 +1318,7 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) - { - fdrive_t *cur_drv; - uint32_t retval = 0; -- int pos; -+ uint32_t pos; - - cur_drv = get_cur_drv(fdctrl); - fdctrl->dsr &= ~FD_DSR_PWRDOWN; -@@ -1327,8 +1327,8 @@ static uint32_t fdctrl_read_data (fdctrl_t *fdctrl) - return 0; - } - pos = fdctrl->data_pos; -+ pos %= FD_SECTOR_LEN; - if (fdctrl->msr & FD_MSR_NONDMA) { -- pos %= FD_SECTOR_LEN; - if (pos == 0) { - if (fdctrl->data_pos != 0) - if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { -@@ -1673,10 +1673,13 @@ static void fdctrl_handle_option (fdctrl_t *fdctrl, int direction) - static void fdctrl_handle_drive_specification_command (fdctrl_t *fdctrl, int direction) - { - fdrive_t *cur_drv = get_cur_drv(fdctrl); -+ uint32_t pos; - -- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) { -+ pos = fdctrl->data_pos - 1; -+ pos %= FD_SECTOR_LEN; -+ if (fdctrl->fifo[pos] & 0x80) { - /* Command parameters done */ -- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) { -+ if (fdctrl->fifo[pos] & 0x40) { - fdctrl->fifo[0] = fdctrl->fifo[1]; - fdctrl->fifo[2] = 0; - fdctrl->fifo[3] = 0; -@@ -1771,7 +1774,7 @@ static uint8_t command_to_handler[256]; - static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value) - { - fdrive_t *cur_drv; -- int pos; -+ uint32_t pos; - - /* Reset mode */ - if (!(fdctrl->dor & FD_DOR_nRESET)) { -@@ -1817,7 +1820,9 @@ static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value) - } - - FLOPPY_DPRINTF("%s: %02x\n", __func__, value); -- fdctrl->fifo[fdctrl->data_pos++] = value; -+ pos = fdctrl->data_pos++; -+ pos %= FD_SECTOR_LEN; -+ fdctrl->fifo[pos] = value; - if (fdctrl->data_pos == fdctrl->data_len) { - /* We now have all parameters - * and will be able to treat the command diff --git a/sysutils/xen-tools/files/xsa133-qemuu.patch b/sysutils/xen-tools/files/xsa133-qemuu.patch deleted file mode 100644 index 95f3dcc21e5b..000000000000 --- a/sysutils/xen-tools/files/xsa133-qemuu.patch +++ /dev/null @@ -1,84 +0,0 @@ -From ac7ddbe342d7aa2303c39ca731cc6229dbbd739b Mon Sep 17 00:00:00 2001 -From: Petr Matousek <pmatouse@redhat.com> -Date: Wed, 6 May 2015 09:48:59 +0200 -Subject: [PATCH] fdc: force the fifo access to be in bounds of the allocated buffer - -During processing of certain commands such as FD_CMD_READ_ID and -FD_CMD_DRIVE_SPECIFICATION_COMMAND the fifo memory access could -get out of bounds leading to memory corruption with values coming -from the guest. - -Fix this by making sure that the index is always bounded by the -allocated memory. - -This is CVE-2015-3456. - -Signed-off-by: Petr Matousek <pmatouse@redhat.com> -Reviewed-by: John Snow <jsnow@redhat.com> ---- - hw/block/fdc.c | 17 +++++++++++------ - 1 file changed, 11 insertions(+), 6 deletions(-) - -diff --git a/hw/block/fdc.c b/hw/block/fdc.c -index f72a392..d8a8edd 100644 ---- a/hw/block/fdc.c -+++ b/hw/block/fdc.c -@@ -1497,7 +1497,7 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl) - { - FDrive *cur_drv; - uint32_t retval = 0; -- int pos; -+ uint32_t pos; - - cur_drv = get_cur_drv(fdctrl); - fdctrl->dsr &= ~FD_DSR_PWRDOWN; -@@ -1506,8 +1506,8 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl) - return 0; - } - pos = fdctrl->data_pos; -+ pos %= FD_SECTOR_LEN; - if (fdctrl->msr & FD_MSR_NONDMA) { -- pos %= FD_SECTOR_LEN; - if (pos == 0) { - if (fdctrl->data_pos != 0) - if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { -@@ -1852,10 +1852,13 @@ static void fdctrl_handle_option(FDCtrl *fdctrl, int direction) - static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction) - { - FDrive *cur_drv = get_cur_drv(fdctrl); -+ uint32_t pos; - -- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) { -+ pos = fdctrl->data_pos - 1; -+ pos %= FD_SECTOR_LEN; -+ if (fdctrl->fifo[pos] & 0x80) { - /* Command parameters done */ -- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) { -+ if (fdctrl->fifo[pos] & 0x40) { - fdctrl->fifo[0] = fdctrl->fifo[1]; - fdctrl->fifo[2] = 0; - fdctrl->fifo[3] = 0; -@@ -1955,7 +1958,7 @@ static uint8_t command_to_handler[256]; - static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value) - { - FDrive *cur_drv; -- int pos; -+ uint32_t pos; - - /* Reset mode */ - if (!(fdctrl->dor & FD_DOR_nRESET)) { -@@ -2004,7 +2007,9 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value) - } - - FLOPPY_DPRINTF("%s: %02x\n", __func__, value); -- fdctrl->fifo[fdctrl->data_pos++] = value; -+ pos = fdctrl->data_pos++; -+ pos %= FD_SECTOR_LEN; -+ fdctrl->fifo[pos] = value; - if (fdctrl->data_pos == fdctrl->data_len) { - /* We now have all parameters - * and will be able to treat the command --- -2.1.0 - - diff --git a/sysutils/xen-tools/files/xsa135-qemuu-4.5-1.patch b/sysutils/xen-tools/files/xsa135-qemuu-4.5-1.patch deleted file mode 100644 index 31b161026f14..000000000000 --- a/sysutils/xen-tools/files/xsa135-qemuu-4.5-1.patch +++ /dev/null @@ -1,94 +0,0 @@ -pcnet: fix Negative array index read - -From: Gonglei <arei.gonglei@huawei.com> - -s->xmit_pos maybe assigned to a negative value (-1), -but in this branch variable s->xmit_pos as an index to -array s->buffer. Let's add a check for s->xmit_pos. - -upstream-commit-id: 7b50d00911ddd6d56a766ac5671e47304c20a21b - -Signed-off-by: Gonglei <arei.gonglei@huawei.com> -Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> -Reviewed-by: Jason Wang <jasowang@redhat.com> -Reviewed-by: Jason Wang <jasowang@redhat.com> -Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> - -diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c -index d344c15..f409b92 100644 ---- a/hw/net/pcnet.c -+++ b/hw/net/pcnet.c -@@ -1212,7 +1212,7 @@ static void pcnet_transmit(PCNetState *s) - hwaddr xmit_cxda = 0; - int count = CSR_XMTRL(s)-1; - int add_crc = 0; -- -+ int bcnt; - s->xmit_pos = -1; - - if (!CSR_TXON(s)) { -@@ -1247,35 +1247,40 @@ static void pcnet_transmit(PCNetState *s) - s->xmit_pos = -1; - goto txdone; - } -+ -+ if (s->xmit_pos < 0) { -+ goto txdone; -+ } -+ -+ bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); -+ s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), -+ s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); -+ s->xmit_pos += bcnt; -+ - if (!GET_FIELD(tmd.status, TMDS, ENP)) { -- int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); -- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), -- s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); -- s->xmit_pos += bcnt; -- } else if (s->xmit_pos >= 0) { -- int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); -- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), -- s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); -- s->xmit_pos += bcnt; -+ goto txdone; -+ } -+ - #ifdef PCNET_DEBUG -- printf("pcnet_transmit size=%d\n", s->xmit_pos); -+ printf("pcnet_transmit size=%d\n", s->xmit_pos); - #endif -- if (CSR_LOOP(s)) { -- if (BCR_SWSTYLE(s) == 1) -- add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS); -- s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC; -- pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos); -- s->looptest = 0; -- } else -- if (s->nic) -- qemu_send_packet(qemu_get_queue(s->nic), s->buffer, -- s->xmit_pos); -- -- s->csr[0] &= ~0x0008; /* clear TDMD */ -- s->csr[4] |= 0x0004; /* set TXSTRT */ -- s->xmit_pos = -1; -+ if (CSR_LOOP(s)) { -+ if (BCR_SWSTYLE(s) == 1) -+ add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS); -+ s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC; -+ pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos); -+ s->looptest = 0; -+ } else { -+ if (s->nic) { -+ qemu_send_packet(qemu_get_queue(s->nic), s->buffer, -+ s->xmit_pos); -+ } - } - -+ s->csr[0] &= ~0x0008; /* clear TDMD */ -+ s->csr[4] |= 0x0004; /* set TXSTRT */ -+ s->xmit_pos = -1; -+ - txdone: - SET_FIELD(&tmd.status, TMDS, OWN, 0); - TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s))); diff --git a/sysutils/xen-tools/files/xsa135-qemuu-4.5-2.patch b/sysutils/xen-tools/files/xsa135-qemuu-4.5-2.patch deleted file mode 100644 index 4fe7df5440fd..000000000000 --- a/sysutils/xen-tools/files/xsa135-qemuu-4.5-2.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 2630672ab22255de252f877709851c0557a1c647 Mon Sep 17 00:00:00 2001 -From: Petr Matousek <pmatouse@redhat.com> -Date: Sun, 24 May 2015 10:53:44 +0200 -Subject: [PATCH] pcnet: force the buffer access to be in bounds during tx - -4096 is the maximum length per TMD and it is also currently the size of -the relay buffer pcnet driver uses for sending the packet data to QEMU -for further processing. With packet spanning multiple TMDs it can -happen that the overall packet size will be bigger than sizeof(buffer), -which results in memory corruption. - -Fix this by only allowing to queue maximum sizeof(buffer) bytes. - -This is CVE-2015-3209. - -Signed-off-by: Petr Matousek <pmatouse@redhat.com> -Reported-by: Matt Tait <matttait@google.com> -Reviewed-by: Peter Maydell <peter.maydell@linaro.org> -Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> ---- - hw/net/pcnet.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c -index bdfd38f..6d32e4c 100644 ---- a/hw/net/pcnet.c -+++ b/hw/net/pcnet.c -@@ -1241,6 +1241,14 @@ static void pcnet_transmit(PCNetState *s) - } - - bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); -+ -+ /* if multi-tmd packet outsizes s->buffer then skip it silently. -+ Note: this is not what real hw does */ -+ if (s->xmit_pos + bcnt > sizeof(s->buffer)) { -+ s->xmit_pos = -1; -+ goto txdone; -+ } -+ - s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), - s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); - s->xmit_pos += bcnt; --- -2.1.0 - diff --git a/sysutils/xen-tools/files/xsa139-qemuu-4.5.patch b/sysutils/xen-tools/files/xsa139-qemuu-4.5.patch new file mode 100644 index 000000000000..70ea0661d43a --- /dev/null +++ b/sysutils/xen-tools/files/xsa139-qemuu-4.5.patch @@ -0,0 +1,38 @@ +pci_piix3_xen_ide_unplug should completely unhook the unplugged +IDEDevice from the corresponding BlockBackend, otherwise the next call +to release_drive will try to detach the drive again. + +Suggested-by: Kevin Wolf <kwolf@redhat.com> +Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> +--- + hw/ide/piix.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/hw/ide/piix.c b/hw/ide/piix.c +index 40757eb..0524dce 100644 +--- a/hw/ide/piix.c ++++ b/hw/ide/piix.c +@@ -172,6 +172,7 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev) + PCIIDEState *pci_ide; + DriveInfo *di; + int i = 0; ++ IDEDevice *idedev; + + pci_ide = PCI_IDE(dev); + +@@ -184,6 +185,12 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev) + } + bdrv_close(di->bdrv); + pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; ++ if (!(i % 2)) { ++ idedev = pci_ide->bus[di->bus].master; ++ } else { ++ idedev = pci_ide->bus[di->bus].slave; ++ } ++ idedev->conf.bs = NULL; + drive_put_ref(di); + } + } +-- +2.1.4 + diff --git a/sysutils/xen-tools/files/xsa140-qemuu-unstable-1.patch b/sysutils/xen-tools/files/xsa140-qemuu-unstable-1.patch new file mode 100644 index 000000000000..043d1893579c --- /dev/null +++ b/sysutils/xen-tools/files/xsa140-qemuu-unstable-1.patch @@ -0,0 +1,82 @@ +From 5e0c290415b9d57077a86e70c8e6a058868334d3 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi <stefanha@redhat.com> +Date: Wed, 15 Jul 2015 18:16:58 +0100 +Subject: [PATCH 1/7] rtl8139: avoid nested ifs in IP header parsing + +Transmit offload needs to parse packet headers. If header fields have +unexpected values the offload processing is skipped. + +The code currently uses nested ifs because there is relatively little +input validation. The next patches will add missing input validation +and a goto label is more appropriate to avoid deep if statement nesting. + +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> +--- + hw/net/rtl8139.c | 41 ++++++++++++++++++++++------------------- + 1 file changed, 22 insertions(+), 19 deletions(-) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index 5f0197c..91ba33b 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2174,28 +2174,30 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + size_t eth_payload_len = 0; + + int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12)); +- if (proto == ETH_P_IP) ++ if (proto != ETH_P_IP) + { +- DPRINTF("+++ C+ mode has IP packet\n"); +- +- /* not aligned */ +- eth_payload_data = saved_buffer + ETH_HLEN; +- eth_payload_len = saved_size - ETH_HLEN; +- +- ip = (ip_header*)eth_payload_data; +- +- if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { +- DPRINTF("+++ C+ mode packet has bad IP version %d " +- "expected %d\n", IP_HEADER_VERSION(ip), +- IP_HEADER_VERSION_4); +- ip = NULL; +- } else { +- hlen = IP_HEADER_LENGTH(ip); +- ip_protocol = ip->ip_p; +- ip_data_len = be16_to_cpu(ip->ip_len) - hlen; +- } ++ goto skip_offload; + } + ++ DPRINTF("+++ C+ mode has IP packet\n"); ++ ++ /* not aligned */ ++ eth_payload_data = saved_buffer + ETH_HLEN; ++ eth_payload_len = saved_size - ETH_HLEN; ++ ++ ip = (ip_header*)eth_payload_data; ++ ++ if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { ++ DPRINTF("+++ C+ mode packet has bad IP version %d " ++ "expected %d\n", IP_HEADER_VERSION(ip), ++ IP_HEADER_VERSION_4); ++ goto skip_offload; ++ } ++ ++ hlen = IP_HEADER_LENGTH(ip); ++ ip_protocol = ip->ip_p; ++ ip_data_len = be16_to_cpu(ip->ip_len) - hlen; ++ + if (ip) + { + if (txdw0 & CP_TX_IPCS) +@@ -2391,6 +2393,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + } + } + ++skip_offload: + /* update tally counter */ + ++s->tally_counters.TxOk; + +-- +2.1.4 + diff --git a/sysutils/xen-tools/files/xsa140-qemuu-unstable-2.patch b/sysutils/xen-tools/files/xsa140-qemuu-unstable-2.patch new file mode 100644 index 000000000000..7a76a8a40d25 --- /dev/null +++ b/sysutils/xen-tools/files/xsa140-qemuu-unstable-2.patch @@ -0,0 +1,373 @@ +From 2d7d80e8dc160904fa7276cc05da26c062a50066 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi <stefanha@redhat.com> +Date: Wed, 15 Jul 2015 18:16:59 +0100 +Subject: [PATCH 2/7] rtl8139: drop tautologous if (ip) {...} statement + +The previous patch stopped using the ip pointer as an indicator that the +IP header is present. When we reach the if (ip) {...} statement we know +ip is always non-NULL. + +Remove the if statement to reduce nesting. + +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> +--- + hw/net/rtl8139.c | 305 +++++++++++++++++++++++++++---------------------------- + 1 file changed, 151 insertions(+), 154 deletions(-) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index 91ba33b..2f12d42 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2198,198 +2198,195 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + ip_protocol = ip->ip_p; + ip_data_len = be16_to_cpu(ip->ip_len) - hlen; + +- if (ip) ++ if (txdw0 & CP_TX_IPCS) + { +- if (txdw0 & CP_TX_IPCS) +- { +- DPRINTF("+++ C+ mode need IP checksum\n"); ++ DPRINTF("+++ C+ mode need IP checksum\n"); + +- if (hlen<sizeof(ip_header) || hlen>eth_payload_len) {/* min header length */ +- /* bad packet header len */ +- /* or packet too short */ +- } +- else +- { +- ip->ip_sum = 0; +- ip->ip_sum = ip_checksum(ip, hlen); +- DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", +- hlen, ip->ip_sum); +- } ++ if (hlen<sizeof(ip_header) || hlen>eth_payload_len) {/* min header length */ ++ /* bad packet header len */ ++ /* or packet too short */ + } +- +- if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) ++ else + { +- int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; ++ ip->ip_sum = 0; ++ ip->ip_sum = ip_checksum(ip, hlen); ++ DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", ++ hlen, ip->ip_sum); ++ } ++ } + +- DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " +- "frame data %d specified MSS=%d\n", ETH_MTU, +- ip_data_len, saved_size - ETH_HLEN, large_send_mss); ++ if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) ++ { ++ int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; + +- int tcp_send_offset = 0; +- int send_count = 0; ++ DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " ++ "frame data %d specified MSS=%d\n", ETH_MTU, ++ ip_data_len, saved_size - ETH_HLEN, large_send_mss); + +- /* maximum IP header length is 60 bytes */ +- uint8_t saved_ip_header[60]; ++ int tcp_send_offset = 0; ++ int send_count = 0; + +- /* save IP header template; data area is used in tcp checksum calculation */ +- memcpy(saved_ip_header, eth_payload_data, hlen); ++ /* maximum IP header length is 60 bytes */ ++ uint8_t saved_ip_header[60]; + +- /* a placeholder for checksum calculation routine in tcp case */ +- uint8_t *data_to_checksum = eth_payload_data + hlen - 12; +- // size_t data_to_checksum_len = eth_payload_len - hlen + 12; ++ /* save IP header template; data area is used in tcp checksum calculation */ ++ memcpy(saved_ip_header, eth_payload_data, hlen); + +- /* pointer to TCP header */ +- tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); ++ /* a placeholder for checksum calculation routine in tcp case */ ++ uint8_t *data_to_checksum = eth_payload_data + hlen - 12; ++ // size_t data_to_checksum_len = eth_payload_len - hlen + 12; + +- int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); ++ /* pointer to TCP header */ ++ tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); + +- /* ETH_MTU = ip header len + tcp header len + payload */ +- int tcp_data_len = ip_data_len - tcp_hlen; +- int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; ++ int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); + +- DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP " +- "data len %d TCP chunk size %d\n", ip_data_len, +- tcp_hlen, tcp_data_len, tcp_chunk_size); ++ /* ETH_MTU = ip header len + tcp header len + payload */ ++ int tcp_data_len = ip_data_len - tcp_hlen; ++ int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; + +- /* note the cycle below overwrites IP header data, +- but restores it from saved_ip_header before sending packet */ ++ DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP " ++ "data len %d TCP chunk size %d\n", ip_data_len, ++ tcp_hlen, tcp_data_len, tcp_chunk_size); + +- int is_last_frame = 0; ++ /* note the cycle below overwrites IP header data, ++ but restores it from saved_ip_header before sending packet */ + +- for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size) +- { +- uint16_t chunk_size = tcp_chunk_size; +- +- /* check if this is the last frame */ +- if (tcp_send_offset + tcp_chunk_size >= tcp_data_len) +- { +- is_last_frame = 1; +- chunk_size = tcp_data_len - tcp_send_offset; +- } +- +- DPRINTF("+++ C+ mode TSO TCP seqno %08x\n", +- be32_to_cpu(p_tcp_hdr->th_seq)); +- +- /* add 4 TCP pseudoheader fields */ +- /* copy IP source and destination fields */ +- memcpy(data_to_checksum, saved_ip_header + 12, 8); +- +- DPRINTF("+++ C+ mode TSO calculating TCP checksum for " +- "packet with %d bytes data\n", tcp_hlen + +- chunk_size); +- +- if (tcp_send_offset) +- { +- memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size); +- } +- +- /* keep PUSH and FIN flags only for the last frame */ +- if (!is_last_frame) +- { +- TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN); +- } +- +- /* recalculate TCP checksum */ +- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; +- p_tcpip_hdr->zeros = 0; +- p_tcpip_hdr->ip_proto = IP_PROTO_TCP; +- p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size); +- +- p_tcp_hdr->th_sum = 0; +- +- int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); +- DPRINTF("+++ C+ mode TSO TCP checksum %04x\n", +- tcp_checksum); +- +- p_tcp_hdr->th_sum = tcp_checksum; +- +- /* restore IP header */ +- memcpy(eth_payload_data, saved_ip_header, hlen); +- +- /* set IP data length and recalculate IP checksum */ +- ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); +- +- /* increment IP id for subsequent frames */ +- ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id)); +- +- ip->ip_sum = 0; +- ip->ip_sum = ip_checksum(eth_payload_data, hlen); +- DPRINTF("+++ C+ mode TSO IP header len=%d " +- "checksum=%04x\n", hlen, ip->ip_sum); +- +- int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; +- DPRINTF("+++ C+ mode TSO transferring packet size " +- "%d\n", tso_send_size); +- rtl8139_transfer_frame(s, saved_buffer, tso_send_size, +- 0, (uint8_t *) dot1q_buffer); +- +- /* add transferred count to TCP sequence number */ +- p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq)); +- ++send_count; +- } ++ int is_last_frame = 0; + +- /* Stop sending this frame */ +- saved_size = 0; +- } +- else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) ++ for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size) + { +- DPRINTF("+++ C+ mode need TCP or UDP checksum\n"); ++ uint16_t chunk_size = tcp_chunk_size; + +- /* maximum IP header length is 60 bytes */ +- uint8_t saved_ip_header[60]; +- memcpy(saved_ip_header, eth_payload_data, hlen); ++ /* check if this is the last frame */ ++ if (tcp_send_offset + tcp_chunk_size >= tcp_data_len) ++ { ++ is_last_frame = 1; ++ chunk_size = tcp_data_len - tcp_send_offset; ++ } + +- uint8_t *data_to_checksum = eth_payload_data + hlen - 12; +- // size_t data_to_checksum_len = eth_payload_len - hlen + 12; ++ DPRINTF("+++ C+ mode TSO TCP seqno %08x\n", ++ be32_to_cpu(p_tcp_hdr->th_seq)); + + /* add 4 TCP pseudoheader fields */ + /* copy IP source and destination fields */ + memcpy(data_to_checksum, saved_ip_header + 12, 8); + +- if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) ++ DPRINTF("+++ C+ mode TSO calculating TCP checksum for " ++ "packet with %d bytes data\n", tcp_hlen + ++ chunk_size); ++ ++ if (tcp_send_offset) + { +- DPRINTF("+++ C+ mode calculating TCP checksum for " +- "packet with %d bytes data\n", ip_data_len); ++ memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size); ++ } + +- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; +- p_tcpip_hdr->zeros = 0; +- p_tcpip_hdr->ip_proto = IP_PROTO_TCP; +- p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ /* keep PUSH and FIN flags only for the last frame */ ++ if (!is_last_frame) ++ { ++ TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN); ++ } + +- tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12); ++ /* recalculate TCP checksum */ ++ ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; ++ p_tcpip_hdr->zeros = 0; ++ p_tcpip_hdr->ip_proto = IP_PROTO_TCP; ++ p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size); + +- p_tcp_hdr->th_sum = 0; ++ p_tcp_hdr->th_sum = 0; + +- int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); +- DPRINTF("+++ C+ mode TCP checksum %04x\n", +- tcp_checksum); ++ int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); ++ DPRINTF("+++ C+ mode TSO TCP checksum %04x\n", ++ tcp_checksum); + +- p_tcp_hdr->th_sum = tcp_checksum; +- } +- else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) +- { +- DPRINTF("+++ C+ mode calculating UDP checksum for " +- "packet with %d bytes data\n", ip_data_len); ++ p_tcp_hdr->th_sum = tcp_checksum; + +- ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum; +- p_udpip_hdr->zeros = 0; +- p_udpip_hdr->ip_proto = IP_PROTO_UDP; +- p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ /* restore IP header */ ++ memcpy(eth_payload_data, saved_ip_header, hlen); + +- udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12); ++ /* set IP data length and recalculate IP checksum */ ++ ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); + +- p_udp_hdr->uh_sum = 0; ++ /* increment IP id for subsequent frames */ ++ ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id)); + +- int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); +- DPRINTF("+++ C+ mode UDP checksum %04x\n", +- udp_checksum); ++ ip->ip_sum = 0; ++ ip->ip_sum = ip_checksum(eth_payload_data, hlen); ++ DPRINTF("+++ C+ mode TSO IP header len=%d " ++ "checksum=%04x\n", hlen, ip->ip_sum); + +- p_udp_hdr->uh_sum = udp_checksum; +- } ++ int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; ++ DPRINTF("+++ C+ mode TSO transferring packet size " ++ "%d\n", tso_send_size); ++ rtl8139_transfer_frame(s, saved_buffer, tso_send_size, ++ 0, (uint8_t *) dot1q_buffer); + +- /* restore IP header */ +- memcpy(eth_payload_data, saved_ip_header, hlen); ++ /* add transferred count to TCP sequence number */ ++ p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq)); ++ ++send_count; + } ++ ++ /* Stop sending this frame */ ++ saved_size = 0; ++ } ++ else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) ++ { ++ DPRINTF("+++ C+ mode need TCP or UDP checksum\n"); ++ ++ /* maximum IP header length is 60 bytes */ ++ uint8_t saved_ip_header[60]; ++ memcpy(saved_ip_header, eth_payload_data, hlen); ++ ++ uint8_t *data_to_checksum = eth_payload_data + hlen - 12; ++ // size_t data_to_checksum_len = eth_payload_len - hlen + 12; ++ ++ /* add 4 TCP pseudoheader fields */ ++ /* copy IP source and destination fields */ ++ memcpy(data_to_checksum, saved_ip_header + 12, 8); ++ ++ if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) ++ { ++ DPRINTF("+++ C+ mode calculating TCP checksum for " ++ "packet with %d bytes data\n", ip_data_len); ++ ++ ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; ++ p_tcpip_hdr->zeros = 0; ++ p_tcpip_hdr->ip_proto = IP_PROTO_TCP; ++ p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ ++ tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12); ++ ++ p_tcp_hdr->th_sum = 0; ++ ++ int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); ++ DPRINTF("+++ C+ mode TCP checksum %04x\n", ++ tcp_checksum); ++ ++ p_tcp_hdr->th_sum = tcp_checksum; ++ } ++ else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) ++ { ++ DPRINTF("+++ C+ mode calculating UDP checksum for " ++ "packet with %d bytes data\n", ip_data_len); ++ ++ ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum; ++ p_udpip_hdr->zeros = 0; ++ p_udpip_hdr->ip_proto = IP_PROTO_UDP; ++ p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ ++ udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12); ++ ++ p_udp_hdr->uh_sum = 0; ++ ++ int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); ++ DPRINTF("+++ C+ mode UDP checksum %04x\n", ++ udp_checksum); ++ ++ p_udp_hdr->uh_sum = udp_checksum; ++ } ++ ++ /* restore IP header */ ++ memcpy(eth_payload_data, saved_ip_header, hlen); + } + } + +-- +2.1.4 + diff --git a/sysutils/xen-tools/files/xsa140-qemuu-unstable-3.patch b/sysutils/xen-tools/files/xsa140-qemuu-unstable-3.patch new file mode 100644 index 000000000000..5676f4653284 --- /dev/null +++ b/sysutils/xen-tools/files/xsa140-qemuu-unstable-3.patch @@ -0,0 +1,39 @@ +From 043d28507ef7c5fdc34866f5e3b27a72bd0cd072 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi <stefanha@redhat.com> +Date: Wed, 15 Jul 2015 18:17:00 +0100 +Subject: [PATCH 3/7] rtl8139: skip offload on short Ethernet/IP header + +Transmit offload features access Ethernet and IP headers the packet. If +the packet is too short we must not attempt to access header fields: + + int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12)); + ... + eth_payload_data = saved_buffer + ETH_HLEN; + ... + ip = (ip_header*)eth_payload_data; + if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { + +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> +--- + hw/net/rtl8139.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index 2f12d42..d377b6b 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2164,6 +2164,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + { + DPRINTF("+++ C+ mode offloaded task checksum\n"); + ++ /* Large enough for Ethernet and IP headers? */ ++ if (saved_size < ETH_HLEN + sizeof(ip_header)) { ++ goto skip_offload; ++ } ++ + /* ip packet header */ + ip_header *ip = NULL; + int hlen = 0; +-- +2.1.4 + diff --git a/sysutils/xen-tools/files/xsa140-qemuu-unstable-4.patch b/sysutils/xen-tools/files/xsa140-qemuu-unstable-4.patch new file mode 100644 index 000000000000..495d8d616b26 --- /dev/null +++ b/sysutils/xen-tools/files/xsa140-qemuu-unstable-4.patch @@ -0,0 +1,53 @@ +From 5a75d242fe019d05b46ef9bc330a6892525c84a7 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi <stefanha@redhat.com> +Date: Wed, 15 Jul 2015 18:17:01 +0100 +Subject: [PATCH 4/7] rtl8139: check IP Header Length field + +The IP Header Length field was only checked in the IP checksum case, but +is used in other cases too. + +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> +--- + hw/net/rtl8139.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index d377b6b..cd5ac05 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2200,6 +2200,10 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + } + + hlen = IP_HEADER_LENGTH(ip); ++ if (hlen < sizeof(ip_header) || hlen > eth_payload_len) { ++ goto skip_offload; ++ } ++ + ip_protocol = ip->ip_p; + ip_data_len = be16_to_cpu(ip->ip_len) - hlen; + +@@ -2207,17 +2211,10 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + { + DPRINTF("+++ C+ mode need IP checksum\n"); + +- if (hlen<sizeof(ip_header) || hlen>eth_payload_len) {/* min header length */ +- /* bad packet header len */ +- /* or packet too short */ +- } +- else +- { +- ip->ip_sum = 0; +- ip->ip_sum = ip_checksum(ip, hlen); +- DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", +- hlen, ip->ip_sum); +- } ++ ip->ip_sum = 0; ++ ip->ip_sum = ip_checksum(ip, hlen); ++ DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", ++ hlen, ip->ip_sum); + } + + if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) +-- +2.1.4 + diff --git a/sysutils/xen-tools/files/xsa140-qemuu-unstable-5.patch b/sysutils/xen-tools/files/xsa140-qemuu-unstable-5.patch new file mode 100644 index 000000000000..e633ea6b2e0b --- /dev/null +++ b/sysutils/xen-tools/files/xsa140-qemuu-unstable-5.patch @@ -0,0 +1,34 @@ +From 6c79ea275d72bc1fd88bdcf1e7d231b2c9c865de Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi <stefanha@redhat.com> +Date: Wed, 15 Jul 2015 18:17:02 +0100 +Subject: [PATCH 5/7] rtl8139: check IP Total Length field + +The IP Total Length field includes the IP header and data. Make sure it +is valid and does not exceed the Ethernet payload size. + +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> +--- + hw/net/rtl8139.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index cd5ac05..ed2b23b 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2205,7 +2205,12 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + } + + ip_protocol = ip->ip_p; +- ip_data_len = be16_to_cpu(ip->ip_len) - hlen; ++ ++ ip_data_len = be16_to_cpu(ip->ip_len); ++ if (ip_data_len < hlen || ip_data_len > eth_payload_len) { ++ goto skip_offload; ++ } ++ ip_data_len -= hlen; + + if (txdw0 & CP_TX_IPCS) + { +-- +2.1.4 + diff --git a/sysutils/xen-tools/files/xsa140-qemuu-unstable-6.patch b/sysutils/xen-tools/files/xsa140-qemuu-unstable-6.patch new file mode 100644 index 000000000000..dd716a6d6dc7 --- /dev/null +++ b/sysutils/xen-tools/files/xsa140-qemuu-unstable-6.patch @@ -0,0 +1,35 @@ +From 30aa7be430e7c982e9163f3bcc745d3aa57b6aa4 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi <stefanha@redhat.com> +Date: Wed, 15 Jul 2015 18:17:03 +0100 +Subject: [PATCH 6/7] rtl8139: skip offload on short TCP header + +TCP Large Segment Offload accesses the TCP header in the packet. If the +packet is too short we must not attempt to access header fields: + + tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); + int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); + +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> +--- + hw/net/rtl8139.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index ed2b23b..c8f0df9 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2224,6 +2224,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + + if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) + { ++ /* Large enough for the TCP header? */ ++ if (ip_data_len < sizeof(tcp_header)) { ++ goto skip_offload; ++ } ++ + int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; + + DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " +-- +2.1.4 + diff --git a/sysutils/xen-tools/files/xsa140-qemuu-unstable-7.patch b/sysutils/xen-tools/files/xsa140-qemuu-unstable-7.patch new file mode 100644 index 000000000000..4c0ad7993545 --- /dev/null +++ b/sysutils/xen-tools/files/xsa140-qemuu-unstable-7.patch @@ -0,0 +1,32 @@ +From 9a084807bf6ca7c16d997a236d304111894a6539 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi <stefanha@redhat.com> +Date: Wed, 15 Jul 2015 18:17:04 +0100 +Subject: [PATCH 7/7] rtl8139: check TCP Data Offset field + +The TCP Data Offset field contains the length of the header. Make sure +it is valid and does not exceed the IP data length. + +Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> +--- + hw/net/rtl8139.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index c8f0df9..2df4a51 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2253,6 +2253,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + + int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); + ++ /* Invalid TCP data offset? */ ++ if (tcp_hlen < sizeof(tcp_header) || tcp_hlen > ip_data_len) { ++ goto skip_offload; ++ } ++ + /* ETH_MTU = ip header len + tcp header len + payload */ + int tcp_data_len = ip_data_len - tcp_hlen; + int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; +-- +2.1.4 + diff --git a/sysutils/xen-tools/pkg-plist b/sysutils/xen-tools/pkg-plist index e0b4463a5c8d..233db6b77f95 100644 --- a/sysutils/xen-tools/pkg-plist +++ b/sysutils/xen-tools/pkg-plist @@ -36,6 +36,7 @@ include/libxl_event.h include/libxl_json.h include/libxl_utils.h include/libxl_uuid.h +include/libxlutil.h include/xen/COPYING include/xen/arch-arm.h include/xen/arch-arm/hvm/save.h |