diff --git a/9pfs-local-Fix-possible-memory-leak-in-local_link.patch b/9pfs-local-Fix-possible-memory-leak-in-local_link.patch index f9491f18950937af2708fdd47553a152c400eed0..56b7acb14b023fe3d9f94e22ece7c995a73c3fa6 100644 --- a/9pfs-local-Fix-possible-memory-leak-in-local_link.patch +++ b/9pfs-local-Fix-possible-memory-leak-in-local_link.patch @@ -1,16 +1,30 @@ +From 841b8d099c462cd4282c4ced8c2a6512899fd8d9 Mon Sep 17 00:00:00 2001 +From: Jiajun Chen +Date: Mon, 20 Jan 2020 15:11:39 +0100 +Subject: [PATCH] 9pfs: local: Fix possible memory leak in local_link() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + There is a possible memory leak while local_link return -1 without free odirpath and oname. Reported-by: Euler Robot -Reviewed-by: Christian Schoenebeck Signed-off-by: Jaijun Chen Signed-off-by: Xiang Zheng +Reviewed-by: Christian Schoenebeck +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Greg Kurz +(cherry picked from commit 841b8d099c462cd4282c4ced8c2a6512899fd8d9) +--- + hw/9pfs/9p-local.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c -index 4708c0bd89..491b08aee8 100644 +index ca64139..d0592c3 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c -@@ -947,7 +947,7 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath, +@@ -947,7 +947,7 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath, if (ctx->export_flags & V9FS_SM_MAPPED_FILE && local_is_mapped_file_metadata(ctx, name)) { errno = EINVAL; @@ -19,3 +33,6 @@ index 4708c0bd89..491b08aee8 100644 } odirfd = local_opendir_nofollow(ctx, odirpath); +-- +1.8.3.1 + diff --git a/Revert-Enable-build-and-install-of-our-rST-docs.patch b/Revert-Enable-build-and-install-of-our-rST-docs.patch deleted file mode 100644 index e357273e1015d55a8849a53abec1c520c14e6b51..0000000000000000000000000000000000000000 --- a/Revert-Enable-build-and-install-of-our-rST-docs.patch +++ /dev/null @@ -1,1306 +0,0 @@ -From 4ed2ab47ab39de39f9753074b79303638dac020d Mon Sep 17 00:00:00 2001 -From: zhanghailiang -Date: Wed, 17 Jul 2019 09:51:03 +0800 -Subject: [PATCH] Revert "Enable build and install of our rST docs" - ---- - .gitignore | 1 - - MAINTAINERS | 6 - - Makefile | 88 +++--------- - configure | 15 +- - docs/conf.py | 216 ----------------------------- - docs/cpu-hotplug.rst | 2 +- - docs/devel/conf.py | 15 -- - docs/devel/index.rst | 22 --- - docs/devel/memory.rst | 363 ------------------------------------------------- - docs/devel/memory.txt | 351 +++++++++++++++++++++++++++++++++++++++++++++++ - docs/index.rst | 15 -- - docs/interop/conf.py | 15 -- - docs/interop/index.rst | 18 --- - 13 files changed, 374 insertions(+), 753 deletions(-) - delete mode 100644 docs/conf.py - delete mode 100644 docs/devel/conf.py - delete mode 100644 docs/devel/index.rst - delete mode 100644 docs/devel/memory.rst - create mode 100644 docs/devel/memory.txt - delete mode 100644 docs/index.rst - delete mode 100644 docs/interop/conf.py - delete mode 100644 docs/interop/index.rst - -diff --git a/.gitignore b/.gitignore -index 8f78221..7385d5c 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -1,4 +1,3 @@ --/.doctrees - /config-devices.* - /config-all-devices.* - /config-all-disas.* -diff --git a/MAINTAINERS b/MAINTAINERS -index 56139ac..a162586 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -2586,9 +2586,3 @@ GIT submodules - M: Daniel P. Berrange - S: Odd Fixes - F: scripts/git-submodule.sh -- --Sphinx documentation configuration and build machinery --M: Peter Maydell --S: Maintained --F: docs/conf.py --F: docs/*/conf.py -diff --git a/Makefile b/Makefile -index 04a0d45..d1e465f 100644 ---- a/Makefile -+++ b/Makefile -@@ -87,20 +87,6 @@ endif - - include $(SRC_PATH)/rules.mak - --# Create QEMU_PKGVERSION and FULL_VERSION strings --# If PKGVERSION is set, use that; otherwise get version and -dirty status from git --QEMU_PKGVERSION := $(if $(PKGVERSION),$(PKGVERSION),$(shell \ -- cd $(SRC_PATH); \ -- if test -e .git; then \ -- git describe --match 'v*' 2>/dev/null | tr -d '\n'; \ -- if ! git diff-index --quiet HEAD &>/dev/null; then \ -- echo "-dirty"; \ -- fi; \ -- fi)) -- --# Either "version (pkgversion)", or just "version" if pkgversion not set --FULL_VERSION := $(if $(QEMU_PKGVERSION),$(VERSION) ($(QEMU_PKGVERSION)),$(VERSION)) -- - GENERATED_FILES = qemu-version.h config-host.h qemu-options.def - - GENERATED_QAPI_FILES = qapi/qapi-builtin-types.h qapi/qapi-builtin-types.c -@@ -419,12 +405,27 @@ dummy := $(call unnest-vars,, \ - - include $(SRC_PATH)/tests/Makefile.include - --all: $(DOCS) $(if $(BUILD_DOCS),sphinxdocs) $(TOOLS) $(HELPERS-y) recurse-all modules -+all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules - - qemu-version.h: FORCE - $(call quiet-command, \ -- (printf '#define QEMU_PKGVERSION "$(QEMU_PKGVERSION)"\n'; \ -- printf '#define QEMU_FULL_VERSION "$(FULL_VERSION)"\n'; \ -+ (cd $(SRC_PATH); \ -+ if test -n "$(PKGVERSION)"; then \ -+ pkgvers="$(PKGVERSION)"; \ -+ else \ -+ if test -d .git; then \ -+ pkgvers=$$(git describe --match 'v*' 2>/dev/null | tr -d '\n');\ -+ if ! git diff-index --quiet HEAD &>/dev/null; then \ -+ pkgvers="$${pkgvers}-dirty"; \ -+ fi; \ -+ fi; \ -+ fi; \ -+ printf "#define QEMU_PKGVERSION \"$${pkgvers}\"\n"; \ -+ if test -n "$${pkgvers}"; then \ -+ printf '#define QEMU_FULL_VERSION QEMU_VERSION " (" QEMU_PKGVERSION ")"\n'; \ -+ else \ -+ printf '#define QEMU_FULL_VERSION QEMU_VERSION\n'; \ -+ fi; \ - ) > $@.tmp) - $(call quiet-command, if ! cmp -s $@ $@.tmp; then \ - mv $@.tmp $@; \ -@@ -656,22 +657,6 @@ dist: qemu-$(VERSION).tar.bz2 - qemu-%.tar.bz2: - $(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst qemu-%.tar.bz2,%,$@)" - --# Sphinx does not allow building manuals into the same directory as --# the source files, so if we're doing an in-tree QEMU build we must --# build the manuals into a subdirectory (and then install them from --# there for 'make install'). For an out-of-tree build we can just --# use the docs/ subdirectory in the build tree as normal. --ifeq ($(realpath $(SRC_PATH)),$(realpath .)) --MANUAL_BUILDDIR := docs/built --else --MANUAL_BUILDDIR := docs --endif -- --define clean-manual = --rm -rf $(MANUAL_BUILDDIR)/$1/_static --rm -f $(MANUAL_BUILDDIR)/$1/objects.inv $(MANUAL_BUILDDIR)/$1/searchindex.js $(MANUAL_BUILDDIR)/$1/*.html --endef -- - distclean: clean - rm -f config-host.mak config-host.h* config-host.ld $(DOCS) qemu-options.texi qemu-img-cmds.texi qemu-monitor.texi qemu-monitor-info.texi - rm -f config-all-devices.mak config-all-disas.mak config.status -@@ -692,9 +677,6 @@ distclean: clean - rm -f docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html - rm -f docs/qemu-block-drivers.7 - rm -f docs/qemu-cpu-models.7 -- rm -rf .doctrees -- $(call clean-manual,devel) -- $(call clean-manual,interop) - for d in $(TARGET_DIRS); do \ - rm -rf $$d || exit 1 ; \ - done -@@ -728,20 +710,7 @@ else - BLOBS= - endif - --# Note that we manually filter-out the non-Sphinx documentation which --# is currently built into the docs/interop directory in the build tree. --define install-manual = --for d in $$(cd $(MANUAL_BUILDDIR) && find $1 -type d); do $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)/$$d"; done --for f in $$(cd $(MANUAL_BUILDDIR) && find $1 -type f -a '!' '(' -name 'qemu-*-qapi.*' -o -name 'qemu-*-ref.*' ')' ); do $(INSTALL_DATA) "$(MANUAL_BUILDDIR)/$$f" "$(DESTDIR)$(qemu_docdir)/$$f"; done --endef -- --# Note that we deliberately do not install the "devel" manual: it is --# for QEMU developers, and not interesting to our users. --.PHONY: install-sphinxdocs --install-sphinxdocs: sphinxdocs -- $(call install-manual,interop) -- --install-doc: $(DOCS) install-sphinxdocs -+install-doc: $(DOCS) - $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)" - $(INSTALL_DATA) qemu-doc.html "$(DESTDIR)$(qemu_docdir)" - $(INSTALL_DATA) qemu-doc.txt "$(DESTDIR)$(qemu_docdir)" -@@ -892,23 +861,6 @@ docs/version.texi: $(SRC_PATH)/VERSION - %.pdf: %.texi docs/version.texi - $(call quiet-command,texi2pdf $(TEXI2PDFFLAGS) $< -o $@,"GEN","$@") - --# Sphinx builds all its documentation at once in one invocation --# and handles "don't rebuild things unless necessary" itself. --# The '.doctrees' files are cached information to speed this up. --.PHONY: sphinxdocs --sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html $(MANUAL_BUILDDIR)/interop/index.html -- --# Canned command to build a single manual --build-manual = $(call quiet-command,sphinx-build $(if $(V),,-q) -b html -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1") --# We assume all RST files in the manual's directory are used in it --manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py -- --$(MANUAL_BUILDDIR)/devel/index.html: $(call manual-deps,devel) -- $(call build-manual,devel) -- --$(MANUAL_BUILDDIR)/interop/index.html: $(call manual-deps,interop) -- $(call build-manual,interop) -- - qemu-options.texi: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool - $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"GEN","$@") - -@@ -937,7 +889,7 @@ docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi - docs/qemu-cpu-models.7: docs/qemu-cpu-models.texi - scripts/qemu-trace-stap.1: scripts/qemu-trace-stap.texi - --html: qemu-doc.html docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html sphinxdocs -+html: qemu-doc.html docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html - info: qemu-doc.info docs/interop/qemu-qmp-ref.info docs/interop/qemu-ga-ref.info - pdf: qemu-doc.pdf docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf - txt: qemu-doc.txt docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt -diff --git a/configure b/configure -index 1c563a7..384a241 100755 ---- a/configure -+++ b/configure -@@ -4708,24 +4708,13 @@ if compile_prog "" "" ; then - syncfs=yes - fi - --# Check we have a new enough version of sphinx-build --has_sphinx_build() { -- # This is a bit awkward but works: create a trivial document and -- # try to run it with our configuration file (which enforces a -- # version requirement). This will fail if either -- # sphinx-build doesn't exist at all or if it is too old. -- mkdir -p "$TMPDIR1/sphinx" -- touch "$TMPDIR1/sphinx/index.rst" -- sphinx-build -c "$source_path/docs" -b html "$TMPDIR1/sphinx" "$TMPDIR1/sphinx/out" >/dev/null 2>&1 --} -- - # Check if tools are available to build documentation. - if test "$docs" != "no" ; then -- if has makeinfo && has pod2man && has_sphinx_build; then -+ if has makeinfo && has pod2man; then - docs=yes - else - if test "$docs" = "yes" ; then -- feature_not_found "docs" "Install texinfo, Perl/perl-podlators and python-sphinx" -+ feature_not_found "docs" "Install texinfo and Perl/perl-podlators" - fi - docs=no - fi -diff --git a/docs/conf.py b/docs/conf.py -deleted file mode 100644 -index befbcc6..0000000 ---- a/docs/conf.py -+++ /dev/null -@@ -1,216 +0,0 @@ --# -*- coding: utf-8 -*- --# --# QEMU documentation build configuration file, created by --# sphinx-quickstart on Thu Jan 31 16:40:14 2019. --# --# This config file can be used in one of two ways: --# (1) as a common config file which is included by the conf.py --# for each of QEMU's manuals: in this case sphinx-build is run multiple --# times, once per subdirectory. --# (2) as a top level conf file which will result in building all --# the manuals into a single document: in this case sphinx-build is --# run once, on the top-level docs directory. --# --# QEMU's makefiles take option (1), which allows us to install --# only the ones the user cares about (in particular we don't want --# to ship the 'devel' manual to end-users). --# Third-party sites such as readthedocs.org will take option (2). --# --# --# This file is execfile()d with the current directory set to its --# containing dir. --# --# Note that not all possible configuration values are present in this --# autogenerated file. --# --# All configuration values have a default; values that are commented out --# serve to show the default. -- --import os --import sys -- --# The per-manual conf.py will set qemu_docdir for a single-manual build; --# otherwise set it here if this is an entire-manual-set build. --# This is always the absolute path of the docs/ directory in the source tree. --try: -- qemu_docdir --except NameError: -- qemu_docdir = os.path.abspath(".") -- --# If extensions (or modules to document with autodoc) are in another directory, --# add these directories to sys.path here. If the directory is relative to the --# documentation root, use an absolute path starting from qemu_docdir. --# --# sys.path.insert(0, os.path.join(qemu_docdir, "my_subdir")) -- -- --# -- General configuration ------------------------------------------------ -- --# If your documentation needs a minimal Sphinx version, state it here. --# --# 1.3 is where the 'alabaster' theme was shipped with Sphinx. --needs_sphinx = '1.3' -- --# Add any Sphinx extension module names here, as strings. They can be --# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom --# ones. --extensions = [] -- --# Add any paths that contain templates here, relative to this directory. --templates_path = ['_templates'] -- --# The suffix(es) of source filenames. --# You can specify multiple suffix as a list of string: --# --# source_suffix = ['.rst', '.md'] --source_suffix = '.rst' -- --# The master toctree document. --master_doc = 'index' -- --# General information about the project. --project = u'QEMU' --copyright = u'2019, The QEMU Project Developers' --author = u'The QEMU Project Developers' -- --# The version info for the project you're documenting, acts as replacement for --# |version| and |release|, also used in various other places throughout the --# built documents. -- --# Extract this information from the VERSION file, for the benefit of --# standalone Sphinx runs as used by readthedocs.org. Builds run from --# the Makefile will pass version and release on the sphinx-build --# command line, which override this. --try: -- extracted_version = None -- with open(os.path.join(qemu_docdir, '../VERSION')) as f: -- extracted_version = f.readline().strip() --except: -- pass --finally: -- if extracted_version: -- version = release = extracted_version -- else: -- version = release = "unknown version" -- --# The language for content autogenerated by Sphinx. Refer to documentation --# for a list of supported languages. --# --# This is also used if you do content translation via gettext catalogs. --# Usually you set "language" from the command line for these cases. --language = None -- --# List of patterns, relative to source directory, that match files and --# directories to ignore when looking for source files. --# This patterns also effect to html_static_path and html_extra_path --exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] -- --# The name of the Pygments (syntax highlighting) style to use. --pygments_style = 'sphinx' -- --# If true, `todo` and `todoList` produce output, else they produce nothing. --todo_include_todos = False -- --# Sphinx defaults to warning about use of :option: for options not defined --# with "option::" in the document being processed. Turn that off. --suppress_warnings = ["ref.option"] -- --# -- Options for HTML output ---------------------------------------------- -- --# The theme to use for HTML and HTML Help pages. See the documentation for --# a list of builtin themes. --# --html_theme = 'alabaster' -- --# Theme options are theme-specific and customize the look and feel of a theme --# further. For a list of options available for each theme, see the --# documentation. --# We initialize this to empty here, so the per-manual conf.py can just --# add individual key/value entries. --html_theme_options = { --} -- --# Add any paths that contain custom static files (such as style sheets) here, --# relative to this directory. They are copied after the builtin static files, --# so a file named "default.css" will overwrite the builtin "default.css". --# QEMU doesn't yet have any static files, so comment this out so we don't --# get a warning about a missing directory. --# If we do ever add this then it would probably be better to call the --# subdirectory sphinx_static, as the Linux kernel does. --# html_static_path = ['_static'] -- --# Custom sidebar templates, must be a dictionary that maps document names --# to template names. --# --# This is required for the alabaster theme --# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars --html_sidebars = { -- '**': [ -- 'about.html', -- 'navigation.html', -- 'searchbox.html', -- ] --} -- --# Don't copy the rST source files to the HTML output directory, --# and don't put links to the sources into the output HTML. --html_copy_source = False -- --# -- Options for HTMLHelp output ------------------------------------------ -- --# Output file base name for HTML help builder. --htmlhelp_basename = 'QEMUdoc' -- -- --# -- Options for LaTeX output --------------------------------------------- -- --latex_elements = { -- # The paper size ('letterpaper' or 'a4paper'). -- # -- # 'papersize': 'letterpaper', -- -- # The font size ('10pt', '11pt' or '12pt'). -- # -- # 'pointsize': '10pt', -- -- # Additional stuff for the LaTeX preamble. -- # -- # 'preamble': '', -- -- # Latex figure (float) alignment -- # -- # 'figure_align': 'htbp', --} -- --# Grouping the document tree into LaTeX files. List of tuples --# (source start file, target name, title, --# author, documentclass [howto, manual, or own class]). --latex_documents = [ -- (master_doc, 'QEMU.tex', u'QEMU Documentation', -- u'The QEMU Project Developers', 'manual'), --] -- -- --# -- Options for manual page output --------------------------------------- -- --# One entry per manual page. List of tuples --# (source start file, name, description, authors, manual section). --man_pages = [ -- (master_doc, 'qemu', u'QEMU Documentation', -- [author], 1) --] -- -- --# -- Options for Texinfo output ------------------------------------------- -- --# Grouping the document tree into Texinfo files. List of tuples --# (source start file, target name, title, author, --# dir menu entry, description, category) --texinfo_documents = [ -- (master_doc, 'QEMU', u'QEMU Documentation', -- author, 'QEMU', 'One line description of project.', -- 'Miscellaneous'), --] -- -- -- -diff --git a/docs/cpu-hotplug.rst b/docs/cpu-hotplug.rst -index d0b0640..cfeb79f 100644 ---- a/docs/cpu-hotplug.rst -+++ b/docs/cpu-hotplug.rst -@@ -60,7 +60,7 @@ vCPU hotplug - hot-plugged (no "qom-path" member). From its output in step (3), we - can see that ``IvyBridge-IBRS-x86_64-cpu`` is present in socket 0, - while hot-plugging a CPU into socket 1 requires passing the listed -- properties to QMP ``device_add``:: -+ properties to QMP ``device_add``: - - (QEMU) device_add id=cpu-2 driver=IvyBridge-IBRS-x86_64-cpu socket-id=1 core-id=0 thread-id=0 - { -diff --git a/docs/devel/conf.py b/docs/devel/conf.py -deleted file mode 100644 -index 7441f87..0000000 ---- a/docs/devel/conf.py -+++ /dev/null -@@ -1,15 +0,0 @@ --# -*- coding: utf-8 -*- --# --# QEMU documentation build configuration file for the 'devel' manual. --# --# This includes the top level conf file and then makes any necessary tweaks. --import sys --import os -- --qemu_docdir = os.path.abspath("..") --parent_config = os.path.join(qemu_docdir, "conf.py") --exec(compile(open(parent_config, "rb").read(), parent_config, 'exec')) -- --# This slightly misuses the 'description', but is the best way to get --# the manual title to appear in the sidebar. --html_theme_options['description'] = u'Developer''s Guide' -diff --git a/docs/devel/index.rst b/docs/devel/index.rst -deleted file mode 100644 -index ebbab63..0000000 ---- a/docs/devel/index.rst -+++ /dev/null -@@ -1,22 +0,0 @@ --.. This is the top level page for the 'devel' manual. -- -- --QEMU Developer's Guide --====================== -- --This manual documents various parts of the internals of QEMU. --You only need to read it if you are interested in reading or --modifying QEMU's source code. -- --Contents: -- --.. toctree:: -- :maxdepth: 2 -- -- kconfig -- loads-stores -- memory -- migration -- stable-process -- testing -- decodetree -diff --git a/docs/devel/memory.rst b/docs/devel/memory.rst -deleted file mode 100644 -index b6a4c37..0000000 ---- a/docs/devel/memory.rst -+++ /dev/null -@@ -1,363 +0,0 @@ --============== --The memory API --============== -- --The memory API models the memory and I/O buses and controllers of a QEMU --machine. It attempts to allow modelling of: -- --- ordinary RAM --- memory-mapped I/O (MMIO) --- memory controllers that can dynamically reroute physical memory regions -- to different destinations -- --The memory model provides support for -- --- tracking RAM changes by the guest --- setting up coalesced memory for kvm --- setting up ioeventfd regions for kvm -- --Memory is modelled as an acyclic graph of MemoryRegion objects. Sinks --(leaves) are RAM and MMIO regions, while other nodes represent --buses, memory controllers, and memory regions that have been rerouted. -- --In addition to MemoryRegion objects, the memory API provides AddressSpace --objects for every root and possibly for intermediate MemoryRegions too. --These represent memory as seen from the CPU or a device's viewpoint. -- --Types of regions ------------------ -- --There are multiple types of memory regions (all represented by a single C type --MemoryRegion): -- --- RAM: a RAM region is simply a range of host memory that can be made available -- to the guest. -- You typically initialize these with memory_region_init_ram(). Some special -- purposes require the variants memory_region_init_resizeable_ram(), -- memory_region_init_ram_from_file(), or memory_region_init_ram_ptr(). -- --- MMIO: a range of guest memory that is implemented by host callbacks; -- each read or write causes a callback to be called on the host. -- You initialize these with memory_region_init_io(), passing it a -- MemoryRegionOps structure describing the callbacks. -- --- ROM: a ROM memory region works like RAM for reads (directly accessing -- a region of host memory), and forbids writes. You initialize these with -- memory_region_init_rom(). -- --- ROM device: a ROM device memory region works like RAM for reads -- (directly accessing a region of host memory), but like MMIO for -- writes (invoking a callback). You initialize these with -- memory_region_init_rom_device(). -- --- IOMMU region: an IOMMU region translates addresses of accesses made to it -- and forwards them to some other target memory region. As the name suggests, -- these are only needed for modelling an IOMMU, not for simple devices. -- You initialize these with memory_region_init_iommu(). -- --- container: a container simply includes other memory regions, each at -- a different offset. Containers are useful for grouping several regions -- into one unit. For example, a PCI BAR may be composed of a RAM region -- and an MMIO region. -- -- A container's subregions are usually non-overlapping. In some cases it is -- useful to have overlapping regions; for example a memory controller that -- can overlay a subregion of RAM with MMIO or ROM, or a PCI controller -- that does not prevent card from claiming overlapping BARs. -- -- You initialize a pure container with memory_region_init(). -- --- alias: a subsection of another region. Aliases allow a region to be -- split apart into discontiguous regions. Examples of uses are memory banks -- used when the guest address space is smaller than the amount of RAM -- addressed, or a memory controller that splits main memory to expose a "PCI -- hole". Aliases may point to any type of region, including other aliases, -- but an alias may not point back to itself, directly or indirectly. -- You initialize these with memory_region_init_alias(). -- --- reservation region: a reservation region is primarily for debugging. -- It claims I/O space that is not supposed to be handled by QEMU itself. -- The typical use is to track parts of the address space which will be -- handled by the host kernel when KVM is enabled. You initialize these -- by passing a NULL callback parameter to memory_region_init_io(). -- --It is valid to add subregions to a region which is not a pure container --(that is, to an MMIO, RAM or ROM region). This means that the region --will act like a container, except that any addresses within the container's --region which are not claimed by any subregion are handled by the --container itself (ie by its MMIO callbacks or RAM backing). However --it is generally possible to achieve the same effect with a pure container --one of whose subregions is a low priority "background" region covering --the whole address range; this is often clearer and is preferred. --Subregions cannot be added to an alias region. -- --Migration ----------- -- --Where the memory region is backed by host memory (RAM, ROM and --ROM device memory region types), this host memory needs to be --copied to the destination on migration. These APIs which allocate --the host memory for you will also register the memory so it is --migrated: -- --- memory_region_init_ram() --- memory_region_init_rom() --- memory_region_init_rom_device() -- --For most devices and boards this is the correct thing. If you --have a special case where you need to manage the migration of --the backing memory yourself, you can call the functions: -- --- memory_region_init_ram_nomigrate() --- memory_region_init_rom_nomigrate() --- memory_region_init_rom_device_nomigrate() -- --which only initialize the MemoryRegion and leave handling --migration to the caller. -- --The functions: -- --- memory_region_init_resizeable_ram() --- memory_region_init_ram_from_file() --- memory_region_init_ram_from_fd() --- memory_region_init_ram_ptr() --- memory_region_init_ram_device_ptr() -- --are for special cases only, and so they do not automatically --register the backing memory for migration; the caller must --manage migration if necessary. -- --Region names -------------- -- --Regions are assigned names by the constructor. For most regions these are --only used for debugging purposes, but RAM regions also use the name to identify --live migration sections. This means that RAM region names need to have ABI --stability. -- --Region lifecycle ------------------ -- --A region is created by one of the memory_region_init*() functions and --attached to an object, which acts as its owner or parent. QEMU ensures --that the owner object remains alive as long as the region is visible to --the guest, or as long as the region is in use by a virtual CPU or another --device. For example, the owner object will not die between an --address_space_map operation and the corresponding address_space_unmap. -- --After creation, a region can be added to an address space or a --container with memory_region_add_subregion(), and removed using --memory_region_del_subregion(). -- --Various region attributes (read-only, dirty logging, coalesced mmio, --ioeventfd) can be changed during the region lifecycle. They take effect --as soon as the region is made visible. This can be immediately, later, --or never. -- --Destruction of a memory region happens automatically when the owner --object dies. -- --If however the memory region is part of a dynamically allocated data --structure, you should call object_unparent() to destroy the memory region --before the data structure is freed. For an example see VFIOMSIXInfo --and VFIOQuirk in hw/vfio/pci.c. -- --You must not destroy a memory region as long as it may be in use by a --device or CPU. In order to do this, as a general rule do not create or --destroy memory regions dynamically during a device's lifetime, and only --call object_unparent() in the memory region owner's instance_finalize --callback. The dynamically allocated data structure that contains the --memory region then should obviously be freed in the instance_finalize --callback as well. -- --If you break this rule, the following situation can happen: -- --- the memory region's owner had a reference taken via memory_region_ref -- (for example by address_space_map) -- --- the region is unparented, and has no owner anymore -- --- when address_space_unmap is called, the reference to the memory region's -- owner is leaked. -- -- --There is an exception to the above rule: it is okay to call --object_unparent at any time for an alias or a container region. It is --therefore also okay to create or destroy alias and container regions --dynamically during a device's lifetime. -- --This exceptional usage is valid because aliases and containers only help --QEMU building the guest's memory map; they are never accessed directly. --memory_region_ref and memory_region_unref are never called on aliases --or containers, and the above situation then cannot happen. Exploiting --this exception is rarely necessary, and therefore it is discouraged, --but nevertheless it is used in a few places. -- --For regions that "have no owner" (NULL is passed at creation time), the --machine object is actually used as the owner. Since instance_finalize is --never called for the machine object, you must never call object_unparent --on regions that have no owner, unless they are aliases or containers. -- -- --Overlapping regions and priority ---------------------------------- --Usually, regions may not overlap each other; a memory address decodes into --exactly one target. In some cases it is useful to allow regions to overlap, --and sometimes to control which of an overlapping regions is visible to the --guest. This is done with memory_region_add_subregion_overlap(), which --allows the region to overlap any other region in the same container, and --specifies a priority that allows the core to decide which of two regions at --the same address are visible (highest wins). --Priority values are signed, and the default value is zero. This means that --you can use memory_region_add_subregion_overlap() both to specify a region --that must sit 'above' any others (with a positive priority) and also a --background region that sits 'below' others (with a negative priority). -- --If the higher priority region in an overlap is a container or alias, then --the lower priority region will appear in any "holes" that the higher priority --region has left by not mapping subregions to that area of its address range. --(This applies recursively -- if the subregions are themselves containers or --aliases that leave holes then the lower priority region will appear in these --holes too.) -- --For example, suppose we have a container A of size 0x8000 with two subregions --B and C. B is a container mapped at 0x2000, size 0x4000, priority 2; C is --an MMIO region mapped at 0x0, size 0x6000, priority 1. B currently has two --of its own subregions: D of size 0x1000 at offset 0 and E of size 0x1000 at --offset 0x2000. As a diagram:: -- -- 0 1000 2000 3000 4000 5000 6000 7000 8000 -- |------|------|------|------|------|------|------|------| -- A: [ ] -- C: [CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC] -- B: [ ] -- D: [DDDDD] -- E: [EEEEE] -- --The regions that will be seen within this address range then are:: -- -- [CCCCCCCCCCCC][DDDDD][CCCCC][EEEEE][CCCCC] -- --Since B has higher priority than C, its subregions appear in the flat map --even where they overlap with C. In ranges where B has not mapped anything --C's region appears. -- --If B had provided its own MMIO operations (ie it was not a pure container) --then these would be used for any addresses in its range not handled by --D or E, and the result would be:: -- -- [CCCCCCCCCCCC][DDDDD][BBBBB][EEEEE][BBBBB] -- --Priority values are local to a container, because the priorities of two --regions are only compared when they are both children of the same container. --This means that the device in charge of the container (typically modelling --a bus or a memory controller) can use them to manage the interaction of --its child regions without any side effects on other parts of the system. --In the example above, the priorities of D and E are unimportant because --they do not overlap each other. It is the relative priority of B and C --that causes D and E to appear on top of C: D and E's priorities are never --compared against the priority of C. -- --Visibility ------------ --The memory core uses the following rules to select a memory region when the --guest accesses an address: -- --- all direct subregions of the root region are matched against the address, in -- descending priority order -- -- - if the address lies outside the region offset/size, the subregion is -- discarded -- - if the subregion is a leaf (RAM or MMIO), the search terminates, returning -- this leaf region -- - if the subregion is a container, the same algorithm is used within the -- subregion (after the address is adjusted by the subregion offset) -- - if the subregion is an alias, the search is continued at the alias target -- (after the address is adjusted by the subregion offset and alias offset) -- - if a recursive search within a container or alias subregion does not -- find a match (because of a "hole" in the container's coverage of its -- address range), then if this is a container with its own MMIO or RAM -- backing the search terminates, returning the container itself. Otherwise -- we continue with the next subregion in priority order -- --- if none of the subregions match the address then the search terminates -- with no match found -- --Example memory map -------------------- -- --:: -- -- system_memory: container@0-2^48-1 -- | -- +---- lomem: alias@0-0xdfffffff ---> #ram (0-0xdfffffff) -- | -- +---- himem: alias@0x100000000-0x11fffffff ---> #ram (0xe0000000-0xffffffff) -- | -- +---- vga-window: alias@0xa0000-0xbffff ---> #pci (0xa0000-0xbffff) -- | (prio 1) -- | -- +---- pci-hole: alias@0xe0000000-0xffffffff ---> #pci (0xe0000000-0xffffffff) -- -- pci (0-2^32-1) -- | -- +--- vga-area: container@0xa0000-0xbffff -- | | -- | +--- alias@0x00000-0x7fff ---> #vram (0x010000-0x017fff) -- | | -- | +--- alias@0x08000-0xffff ---> #vram (0x020000-0x027fff) -- | -- +---- vram: ram@0xe1000000-0xe1ffffff -- | -- +---- vga-mmio: mmio@0xe2000000-0xe200ffff -- -- ram: ram@0x00000000-0xffffffff -- --This is a (simplified) PC memory map. The 4GB RAM block is mapped into the --system address space via two aliases: "lomem" is a 1:1 mapping of the first --3.5GB; "himem" maps the last 0.5GB at address 4GB. This leaves 0.5GB for the --so-called PCI hole, that allows a 32-bit PCI bus to exist in a system with --4GB of memory. -- --The memory controller diverts addresses in the range 640K-768K to the PCI --address space. This is modelled using the "vga-window" alias, mapped at a --higher priority so it obscures the RAM at the same addresses. The vga window --can be removed by programming the memory controller; this is modelled by --removing the alias and exposing the RAM underneath. -- --The pci address space is not a direct child of the system address space, since --we only want parts of it to be visible (we accomplish this using aliases). --It has two subregions: vga-area models the legacy vga window and is occupied --by two 32K memory banks pointing at two sections of the framebuffer. --In addition the vram is mapped as a BAR at address e1000000, and an additional --BAR containing MMIO registers is mapped after it. -- --Note that if the guest maps a BAR outside the PCI hole, it would not be --visible as the pci-hole alias clips it to a 0.5GB range. -- --MMIO Operations ----------------- -- --MMIO regions are provided with ->read() and ->write() callbacks, --which are sufficient for most devices. Some devices change behaviour --based on the attributes used for the memory transaction, or need --to be able to respond that the access should provoke a bus error --rather than completing successfully; those devices can use the --->read_with_attrs() and ->write_with_attrs() callbacks instead. -- --In addition various constraints can be supplied to control how these --callbacks are called: -- --- .valid.min_access_size, .valid.max_access_size define the access sizes -- (in bytes) which the device accepts; accesses outside this range will -- have device and bus specific behaviour (ignored, or machine check) --- .valid.unaligned specifies that the *device being modelled* supports -- unaligned accesses; if false, unaligned accesses will invoke the -- appropriate bus or CPU specific behaviour. --- .impl.min_access_size, .impl.max_access_size define the access sizes -- (in bytes) supported by the *implementation*; other access sizes will be -- emulated using the ones available. For example a 4-byte write will be -- emulated using four 1-byte writes, if .impl.max_access_size = 1. --- .impl.unaligned specifies that the *implementation* supports unaligned -- accesses; if false, unaligned accesses will be emulated by two aligned -- accesses. -diff --git a/docs/devel/memory.txt b/docs/devel/memory.txt -new file mode 100644 -index 0000000..42577e1 ---- /dev/null -+++ b/docs/devel/memory.txt -@@ -0,0 +1,351 @@ -+The memory API -+============== -+ -+The memory API models the memory and I/O buses and controllers of a QEMU -+machine. It attempts to allow modelling of: -+ -+ - ordinary RAM -+ - memory-mapped I/O (MMIO) -+ - memory controllers that can dynamically reroute physical memory regions -+ to different destinations -+ -+The memory model provides support for -+ -+ - tracking RAM changes by the guest -+ - setting up coalesced memory for kvm -+ - setting up ioeventfd regions for kvm -+ -+Memory is modelled as an acyclic graph of MemoryRegion objects. Sinks -+(leaves) are RAM and MMIO regions, while other nodes represent -+buses, memory controllers, and memory regions that have been rerouted. -+ -+In addition to MemoryRegion objects, the memory API provides AddressSpace -+objects for every root and possibly for intermediate MemoryRegions too. -+These represent memory as seen from the CPU or a device's viewpoint. -+ -+Types of regions -+---------------- -+ -+There are multiple types of memory regions (all represented by a single C type -+MemoryRegion): -+ -+- RAM: a RAM region is simply a range of host memory that can be made available -+ to the guest. -+ You typically initialize these with memory_region_init_ram(). Some special -+ purposes require the variants memory_region_init_resizeable_ram(), -+ memory_region_init_ram_from_file(), or memory_region_init_ram_ptr(). -+ -+- MMIO: a range of guest memory that is implemented by host callbacks; -+ each read or write causes a callback to be called on the host. -+ You initialize these with memory_region_init_io(), passing it a -+ MemoryRegionOps structure describing the callbacks. -+ -+- ROM: a ROM memory region works like RAM for reads (directly accessing -+ a region of host memory), and forbids writes. You initialize these with -+ memory_region_init_rom(). -+ -+- ROM device: a ROM device memory region works like RAM for reads -+ (directly accessing a region of host memory), but like MMIO for -+ writes (invoking a callback). You initialize these with -+ memory_region_init_rom_device(). -+ -+- IOMMU region: an IOMMU region translates addresses of accesses made to it -+ and forwards them to some other target memory region. As the name suggests, -+ these are only needed for modelling an IOMMU, not for simple devices. -+ You initialize these with memory_region_init_iommu(). -+ -+- container: a container simply includes other memory regions, each at -+ a different offset. Containers are useful for grouping several regions -+ into one unit. For example, a PCI BAR may be composed of a RAM region -+ and an MMIO region. -+ -+ A container's subregions are usually non-overlapping. In some cases it is -+ useful to have overlapping regions; for example a memory controller that -+ can overlay a subregion of RAM with MMIO or ROM, or a PCI controller -+ that does not prevent card from claiming overlapping BARs. -+ -+ You initialize a pure container with memory_region_init(). -+ -+- alias: a subsection of another region. Aliases allow a region to be -+ split apart into discontiguous regions. Examples of uses are memory banks -+ used when the guest address space is smaller than the amount of RAM -+ addressed, or a memory controller that splits main memory to expose a "PCI -+ hole". Aliases may point to any type of region, including other aliases, -+ but an alias may not point back to itself, directly or indirectly. -+ You initialize these with memory_region_init_alias(). -+ -+- reservation region: a reservation region is primarily for debugging. -+ It claims I/O space that is not supposed to be handled by QEMU itself. -+ The typical use is to track parts of the address space which will be -+ handled by the host kernel when KVM is enabled. You initialize these -+ by passing a NULL callback parameter to memory_region_init_io(). -+ -+It is valid to add subregions to a region which is not a pure container -+(that is, to an MMIO, RAM or ROM region). This means that the region -+will act like a container, except that any addresses within the container's -+region which are not claimed by any subregion are handled by the -+container itself (ie by its MMIO callbacks or RAM backing). However -+it is generally possible to achieve the same effect with a pure container -+one of whose subregions is a low priority "background" region covering -+the whole address range; this is often clearer and is preferred. -+Subregions cannot be added to an alias region. -+ -+Migration -+--------- -+ -+Where the memory region is backed by host memory (RAM, ROM and -+ROM device memory region types), this host memory needs to be -+copied to the destination on migration. These APIs which allocate -+the host memory for you will also register the memory so it is -+migrated: -+ - memory_region_init_ram() -+ - memory_region_init_rom() -+ - memory_region_init_rom_device() -+ -+For most devices and boards this is the correct thing. If you -+have a special case where you need to manage the migration of -+the backing memory yourself, you can call the functions: -+ - memory_region_init_ram_nomigrate() -+ - memory_region_init_rom_nomigrate() -+ - memory_region_init_rom_device_nomigrate() -+which only initialize the MemoryRegion and leave handling -+migration to the caller. -+ -+The functions: -+ - memory_region_init_resizeable_ram() -+ - memory_region_init_ram_from_file() -+ - memory_region_init_ram_from_fd() -+ - memory_region_init_ram_ptr() -+ - memory_region_init_ram_device_ptr() -+are for special cases only, and so they do not automatically -+register the backing memory for migration; the caller must -+manage migration if necessary. -+ -+Region names -+------------ -+ -+Regions are assigned names by the constructor. For most regions these are -+only used for debugging purposes, but RAM regions also use the name to identify -+live migration sections. This means that RAM region names need to have ABI -+stability. -+ -+Region lifecycle -+---------------- -+ -+A region is created by one of the memory_region_init*() functions and -+attached to an object, which acts as its owner or parent. QEMU ensures -+that the owner object remains alive as long as the region is visible to -+the guest, or as long as the region is in use by a virtual CPU or another -+device. For example, the owner object will not die between an -+address_space_map operation and the corresponding address_space_unmap. -+ -+After creation, a region can be added to an address space or a -+container with memory_region_add_subregion(), and removed using -+memory_region_del_subregion(). -+ -+Various region attributes (read-only, dirty logging, coalesced mmio, -+ioeventfd) can be changed during the region lifecycle. They take effect -+as soon as the region is made visible. This can be immediately, later, -+or never. -+ -+Destruction of a memory region happens automatically when the owner -+object dies. -+ -+If however the memory region is part of a dynamically allocated data -+structure, you should call object_unparent() to destroy the memory region -+before the data structure is freed. For an example see VFIOMSIXInfo -+and VFIOQuirk in hw/vfio/pci.c. -+ -+You must not destroy a memory region as long as it may be in use by a -+device or CPU. In order to do this, as a general rule do not create or -+destroy memory regions dynamically during a device's lifetime, and only -+call object_unparent() in the memory region owner's instance_finalize -+callback. The dynamically allocated data structure that contains the -+memory region then should obviously be freed in the instance_finalize -+callback as well. -+ -+If you break this rule, the following situation can happen: -+ -+- the memory region's owner had a reference taken via memory_region_ref -+ (for example by address_space_map) -+ -+- the region is unparented, and has no owner anymore -+ -+- when address_space_unmap is called, the reference to the memory region's -+ owner is leaked. -+ -+ -+There is an exception to the above rule: it is okay to call -+object_unparent at any time for an alias or a container region. It is -+therefore also okay to create or destroy alias and container regions -+dynamically during a device's lifetime. -+ -+This exceptional usage is valid because aliases and containers only help -+QEMU building the guest's memory map; they are never accessed directly. -+memory_region_ref and memory_region_unref are never called on aliases -+or containers, and the above situation then cannot happen. Exploiting -+this exception is rarely necessary, and therefore it is discouraged, -+but nevertheless it is used in a few places. -+ -+For regions that "have no owner" (NULL is passed at creation time), the -+machine object is actually used as the owner. Since instance_finalize is -+never called for the machine object, you must never call object_unparent -+on regions that have no owner, unless they are aliases or containers. -+ -+ -+Overlapping regions and priority -+-------------------------------- -+Usually, regions may not overlap each other; a memory address decodes into -+exactly one target. In some cases it is useful to allow regions to overlap, -+and sometimes to control which of an overlapping regions is visible to the -+guest. This is done with memory_region_add_subregion_overlap(), which -+allows the region to overlap any other region in the same container, and -+specifies a priority that allows the core to decide which of two regions at -+the same address are visible (highest wins). -+Priority values are signed, and the default value is zero. This means that -+you can use memory_region_add_subregion_overlap() both to specify a region -+that must sit 'above' any others (with a positive priority) and also a -+background region that sits 'below' others (with a negative priority). -+ -+If the higher priority region in an overlap is a container or alias, then -+the lower priority region will appear in any "holes" that the higher priority -+region has left by not mapping subregions to that area of its address range. -+(This applies recursively -- if the subregions are themselves containers or -+aliases that leave holes then the lower priority region will appear in these -+holes too.) -+ -+For example, suppose we have a container A of size 0x8000 with two subregions -+B and C. B is a container mapped at 0x2000, size 0x4000, priority 2; C is -+an MMIO region mapped at 0x0, size 0x6000, priority 1. B currently has two -+of its own subregions: D of size 0x1000 at offset 0 and E of size 0x1000 at -+offset 0x2000. As a diagram: -+ -+ 0 1000 2000 3000 4000 5000 6000 7000 8000 -+ |------|------|------|------|------|------|------|------| -+ A: [ ] -+ C: [CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC] -+ B: [ ] -+ D: [DDDDD] -+ E: [EEEEE] -+ -+The regions that will be seen within this address range then are: -+ [CCCCCCCCCCCC][DDDDD][CCCCC][EEEEE][CCCCC] -+ -+Since B has higher priority than C, its subregions appear in the flat map -+even where they overlap with C. In ranges where B has not mapped anything -+C's region appears. -+ -+If B had provided its own MMIO operations (ie it was not a pure container) -+then these would be used for any addresses in its range not handled by -+D or E, and the result would be: -+ [CCCCCCCCCCCC][DDDDD][BBBBB][EEEEE][BBBBB] -+ -+Priority values are local to a container, because the priorities of two -+regions are only compared when they are both children of the same container. -+This means that the device in charge of the container (typically modelling -+a bus or a memory controller) can use them to manage the interaction of -+its child regions without any side effects on other parts of the system. -+In the example above, the priorities of D and E are unimportant because -+they do not overlap each other. It is the relative priority of B and C -+that causes D and E to appear on top of C: D and E's priorities are never -+compared against the priority of C. -+ -+Visibility -+---------- -+The memory core uses the following rules to select a memory region when the -+guest accesses an address: -+ -+- all direct subregions of the root region are matched against the address, in -+ descending priority order -+ - if the address lies outside the region offset/size, the subregion is -+ discarded -+ - if the subregion is a leaf (RAM or MMIO), the search terminates, returning -+ this leaf region -+ - if the subregion is a container, the same algorithm is used within the -+ subregion (after the address is adjusted by the subregion offset) -+ - if the subregion is an alias, the search is continued at the alias target -+ (after the address is adjusted by the subregion offset and alias offset) -+ - if a recursive search within a container or alias subregion does not -+ find a match (because of a "hole" in the container's coverage of its -+ address range), then if this is a container with its own MMIO or RAM -+ backing the search terminates, returning the container itself. Otherwise -+ we continue with the next subregion in priority order -+- if none of the subregions match the address then the search terminates -+ with no match found -+ -+Example memory map -+------------------ -+ -+system_memory: container@0-2^48-1 -+ | -+ +---- lomem: alias@0-0xdfffffff ---> #ram (0-0xdfffffff) -+ | -+ +---- himem: alias@0x100000000-0x11fffffff ---> #ram (0xe0000000-0xffffffff) -+ | -+ +---- vga-window: alias@0xa0000-0xbffff ---> #pci (0xa0000-0xbffff) -+ | (prio 1) -+ | -+ +---- pci-hole: alias@0xe0000000-0xffffffff ---> #pci (0xe0000000-0xffffffff) -+ -+pci (0-2^32-1) -+ | -+ +--- vga-area: container@0xa0000-0xbffff -+ | | -+ | +--- alias@0x00000-0x7fff ---> #vram (0x010000-0x017fff) -+ | | -+ | +--- alias@0x08000-0xffff ---> #vram (0x020000-0x027fff) -+ | -+ +---- vram: ram@0xe1000000-0xe1ffffff -+ | -+ +---- vga-mmio: mmio@0xe2000000-0xe200ffff -+ -+ram: ram@0x00000000-0xffffffff -+ -+This is a (simplified) PC memory map. The 4GB RAM block is mapped into the -+system address space via two aliases: "lomem" is a 1:1 mapping of the first -+3.5GB; "himem" maps the last 0.5GB at address 4GB. This leaves 0.5GB for the -+so-called PCI hole, that allows a 32-bit PCI bus to exist in a system with -+4GB of memory. -+ -+The memory controller diverts addresses in the range 640K-768K to the PCI -+address space. This is modelled using the "vga-window" alias, mapped at a -+higher priority so it obscures the RAM at the same addresses. The vga window -+can be removed by programming the memory controller; this is modelled by -+removing the alias and exposing the RAM underneath. -+ -+The pci address space is not a direct child of the system address space, since -+we only want parts of it to be visible (we accomplish this using aliases). -+It has two subregions: vga-area models the legacy vga window and is occupied -+by two 32K memory banks pointing at two sections of the framebuffer. -+In addition the vram is mapped as a BAR at address e1000000, and an additional -+BAR containing MMIO registers is mapped after it. -+ -+Note that if the guest maps a BAR outside the PCI hole, it would not be -+visible as the pci-hole alias clips it to a 0.5GB range. -+ -+MMIO Operations -+--------------- -+ -+MMIO regions are provided with ->read() and ->write() callbacks, -+which are sufficient for most devices. Some devices change behaviour -+based on the attributes used for the memory transaction, or need -+to be able to respond that the access should provoke a bus error -+rather than completing successfully; those devices can use the -+->read_with_attrs() and ->write_with_attrs() callbacks instead. -+ -+In addition various constraints can be supplied to control how these -+callbacks are called: -+ -+ - .valid.min_access_size, .valid.max_access_size define the access sizes -+ (in bytes) which the device accepts; accesses outside this range will -+ have device and bus specific behaviour (ignored, or machine check) -+ - .valid.unaligned specifies that the *device being modelled* supports -+ unaligned accesses; if false, unaligned accesses will invoke the -+ appropriate bus or CPU specific behaviour. -+ - .impl.min_access_size, .impl.max_access_size define the access sizes -+ (in bytes) supported by the *implementation*; other access sizes will be -+ emulated using the ones available. For example a 4-byte write will be -+ emulated using four 1-byte writes, if .impl.max_access_size = 1. -+ - .impl.unaligned specifies that the *implementation* supports unaligned -+ accesses; if false, unaligned accesses will be emulated by two aligned -+ accesses. -diff --git a/docs/index.rst b/docs/index.rst -deleted file mode 100644 -index 3690955..0000000 ---- a/docs/index.rst -+++ /dev/null -@@ -1,15 +0,0 @@ --.. QEMU documentation master file, created by -- sphinx-quickstart on Thu Jan 31 16:40:14 2019. -- You can adapt this file completely to your liking, but it should at least -- contain the root `toctree` directive. -- --Welcome to QEMU's documentation! --================================ -- --.. toctree:: -- :maxdepth: 2 -- :caption: Contents: -- -- interop/index -- devel/index -- -diff --git a/docs/interop/conf.py b/docs/interop/conf.py -deleted file mode 100644 -index cf3c69d..0000000 ---- a/docs/interop/conf.py -+++ /dev/null -@@ -1,15 +0,0 @@ --# -*- coding: utf-8 -*- --# --# QEMU documentation build configuration file for the 'interop' manual. --# --# This includes the top level conf file and then makes any necessary tweaks. --import sys --import os -- --qemu_docdir = os.path.abspath("..") --parent_config = os.path.join(qemu_docdir, "conf.py") --exec(compile(open(parent_config, "rb").read(), parent_config, 'exec')) -- --# This slightly misuses the 'description', but is the best way to get --# the manual title to appear in the sidebar. --html_theme_options['description'] = u'System Emulation Management and Interoperability Guide' -diff --git a/docs/interop/index.rst b/docs/interop/index.rst -deleted file mode 100644 -index 2df977d..0000000 ---- a/docs/interop/index.rst -+++ /dev/null -@@ -1,18 +0,0 @@ --.. This is the top level page for the 'interop' manual. -- -- --QEMU System Emulation Management and Interoperability Guide --=========================================================== -- --This manual contains documents and specifications that are useful --for making QEMU interoperate with other software. -- --Contents: -- --.. toctree:: -- :maxdepth: 2 -- -- bitmaps -- live-block-operations -- pr-helper -- --- -1.8.3.1 - diff --git a/block-Fix-AioContext-switch-for-bs-drv-NULL.patch b/block-Fix-AioContext-switch-for-bs-drv-NULL.patch deleted file mode 100644 index c1702d0287be4703ac46104d1d7acf28cb37cd47..0000000000000000000000000000000000000000 --- a/block-Fix-AioContext-switch-for-bs-drv-NULL.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 1bffe1ae7a7b707c3a14ea2ccd00d3609d3ce4d8 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Wed, 17 Apr 2019 17:15:25 +0200 -Subject: [PATCH] block: Fix AioContext switch for bs->drv == NULL - -Even for block nodes with bs->drv == NULL, we can't just ignore a -bdrv_set_aio_context() call. Leaving the node in its old context can -mean that it's still in an iothread context in bdrv_close_all() during -shutdown, resulting in an attempted unlock of the AioContext lock which -we don't hold. - -This is an example stack trace of a related crash: - - #0 0x00007ffff59da57f in raise () at /lib64/libc.so.6 - #1 0x00007ffff59c4895 in abort () at /lib64/libc.so.6 - #2 0x0000555555b97b1e in error_exit (err=, msg=msg@entry=0x555555d386d0 <__func__.19059> "qemu_mutex_unlock_impl") at util/qemu-thread-posix.c:36 - #3 0x0000555555b97f7f in qemu_mutex_unlock_impl (mutex=mutex@entry=0x5555568002f0, file=file@entry=0x555555d378df "util/async.c", line=line@entry=507) at util/qemu-thread-posix.c:97 - #4 0x0000555555b92f55 in aio_context_release (ctx=ctx@entry=0x555556800290) at util/async.c:507 - #5 0x0000555555b05cf8 in bdrv_prwv_co (child=child@entry=0x7fffc80012f0, offset=offset@entry=131072, qiov=qiov@entry=0x7fffffffd4f0, is_write=is_write@entry=true, flags=flags@entry=0) - at block/io.c:833 - #6 0x0000555555b060a9 in bdrv_pwritev (qiov=0x7fffffffd4f0, offset=131072, child=0x7fffc80012f0) at block/io.c:990 - #7 0x0000555555b060a9 in bdrv_pwrite (child=0x7fffc80012f0, offset=131072, buf=, bytes=) at block/io.c:990 - #8 0x0000555555ae172b in qcow2_cache_entry_flush (bs=bs@entry=0x555556810680, c=c@entry=0x5555568cc740, i=i@entry=0) at block/qcow2-cache.c:51 - #9 0x0000555555ae18dd in qcow2_cache_write (bs=bs@entry=0x555556810680, c=0x5555568cc740) at block/qcow2-cache.c:248 - #10 0x0000555555ae15de in qcow2_cache_flush (bs=0x555556810680, c=) at block/qcow2-cache.c:259 - #11 0x0000555555ae16b1 in qcow2_cache_flush_dependency (c=0x5555568a1700, c=0x5555568a1700, bs=0x555556810680) at block/qcow2-cache.c:194 - #12 0x0000555555ae16b1 in qcow2_cache_entry_flush (bs=bs@entry=0x555556810680, c=c@entry=0x5555568a1700, i=i@entry=0) at block/qcow2-cache.c:194 - #13 0x0000555555ae18dd in qcow2_cache_write (bs=bs@entry=0x555556810680, c=0x5555568a1700) at block/qcow2-cache.c:248 - #14 0x0000555555ae15de in qcow2_cache_flush (bs=bs@entry=0x555556810680, c=) at block/qcow2-cache.c:259 - #15 0x0000555555ad242c in qcow2_inactivate (bs=bs@entry=0x555556810680) at block/qcow2.c:2124 - #16 0x0000555555ad2590 in qcow2_close (bs=0x555556810680) at block/qcow2.c:2153 - #17 0x0000555555ab0c62 in bdrv_close (bs=0x555556810680) at block.c:3358 - #18 0x0000555555ab0c62 in bdrv_delete (bs=0x555556810680) at block.c:3542 - #19 0x0000555555ab0c62 in bdrv_unref (bs=0x555556810680) at block.c:4598 - #20 0x0000555555af4d72 in blk_remove_bs (blk=blk@entry=0x5555568103d0) at block/block-backend.c:785 - #21 0x0000555555af4dbb in blk_remove_all_bs () at block/block-backend.c:483 - #22 0x0000555555aae02f in bdrv_close_all () at block.c:3412 - #23 0x00005555557f9796 in main (argc=, argv=, envp=) at vl.c:4776 - -The reproducer I used is a qcow2 image on gluster volume, where the -virtual disk size (4 GB) is larger than the gluster volume size (64M), -so we can easily trigger an ENOSPC. This backend is assigned to a -virtio-blk device using an iothread, and then from the guest a -'dd if=/dev/zero of=/dev/vda bs=1G count=1' causes the VM to stop -because of an I/O error. qemu_gluster_co_flush_to_disk() sets -bs->drv = NULL on error, so when virtio-blk stops the dataplane, the -block nodes stay in the iothread AioContext. A 'quit' monitor command -issued from this paused state crashes the process. - -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1631227 -Cc: qemu-stable@nongnu.org -Signed-off-by: Kevin Wolf -Reviewed-by: Eric Blake -Reviewed-by: Max Reitz -Reviewed-by: Stefano Garzarella -(cherry-picked from commit 1bffe1ae7a7b707c3a14ea2ccd00d3609d3ce4d8) ---- - block.c | 12 ++---------- - 1 file changed, 2 insertions(+), 10 deletions(-) - -diff --git a/block.c b/block.c -index 16615bc876..9ae5c0ed2f 100644 ---- a/block.c -+++ b/block.c -@@ -5672,10 +5672,6 @@ void bdrv_detach_aio_context(BlockDriverState *bs) - BdrvAioNotifier *baf, *baf_tmp; - BdrvChild *child; - -- if (!bs->drv) { -- return; -- } -- - assert(!bs->walking_aio_notifiers); - bs->walking_aio_notifiers = true; - QLIST_FOREACH_SAFE(baf, &bs->aio_notifiers, list, baf_tmp) { -@@ -5690,7 +5686,7 @@ void bdrv_detach_aio_context(BlockDriverState *bs) - */ - bs->walking_aio_notifiers = false; - -- if (bs->drv->bdrv_detach_aio_context) { -+ if (bs->drv && bs->drv->bdrv_detach_aio_context) { - bs->drv->bdrv_detach_aio_context(bs); - } - QLIST_FOREACH(child, &bs->children, next) { -@@ -5709,10 +5705,6 @@ void bdrv_attach_aio_context(BlockDriverState *bs, - BdrvAioNotifier *ban, *ban_tmp; - BdrvChild *child; - -- if (!bs->drv) { -- return; -- } -- - if (bs->quiesce_counter) { - aio_disable_external(new_context); - } -@@ -5722,7 +5714,7 @@ void bdrv_attach_aio_context(BlockDriverState *bs, - QLIST_FOREACH(child, &bs->children, next) { - bdrv_attach_aio_context(child->bs, new_context); - } -- if (bs->drv->bdrv_attach_aio_context) { -+ if (bs->drv && bs->drv->bdrv_attach_aio_context) { - bs->drv->bdrv_attach_aio_context(bs, new_context); - } - --- -2.19.1 - diff --git a/block-create-Do-not-abort-if-a-block-driver-is-not-available.patch b/block-create-Do-not-abort-if-a-block-driver-is-not-available.patch deleted file mode 100644 index ef0a880e9ae3b75de51578bd9bce2bd6da846ccf..0000000000000000000000000000000000000000 --- a/block-create-Do-not-abort-if-a-block-driver-is-not-available.patch +++ /dev/null @@ -1,96 +0,0 @@ -From c24d971c130d889d4d001d2ae2cb02b9a34d51b6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 12 Sep 2019 00:08:49 +0200 -Subject: [PATCH] block/create: Do not abort if a block driver is not available -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The 'blockdev-create' QMP command was introduced as experimental -feature in commit b0292b851b8, using the assert() debug call. -It got promoted to 'stable' command in 3fb588a0f2c, but the -assert call was not removed. - -Some block drivers are optional, and bdrv_find_format() might -return a NULL value, triggering the assertion. - -Stable code is not expected to abort, so return an error instead. - -This is easily reproducible when libnfs is not installed: - - ./configure - [...] - module support no - Block whitelist (rw) - Block whitelist (ro) - libiscsi support yes - libnfs support no - [...] - -Start QEMU: - - $ qemu-system-x86_64 -S -qmp unix:/tmp/qemu.qmp,server,nowait - -Send the 'blockdev-create' with the 'nfs' driver: - - $ ( cat << 'EOF' - {'execute': 'qmp_capabilities'} - {'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': {'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': '::1', 'type': 'inet'}}}}, 'id': 'x'} - EOF - ) | socat STDIO UNIX:/tmp/qemu.qmp - {"QMP": {"version": {"qemu": {"micro": 50, "minor": 1, "major": 4}, "package": "v4.1.0-733-g89ea03a7dc"}, "capabilities": ["oob"]}} - {"return": {}} - -QEMU crashes: - - $ gdb qemu-system-x86_64 core - Program received signal SIGSEGV, Segmentation fault. - (gdb) bt - #0 0x00007ffff510957f in raise () at /lib64/libc.so.6 - #1 0x00007ffff50f3895 in abort () at /lib64/libc.so.6 - #2 0x00007ffff50f3769 in _nl_load_domain.cold.0 () at /lib64/libc.so.6 - #3 0x00007ffff5101a26 in .annobin_assert.c_end () at /lib64/libc.so.6 - #4 0x0000555555d7e1f1 in qmp_blockdev_create (job_id=0x555556baee40 "x", options=0x555557666610, errp=0x7fffffffc770) at block/create.c:69 - #5 0x0000555555c96b52 in qmp_marshal_blockdev_create (args=0x7fffdc003830, ret=0x7fffffffc7f8, errp=0x7fffffffc7f0) at qapi/qapi-commands-block-core.c:1314 - #6 0x0000555555deb0a0 in do_qmp_dispatch (cmds=0x55555645de70 , request=0x7fffdc005c70, allow_oob=false, errp=0x7fffffffc898) at qapi/qmp-dispatch.c:131 - #7 0x0000555555deb2a1 in qmp_dispatch (cmds=0x55555645de70 , request=0x7fffdc005c70, allow_oob=false) at qapi/qmp-dispatch.c:174 - -With this patch applied, QEMU returns a QMP error: - - {'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': {'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': '::1', 'type': 'inet'}}}}, 'id': 'x'} - {"id": "x", "error": {"class": "GenericError", "desc": "Block driver 'nfs' not found or not supported"}} - -Cc: qemu-stable@nongnu.org -Reported-by: Xu Tian -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Eric Blake -Reviewed-by: John Snow -Signed-off-by: Kevin Wolf -(cherry picked from commit d90d5cae2b10efc0e8d0b3cc91ff16201853d3ba) -Signed-off-by: Michael Roth ---- - block/create.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/block/create.c b/block/create.c -index 95341219ef..de5e97bb18 100644 ---- a/block/create.c -+++ b/block/create.c -@@ -63,9 +63,13 @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options, - const char *fmt = BlockdevDriver_str(options->driver); - BlockDriver *drv = bdrv_find_format(fmt); - -+ if (!drv) { -+ error_setg(errp, "Block driver '%s' not found or not supported", fmt); -+ return; -+ } -+ - /* If the driver is in the schema, we know that it exists. But it may not - * be whitelisted. */ -- assert(drv); - if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) { - error_setg(errp, "Driver is not whitelisted"); - return; --- -2.19.1 - diff --git a/block-file-posix-Unaligned-O_DIRECT-block-status.patch b/block-file-posix-Unaligned-O_DIRECT-block-status.patch deleted file mode 100644 index 40d84c8e501223cba411ca2beb10ec3345673823..0000000000000000000000000000000000000000 --- a/block-file-posix-Unaligned-O_DIRECT-block-status.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 9c3db310ff0b7473272ae8dce5e04e2f8a825390 Mon Sep 17 00:00:00 2001 -From: Max Reitz -Date: Wed, 15 May 2019 06:15:40 +0200 -Subject: [PATCH] block/file-posix: Unaligned O_DIRECT block-status - -Currently, qemu crashes whenever someone queries the block status of an -unaligned image tail of an O_DIRECT image: -$ echo > foo -$ qemu-img map --image-opts driver=file,filename=foo,cache.direct=on -Offset Length Mapped to File -qemu-img: block/io.c:2093: bdrv_co_block_status: Assertion `*pnum && -QEMU_IS_ALIGNED(*pnum, align) && align > offset - aligned_offset' -failed. - -This is because bdrv_co_block_status() checks that the result returned -by the driver's implementation is aligned to the request_alignment, but -file-posix can fail to do so, which is actually mentioned in a comment -there: "[...] possibly including a partial sector at EOF". - -Fix this by rounding up those partial sectors. - -There are two possible alternative fixes: -(1) We could refuse to open unaligned image files with O_DIRECT - altogether. That sounds reasonable until you realize that qcow2 - does necessarily not fill up its metadata clusters, and that nobody - runs qemu-img create with O_DIRECT. Therefore, unpreallocated qcow2 - files usually have an unaligned image tail. - -(2) bdrv_co_block_status() could ignore unaligned tails. It actually - throws away everything past the EOF already, so that sounds - reasonable. - Unfortunately, the block layer knows file lengths only with a - granularity of BDRV_SECTOR_SIZE, so bdrv_co_block_status() usually - would have to guess whether its file length information is inexact - or whether the driver is broken. - -Fixing what raw_co_block_status() returns is the safest thing to do. - -There seems to be no other block driver that sets request_alignment and -does not make sure that it always returns aligned values. - -Cc: qemu-stable@nongnu.org -Signed-off-by: Max Reitz -Reviewed-by: Eric Blake -Signed-off-by: Kevin Wolf -(cherry-picked from commit 9c3db310ff0b7473272ae8dce5e04e2f8a825390) ---- - block/file-posix.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/block/file-posix.c b/block/file-posix.c -index e09e15bbf8..d018429672 100644 ---- a/block/file-posix.c -+++ b/block/file-posix.c -@@ -2488,6 +2488,8 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs, - off_t data = 0, hole = 0; - int ret; - -+ assert(QEMU_IS_ALIGNED(offset | bytes, bs->bl.request_alignment)); -+ - ret = fd_open(bs); - if (ret < 0) { - return ret; -@@ -2513,6 +2515,20 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs, - /* On a data extent, compute bytes to the end of the extent, - * possibly including a partial sector at EOF. */ - *pnum = MIN(bytes, hole - offset); -+ -+ /* -+ * We are not allowed to return partial sectors, though, so -+ * round up if necessary. -+ */ -+ if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) { -+ int64_t file_length = raw_getlength(bs); -+ if (file_length > 0) { -+ /* Ignore errors, this is just a safeguard */ -+ assert(hole == file_length); -+ } -+ *pnum = ROUND_UP(*pnum, bs->bl.request_alignment); -+ } -+ - ret = BDRV_BLOCK_DATA; - } else { - /* On a hole, compute bytes to the beginning of the next extent. */ --- -2.19.1 - diff --git a/block-nfs-tear-down-aio-before-nfs_close.patch b/block-nfs-tear-down-aio-before-nfs_close.patch deleted file mode 100644 index a22a7ee7380906a189b99ecbe008958072611631..0000000000000000000000000000000000000000 --- a/block-nfs-tear-down-aio-before-nfs_close.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6cb3e9e4f17c182c43ded773a04b1072c881aa78 Mon Sep 17 00:00:00 2001 -From: Peter Lieven -Date: Tue, 10 Sep 2019 17:41:09 +0200 -Subject: [PATCH] block/nfs: tear down aio before nfs_close - -nfs_close is a sync call from libnfs and has its own event -handler polling on the nfs FD. Avoid that both QEMU and libnfs -are intefering here. - -CC: qemu-stable@nongnu.org -Signed-off-by: Peter Lieven -Signed-off-by: Kevin Wolf -(cherry picked from commit 601dc6559725f7a614b6f893611e17ff0908e914) -Signed-off-by: Michael Roth ---- - block/nfs.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/block/nfs.c b/block/nfs.c -index 531903610b..f04f675c63 100644 ---- a/block/nfs.c -+++ b/block/nfs.c -@@ -389,12 +389,14 @@ static void nfs_attach_aio_context(BlockDriverState *bs, - static void nfs_client_close(NFSClient *client) - { - if (client->context) { -+ qemu_mutex_lock(&client->mutex); -+ aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context), -+ false, NULL, NULL, NULL, NULL); -+ qemu_mutex_unlock(&client->mutex); - if (client->fh) { - nfs_close(client->context, client->fh); - client->fh = NULL; - } -- aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context), -- false, NULL, NULL, NULL, NULL); - nfs_destroy_context(client->context); - client->context = NULL; - } --- -2.19.1 - diff --git a/blockdev-backup-don-t-check-aio_context-too-early.patch b/blockdev-backup-don-t-check-aio_context-too-early.patch deleted file mode 100644 index aa793d59a2dbf74c9c1aa03cbd076217cd8ca63f..0000000000000000000000000000000000000000 --- a/blockdev-backup-don-t-check-aio_context-too-early.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 2429dc4eea91b381ff67a4d25ea9f6bbfe87c784 Mon Sep 17 00:00:00 2001 -From: John Snow -Date: Thu, 23 May 2019 13:06:39 -0400 -Subject: [PATCH] blockdev-backup: don't check aio_context too early - -in blockdev_backup_prepare, we check to make sure that the target is -associated with a compatible aio context. However, do_blockdev_backup is -called later and has some logic to move the target to a compatible -aio_context. The transaction version will fail certain commands -needlessly early as a result. - -Allow blockdev_backup_prepare to simply call do_blockdev_backup, which -will ultimately decide if the contexts are compatible or not. - -Note: the transaction version has always disallowed this operation since -its initial commit bd8baecd (2014), whereas the version of -qmp_blockdev_backup at the time, from commit c29c1dd312f, tried to -enforce the aio_context switch instead. It's not clear, and I can't see -from the mailing list archives at the time, why the two functions take a -different approach. It wasn't until later in efd7556708b (2016) that the -standalone version tried to determine if it could set the context or -not. - -Reported-by: aihua liang -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1683498 -Signed-off-by: John Snow -Message-id: 20190523170643.20794-2-jsnow@redhat.com -Reviewed-by: Max Reitz -Signed-off-by: Max Reitz -(cherry picked from commit d81e1efbea7d19c2f142d300df56538c73800590) -Signed-off-by: Michael Roth ---- - blockdev.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/blockdev.c b/blockdev.c -index 4775a07d93..d358169995 100644 ---- a/blockdev.c -+++ b/blockdev.c -@@ -1871,10 +1871,6 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp) - } - - aio_context = bdrv_get_aio_context(bs); -- if (aio_context != bdrv_get_aio_context(target)) { -- error_setg(errp, "Backup between two IO threads is not implemented"); -- return; -- } - aio_context_acquire(aio_context); - state->bs = bs; - --- -2.19.1 - diff --git a/blockjob-update-nodes-head-while-removing-all-bdrv.patch b/blockjob-update-nodes-head-while-removing-all-bdrv.patch deleted file mode 100644 index 4ad76d41e0d18d249c88dff2b28d237243828df9..0000000000000000000000000000000000000000 --- a/blockjob-update-nodes-head-while-removing-all-bdrv.patch +++ /dev/null @@ -1,62 +0,0 @@ -From b9405afb0956fe2c293a94bdc4440579e5c0efee Mon Sep 17 00:00:00 2001 -From: Sergio Lopez -Date: Wed, 11 Sep 2019 12:03:16 +0200 -Subject: [PATCH] blockjob: update nodes head while removing all bdrv - -block_job_remove_all_bdrv() iterates through job->nodes, calling -bdrv_root_unref_child() for each entry. The call to the latter may -reach child_job_[can_]set_aio_ctx(), which will also attempt to -traverse job->nodes, potentially finding entries that where freed -on previous iterations. - -To avoid this situation, update job->nodes head on each iteration to -ensure that already freed entries are no longer linked to the list. - -RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1746631 -Signed-off-by: Sergio Lopez -Cc: qemu-stable@nongnu.org -Signed-off-by: Max Reitz -Message-id: 20190911100316.32282-1-mreitz@redhat.com -Reviewed-by: Sergio Lopez -Signed-off-by: Max Reitz -(cherry picked from commit d876bf676f5e7c6aa9ac64555e48cba8734ecb2f) -Signed-off-by: Michael Roth ---- - blockjob.c | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) - -diff --git a/blockjob.c b/blockjob.c -index 730101d282..d770144fd6 100644 ---- a/blockjob.c -+++ b/blockjob.c -@@ -193,14 +193,23 @@ static const BdrvChildRole child_job = { - - void block_job_remove_all_bdrv(BlockJob *job) - { -- GSList *l; -- for (l = job->nodes; l; l = l->next) { -+ /* -+ * bdrv_root_unref_child() may reach child_job_[can_]set_aio_ctx(), -+ * which will also traverse job->nodes, so consume the list one by -+ * one to make sure that such a concurrent access does not attempt -+ * to process an already freed BdrvChild. -+ */ -+ while (job->nodes) { -+ GSList *l = job->nodes; - BdrvChild *c = l->data; -+ -+ job->nodes = l->next; -+ - bdrv_op_unblock_all(c->bs, job->blocker); - bdrv_root_unref_child(c); -+ -+ g_slist_free_1(l); - } -- g_slist_free(job->nodes); -- job->nodes = NULL; - } - - int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs, --- -2.19.1 - diff --git a/cutils-Fix-size_to_str-on-32-bit-platforms.patch b/cutils-Fix-size_to_str-on-32-bit-platforms.patch deleted file mode 100644 index aaf02e3a18dea2497b2fee9b7b29de088a4a7521..0000000000000000000000000000000000000000 --- a/cutils-Fix-size_to_str-on-32-bit-platforms.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 754da86714d550c3f995f11a2587395081362e0a Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Wed, 17 Apr 2019 12:11:00 -0500 -Subject: [PATCH] cutils: Fix size_to_str() on 32-bit platforms - -When extracting a human-readable size formatter, we changed 'uint64_t -div' pre-patch to 'unsigned long div' post-patch. Which breaks on -32-bit platforms, resulting in 'inf' instead of intended values larger -than 999GB. - -Fixes: 22951aaa -CC: qemu-stable@nongnu.org -Reported-by: Max Reitz -Signed-off-by: Eric Blake -Reviewed-by: Max Reitz -Signed-off-by: Kevin Wolf -(cherry-picked from commit 754da86714d550c3f995f11a2587395081362e0a) ---- - util/cutils.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/cutils.c b/util/cutils.c -index e098debdc0..d682c90901 100644 ---- a/util/cutils.c -+++ b/util/cutils.c -@@ -825,7 +825,7 @@ const char *qemu_ether_ntoa(const MACAddr *mac) - char *size_to_str(uint64_t val) - { - static const char *suffixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" }; -- unsigned long div; -+ uint64_t div; - int i; - - /* --- -2.19.1 - diff --git a/dma-helpers-ensure-AIO-callback-is-invoked-after-can.patch b/dma-helpers-ensure-AIO-callback-is-invoked-after-can.patch deleted file mode 100644 index db01a655e5932faa16b48d136b56a5d3690826d9..0000000000000000000000000000000000000000 --- a/dma-helpers-ensure-AIO-callback-is-invoked-after-can.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 53c641048e0a8da1d2bed76cbd17f259a35e39a0 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 29 Jul 2019 23:34:16 +0200 -Subject: [PATCH] dma-helpers: ensure AIO callback is invoked after - cancellation - -dma_aio_cancel unschedules the BH if there is one, which corresponds -to the reschedule_dma case of dma_blk_cb. This can stall the DMA -permanently, because dma_complete will never get invoked and therefore -nobody will ever invoke the original AIO callback in dbs->common.cb. - -Fix this by invoking the callback (which is ensured to happen after -a bdrv_aio_cancel_async, or done manually in the dbs->bh case), and -add assertions to check that the DMA state machine is indeed waiting -for dma_complete or reschedule_dma, but never both. - -Reported-by: John Snow -Signed-off-by: Paolo Bonzini -Message-id: 20190729213416.1972-1-pbonzini@redhat.com -Signed-off-by: John Snow -(cherry picked from commit 539343c0a47e19d5dd64d846d64d084d9793681f) -Signed-off-by: Michael Roth ---- - dma-helpers.c | 13 +++++++++---- - 1 file changed, 9 insertions(+), 4 deletions(-) - -diff --git a/dma-helpers.c b/dma-helpers.c -index 2d7e02d35e..d3871dc61e 100644 ---- a/dma-helpers.c -+++ b/dma-helpers.c -@@ -90,6 +90,7 @@ static void reschedule_dma(void *opaque) - { - DMAAIOCB *dbs = (DMAAIOCB *)opaque; - -+ assert(!dbs->acb && dbs->bh); - qemu_bh_delete(dbs->bh); - dbs->bh = NULL; - dma_blk_cb(dbs, 0); -@@ -111,15 +112,12 @@ static void dma_complete(DMAAIOCB *dbs, int ret) - { - trace_dma_complete(dbs, ret, dbs->common.cb); - -+ assert(!dbs->acb && !dbs->bh); - dma_blk_unmap(dbs); - if (dbs->common.cb) { - dbs->common.cb(dbs->common.opaque, ret); - } - qemu_iovec_destroy(&dbs->iov); -- if (dbs->bh) { -- qemu_bh_delete(dbs->bh); -- dbs->bh = NULL; -- } - qemu_aio_unref(dbs); - } - -@@ -179,14 +177,21 @@ static void dma_aio_cancel(BlockAIOCB *acb) - - trace_dma_aio_cancel(dbs); - -+ assert(!(dbs->acb && dbs->bh)); - if (dbs->acb) { -+ /* This will invoke dma_blk_cb. */ - blk_aio_cancel_async(dbs->acb); -+ return; - } -+ - if (dbs->bh) { - cpu_unregister_map_client(dbs->bh); - qemu_bh_delete(dbs->bh); - dbs->bh = NULL; - } -+ if (dbs->common.cb) { -+ dbs->common.cb(dbs->common.opaque, -ECANCELED); -+ } - } - - static AioContext *dma_get_aio_context(BlockAIOCB *acb) --- -2.19.1 - diff --git a/hw-Nuke-hw_compat_4_0_1-and-pc_compat_4_0_1.patch b/hw-Nuke-hw_compat_4_0_1-and-pc_compat_4_0_1.patch deleted file mode 100644 index 15d807769607a5964de8b2869fd53c55e5e16baf..0000000000000000000000000000000000000000 --- a/hw-Nuke-hw_compat_4_0_1-and-pc_compat_4_0_1.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 56deb8f0db72858985ba077cb0f678f2dbc13bba Mon Sep 17 00:00:00 2001 -From: Greg Kurz -Date: Mon, 5 Aug 2019 15:56:58 +0800 -Subject: [PATCH] hw: Nuke hw_compat_4_0_1 and pc_compat_4_0_1 - -Commit c87759ce876a fixed a regression affecting pc-q35 machines by -introducing a new pc-q35-4.0.1 machine version to be used instead -of pc-q35-4.0. The only purpose was to revert the default behaviour -of not using split irqchip, but the change also introduced the usual -hw_compat and pc_compat bits, and wired them for pc-q35 only. - -This raises questions when it comes to add new compat properties for -4.0* machine versions of any architecture. Where to add them ? In -4.0, 4.0.1 or both ? Error prone. Another possibility would be to teach -all other architectures about 4.0.1. This solution isn't satisfying, -especially since this is a pc-q35 specific issue. - -It turns out that the split irqchip default is handled in the machine -option function and doesn't involve compat lists at all. - -Drop all the 4.0.1 compat lists and use the 4.0 ones instead in the 4.0.1 -machine option function. - -Move the compat props that were added to the 4.0.1 since c87759ce876a to -4.0. - -Even if only hw_compat_4_0_1 had an impact on other architectures, -drop pc_compat_4_0_1 as well for consistency. - -Fixes: c87759ce876a "q35: Revert to kernel irqchip" -Suggested-by: Dr. David Alan Gilbert -Signed-off-by: Greg Kurz -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: Michael S. Tsirkin -Message-Id: <156051774276.244890.8660277280145466396.stgit@bahia.lan> -Signed-off-by: Paolo Bonzini -(cherry-picked from commit 8e8cbed09ad9d577955691b4c061b61b602406d1) ---- - hw/core/machine.c | 3 --- - hw/i386/pc.c | 3 --- - hw/i386/pc_q35.c | 9 +++++++-- - include/hw/boards.h | 3 --- - include/hw/i386/pc.h | 3 --- - 5 files changed, 7 insertions(+), 14 deletions(-) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index e41e6698..5d046a43 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -24,9 +24,6 @@ - #include "hw/pci/pci.h" - #include "hw/mem/nvdimm.h" - --GlobalProperty hw_compat_4_0_1[] = {}; --const size_t hw_compat_4_0_1_len = G_N_ELEMENTS(hw_compat_4_0_1); -- - GlobalProperty hw_compat_4_0[] = {}; - const size_t hw_compat_4_0_len = G_N_ELEMENTS(hw_compat_4_0); - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index b5311e7e..d98b737b 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -115,9 +115,6 @@ struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; - /* Physical Address of PVH entry point read from kernel ELF NOTE */ - static size_t pvh_start_addr; - --GlobalProperty pc_compat_4_0_1[] = {}; --const size_t pc_compat_4_0_1_len = G_N_ELEMENTS(pc_compat_4_0_1); -- - GlobalProperty pc_compat_4_0[] = {}; - const size_t pc_compat_4_0_len = G_N_ELEMENTS(pc_compat_4_0); - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index dcddc646..e3498a45 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -378,8 +378,13 @@ static void pc_q35_4_0_1_machine_options(MachineClass *m) - { - pc_q35_4_1_machine_options(m); - m->alias = NULL; -- compat_props_add(m->compat_props, hw_compat_4_0_1, hw_compat_4_0_1_len); -- compat_props_add(m->compat_props, pc_compat_4_0_1, pc_compat_4_0_1_len); -+ /* -+ * This is the default machine for the 4.0-stable branch. It is basically -+ * a 4.0 that doesn't use split irqchip by default. It MUST hence apply the -+ * 4.0 compat props. -+ */ -+ compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len); -+ compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len); - } - - DEFINE_Q35_MACHINE(v4_0_1, "pc-q35-4.0.1", NULL, -diff --git a/include/hw/boards.h b/include/hw/boards.h -index ad3950d3..fe1885cb 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -293,9 +293,6 @@ struct MachineState { - } \ - type_init(machine_initfn##_register_types) - --extern GlobalProperty hw_compat_4_0_1[]; --extern const size_t hw_compat_4_0_1_len; -- - extern GlobalProperty hw_compat_4_0[]; - extern const size_t hw_compat_4_0_len; - -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 5d563624..43df7230 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -293,9 +293,6 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); - int e820_get_num_entries(void); - bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); - --extern GlobalProperty pc_compat_4_0_1[]; --extern const size_t pc_compat_4_0_1_len; -- - extern GlobalProperty pc_compat_4_0[]; - extern const size_t pc_compat_4_0_len; - --- -2.19.1 - diff --git a/hw-add-compat-machines-for-4.1.patch b/hw-add-compat-machines-for-4.1.patch deleted file mode 100644 index 67d1ccd9abf62d9e2bafff5f779fa6f8d3218a16..0000000000000000000000000000000000000000 --- a/hw-add-compat-machines-for-4.1.patch +++ /dev/null @@ -1,232 +0,0 @@ -From 9bf2650bc3aab126b85c034bf86e27d564f9a1aa Mon Sep 17 00:00:00 2001 -From: Cornelia Huck -Date: Thu, 11 Apr 2019 12:20:25 +0200 -Subject: [PATCH] hw: add compat machines for 4.1 - -Add 4.1 machine types for arm/i440fx/q35/s390x/spapr. - -Signed-off-by: Cornelia Huck -Message-Id: <20190411102025.22559-1-cohuck@redhat.com> -Acked-by: Greg Kurz -Acked-by: David Gibson -Signed-off-by: Eduardo Habkost -(cherry-picked from commit 9bf2650bc3aab126b85c034bf86e27d564f9a1aa) ---- - hw/arm/virt.c | 9 ++++++++- - hw/core/machine.c | 3 +++ - hw/i386/pc.c | 3 +++ - hw/i386/pc_piix.c | 14 +++++++++++++- - hw/i386/pc_q35.c | 13 ++++++++++++- - hw/ppc/spapr.c | 15 +++++++++++++-- - hw/s390x/s390-virtio-ccw.c | 14 +++++++++++++- - include/hw/boards.h | 3 +++ - include/hw/i386/pc.h | 3 +++ - 9 files changed, 71 insertions(+), 6 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index ce2664a30b..16ba67f7a7 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -1978,10 +1978,17 @@ static void machvirt_machine_init(void) - } - type_init(machvirt_machine_init); - -+static void virt_machine_4_1_options(MachineClass *mc) -+{ -+} -+DEFINE_VIRT_MACHINE_AS_LATEST(4, 1) -+ - static void virt_machine_4_0_options(MachineClass *mc) - { -+ virt_machine_4_1_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len); - } --DEFINE_VIRT_MACHINE_AS_LATEST(4, 0) -+DEFINE_VIRT_MACHINE(4, 0) - - static void virt_machine_3_1_options(MachineClass *mc) - { -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 743fef2898..5d046a43e3 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -24,6 +24,9 @@ - #include "hw/pci/pci.h" - #include "hw/mem/nvdimm.h" - -+GlobalProperty hw_compat_4_0[] = {}; -+const size_t hw_compat_4_0_len = G_N_ELEMENTS(hw_compat_4_0); -+ - GlobalProperty hw_compat_3_1[] = { - { "pcie-root-port", "x-speed", "2_5" }, - { "pcie-root-port", "x-width", "1" }, -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index f2c15bf1f2..d98b737b8f 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -115,6 +115,9 @@ struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; - /* Physical Address of PVH entry point read from kernel ELF NOTE */ - static size_t pvh_start_addr; - -+GlobalProperty pc_compat_4_0[] = {}; -+const size_t pc_compat_4_0_len = G_N_ELEMENTS(pc_compat_4_0); -+ - GlobalProperty pc_compat_3_1[] = { - { "intel-iommu", "dma-drain", "off" }, - { "Opteron_G3" "-" TYPE_X86_CPU, "rdtscp", "off" }, -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index 8ad8e885c6..2a7700b564 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -428,13 +428,25 @@ static void pc_i440fx_machine_options(MachineClass *m) - machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE); - } - --static void pc_i440fx_4_0_machine_options(MachineClass *m) -+static void pc_i440fx_4_1_machine_options(MachineClass *m) - { - pc_i440fx_machine_options(m); - m->alias = "pc"; - m->is_default = 1; - } - -+DEFINE_I440FX_MACHINE(v4_1, "pc-i440fx-4.1", NULL, -+ pc_i440fx_4_1_machine_options); -+ -+static void pc_i440fx_4_0_machine_options(MachineClass *m) -+{ -+ pc_i440fx_4_1_machine_options(m); -+ m->alias = NULL; -+ m->is_default = 0; -+ compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len); -+ compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len); -+} -+ - DEFINE_I440FX_MACHINE(v4_0, "pc-i440fx-4.0", NULL, - pc_i440fx_4_0_machine_options); - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 372c6b73be..37dd350511 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -365,12 +365,23 @@ static void pc_q35_machine_options(MachineClass *m) - m->max_cpus = 288; - } - --static void pc_q35_4_0_machine_options(MachineClass *m) -+static void pc_q35_4_1_machine_options(MachineClass *m) - { - pc_q35_machine_options(m); - m->alias = "q35"; - } - -+DEFINE_Q35_MACHINE(v4_1, "pc-q35-4.1", NULL, -+ pc_q35_4_1_machine_options); -+ -+static void pc_q35_4_0_machine_options(MachineClass *m) -+{ -+ pc_q35_4_1_machine_options(m); -+ m->alias = NULL; -+ compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len); -+ compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len); -+} -+ - DEFINE_Q35_MACHINE(v4_0, "pc-q35-4.0", NULL, - pc_q35_4_0_machine_options); - -diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c -index b52b82d298..8438741ec2 100644 ---- a/hw/ppc/spapr.c -+++ b/hw/ppc/spapr.c -@@ -4344,15 +4344,26 @@ static const TypeInfo spapr_machine_info = { - } \ - type_init(spapr_machine_register_##suffix) - -+/* -+ * pseries-4.1 -+ */ -+static void spapr_machine_4_1_class_options(MachineClass *mc) -+{ -+ /* Defaults for the latest behaviour inherited from the base class */ -+} -+ -+DEFINE_SPAPR_MACHINE(4_1, "4.1", true); -+ - /* - * pseries-4.0 - */ - static void spapr_machine_4_0_class_options(MachineClass *mc) - { -- /* Defaults for the latest behaviour inherited from the base class */ -+ spapr_machine_4_1_class_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len); - } - --DEFINE_SPAPR_MACHINE(4_0, "4.0", true); -+DEFINE_SPAPR_MACHINE(4_0, "4.0", false); - - /* - * pseries-3.1 -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index d11069b860..02470e78c7 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -646,14 +646,26 @@ bool css_migration_enabled(void) - } \ - type_init(ccw_machine_register_##suffix) - -+static void ccw_machine_4_1_instance_options(MachineState *machine) -+{ -+} -+ -+static void ccw_machine_4_1_class_options(MachineClass *mc) -+{ -+} -+DEFINE_CCW_MACHINE(4_1, "4.1", true); -+ - static void ccw_machine_4_0_instance_options(MachineState *machine) - { -+ ccw_machine_4_1_instance_options(machine); - } - - static void ccw_machine_4_0_class_options(MachineClass *mc) - { -+ ccw_machine_4_1_class_options(mc); -+ compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len); - } --DEFINE_CCW_MACHINE(4_0, "4.0", true); -+DEFINE_CCW_MACHINE(4_0, "4.0", false); - - static void ccw_machine_3_1_instance_options(MachineState *machine) - { -diff --git a/include/hw/boards.h b/include/hw/boards.h -index e231860666..fe1885cbff 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -293,6 +293,9 @@ struct MachineState { - } \ - type_init(machine_initfn##_register_types) - -+extern GlobalProperty hw_compat_4_0[]; -+extern const size_t hw_compat_4_0_len; -+ - extern GlobalProperty hw_compat_3_1[]; - extern const size_t hw_compat_3_1_len; - -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index ca65ef18af..43df7230a2 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -293,6 +293,9 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); - int e820_get_num_entries(void); - bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); - -+extern GlobalProperty pc_compat_4_0[]; -+extern const size_t pc_compat_4_0_len; -+ - extern GlobalProperty pc_compat_3_1[]; - extern const size_t pc_compat_3_1_len; - --- -2.19.1 - diff --git a/hw-core-loader-Fix-possible-crash-in-rom_copy.patch b/hw-core-loader-Fix-possible-crash-in-rom_copy.patch deleted file mode 100644 index d4301f79286d65327d1fc80a5b1dbd958fc92933..0000000000000000000000000000000000000000 --- a/hw-core-loader-Fix-possible-crash-in-rom_copy.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 4f1c6cb2f9afafda05eab150fd2bd284edce6676 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Wed, 25 Sep 2019 14:16:43 +0200 -Subject: [PATCH] hw/core/loader: Fix possible crash in rom_copy() - -Both, "rom->addr" and "addr" are derived from the binary image -that can be loaded with the "-kernel" paramer. The code in -rom_copy() then calculates: - - d = dest + (rom->addr - addr); - -and uses "d" as destination in a memcpy() some lines later. Now with -bad kernel images, it is possible that rom->addr is smaller than addr, -thus "rom->addr - addr" gets negative and the memcpy() then tries to -copy contents from the image to a bad memory location. This could -maybe be used to inject code from a kernel image into the QEMU binary, -so we better fix it with an additional sanity check here. - -Cc: qemu-stable@nongnu.org -Reported-by: Guangming Liu -Buglink: https://bugs.launchpad.net/qemu/+bug/1844635 -Message-Id: <20190925130331.27825-1-thuth@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Thomas Huth -(cherry picked from commit e423455c4f23a1a828901c78fe6d03b7dde79319) -Signed-off-by: Michael Roth ---- - hw/core/loader.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/core/loader.c b/hw/core/loader.c -index fe5cb24122..4ef2095247 100644 ---- a/hw/core/loader.c -+++ b/hw/core/loader.c -@@ -1240,7 +1240,7 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size) - if (rom->addr + rom->romsize < addr) { - continue; - } -- if (rom->addr > end) { -+ if (rom->addr > end || rom->addr < addr) { - break; - } - --- -2.19.1 - diff --git a/i386-acpi-fix-gint-overflow-in-crs_range_compare.patch b/i386-acpi-fix-gint-overflow-in-crs_range_compare.patch deleted file mode 100644 index 5f5cbc47887b679dc22e628469a56fe678969de7..0000000000000000000000000000000000000000 --- a/i386-acpi-fix-gint-overflow-in-crs_range_compare.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 21e2acd583126db94f6d881005cd58e835160582 Mon Sep 17 00:00:00 2001 -From: Evgeny Yakovlev -Date: Thu, 18 Jul 2019 19:14:23 +0300 -Subject: [PATCH] i386/acpi: fix gint overflow in crs_range_compare - -When very large regions (32GB sized in our case, PCI pass-through of GPUs) -are compared substraction result does not fit into gint. - -As a result crs_replace_with_free_ranges does not get sorted ranges and -incorrectly computes PCI64 free space regions. Which then makes linux -guest complain about device and PCI64 hole intersection and device -becomes unusable. - -Fix that by returning exactly fitting ranges. - -Also fix indentation of an entire crs_replace_with_free_ranges to make -checkpatch happy. - -Cc: qemu-stable@nongnu.org -Signed-off-by: Evgeny Yakovlev -Message-Id: <1563466463-26012-1-git-send-email-wrfsh@yandex-team.ru> -Signed-off-by: Evgeny Yakovlev -(cherry-picked from commit 21e2acd583126db94f6d881005cd58e835160582) ---- - hw/i386/acpi-build.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c -index d281ffa89e..e7b756b51b 100644 ---- a/hw/i386/acpi-build.c -+++ b/hw/i386/acpi-build.c -@@ -755,10 +755,16 @@ static void crs_range_set_free(CrsRangeSet *range_set) - - static gint crs_range_compare(gconstpointer a, gconstpointer b) - { -- CrsRangeEntry *entry_a = *(CrsRangeEntry **)a; -- CrsRangeEntry *entry_b = *(CrsRangeEntry **)b; -+ CrsRangeEntry *entry_a = *(CrsRangeEntry **)a; -+ CrsRangeEntry *entry_b = *(CrsRangeEntry **)b; - -- return (int64_t)entry_a->base - (int64_t)entry_b->base; -+ if (entry_a->base < entry_b->base) { -+ return -1; -+ } else if (entry_a->base > entry_b->base) { -+ return 1; -+ } else { -+ return 0; -+ } - } - - /* --- -2.19.1 - diff --git a/i386-acpi-show-PCI-Express-bus-on-pxb-pcie-expanders.patch b/i386-acpi-show-PCI-Express-bus-on-pxb-pcie-expanders.patch deleted file mode 100644 index 640329867cb1750b83ccceb72a2c44c8a5577fa3..0000000000000000000000000000000000000000 --- a/i386-acpi-show-PCI-Express-bus-on-pxb-pcie-expanders.patch +++ /dev/null @@ -1,40 +0,0 @@ -From ee4b0c8686f781987879508d7c6dd605b5435bac Mon Sep 17 00:00:00 2001 -From: Evgeny Yakovlev -Date: Fri, 19 Jul 2019 11:54:29 +0300 -Subject: [PATCH] i386/acpi: show PCI Express bus on pxb-pcie expanders - -Show PCIe host bridge PNP id with PCI host bridge as a compatible id -when expanding a pcie bus. - -Cc: qemu-stable@nongnu.org -Signed-off-by: Evgeny Yakovlev -Message-Id: <1563526469-15588-1-git-send-email-wrfsh@yandex-team.ru> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry-picked from commit ee4b0c8686f781987879508d7c6dd605b5435bac) ---- - hw/i386/acpi-build.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c -index e7b756b51b..f3fdfefcd5 100644 ---- a/hw/i386/acpi-build.c -+++ b/hw/i386/acpi-build.c -@@ -1914,10 +1914,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, - scope = aml_scope("\\_SB"); - dev = aml_device("PC%.02X", bus_num); - aml_append(dev, aml_name_decl("_UID", aml_int(bus_num))); -- aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); - aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num))); - if (pci_bus_is_express(bus)) { -+ aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); -+ aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); - aml_append(dev, build_q35_osc_method()); -+ } else { -+ aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); - } - - if (numa_node != NUMA_NODE_UNASSIGNED) { --- -2.19.1 - diff --git a/ioapic-kvm-Skip-route-updates-for-masked-pins.patch b/ioapic-kvm-Skip-route-updates-for-masked-pins.patch deleted file mode 100644 index 0a27bfdcc58b01cab2e95ea2589f19867226b600..0000000000000000000000000000000000000000 --- a/ioapic-kvm-Skip-route-updates-for-masked-pins.patch +++ /dev/null @@ -1,46 +0,0 @@ -From be1927c97e564346cbd409cb17fe611df74b84e5 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Sun, 2 Jun 2019 13:42:13 +0200 -Subject: [PATCH] ioapic: kvm: Skip route updates for masked pins - -Masked entries will not generate interrupt messages, thus do no need to -be routed by KVM. This is a cosmetic cleanup, just avoiding warnings of -the kind - -qemu-system-x86_64: vtd_irte_get: detected non-present IRTE (index=0, high=0xff00, low=0x100) - -if the masked entry happens to reference a non-present IRTE. - -Cc: qemu-stable@nongnu.org -Signed-off-by: Jan Kiszka -Message-Id: -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Peter Xu -(cherry-picked from commit be1927c97e564346cbd409cb17fe611df74b84e5) ---- - hw/intc/ioapic.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c -index c408749876..e99c37cceb 100644 ---- a/hw/intc/ioapic.c -+++ b/hw/intc/ioapic.c -@@ -197,9 +197,11 @@ static void ioapic_update_kvm_routes(IOAPICCommonState *s) - MSIMessage msg; - struct ioapic_entry_info info; - ioapic_entry_parse(s->ioredtbl[i], &info); -- msg.address = info.addr; -- msg.data = info.data; -- kvm_irqchip_update_msi_route(kvm_state, i, msg, NULL); -+ if (!info.masked) { -+ msg.address = info.addr; -+ msg.data = info.data; -+ kvm_irqchip_update_msi_route(kvm_state, i, msg, NULL); -+ } - } - kvm_irqchip_commit_routes(kvm_state); - } --- -2.19.1 - diff --git a/iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch b/iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..e6abdf7a51d13c4a94ee722164df1fbc54ed48bb --- /dev/null +++ b/iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch @@ -0,0 +1,58 @@ +From 693fd2acdf14dd86c0bf852610f1c2cca80a74dc Mon Sep 17 00:00:00 2001 +From: Felipe Franciosi +Date: Thu, 23 Jan 2020 12:44:59 +0000 +Subject: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711) + +When querying an iSCSI server for the provisioning status of blocks (via +GET LBA STATUS), Qemu only validates that the response descriptor zero's +LBA matches the one requested. Given the SCSI spec allows servers to +respond with the status of blocks beyond the end of the LUN, Qemu may +have its heap corrupted by clearing/setting too many bits at the end of +its allocmap for the LUN. + +A malicious guest in control of the iSCSI server could carefully program +Qemu's heap (by selectively setting the bitmap) and then smash it. + +This limits the number of bits that iscsi_co_block_status() will try to +update in the allocmap so it can't overflow the bitmap. + +Fixes: CVE-2020-1711 +Cc: qemu-stable@nongnu.org +Signed-off-by: Felipe Franciosi +Signed-off-by: Peter Turschmid +Signed-off-by: Raphael Norwitz +Signed-off-by: Kevin Wolf + +diff --git a/block/iscsi.c b/block/iscsi.c +index 2aea7e3f13..cbd57294ab 100644 +--- a/block/iscsi.c ++++ b/block/iscsi.c +@@ -701,7 +701,7 @@ static int coroutine_fn iscsi_co_block_status(BlockDriverState *bs, + struct scsi_get_lba_status *lbas = NULL; + struct scsi_lba_status_descriptor *lbasd = NULL; + struct IscsiTask iTask; +- uint64_t lba; ++ uint64_t lba, max_bytes; + int ret; + + iscsi_co_init_iscsitask(iscsilun, &iTask); +@@ -721,6 +721,7 @@ static int coroutine_fn iscsi_co_block_status(BlockDriverState *bs, + } + + lba = offset / iscsilun->block_size; ++ max_bytes = (iscsilun->num_blocks - lba) * iscsilun->block_size; + + qemu_mutex_lock(&iscsilun->mutex); + retry: +@@ -764,7 +765,7 @@ retry: + goto out_unlock; + } + +- *pnum = (int64_t) lbasd->num_blocks * iscsilun->block_size; ++ *pnum = MIN((int64_t) lbasd->num_blocks * iscsilun->block_size, max_bytes); + + if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED || + lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) { +-- +2.21.1 (Apple Git-122.3) + diff --git a/kbd-state-fix-autorepeat-handling.patch b/kbd-state-fix-autorepeat-handling.patch deleted file mode 100644 index aa1bef302866dd7202eca95b74e0a3b61820f020..0000000000000000000000000000000000000000 --- a/kbd-state-fix-autorepeat-handling.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 5fff13f245cddd3bc260dfe6ebe1b1f05b72116f Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 14 May 2019 06:24:43 +0200 -Subject: [PATCH] kbd-state: fix autorepeat handling - -When allowing multiple down-events in a row (key autorepeat) we can't -use change_bit() any more to update the state, because autorepeat events -don't change the key state. We have to explicitly use set_bit() and -clear_bit() instead. - -Cc: qemu-stable@nongnu.org -Fixes: 35921860156e kbd-state: don't block auto-repeat events -Buglink: https://bugs.launchpad.net/qemu/+bug/1828272 -Signed-off-by: Gerd Hoffmann -Message-id: 20190514042443.10735-1-kraxel@redhat.com -(cherry-picked from commit 5fff13f245cddd3bc260dfe6ebe1b1f05b72116f) ---- - ui/kbd-state.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/ui/kbd-state.c b/ui/kbd-state.c -index f3ab2d7a66..1668d17dda 100644 ---- a/ui/kbd-state.c -+++ b/ui/kbd-state.c -@@ -59,7 +59,11 @@ void qkbd_state_key_event(QKbdState *kbd, QKeyCode qcode, bool down) - } - - /* update key and modifier state */ -- change_bit(qcode, kbd->keys); -+ if (down) { -+ set_bit(qcode, kbd->keys); -+ } else { -+ clear_bit(qcode, kbd->keys); -+ } - switch (qcode) { - case Q_KEY_CODE_SHIFT: - case Q_KEY_CODE_SHIFT_R: --- -2.19.1 - diff --git a/megasas-fix-mapped-frame-size.patch b/megasas-fix-mapped-frame-size.patch deleted file mode 100644 index 46cc8d30f9506545dec3a307a3bdc777678cbce9..0000000000000000000000000000000000000000 --- a/megasas-fix-mapped-frame-size.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 2e56fbc87f6ec3cd56c37b01d313abd502b80d61 Mon Sep 17 00:00:00 2001 -From: Peter Lieven -Date: Thu, 4 Apr 2019 14:10:15 +0200 -Subject: [PATCH] megasas: fix mapped frame size - -the current value of 1024 bytes (16 * MFI_FRAME_SIZE) we map is not enough to hold -the maximum number of scatter gather elements we advertise. We actually need a -maximum of 2048 bytes. This is 128 max sg elements * 16 bytes (sizeof (union mfi_sgl)). - -Cc: qemu-stable@nongnu.org -Signed-off-by: Peter Lieven -Message-Id: <20190404121015.28634-1-pl@kamp.de> -Reviewed-by: Hannes Reinecke -Signed-off-by: Paolo Bonzini -(cherry-picked from commit 2e56fbc87f6ec3cd56c37b01d313abd502b80d61) ---- - hw/scsi/megasas.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c -index a56317e026..5ad762de23 100644 ---- a/hw/scsi/megasas.c -+++ b/hw/scsi/megasas.c -@@ -477,7 +477,7 @@ static MegasasCmd *megasas_enqueue_frame(MegasasState *s, - { - PCIDevice *pcid = PCI_DEVICE(s); - MegasasCmd *cmd = NULL; -- int frame_size = MFI_FRAME_SIZE * 16; -+ int frame_size = MEGASAS_MAX_SGE * sizeof(union mfi_sgl); - hwaddr frame_size_p = frame_size; - unsigned long index; - --- -2.19.1 - diff --git a/migration-Fix-use-after-free-during-process-exit.patch b/migration-Fix-use-after-free-during-process-exit.patch deleted file mode 100644 index e64034241b749db9b6f078815f806fbfca15bf3d..0000000000000000000000000000000000000000 --- a/migration-Fix-use-after-free-during-process-exit.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 35d6458d6a100b2f15a7e079558a4570742c6e5a Mon Sep 17 00:00:00 2001 -From: Yury Kotov -Date: Mon, 8 Apr 2019 14:33:43 +0300 -Subject: [PATCH] migration: Fix use-after-free during process exit - -It fixes heap-use-after-free which was found by clang's ASAN. - -Control flow of this use-after-free: -main_thread: - * Got SIGTERM and completes main loop - * Calls migration_shutdown - - migrate_fd_cancel (so, migration_thread begins to complete) - - object_unref(OBJECT(current_migration)); - -migration_thread: - * migration_iteration_finish -> schedule cleanup bh - * object_unref(OBJECT(s)); (Now, current_migration is freed) - * exits - -main_thread: - * Calls vm_shutdown -> drain bdrvs -> main loop - -> cleanup_bh -> use after free - -If you want to reproduce, these couple of sleeps will help: -vl.c:4613: - migration_shutdown(); -+ sleep(2); -migration.c:3269: -+ sleep(1); - trace_migration_thread_after_loop(); - migration_iteration_finish(s); - -Original output: -qemu-system-x86_64: terminating on signal 15 from pid 31980 () -================================================================= -==31958==ERROR: AddressSanitizer: heap-use-after-free on address 0x61900001d210 - at pc 0x555558a535ca bp 0x7fffffffb190 sp 0x7fffffffb188 -READ of size 8 at 0x61900001d210 thread T0 (qemu-vm-0) - #0 0x555558a535c9 in migrate_fd_cleanup migration/migration.c:1502:23 - #1 0x5555594fde0a in aio_bh_call util/async.c:90:5 - #2 0x5555594fe522 in aio_bh_poll util/async.c:118:13 - #3 0x555559524783 in aio_poll util/aio-posix.c:725:17 - #4 0x555559504fb3 in aio_wait_bh_oneshot util/aio-wait.c:71:5 - #5 0x5555573bddf6 in virtio_blk_data_plane_stop - hw/block/dataplane/virtio-blk.c:282:5 - #6 0x5555589d5c09 in virtio_bus_stop_ioeventfd hw/virtio/virtio-bus.c:246:9 - #7 0x5555589e9917 in virtio_pci_stop_ioeventfd hw/virtio/virtio-pci.c:287:5 - #8 0x5555589e22bf in virtio_pci_vmstate_change hw/virtio/virtio-pci.c:1072:9 - #9 0x555557628931 in virtio_vmstate_change hw/virtio/virtio.c:2257:9 - #10 0x555557c36713 in vm_state_notify vl.c:1605:9 - #11 0x55555716ef53 in do_vm_stop cpus.c:1074:9 - #12 0x55555716eeff in vm_shutdown cpus.c:1092:12 - #13 0x555557c4283e in main vl.c:4617:5 - #14 0x7fffdfdb482f in __libc_start_main - (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) - #15 0x555556ecb118 in _start (x86_64-softmmu/qemu-system-x86_64+0x1977118) - -0x61900001d210 is located 144 bytes inside of 952-byte region - [0x61900001d180,0x61900001d538) -freed by thread T6 (live_migration) here: - #0 0x555556f76782 in __interceptor_free - /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:124:3 - #1 0x555558d5fa94 in object_finalize qom/object.c:618:9 - #2 0x555558d57651 in object_unref qom/object.c:1068:9 - #3 0x555558a55588 in migration_thread migration/migration.c:3272:5 - #4 0x5555595393f2 in qemu_thread_start util/qemu-thread-posix.c:502:9 - #5 0x7fffe057f6b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9) - -previously allocated by thread T0 (qemu-vm-0) here: - #0 0x555556f76b03 in __interceptor_malloc - /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:146:3 - #1 0x7ffff6ee37b8 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4f7b8) - #2 0x555558d58031 in object_new qom/object.c:640:12 - #3 0x555558a31f21 in migration_object_init migration/migration.c:139:25 - #4 0x555557c41398 in main vl.c:4320:5 - #5 0x7fffdfdb482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) - -Thread T6 (live_migration) created by T0 (qemu-vm-0) here: - #0 0x555556f5f0dd in pthread_create - /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors.cc:210:3 - #1 0x555559538cf9 in qemu_thread_create util/qemu-thread-posix.c:539:11 - #2 0x555558a53304 in migrate_fd_connect migration/migration.c:3332:5 - #3 0x555558a72bd8 in migration_channel_connect migration/channel.c:92:5 - #4 0x555558a6ef87 in exec_start_outgoing_migration migration/exec.c:42:5 - #5 0x555558a4f3c2 in qmp_migrate migration/migration.c:1922:9 - #6 0x555558bb4f6a in qmp_marshal_migrate qapi/qapi-commands-migration.c:607:5 - #7 0x555559363738 in do_qmp_dispatch qapi/qmp-dispatch.c:131:5 - #8 0x555559362a15 in qmp_dispatch qapi/qmp-dispatch.c:174:11 - #9 0x5555571bac15 in monitor_qmp_dispatch monitor.c:4124:11 - #10 0x55555719a22d in monitor_qmp_bh_dispatcher monitor.c:4207:9 - #11 0x5555594fde0a in aio_bh_call util/async.c:90:5 - #12 0x5555594fe522 in aio_bh_poll util/async.c:118:13 - #13 0x5555595201e0 in aio_dispatch util/aio-posix.c:460:5 - #14 0x555559503553 in aio_ctx_dispatch util/async.c:261:5 - #15 0x7ffff6ede196 in g_main_context_dispatch - (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4a196) - -SUMMARY: AddressSanitizer: heap-use-after-free migration/migration.c:1502:23 - in migrate_fd_cleanup -Shadow bytes around the buggy address: - 0x0c327fffb9f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa - 0x0c327fffba00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa - 0x0c327fffba10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa - 0x0c327fffba20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa - 0x0c327fffba30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd -=>0x0c327fffba40: fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd - 0x0c327fffba50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd - 0x0c327fffba60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd - 0x0c327fffba70: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd - 0x0c327fffba80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd - 0x0c327fffba90: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd -Shadow byte legend (one shadow byte represents 8 application bytes): - Addressable: 00 - Partially addressable: 01 02 03 04 05 06 07 - Heap left redzone: fa - Freed heap region: fd - Stack left redzone: f1 - Stack mid redzone: f2 - Stack right redzone: f3 - Stack after return: f5 - Stack use after scope: f8 - Global redzone: f9 - Global init order: f6 - Poisoned by user: f7 - Container overflow: fc - Array cookie: ac - Intra object redzone: bb - ASan internal: fe - Left alloca redzone: ca - Right alloca redzone: cb - Shadow gap: cc -==31958==ABORTING - -Signed-off-by: Yury Kotov -Message-Id: <20190408113343.2370-1-yury-kotov@yandex-team.ru> -Reviewed-by: Dr. David Alan Gilbert -Signed-off-by: Dr. David Alan Gilbert - Fixed up comment formatting -(cherry picked from commit fd392cfa8e6fb0dc34bd0327fc356dfbf6edf1fd) -Signed-off-by: Michael Roth ---- - migration/migration.c | 25 ++++++++++++++++++++----- - 1 file changed, 20 insertions(+), 5 deletions(-) - -diff --git a/migration/migration.c b/migration/migration.c -index 609e0df5d0..2f617b9dba 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -1495,10 +1495,8 @@ static void block_cleanup_parameters(MigrationState *s) - } - } - --static void migrate_fd_cleanup(void *opaque) -+static void migrate_fd_cleanup(MigrationState *s) - { -- MigrationState *s = opaque; -- - qemu_bh_delete(s->cleanup_bh); - s->cleanup_bh = NULL; - -@@ -1543,6 +1541,23 @@ static void migrate_fd_cleanup(void *opaque) - block_cleanup_parameters(s); - } - -+static void migrate_fd_cleanup_schedule(MigrationState *s) -+{ -+ /* -+ * Ref the state for bh, because it may be called when -+ * there're already no other refs -+ */ -+ object_ref(OBJECT(s)); -+ qemu_bh_schedule(s->cleanup_bh); -+} -+ -+static void migrate_fd_cleanup_bh(void *opaque) -+{ -+ MigrationState *s = opaque; -+ migrate_fd_cleanup(s); -+ object_unref(OBJECT(s)); -+} -+ - void migrate_set_error(MigrationState *s, const Error *error) - { - qemu_mutex_lock(&s->error_mutex); -@@ -3144,7 +3159,7 @@ static void migration_iteration_finish(MigrationState *s) - error_report("%s: Unknown ending state %d", __func__, s->state); - break; - } -- qemu_bh_schedule(s->cleanup_bh); -+ migrate_fd_cleanup_schedule(s); - qemu_mutex_unlock_iothread(); - } - -@@ -3279,7 +3294,7 @@ void migrate_fd_connect(MigrationState *s, Error *error_in) - bool resume = s->state == MIGRATION_STATUS_POSTCOPY_PAUSED; - - s->expected_downtime = s->parameters.downtime_limit; -- s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); -+ s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup_bh, s); - if (error_in) { - migrate_fd_error(s, error_in); - migrate_fd_cleanup(s); --- -2.19.1 - diff --git a/migration-dirty-bitmaps-change-bitmap-enumeration-method.patch b/migration-dirty-bitmaps-change-bitmap-enumeration-method.patch deleted file mode 100644 index c720cc1e6942f5b2bbb2812aae583ca9fd4c6b18..0000000000000000000000000000000000000000 --- a/migration-dirty-bitmaps-change-bitmap-enumeration-method.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 3a87d07722d4be717a97b59cfbc7b2ba27ca30b0 Mon Sep 17 00:00:00 2001 -From: John Snow -Date: Tue, 28 May 2019 19:33:31 -0400 -Subject: [PATCH] migration/dirty-bitmaps: change bitmap enumeration method -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Shift from looking at every root BDS to *every* BDS. This will migrate -bitmaps that are attached to blockdev created nodes instead of just ones -attached to emulated storage devices. - -Note that this will not migrate anonymous or internal-use bitmaps, as -those are defined as having no name. - -This will also fix the Coverity issues Peter Maydell has been asking -about for the past several releases, as well as fixing a real bug. - -Reported-by: Peter Maydell -Reported-by: Coverity 😅 -Reported-by: aihua liang -Reviewed-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: John Snow -Message-id: 20190514201926.10407-1-jsnow@redhat.com -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1652490 -Fixes: Coverity CID 1390625 -CC: Stefan Hajnoczi -Signed-off-by: John Snow -(cherry picked from commit 592203e7cfbd1ad261178431fcf390adfe8b16df) -Signed-off-by: Michael Roth ---- - migration/block-dirty-bitmap.c | 14 ++++---------- - 1 file changed, 4 insertions(+), 10 deletions(-) - -diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c -index d1bb863cb6..4a896a09eb 100644 ---- a/migration/block-dirty-bitmap.c -+++ b/migration/block-dirty-bitmap.c -@@ -273,7 +273,6 @@ static int init_dirty_bitmap_migration(void) - BlockDriverState *bs; - BdrvDirtyBitmap *bitmap; - DirtyBitmapMigBitmapState *dbms; -- BdrvNextIterator it; - Error *local_err = NULL; - - dirty_bitmap_mig_state.bulk_completed = false; -@@ -281,13 +280,8 @@ static int init_dirty_bitmap_migration(void) - dirty_bitmap_mig_state.prev_bitmap = NULL; - dirty_bitmap_mig_state.no_bitmaps = false; - -- for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { -- const char *drive_name = bdrv_get_device_or_node_name(bs); -- -- /* skip automatically inserted nodes */ -- while (bs && bs->drv && bs->implicit) { -- bs = backing_bs(bs); -- } -+ for (bs = bdrv_next_all_states(NULL); bs; bs = bdrv_next_all_states(bs)) { -+ const char *name = bdrv_get_device_or_node_name(bs); - - for (bitmap = bdrv_dirty_bitmap_next(bs, NULL); bitmap; - bitmap = bdrv_dirty_bitmap_next(bs, bitmap)) -@@ -296,7 +290,7 @@ static int init_dirty_bitmap_migration(void) - continue; - } - -- if (drive_name == NULL) { -+ if (!name || strcmp(name, "") == 0) { - error_report("Found bitmap '%s' in unnamed node %p. It can't " - "be migrated", bdrv_dirty_bitmap_name(bitmap), bs); - goto fail; -@@ -313,7 +307,7 @@ static int init_dirty_bitmap_migration(void) - - dbms = g_new0(DirtyBitmapMigBitmapState, 1); - dbms->bs = bs; -- dbms->node_name = drive_name; -+ dbms->node_name = name; - dbms->bitmap = bitmap; - dbms->total_sectors = bdrv_nb_sectors(bs); - dbms->sectors_per_chunk = CHUNK_SIZE * 8 * --- -2.19.1 - diff --git a/mirror-Only-mirror-granularity-aligned-chunks.patch b/mirror-Only-mirror-granularity-aligned-chunks.patch deleted file mode 100644 index 17a87ee2a9a4c29f6b451b2b216b14413e3876e9..0000000000000000000000000000000000000000 --- a/mirror-Only-mirror-granularity-aligned-chunks.patch +++ /dev/null @@ -1,84 +0,0 @@ -From d65d02614b6b0f6bcc64cd2a737b5204c0fc5304 Mon Sep 17 00:00:00 2001 -From: Max Reitz -Date: Mon, 5 Aug 2019 17:33:08 +0200 -Subject: [PATCH] mirror: Only mirror granularity-aligned chunks - -In write-blocking mode, all writes to the top node directly go to the -target. We must only mirror chunks of data that are aligned to the -job's granularity, because that is how the dirty bitmap works. -Therefore, the request alignment for writes must be the job's -granularity (in write-blocking mode). - -Unfortunately, this forces all reads and writes to have the same -granularity (we only need this alignment for writes to the target, not -the source), but that is something to be fixed another time. - -Cc: qemu-stable@nongnu.org -Signed-off-by: Max Reitz -Message-id: 20190805153308.2657-1-mreitz@redhat.com -Reviewed-by: Vladimir Sementsov-Ogievskiy -Fixes: d06107ade0ce74dc39739bac80de84b51ec18546 -Signed-off-by: Max Reitz -(cherry picked from commit 9adc1cb49af8d4e54f57980b1eed5c0a4b2dafa6) -Signed-off-by: Michael Roth ---- - block/mirror.c | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/block/mirror.c b/block/mirror.c -index ff15cfb197..062dc42867 100644 ---- a/block/mirror.c -+++ b/block/mirror.c -@@ -1477,6 +1477,15 @@ static void bdrv_mirror_top_child_perm(BlockDriverState *bs, BdrvChild *c, - *nshared = BLK_PERM_ALL; - } - -+static void bdrv_mirror_top_refresh_limits(BlockDriverState *bs, Error **errp) -+{ -+ MirrorBDSOpaque *s = bs->opaque; -+ -+ if (s && s->job && s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING) { -+ bs->bl.request_alignment = s->job->granularity; -+ } -+} -+ - /* Dummy node that provides consistent read to its users without requiring it - * from its backing file and that allows writes on the backing file chain. */ - static BlockDriver bdrv_mirror_top = { -@@ -1489,6 +1498,7 @@ static BlockDriver bdrv_mirror_top = { - .bdrv_co_block_status = bdrv_co_block_status_from_backing, - .bdrv_refresh_filename = bdrv_mirror_top_refresh_filename, - .bdrv_child_perm = bdrv_mirror_top_child_perm, -+ .bdrv_refresh_limits = bdrv_mirror_top_refresh_limits, - }; - - static void mirror_start_job(const char *job_id, BlockDriverState *bs, -@@ -1627,6 +1637,25 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs, - s->should_complete = true; - } - -+ /* -+ * Must be called before we start tracking writes, but after -+ * -+ * ((MirrorBlockJob *) -+ * ((MirrorBDSOpaque *) -+ * mirror_top_bs->opaque -+ * )->job -+ * )->copy_mode -+ * -+ * has the correct value. -+ * (We start tracking writes as of the following -+ * bdrv_create_dirty_bitmap() call.) -+ */ -+ bdrv_refresh_limits(mirror_top_bs, &local_err); -+ if (local_err) { -+ error_propagate(errp, local_err); -+ goto fail; -+ } -+ - s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp); - if (!s->dirty_bitmap) { - goto fail; --- -2.19.1 - diff --git a/pr-manager-Fix-invalid-g_free-crash-bug.patch b/pr-manager-Fix-invalid-g_free-crash-bug.patch deleted file mode 100644 index 7e0fc7ee4f5dfa4f445b32c1c21bf17348faad7e..0000000000000000000000000000000000000000 --- a/pr-manager-Fix-invalid-g_free-crash-bug.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 83f9b84c8bcb24265e25cd7f22e971e81cacebc6 Mon Sep 17 00:00:00 2001 -From: Markus Armbruster -Date: Thu, 22 Aug 2019 15:38:46 +0200 -Subject: [PATCH] pr-manager: Fix invalid g_free() crash bug -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -pr_manager_worker() passes its @opaque argument to g_free(). Wrong; -it points to pr_manager_worker()'s automatic @data. Broken when -commit 2f3a7ab39be converted @data from heap- to stack-allocated. Fix -by deleting the g_free(). - -Fixes: 2f3a7ab39bec4ba8022dc4d42ea641165b004e3e -Cc: qemu-stable@nongnu.org -Signed-off-by: Markus Armbruster -Reviewed-by: Philippe Mathieu-Daudé -Acked-by: Paolo Bonzini -Signed-off-by: Kevin Wolf -(cherry picked from commit 6b9d62c2a9e83bbad73fb61406f0ff69b46ff6f3) -Signed-off-by: Michael Roth ---- - scsi/pr-manager.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/scsi/pr-manager.c b/scsi/pr-manager.c -index d9f4e8c3ad..227bdfaad2 100644 ---- a/scsi/pr-manager.c -+++ b/scsi/pr-manager.c -@@ -38,7 +38,6 @@ static int pr_manager_worker(void *opaque) - int fd = data->fd; - int r; - -- g_free(data); - trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]); - - /* The reference was taken in pr_manager_execute. */ --- -2.19.1 - diff --git a/q35-Revert-to-kernel-irqchip.patch b/q35-Revert-to-kernel-irqchip.patch deleted file mode 100644 index 084217a233b199617c195386aa603eda757b7248..0000000000000000000000000000000000000000 --- a/q35-Revert-to-kernel-irqchip.patch +++ /dev/null @@ -1,132 +0,0 @@ -From c87759ce876a7a0b17c2bf4f0b964bd51f0ee871 Mon Sep 17 00:00:00 2001 -From: Alex Williamson -Date: Tue, 14 May 2019 14:14:41 -0600 -Subject: [PATCH] q35: Revert to kernel irqchip - -Commit b2fc91db8447 ("q35: set split kernel irqchip as default") changed -the default for the pc-q35-4.0 machine type to use split irqchip, which -turned out to have disasterous effects on vfio-pci INTx support. KVM -resampling irqfds are registered for handling these interrupts, but -these are non-functional in split irqchip mode. We can't simply test -for split irqchip in QEMU as userspace handling of this interrupt is a -significant performance regression versus KVM handling (GeForce GPUs -assigned to Windows VMs are non-functional without forcing MSI mode or -re-enabling kernel irqchip). - -The resolution is to revert the change in default irqchip mode in the -pc-q35-4.1 machine and create a pc-q35-4.0.1 machine for the 4.0-stable -branch. The qemu-q35-4.0 machine type should not be used in vfio-pci -configurations for devices requiring legacy INTx support without -explicitly modifying the VM configuration to use kernel irqchip. - -Link: https://bugs.launchpad.net/qemu/+bug/1826422 -Fixes: b2fc91db8447 ("q35: set split kernel irqchip as default") -Signed-off-by: Alex Williamson -Reviewed-by: Peter Xu -Message-Id: <155786484688.13873.6037015630912983760.stgit@gimli.home> -Signed-off-by: Paolo Bonzini -(cherry-picked from commit c87759ce876a7a0b17c2bf4f0b964bd51f0ee871) ---- - hw/core/machine.c | 3 +++ - hw/i386/pc.c | 3 +++ - hw/i386/pc_q35.c | 16 ++++++++++++++-- - include/hw/boards.h | 3 +++ - include/hw/i386/pc.h | 3 +++ - 5 files changed, 26 insertions(+), 2 deletions(-) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 16ba667434..f1a0f45f9c 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -24,6 +24,9 @@ - #include "hw/pci/pci.h" - #include "hw/mem/nvdimm.h" - -+GlobalProperty hw_compat_4_0_1[] = {}; -+const size_t hw_compat_4_0_1_len = G_N_ELEMENTS(hw_compat_4_0_1); -+ - GlobalProperty hw_compat_4_0[] = {}; - const size_t hw_compat_4_0_len = G_N_ELEMENTS(hw_compat_4_0); - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 2632b73f80..edc240bcbf 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -110,6 +110,9 @@ struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; - /* Physical Address of PVH entry point read from kernel ELF NOTE */ - static size_t pvh_start_addr; - -+GlobalProperty pc_compat_4_0_1[] = {}; -+const size_t pc_compat_4_0_1_len = G_N_ELEMENTS(pc_compat_4_0_1); -+ - GlobalProperty pc_compat_4_0[] = {}; - const size_t pc_compat_4_0_len = G_N_ELEMENTS(pc_compat_4_0); - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 37dd350511..dcddc64662 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -357,7 +357,7 @@ static void pc_q35_machine_options(MachineClass *m) - m->units_per_default_bus = 1; - m->default_machine_opts = "firmware=bios-256k.bin"; - m->default_display = "std"; -- m->default_kernel_irqchip_split = true; -+ m->default_kernel_irqchip_split = false; - m->no_floppy = 1; - machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE); - machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE); -@@ -374,10 +374,22 @@ static void pc_q35_4_1_machine_options(MachineClass *m) - DEFINE_Q35_MACHINE(v4_1, "pc-q35-4.1", NULL, - pc_q35_4_1_machine_options); - --static void pc_q35_4_0_machine_options(MachineClass *m) -+static void pc_q35_4_0_1_machine_options(MachineClass *m) - { - pc_q35_4_1_machine_options(m); - m->alias = NULL; -+ compat_props_add(m->compat_props, hw_compat_4_0_1, hw_compat_4_0_1_len); -+ compat_props_add(m->compat_props, pc_compat_4_0_1, pc_compat_4_0_1_len); -+} -+ -+DEFINE_Q35_MACHINE(v4_0_1, "pc-q35-4.0.1", NULL, -+ pc_q35_4_0_1_machine_options); -+ -+static void pc_q35_4_0_machine_options(MachineClass *m) -+{ -+ pc_q35_4_0_1_machine_options(m); -+ m->default_kernel_irqchip_split = true; -+ m->alias = NULL; - compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len); - compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len); - } -diff --git a/include/hw/boards.h b/include/hw/boards.h -index 6f7916f88f..6ff02bf3e4 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -292,6 +292,9 @@ struct MachineState { - } \ - type_init(machine_initfn##_register_types) - -+extern GlobalProperty hw_compat_4_0_1[]; -+extern const size_t hw_compat_4_0_1_len; -+ - extern GlobalProperty hw_compat_4_0[]; - extern const size_t hw_compat_4_0_len; - -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 43df7230a2..5d5636241e 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -293,6 +293,9 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); - int e820_get_num_entries(void); - bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); - -+extern GlobalProperty pc_compat_4_0_1[]; -+extern const size_t pc_compat_4_0_1_len; -+ - extern GlobalProperty pc_compat_4_0[]; - extern const size_t pc_compat_4_0_len; - --- -2.19.1 - diff --git a/qcow2-Add-errp-to-preallocate_co.patch b/qcow2-Add-errp-to-preallocate_co.patch deleted file mode 100644 index 0b3dc7172270f7d9038c9ac5ea6ca4ae93a2d30d..0000000000000000000000000000000000000000 --- a/qcow2-Add-errp-to-preallocate_co.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 360bd07471dfd1830246e8403ffdc9ba9d82f9d4 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Mon, 15 Apr 2019 16:56:07 +0200 -Subject: [PATCH] qcow2: Add errp to preallocate_co() - -We'll add a bdrv_co_truncate() call in the next patch which can return -an Error that we don't want to discard. So add an errp parameter to -preallocate_co(). - -Cc: qemu-stable@nongnu.org -Signed-off-by: Kevin Wolf -Reviewed-by: Eric Blake -(cherry-picked from commit 360bd07471dfd1830246e8403ffdc9ba9d82f9d4) ---- - block/qcow2.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/block/qcow2.c b/block/qcow2.c -index dfac74c264..b4f9f5a240 100644 ---- a/block/qcow2.c -+++ b/block/qcow2.c -@@ -2721,7 +2721,7 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, - * Returns: 0 on success, -errno on failure. - */ - static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset, -- uint64_t new_length) -+ uint64_t new_length, Error **errp) - { - BDRVQcow2State *s = bs->opaque; - uint64_t bytes; -@@ -2738,6 +2738,7 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset, - ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes, - &host_offset, &meta); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Allocating clusters failed"); - return ret; - } - -@@ -2746,6 +2747,7 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset, - - ret = qcow2_alloc_cluster_link_l2(bs, meta); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Mapping clusters failed"); - qcow2_free_any_clusters(bs, meta->alloc_offset, - meta->nb_clusters, QCOW2_DISCARD_NEVER); - return ret; -@@ -2775,6 +2777,7 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset, - ret = bdrv_pwrite(s->data_file, (host_offset + cur_bytes) - 1, - &data, 1); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Writing to EOF failed"); - return ret; - } - } -@@ -3748,9 +3751,8 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset, - break; - - case PREALLOC_MODE_METADATA: -- ret = preallocate_co(bs, old_length, offset); -+ ret = preallocate_co(bs, old_length, offset, errp); - if (ret < 0) { -- error_setg_errno(errp, -ret, "Preallocation failed"); - goto fail; - } - break; -@@ -3766,9 +3768,8 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset, - /* With a data file, preallocation means just allocating the metadata - * and forwarding the truncate request to the data file */ - if (has_data_file(bs)) { -- ret = preallocate_co(bs, old_length, offset); -+ ret = preallocate_co(bs, old_length, offset, errp); - if (ret < 0) { -- error_setg_errno(errp, -ret, "Preallocation failed"); - goto fail; - } - break; --- -2.19.1 - diff --git a/qcow2-Avoid-COW-during-metadata-preallocation.patch b/qcow2-Avoid-COW-during-metadata-preallocation.patch deleted file mode 100644 index 483d1199045004c8cbdabf467db08f664fa09bb0..0000000000000000000000000000000000000000 --- a/qcow2-Avoid-COW-during-metadata-preallocation.patch +++ /dev/null @@ -1,38 +0,0 @@ -From f29fbf7c6b1c9a84f6931c1c222716fbe073e6e4 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Mon, 15 Apr 2019 16:25:01 +0200 -Subject: [PATCH] qcow2: Avoid COW during metadata preallocation - -Limiting the allocation to INT_MAX bytes isn't particularly clever -because it means that the final cluster will be a partial cluster which -will be completed through a COW operation. This results in unnecessary -data read and write requests which lead to an unwanted non-sparse -filesystem block for metadata preallocation. - -Align the maximum allocation size down to the cluster size to avoid this -situation. - -Cc: qemu-stable@nongnu.org -Signed-off-by: Kevin Wolf -Reviewed-by: Eric Blake -(cherry-picked from commit f29fbf7c6b1c9a84f6931c1c222716fbe073e6e4) ---- - block/qcow2.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/block/qcow2.c b/block/qcow2.c -index 3ace3b2209..dfac74c264 100644 ---- a/block/qcow2.c -+++ b/block/qcow2.c -@@ -2734,7 +2734,7 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset, - bytes = new_length - offset; - - while (bytes) { -- cur_bytes = MIN(bytes, INT_MAX); -+ cur_bytes = MIN(bytes, QEMU_ALIGN_DOWN(INT_MAX, s->cluster_size)); - ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes, - &host_offset, &meta); - if (ret < 0) { --- -2.19.1 - diff --git a/qcow2-Fix-full-preallocation-with-external-data-file.patch b/qcow2-Fix-full-preallocation-with-external-data-file.patch deleted file mode 100644 index 12ad5215de829a101f03c7996b5c9078c5d3c606..0000000000000000000000000000000000000000 --- a/qcow2-Fix-full-preallocation-with-external-data-file.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 718c0fce2f56755a8d8f737607779a98aa6e7cc4 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Mon, 15 Apr 2019 16:34:30 +0200 -Subject: [PATCH] qcow2: Fix full preallocation with external data file - -preallocate_co() already gave the data file the full size without -forwarding the requested preallocation mode to the protocol. When -bdrv_co_truncate() was called later with the preallocation mode, the -file didn't actually grow any more, so the data file stayed unallocated -even if full preallocation was requested. - -Pass the right preallocation mode to preallocate_co() and remove the -second bdrv_co_truncate() to fix this. As a side effect, the ugly -one-byte write in preallocate_co() is replaced with a truncate call, -now leaving the last block unallocated on the protocol level as it -should be. - -Cc: qemu-stable@nongnu.org -Signed-off-by: Kevin Wolf -Reviewed-by: Eric Blake -(cherry-picked from commit 718c0fce2f56755a8d8f737607779a98aa6e7cc4) ---- - block/qcow2.c | 41 +++++++++++++++++++++++------------------ - 1 file changed, 23 insertions(+), 18 deletions(-) - -diff --git a/block/qcow2.c b/block/qcow2.c -index b4f9f5a240..7fbef97aab 100644 ---- a/block/qcow2.c -+++ b/block/qcow2.c -@@ -2721,11 +2721,13 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, - * Returns: 0 on success, -errno on failure. - */ - static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset, -- uint64_t new_length, Error **errp) -+ uint64_t new_length, PreallocMode mode, -+ Error **errp) - { - BDRVQcow2State *s = bs->opaque; - uint64_t bytes; - uint64_t host_offset = 0; -+ int64_t file_length; - unsigned int cur_bytes; - int ret; - QCowL2Meta *meta; -@@ -2772,12 +2774,19 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset, - * all of the allocated clusters (otherwise we get failing reads after - * EOF). Extend the image to the last allocated sector. - */ -- if (host_offset != 0) { -- uint8_t data = 0; -- ret = bdrv_pwrite(s->data_file, (host_offset + cur_bytes) - 1, -- &data, 1); -+ file_length = bdrv_getlength(s->data_file->bs); -+ if (file_length < 0) { -+ error_setg_errno(errp, -file_length, "Could not get file size"); -+ return file_length; -+ } -+ -+ if (host_offset + cur_bytes > file_length) { -+ if (mode == PREALLOC_MODE_METADATA) { -+ mode = PREALLOC_MODE_OFF; -+ } -+ ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, mode, -+ errp); - if (ret < 0) { -- error_setg_errno(errp, -ret, "Writing to EOF failed"); - return ret; - } - } -@@ -3748,10 +3757,16 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset, - - switch (prealloc) { - case PREALLOC_MODE_OFF: -+ if (has_data_file(bs)) { -+ ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp); -+ if (ret < 0) { -+ goto fail; -+ } -+ } - break; - - case PREALLOC_MODE_METADATA: -- ret = preallocate_co(bs, old_length, offset, errp); -+ ret = preallocate_co(bs, old_length, offset, prealloc, errp); - if (ret < 0) { - goto fail; - } -@@ -3768,7 +3783,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset, - /* With a data file, preallocation means just allocating the metadata - * and forwarding the truncate request to the data file */ - if (has_data_file(bs)) { -- ret = preallocate_co(bs, old_length, offset, errp); -+ ret = preallocate_co(bs, old_length, offset, prealloc, errp); - if (ret < 0) { - goto fail; - } -@@ -3883,16 +3898,6 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset, - - bs->total_sectors = offset / BDRV_SECTOR_SIZE; - -- if (has_data_file(bs)) { -- if (prealloc == PREALLOC_MODE_METADATA) { -- prealloc = PREALLOC_MODE_OFF; -- } -- ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp); -- if (ret < 0) { -- goto fail; -- } -- } -- - /* write updated header.size */ - offset = cpu_to_be64(offset); - ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size), --- -2.19.1 - diff --git a/qcow2-Fix-qcow2_make_empty-with-external-data-file.patch b/qcow2-Fix-qcow2_make_empty-with-external-data-file.patch deleted file mode 100644 index 636e6e7e4868fa435ad62ed9897afb6ba266a15b..0000000000000000000000000000000000000000 --- a/qcow2-Fix-qcow2_make_empty-with-external-data-file.patch +++ /dev/null @@ -1,49 +0,0 @@ -From db04524f820582ebf1189223b6378de238511da1 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Mon, 29 Apr 2019 12:52:21 +0200 -Subject: [PATCH] qcow2: Fix qcow2_make_empty() with external data file - -make_completely_empty() is an optimisated path for bdrv_make_empty() -where completely new metadata is created inside the image file instead -of going through all clusters and discarding them. For an external data -file, however, we actually need to do discard operations on the data -file; just overwriting the qcow2 file doesn't get rid of the data. - -The necessary slow path with an explicit discard operation already -exists for other cases. Use it for external data files, too. - -Cc: qemu-stable@nongnu.org -Signed-off-by: Kevin Wolf -Reviewed-by: Eric Blake -(cherry-picked from commit db04524f820582ebf1189223b6378de238511da1) ---- - block/qcow2.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/block/qcow2.c b/block/qcow2.c -index 7fbef97aab..840f289a48 100644 ---- a/block/qcow2.c -+++ b/block/qcow2.c -@@ -4384,14 +4384,17 @@ static int qcow2_make_empty(BlockDriverState *bs) - - if (s->qcow_version >= 3 && !s->snapshots && !s->nb_bitmaps && - 3 + l1_clusters <= s->refcount_block_size && -- s->crypt_method_header != QCOW_CRYPT_LUKS) { -+ s->crypt_method_header != QCOW_CRYPT_LUKS && -+ !has_data_file(bs)) { - /* The following function only works for qcow2 v3 images (it - * requires the dirty flag) and only as long as there are no - * features that reserve extra clusters (such as snapshots, - * LUKS header, or persistent bitmaps), because it completely - * empties the image. Furthermore, the L1 table and three - * additional clusters (image header, refcount table, one -- * refcount block) have to fit inside one refcount block. */ -+ * refcount block) have to fit inside one refcount block. It -+ * only resets the image file, i.e. does not work with an -+ * external data file. */ - return make_completely_empty(bs); - } - --- -2.19.1 - diff --git a/qcow2-Fix-the-calculation-of-the-maximum-L2-cache-size.patch b/qcow2-Fix-the-calculation-of-the-maximum-L2-cache-size.patch deleted file mode 100644 index 54c45123a82ba9e926fc1697035de74c656a3175..0000000000000000000000000000000000000000 --- a/qcow2-Fix-the-calculation-of-the-maximum-L2-cache-size.patch +++ /dev/null @@ -1,59 +0,0 @@ -From cb7630af20d353cbde66ddfb14d858737ffaf877 Mon Sep 17 00:00:00 2001 -From: Alberto Garcia -Date: Fri, 16 Aug 2019 15:17:42 +0300 -Subject: [PATCH] qcow2: Fix the calculation of the maximum L2 cache size - -The size of the qcow2 L2 cache defaults to 32 MB, which can be easily -larger than the maximum amount of L2 metadata that the image can have. -For example: with 64 KB clusters the user would need a qcow2 image -with a virtual size of 256 GB in order to have 32 MB of L2 metadata. - -Because of that, since commit b749562d9822d14ef69c9eaa5f85903010b86c30 -we forbid the L2 cache to become larger than the maximum amount of L2 -metadata for the image, calculated using this formula: - - uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8); - -The problem with this formula is that the result should be rounded up -to the cluster size because an L2 table on disk always takes one full -cluster. - -For example, a 1280 MB qcow2 image with 64 KB clusters needs exactly -160 KB of L2 metadata, but we need 192 KB on disk (3 clusters) even if -the last 32 KB of those are not going to be used. - -However QEMU rounds the numbers down and only creates 2 cache tables -(128 KB), which is not enough for the image. - -A quick test doing 4KB random writes on a 1280 MB image gives me -around 500 IOPS, while with the correct cache size I get 16K IOPS. - -Cc: qemu-stable@nongnu.org -Signed-off-by: Alberto Garcia -Signed-off-by: Kevin Wolf -(cherry picked from commit b70d08205b2e4044c529eefc21df2c8ab61b473b) -Signed-off-by: Michael Roth ---- - block/qcow2.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/block/qcow2.c b/block/qcow2.c -index 840f289a48..c80f48a02b 100644 ---- a/block/qcow2.c -+++ b/block/qcow2.c -@@ -831,7 +831,11 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, - bool l2_cache_entry_size_set; - int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size; - uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; -- uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8); -+ uint64_t max_l2_entries = DIV_ROUND_UP(virtual_disk_size, s->cluster_size); -+ /* An L2 table is always one cluster in size so the max cache size -+ * should be a multiple of the cluster size. */ -+ uint64_t max_l2_cache = ROUND_UP(max_l2_entries * sizeof(uint64_t), -+ s->cluster_size); - - combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE); - l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE); --- -2.19.1 - diff --git a/qemu-4.0.0.tar.xz b/qemu-4.0.1.tar.xz similarity index 80% rename from qemu-4.0.0.tar.xz rename to qemu-4.0.1.tar.xz index dd626a42feee356cefd342d5a1d5f34abae5656e..703a6c2ff7a99ef107bc55570fc0d52b5e79f0a9 100644 Binary files a/qemu-4.0.0.tar.xz and b/qemu-4.0.1.tar.xz differ diff --git a/qemu.spec b/qemu.spec index f7bcb642f4f10ac1184c8db2d034f508e4f5810e..80f353832c1bedfcb54ee0b89ea23197bc081aef 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu -Version: 4.0.0 -Release: 6 +Version: 4.0.1 +Release: 8 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY @@ -11,84 +11,42 @@ Source2: 99-qemu-guest-agent.rules Source3: bridge.conf Patch0001: qxl-check-release-info-object.patch -Patch0002: target-i386-define-md-clear-bit.patch -Patch0003: Revert-Enable-build-and-install-of-our-rST-docs.patch -Patch0004: ARM64-record-vtimer-tick-when-cpu-is-stopped.patch -Patch0005: pl011-reset-read-FIFO-when-UARTTIMSC-0-UARTICR-0xfff.patch -Patch0006: pl031-support-rtc-timer-property-for-pl031.patch -Patch0007: vhost-cancel-migration-when-vhost-user-restarted.patch -Patch0008: qcow2-fix-memory-leak-in-qcow2_read_extensions.patch -Patch0009: hw-arm-expose-host-CPU-frequency-info-to-guest.patch -Patch0010: block-Fix-AioContext-switch-for-bs-drv-NULL.patch -Patch0011: cutils-Fix-size_to_str-on-32-bit-platforms.patch -Patch0012: qcow2-Avoid-COW-during-metadata-preallocation.patch -Patch0013: qcow2-Add-errp-to-preallocate_co.patch -Patch0014: qcow2-Fix-full-preallocation-with-external-data-file.patch -Patch0015: qcow2-Fix-qcow2_make_empty-with-external-data-file.patch -Patch0016: megasas-fix-mapped-frame-size.patch -Patch0017: kbd-state-fix-autorepeat-handling.patch -Patch0018: block-file-posix-Unaligned-O_DIRECT-block-status.patch -Patch0019: hw-add-compat-machines-for-4.1.patch -Patch0020: usb-tablet-fix-serial-compat-property.patch -Patch0021: q35-Revert-to-kernel-irqchip.patch -Patch0022: hw-Nuke-hw_compat_4_0_1-and-pc_compat_4_0_1.patch -Patch0023: vl-Fix-drive-blockdev-persistent-reservation-management.patch -Patch0024: vhost-fix-vhost_log-size-overflow-during-migration.patch -Patch0025: virtio-pci-fix-missing-device-properties.patch -Patch0026: i386-acpi-fix-gint-overflow-in-crs_range_compare.patch -Patch0027: ioapic-kvm-Skip-route-updates-for-masked-pins.patch -Patch0028: i386-acpi-show-PCI-Express-bus-on-pxb-pcie-expanders.patch -Patch0029: virtio-balloon-fix-QEMU-4.0-config-size-migration-in.patch -Patch0030: virtio-balloon-Fix-wrong-sign-extension-of-PFNs.patch -Patch0031: virtio-balloon-Fix-QEMU-crashes-on-pagesize-BALLOON_.patch -Patch0032: virtio-balloon-Simplify-deflate-with-pbp.patch -Patch0033: virtio-balloon-Better-names-for-offset-variables.patch -Patch0034: virtio-balloon-Rework-pbp-tracking-data.patch -Patch0035: virtio-balloon-Use-temporary-PBP-only.patch -Patch0036: virtio-balloon-don-t-track-subpages-for-the-PBP.patch -Patch0037: virtio-balloon-free-pbp-more-aggressively.patch -Patch0038: qemu-bridge-helper-restrict-interface-name-to-IFNAMS.patch -Patch0039: qemu-bridge-helper-move-repeating-code-in-parse_acl.patch -Patch0040: smbios-Add-missing-member-of-type-4-for-smbios-3.0.patch -Patch0041: hw-arm-virt-Introduce-cpu-topology-support.patch -Patch0042: hw-arm64-add-vcpu-cache-info-support.patch -Patch0043: xhci-Fix-memory-leak-in-xhci_address_slot.patch -Patch0044: xhci-Fix-memory-leak-in-xhci_kick_epctx.patch -Patch0045: ehci-fix-queue-dev-null-ptr-dereference.patch -Patch0046: memory-unref-the-memory-region-in-simplify-flatview.patch -Patch0047: scsi-lsi-exit-infinite-loop-while-executing-script.patch -Patch0048: util-async-hold-AioContext-ref-to-prevent-use-after-free.patch -Patch0049: vhost-user-scsi-prevent-using-uninitialized-vqs.patch -Patch0050: cpu-add-Kunpeng-920-cpu-support.patch -Patch0051: cpu-parse-feature-to-avoid-failure.patch -Patch0052: cpu-add-Cortex-A72-processor-kvm-target-support.patch -Patch0053: vnc-fix-memory-leak-when-vnc-disconnect.patch -Patch0054: pcie-disable-the-PCI_EXP_LINKSTA_DLLA-cap.patch -Patch0055: blockdev-backup-don-t-check-aio_context-too-early.patch -Patch0056: migration-dirty-bitmaps-change-bitmap-enumeration-method.patch -Patch0057: target-i386-add-MDS-NO-feature.patch -Patch0058: usbredir-fix-buffer-overflow-on-vmload.patch -Patch0059: util-hbitmap-update-orig_size-on-truncate.patch -Patch0060: mirror-Only-mirror-granularity-aligned-chunks.patch -Patch0061: qcow2-Fix-the-calculation-of-the-maximum-L2-cache-size.patch -Patch0062: dma-helpers-ensure-AIO-callback-is-invoked-after-can.patch -Patch0063: pr-manager-Fix-invalid-g_free-crash-bug.patch -Patch0064: block-create-Do-not-abort-if-a-block-driver-is-not-available.patch -Patch0065: block-nfs-tear-down-aio-before-nfs_close.patch -Patch0066: blockjob-update-nodes-head-while-removing-all-bdrv.patch -Patch0067: slirp-Fix-heap-overflow-in-ip_reass-on-big-packet-input.patch -Patch0068: slirp-ip_reass-Fix-use-after-free.patch -Patch0069: hw-core-loader-Fix-possible-crash-in-rom_copy.patch -Patch0070: migration-Fix-use-after-free-during-process-exit.patch -Patch0071: linux-headers-update-against-KVM-ARM-Fix-256-vcpus.patch -Patch0072: intc-arm_gic-Support-IRQ-injection-for-more-than-256.patch -Patch0073: ARM-KVM-Check-KVM_CAP_ARM_IRQ_LINE_LAYOUT_2-for-smp_.patch -Patch0074: 9pfs-local-Fix-possible-memory-leak-in-local_link.patch -Patch0075: scsi-disk-define-props-in-scsi_block_disk-to-avoid-memleaks.patch -Patch0076: arm-translate-a64-fix-uninitialized-variable-warning.patch -Patch0077: nbd-fix-uninitialized-variable-warning.patch -Patch0078: xhci-Fix-memory-leak-in-xhci_kick_epctx-when-poweroff.patch -Patch0079: block-fix-memleaks-in-bdrv_refresh_filename.patch +Patch0002: ARM64-record-vtimer-tick-when-cpu-is-stopped.patch +Patch0003: pl011-reset-read-FIFO-when-UARTTIMSC-0-UARTICR-0xfff.patch +Patch0004: pl031-support-rtc-timer-property-for-pl031.patch +Patch0005: vhost-cancel-migration-when-vhost-user-restarted.patch +Patch0006: qcow2-fix-memory-leak-in-qcow2_read_extensions.patch +Patch0007: hw-arm-expose-host-CPU-frequency-info-to-guest.patch +Patch0008: qemu-bridge-helper-restrict-interface-name-to-IFNAMS.patch +Patch0009: qemu-bridge-helper-move-repeating-code-in-parse_acl.patch +Patch0010: smbios-Add-missing-member-of-type-4-for-smbios-3.0.patch +Patch0011: hw-arm-virt-Introduce-cpu-topology-support.patch +Patch0012: hw-arm64-add-vcpu-cache-info-support.patch +Patch0013: xhci-Fix-memory-leak-in-xhci_address_slot.patch +Patch0014: xhci-Fix-memory-leak-in-xhci_kick_epctx.patch +Patch0015: ehci-fix-queue-dev-null-ptr-dereference.patch +Patch0016: memory-unref-the-memory-region-in-simplify-flatview.patch +Patch0017: util-async-hold-AioContext-ref-to-prevent-use-after-free.patch +Patch0018: vhost-user-scsi-prevent-using-uninitialized-vqs.patch +Patch0019: cpu-add-Kunpeng-920-cpu-support.patch +Patch0020: cpu-parse-feature-to-avoid-failure.patch +Patch0021: cpu-add-Cortex-A72-processor-kvm-target-support.patch +Patch0022: vnc-fix-memory-leak-when-vnc-disconnect.patch +Patch0023: pcie-disable-the-PCI_EXP_LINKSTA_DLLA-cap.patch +Patch0024: linux-headers-update-against-KVM-ARM-Fix-256-vcpus.patch +Patch0025: intc-arm_gic-Support-IRQ-injection-for-more-than-256.patch +Patch0026: ARM-KVM-Check-KVM_CAP_ARM_IRQ_LINE_LAYOUT_2-for-smp_.patch +Patch0027: 9pfs-local-Fix-possible-memory-leak-in-local_link.patch +Patch0028: scsi-disk-define-props-in-scsi_block_disk-to-avoid-memleaks.patch +Patch0029: arm-translate-a64-fix-uninitialized-variable-warning.patch +Patch0030: nbd-fix-uninitialized-variable-warning.patch +Patch0031: xhci-Fix-memory-leak-in-xhci_kick_epctx-when-poweroff.patch +Patch0032: block-fix-memleaks-in-bdrv_refresh_filename.patch +Patch0033: iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch +Patch0034: tcp_emu-Fix-oob-access.patch +Patch0035: slirp-use-correct-size-while-emulating-IRC-commands.patch +Patch0036: slirp-use-correct-size-while-emulating-commands.patch +Patch0037: tcp_emu-fix-unsafe-snprintf-usages.patch BuildRequires: flex BuildRequires: bison @@ -97,6 +55,7 @@ BuildRequires: perl-podlators BuildRequires: kernel BuildRequires: chrpath BuildRequires: gettext +BuildRequires: python-sphinx BuildRequires: zlib-devel BuildRequires: gtk3-devel @@ -212,6 +171,7 @@ buildldflags="VL_LDFLAGS=-Wl,--build-id" --interp-prefix=%{_prefix}/qemu-%%M \ --firmwarepath=%{_datadir}/%{name} \ --with-pkgversion=%{name}-%{version}-%{release} \ + --python=/usr/bin/python3 \ --disable-strip \ --disable-werror \ --disable-slirp \ @@ -388,6 +348,7 @@ getent passwd qemu >/dev/null || \ %doc %{qemudocdir}/qemu-ga-ref.txt %doc %{qemudocdir}/qemu-qmp-ref.html %doc %{qemudocdir}/qemu-qmp-ref.txt +%doc %{qemudocdir}/interop %doc %{qemudocdir}/README %doc %{qemudocdir}/Changelog %{_mandir}/man1/qemu.1* @@ -419,6 +380,15 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Wed Mar 11 2020 backport from qemu upstream +- tcp_emu: Fix oob access +- slirp: use correct size while emulating IRC commands +- slirp: use correct size while emulating commands +- tcp_emu: fix unsafe snprintf() usages + +* Mon Mar 9 2020 backport from qemu upstream +- iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711) + * Thu Feb 6 2020 Huawei Technologies Co., Ltd. - spec: remove fno-inline option for configure @@ -438,24 +408,8 @@ getent passwd qemu >/dev/null || \ - ARM: KVM: Check KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 for smp_cpus > 256 * Thu Dec 12 2019 backport from qemu upstream v4.0.1 release -- usb-tablet: fix serial compat property -- blockdev-backup: don't check aio_context too early -- migration/dirty-bitmaps: change bitmap enumeration method -- target/i386: add MDS-NO feature -- usbredir: fix buffer-overflow on vmload - tpm: Exit in reset when backend indicates failure - tpm_emulator: Translate TPM error codes to strings -- util/hbitmap: update orig_size on truncate -- mirror: Only mirror granularity-aligned chunks -- qcow2: Fix the calculation of the maximum L2 cache size -- dma-helpers: ensure AIO callback is invoked after cancellation -- pr-manager: Fix invalid g_free() crash bug -- block/nfs: tear down aio before nfs_close -- blockjob: update nodes head while removing all bdrv -- slirp: Fix heap overflow in ip_reass on big packet input -- slirp: ip_reass: Fix use after free -- hw/core/loader: Fix possible crash in rom_copy() -- migration: Fix use-after-free during process exit * Thu Oct 17 2019 backport from qemu upstream - vnc-fix-memory-leak-when-vnc-disconnect.patch @@ -463,7 +417,6 @@ getent passwd qemu >/dev/null || \ * Mon Sep 9 2019 backport from qemu upstream - ehci-fix-queue-dev-null-ptr-dereference.patch - memory-unref-the-memory-region-in-simplify-flatview.patch -- scsi-lsi-exit-infinite-loop-while-executing-script-C.patch - util-async-hold-AioContext-ref-to-prevent-use-after-.patch - vhost-user-scsi-prevent-using-uninitialized-vqs.patch @@ -486,34 +439,6 @@ getent passwd qemu >/dev/null || \ - qemu-bridge-helper: restrict interface name to IFNAMSIZ - qemu-bridge-helper: move repeating code in parse_acl_file -* Wed Jul 31 2019 backport from qemu upstream -- block: Fix AioContext switch for bs->drv == NULL -- cutils: Fix size_to_str() on 32-bit platforms -- qcow2: Avoid COW during metadata preallocation -- qcow2: Add errp to preallocate_co() -- qcow2: qcow2: Fix full preallocation with external data file -- qcow2: Fix qcow2_make_empty() with external data file -- megasas: fix mapped frame size -- kbd-state: fix autorepeat handling -- block/file-posix: Unaligned O_DIRECT block-status -- hw: add compat machines for 4.1 -- q35: Revert to kernel irqchip -- hw: Nuke hw_compat_4_0_1 and pc_compat_4_0_1 -- vl: Fix -drive / -blockdev persistent reservation management -- vhost: fix vhost_log size overflow during migration -- virtio-pci: fix missing device properties -- i386/acpi: fix gint overflow in crs_range_compare -- ioapic: kvm: Skip route updates for masked pins -- i386/acpi: show PCI Express bus on pxb-pcie expanders -- virtio-balloon: Fix wrong sign extension of PFNs -- virtio-balloon: Fix QEMU crashes on pagesize > BALLOON_PAGE_SIZE -- virtio-balloon: Simplify deflate with pbp -- virtio-balloon: Better names for offset variables in inflate/deflate code -- virtio-balloon: Rework pbp tracking data -- virtio-balloon: Use temporary PBP only -- virtio-balloon: virtio-balloon: don't track subpages for the PBP -- virtio-balloon: free pbp more aggressively - * Tue Jul 30 2019 Huawei Technologies Co., Ltd. -Date: Wed, 14 Aug 2019 17:35:21 +0530 -Subject: [PATCH 3/5] scsi: lsi: exit infinite loop while executing script - (CVE-2019-12068) - -When executing script in lsi_execute_script(), the LSI scsi adapter -emulator advances 's->dsp' index to read next opcode. This can lead -to an infinite loop if the next opcode is empty. Move the existing -loop exit after 10k iterations so that it covers no-op opcodes as -well. - -Reported-by: Bugs SysSec -Signed-off-by: Paolo Bonzini -Signed-off-by: Prasad J Pandit -Signed-off-by: Paolo Bonzini -(cherry-picked from commit de594e47659029316bbf9391efb79da0a1a08e08) ---- - hw/scsi/lsi53c895a.c | 41 +++++++++++++++++++++++++++-------------- - 1 file changed, 27 insertions(+), 14 deletions(-) - -diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c -index da7239d..d3380b6 100644 ---- a/hw/scsi/lsi53c895a.c -+++ b/hw/scsi/lsi53c895a.c -@@ -184,6 +184,9 @@ static const char *names[] = { - /* Flag set if this is a tagged command. */ - #define LSI_TAG_VALID (1 << 16) - -+/* Maximum instructions to process. */ -+#define LSI_MAX_INSN 10000 -+ - typedef struct lsi_request { - SCSIRequest *req; - uint32_t tag; -@@ -1131,7 +1134,21 @@ static void lsi_execute_script(LSIState *s) - - s->istat1 |= LSI_ISTAT1_SRUN; - again: -- insn_processed++; -+ if (++insn_processed > LSI_MAX_INSN) { -+ /* Some windows drivers make the device spin waiting for a memory -+ location to change. If we have been executed a lot of code then -+ assume this is the case and force an unexpected device disconnect. -+ This is apparently sufficient to beat the drivers into submission. -+ */ -+ if (!(s->sien0 & LSI_SIST0_UDC)) { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "lsi_scsi: inf. loop with UDC masked"); -+ } -+ lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0); -+ lsi_disconnect(s); -+ trace_lsi_execute_script_stop(); -+ return; -+ } - insn = read_dword(s, s->dsp); - if (!insn) { - /* If we receive an empty opcode increment the DSP by 4 bytes -@@ -1568,19 +1585,7 @@ again: - } - } - } -- if (insn_processed > 10000 && s->waiting == LSI_NOWAIT) { -- /* Some windows drivers make the device spin waiting for a memory -- location to change. If we have been executed a lot of code then -- assume this is the case and force an unexpected device disconnect. -- This is apparently sufficient to beat the drivers into submission. -- */ -- if (!(s->sien0 & LSI_SIST0_UDC)) { -- qemu_log_mask(LOG_GUEST_ERROR, -- "lsi_scsi: inf. loop with UDC masked"); -- } -- lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0); -- lsi_disconnect(s); -- } else if (s->istat1 & LSI_ISTAT1_SRUN && s->waiting == LSI_NOWAIT) { -+ if (s->istat1 & LSI_ISTAT1_SRUN && s->waiting == LSI_NOWAIT) { - if (s->dcntl & LSI_DCNTL_SSM) { - lsi_script_dma_interrupt(s, LSI_DSTAT_SSI); - } else { -@@ -1968,6 +1973,10 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) - case 0x2f: /* DSP[24:31] */ - s->dsp &= 0x00ffffff; - s->dsp |= val << 24; -+ /* -+ * FIXME: if s->waiting != LSI_NOWAIT, this will only execute one -+ * instruction. Is this correct? -+ */ - if ((s->dmode & LSI_DMODE_MAN) == 0 - && (s->istat1 & LSI_ISTAT1_SRUN) == 0) - lsi_execute_script(s); -@@ -1986,6 +1995,10 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) - break; - case 0x3b: /* DCNTL */ - s->dcntl = val & ~(LSI_DCNTL_PFF | LSI_DCNTL_STD); -+ /* -+ * FIXME: if s->waiting != LSI_NOWAIT, this will only execute one -+ * instruction. Is this correct? -+ */ - if ((val & LSI_DCNTL_STD) && (s->istat1 & LSI_ISTAT1_SRUN) == 0) - lsi_execute_script(s); - break; --- -1.8.3.1 - diff --git a/slirp-Fix-heap-overflow-in-ip_reass-on-big-packet-input.patch b/slirp-Fix-heap-overflow-in-ip_reass-on-big-packet-input.patch deleted file mode 100644 index 3ebf0297748c77e23667cd1b641de192fb13d06e..0000000000000000000000000000000000000000 --- a/slirp-Fix-heap-overflow-in-ip_reass-on-big-packet-input.patch +++ /dev/null @@ -1,53 +0,0 @@ -From c2e03e2aa42d0f4f41deb08c2655503835840afa Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Tue, 24 Sep 2019 15:57:59 -0500 -Subject: [PATCH] slirp: Fix heap overflow in ip_reass on big packet input - -When the first fragment does not fit in the preallocated buffer, q will -already be pointing to the ext buffer, so we mustn't try to update it. - -Signed-off-by: Samuel Thibault -(from libslirp.git commit 126c04acbabd7ad32c2b018fe10dfac2a3bc1210) -(from libslirp.git commit e0be80430c390bce181ea04dfcdd6ea3dfa97de1) -*squash in e0be80 (clarifying comments) -Fixes: CVE-2019-14378 -Signed-off-by: Michael Roth ---- - slirp/src/ip_input.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - -diff --git a/slirp/src/ip_input.c b/slirp/src/ip_input.c -index a714fecd58..68a99de5b5 100644 ---- a/slirp/src/ip_input.c -+++ b/slirp/src/ip_input.c -@@ -331,6 +331,8 @@ insert: - q = fp->frag_link.next; - m = dtom(slirp, q); - -+ int was_ext = m->m_flags & M_EXT; -+ - q = (struct ipasfrag *) q->ipf_next; - while (q != (struct ipasfrag*)&fp->frag_link) { - struct mbuf *t = dtom(slirp, q); -@@ -347,13 +349,12 @@ insert: - q = fp->frag_link.next; - - /* -- * If the fragments concatenated to an mbuf that's -- * bigger than the total size of the fragment, then and -- * m_ext buffer was alloced. But fp->ipq_next points to -- * the old buffer (in the mbuf), so we must point ip -- * into the new buffer. -+ * If the fragments concatenated to an mbuf that's bigger than the total -+ * size of the fragment and the mbuf was not already using an m_ext buffer, -+ * then an m_ext buffer was alloced. But fp->ipq_next points to the old -+ * buffer (in the mbuf), so we must point ip into the new buffer. - */ -- if (m->m_flags & M_EXT) { -+ if (!was_ext && m->m_flags & M_EXT) { - int delta = (char *)q - m->m_dat; - q = (struct ipasfrag *)(m->m_ext + delta); - } --- -2.19.1 - diff --git a/slirp-ip_reass-Fix-use-after-free.patch b/slirp-ip_reass-Fix-use-after-free.patch deleted file mode 100644 index b603379f8a8ae7854bb98d50bdfe48da47b9bd91..0000000000000000000000000000000000000000 --- a/slirp-ip_reass-Fix-use-after-free.patch +++ /dev/null @@ -1,47 +0,0 @@ -From b27192be13da3fb59f51185d9a1f944b3474b2fc Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Tue, 24 Sep 2019 16:04:04 -0500 -Subject: [PATCH] slirp: ip_reass: Fix use after free - -Using ip_deq after m_free might read pointers from an allocation reuse. - -This would be difficult to exploit, but that is still related with -CVE-2019-14378 which generates fragmented IP packets that would trigger this -issue and at least produce a DoS. - -Signed-off-by: Samuel Thibault -(from libslirp.git commit c59279437eda91841b9d26079c70b8a540d41204) -Fixes: CVE-2019-15890 -Signed-off-by: Michael Roth ---- - slirp/src/ip_input.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/slirp/src/ip_input.c b/slirp/src/ip_input.c -index 68a99de5b5..89ae04e0c1 100644 ---- a/slirp/src/ip_input.c -+++ b/slirp/src/ip_input.c -@@ -297,6 +297,7 @@ ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp) - */ - while (q != (struct ipasfrag*)&fp->frag_link && - ip->ip_off + ip->ip_len > q->ipf_off) { -+ struct ipasfrag *prev; - i = (ip->ip_off + ip->ip_len) - q->ipf_off; - if (i < q->ipf_len) { - q->ipf_len -= i; -@@ -304,9 +305,10 @@ ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp) - m_adj(dtom(slirp, q), i); - break; - } -+ prev = q; - q = q->ipf_next; -- m_free(dtom(slirp, q->ipf_prev)); -- ip_deq(q->ipf_prev); -+ ip_deq(prev); -+ m_free(dtom(slirp, prev)); - } - - insert: --- -2.19.1 - diff --git a/slirp-use-correct-size-while-emulating-IRC-commands.patch b/slirp-use-correct-size-while-emulating-IRC-commands.patch new file mode 100644 index 0000000000000000000000000000000000000000..4503688dd1502c85f7a8e0fee1e5a36bcca838b2 --- /dev/null +++ b/slirp-use-correct-size-while-emulating-IRC-commands.patch @@ -0,0 +1,52 @@ +From 882149fd8401f8ff667ea384bb68008354fd110f Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Wed, 11 Mar 2020 18:19:36 +0800 +Subject: [PATCH] slirp: use correct size while emulating IRC commands + +While emulating IRC DCC commands, tcp_emu() uses 'mbuf' size +'m->m_size' to write DCC commands via snprintf(3). This may +lead to OOB write access, because 'bptr' points somewhere in +the middle of 'mbuf' buffer, not at the start. Use M_FREEROOM(m) +size to avoid OOB access. +Reported-by: default avatarVishnu Dev TJ +Signed-off-by: default avatarPrasad J Pandit +Reviewed-by: Samuel Thibault's avatarSamuel Thibault +Message-Id: <20200109094228.79764-2-ppandit@redhat.com> +--- + slirp/src/tcp_subr.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/slirp/src/tcp_subr.c b/slirp/src/tcp_subr.c +index 4608942f..2053b11b 100644 +--- a/slirp/src/tcp_subr.c ++++ b/slirp/src/tcp_subr.c +@@ -786,7 +786,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, m->m_size, ++ m->m_len += snprintf(bptr, M_FREEROOM(m), + "DCC CHAT chat %lu %u%c\n", + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), 1); +@@ -797,7 +797,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, m->m_size, ++ m->m_len += snprintf(bptr, M_FREEROOM(m), + "DCC SEND %s %lu %u %u%c\n", buff, + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), n1, 1); +@@ -808,7 +808,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, m->m_size, ++ m->m_len += snprintf(bptr, M_FREEROOM(m), + "DCC MOVE %s %lu %u %u%c\n", buff, + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), n1, 1); +-- +2.21.1 (Apple Git-122.3) + diff --git a/slirp-use-correct-size-while-emulating-commands.patch b/slirp-use-correct-size-while-emulating-commands.patch new file mode 100644 index 0000000000000000000000000000000000000000..76507a4d82f3c769540cf34294d855242ac0737f --- /dev/null +++ b/slirp-use-correct-size-while-emulating-commands.patch @@ -0,0 +1,51 @@ +From 66e2f47a01ffcaafe11acae0a191efd1805f86c6 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Wed, 11 Mar 2020 18:27:22 +0800 +Subject: [PATCH] slirp: use correct size while emulating commands + +While emulating services in tcp_emu(), it uses 'mbuf' size +'m->m_size' to write commands via snprintf(3). Use M_FREEROOM(m) +size to avoid possible OOB access. +Signed-off-by: default avatarPrasad J Pandit +Signed-off-by: Samuel Thibault's avatarSamuel Thibault +Message-Id: <20200109094228.79764-3-ppandit@redhat.com> +--- + slirp/src/tcp_subr.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/slirp/src/tcp_subr.c b/slirp/src/tcp_subr.c +index 2053b11b..e898fd03 100644 +--- a/slirp/src/tcp_subr.c ++++ b/slirp/src/tcp_subr.c +@@ -707,7 +707,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + n4 = (laddr & 0xff); + + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, m->m_size - m->m_len, ++ m->m_len += snprintf(bptr, M_FREEROOM(m), + "ORT %d,%d,%d,%d,%d,%d\r\n%s", + n1, n2, n3, n4, n5, n6, x==7?buff:""); + return 1; +@@ -740,7 +740,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + n4 = (laddr & 0xff); + + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, m->m_size - m->m_len, ++ m->m_len += snprintf(bptr, M_FREEROOM(m), + "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", + n1, n2, n3, n4, n5, n6, x==7?buff:""); + +@@ -766,8 +766,8 @@ tcp_emu(struct socket *so, struct mbuf *m) + if (m->m_data[m->m_len-1] == '\0' && lport != 0 && + (so = tcp_listen(slirp, INADDR_ANY, 0, so->so_laddr.s_addr, + htons(lport), SS_FACCEPTONCE)) != NULL) +- m->m_len = snprintf(m->m_data, m->m_size, "%d", +- ntohs(so->so_fport)) + 1; ++ m->m_len = snprintf(m->m_data, M_ROOM(m), ++ "%d", ntohs(so->so_fport)) + 1; + return 1; + + case EMU_IRC: +-- +2.21.1 (Apple Git-122.3) + diff --git a/target-i386-add-MDS-NO-feature.patch b/target-i386-add-MDS-NO-feature.patch deleted file mode 100644 index 0c8ccfd98b34f8a237ad347e48af10c1910b3055..0000000000000000000000000000000000000000 --- a/target-i386-add-MDS-NO-feature.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 41e1564fb50515d7902628d25c0c8421a8516cc1 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Thu, 6 Jun 2019 16:12:03 +0200 -Subject: [PATCH] target/i386: add MDS-NO feature - -Microarchitectural Data Sampling is a hardware vulnerability which allows -unprivileged speculative access to data which is available in various CPU -internal buffers. - -Some Intel processors use the ARCH_CAP_MDS_NO bit in the -IA32_ARCH_CAPABILITIES -MSR to report that they are not vulnerable, make it available to guests. - -Signed-off-by: Paolo Bonzini -Message-Id: <20190516185320.28340-1-pbonzini@redhat.com> -Signed-off-by: Eduardo Habkost -(cherry picked from commit 20140a82c67467f53814ca197403d5e1b561a5e5) -Signed-off-by: Oguz Bektas -Signed-off-by: Michael Roth ---- - target/i386/cpu.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index d6bb57d210..ee4b8b47e2 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1183,7 +1183,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .type = MSR_FEATURE_WORD, - .feat_names = { - "rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry", -- "ssb-no", NULL, NULL, NULL, -+ "ssb-no", "mds-no", NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, --- -2.19.1 - diff --git a/target-i386-define-md-clear-bit.patch b/target-i386-define-md-clear-bit.patch deleted file mode 100644 index 57289e4ac89a1390f4b0e9bfbc9062422e17d888..0000000000000000000000000000000000000000 --- a/target-i386-define-md-clear-bit.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Paolo Bonzini -Date: Wed, 15 May 2019 15:10:10 +0100 -Subject: [PATCH] target/i386: define md-clear bit - -md-clear is a new CPUID bit which is set when microcode provides the -mechanism to invoke a flush of various exploitable CPU buffers by invoking -the VERW instruction. - -Signed-off-by: Paolo Bonzini -Message-Id: <20190515141011.5315-2-berrange@redhat.com> -Signed-off-by: Eduardo Habkost -(cherry picked from commit b2ae52101fca7f9547ac2f388085dbc58f8fe1c0) ---- - target/i386/cpu.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index d6bb57d210..4ea78a4939 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1076,7 +1076,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .feat_names = { - NULL, NULL, "avx512-4vnniw", "avx512-4fmaps", - NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, NULL, "md-clear", NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, diff --git a/tcp_emu-Fix-oob-access.patch b/tcp_emu-Fix-oob-access.patch new file mode 100644 index 0000000000000000000000000000000000000000..5182f54363d585efd23f0a5c236d0e9c5153215e --- /dev/null +++ b/tcp_emu-Fix-oob-access.patch @@ -0,0 +1,38 @@ +From 0f7224535cdfec549cd43a5ae4ccde936f50ee95 Mon Sep 17 00:00:00 2001 +From: Samuel Thibault +Date: Wed, 11 Mar 2020 17:33:46 +0800 +Subject: [PATCH] tcp_emu: Fix oob access + +The main loop only checks for one available byte, while we sometimes +need two bytes. +--- + slirp/src/tcp_subr.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/slirp/src/tcp_subr.c b/slirp/src/tcp_subr.c +index fde9207b..4608942f 100644 +--- a/slirp/src/tcp_subr.c ++++ b/slirp/src/tcp_subr.c +@@ -895,6 +895,9 @@ tcp_emu(struct socket *so, struct mbuf *m) + break; + + case 5: ++ if (bptr == m->m_data + m->m_len - 1) ++ return 1; /* We need two bytes */ ++ + /* + * The difference between versions 1.0 and + * 2.0 is here. For future versions of +@@ -910,6 +913,9 @@ tcp_emu(struct socket *so, struct mbuf *m) + /* This is the field containing the port + * number that RA-player is listening to. + */ ++ if (bptr == m->m_data + m->m_len - 1) ++ return 1; /* We need two bytes */ ++ + lport = (((uint8_t*)bptr)[0] << 8) + + ((uint8_t *)bptr)[1]; + if (lport < 6970) +-- +2.21.1 (Apple Git-122.3) + diff --git a/tcp_emu-fix-unsafe-snprintf-usages.patch b/tcp_emu-fix-unsafe-snprintf-usages.patch new file mode 100644 index 0000000000000000000000000000000000000000..cc13154ca1449831d6a91dbacc27234af4caf0e5 --- /dev/null +++ b/tcp_emu-fix-unsafe-snprintf-usages.patch @@ -0,0 +1,94 @@ +From 1db8bcc0ec91bb4374b3ffdd03da3c4ede381fb5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Wed, 11 Mar 2020 18:52:07 +0800 +Subject: [PATCH] tcp_emu: fix unsafe snprintf() usages +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Various calls to snprintf() assume that snprintf() returns "only" the +number of bytes written (excluding terminating NUL). + +https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html#tag_16_159_04 + +"Upon successful completion, the snprintf() function shall return the +number of bytes that would be written to s had n been sufficiently +large excluding the terminating null byte." + +Before patch ce131029, if there isn't enough room in "m_data" for the +"DCC ..." message, we overflow "m_data". + +After the patch, if there isn't enough room for the same, we don't +overflow "m_data", but we set "m_len" out-of-bounds. The next time an +access is bounded by "m_len", we'll have a buffer overflow then. + +Use slirp_fmt*() to fix potential OOB memory access. +Reported-by: default avatarLaszlo Ersek +Signed-off-by: default avatarMarc-André Lureau +Reviewed-by: Samuel Thibault's avatarSamuel Thibault +Message-Id: <20200127092414.169796-7-marcandre.lureau@redhat.com> +--- + slirp/src/tcp_subr.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/slirp/src/tcp_subr.c b/slirp/src/tcp_subr.c +index e898fd03..88dadc76 100644 +--- a/slirp/src/tcp_subr.c ++++ b/slirp/src/tcp_subr.c +@@ -707,7 +707,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + n4 = (laddr & 0xff); + + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, M_FREEROOM(m), ++ m->m_len += slirp_fmt(bptr, M_FREEROOM(m), + "ORT %d,%d,%d,%d,%d,%d\r\n%s", + n1, n2, n3, n4, n5, n6, x==7?buff:""); + return 1; +@@ -740,7 +740,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + n4 = (laddr & 0xff); + + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, M_FREEROOM(m), ++ m->m_len += slirp_fmt(bptr, M_FREEROOM(m), + "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", + n1, n2, n3, n4, n5, n6, x==7?buff:""); + +@@ -766,7 +766,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + if (m->m_data[m->m_len-1] == '\0' && lport != 0 && + (so = tcp_listen(slirp, INADDR_ANY, 0, so->so_laddr.s_addr, + htons(lport), SS_FACCEPTONCE)) != NULL) +- m->m_len = snprintf(m->m_data, M_ROOM(m), ++ m->m_len = slirp_fmt0(m->m_data, M_ROOM(m), + "%d", ntohs(so->so_fport)) + 1; + return 1; + +@@ -786,7 +786,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, M_FREEROOM(m), ++ m->m_len += slirp_fmt(bptr, M_FREEROOM(m), + "DCC CHAT chat %lu %u%c\n", + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), 1); +@@ -797,7 +797,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, M_FREEROOM(m), ++ m->m_len += slirp_fmt(bptr, M_FREEROOM(m), + "DCC SEND %s %lu %u %u%c\n", buff, + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), n1, 1); +@@ -808,7 +808,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, M_FREEROOM(m), ++ m->m_len += slirp_fmt(bptr, M_FREEROOM(m), + "DCC MOVE %s %lu %u %u%c\n", buff, + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), n1, 1); +-- +2.21.1 (Apple Git-122.3) + diff --git a/usb-tablet-fix-serial-compat-property.patch b/usb-tablet-fix-serial-compat-property.patch deleted file mode 100644 index 6397f61fb463cf11f9805bdb4b51cf68d05c7349..0000000000000000000000000000000000000000 --- a/usb-tablet-fix-serial-compat-property.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 665218cc085c5c1ec871d8af6986903313638fbf Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Mon, 20 May 2019 10:18:05 +0200 -Subject: [PATCH] usb-tablet: fix serial compat property -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -s/kbd/tablet/, fixes cut+paste bug. - -Cc: qemu-stable@nongnu.org -Reported-by: Dr. David Alan Gilbert -Signed-off-by: Gerd Hoffmann -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: Laurent Vivier -Reviewed-by: Philippe Mathieu-Daudé -Message-id: 20190520081805.15019-1-kraxel@redhat.com -(cherry picked from commit 442bac16a6cd708a9f87adb0a263f9d833f03ed5) -Signed-off-by: Michael Roth ---- - hw/core/machine.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 743fef2898..b6766632d9 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -33,7 +33,7 @@ GlobalProperty hw_compat_3_1[] = { - { "tpm-tis", "ppi", "false" }, - { "usb-kbd", "serial", "42" }, - { "usb-mouse", "serial", "42" }, -- { "usb-kbd", "serial", "42" }, -+ { "usb-tablet", "serial", "42" }, - { "virtio-blk-device", "discard", "false" }, - { "virtio-blk-device", "write-zeroes", "false" }, - }; --- -2.19.1 - diff --git a/usbredir-fix-buffer-overflow-on-vmload.patch b/usbredir-fix-buffer-overflow-on-vmload.patch deleted file mode 100644 index 2fec639d85b838f30c87aebde7075fd34de65427..0000000000000000000000000000000000000000 --- a/usbredir-fix-buffer-overflow-on-vmload.patch +++ /dev/null @@ -1,55 +0,0 @@ -From e86e620656becb37890a6d91e0148c74f3e43f3d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Wed, 7 Aug 2019 12:40:48 +0400 -Subject: [PATCH] usbredir: fix buffer-overflow on vmload -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If interface_count is NO_INTERFACE_INFO, let's not access the arrays -out-of-bounds. - -==994==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x625000243930 at pc 0x5642068086a8 bp 0x7f0b6f9ffa50 sp 0x7f0b6f9ffa40 -READ of size 1 at 0x625000243930 thread T0 - #0 0x5642068086a7 in usbredir_check_bulk_receiving /home/elmarco/src/qemu/hw/usb/redirect.c:1503 - #1 0x56420681301c in usbredir_post_load /home/elmarco/src/qemu/hw/usb/redirect.c:2154 - #2 0x5642068a56c2 in vmstate_load_state /home/elmarco/src/qemu/migration/vmstate.c:168 - #3 0x56420688e2ac in vmstate_load /home/elmarco/src/qemu/migration/savevm.c:829 - #4 0x5642068980cb in qemu_loadvm_section_start_full /home/elmarco/src/qemu/migration/savevm.c:2211 - #5 0x564206899645 in qemu_loadvm_state_main /home/elmarco/src/qemu/migration/savevm.c:2395 - #6 0x5642068998cf in qemu_loadvm_state /home/elmarco/src/qemu/migration/savevm.c:2467 - #7 0x56420685f3e9 in process_incoming_migration_co /home/elmarco/src/qemu/migration/migration.c:449 - #8 0x564207106c47 in coroutine_trampoline /home/elmarco/src/qemu/util/coroutine-ucontext.c:115 - #9 0x7f0c0604e37f (/lib64/libc.so.6+0x4d37f) - -Signed-off-by: Marc-André Lureau -Reviewed-by: Liam Merwick -Reviewed-by: Li Qiang -Reviewed-by: Philippe Mathieu-Daudé -Message-id: 20190807084048.4258-1-marcandre.lureau@redhat.com -Signed-off-by: Gerd Hoffmann -(cherry picked from commit 7b84b90966568da0e05655ecaa78c209300aae6e) -Signed-off-by: Michael Roth ---- - hw/usb/redirect.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c -index 7cb6b120d4..586c7db025 100644 ---- a/hw/usb/redirect.c -+++ b/hw/usb/redirect.c -@@ -1494,6 +1494,11 @@ static void usbredir_check_bulk_receiving(USBRedirDevice *dev) - for (i = EP2I(USB_DIR_IN); i < MAX_ENDPOINTS; i++) { - dev->endpoint[i].bulk_receiving_enabled = 0; - } -+ -+ if (dev->interface_info.interface_count == NO_INTERFACE_INFO) { -+ return; -+ } -+ - for (i = 0; i < dev->interface_info.interface_count; i++) { - quirks = usb_get_quirks(dev->device_info.vendor_id, - dev->device_info.product_id, --- -2.19.1 - diff --git a/util-hbitmap-update-orig_size-on-truncate.patch b/util-hbitmap-update-orig_size-on-truncate.patch deleted file mode 100644 index 137d8b9c5cdb3574b25b2cad905740dff4e79d7b..0000000000000000000000000000000000000000 --- a/util-hbitmap-update-orig_size-on-truncate.patch +++ /dev/null @@ -1,48 +0,0 @@ -From fc5c701636127a0b90cd7ab564da0354d06809dc Mon Sep 17 00:00:00 2001 -From: Vladimir Sementsov-Ogievskiy -Date: Mon, 5 Aug 2019 15:01:20 +0300 -Subject: [PATCH] util/hbitmap: update orig_size on truncate - -Without this, hbitmap_next_zero and hbitmap_next_dirty_area are broken -after truncate. So, orig_size is broken since it's introduction in -76d570dc495c56bb. - -Fixes: 76d570dc495c56bb -Signed-off-by: Vladimir Sementsov-Ogievskiy -Message-id: 20190805120120.23585-1-vsementsov@virtuozzo.com -Reviewed-by: Max Reitz -Cc: qemu-stable@nongnu.org -Signed-off-by: Max Reitz -(cherry picked from commit 4e4de222799634d8159ee7b9303b9e1b45c6be2c) -Signed-off-by: Michael Roth ---- - util/hbitmap.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/util/hbitmap.c b/util/hbitmap.c -index 7905212a8b..bcc0acdc6a 100644 ---- a/util/hbitmap.c -+++ b/util/hbitmap.c -@@ -53,7 +53,9 @@ - */ - - struct HBitmap { -- /* Size of the bitmap, as requested in hbitmap_alloc. */ -+ /* -+ * Size of the bitmap, as requested in hbitmap_alloc or in hbitmap_truncate. -+ */ - uint64_t orig_size; - - /* Number of total bits in the bottom level. */ -@@ -732,6 +734,8 @@ void hbitmap_truncate(HBitmap *hb, uint64_t size) - uint64_t num_elements = size; - uint64_t old; - -+ hb->orig_size = size; -+ - /* Size comes in as logical elements, adjust for granularity. */ - size = (size + (1ULL << hb->granularity) - 1) >> hb->granularity; - assert(size <= ((uint64_t)1 << HBITMAP_LOG_MAX_SIZE)); --- -2.19.1 - diff --git a/vhost-fix-vhost_log-size-overflow-during-migration.patch b/vhost-fix-vhost_log-size-overflow-during-migration.patch deleted file mode 100644 index 2111f2aee55847dd6e58049aa2b4c399e97f9d82..0000000000000000000000000000000000000000 --- a/vhost-fix-vhost_log-size-overflow-during-migration.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 240e647a14df9677b3a501f7b8b870e40aac3fd5 Mon Sep 17 00:00:00 2001 -From: Li Hangjing -Date: Mon, 3 Jun 2019 14:15:24 +0800 -Subject: [PATCH] vhost: fix vhost_log size overflow during migration - -When a guest which doesn't support multiqueue is migrated with a multi queues -vhost-user-blk deivce, a crash will occur like: - -0 qemu_memfd_alloc (name=, size=562949953421312, seals=, fd=0x7f87171fe8b4, errp=0x7f87171fe8a8) at util/memfd.c:153 -1 0x00007f883559d7cf in vhost_log_alloc (size=70368744177664, share=true) at hw/virtio/vhost.c:186 -2 0x00007f88355a0758 in vhost_log_get (listener=0x7f8838bd7940, enable=1) at qemu-2-12/hw/virtio/vhost.c:211 -3 vhost_dev_log_resize (listener=0x7f8838bd7940, enable=1) at hw/virtio/vhost.c:263 -4 vhost_migration_log (listener=0x7f8838bd7940, enable=1) at hw/virtio/vhost.c:787 -5 0x00007f88355463d6 in memory_global_dirty_log_start () at memory.c:2503 -6 0x00007f8835550577 in ram_init_bitmaps (f=0x7f88384ce600, opaque=0x7f8836024098) at migration/ram.c:2173 -7 ram_init_all (f=0x7f88384ce600, opaque=0x7f8836024098) at migration/ram.c:2192 -8 ram_save_setup (f=0x7f88384ce600, opaque=0x7f8836024098) at migration/ram.c:2219 -9 0x00007f88357a419d in qemu_savevm_state_setup (f=0x7f88384ce600) at migration/savevm.c:1002 -10 0x00007f883579fc3e in migration_thread (opaque=0x7f8837530400) at migration/migration.c:2382 -11 0x00007f8832447893 in start_thread () from /lib64/libpthread.so.0 -12 0x00007f8832178bfd in clone () from /lib64/libc.so.6 - -This is because vhost_get_log_size() returns a overflowed vhost-log size. -In this function, it uses the uninitialized variable vqs->used_phys and -vqs->used_size to get the vhost-log size. - -Signed-off-by: Li Hangjing -Reviewed-by: Xie Yongji -Reviewed-by: Chai Wen -Message-Id: <20190603061524.24076-1-lihangjing@baidu.com> -Cc: qemu-stable@nongnu.org -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry-pick from commit 240e647a14df9677b3a501f7b8b870e40aac3fd5) ---- - hw/virtio/vhost.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 60747a6f93..bc899fc60e 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -131,6 +131,11 @@ static int vhost_sync_dirty_bitmap(struct vhost_dev *dev, - } - for (i = 0; i < dev->nvqs; ++i) { - struct vhost_virtqueue *vq = dev->vqs + i; -+ -+ if (!vq->used_phys && !vq->used_size) { -+ continue; -+ } -+ - vhost_dev_sync_region(dev, section, start_addr, end_addr, vq->used_phys, - range_get_last(vq->used_phys, vq->used_size)); - } -@@ -168,6 +173,11 @@ static uint64_t vhost_get_log_size(struct vhost_dev *dev) - } - for (i = 0; i < dev->nvqs; ++i) { - struct vhost_virtqueue *vq = dev->vqs + i; -+ -+ if (!vq->used_phys && !vq->used_size) { -+ continue; -+ } -+ - uint64_t last = vq->used_phys + vq->used_size - 1; - log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1); - } --- -2.19.1 - diff --git a/virtio-balloon-Better-names-for-offset-variables.patch b/virtio-balloon-Better-names-for-offset-variables.patch deleted file mode 100644 index 7f9d3a99432e80a2bd11f04f0eea79a00b7ef7b4..0000000000000000000000000000000000000000 --- a/virtio-balloon-Better-names-for-offset-variables.patch +++ /dev/null @@ -1,113 +0,0 @@ -From e6129b271b9dccca22c84870e313c315f2c70063 Mon Sep 17 00:00:00 2001 -From: David Hildenbrand -Date: Mon, 22 Jul 2019 15:41:06 +0200 -Subject: [PATCH] virtio-balloon: Better names for offset variables in - inflate/deflate code - -"host_page_base" is really confusing, let's make this clearer, also -rename the other offsets to indicate to which base they apply. - -offset -> mr_offset -ram_offset -> rb_offset -host_page_base -> rb_aligned_offset - -While at it, use QEMU_ALIGN_DOWN() instead of a handcrafted computation -and move the computation to the place where it is needed. - -Acked-by: David Gibson -Signed-off-by: David Hildenbrand -Message-Id: <20190722134108.22151-5-david@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry-picked from commit e6129b271b9dccca22c84870e313c315f2c70063) ---- - hw/virtio/virtio-balloon.c | 26 +++++++++++++------------- - 1 file changed, 13 insertions(+), 13 deletions(-) - -diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c -index 04a7e6c772..f206cc8bf7 100644 ---- a/hw/virtio/virtio-balloon.c -+++ b/hw/virtio/virtio-balloon.c -@@ -41,24 +41,23 @@ struct PartiallyBalloonedPage { - }; - - static void balloon_inflate_page(VirtIOBalloon *balloon, -- MemoryRegion *mr, hwaddr offset) -+ MemoryRegion *mr, hwaddr mr_offset) - { -- void *addr = memory_region_get_ram_ptr(mr) + offset; -+ void *addr = memory_region_get_ram_ptr(mr) + mr_offset; -+ ram_addr_t rb_offset, rb_aligned_offset; - RAMBlock *rb; - size_t rb_page_size; - int subpages; -- ram_addr_t ram_offset, host_page_base; - - /* XXX is there a better way to get to the RAMBlock than via a - * host address? */ -- rb = qemu_ram_block_from_host(addr, false, &ram_offset); -+ rb = qemu_ram_block_from_host(addr, false, &rb_offset); - rb_page_size = qemu_ram_pagesize(rb); -- host_page_base = ram_offset & ~(rb_page_size - 1); - - if (rb_page_size == BALLOON_PAGE_SIZE) { - /* Easy case */ - -- ram_block_discard_range(rb, ram_offset, rb_page_size); -+ ram_block_discard_range(rb, rb_offset, rb_page_size); - /* We ignore errors from ram_block_discard_range(), because it - * has already reported them, and failing to discard a balloon - * page is not fatal */ -@@ -74,11 +73,12 @@ static void balloon_inflate_page(VirtIOBalloon *balloon, - warn_report_once( - "Balloon used with backing page size > 4kiB, this may not be reliable"); - -+ rb_aligned_offset = QEMU_ALIGN_DOWN(rb_offset, rb_page_size); - subpages = rb_page_size / BALLOON_PAGE_SIZE; - - if (balloon->pbp - && (rb != balloon->pbp->rb -- || host_page_base != balloon->pbp->base)) { -+ || rb_aligned_offset != balloon->pbp->base)) { - /* We've partially ballooned part of a host page, but now - * we're trying to balloon part of a different one. Too hard, - * give up on the old partial page */ -@@ -91,10 +91,10 @@ static void balloon_inflate_page(VirtIOBalloon *balloon, - size_t bitlen = BITS_TO_LONGS(subpages) * sizeof(unsigned long); - balloon->pbp = g_malloc0(sizeof(PartiallyBalloonedPage) + bitlen); - balloon->pbp->rb = rb; -- balloon->pbp->base = host_page_base; -+ balloon->pbp->base = rb_aligned_offset; - } - -- set_bit((ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, -+ set_bit((rb_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, - balloon->pbp->bitmap); - - if (bitmap_full(balloon->pbp->bitmap, subpages)) { -@@ -112,18 +112,18 @@ static void balloon_inflate_page(VirtIOBalloon *balloon, - } - - static void balloon_deflate_page(VirtIOBalloon *balloon, -- MemoryRegion *mr, hwaddr offset) -+ MemoryRegion *mr, hwaddr mr_offset) - { -- void *addr = memory_region_get_ram_ptr(mr) + offset; -+ void *addr = memory_region_get_ram_ptr(mr) + mr_offset; -+ ram_addr_t rb_offset; - RAMBlock *rb; - size_t rb_page_size; -- ram_addr_t ram_offset; - void *host_addr; - int ret; - - /* XXX is there a better way to get to the RAMBlock than via a - * host address? */ -- rb = qemu_ram_block_from_host(addr, false, &ram_offset); -+ rb = qemu_ram_block_from_host(addr, false, &rb_offset); - rb_page_size = qemu_ram_pagesize(rb); - - if (balloon->pbp) { --- -2.19.1 - diff --git a/virtio-balloon-Fix-QEMU-crashes-on-pagesize-BALLOON_.patch b/virtio-balloon-Fix-QEMU-crashes-on-pagesize-BALLOON_.patch deleted file mode 100644 index 7507b9c3234e2c57f77d1f806ebb4ba02503f404..0000000000000000000000000000000000000000 --- a/virtio-balloon-Fix-QEMU-crashes-on-pagesize-BALLOON_.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 483f13524bb2a08b7ff6a7560b846564ed3b0c33 Mon Sep 17 00:00:00 2001 -From: David Hildenbrand -Date: Mon, 22 Jul 2019 15:41:04 +0200 -Subject: [PATCH] virtio-balloon: Fix QEMU crashes on pagesize > - BALLOON_PAGE_SIZE - -We are using the wrong functions to set/clear bits, effectively touching -multiple bits, writing out of range of the bitmap, resulting in memory -corruptions. We have to use set_bit()/clear_bit() instead. - -Can easily be reproduced by starting a qemu guest on hugetlbfs memory, -inflating the balloon. QEMU crashes. This never could have worked -properly - especially, also pages would have been discarded when the -first sub-page would be inflated (the whole bitmap would be set). - -While testing I realized, that on hugetlbfs it is pretty much impossible -to discard a page - the guest just frees the 4k sub-pages in random order -most of the time. I was only able to discard a hugepage a handful of -times - so I hope that now works correctly. - -Fixes: ed48c59875b6 ("virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size") -Fixes: b27b32391404 ("virtio-balloon: Fix possible guest memory corruption with inflates & deflates") -Cc: qemu-stable@nongnu.org #v4.0.0 -Acked-by: David Gibson -Signed-off-by: David Hildenbrand -Message-Id: <20190722134108.22151-3-david@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry-pick from commit 483f13524bb2a08b7ff6a7560b846564ed3b0c33) ---- - hw/virtio/virtio-balloon.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c -index 515abf6553..a78d2d2184 100644 ---- a/hw/virtio/virtio-balloon.c -+++ b/hw/virtio/virtio-balloon.c -@@ -94,9 +94,8 @@ static void balloon_inflate_page(VirtIOBalloon *balloon, - balloon->pbp->base = host_page_base; - } - -- bitmap_set(balloon->pbp->bitmap, -- (ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, -- subpages); -+ set_bit((ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, -+ balloon->pbp->bitmap); - - if (bitmap_full(balloon->pbp->bitmap, subpages)) { - /* We've accumulated a full host page, we can actually discard -@@ -140,9 +139,8 @@ static void balloon_deflate_page(VirtIOBalloon *balloon, - * for a guest to do this in practice, but handle it anyway, - * since getting it wrong could mean discarding memory the - * guest is still using. */ -- bitmap_clear(balloon->pbp->bitmap, -- (ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, -- subpages); -+ clear_bit((ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, -+ balloon->pbp->bitmap); - - if (bitmap_empty(balloon->pbp->bitmap, subpages)) { - g_free(balloon->pbp); --- -2.19.1 - diff --git a/virtio-balloon-Fix-wrong-sign-extension-of-PFNs.patch b/virtio-balloon-Fix-wrong-sign-extension-of-PFNs.patch deleted file mode 100644 index 25497995573f8d5ae90f54398631736aa9f244f6..0000000000000000000000000000000000000000 --- a/virtio-balloon-Fix-wrong-sign-extension-of-PFNs.patch +++ /dev/null @@ -1,41 +0,0 @@ -From ffa207d08253ffffb3993a1dbe09e40af4fc91f1 Mon Sep 17 00:00:00 2001 -From: David Hildenbrand -Date: Mon, 22 Jul 2019 15:41:03 +0200 -Subject: [PATCH] virtio-balloon: Fix wrong sign extension of PFNs - -If we directly cast from int to uint64_t, we will first sign-extend to -an int64_t, which is wrong. We actually want to treat the PFNs like -unsigned values. - -As far as I can see, this dates back to the initial virtio-balloon -commit, but wasn't triggered as fairly big guests would be required. - -Cc: qemu-stable@nongnu.org -Reported-by: Michael S. Tsirkin -Signed-off-by: David Hildenbrand -Message-Id: <20190722134108.22151-2-david@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: David Gibson -(cherry-picked from commit ffa207d08253ffffb3993a1dbe09e40af4fc91f1) ---- - hw/virtio/virtio-balloon.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c -index e85d1c0d5c..515abf6553 100644 ---- a/hw/virtio/virtio-balloon.c -+++ b/hw/virtio/virtio-balloon.c -@@ -343,8 +343,8 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) - } - - while (iov_to_buf(elem->out_sg, elem->out_num, offset, &pfn, 4) == 4) { -+ unsigned int p = virtio_ldl_p(vdev, &pfn); - hwaddr pa; -- int p = virtio_ldl_p(vdev, &pfn); - - pa = (hwaddr) p << VIRTIO_BALLOON_PFN_SHIFT; - offset += 4; --- -2.19.1 - diff --git a/virtio-balloon-Rework-pbp-tracking-data.patch b/virtio-balloon-Rework-pbp-tracking-data.patch deleted file mode 100644 index 1930ac131b30118df7a5cb00441495ccb0f2ec9e..0000000000000000000000000000000000000000 --- a/virtio-balloon-Rework-pbp-tracking-data.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 1c5cfc2b7153dd72bf4b8ddc456408eb2b9b66d8 Mon Sep 17 00:00:00 2001 -From: David Hildenbrand -Date: Mon, 22 Jul 2019 15:41:07 +0200 -Subject: [PATCH] virtio-balloon: Rework pbp tracking data - -Using the address of a RAMBlock to test for a matching pbp is not really -safe. Instead, let's use the guest physical address of the base page -along with the page size (via the number of subpages). - -Also, let's allocate the bitmap separately. This makes the code -easier to read and maintain - we can reuse bitmap_new(). - -Prepare the code to move the PBP out of the device. - -Fixes: ed48c59875b6 ("virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size") -Fixes: b27b32391404 ("virtio-balloon: Fix possible guest memory corruption with inflates & deflates") -Cc: qemu-stable@nongnu.org #v4.0.0 -Signed-off-by: David Hildenbrand -Message-Id: <20190722134108.22151-6-david@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry-picked from commit 1c5cfc2b7153dd72bf4b8ddc456408eb2b9b66d8) ---- - hw/virtio/virtio-balloon.c | 69 +++++++++++++++++++++++++------------- - 1 file changed, 46 insertions(+), 23 deletions(-) - -diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c -index f206cc8bf7..40d493a31a 100644 ---- a/hw/virtio/virtio-balloon.c -+++ b/hw/virtio/virtio-balloon.c -@@ -35,16 +35,44 @@ - #define BALLOON_PAGE_SIZE (1 << VIRTIO_BALLOON_PFN_SHIFT) - - struct PartiallyBalloonedPage { -- RAMBlock *rb; -- ram_addr_t base; -- unsigned long bitmap[]; -+ ram_addr_t base_gpa; -+ long subpages; -+ unsigned long *bitmap; - }; - -+static void virtio_balloon_pbp_free(PartiallyBalloonedPage *pbp) -+{ -+ if (!pbp) { -+ return; -+ } -+ g_free(pbp->bitmap); -+ g_free(pbp); -+} -+ -+static PartiallyBalloonedPage *virtio_balloon_pbp_alloc(ram_addr_t base_gpa, -+ long subpages) -+{ -+ PartiallyBalloonedPage *pbp = g_new0(PartiallyBalloonedPage, 1); -+ -+ pbp->base_gpa = base_gpa; -+ pbp->subpages = subpages; -+ pbp->bitmap = bitmap_new(subpages); -+ -+ return pbp; -+} -+ -+static bool virtio_balloon_pbp_matches(PartiallyBalloonedPage *pbp, -+ ram_addr_t base_gpa, long subpages) -+{ -+ return pbp->subpages == subpages && pbp->base_gpa == base_gpa; -+} -+ - static void balloon_inflate_page(VirtIOBalloon *balloon, - MemoryRegion *mr, hwaddr mr_offset) - { - void *addr = memory_region_get_ram_ptr(mr) + mr_offset; -- ram_addr_t rb_offset, rb_aligned_offset; -+ ram_addr_t rb_offset, rb_aligned_offset, base_gpa; -+ PartiallyBalloonedPage **pbp = &balloon->pbp; - RAMBlock *rb; - size_t rb_page_size; - int subpages; -@@ -75,39 +103,34 @@ static void balloon_inflate_page(VirtIOBalloon *balloon, - - rb_aligned_offset = QEMU_ALIGN_DOWN(rb_offset, rb_page_size); - subpages = rb_page_size / BALLOON_PAGE_SIZE; -+ base_gpa = memory_region_get_ram_addr(mr) + mr_offset - -+ (rb_offset - rb_aligned_offset); - -- if (balloon->pbp -- && (rb != balloon->pbp->rb -- || rb_aligned_offset != balloon->pbp->base)) { -+ if (*pbp && !virtio_balloon_pbp_matches(*pbp, base_gpa, subpages)) { - /* We've partially ballooned part of a host page, but now - * we're trying to balloon part of a different one. Too hard, - * give up on the old partial page */ -- g_free(balloon->pbp); -- balloon->pbp = NULL; -+ virtio_balloon_pbp_free(*pbp); -+ *pbp = NULL; - } - -- if (!balloon->pbp) { -- /* Starting on a new host page */ -- size_t bitlen = BITS_TO_LONGS(subpages) * sizeof(unsigned long); -- balloon->pbp = g_malloc0(sizeof(PartiallyBalloonedPage) + bitlen); -- balloon->pbp->rb = rb; -- balloon->pbp->base = rb_aligned_offset; -+ if (!*pbp) { -+ *pbp = virtio_balloon_pbp_alloc(base_gpa, subpages); - } - -- set_bit((rb_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, -- balloon->pbp->bitmap); -+ set_bit((rb_offset - rb_aligned_offset) / BALLOON_PAGE_SIZE, -+ (*pbp)->bitmap); - -- if (bitmap_full(balloon->pbp->bitmap, subpages)) { -+ if (bitmap_full((*pbp)->bitmap, subpages)) { - /* We've accumulated a full host page, we can actually discard - * it now */ - -- ram_block_discard_range(rb, balloon->pbp->base, rb_page_size); -+ ram_block_discard_range(rb, rb_aligned_offset, rb_page_size); - /* We ignore errors from ram_block_discard_range(), because it - * has already reported them, and failing to discard a balloon - * page is not fatal */ -- -- g_free(balloon->pbp); -- balloon->pbp = NULL; -+ virtio_balloon_pbp_free(*pbp); -+ *pbp = NULL; - } - } - -@@ -128,7 +151,7 @@ static void balloon_deflate_page(VirtIOBalloon *balloon, - - if (balloon->pbp) { - /* Let's play safe and always reset the pbp on deflation requests. */ -- g_free(balloon->pbp); -+ virtio_balloon_pbp_free(balloon->pbp); - balloon->pbp = NULL; - } - --- -2.19.1 - diff --git a/virtio-balloon-Simplify-deflate-with-pbp.patch b/virtio-balloon-Simplify-deflate-with-pbp.patch deleted file mode 100644 index 673ae1dd4b097cd9273eb6bc312f2effaac8cba4..0000000000000000000000000000000000000000 --- a/virtio-balloon-Simplify-deflate-with-pbp.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 2ffc49eea1bbd454913a88a0ad872c2649b36950 Mon Sep 17 00:00:00 2001 -From: David Hildenbrand -Date: Mon, 22 Jul 2019 15:41:05 +0200 -Subject: [PATCH] virtio-balloon: Simplify deflate with pbp - -Let's simplify this - the case we are optimizing for is very hard to -trigger and not worth the effort. If we're switching from inflation to -deflation, let's reset the pbp. - -Acked-by: David Gibson -Signed-off-by: David Hildenbrand -Message-Id: <20190722134108.22151-4-david@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry-picked from commit 2ffc49eea1bbd454913a88a0ad872c2649b36950) ---- - hw/virtio/virtio-balloon.c | 26 +++++--------------------- - 1 file changed, 5 insertions(+), 21 deletions(-) - -diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c -index a78d2d2184..04a7e6c772 100644 ---- a/hw/virtio/virtio-balloon.c -+++ b/hw/virtio/virtio-balloon.c -@@ -117,7 +117,7 @@ static void balloon_deflate_page(VirtIOBalloon *balloon, - void *addr = memory_region_get_ram_ptr(mr) + offset; - RAMBlock *rb; - size_t rb_page_size; -- ram_addr_t ram_offset, host_page_base; -+ ram_addr_t ram_offset; - void *host_addr; - int ret; - -@@ -125,27 +125,11 @@ static void balloon_deflate_page(VirtIOBalloon *balloon, - * host address? */ - rb = qemu_ram_block_from_host(addr, false, &ram_offset); - rb_page_size = qemu_ram_pagesize(rb); -- host_page_base = ram_offset & ~(rb_page_size - 1); -- -- if (balloon->pbp -- && rb == balloon->pbp->rb -- && host_page_base == balloon->pbp->base) { -- int subpages = rb_page_size / BALLOON_PAGE_SIZE; - -- /* -- * This means the guest has asked to discard some of the 4kiB -- * subpages of a host page, but then changed its mind and -- * asked to keep them after all. It's exceedingly unlikely -- * for a guest to do this in practice, but handle it anyway, -- * since getting it wrong could mean discarding memory the -- * guest is still using. */ -- clear_bit((ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, -- balloon->pbp->bitmap); -- -- if (bitmap_empty(balloon->pbp->bitmap, subpages)) { -- g_free(balloon->pbp); -- balloon->pbp = NULL; -- } -+ if (balloon->pbp) { -+ /* Let's play safe and always reset the pbp on deflation requests. */ -+ g_free(balloon->pbp); -+ balloon->pbp = NULL; - } - - host_addr = (void *)((uintptr_t)addr & ~(rb_page_size - 1)); --- -2.19.1 - diff --git a/virtio-balloon-Use-temporary-PBP-only.patch b/virtio-balloon-Use-temporary-PBP-only.patch deleted file mode 100644 index 9d0a8cda0b48d706cddda9d75b74bcfb366a60fe..0000000000000000000000000000000000000000 --- a/virtio-balloon-Use-temporary-PBP-only.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 8e20acad634e38f29afd54b951c42eec113288bc Mon Sep 17 00:00:00 2001 -From: David Hildenbrand -Date: Mon, 22 Jul 2019 15:41:08 +0200 -Subject: [PATCH] virtio-balloon: Use temporary PBP only - -We still have multiple issues in the current code -- The PBP is not freed during unrealize() -- The PBP is not reset on device resets: After a reset, the PBP is stale. -- We are not indicating VIRTIO_BALLOON_F_MUST_TELL_HOST, therefore - guests (esp. legacy guests) will reuse pages without deflating, - turning the PBP stale. Adding that would require compat handling. - -Instead, let's use the PBP only temporarily, when processing one bulk of -inflation requests. This will keep guest_page_size > 4k working (with -Linux guests). There is nothing to do for deflation requests anymore. -The pbp is only used for a limited amount of time. - -Fixes: ed48c59875b6 ("virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size") -Cc: qemu-stable@nongnu.org #v4.0.0 -Suggested-by: Michael S. Tsirkin -Signed-off-by: David Hildenbrand -Message-Id: <20190722134108.22151-7-david@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Acked-by: David Gibson -(cherry picked from commit a8cd64d488325f3be5c4ddec4bf07efb3b8c7330) -Signed-off-by: Michael Roth ---- - hw/virtio/virtio-balloon.c | 21 +++++++++------------ - include/hw/virtio/virtio-balloon.h | 3 --- - 2 files changed, 9 insertions(+), 15 deletions(-) - -diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c -index 49999d0bbe..bd54e302de 100644 ---- a/hw/virtio/virtio-balloon.c -+++ b/hw/virtio/virtio-balloon.c -@@ -34,11 +34,11 @@ - - #define BALLOON_PAGE_SIZE (1 << VIRTIO_BALLOON_PFN_SHIFT) - --struct PartiallyBalloonedPage { -+typedef struct PartiallyBalloonedPage { - ram_addr_t base_gpa; - long subpages; - unsigned long *bitmap; --}; -+} PartiallyBalloonedPage; - - static void virtio_balloon_pbp_free(PartiallyBalloonedPage *pbp) - { -@@ -68,11 +68,11 @@ static bool virtio_balloon_pbp_matches(PartiallyBalloonedPage *pbp, - } - - static void balloon_inflate_page(VirtIOBalloon *balloon, -- MemoryRegion *mr, hwaddr mr_offset) -+ MemoryRegion *mr, hwaddr mr_offset, -+ PartiallyBalloonedPage **pbp) - { - void *addr = memory_region_get_ram_ptr(mr) + mr_offset; - ram_addr_t rb_offset, rb_aligned_offset, base_gpa; -- PartiallyBalloonedPage **pbp = &balloon->pbp; - RAMBlock *rb; - size_t rb_page_size; - int subpages; -@@ -149,12 +149,6 @@ static void balloon_deflate_page(VirtIOBalloon *balloon, - rb = qemu_ram_block_from_host(addr, false, &rb_offset); - rb_page_size = qemu_ram_pagesize(rb); - -- if (balloon->pbp) { -- /* Let's play safe and always reset the pbp on deflation requests. */ -- virtio_balloon_pbp_free(balloon->pbp); -- balloon->pbp = NULL; -- } -- - host_addr = (void *)((uintptr_t)addr & ~(rb_page_size - 1)); - - /* When a page is deflated, we hint the whole host page it lives -@@ -336,6 +330,7 @@ static void balloon_stats_set_poll_interval(Object *obj, Visitor *v, - static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) - { - VirtIOBalloon *s = VIRTIO_BALLOON(vdev); -+ PartiallyBalloonedPage *pbp = NULL; - VirtQueueElement *elem; - MemoryRegionSection section; - -@@ -344,7 +339,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) - uint32_t pfn; - elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); - if (!elem) { -- return; -+ break; - } - - while (iov_to_buf(elem->out_sg, elem->out_num, offset, &pfn, 4) == 4) { -@@ -373,7 +368,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) - if (!qemu_balloon_is_inhibited()) { - if (vq == s->ivq) { - balloon_inflate_page(s, section.mr, -- section.offset_within_region); -+ section.offset_within_region, &pbp); - } else if (vq == s->dvq) { - balloon_deflate_page(s, section.mr, section.offset_within_region); - } else { -@@ -387,6 +382,8 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) - virtio_notify(vdev, vq); - g_free(elem); - } -+ -+ virtio_balloon_pbp_free(pbp); - } - - static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq) -diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h -index 5a99293a45..d1c968d237 100644 ---- a/include/hw/virtio/virtio-balloon.h -+++ b/include/hw/virtio/virtio-balloon.h -@@ -33,8 +33,6 @@ typedef struct virtio_balloon_stat_modern { - uint64_t val; - } VirtIOBalloonStatModern; - --typedef struct PartiallyBalloonedPage PartiallyBalloonedPage; -- - enum virtio_balloon_free_page_report_status { - FREE_PAGE_REPORT_S_STOP = 0, - FREE_PAGE_REPORT_S_REQUESTED = 1, -@@ -70,7 +68,6 @@ typedef struct VirtIOBalloon { - int64_t stats_last_update; - int64_t stats_poll_interval; - uint32_t host_features; -- PartiallyBalloonedPage *pbp; - - bool qemu_4_0_config_size; - } VirtIOBalloon; --- -2.19.1 - diff --git a/virtio-balloon-don-t-track-subpages-for-the-PBP.patch b/virtio-balloon-don-t-track-subpages-for-the-PBP.patch deleted file mode 100644 index 942eb762b2bef00bb7b76eaa7c83287b6aeaddeb..0000000000000000000000000000000000000000 --- a/virtio-balloon-don-t-track-subpages-for-the-PBP.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 9a7ca8a7c920360db9dcaf616ca6f1440c025043 Mon Sep 17 00:00:00 2001 -From: David Hildenbrand -Date: Thu, 25 Jul 2019 13:36:38 +0200 -Subject: [PATCH] virtio-balloon: don't track subpages for the PBP - -As ramblocks cannot get removed/readded while we are processing a bulk -of inflation requests, there is no more need to track the page size -in form of the number of subpages. - -Suggested-by: David Gibson -Signed-off-by: David Hildenbrand -Message-Id: <20190725113638.4702-8-david@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry-picked from commit 9a7ca8a7c920360db9dcaf616ca6f1440c025043) ---- - hw/virtio/virtio-balloon.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c -index a6282d58d4..fe9664e42c 100644 ---- a/hw/virtio/virtio-balloon.c -+++ b/hw/virtio/virtio-balloon.c -@@ -36,7 +36,6 @@ - - typedef struct PartiallyBalloonedPage { - ram_addr_t base_gpa; -- long subpages; - unsigned long *bitmap; - } PartiallyBalloonedPage; - -@@ -55,16 +54,15 @@ static PartiallyBalloonedPage *virtio_balloon_pbp_alloc(ram_addr_t base_gpa, - PartiallyBalloonedPage *pbp = g_new0(PartiallyBalloonedPage, 1); - - pbp->base_gpa = base_gpa; -- pbp->subpages = subpages; - pbp->bitmap = bitmap_new(subpages); - - return pbp; - } - - static bool virtio_balloon_pbp_matches(PartiallyBalloonedPage *pbp, -- ram_addr_t base_gpa, long subpages) -+ ram_addr_t base_gpa) - { -- return pbp->subpages == subpages && pbp->base_gpa == base_gpa; -+ return pbp->base_gpa == base_gpa; - } - - static void balloon_inflate_page(VirtIOBalloon *balloon, -@@ -106,7 +104,7 @@ static void balloon_inflate_page(VirtIOBalloon *balloon, - base_gpa = memory_region_get_ram_addr(mr) + mr_offset - - (rb_offset - rb_aligned_offset); - -- if (*pbp && !virtio_balloon_pbp_matches(*pbp, base_gpa, subpages)) { -+ if (*pbp && !virtio_balloon_pbp_matches(*pbp, base_gpa)) { - /* We've partially ballooned part of a host page, but now - * we're trying to balloon part of a different one. Too hard, - * give up on the old partial page */ --- -2.19.1 - diff --git a/virtio-balloon-fix-QEMU-4.0-config-size-migration-in.patch b/virtio-balloon-fix-QEMU-4.0-config-size-migration-in.patch deleted file mode 100644 index be4a77b758b75bfde52359fad57868a4a882d18f..0000000000000000000000000000000000000000 --- a/virtio-balloon-fix-QEMU-4.0-config-size-migration-in.patch +++ /dev/null @@ -1,148 +0,0 @@ -From a6fe4a3aa8007524ffe4758109c08f3ac102c628 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 10 Jul 2019 16:14:40 +0200 -Subject: [PATCH] virtio-balloon: fix QEMU 4.0 config size migration - incompatibility - -The virtio-balloon config size changed in QEMU 4.0 even for existing -machine types. Migration from QEMU 3.1 to 4.0 can fail in some -circumstances with the following error: - - qemu-system-x86_64: get_pci_config_device: Bad config data: i=0x10 read: a1 device: 1 cmask: ff wmask: c0 w1cmask:0 - -This happens because the virtio-balloon config size affects the VIRTIO -Legacy I/O Memory PCI BAR size. - -Introduce a qdev property called "qemu-4-0-config-size" and enable it -only for the QEMU 4.0 machine types. This way <4.0 machine types use -the old size, 4.0 uses the larger size, and >4.0 machine types use the -appropriate size depending on enabled virtio-balloon features. - -Live migration to and from old QEMUs to QEMU 4.1 works again as long as -a versioned machine type is specified (do not use just "pc"!). - -Originally-by: Wolfgang Bumiller -Signed-off-by: Stefan Hajnoczi -Message-Id: <20190710141440.27635-1-stefanha@redhat.com> -Reviewed-by: Dr. David Alan Gilbert -Tested-by: Dr. David Alan Gilbert -Tested-by: Wolfgang Bumiller -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry picked from commit 2bbadb08ce272d65e1f78621002008b07d1e0f03) - Conflicts: - hw/core/machine.c -* drop context dep. on 0a71966253c -Signed-off-by: Michael Roth ---- - hw/core/machine.c | 5 ++++- - hw/virtio/virtio-balloon.c | 28 +++++++++++++++++++++++++--- - include/hw/virtio/virtio-balloon.h | 2 ++ - 3 files changed, 31 insertions(+), 4 deletions(-) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index eb34f53a85..55b08f1466 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -24,7 +24,9 @@ - #include "hw/pci/pci.h" - #include "hw/mem/nvdimm.h" - --GlobalProperty hw_compat_4_0[] = {}; -+GlobalProperty hw_compat_4_0[] = { -+ { "virtio-balloon-device", "qemu-4-0-config-size", "true" }, -+}; - const size_t hw_compat_4_0_len = G_N_ELEMENTS(hw_compat_4_0); - - GlobalProperty hw_compat_3_1[] = { -@@ -39,6 +41,7 @@ GlobalProperty hw_compat_3_1[] = { - { "usb-tablet", "serial", "42" }, - { "virtio-blk-device", "discard", "false" }, - { "virtio-blk-device", "write-zeroes", "false" }, -+ { "virtio-balloon-device", "qemu-4-0-config-size", "false" }, - }; - const size_t hw_compat_3_1_len = G_N_ELEMENTS(hw_compat_3_1); - -diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c -index 2112874055..5579260fd4 100644 ---- a/hw/virtio/virtio-balloon.c -+++ b/hw/virtio/virtio-balloon.c -@@ -615,6 +615,22 @@ virtio_balloon_free_page_report_notify(NotifierWithReturn *n, void *data) - return 0; - } - -+static size_t virtio_balloon_config_size(VirtIOBalloon *s) -+{ -+ uint64_t features = s->host_features; -+ -+ if (s->qemu_4_0_config_size) { -+ return sizeof(struct virtio_balloon_config); -+ } -+ if (virtio_has_feature(features, VIRTIO_BALLOON_F_PAGE_POISON)) { -+ return sizeof(struct virtio_balloon_config); -+ } -+ if (virtio_has_feature(features, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { -+ return offsetof(struct virtio_balloon_config, poison_val); -+ } -+ return offsetof(struct virtio_balloon_config, free_page_report_cmd_id); -+} -+ - static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data) - { - VirtIOBalloon *dev = VIRTIO_BALLOON(vdev); -@@ -635,7 +651,7 @@ static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data) - } - - trace_virtio_balloon_get_config(config.num_pages, config.actual); -- memcpy(config_data, &config, sizeof(struct virtio_balloon_config)); -+ memcpy(config_data, &config, virtio_balloon_config_size(dev)); - } - - static int build_dimm_list(Object *obj, void *opaque) -@@ -679,7 +695,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev, - uint32_t oldactual = dev->actual; - ram_addr_t vm_ram_size = get_current_ram_size(); - -- memcpy(&config, config_data, sizeof(struct virtio_balloon_config)); -+ memcpy(&config, config_data, virtio_balloon_config_size(dev)); - dev->actual = le32_to_cpu(config.actual); - if (dev->actual != oldactual) { - qapi_event_send_balloon_change(vm_ram_size - -@@ -766,7 +782,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) - int ret; - - virtio_init(vdev, "virtio-balloon", VIRTIO_ID_BALLOON, -- sizeof(struct virtio_balloon_config)); -+ virtio_balloon_config_size(s)); - - ret = qemu_add_balloon_handler(virtio_balloon_to_target, - virtio_balloon_stat, s); -@@ -897,6 +913,12 @@ static Property virtio_balloon_properties[] = { - VIRTIO_BALLOON_F_DEFLATE_ON_OOM, false), - DEFINE_PROP_BIT("free-page-hint", VirtIOBalloon, host_features, - VIRTIO_BALLOON_F_FREE_PAGE_HINT, false), -+ /* QEMU 4.0 accidentally changed the config size even when free-page-hint -+ * is disabled, resulting in QEMU 3.1 migration incompatibility. This -+ * property retains this quirk for QEMU 4.1 machine types. -+ */ -+ DEFINE_PROP_BOOL("qemu-4-0-config-size", VirtIOBalloon, -+ qemu_4_0_config_size, false), - DEFINE_PROP_LINK("iothread", VirtIOBalloon, iothread, TYPE_IOTHREAD, - IOThread *), - DEFINE_PROP_END_OF_LIST(), -diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h -index 1afafb12f6..5a99293a45 100644 ---- a/include/hw/virtio/virtio-balloon.h -+++ b/include/hw/virtio/virtio-balloon.h -@@ -71,6 +71,8 @@ typedef struct VirtIOBalloon { - int64_t stats_poll_interval; - uint32_t host_features; - PartiallyBalloonedPage *pbp; -+ -+ bool qemu_4_0_config_size; - } VirtIOBalloon; - - #endif --- -2.19.1 - diff --git a/virtio-balloon-free-pbp-more-aggressively.patch b/virtio-balloon-free-pbp-more-aggressively.patch deleted file mode 100644 index 8ba4bcd66b81dc5ce5a7c015b4b33287a9599249..0000000000000000000000000000000000000000 --- a/virtio-balloon-free-pbp-more-aggressively.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 1b47b37c33ec01ae1efc527f4c97f97f93723bc4 Mon Sep 17 00:00:00 2001 -From: "Michael S. Tsirkin" -Date: Thu, 25 Jul 2019 07:54:25 -0400 -Subject: [PATCH] virtio-balloon: free pbp more aggressively - -Previous patches switched to a temporary pbp but that does not go far -enough: after device uses a buffer, guest is free to reuse it, so -tracking the page and freeing it later is wrong. - -Free and reset the pbp after we push each element. - -Fixes: ed48c59875b6 ("virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size") -Cc: qemu-stable@nongnu.org #v4.0.0 -Cc: David Hildenbrand -Signed-off-by: Michael S. Tsirkin -(cherry-picked from commit 1b47b37c33ec01ae1efc527f4c97f97f93723bc4) ---- - hw/virtio/virtio-balloon.c | 37 ++++++++++++++++--------------------- - 1 file changed, 16 insertions(+), 21 deletions(-) - -diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c -index fe9664e42c..25de154307 100644 ---- a/hw/virtio/virtio-balloon.c -+++ b/hw/virtio/virtio-balloon.c -@@ -41,22 +41,19 @@ typedef struct PartiallyBalloonedPage { - - static void virtio_balloon_pbp_free(PartiallyBalloonedPage *pbp) - { -- if (!pbp) { -+ if (!pbp->bitmap) { - return; - } - g_free(pbp->bitmap); -- g_free(pbp); -+ pbp->bitmap = NULL; - } - --static PartiallyBalloonedPage *virtio_balloon_pbp_alloc(ram_addr_t base_gpa, -- long subpages) -+static void virtio_balloon_pbp_alloc(PartiallyBalloonedPage *pbp, -+ ram_addr_t base_gpa, -+ long subpages) - { -- PartiallyBalloonedPage *pbp = g_new0(PartiallyBalloonedPage, 1); -- - pbp->base_gpa = base_gpa; - pbp->bitmap = bitmap_new(subpages); -- -- return pbp; - } - - static bool virtio_balloon_pbp_matches(PartiallyBalloonedPage *pbp, -@@ -67,7 +64,7 @@ static bool virtio_balloon_pbp_matches(PartiallyBalloonedPage *pbp, - - static void balloon_inflate_page(VirtIOBalloon *balloon, - MemoryRegion *mr, hwaddr mr_offset, -- PartiallyBalloonedPage **pbp) -+ PartiallyBalloonedPage *pbp) - { - void *addr = memory_region_get_ram_ptr(mr) + mr_offset; - ram_addr_t rb_offset, rb_aligned_offset, base_gpa; -@@ -104,22 +101,21 @@ static void balloon_inflate_page(VirtIOBalloon *balloon, - base_gpa = memory_region_get_ram_addr(mr) + mr_offset - - (rb_offset - rb_aligned_offset); - -- if (*pbp && !virtio_balloon_pbp_matches(*pbp, base_gpa)) { -+ if (pbp->bitmap && !virtio_balloon_pbp_matches(pbp, base_gpa)) { - /* We've partially ballooned part of a host page, but now - * we're trying to balloon part of a different one. Too hard, - * give up on the old partial page */ -- virtio_balloon_pbp_free(*pbp); -- *pbp = NULL; -+ virtio_balloon_pbp_free(pbp); - } - -- if (!*pbp) { -- *pbp = virtio_balloon_pbp_alloc(base_gpa, subpages); -+ if (!pbp->bitmap) { -+ virtio_balloon_pbp_alloc(pbp, base_gpa, subpages); - } - - set_bit((rb_offset - rb_aligned_offset) / BALLOON_PAGE_SIZE, -- (*pbp)->bitmap); -+ pbp->bitmap); - -- if (bitmap_full((*pbp)->bitmap, subpages)) { -+ if (bitmap_full(pbp->bitmap, subpages)) { - /* We've accumulated a full host page, we can actually discard - * it now */ - -@@ -127,8 +123,7 @@ static void balloon_inflate_page(VirtIOBalloon *balloon, - /* We ignore errors from ram_block_discard_range(), because it - * has already reported them, and failing to discard a balloon - * page is not fatal */ -- virtio_balloon_pbp_free(*pbp); -- *pbp = NULL; -+ virtio_balloon_pbp_free(pbp); - } - } - -@@ -328,13 +323,14 @@ static void balloon_stats_set_poll_interval(Object *obj, Visitor *v, - static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) - { - VirtIOBalloon *s = VIRTIO_BALLOON(vdev); -- PartiallyBalloonedPage *pbp = NULL; - VirtQueueElement *elem; - MemoryRegionSection section; - - for (;;) { -+ PartiallyBalloonedPage pbp = {}; - size_t offset = 0; - uint32_t pfn; -+ - elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); - if (!elem) { - break; -@@ -379,9 +375,8 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) - virtqueue_push(vq, elem, offset); - virtio_notify(vdev, vq); - g_free(elem); -+ virtio_balloon_pbp_free(&pbp); - } -- -- virtio_balloon_pbp_free(pbp); - } - - static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq) --- -2.19.1 - diff --git a/virtio-pci-fix-missing-device-properties.patch b/virtio-pci-fix-missing-device-properties.patch deleted file mode 100644 index 3281d0404913f65bb5d68cb1f74ec021fb11d479..0000000000000000000000000000000000000000 --- a/virtio-pci-fix-missing-device-properties.patch +++ /dev/null @@ -1,101 +0,0 @@ -From b728ea5f2597f97088db8517576caa2877118cb0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Mon, 5 Aug 2019 16:04:40 +0800 -Subject: [PATCH] virtio-pci: fix missing device properties -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since commit a4ee4c8baa37154 ("virtio: Helper for registering virtio -device types"), virtio-gpu-pci, virtio-vga, and virtio-crypto-pci lost -some properties: "ioeventfd" and "vectors". This may cause various -issues, such as failing migration or invalid properties. - -Since those VirtioPCI devices do not have a base name, their class are -initialized with virtio_pci_generic_base_class_init(). However, if the -VirtioPCIDeviceTypeInfo provided a class_init which sets dc->props, -the properties were overwritten by virtio_pci_generic_class_init(). - -Instead, introduce an intermediary base-type to register the generic -properties. - -Fixes: a4ee4c8baa37154f42b4dc6a13fee79268d15238 -Cc: qemu-stable@nongnu.org -Signed-off-by: Marc-André Lureau -Message-Id: <20190625232333.30752-1-marcandre.lureau@redhat.com> -(cherry-pick from commit 683c1d89efd1eeb111c129a9a91f629b94d90d45) ---- - hw/virtio/virtio-pci.c | 28 ++++++++++++++-------------- - 1 file changed, 14 insertions(+), 14 deletions(-) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index cb44e19b..497092e8 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -1905,13 +1905,6 @@ static void virtio_pci_generic_class_init(ObjectClass *klass, void *data) - dc->props = virtio_pci_generic_properties; - } - --/* Used when the generic type and the base type is the same */ --static void virtio_pci_generic_base_class_init(ObjectClass *klass, void *data) --{ -- virtio_pci_base_class_init(klass, data); -- virtio_pci_generic_class_init(klass, NULL); --} -- - static void virtio_pci_transitional_instance_init(Object *obj) - { - VirtIOPCIProxy *proxy = VIRTIO_PCI(obj); -@@ -1930,14 +1923,13 @@ static void virtio_pci_non_transitional_instance_init(Object *obj) - - void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t) - { -+ char *base_name = NULL; - TypeInfo base_type_info = { - .name = t->base_name, - .parent = t->parent ? t->parent : TYPE_VIRTIO_PCI, - .instance_size = t->instance_size, - .instance_init = t->instance_init, - .class_size = t->class_size, -- .class_init = virtio_pci_base_class_init, -- .class_data = (void *)t, - .abstract = true, - }; - TypeInfo generic_type_info = { -@@ -1953,13 +1945,20 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t) - - if (!base_type_info.name) { - /* No base type -> register a single generic device type */ -- base_type_info.name = t->generic_name; -- base_type_info.class_init = virtio_pci_generic_base_class_init; -- base_type_info.interfaces = generic_type_info.interfaces; -- base_type_info.abstract = false; -- generic_type_info.name = NULL; -+ /* use intermediate %s-base-type to add generic device props */ -+ base_name = g_strdup_printf("%s-base-type", t->generic_name); -+ base_type_info.name = base_name; -+ base_type_info.class_init = virtio_pci_generic_class_init; -+ -+ generic_type_info.parent = base_name; -+ generic_type_info.class_init = virtio_pci_base_class_init; -+ generic_type_info.class_data = (void *)t; -+ - assert(!t->non_transitional_name); - assert(!t->transitional_name); -+ } else { -+ base_type_info.class_init = virtio_pci_base_class_init; -+ base_type_info.class_data = (void *)t; - } - - type_register(&base_type_info); -@@ -1997,6 +1996,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t) - }; - type_register(&transitional_type_info); - } -+ g_free(base_name); - } - - /* virtio-pci-bus */ --- -2.19.1 - diff --git a/vl-Fix-drive-blockdev-persistent-reservation-management.patch b/vl-Fix-drive-blockdev-persistent-reservation-management.patch deleted file mode 100644 index d05c3001b5135816bcafd86f2fb650555afee655..0000000000000000000000000000000000000000 --- a/vl-Fix-drive-blockdev-persistent-reservation-management.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 9ea18ed25a36527167e9676f25d983df5e7f76e6 Mon Sep 17 00:00:00 2001 -From: Markus Armbruster -Date: Tue, 4 Jun 2019 17:12:50 +0200 -Subject: [PATCH] vl: Fix -drive / -blockdev persistent reservation management - -qemu-system-FOO's main() acts on command line arguments in its own -idiosyncratic order. There's not much method to its madness. -Whenever we find a case where one kind of command line argument needs -to refer to something created for another kind later, we rejigger the -order. - -Recent commit cda4aa9a5a "vl: Create block backends before setting -machine properties" was such a rejigger. Block backends are now -created before "delayed" objects. This broke persistent reservation -management. Reproducer: - - $ qemu-system-x86_64 -object pr-manager-helper,id=pr-helper0,path=/tmp/pr-helper0.sock-drive -drive file=/dev/mapper/crypt,file.pr-manager=pr-helper0,format=raw,if=none,id=drive-scsi0-0-0-2 - qemu-system-x86_64: -drive file=/dev/mapper/crypt,file.pr-manager=pr-helper0,format=raw,if=none,id=drive-scsi0-0-0-2: No persistent reservation manager with id 'pr-helper0' - -The delayed pr-manager-helper object is created too late for use by --drive or -blockdev. Normal objects are still created in time. - -pr-manager-helper has always been a delayed object (commit 7c9e527659 -"scsi, file-posix: add support for persistent reservation -management"). Turns out there's no real reason for that. Make it a -normal object. - -Fixes: cda4aa9a5a08777cf13e164c0543bd4888b8adce -Signed-off-by: Markus Armbruster -Message-Id: <20190604151251.9903-2-armbru@redhat.com> -Reviewed-by: Michal Privoznik -Cc: qemu-stable@nongnu.org -Signed-off-by: Paolo Bonzini -(cherry-picked from commit 9ea18ed25a36527167e9676f25d983df5e7f76e6) ---- - vl.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/vl.c b/vl.c -index f023a8ca73..cc6246d2af 100644 ---- a/vl.c -+++ b/vl.c -@@ -2751,8 +2751,7 @@ static bool object_create_initial(const char *type, QemuOpts *opts) - exit(0); - } - -- if (g_str_equal(type, "rng-egd") || -- g_str_has_prefix(type, "pr-manager-")) { -+ if (g_str_equal(type, "rng-egd")) { - return false; - } - --- -2.19.1 -