Re: [PATCH v3 3/3] target/arm: set ID_AA64ISAR0.TLB to 2 for max AARCH64 CPU type

2021-03-10 Thread Richard Henderson

On 3/9/21 6:29 PM, Rebecca Cran wrote:

@@ -651,6 +651,7 @@ static void aarch64_max_initfn(Object *obj)
  t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
  t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
  t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
+t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2);


Just add /* FEAT_TLBIRANGE */ on the line here.
Otherwise,
Reviewed-by: Richard Henderson 

r~



[PATCH v1 6/7] tests/tcg: Use Hexagon Docker image

2021-03-10 Thread Alex Bennée
From: Alessandro Di Federico 

[PMD: Split from 'Add Hexagon Docker image' patch]

Signed-off-by: Alessandro Di Federico 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Alex Bennée 
Message-Id: <20210228222314.304787-5-f4...@amsat.org>
Message-Id: <20210305092328.31792-6-alex.ben...@linaro.org>
---
 tests/tcg/configure.sh | 4 
 1 file changed, 4 insertions(+)

diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
index 36b8a73a54..f70fd7435d 100755
--- a/tests/tcg/configure.sh
+++ b/tests/tcg/configure.sh
@@ -124,6 +124,10 @@ for target in $target_list; do
   container_image=fedora-cris-cross
   container_cross_cc=cris-linux-gnu-gcc
   ;;
+hexagon-*)
+  container_image=debian-hexagon-cross
+  container_cross_cc=hexagon-unknown-linux-musl-clang
+  ;;
 hppa-*)
   container_image=debian-hppa-cross
   container_cross_cc=hppa-linux-gnu-gcc
-- 
2.20.1




[PATCH v1 7/7] gitlab: add build-user-hexagon test

2021-03-10 Thread Alex Bennée
We special case this as the container with the cross compiler for the
tests takes so long to build it is manually uploaded into the
registry.

Signed-off-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Wainer dos Santos Moschetta 
Message-Id: <20210305092328.31792-7-alex.ben...@linaro.org>
---
 .gitlab-ci.yml | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b23364bf3a..5625265ef8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -421,6 +421,17 @@ build-user-static:
 CONFIGURE_ARGS: --disable-tools --disable-system --static
 MAKE_CHECK_ARGS: check-tcg
 
+# Because the hexagon cross-compiler takes so long to build we don't rely
+# on the CI system to build it and hence this job has no dependency
+# declared. The image is manually uploaded.
+build-user-hexagon:
+  <<: *native_build_job_definition
+  variables:
+IMAGE: debian-hexagon-cross
+TARGETS: hexagon-linux-user
+CONFIGURE_ARGS: --disable-tools --disable-docs --enable-debug-tcg
+MAKE_CHECK_ARGS: check-tcg
+
 # Only build the softmmu targets we have check-tcg tests for
 build-some-softmmu:
   <<: *native_build_job_definition
-- 
2.20.1




Re: [RFC] hw/display: add virtio-ramfb device

2021-03-10 Thread Laszlo Ersek
On 03/10/21 17:42, Joelle van Dyne wrote:
> On Wed, Mar 10, 2021 at 4:45 AM Laszlo Ersek  wrote:
>>
>> On 03/10/21 10:51, Gerd Hoffmann wrote:
>>> On Tue, Mar 09, 2021 at 01:35:13PM -0800, Joelle van Dyne wrote:
 Like virtio-vga, but using ramfb instead of legacy vga.
 Useful for booting from OVMF (with updated drivers) into Windows
 ARM which expects a linear FB that the virtio-gpu driver in OVMF
 does not provide.
>>>
>>> What is wrong with "-device ramfb" for that use case?
>>>
 This code was originally written by Gerd Hoffmann and was
 updated to contain later changes to the display driver tree.
>>>
>>> Well, the tricky part with that is OVMF driver binding.  We don't
>>> want two drivers bind to the same device.
>>>
>>> We have QemuRamfbDxe + QemuVideoDxe + VirtioGpuDxe.
>>>
>>>  - QemuRamfbDxe handles ramfb.
>>>  - QemuVideoDxe handles all vga devices (including virtio-vga)
>>>plus bochs-display.
>>>  - VirtioGpuDxe handles all virtio-gpu devices (except virtio-vga).
>>>
>>> VirtioGpuDxe could easily handle virtio-vga too but doesn't to avoid
>>> the conflict with QemuVideoDxe.  It detects that by looking at the pci
>>> class code.  virtio-vga is tagged as display/vga whereas virtio-gpu-pci
>>> is display/other.
>>>
>>> Problem of the virtio-ramfb device is that the guest can't figure
>>> whenever the virtio-gpu device comes with ramfb support or not.
>>> Merging this is a non-starter unless we have a solution for that
>>> problem.
>>>
>>> A use case which actually needs that would be helpful to drive that
>>> effort.  I don't see one.  If your guest comes with virtio-gpu drivers
>>> you don't need ramfb support.  The VirtioGpuDxe driver covers the boot
>>> loader, and the guest driver everything else.  If your guest has no
>>> virtio-gpu drivers the virtio-ramfb combo device is useless, you can
>>> simply use standalone ramfb instead.
>>
>> Thanks for the CC and the summary, and I agree.
>>
>>
>> Two (tangential) additions:
>>
>> - The arbitration between VirtioGpuDxe and QemuVideoDxe, on a virtio-vga
>> device, happens actually in Virtio10Dxe (the virtio-1.0 transport
>> driver). When Virtio10Dxe recognizes virtio-vga, it does not expose it
>> as a virtio device at all.
>>
>> The reason for this is that VirtioGpuDxe consumes VIRTIO_DEVICE_PROTOCOL
>> (does not deal with PCI [*]), and QemuVideoDxe consumes
>> EFI_PCI_IO_PROTOCOL (does not deal with virtio). Therefore, the
>> arbitration needs to happen in a layer that deals with both of those
>> abstractions at the same time; and that's the virtio transport driver,
>> which produces VIRTIO_DEVICE_PROTOCOL on top of EFI_PCI_IO_PROTOCOL.
>>
>> [*] I'm lying a bit here; it does consume PciIo momentarily. But, for
>> nothing relevant to the UEFI driver model. VirtioGpuDxe *attempts* using
>> PciIo for formatting the human-readable device name, with the B/D/F in
>> it; but even if that fails, the driver works just fine (with a less
>> detailed human-readable device name).
>>
>> - QemuRamfbDxe is a platform DXE driver, not a UEFI driver that follows
>> the UEFI driver model. The reason is that the fw_cfg stuff underlying
>> ramfb is a "platform device" (a singleton one at that), not an
>> enumerable device.
>>
>>
>> So, if you combined ramfb with any other (enumerable) display device
>> into a single device, that would allow the QemuRamfbDxe platform driver
>> and the other (UEFI) driver to bind the *same display hardware* via
>> different interfaces at the same time.
>>
>> And arbitrating between such drivers is practically impossible without
>> violating the UEFI driver model: first, the QemuRamfbDxe platform driver
>> has no way of knowing whether the same display hardware qualifies for
>> the other (UEFI) driver though PCI (or another enumerable interface);
>> second, the other (UEFI) driver would have to check for a platform
>> device (fw_cfg in this case), which is *wrong*. (Consider e.g. what
>> happens if we have multiple (separate) PCI-based display devices, plus
>> one ramfb device -- if ramfb were allowed to share the underlying
>> hardware with one of the PCI ones, how would we tell which PCI device
>> the ramfb device belonged to?)
>>
>> (... In fact, the second argument is akin to why I keep rejecting
>> various manifestations of a GVT-g driver for OVMF -- refer to
>> . Due to the
>> opregion being based on fw_cfg, the hardware itself is a fusion of a PCI
>> device and a platform device -- and that's wrong for both a platform DXE
>> driver, and a UEFI driver that follows the UEFI driver model. It's not
>> that the driver is impossible to implement (three variants have been
>> written already, mutually independently of each other), but that any
>> such driver involves a layering / driver model violation one way or
>> another. But, I digress.)
>>
>> Thanks
>> Laszlo
>>
> 
> Thanks for the feedback, Laszlo and Gerd. To avoid the XY problem
> here, what I am trying t

Re: [PATCH v1 0/7] testing/next (hexagon 2, electric boogaloo)

2021-03-10 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20210310192331.29284-1-alex.ben...@linaro.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20210310192331.29284-1-alex.ben...@linaro.org
Subject: [PATCH  v1 0/7] testing/next (hexagon 2, electric boogaloo)

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20210310002917.8876-1-rebe...@nuviainc.com -> 
patchew/20210310002917.8876-1-rebe...@nuviainc.com
 * [new tag] patchew/20210310192331.29284-1-alex.ben...@linaro.org -> 
patchew/20210310192331.29284-1-alex.ben...@linaro.org
Switched to a new branch 'test'
1033b8c gitlab: add build-user-hexagon test
0a3811b tests/tcg: Use Hexagon Docker image
d98a5bd docker: Add Hexagon image
2bbe59e tests/docker: add "fetch" sub-command
4e01e21 tests/docker: allow "update" to add the current user
06d1e23 tests/docker: make executable an optional argument to "update"
7cb400a tests/docker: fix copying of executable in "update"

=== OUTPUT BEGIN ===
1/7 Checking commit 7cb400a521db (tests/docker: fix copying of executable in 
"update")
2/7 Checking commit 06d1e23c51b0 (tests/docker: make executable an optional 
argument to "update")
WARNING: line over 80 characters
#99: FILE: tests/docker/docker.py:562:
+ print("Couldn't add %s/%s to archive" % (so_path, 
name))

total: 0 errors, 1 warnings, 79 lines checked

Patch 2/7 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/7 Checking commit 4e01e215127c (tests/docker: allow "update" to add the 
current user)
4/7 Checking commit 2bbe59ed6894 (tests/docker: add "fetch" sub-command)
5/7 Checking commit d98a5bd95e70 (docker: Add Hexagon image)
WARNING: line over 80 characters
#203: FILE: 
tests/docker/dockerfiles/debian-hexagon-cross.docker.d/build-toolchain.sh:63:
+-DCMAKE_ASM_FLAGS="-G0 -mlong-calls -fno-pic 
--target=hexagon-unknown-linux-musl " \

ERROR: line over 90 characters
#230: FILE: 
tests/docker/dockerfiles/debian-hexagon-cross.docker.d/build-toolchain.sh:90:
+CROSS_CFLAGS="-G0 -O0 -mv65 -fno-builtin -fno-rounding-math 
--target=hexagon-unknown-linux-musl" \

ERROR: line over 90 characters
#267: FILE: 
tests/docker/dockerfiles/debian-hexagon-cross.docker.d/build-toolchain.sh:127:
+CFLAGS="-G0 -O0 -mv65 -fno-builtin -fno-rounding-math 
--target=hexagon-unknown-linux-musl" \

total: 2 errors, 1 warnings, 221 lines checked

Patch 5/7 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

6/7 Checking commit 0a3811b8e453 (tests/tcg: Use Hexagon Docker image)
7/7 Checking commit 1033b8cdde1e (gitlab: add build-user-hexagon test)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20210310192331.29284-1-alex.ben...@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH 1/2] hw/mips/jazz: Use generic I/O bus via get_system_io()

2021-03-10 Thread Peter Xu
On Wed, Mar 10, 2021 at 08:12:54PM +0100, Philippe Mathieu-Daudé wrote:
> No need to create a local ISA I/O MemoryRegion, use get_system_io().
> 
> This partly reverts commit 5c63bcf7501527b844f61624957bdba254d75bfc.

I think it's not a clean revert of that, see below.

> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/mips/jazz.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
> index 1a0888a0fd5..9ac9361b7eb 100644
> --- a/hw/mips/jazz.c
> +++ b/hw/mips/jazz.c
> @@ -158,7 +158,6 @@ static void mips_jazz_init(MachineState *machine,
>  rc4030_dma *dmas;
>  IOMMUMemoryRegion *rc4030_dma_mr;
>  MemoryRegion *isa_mem = g_new(MemoryRegion, 1);
> -MemoryRegion *isa_io = g_new(MemoryRegion, 1);
>  MemoryRegion *rtc = g_new(MemoryRegion, 1);
>  MemoryRegion *i8042 = g_new(MemoryRegion, 1);
>  MemoryRegion *dma_dummy = g_new(MemoryRegion, 1);
> @@ -259,11 +258,10 @@ static void mips_jazz_init(MachineState *machine,
>  memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);
>  
>  /* ISA bus: IO space at 0x9000, mem space at 0x9100 */
> -memory_region_init(isa_io, NULL, "isa-io", 0x0001);
>  memory_region_init(isa_mem, NULL, "isa-mem", 0x0100);
> -memory_region_add_subregion(address_space, 0x9000, isa_io);
> +memory_region_add_subregion(address_space, 0x9000, get_system_io());

The old code has an alias created just for adding subregion into address_space:

-/* ISA IO space at 0x9000 */
-memory_region_init_alias(isa, NULL, "isa_mmio",
- get_system_io(), 0, 0x0100);
-memory_region_add_subregion(address_space, 0x9000, isa);
-isa_mem_base = 0x1100;

While you didn't revert that part.  Maybe that's the issue?

-- 
Peter Xu




[PATCH v4 0/5] Allwinner H3 fixes for EMAC and acceptance tests

2021-03-10 Thread Niek Linnenbank
The following are maintenance patches for the Allwinner H3. The first patch
resolves artifact download errors by updating the URLs to the armbian.com 
server.

The second patch is a fix for the EMAC that is used by the Allwinner H3 / 
Orange Pi PC machine.

All these patches have been reviewed and tested and should be ready to pull in.

ChangeLog:

v4:
 - added Reviewed-By/Tested-By tags

v3:
 - fixed the acceptance tests by using up-to-date armbian.com URLs

v2:
 - added Reviewed-By tags
 - changed URL for artifacts to github.com/nieklinnenbank/QemuArtifacts

Kind regards,

Niek

Niek Linnenbank (5):
  hw/net/allwinner-sun8i-emac: traverse transmit queue using TX_CUR_DESC
register value
  tests/acceptance/boot_linux_console: remove Armbian 19.11.3 bionic
test for orangepi-pc machine
  tests/acceptance/boot_linux_console: change URL for
test_arm_orangepi_bionic_20_08
  tests/acceptance: update sunxi kernel from armbian to 5.10.16
  tests/acceptance: drop ARMBIAN_ARTIFACTS_CACHED condition for
orangepi-pc, cubieboard tests

 hw/net/allwinner-sun8i-emac.c  |  58 ++--
 tests/acceptance/boot_linux_console.py | 120 +
 tests/acceptance/replay_kernel.py  |  10 +--
 3 files changed, 77 insertions(+), 111 deletions(-)

-- 
2.25.1




[PATCH v4 2/5] tests/acceptance/boot_linux_console: remove Armbian 19.11.3 bionic test for orangepi-pc machine

2021-03-10 Thread Niek Linnenbank
The image for Armbian 19.11.3 bionic has been removed from the armbian server.
Without the image as input the test arm_orangepi_bionic_19_11 cannot run.

This commit removes the test completely and merges the code of the generic 
function
do_test_arm_orangepi_uboot_armbian back with the 20.08 test.

Signed-off-by: Niek Linnenbank 
Reviewed-by: Willian Rampazzo 
---
 tests/acceptance/boot_linux_console.py | 72 --
 1 file changed, 23 insertions(+), 49 deletions(-)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index eb01286799..9fadea9958 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -802,7 +802,29 @@ def test_arm_orangepi_sd(self):
 # Wait for VM to shut down gracefully
 self.vm.wait()
 
-def do_test_arm_orangepi_uboot_armbian(self, image_path):
+@skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
+'Test artifacts fetched from unreliable apt.armbian.com')
+@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
+def test_arm_orangepi_bionic_20_08(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:orangepi-pc
+:avocado: tags=device:sd
+"""
+
+# This test download a 275 MiB compressed image and expand it
+# to 1036 MiB, but the underlying filesystem is 1552 MiB...
+# As we expand it to 2 GiB we are safe.
+
+image_url = ('https://dl.armbian.com/orangepipc/archive/'
+ 'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
+image_hash = ('b4d6775f5673486329e45a0586bf06b6'
+  'dbe792199fd182ac6b9c7bb6c7d3e6dd')
+image_path_xz = self.fetch_asset(image_url, asset_hash=image_hash,
+ algorithm='sha256')
+image_path = archive.extract(image_path_xz, self.workdir)
+image_pow2ceil_expand(image_path)
+
 self.vm.set_console()
 self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw',
  '-nic', 'user',
@@ -828,54 +850,6 @@ def do_test_arm_orangepi_uboot_armbian(self, image_path):
   'to ')
 self.wait_for_console_pattern('Starting Load Kernel Modules...')
 
-@skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
-'Test artifacts fetched from unreliable apt.armbian.com')
-@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
-@skipUnless(P7ZIP_AVAILABLE, '7z not installed')
-def test_arm_orangepi_bionic_19_11(self):
-"""
-:avocado: tags=arch:arm
-:avocado: tags=machine:orangepi-pc
-:avocado: tags=device:sd
-"""
-
-# This test download a 196MB compressed image and expand it to 1GB
-image_url = ('https://dl.armbian.com/orangepipc/archive/'
- 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.7z')
-image_hash = '196a8ffb72b0123d92cea4a070894813d305c71e'
-image_path_7z = self.fetch_asset(image_url, asset_hash=image_hash)
-image_name = 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.img'
-image_path = os.path.join(self.workdir, image_name)
-process.run("7z e -o%s %s" % (self.workdir, image_path_7z))
-image_pow2ceil_expand(image_path)
-
-self.do_test_arm_orangepi_uboot_armbian(image_path)
-
-@skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
-'Test artifacts fetched from unreliable apt.armbian.com')
-@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
-def test_arm_orangepi_bionic_20_08(self):
-"""
-:avocado: tags=arch:arm
-:avocado: tags=machine:orangepi-pc
-:avocado: tags=device:sd
-"""
-
-# This test download a 275 MiB compressed image and expand it
-# to 1036 MiB, but the underlying filesystem is 1552 MiB...
-# As we expand it to 2 GiB we are safe.
-
-image_url = ('https://dl.armbian.com/orangepipc/archive/'
- 'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
-image_hash = ('b4d6775f5673486329e45a0586bf06b6'
-  'dbe792199fd182ac6b9c7bb6c7d3e6dd')
-image_path_xz = self.fetch_asset(image_url, asset_hash=image_hash,
- algorithm='sha256')
-image_path = archive.extract(image_path_xz, self.workdir)
-image_pow2ceil_expand(image_path)
-
-self.do_test_arm_orangepi_uboot_armbian(image_path)
-
 @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
 def test_arm_orangepi_uboot_netbsd9(self):
 """
-- 
2.25.1




[PATCH v4 3/5] tests/acceptance/boot_linux_console: change URL for test_arm_orangepi_bionic_20_08

2021-03-10 Thread Niek Linnenbank
Update the download URL of the Armbian 20.08 Bionic image for
test_arm_orangepi_bionic_20_08 of the orangepi-pc machine.

The archive.armbian.com URL contains more images and should keep stable
for a longer period of time than dl.armbian.com.

Signed-off-by: Niek Linnenbank 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Willian Rampazzo 
---
 tests/acceptance/boot_linux_console.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 9fadea9958..4a7a6830ca 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -816,7 +816,7 @@ def test_arm_orangepi_bionic_20_08(self):
 # to 1036 MiB, but the underlying filesystem is 1552 MiB...
 # As we expand it to 2 GiB we are safe.
 
-image_url = ('https://dl.armbian.com/orangepipc/archive/'
+image_url = ('https://archive.armbian.com/orangepipc/archive/'
  'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
 image_hash = ('b4d6775f5673486329e45a0586bf06b6'
   'dbe792199fd182ac6b9c7bb6c7d3e6dd')
-- 
2.25.1




[PATCH v4 1/5] hw/net/allwinner-sun8i-emac: traverse transmit queue using TX_CUR_DESC register value

2021-03-10 Thread Niek Linnenbank
Currently the emulated EMAC for sun8i always traverses the transmit queue
from the head when transferring packets. It searches for a list of consecutive
descriptors whichs are flagged as ready for processing and transmits their 
payloads
accordingly. The controller stops processing once it finds a descriptor that is 
not
marked ready.

While the above behaviour works in most situations, it is not the same as the 
actual
EMAC in hardware. Actual hardware uses the TX_CUR_DESC register value to keep 
track
of the last position in the transmit queue and continues processing from that 
position
when software triggers the start of DMA processing. The currently emulated 
behaviour can
lead to packet loss on transmit when software fills the transmit queue with 
ready
descriptors that overlap the tail of the circular list.

This commit modifies the emulated EMAC for sun8i such that it processes
the transmit queue using the TX_CUR_DESC register in the same way as hardware.

Signed-off-by: Niek Linnenbank 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/net/allwinner-sun8i-emac.c | 58 +++
 1 file changed, 32 insertions(+), 26 deletions(-)

diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
index 042768922c..e586c147e5 100644
--- a/hw/net/allwinner-sun8i-emac.c
+++ b/hw/net/allwinner-sun8i-emac.c
@@ -339,35 +339,40 @@ static void 
allwinner_sun8i_emac_update_irq(AwSun8iEmacState *s)
 qemu_set_irq(s->irq, (s->int_sta & s->int_en) != 0);
 }
 
-static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
-   FrameDescriptor *desc,
-   size_t min_size)
+static bool allwinner_sun8i_emac_desc_owned(FrameDescriptor *desc,
+size_t min_buf_size)
 {
-uint32_t paddr = desc->next;
+return (desc->status & DESC_STATUS_CTL) && (min_buf_size == 0 ||
+   (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_buf_size);
+}
 
-dma_memory_read(&s->dma_as, paddr, desc, sizeof(*desc));
+static void allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
+  FrameDescriptor *desc,
+  uint32_t phys_addr)
+{
+dma_memory_read(&s->dma_as, phys_addr, desc, sizeof(*desc));
+}
 
-if ((desc->status & DESC_STATUS_CTL) &&
-(desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) {
-return paddr;
-} else {
-return 0;
-}
+static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
+   FrameDescriptor *desc)
+{
+const uint32_t nxt = desc->next;
+allwinner_sun8i_emac_get_desc(s, desc, nxt);
+return nxt;
 }
 
-static uint32_t allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
-  FrameDescriptor *desc,
-  uint32_t start_addr,
-  size_t min_size)
+static uint32_t allwinner_sun8i_emac_find_desc(AwSun8iEmacState *s,
+   FrameDescriptor *desc,
+   uint32_t start_addr,
+   size_t min_size)
 {
 uint32_t desc_addr = start_addr;
 
 /* Note that the list is a cycle. Last entry points back to the head. */
 while (desc_addr != 0) {
-dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc));
+allwinner_sun8i_emac_get_desc(s, desc, desc_addr);
 
-if ((desc->status & DESC_STATUS_CTL) &&
-(desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) {
+if (allwinner_sun8i_emac_desc_owned(desc, min_size)) {
 return desc_addr;
 } else if (desc->next == start_addr) {
 break;
@@ -383,14 +388,14 @@ static uint32_t 
allwinner_sun8i_emac_rx_desc(AwSun8iEmacState *s,
  FrameDescriptor *desc,
  size_t min_size)
 {
-return allwinner_sun8i_emac_get_desc(s, desc, s->rx_desc_curr, min_size);
+return allwinner_sun8i_emac_find_desc(s, desc, s->rx_desc_curr, min_size);
 }
 
 static uint32_t allwinner_sun8i_emac_tx_desc(AwSun8iEmacState *s,
- FrameDescriptor *desc,
- size_t min_size)
+ FrameDescriptor *desc)
 {
-return allwinner_sun8i_emac_get_desc(s, desc, s->tx_desc_head, min_size);
+allwinner_sun8i_emac_get_desc(s, desc, s->tx_desc_curr);
+return s->tx_desc_curr;
 }
 
 static void allwinner_sun8i_emac_flush_desc(AwSun8iEmacState *s,
@@ -470,7 +475,8 @@ static ssize_t allwinner_sun8i_emac_receive(NetClientState 
*nc,
 bytes_left -= desc_bytes;
 
 /* Move to the next descriptor */
-s->rx_desc_curr = 

[PATCH v4 5/5] tests/acceptance: drop ARMBIAN_ARTIFACTS_CACHED condition for orangepi-pc, cubieboard tests

2021-03-10 Thread Niek Linnenbank
Previously the ARMBIAN_ARTIFACTS_CACHED pre-condition was added to allow running
tests that have already existing armbian.com artifacts stored in the local 
avocado cache,
but do not have working URLs to download a fresh copy.

At this time of writing the URLs for artifacts on the armbian.com server are 
updated and working.
Any future broken URLs will result in a skipped acceptance test, for example:

 (1/5) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi:
  CANCEL: Missing asset 
https://apt.armbian.com/pool/main/l/linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb
 (0.53 s)

This commits removes the ARMBIAN_ARTIFACTS_CACHED pre-condition such that
the acceptance tests for the orangepi-pc and cubieboard machines can run.

Signed-off-by: Niek Linnenbank 
Reviewed-by: Willian Rampazzo 
---
 tests/acceptance/boot_linux_console.py | 12 
 tests/acceptance/replay_kernel.py  |  2 --
 2 files changed, 14 deletions(-)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 04a8b23352..1ca32ecf25 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -507,8 +507,6 @@ def test_arm_exynos4210_initrd(self):
 self.wait_for_console_pattern('Boot successful.')
 # TODO user command, for now the uart is stuck
 
-@skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
-'Test artifacts fetched from unreliable apt.armbian.com')
 def test_arm_cubieboard_initrd(self):
 """
 :avocado: tags=arch:arm
@@ -549,8 +547,6 @@ def test_arm_cubieboard_initrd(self):
 'system-control@1c0')
 # cubieboard's reboot is not functioning; omit reboot test.
 
-@skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
-'Test artifacts fetched from unreliable apt.armbian.com')
 def test_arm_cubieboard_sata(self):
 """
 :avocado: tags=arch:arm
@@ -678,8 +674,6 @@ def test_arm_quanta_gsj_initrd(self):
 self.wait_for_console_pattern(
 'Give root password for system maintenance')
 
-@skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
-'Test artifacts fetched from unreliable apt.armbian.com')
 def test_arm_orangepi(self):
 """
 :avocado: tags=arch:arm
@@ -705,8 +699,6 @@ def test_arm_orangepi(self):
 console_pattern = 'Kernel command line: %s' % kernel_command_line
 self.wait_for_console_pattern(console_pattern)
 
-@skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
-'Test artifacts fetched from unreliable apt.armbian.com')
 def test_arm_orangepi_initrd(self):
 """
 :avocado: tags=arch:arm
@@ -749,8 +741,6 @@ def test_arm_orangepi_initrd(self):
 # Wait for VM to shut down gracefully
 self.vm.wait()
 
-@skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
-'Test artifacts fetched from unreliable apt.armbian.com')
 def test_arm_orangepi_sd(self):
 """
 :avocado: tags=arch:arm
@@ -802,8 +792,6 @@ def test_arm_orangepi_sd(self):
 # Wait for VM to shut down gracefully
 self.vm.wait()
 
-@skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
-'Test artifacts fetched from unreliable apt.armbian.com')
 @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
 def test_arm_orangepi_bionic_20_08(self):
 """
diff --git a/tests/acceptance/replay_kernel.py 
b/tests/acceptance/replay_kernel.py
index 8c68caae31..71facdaa75 100644
--- a/tests/acceptance/replay_kernel.py
+++ b/tests/acceptance/replay_kernel.py
@@ -177,8 +177,6 @@ def test_arm_virt(self):
 self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=1)
 
 @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
-@skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
-'Test artifacts fetched from unreliable apt.armbian.com')
 def test_arm_cubieboard_initrd(self):
 """
 :avocado: tags=arch:arm
-- 
2.25.1




[PATCH v4 4/5] tests/acceptance: update sunxi kernel from armbian to 5.10.16

2021-03-10 Thread Niek Linnenbank
The linux kernel 4.20.7 binary for sunxi has been removed from apt.armbian.com:

  $ ARMBIAN_ARTIFACTS_CACHED=yes AVOCADO_ALLOW_LARGE_STORAGE=yes avocado 
--show=app,console run -t machine:orangepi-pc 
tests/acceptance/boot_linux_console.py
  Fetching asset from 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi
  ...
  (1/6) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi:
CANCEL: Missing asset 
https://apt.armbian.com/pool/main/l/linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb
 (0.55 s)

This commit updates the sunxi kernel to 5.10.16 for the acceptance
tests of the orangepi-pc and cubieboard machines.

Signed-off-by: Niek Linnenbank 
Reviewed-by: Willian Rampazzo 
---
 tests/acceptance/boot_linux_console.py | 40 +-
 tests/acceptance/replay_kernel.py  |  8 +++---
 2 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 4a7a6830ca..04a8b23352 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -515,12 +515,12 @@ def test_arm_cubieboard_initrd(self):
 :avocado: tags=machine:cubieboard
 """
 deb_url = ('https://apt.armbian.com/pool/main/l/'
-   'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
-deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
+   
'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
+deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
 deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
 kernel_path = self.extract_from_deb(deb_path,
-'/boot/vmlinuz-4.20.7-sunxi')
-dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
+'/boot/vmlinuz-5.10.16-sunxi')
+dtb_path = 
'/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
 dtb_path = self.extract_from_deb(deb_path, dtb_path)
 initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
   '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
@@ -557,12 +557,12 @@ def test_arm_cubieboard_sata(self):
 :avocado: tags=machine:cubieboard
 """
 deb_url = ('https://apt.armbian.com/pool/main/l/'
-   'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
-deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
+   
'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
+deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
 deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
 kernel_path = self.extract_from_deb(deb_path,
-'/boot/vmlinuz-4.20.7-sunxi')
-dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
+'/boot/vmlinuz-5.10.16-sunxi')
+dtb_path = 
'/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
 dtb_path = self.extract_from_deb(deb_path, dtb_path)
 rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
   '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
@@ -686,12 +686,12 @@ def test_arm_orangepi(self):
 :avocado: tags=machine:orangepi-pc
 """
 deb_url = ('https://apt.armbian.com/pool/main/l/'
-   'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
-deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
+   
'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
+deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
 deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
 kernel_path = self.extract_from_deb(deb_path,
-'/boot/vmlinuz-4.20.7-sunxi')
-dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
+'/boot/vmlinuz-5.10.16-sunxi')
+dtb_path = 
'/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
 dtb_path = self.extract_from_deb(deb_path, dtb_path)
 
 self.vm.set_console()
@@ -713,12 +713,12 @@ def test_arm_orangepi_initrd(self):
 :avocado: tags=machine:orangepi-pc
 """
 deb_url = ('https://apt.armbian.com/pool/main/l/'
-   'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
-deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
+   
'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
+deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
 deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
 kernel_path = self.extract_from_deb(deb_path,
-'/boot/vmlinuz-4

Re: [PULL 00/14] Gitlab, testing and misc patches

2021-03-10 Thread Peter Maydell
On Tue, 9 Mar 2021 at 10:55, Thomas Huth  wrote:
>
>  Hi Peter,
>
> the following changes since commit 229a834518b950d56fd1bc94923276504d0ee9d4:
>
>   Merge remote-tracking branch 'remotes/philmd-gitlab/tags/renesas-20210306' 
> into staging (2021-03-08 15:45:48 +)
>
> are available in the Git repository at:
>
>   https://gitlab.com/thuth/qemu.git tags/pull-request-2021-03-09
>
> for you to fetch changes up to 65a9d3807e9a0ffd9f9719416a07be41b6f39e94:
>
>   bsd-user: Add new maintainers (2021-03-09 11:26:32 +0100)
>
> Gitlab-CI run can be found here:
>
>  https://gitlab.com/thuth/qemu/-/pipelines/267522743
>
> 
> * Add some missing gitlab-CI job dependencies
> * Re-enable "make check SPEED=slow"
> * Improve the gitlab-pipeline-status script
> * Clean up inclusing of qtest.h headers
> * Improve libqos/qgraph documentation
> * Fix downloading problem in the acceptance tests
> * Remove deprecated target tilegx
> * Add new bsd-user maintainers


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/6.0
for any user-visible changes.

-- PMM



Re: [PATCH 1/2] hw/mips/jazz: Use generic I/O bus via get_system_io()

2021-03-10 Thread Philippe Mathieu-Daudé
On 3/10/21 8:49 PM, Peter Xu wrote:
> On Wed, Mar 10, 2021 at 08:12:54PM +0100, Philippe Mathieu-Daudé wrote:
>> No need to create a local ISA I/O MemoryRegion, use get_system_io().
>>
>> This partly reverts commit 5c63bcf7501527b844f61624957bdba254d75bfc.
> 
> I think it's not a clean revert of that, see below.
> 
>>
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
>>  hw/mips/jazz.c | 6 ++
>>  1 file changed, 2 insertions(+), 4 deletions(-)
>>
>> diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
>> index 1a0888a0fd5..9ac9361b7eb 100644
>> --- a/hw/mips/jazz.c
>> +++ b/hw/mips/jazz.c
>> @@ -158,7 +158,6 @@ static void mips_jazz_init(MachineState *machine,
>>  rc4030_dma *dmas;
>>  IOMMUMemoryRegion *rc4030_dma_mr;
>>  MemoryRegion *isa_mem = g_new(MemoryRegion, 1);
>> -MemoryRegion *isa_io = g_new(MemoryRegion, 1);
>>  MemoryRegion *rtc = g_new(MemoryRegion, 1);
>>  MemoryRegion *i8042 = g_new(MemoryRegion, 1);
>>  MemoryRegion *dma_dummy = g_new(MemoryRegion, 1);
>> @@ -259,11 +258,10 @@ static void mips_jazz_init(MachineState *machine,
>>  memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);
>>  
>>  /* ISA bus: IO space at 0x9000, mem space at 0x9100 */
>> -memory_region_init(isa_io, NULL, "isa-io", 0x0001);
>>  memory_region_init(isa_mem, NULL, "isa-mem", 0x0100);
>> -memory_region_add_subregion(address_space, 0x9000, isa_io);
>> +memory_region_add_subregion(address_space, 0x9000, get_system_io());
> 
> The old code has an alias created just for adding subregion into 
> address_space:
> 
> -/* ISA IO space at 0x9000 */
> -memory_region_init_alias(isa, NULL, "isa_mmio",
> - get_system_io(), 0, 0x0100);
> -memory_region_add_subregion(address_space, 0x9000, isa);
> -isa_mem_base = 0x1100;
> 
> While you didn't revert that part.  Maybe that's the issue?

Hmm I'll have a look. This is not the series I'm working on, which
is much bigger and not ready for posting yet. I simply looked for
something similar (a bus mapped into sysbus) and remembered the
ISA bus from Jazz machines. I'll see if I can find a better PoC.

Thanks for having a look at this patch,

Phil.



Re: [PATCH v1 4/7] tests/docker: add "fetch" sub-command

2021-03-10 Thread Philippe Mathieu-Daudé
On 3/10/21 8:23 PM, Alex Bennée wrote:
> This simply wraps up fetching a build from the registry and tagging it
> as the local build.
> 
> Signed-off-by: Alex Bennée 
> ---
>  tests/docker/docker.py | 17 +
>  1 file changed, 17 insertions(+)

Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v4 00/78] target/arm: Implement SVE2

2021-03-10 Thread Peter Maydell
On Tue, 9 Mar 2021 at 16:20, Richard Henderson
 wrote:
>
> After a 6-month hiatus, sve2 is back.  This time, with RISU
> testing vs FVP 11.13.36.
>
> Based-on: 20210309155305.11301-1-richard.hender...@linaro.org
> ("target/arm: sve1 fixes")

Are you hoping to squeeze this into 6.0, or can I delay
review of it in favour of for-6.0 stuff ?

thanks
-- PMM



Re: [PATCH] vfio: Support host translation granule size

2021-03-10 Thread Alex Williamson
On Wed, 10 Mar 2021 15:19:33 +0800
Kunkun Jiang  wrote:

> Hi Alex,
> 
> On 2021/3/10 7:17, Alex Williamson wrote:
> > On Thu, 4 Mar 2021 21:34:46 +0800
> > Kunkun Jiang  wrote:
> >  
> >> The cpu_physical_memory_set_dirty_lebitmap() can quickly deal with
> >> the dirty pages of memory by bitmap-traveling, regardless of whether
> >> the bitmap is aligned correctly or not.
> >>
> >> cpu_physical_memory_set_dirty_lebitmap() supports pages in bitmap of
> >> host page size. So it'd better to set bitmap_pgsize to host page size
> >> to support more translation granule sizes.
> >>
> >> Fixes: 87ea529c502 (vfio: Get migration capability flags for container)
> >> Signed-off-by: Kunkun Jiang 
> >> ---
> >>   hw/vfio/common.c | 44 ++--
> >>   1 file changed, 22 insertions(+), 22 deletions(-)
> >>
> >> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> >> index 6ff1daa763..69fb5083a4 100644
> >> --- a/hw/vfio/common.c
> >> +++ b/hw/vfio/common.c
> >> @@ -378,7 +378,7 @@ static int vfio_dma_unmap_bitmap(VFIOContainer 
> >> *container,
> >>   {
> >>   struct vfio_iommu_type1_dma_unmap *unmap;
> >>   struct vfio_bitmap *bitmap;
> >> -uint64_t pages = TARGET_PAGE_ALIGN(size) >> TARGET_PAGE_BITS;
> >> +uint64_t pages = REAL_HOST_PAGE_ALIGN(size) / 
> >> qemu_real_host_page_size;
> >>   int ret;
> >>   
> >>   unmap = g_malloc0(sizeof(*unmap) + sizeof(*bitmap));
> >> @@ -390,12 +390,12 @@ static int vfio_dma_unmap_bitmap(VFIOContainer 
> >> *container,
> >>   bitmap = (struct vfio_bitmap *)&unmap->data;
> >>   
> >>   /*
> >> - * cpu_physical_memory_set_dirty_lebitmap() expects pages in bitmap of
> >> - * TARGET_PAGE_SIZE to mark those dirty. Hence set bitmap_pgsize to
> >> - * TARGET_PAGE_SIZE.
> >> + * cpu_physical_memory_set_dirty_lebitmap() supports pages in bitmap 
> >> of
> >> + * qemu_real_host_page_size to mark those dirty. Hence set 
> >> bitmap_pgsize
> >> + * to qemu_real_host_page_size.  
> >
> > I don't see that this change is well supported by the code,
> > cpu_physical_memory_set_dirty_lebitmap() seems to operate on  
> Yes, cpu_physical_memory_set_dirty_lebitmap() is finally to operate on
> TARGET_PAGE_SIZE. But actually it supports pages in bitmap of
> qemu_real_host_page_size to mark those dirty. It uses
> "hpratio = qemu_real_host_page_size / TARGET_PAGE_SIZE" to adapt to
> different translation granule size(e.g. 4K 2M 1G).

Thanks for the explanation, it becomes more clear but I'm still a
little confused.  It appears that
cpu_physical_memory_set_dirty_lebitmap() requires a bitmap in terms of
qemu_real_host_page_size which is translated to target pages using
hpratio.  It's not clear to me by the explanation here and in the
commit log that we're technically using the wrong page size reference
for this function.

> > TARGET_PAGE_SIZE, and the next three patch chunks take a detour through
> > memory listener code that seem unrelated to the change described in the
> > commit log.  This claims to fix something, what is actually broken?
> > Thanks,
> >
> > Alex  
> This patch 87ea529c502 (vfio: Get migration capability flags for container)
> is the start of the bug. The code of [1](marked below) restricts the host
> page size must be TARGET_PAGE_SIZE(e.g. 4K) to set
> container->dirty_pages_supported = true. It is inappropriate to limit the
> page size to TARGET_PAGE_SIZE.

Right, the noted code requires that vfio supports the target page size,
which for all practical purposes implies an hpratio = 1 currently.
That unnecessarily restricts migration support to cases where target and
host use the same page size, but this change allows migration in any
case where vfio dirty bitmap supports the host page size, which is
effectively any case where the device supports migration.  However, the
hpratio calculation requires that qemu_real_host_page_size is >=
TARGET_PAGE_SIZE, otherwise the value becomes zero and it appears we'd
only ever dirty the target zero page.  Is this configuration restricted
elsewhere, ex. 64K guest on 4K host?  Exchanging an unnecessary
restriction for allowing a buggy configuration isn't a good trade-off.
Thanks,

Alex

> >>*/
> >>   
> >> -bitmap->pgsize = TARGET_PAGE_SIZE;
> >> +bitmap->pgsize = qemu_real_host_page_size;
> >>   bitmap->size = ROUND_UP(pages, sizeof(__u64) * BITS_PER_BYTE) /
> >>  BITS_PER_BYTE;
> >>   
> >> @@ -674,16 +674,16 @@ static void vfio_listener_region_add(MemoryListener 
> >> *listener,
> >>   return;
> >>   }
> >>   
> >> -if (unlikely((section->offset_within_address_space & 
> >> ~TARGET_PAGE_MASK) !=
> >> - (section->offset_within_region & ~TARGET_PAGE_MASK))) {
> >> +if (unlikely((section->offset_within_address_space & 
> >> ~qemu_real_host_page_mask) !=
> >> + (section->offset_within_region & 
> >> ~qemu_real_host_page_mask))) {
> >>   error_report("%s received unalig

Re: [PATCH 1/2] hw/mips/jazz: Use generic I/O bus via get_system_io()

2021-03-10 Thread Peter Xu
On Wed, Mar 10, 2021 at 09:11:40PM +0100, Philippe Mathieu-Daudé wrote:
> >>  /* ISA bus: IO space at 0x9000, mem space at 0x9100 */
> >> -memory_region_init(isa_io, NULL, "isa-io", 0x0001);
> >>  memory_region_init(isa_mem, NULL, "isa-mem", 0x0100);
> >> -memory_region_add_subregion(address_space, 0x9000, isa_io);
> >> +memory_region_add_subregion(address_space, 0x9000, 
> >> get_system_io());
> > 
> > The old code has an alias created just for adding subregion into 
> > address_space:
> > 
> > -/* ISA IO space at 0x9000 */
> > -memory_region_init_alias(isa, NULL, "isa_mmio",
> > - get_system_io(), 0, 0x0100);
> > -memory_region_add_subregion(address_space, 0x9000, isa);
> > -isa_mem_base = 0x1100;
> > 
> > While you didn't revert that part.  Maybe that's the issue?
> 
> Hmm I'll have a look. This is not the series I'm working on, which
> is much bigger and not ready for posting yet. I simply looked for
> something similar (a bus mapped into sysbus) and remembered the
> ISA bus from Jazz machines. I'll see if I can find a better PoC.

Yeah no worry - it's just that I feel one memory_region_init_alias() call is
probably missing in your huge series somewhere, so that you'll take that alias
MR as subregion rather than the real MR (which is the root of one AS).

-- 
Peter Xu




[PATCH v5 03/10] KVM: Create the KVMSlot dirty bitmap on flag changes

2021-03-10 Thread Peter Xu
Previously we have two places that will create the per KVMSlot dirty
bitmap:

  1. When a newly created KVMSlot has dirty logging enabled,
  2. When the first log_sync() happens for a memory slot.

The 2nd case is lazy-init, while the 1st case is not (which is a fix
of what the 2nd case missed).

To do explicit initialization of dirty bitmaps, what we're missing is
to create the dirty bitmap when the slot changed from not-dirty-track
to dirty-track.  Do that in kvm_slot_update_flags().

With that, we can safely remove the 2nd lazy-init.

This change will be needed for kvm dirty ring because kvm dirty ring
does not use the log_sync() interface at all.

Also move all the pre-checks into kvm_slot_init_dirty_bitmap().

Reviewed-by: Dr. David Alan Gilbert 
Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c | 23 +--
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 94e881f123b..fa337418636 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -179,6 +179,8 @@ static QemuMutex kml_slots_lock;
 #define kvm_slots_lock()  qemu_mutex_lock(&kml_slots_lock)
 #define kvm_slots_unlock()  qemu_mutex_unlock(&kml_slots_lock)
 
+static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
+
 static inline void kvm_resample_fd_remove(int gsi)
 {
 KVMResampleFd *rfd;
@@ -502,6 +504,7 @@ static int kvm_slot_update_flags(KVMMemoryListener *kml, 
KVMSlot *mem,
 return 0;
 }
 
+kvm_slot_init_dirty_bitmap(mem);
 return kvm_set_user_memory_region(kml, mem, false);
 }
 
@@ -586,8 +589,12 @@ static int 
kvm_get_dirty_pages_log_range(MemoryRegionSection *section,
 #define ALIGN(x, y)  (((x)+(y)-1) & ~((y)-1))
 
 /* Allocate the dirty bitmap for a slot  */
-static void kvm_memslot_init_dirty_bitmap(KVMSlot *mem)
+static void kvm_slot_init_dirty_bitmap(KVMSlot *mem)
 {
+if (!(mem->flags & KVM_MEM_LOG_DIRTY_PAGES) || mem->dirty_bmap) {
+return;
+}
+
 /*
  * XXX bad kernel interface alert
  * For dirty bitmap, kernel allocates array of size aligned to
@@ -642,11 +649,6 @@ static int 
kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
 goto out;
 }
 
-if (!mem->dirty_bmap) {
-/* Allocate on the first log_sync, once and for all */
-kvm_memslot_init_dirty_bitmap(mem);
-}
-
 d.dirty_bitmap = mem->dirty_bmap;
 d.slot = mem->slot | (kml->as_id << 16);
 ret = kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d);
@@ -1190,14 +1192,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 mem->start_addr = start_addr;
 mem->ram = ram;
 mem->flags = kvm_mem_flags(mr);
-
-if (mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
-/*
- * Reallocate the bmap; it means it doesn't disappear in
- * middle of a migrate.
- */
-kvm_memslot_init_dirty_bitmap(mem);
-}
+kvm_slot_init_dirty_bitmap(mem);
 err = kvm_set_user_memory_region(kml, mem, true);
 if (err) {
 fprintf(stderr, "%s: error registering slot: %s\n", __func__,
-- 
2.26.2




[PATCH v5 02/10] KVM: Use a big lock to replace per-kml slots_lock

2021-03-10 Thread Peter Xu
Per-kml slots_lock will bring some trouble if we want to take all slots_lock of
all the KMLs, especially when we're in a context that we could have taken some
of the KML slots_lock, then we even need to figure out what we've taken and
what we need to take.

Make this simple by merging all KML slots_lock into a single slots lock.

Per-kml slots_lock isn't anything that helpful anyway - so far only x86 has two
address spaces (so, two slots_locks).  All the rest archs will be having one
address space always, which means there's actually one slots_lock so it will be
the same as before.

Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c  | 32 +---
 include/sysemu/kvm_int.h |  2 --
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index f88a52393fe..94e881f123b 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -174,8 +174,10 @@ typedef struct KVMResampleFd KVMResampleFd;
 static QLIST_HEAD(, KVMResampleFd) kvm_resample_fd_list =
 QLIST_HEAD_INITIALIZER(kvm_resample_fd_list);
 
-#define kvm_slots_lock(kml)  qemu_mutex_lock(&(kml)->slots_lock)
-#define kvm_slots_unlock(kml)qemu_mutex_unlock(&(kml)->slots_lock)
+static QemuMutex kml_slots_lock;
+
+#define kvm_slots_lock()  qemu_mutex_lock(&kml_slots_lock)
+#define kvm_slots_unlock()  qemu_mutex_unlock(&kml_slots_lock)
 
 static inline void kvm_resample_fd_remove(int gsi)
 {
@@ -241,9 +243,9 @@ bool kvm_has_free_slot(MachineState *ms)
 bool result;
 KVMMemoryListener *kml = &s->memory_listener;
 
-kvm_slots_lock(kml);
+kvm_slots_lock();
 result = !!kvm_get_free_slot(kml);
-kvm_slots_unlock(kml);
+kvm_slots_unlock();
 
 return result;
 }
@@ -309,7 +311,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void 
*ram,
 KVMMemoryListener *kml = &s->memory_listener;
 int i, ret = 0;
 
-kvm_slots_lock(kml);
+kvm_slots_lock();
 for (i = 0; i < s->nr_slots; i++) {
 KVMSlot *mem = &kml->slots[i];
 
@@ -319,7 +321,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void 
*ram,
 break;
 }
 }
-kvm_slots_unlock(kml);
+kvm_slots_unlock();
 
 return ret;
 }
@@ -515,7 +517,7 @@ static int kvm_section_update_flags(KVMMemoryListener *kml,
 return 0;
 }
 
-kvm_slots_lock(kml);
+kvm_slots_lock();
 
 while (size && !ret) {
 slot_size = MIN(kvm_max_slot_size, size);
@@ -531,7 +533,7 @@ static int kvm_section_update_flags(KVMMemoryListener *kml,
 }
 
 out:
-kvm_slots_unlock(kml);
+kvm_slots_unlock();
 return ret;
 }
 
@@ -819,7 +821,7 @@ static int kvm_physical_log_clear(KVMMemoryListener *kml,
 return ret;
 }
 
-kvm_slots_lock(kml);
+kvm_slots_lock();
 
 for (i = 0; i < s->nr_slots; i++) {
 mem = &kml->slots[i];
@@ -845,7 +847,7 @@ static int kvm_physical_log_clear(KVMMemoryListener *kml,
 }
 }
 
-kvm_slots_unlock(kml);
+kvm_slots_unlock();
 
 return ret;
 }
@@ -1150,7 +1152,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 ram = memory_region_get_ram_ptr(mr) + section->offset_within_region +
   (start_addr - section->offset_within_address_space);
 
-kvm_slots_lock(kml);
+kvm_slots_lock();
 
 if (!add) {
 do {
@@ -1208,7 +1210,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 } while (size);
 
 out:
-kvm_slots_unlock(kml);
+kvm_slots_unlock();
 }
 
 static void kvm_region_add(MemoryListener *listener,
@@ -1235,9 +1237,9 @@ static void kvm_log_sync(MemoryListener *listener,
 KVMMemoryListener *kml = container_of(listener, KVMMemoryListener, 
listener);
 int r;
 
-kvm_slots_lock(kml);
+kvm_slots_lock();
 r = kvm_physical_sync_dirty_bitmap(kml, section);
-kvm_slots_unlock(kml);
+kvm_slots_unlock();
 if (r < 0) {
 abort();
 }
@@ -1337,7 +1339,7 @@ void kvm_memory_listener_register(KVMState *s, 
KVMMemoryListener *kml,
 {
 int i;
 
-qemu_mutex_init(&kml->slots_lock);
+qemu_mutex_init(&kml_slots_lock);
 kml->slots = g_malloc0(s->nr_slots * sizeof(KVMSlot));
 kml->as_id = as_id;
 
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index ccb8869f01b..1da30e18841 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -27,8 +27,6 @@ typedef struct KVMSlot
 
 typedef struct KVMMemoryListener {
 MemoryListener listener;
-/* Protects the slots and all inside them */
-QemuMutex slots_lock;
 KVMSlot *slots;
 int as_id;
 } KVMMemoryListener;
-- 
2.26.2




[PATCH v5 01/10] memory: Introduce log_sync_global() to memory listener

2021-03-10 Thread Peter Xu
Some of the memory listener may want to do log synchronization without
being able to specify a range of memory to sync but always globally.
Such a memory listener should provide this new method instead of the
log_sync() method.

Obviously we can also achieve similar thing when we put the global
sync logic into a log_sync() handler. However that's not efficient
enough because otherwise memory_global_dirty_log_sync() may do the
global sync N times, where N is the number of flat ranges in the
address space.

Make this new method be exclusive to log_sync().

Reviewed-by: Dr. David Alan Gilbert 
Signed-off-by: Peter Xu 
---
 include/exec/memory.h | 12 
 softmmu/memory.c  | 33 +++--
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index c6fb714e499..e52e2c31eb7 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -616,6 +616,18 @@ struct MemoryListener {
  */
 void (*log_sync)(MemoryListener *listener, MemoryRegionSection *section);
 
+/**
+ * @log_sync_global:
+ *
+ * This is the global version of @log_sync when the listener does
+ * not have a way to synchronize the log with finer granularity.
+ * When the listener registers with @log_sync_global defined, then
+ * its @log_sync must be NULL.  Vice versa.
+ *
+ * @listener: The #MemoryListener.
+ */
+void (*log_sync_global)(MemoryListener *listener);
+
 /**
  * @log_clear:
  *
diff --git a/softmmu/memory.c b/softmmu/memory.c
index 874a8fccdee..f655ed83129 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -2056,6 +2056,10 @@ void memory_region_set_dirty(MemoryRegion *mr, hwaddr 
addr,
 memory_region_get_dirty_log_mask(mr));
 }
 
+/*
+ * If memory region `mr' is NULL, do global sync.  Otherwise, sync
+ * dirty bitmap for the specified memory region.
+ */
 static void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
 {
 MemoryListener *listener;
@@ -2069,18 +2073,24 @@ static void 
memory_region_sync_dirty_bitmap(MemoryRegion *mr)
  * address space once.
  */
 QTAILQ_FOREACH(listener, &memory_listeners, link) {
-if (!listener->log_sync) {
-continue;
-}
-as = listener->address_space;
-view = address_space_get_flatview(as);
-FOR_EACH_FLAT_RANGE(fr, view) {
-if (fr->dirty_log_mask && (!mr || fr->mr == mr)) {
-MemoryRegionSection mrs = section_from_flat_range(fr, view);
-listener->log_sync(listener, &mrs);
+if (listener->log_sync) {
+as = listener->address_space;
+view = address_space_get_flatview(as);
+FOR_EACH_FLAT_RANGE(fr, view) {
+if (fr->dirty_log_mask && (!mr || fr->mr == mr)) {
+MemoryRegionSection mrs = section_from_flat_range(fr, 
view);
+listener->log_sync(listener, &mrs);
+}
 }
+flatview_unref(view);
+} else if (listener->log_sync_global) {
+/*
+ * No matter whether MR is specified, what we can do here
+ * is to do a global sync, because we are not capable to
+ * sync in a finer granularity.
+ */
+listener->log_sync_global(listener);
 }
-flatview_unref(view);
 }
 }
 
@@ -2768,6 +2778,9 @@ void memory_listener_register(MemoryListener *listener, 
AddressSpace *as)
 {
 MemoryListener *other = NULL;
 
+/* Only one of them can be defined for a listener */
+assert(!(listener->log_sync && listener->log_sync_global));
+
 listener->address_space = as;
 if (QTAILQ_EMPTY(&memory_listeners)
 || listener->priority >= QTAILQ_LAST(&memory_listeners)->priority) {
-- 
2.26.2




[PATCH v5 04/10] KVM: Provide helper to get kvm dirty log

2021-03-10 Thread Peter Xu
Provide a helper kvm_slot_get_dirty_log() to make the function
kvm_physical_sync_dirty_bitmap() clearer.  We can even cache the as_id
into KVMSlot when it is created, so that we don't even need to pass it
down every time.

Since at it, remove return value of kvm_physical_sync_dirty_bitmap()
because it should never fail.

Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c  | 52 +++-
 include/sysemu/kvm_int.h |  2 ++
 2 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index fa337418636..853dfb076bd 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -617,6 +617,30 @@ static void kvm_slot_init_dirty_bitmap(KVMSlot *mem)
 mem->dirty_bmap = g_malloc0(bitmap_size);
 }
 
+/*
+ * Sync dirty bitmap from kernel to KVMSlot.dirty_bmap, return true if
+ * succeeded, false otherwise
+ */
+static bool kvm_slot_get_dirty_log(KVMState *s, KVMSlot *slot)
+{
+struct kvm_dirty_log d = {};
+int ret;
+
+d.dirty_bitmap = slot->dirty_bmap;
+d.slot = slot->slot | (slot->as_id << 16);
+ret = kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d);
+
+if (ret == -ENOENT) {
+/* kernel does not have dirty bitmap in this slot */
+ret = 0;
+}
+if (ret) {
+error_report_once("%s: KVM_GET_DIRTY_LOG failed with %d",
+  __func__, ret);
+}
+return ret == 0;
+}
+
 /**
  * kvm_physical_sync_dirty_bitmap - Sync dirty bitmap from kernel space
  *
@@ -628,15 +652,13 @@ static void kvm_slot_init_dirty_bitmap(KVMSlot *mem)
  * @kml: the KVM memory listener object
  * @section: the memory section to sync the dirty bitmap with
  */
-static int kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
-  MemoryRegionSection *section)
+static void kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
+   MemoryRegionSection *section)
 {
 KVMState *s = kvm_state;
-struct kvm_dirty_log d = {};
 KVMSlot *mem;
 hwaddr start_addr, size;
 hwaddr slot_size, slot_offset = 0;
-int ret = 0;
 
 size = kvm_align_section(section, &start_addr);
 while (size) {
@@ -646,19 +668,10 @@ static int 
kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
 mem = kvm_lookup_matching_slot(kml, start_addr, slot_size);
 if (!mem) {
 /* We don't have a slot if we want to trap every access. */
-goto out;
+return;
 }
 
-d.dirty_bitmap = mem->dirty_bmap;
-d.slot = mem->slot | (kml->as_id << 16);
-ret = kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d);
-if (ret == -ENOENT) {
-/* kernel does not have dirty bitmap in this slot */
-ret = 0;
-} else if (ret < 0) {
-error_report("ioctl KVM_GET_DIRTY_LOG failed: %d", errno);
-goto out;
-} else {
+if (kvm_slot_get_dirty_log(s, mem)) {
 subsection.offset_within_region += slot_offset;
 subsection.size = int128_make64(slot_size);
 kvm_get_dirty_pages_log_range(&subsection, d.dirty_bitmap);
@@ -668,8 +681,6 @@ static int kvm_physical_sync_dirty_bitmap(KVMMemoryListener 
*kml,
 start_addr += slot_size;
 size -= slot_size;
 }
-out:
-return ret;
 }
 
 /* Alignment requirement for KVM_CLEAR_DIRTY_LOG - 64 pages */
@@ -1188,6 +1199,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 do {
 slot_size = MIN(kvm_max_slot_size, size);
 mem = kvm_alloc_slot(kml);
+mem->as_id = kml->as_id;
 mem->memory_size = slot_size;
 mem->start_addr = start_addr;
 mem->ram = ram;
@@ -1230,14 +1242,10 @@ static void kvm_log_sync(MemoryListener *listener,
  MemoryRegionSection *section)
 {
 KVMMemoryListener *kml = container_of(listener, KVMMemoryListener, 
listener);
-int r;
 
 kvm_slots_lock();
-r = kvm_physical_sync_dirty_bitmap(kml, section);
+kvm_physical_sync_dirty_bitmap(kml, section);
 kvm_slots_unlock();
-if (r < 0) {
-abort();
-}
 }
 
 static void kvm_log_clear(MemoryListener *listener,
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index 1da30e18841..e13075f738a 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -23,6 +23,8 @@ typedef struct KVMSlot
 int old_flags;
 /* Dirty bitmap cache for the slot */
 unsigned long *dirty_bmap;
+/* Cache of the address space ID */
+int as_id;
 } KVMSlot;
 
 typedef struct KVMMemoryListener {
-- 
2.26.2




[PATCH v5 08/10] KVM: Add dirty-gfn-count property

2021-03-10 Thread Peter Xu
Add a parameter for dirty gfn count for dirty rings.  If zero, dirty ring is
disabled.  Otherwise dirty ring will be enabled with the per-vcpu gfn count as
specified.  If dirty ring cannot be enabled due to unsupported kernel or
illegal parameter, it'll fallback to dirty logging.

By default, dirty ring is not enabled (dirty-gfn-count default to 0).

Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c | 72 +
 qemu-options.hx | 12 
 2 files changed, 84 insertions(+)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index a1e7b1332a1..10137b6af11 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -128,6 +128,9 @@ struct KVMState
 KVMMemoryListener *ml;
 AddressSpace *as;
 } *as;
+bool kvm_dirty_ring_enabled;/* Whether KVM dirty ring is enabled */
+uint64_t kvm_dirty_ring_size;   /* Size of the per-vcpu dirty ring */
+uint32_t kvm_dirty_gfn_count;   /* Number of dirty GFNs per ring */
 };
 
 KVMState *kvm_state;
@@ -2136,6 +2139,40 @@ static int kvm_init(MachineState *ms)
 s->coalesced_pio = s->coalesced_mmio &&
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
 
+/*
+ * Enable KVM dirty ring if supported, otherwise fall back to
+ * dirty logging mode
+ */
+if (s->kvm_dirty_gfn_count > 0) {
+uint64_t ring_size;
+
+ring_size = s->kvm_dirty_gfn_count * sizeof(struct kvm_dirty_gfn);
+
+/* Read the max supported pages */
+ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING);
+if (ret > 0) {
+if (ring_size > ret) {
+error_report("KVM dirty GFN count %" PRIu32 " too big "
+ "(maximum is %ld).  Please use a smaller value.",
+ s->kvm_dirty_gfn_count,
+ ret / sizeof(struct kvm_dirty_gfn));
+ret = -EINVAL;
+goto err;
+}
+
+ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING, 0, ring_size);
+if (ret) {
+error_report("Enabling of KVM dirty ring failed: %d. "
+ "Suggested mininum value is 1024. "
+ "Please also make sure it's a power of two.", 
ret);
+goto err;
+}
+
+s->kvm_dirty_ring_size = ring_size;
+s->kvm_dirty_ring_enabled = true;
+}
+}
+
 dirty_log_manual_caps =
 kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
 dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
@@ -3179,6 +3216,33 @@ bool kvm_kernel_irqchip_split(void)
 return kvm_state->kernel_irqchip_split == ON_OFF_AUTO_ON;
 }
 
+static void kvm_get_dirty_gfn_count(Object *obj, Visitor *v,
+const char *name, void *opaque,
+Error **errp)
+{
+KVMState *s = KVM_STATE(obj);
+uint32_t value = s->kvm_dirty_gfn_count;
+
+visit_type_uint32(v, name, &value, errp);
+}
+
+static void kvm_set_dirty_gfn_count(Object *obj, Visitor *v,
+const char *name, void *opaque,
+Error **errp)
+{
+KVMState *s = KVM_STATE(obj);
+Error *error = NULL;
+uint32_t value;
+
+visit_type_uint32(v, name, &value, &error);
+if (error) {
+error_propagate(errp, error);
+return;
+}
+
+s->kvm_dirty_gfn_count = value;
+}
+
 static void kvm_accel_instance_init(Object *obj)
 {
 KVMState *s = KVM_STATE(obj);
@@ -3186,6 +3250,8 @@ static void kvm_accel_instance_init(Object *obj)
 s->kvm_shadow_mem = -1;
 s->kernel_irqchip_allowed = true;
 s->kernel_irqchip_split = ON_OFF_AUTO_AUTO;
+/* KVM dirty ring is by default off */
+s->kvm_dirty_gfn_count = 0;
 }
 
 static void kvm_accel_class_init(ObjectClass *oc, void *data)
@@ -3207,6 +3273,12 @@ static void kvm_accel_class_init(ObjectClass *oc, void 
*data)
 NULL, NULL);
 object_class_property_set_description(oc, "kvm-shadow-mem",
 "KVM shadow MMU size");
+
+object_class_property_add(oc, "dirty-gfn-count", "uint32",
+kvm_get_dirty_gfn_count, kvm_set_dirty_gfn_count,
+NULL, NULL);
+object_class_property_set_description(oc, "dirty-gfn-count",
+"KVM dirty GFN count (=0 to disable dirty ring)");
 }
 
 static const TypeInfo kvm_accel_type = {
diff --git a/qemu-options.hx b/qemu-options.hx
index 90801286c6e..08becce4ad0 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -141,6 +141,7 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
 "kvm-shadow-mem=size of KVM shadow MMU in bytes\n"
 "split-wx=on|off (enable TCG split w^x mapping)\n"
 "tb-size=n (TCG translation block cache size)\n"
+"dirty-gfn-count=n (KVM dirty ring GFN count, default 0)\n"
 "thread=single|mul

[PATCH v5 06/10] KVM: Simplify dirty log sync in kvm_set_phys_mem

2021-03-10 Thread Peter Xu
kvm_physical_sync_dirty_bitmap() on the whole section is inaccurate, because
the section can be a superset of the memslot that we're working on.  The result
is that if the section covers multiple kvm memslots, we could be doing the
synchronization for multiple times for each kvmslot in the section.

With the two helpers that we just introduced, it's very easy to do it right now
by calling the helpers.

Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 65dc00b0a61..20f852a990b 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1170,7 +1170,8 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 goto out;
 }
 if (mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
-kvm_physical_sync_dirty_bitmap(kml, section);
+kvm_slot_get_dirty_log(kvm_state, mem);
+kvm_slot_sync_dirty_pages(mem);
 }
 
 /* unregister the slot */
-- 
2.26.2




[PATCH v5 05/10] KVM: Provide helper to sync dirty bitmap from slot to ramblock

2021-03-10 Thread Peter Xu
kvm_physical_sync_dirty_bitmap() calculates the ramblock offset in an
awkward way from the MemoryRegionSection that passed in from the
caller.  The truth is for each KVMSlot the ramblock offset never
change for the lifecycle.  Cache the ramblock offset for each KVMSlot
into the structure when the KVMSlot is created.

With that, we can further simplify kvm_physical_sync_dirty_bitmap()
with a helper to sync KVMSlot dirty bitmap to the ramblock dirty
bitmap of a specific KVMSlot.

Reviewed-by: Dr. David Alan Gilbert 
Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c  | 37 +
 include/sysemu/kvm_int.h |  2 ++
 2 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 853dfb076bd..65dc00b0a61 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -575,15 +575,12 @@ static void kvm_log_stop(MemoryListener *listener,
 }
 
 /* get kvm's dirty pages bitmap and update qemu's */
-static int kvm_get_dirty_pages_log_range(MemoryRegionSection *section,
- unsigned long *bitmap)
+static void kvm_slot_sync_dirty_pages(KVMSlot *slot)
 {
-ram_addr_t start = section->offset_within_region +
-   memory_region_get_ram_addr(section->mr);
-ram_addr_t pages = int128_get64(section->size) / qemu_real_host_page_size;
+ram_addr_t start = slot->ram_start_offset;
+ram_addr_t pages = slot->memory_size / qemu_real_host_page_size;
 
-cpu_physical_memory_set_dirty_lebitmap(bitmap, start, pages);
-return 0;
+cpu_physical_memory_set_dirty_lebitmap(slot->dirty_bmap, start, pages);
 }
 
 #define ALIGN(x, y)  (((x)+(y)-1) & ~((y)-1))
@@ -658,26 +655,19 @@ static void 
kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
 KVMState *s = kvm_state;
 KVMSlot *mem;
 hwaddr start_addr, size;
-hwaddr slot_size, slot_offset = 0;
+hwaddr slot_size;
 
 size = kvm_align_section(section, &start_addr);
 while (size) {
-MemoryRegionSection subsection = *section;
-
 slot_size = MIN(kvm_max_slot_size, size);
 mem = kvm_lookup_matching_slot(kml, start_addr, slot_size);
 if (!mem) {
 /* We don't have a slot if we want to trap every access. */
 return;
 }
-
 if (kvm_slot_get_dirty_log(s, mem)) {
-subsection.offset_within_region += slot_offset;
-subsection.size = int128_make64(slot_size);
-kvm_get_dirty_pages_log_range(&subsection, d.dirty_bitmap);
+kvm_slot_sync_dirty_pages(mem);
 }
-
-slot_offset += slot_size;
 start_addr += slot_size;
 size -= slot_size;
 }
@@ -1143,7 +1133,8 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 int err;
 MemoryRegion *mr = section->mr;
 bool writeable = !mr->readonly && !mr->rom_device;
-hwaddr start_addr, size, slot_size;
+hwaddr start_addr, size, slot_size, mr_offset;
+ram_addr_t ram_start_offset;
 void *ram;
 
 if (!memory_region_is_ram(mr)) {
@@ -1161,9 +1152,13 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 return;
 }
 
-/* use aligned delta to align the ram address */
-ram = memory_region_get_ram_ptr(mr) + section->offset_within_region +
-  (start_addr - section->offset_within_address_space);
+/* The offset of the kvmslot within the memory region */
+mr_offset = section->offset_within_region + start_addr -
+section->offset_within_address_space;
+
+/* use aligned delta to align the ram address and offset */
+ram = memory_region_get_ram_ptr(mr) + mr_offset;
+ram_start_offset = memory_region_get_ram_addr(mr) + mr_offset;
 
 kvm_slots_lock();
 
@@ -1202,6 +1197,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 mem->as_id = kml->as_id;
 mem->memory_size = slot_size;
 mem->start_addr = start_addr;
+mem->ram_start_offset = ram_start_offset;
 mem->ram = ram;
 mem->flags = kvm_mem_flags(mr);
 kvm_slot_init_dirty_bitmap(mem);
@@ -1212,6 +1208,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
 abort();
 }
 start_addr += slot_size;
+ram_start_offset += slot_size;
 ram += slot_size;
 size -= slot_size;
 } while (size);
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index e13075f738a..ab09a150e19 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -25,6 +25,8 @@ typedef struct KVMSlot
 unsigned long *dirty_bmap;
 /* Cache of the address space ID */
 int as_id;
+/* Cache of the offset in ram address space */
+ram_addr_t ram_start_offset;
 } KVMSlot;
 
 typedef struct KVMMemoryListener {
-- 
2.26.2




[PATCH v5 00/10] KVM: Dirty ring support (QEMU part)

2021-03-10 Thread Peter Xu
This is v5 of the qemu dirty ring interface support.

v5:
- rebase
- dropped patch "update-linux-headers: Include const.h" after rebase
- dropped patch "KVM: Fixup kvm_log_clear_one_slot() ioctl return check" since
  similar patch got merged recently (38e0b7904eca7cd32f8953c3)

= v4 cover letter below =

It is merely the same as v3 content-wise, but there're a few things to mention
besides the rebase itself:

  - I picked up two patches from Eric Farman for the linux-header updates (from
Eric's v3 series) for convenience just in case any of the series would got
queued by any maintainer.

  - One more patch is added as "KVM: Disable manual dirty log when dirty ring
enabled".  I found this when testing the branch after rebasing to latest
qemu, that not only the manual dirty log capability is not needed for kvm
dirty ring, but more importantly INITIALLY_ALL_SET is totally against kvm
dirty ring and it could silently crash the guest after migration.  For this
new commit, I touched up "KVM: Add dirty-gfn-count property" a bit.

  - A few more documentation lines in qemu-options.hx.

  - I removed the RFC tag after kernel series got merged.

Again, this is only the 1st step to support dirty ring.  Ideally dirty ring
should grant QEMU the possibility to remove the whole layered dirty bitmap so
that dirty ring will work similarly as auto-converge enabled but should better;
we will just throttle vcpus with the dirty ring kvm exit rather than explicitly
adding a timer to stop the vcpu thread from entering the guest again (like what
we did with current migration auto-converge).  Some more information could also
be found in the kvm forum 2020 talk regarding kvm dirty ring (slides 21/22 [1]).

That next step (to remove all the dirty bitmaps, as mentioned above) is still
discussable: firstly I don't know whether there's anything I've overlooked in
there.  Meanwhile that's also only services huge VM cases, may not be extremely
helpful with a lot major scenarios where VMs are not that huge.

There's probably other ways to fix huge VM migration issues, majorly focusing
on responsiveness and convergence.  For example, Google has proposed some new
userfaultfd kernel capability called "minor modes" [2] to track page minor
faults and that could be finally served for that purpose too using postcopy.
That's another long story so I'll stop here, but just as a marker along with
the dirty ring series so there'll still be a record to reference.

Said that, I still think this series is very worth merging even if we don't
persue the next steps yet, since dirty ring is disabled by default, and we can
always work upon this series.

Please review, thanks.

V3: 
https://lore.kernel.org/qemu-devel/20200523232035.1029349-1-pet...@redhat.com/
(V3 contains all the pre-v3 changelog)

QEMU branch for testing (requires kernel version 5.11-rc1+):
https://github.com/xzpeter/qemu/tree/kvm-dirty-ring

[1] 
https://static.sched.com/hosted_files/kvmforum2020/97/kvm_dirty_ring_peter.pdf
[2] 
https://lore.kernel.org/lkml/20210107190453.3051110-1-axelrasmus...@google.com/

---8<-

Overview


KVM dirty ring is a new interface to pass over dirty bits from kernel
to the userspace.  Instead of using a bitmap for each memory region,
the dirty ring contains an array of dirtied GPAs to fetch, one ring
per vcpu.

There're a few major changes comparing to how the old dirty logging
interface would work:

- Granularity of dirty bits

  KVM dirty ring interface does not offer memory region level
  granularity to collect dirty bits (i.e., per KVM memory
  slot). Instead the dirty bit is collected globally for all the vcpus
  at once.  The major effect is on VGA part because VGA dirty tracking
  is enabled as long as the device is created, also it was in memory
  region granularity.  Now that operation will be amplified to a VM
  sync.  Maybe there's smarter way to do the same thing in VGA with
  the new interface, but so far I don't see it affects much at least
  on regular VMs.

- Collection of dirty bits

  The old dirty logging interface collects KVM dirty bits when
  synchronizing dirty bits.  KVM dirty ring interface instead used a
  standalone thread to do that.  So when the other thread (e.g., the
  migration thread) wants to synchronize the dirty bits, it simply
  kick the thread and wait until it flushes all the dirty bits to the
  ramblock dirty bitmap.

A new parameter "dirty-ring-size" is added to "-accel kvm".  By
default, dirty ring is still disabled (size==0).  To enable it, we
need to be with:

  -accel kvm,dirty-ring-size=65536

This establishes a 64K dirty ring buffer per vcpu.  Then if we
migrate, it'll switch to dirty ring.

I gave it a shot with a 24G guest, 8 vcpus, using 10g NIC as migration
channel.  When idle or dirty workload small, I don't observe major
difference on total migration time.  When with higher random dirty
wor

[PATCH v5 10/10] KVM: Dirty ring support

2021-03-10 Thread Peter Xu
KVM dirty ring is a new interface to pass over dirty bits from kernel to the
userspace.  Instead of using a bitmap for each memory region, the dirty ring
contains an array of dirtied GPAs to fetch (in the form of offset in slots).
For each vcpu there will be one dirty ring that binds to it.

kvm_dirty_ring_reap() is the major function to collect dirty rings.  It can be
called either by a standalone reaper thread that runs in the background,
collecting dirty pages for the whole VM.  It can also be called directly by any
thread that has BQL taken.

Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c| 332 -
 accel/kvm/trace-events |   7 +
 include/hw/core/cpu.h  |   8 +
 3 files changed, 344 insertions(+), 3 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index ae9393266b2..bf2b21f038b 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -15,6 +15,7 @@
 
 #include "qemu/osdep.h"
 #include 
+#include 
 
 #include 
 
@@ -80,6 +81,25 @@ struct KVMParkedVcpu {
 QLIST_ENTRY(KVMParkedVcpu) node;
 };
 
+enum KVMDirtyRingReaperState {
+KVM_DIRTY_RING_REAPER_NONE = 0,
+/* The reaper is sleeping */
+KVM_DIRTY_RING_REAPER_WAIT,
+/* The reaper is reaping for dirty pages */
+KVM_DIRTY_RING_REAPER_REAPING,
+};
+
+/*
+ * KVM reaper instance, responsible for collecting the KVM dirty bits
+ * via the dirty ring.
+ */
+struct KVMDirtyRingReaper {
+/* The reaper thread */
+QemuThread reaper_thr;
+volatile uint64_t reaper_iteration; /* iteration number of reaper thr */
+volatile enum KVMDirtyRingReaperState reaper_state; /* reap thr state */
+};
+
 struct KVMState
 {
 AccelState parent_obj;
@@ -131,6 +151,7 @@ struct KVMState
 bool kvm_dirty_ring_enabled;/* Whether KVM dirty ring is enabled */
 uint64_t kvm_dirty_ring_size;   /* Size of the per-vcpu dirty ring */
 uint32_t kvm_dirty_gfn_count;   /* Number of dirty GFNs per ring */
+struct KVMDirtyRingReaper reaper;
 };
 
 KVMState *kvm_state;
@@ -392,6 +413,13 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
 goto err;
 }
 
+if (cpu->kvm_dirty_gfns) {
+ret = munmap(cpu->kvm_dirty_gfns, s->kvm_dirty_ring_size);
+if (ret < 0) {
+goto err;
+}
+}
+
 vcpu = g_malloc0(sizeof(*vcpu));
 vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
 vcpu->kvm_fd = cpu->kvm_fd;
@@ -468,6 +496,19 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
 (void *)cpu->kvm_run + s->coalesced_mmio * PAGE_SIZE;
 }
 
+if (s->kvm_dirty_ring_enabled) {
+/* Use MAP_SHARED to share pages with the kernel */
+cpu->kvm_dirty_gfns = mmap(NULL, s->kvm_dirty_ring_size,
+   PROT_READ | PROT_WRITE, MAP_SHARED,
+   cpu->kvm_fd,
+   PAGE_SIZE * KVM_DIRTY_LOG_PAGE_OFFSET);
+if (cpu->kvm_dirty_gfns == MAP_FAILED) {
+ret = -errno;
+DPRINTF("mmap'ing vcpu dirty gfns failed: %d\n", ret);
+goto err;
+}
+}
+
 ret = kvm_arch_init_vcpu(cpu);
 if (ret < 0) {
 error_setg_errno(errp, -ret,
@@ -586,6 +627,11 @@ static void kvm_slot_sync_dirty_pages(KVMSlot *slot)
 cpu_physical_memory_set_dirty_lebitmap(slot->dirty_bmap, start, pages);
 }
 
+static void kvm_slot_reset_dirty_pages(KVMSlot *slot)
+{
+memset(slot->dirty_bmap, 0, slot->dirty_bmap_size);
+}
+
 #define ALIGN(x, y)  (((x)+(y)-1) & ~((y)-1))
 
 /* Allocate the dirty bitmap for a slot  */
@@ -642,6 +688,170 @@ static bool kvm_slot_get_dirty_log(KVMState *s, KVMSlot 
*slot)
 return ret == 0;
 }
 
+/* Should be with all slots_lock held for the address spaces. */
+static void kvm_dirty_ring_mark_page(KVMState *s, uint32_t as_id,
+ uint32_t slot_id, uint64_t offset)
+{
+KVMMemoryListener *kml;
+KVMSlot *mem;
+
+if (as_id >= s->nr_as) {
+return;
+}
+
+kml = s->as[as_id].ml;
+mem = &kml->slots[slot_id];
+
+if (!mem->memory_size || offset >= (mem->memory_size / TARGET_PAGE_SIZE)) {
+return;
+}
+
+set_bit(offset, mem->dirty_bmap);
+}
+
+static bool dirty_gfn_is_dirtied(struct kvm_dirty_gfn *gfn)
+{
+return gfn->flags == KVM_DIRTY_GFN_F_DIRTY;
+}
+
+static void dirty_gfn_set_collected(struct kvm_dirty_gfn *gfn)
+{
+gfn->flags = KVM_DIRTY_GFN_F_RESET;
+}
+
+/*
+ * Should be with all slots_lock held for the address spaces.  It returns the
+ * dirty page we've collected on this dirty ring.
+ */
+static uint32_t kvm_dirty_ring_reap_one(KVMState *s, CPUState *cpu)
+{
+struct kvm_dirty_gfn *dirty_gfns = cpu->kvm_dirty_gfns, *cur;
+uint32_t gfn_count = s->kvm_dirty_gfn_count;
+uint32_t count = 0, fetch = cpu->kvm_fetch_index;
+
+assert(dirty_gfns && gfn_count);
+trace_kvm_dirty_ring_reap_vcpu(cpu->cpu_index);
+
+while (true) {
+cur = &dirty_gfns[fetch % gfn_count];
+  

[PATCH v5 07/10] KVM: Cache kvm slot dirty bitmap size

2021-03-10 Thread Peter Xu
Cache it too because we'll reference it more frequently in the future.

Reviewed-by: Dr. David Alan Gilbert 
Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c  | 1 +
 include/sysemu/kvm_int.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 20f852a990b..a1e7b1332a1 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -612,6 +612,7 @@ static void kvm_slot_init_dirty_bitmap(KVMSlot *mem)
 hwaddr bitmap_size = ALIGN(mem->memory_size / qemu_real_host_page_size,
 /*HOST_LONG_BITS*/ 64) / 8;
 mem->dirty_bmap = g_malloc0(bitmap_size);
+mem->dirty_bmap_size = bitmap_size;
 }
 
 /*
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index ab09a150e19..c788452cd96 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -23,6 +23,7 @@ typedef struct KVMSlot
 int old_flags;
 /* Dirty bitmap cache for the slot */
 unsigned long *dirty_bmap;
+unsigned long dirty_bmap_size;
 /* Cache of the address space ID */
 int as_id;
 /* Cache of the offset in ram address space */
-- 
2.26.2




[PATCH v5 09/10] KVM: Disable manual dirty log when dirty ring enabled

2021-03-10 Thread Peter Xu
KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is for KVM_CLEAR_DIRTY_LOG, which is only
useful for KVM_GET_DIRTY_LOG.  Skip enabling it for kvm dirty ring.

More importantly, KVM_DIRTY_LOG_INITIALLY_SET will not wr-protect all the pages
initially, which is against how kvm dirty ring is used - there's no way for kvm
dirty ring to re-protect a page before it's notified as being written first
with a GFN entry in the ring!  So when KVM_DIRTY_LOG_INITIALLY_SET is enabled
with dirty ring, we'll see silent data loss after migration.

Signed-off-by: Peter Xu 
---
 accel/kvm/kvm-all.c | 37 +++--
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 10137b6af11..ae9393266b2 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2173,20 +2173,29 @@ static int kvm_init(MachineState *ms)
 }
 }
 
-dirty_log_manual_caps =
-kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
-dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
-  KVM_DIRTY_LOG_INITIALLY_SET);
-s->manual_dirty_log_protect = dirty_log_manual_caps;
-if (dirty_log_manual_caps) {
-ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
-   dirty_log_manual_caps);
-if (ret) {
-warn_report("Trying to enable capability %"PRIu64" of "
-"KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
-"Falling back to the legacy mode. ",
-dirty_log_manual_caps);
-s->manual_dirty_log_protect = 0;
+/*
+ * KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is not needed when dirty ring is
+ * enabled.  More importantly, KVM_DIRTY_LOG_INITIALLY_SET will assume no
+ * page is wr-protected initially, which is against how kvm dirty ring is
+ * usage - kvm dirty ring requires all pages are wr-protected at the very
+ * beginning.  Enabling this feature for dirty ring causes data corruption.
+ */
+if (!s->kvm_dirty_ring_enabled) {
+dirty_log_manual_caps =
+kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
+dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
+  KVM_DIRTY_LOG_INITIALLY_SET);
+s->manual_dirty_log_protect = dirty_log_manual_caps;
+if (dirty_log_manual_caps) {
+ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
+dirty_log_manual_caps);
+if (ret) {
+warn_report("Trying to enable capability %"PRIu64" of "
+"KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
+"Falling back to the legacy mode. ",
+dirty_log_manual_caps);
+s->manual_dirty_log_protect = 0;
+}
 }
 }
 
-- 
2.26.2




Re: [PATCH v4] target/s390x: Implement the MVPG condition-code-option bit

2021-03-10 Thread David Hildenbrand


> Am 09.03.2021 um 22:05 schrieb Thomas Huth :
> 
> On 04/03/2021 09.10, David Hildenbrand wrote:
>>> On 03.03.21 22:36, Richard Henderson wrote:
>>> On 3/3/21 1:22 PM, David Hildenbrand wrote:
 
> Am 03.03.2021 um 22:19 schrieb Richard Henderson 
> :
> 
> On 3/3/21 1:11 PM, David Hildenbrand wrote:
>> MMIO on s390x? :)
> 
> hw/s390x/s390-pci-bus.c, memory_region_init_io*().
> 
 
 ... part of system address space where a CPU could stumble over it?
>>> 
>>> Impossible to tell within 3 layers of object wrappers.  :-(
>>> I suppose I have no idea how "pci" was hacked onto s390x.
>> You've used the right words to describe "pci" (!) on s390x.
>> IIRC, there is no MMIO: configuration space accesses etc. are performed 
>> using special access instructions - which will "emulate" the MMIO access 
>> performed on other archs via simple read/write instructions.
>> Ordinary instructions (e.g., mvpg) that operate on the system address space 
>> should never stumble over MMIO regions - because that concept does not exist 
>> on s390x.
> 
> Sorry, guys, you've lost me here ... is there now something left to do for 
> this patch or is it good as it is?

I think that check for invalid TLB should be replaced by a check against host 
== NULL.




[PULL 00/22] Trivial branch for 6.0 patches

2021-03-10 Thread Laurent Vivier
The following changes since commit b2ae1009d7cca2701e17eae55ae2d44fd22c942a:

  Merge remote-tracking branch 'remotes/mcayland/tags/qemu-sparc-20210307' in=
to staging (2021-03-09 13:50:35 +)

are available in the Git repository at:

  git://github.com/vivier/qemu.git tags/trivial-branch-for-6.0-pull-request

for you to fetch changes up to 538f049704e9b7a07eeaf326af772fdd30d89576:

  sysemu: Let VMChangeStateHandler take boolean 'running' argument (2021-03-0=
9 23:13:57 +0100)


Pull request trivial patches 20210310



Alexander Bulekov (1):
  fuzz-test: remove unneccessary debugging flags

Eric Blake (1):
  scsi: Silence gcc warning

Markus Armbruster (2):
  backends/dbus-vmstate: Fix short read error handling
  vhost_user_gpu: Drop dead check for g_malloc() failure

Michael Tokarev (1):
  Various spelling fixes

Peter Maydell (1):
  qemu-common.h: Update copyright string to 2021

Philippe Mathieu-Daud=C3=A9 (13):
  hw/elf_ops: Fix a typo
  target/hexagon/gen_tcg_funcs: Fix a typo
  exec/memory: Use struct Object typedef
  ui: Replace the word 'whitelist'
  scripts/tracetool: Replace the word 'whitelist'
  seccomp: Replace the word 'blacklist'
  qemu-options: Replace the word 'blacklist'
  tests/fp/fp-test: Replace the word 'blacklist'
  hw/lm32/Kconfig: Introduce CONFIG_LM32_EVR for lm32-evr/uclinux boards
  hw/lm32/Kconfig: Rename CONFIG_LM32 -> CONFIG_LM32_DEVICES
  hw/lm32/Kconfig: Have MILKYMIST select LM32_DEVICES
  sysemu/runstate: Let runstate_is_running() return bool
  sysemu: Let VMChangeStateHandler take boolean 'running' argument

Thomas Huth (1):
  net: Use id_generate() in the network subsystem, too

Wainer dos Santos Moschetta (1):
  MAINTAINERS: Fix the location of tools manuals

lijiejun (1):
  virtio-gpu: Adjust code space style

 MAINTAINERS  | 10 
 accel/xen/xen-all.c  |  2 +-
 audio/audio.c|  2 +-
 backends/dbus-vmstate.c  |  5 +++-
 block/block-backend.c|  2 +-
 default-configs/devices/lm32-softmmu.mak |  2 +-
 disas/nanomips.cpp   |  2 +-
 gdbstub.c|  2 +-
 hw/block/pflash_cfi01.c  |  2 +-
 hw/block/virtio-blk.c|  2 +-
 hw/char/meson.build  |  4 +--
 hw/display/qxl.c |  2 +-
 hw/display/vhost-user-gpu.c  |  1 -
 hw/display/virtio-gpu-3d.c   |  3 +--
 hw/i386/kvm/clock.c  |  2 +-
 hw/i386/kvm/i8254.c  |  2 +-
 hw/i386/kvmvapic.c   |  2 +-
 hw/i386/xen/xen-hvm.c|  2 +-
 hw/ide/core.c|  2 +-
 hw/intc/arm_gicv3_its_kvm.c  |  2 +-
 hw/intc/arm_gicv3_kvm.c  |  2 +-
 hw/intc/meson.build  |  2 +-
 hw/intc/spapr_xive_kvm.c |  2 +-
 hw/lm32/Kconfig  | 10 +---
 hw/lm32/meson.build  |  2 +-
 hw/misc/mac_via.c|  2 +-
 hw/misc/trace-events |  2 +-
 hw/net/allwinner-sun8i-emac.c|  2 +-
 hw/net/e1000e_core.c |  2 +-
 hw/nvram/spapr_nvram.c   |  2 +-
 hw/ppc/pnv_bmc.c |  2 +-
 hw/ppc/pnv_xscom.c   |  2 +-
 hw/ppc/ppc.c |  2 +-
 hw/ppc/ppc_booke.c   |  2 +-
 hw/s390x/tod-kvm.c   |  2 +-
 hw/scsi/scsi-bus.c   |  2 +-
 hw/scsi/scsi-disk.c  |  1 +
 hw/timer/meson.build |  2 +-
 hw/usb/ccid-card-emulated.c  |  2 +-
 hw/usb/hcd-ehci.c|  2 +-
 hw/usb/hcd-ohci.c|  2 +-
 hw/usb/host-libusb.c |  2 +-
 hw/usb/redirect.c|  2 +-
 hw/vfio/migration.c  |  2 +-
 hw/virtio/vhost.c|  2 +-
 hw/virtio/virtio-rng.c   |  2 +-
 hw/virtio/virtio.c   |  2 +-
 include/exec/memory.h| 32 
 include/hw/elf_ops.h |  2 +-
 include/hw/ppc/pnv_xscom.h   |  2 +-
 include/hw/s390x/css.h   |  2 +-
 include/qemu-common.h|  2 +-
 include/qemu/id.h|  1 +
 include/sysemu/runstate.h| 12 ++---
 net/net.c|  8 +++---
 qemu-options.hx  | 10 
 scripts/tracetool/__init__.py|  2 +-
 softmmu/memory.c | 14 +--
 softmmu/qemu-seccomp.c

[PULL 02/22] scsi: Silence gcc warning

2021-03-10 Thread Laurent Vivier
From: Eric Blake 

On Fedora 33, gcc 10.2.1 notes that scsi_cdb_length(buf) can set
len==-1, which in turn overflows g_malloc():

[5/5] Linking target qemu-system-x86_64
In function ‘scsi_disk_new_request_dump’,
inlined from ‘scsi_new_request’ at ../hw/scsi/scsi-disk.c:2608:9:
../hw/scsi/scsi-disk.c:2582:19: warning: argument 1 value 
‘18446744073709551612’ exceeds maximum object size 9223372036854775807 
[-Walloc-size-larger-than=]
 2582 | line_buffer = g_malloc(len * 5 + 1);
  |   ^

Silence it with a decent assertion, since we only convert a buffer to
bytes when we have a valid cdb length.

Signed-off-by: Eric Blake 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20210209152350.207958-1-ebl...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 hw/scsi/scsi-disk.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index bd7103cd0e8a..2eaea7e637d8 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2565,6 +2565,7 @@ static void scsi_disk_new_request_dump(uint32_t lun, 
uint32_t tag, uint8_t *buf)
 int len = scsi_cdb_length(buf);
 char *line_buffer, *p;
 
+assert(len > 0 && len <= 16);
 line_buffer = g_malloc(len * 5 + 1);
 
 for (i = 0, p = line_buffer; i < len; i++) {
-- 
2.29.2




[PULL 06/22] vhost_user_gpu: Drop dead check for g_malloc() failure

2021-03-10 Thread Laurent Vivier
From: Markus Armbruster 

Signed-off-by: Markus Armbruster 
Reviewed-by: Marc-André Lureau 
Reviewed-by: Michael S. Tsirkin 
Message-Id: <20210126124240.2081959-3-arm...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 hw/display/vhost-user-gpu.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index a01f9315e199..6cdaa1c73b9b 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -325,7 +325,6 @@ vhost_user_gpu_chr_read(void *opaque)
 }
 
 msg = g_malloc(VHOST_USER_GPU_HDR_SIZE + size);
-g_return_if_fail(msg != NULL);
 
 r = qemu_chr_fe_read_all(&g->vhost_chr,
  (uint8_t *)&msg->payload, size);
-- 
2.29.2




[PULL 05/22] backends/dbus-vmstate: Fix short read error handling

2021-03-10 Thread Laurent Vivier
From: Markus Armbruster 

When dbus_vmstate_post_load() fails, it complains to stderr.  Except
on short read, where it checks with g_return_val_if_fail().  This
fails silently if G_DISABLE_CHECKS is undefined (it should be), or
else pads the short read with uninitialized bytes.

Replace g_return_val_if_fail() by a proper error check.

Fixes: 5010cec2bc87dafab39b3913c8ca91f88df9c540
Signed-off-by: Markus Armbruster 
Reviewed-by: Marc-André Lureau 
Message-Id: <20210126124240.2081959-2-arm...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 backends/dbus-vmstate.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/backends/dbus-vmstate.c b/backends/dbus-vmstate.c
index bd050e8e9cab..2a0d2e4a31c0 100644
--- a/backends/dbus-vmstate.c
+++ b/backends/dbus-vmstate.c
@@ -229,7 +229,10 @@ static int dbus_vmstate_post_load(void *opaque, int 
version_id)
  &bytes_read, NULL, &err)) {
 goto error;
 }
-g_return_val_if_fail(bytes_read == len, -1);
+if (bytes_read != len) {
+error_report("%s: Short read", __func__);
+return -1;
+}
 id[len] = 0;
 
 trace_dbus_vmstate_loading(id);
-- 
2.29.2




[PULL 01/22] Various spelling fixes

2021-03-10 Thread Laurent Vivier
From: Michael Tokarev 

An assorted set of spelling fixes in various places.

Signed-off-by: Michael Tokarev 
Reviewed-by: Stefan Weil 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Message-Id: <20210309111510.79495-1-...@msgid.tls.msk.ru>
Signed-off-by: Laurent Vivier 
---
 disas/nanomips.cpp| 2 +-
 hw/misc/trace-events  | 2 +-
 hw/net/allwinner-sun8i-emac.c | 2 +-
 hw/ppc/pnv_bmc.c  | 2 +-
 hw/usb/ccid-card-emulated.c   | 2 +-
 hw/usb/hcd-ohci.c | 2 +-
 hw/virtio/vhost.c | 2 +-
 include/hw/s390x/css.h| 2 +-
 qemu-options.hx   | 4 ++--
 target/i386/cpu.c | 2 +-
 target/i386/machine.c | 2 +-
 target/m68k/op_helper.c   | 2 +-
 target/riscv/cpu.c| 2 +-
 13 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 90e63b836746..2b0965527194 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -837,7 +837,7 @@ int NMD::Disassemble(const uint16 * data, std::string & dis,
  * an ASE attribute and the requested version
  * not having that attribute
  */
-dis = "ASE attribute missmatch";
+dis = "ASE attribute mismatch";
 return -5;
 }
 disassembly_function dis_fn = table[i].disassembly;
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index d626b9d7a7c6..ef0a4de39d50 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -127,7 +127,7 @@ npcm7xx_pwm_update_freq(const char *id, uint8_t index, 
uint32_t old_value, uint3
 npcm7xx_pwm_update_duty(const char *id, uint8_t index, uint32_t old_value, 
uint32_t new_value) "%s pwm[%u] Update Duty: old_duty: %u, new_duty: %u"
 
 # stm32f4xx_syscfg.c
-stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interupt: GPIO: %d, 
Line: %d; Level: %d"
+stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interrupt: GPIO: %d, 
Line: %d; Level: %d"
 stm32f4xx_pulse_exti(int irq) "Pulse EXTI: %d"
 stm32f4xx_syscfg_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
 stm32f4xx_syscfg_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" 
PRIx64 " val: 0x%" PRIx64 ""
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
index 042768922c97..bf91803d65a8 100644
--- a/hw/net/allwinner-sun8i-emac.c
+++ b/hw/net/allwinner-sun8i-emac.c
@@ -579,7 +579,7 @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, 
hwaddr offset,
 case REG_INT_STA:   /* Interrupt Status */
 value = s->int_sta;
 break;
-case REG_INT_EN:/* Interupt Enable */
+case REG_INT_EN:/* Interrupt Enable */
 value = s->int_en;
 break;
 case REG_TX_CTL_0:  /* Transmit Control 0 */
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index b9bf5735ea0f..75a22ce50b11 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -233,7 +233,7 @@ static void hiomap_cmd(IPMIBmcSim *ibs, uint8_t *cmd, 
unsigned int cmd_len,
 case HIOMAP_C_RESET:
 case HIOMAP_C_LOCK:
 default:
-qemu_log_mask(LOG_GUEST_ERROR, "HIOMAP: unknow command %02X\n", 
cmd[2]);
+qemu_log_mask(LOG_GUEST_ERROR, "HIOMAP: unknown command %02X\n", 
cmd[2]);
 break;
 }
 }
diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index 2d566f7db104..5c76bed77aa0 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -301,7 +301,7 @@ static void *event_thread(void *arg)
 } else {
 if (event->reader != card->reader) {
 fprintf(stderr,
-"ERROR: wrong reader: quiting event_thread\n");
+"ERROR: wrong reader: quitting event_thread\n");
 break;
 }
 }
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index f8c64c8b95bb..1cf2816772c5 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1126,7 +1126,7 @@ static int ohci_service_td(OHCIState *ohci, struct 
ohci_ed *ed)
 OHCI_SET_BM(td.flags, TD_EC, 3);
 break;
 }
-/* An error occured so we have to clear the interrupt counter. See
+/* An error occurred so we have to clear the interrupt counter. See
  * spec at 6.4.4 on page 104 */
 ohci->done_count = 0;
 }
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 2a01662b0882..e2163a0d63ed 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -909,7 +909,7 @@ check_dev_state:
 r = 0;
 }
 if (r) {
-/* An error is occured. */
+/* An error occurred. */
 dev->log_enabled = false;
 }
 
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index 08c869ab0a

[PULL 03/22] hw/elf_ops: Fix a typo

2021-03-10 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

g_mapped_file_new_from_fd()'s parameter is named 'writable'.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Stefano Garzarella 
Reviewed-by: David Edmondson 
Message-Id: <20210225181344.3623720-1-phi...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 include/hw/elf_ops.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index 78409ab34a9f..6ee458e7bc3c 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -417,7 +417,7 @@ static int glue(load_elf, SZ)(const char *name, int fd,
 
 /*
  * Since we want to be able to modify the mapped buffer, we set the
- * 'writeble' parameter to 'true'. Modifications to the buffer are not
+ * 'writable' parameter to 'true'. Modifications to the buffer are not
  * written back to the file.
  */
 mapped_file = g_mapped_file_new_from_fd(fd, true, NULL);
-- 
2.29.2




[PULL 08/22] net: Use id_generate() in the network subsystem, too

2021-03-10 Thread Laurent Vivier
From: Thomas Huth 

We already got a global function called id_generate() to create unique
IDs within QEMU. Let's use it in the network subsytem, too, instead of
inventing our own ID scheme here.

Signed-off-by: Thomas Huth 
Reviewed-by: Marc-André Lureau 
Message-Id: <20210215090225.1046239-1-th...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 include/qemu/id.h | 1 +
 net/net.c | 6 +++---
 util/id.c | 1 +
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/qemu/id.h b/include/qemu/id.h
index b55c406e69db..46b759b284f3 100644
--- a/include/qemu/id.h
+++ b/include/qemu/id.h
@@ -5,6 +5,7 @@ typedef enum IdSubSystems {
 ID_QDEV,
 ID_BLOCK,
 ID_CHR,
+ID_NET,
 ID_MAX  /* last element, used as array size */
 } IdSubSystems;
 
diff --git a/net/net.c b/net/net.c
index fb7b7dcc2528..ca30df963d77 100644
--- a/net/net.c
+++ b/net/net.c
@@ -43,6 +43,7 @@
 #include "qemu/cutils.h"
 #include "qemu/config-file.h"
 #include "qemu/ctype.h"
+#include "qemu/id.h"
 #include "qemu/iov.h"
 #include "qemu/qemu-print.h"
 #include "qemu/main-loop.h"
@@ -,8 +1112,7 @@ static int net_client_init(QemuOpts *opts, bool 
is_netdev, Error **errp)
 
 /* Create an ID for -net if the user did not specify one */
 if (!is_netdev && !qemu_opts_id(opts)) {
-static int idx;
-qemu_opts_set_id(opts, g_strdup_printf("__org.qemu.net%i", idx++));
+qemu_opts_set_id(opts, id_generate(ID_NET));
 }
 
 if (visit_type_Netdev(v, NULL, &object, errp)) {
@@ -1467,7 +1467,7 @@ static int net_param_nic(void *dummy, QemuOpts *opts, 
Error **errp)
 /* Create an ID if the user did not specify one */
 nd_id = g_strdup(qemu_opts_id(opts));
 if (!nd_id) {
-nd_id = g_strdup_printf("__org.qemu.nic%i", idx);
+nd_id = id_generate(ID_NET);
 qemu_opts_set_id(opts, nd_id);
 }
 
diff --git a/util/id.c b/util/id.c
index 5addb4460ea0..ded41c5025e4 100644
--- a/util/id.c
+++ b/util/id.c
@@ -35,6 +35,7 @@ static const char *const id_subsys_str[ID_MAX] = {
 [ID_QDEV]  = "qdev",
 [ID_BLOCK] = "block",
 [ID_CHR] = "chr",
+[ID_NET] = "net",
 };
 
 /*
-- 
2.29.2




[PULL 10/22] exec/memory: Use struct Object typedef

2021-03-10 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

We forward-declare Object typedef in "qemu/typedefs.h" since commit
ca27b5eb7cd ("qom/object: Move Object typedef to 'qemu/typedefs.h'").
Use it everywhere to make the code simpler.

Signed-off-by: Philippe Mathieu-Daudé 
Acked-by: David Gibson 
Reviewed-by: Laurent Vivier 
Message-Id: <20210225182003.3629342-1-phi...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 hw/ppc/pnv_xscom.c |  2 +-
 include/exec/memory.h  | 32 
 include/hw/ppc/pnv_xscom.h |  2 +-
 softmmu/memory.c   | 12 ++--
 4 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index e9ae1569ffcf..be7018e8ac59 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -308,7 +308,7 @@ void pnv_xscom_add_subregion(PnvChip *chip, hwaddr offset, 
MemoryRegion *mr)
 }
 
 void pnv_xscom_region_init(MemoryRegion *mr,
-   struct Object *owner,
+   Object *owner,
const MemoryRegionOps *ops,
void *opaque,
const char *name,
diff --git a/include/exec/memory.h b/include/exec/memory.h
index c6fb714e499c..54ccf1a5f09b 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -828,7 +828,7 @@ static inline bool 
MemoryRegionSection_eq(MemoryRegionSection *a,
  * @size: size of the region; any subregions beyond this size will be clipped
  */
 void memory_region_init(MemoryRegion *mr,
-struct Object *owner,
+Object *owner,
 const char *name,
 uint64_t size);
 
@@ -876,7 +876,7 @@ void memory_region_unref(MemoryRegion *mr);
  * @size: size of the region.
  */
 void memory_region_init_io(MemoryRegion *mr,
-   struct Object *owner,
+   Object *owner,
const MemoryRegionOps *ops,
void *opaque,
const char *name,
@@ -898,7 +898,7 @@ void memory_region_init_io(MemoryRegion *mr,
  * RAM memory region to be migrated; that is the responsibility of the caller.
  */
 void memory_region_init_ram_nomigrate(MemoryRegion *mr,
-  struct Object *owner,
+  Object *owner,
   const char *name,
   uint64_t size,
   Error **errp);
@@ -920,7 +920,7 @@ void memory_region_init_ram_nomigrate(MemoryRegion *mr,
  * The only difference is part of the RAM region can be remapped.
  */
 void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
- struct Object *owner,
+ Object *owner,
  const char *name,
  uint64_t size,
  bool share,
@@ -946,7 +946,7 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion 
*mr,
  * RAM memory region to be migrated; that is the responsibility of the caller.
  */
 void memory_region_init_resizeable_ram(MemoryRegion *mr,
-   struct Object *owner,
+   Object *owner,
const char *name,
uint64_t size,
uint64_t max_size,
@@ -979,7 +979,7 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
  * RAM memory region to be migrated; that is the responsibility of the caller.
  */
 void memory_region_init_ram_from_file(MemoryRegion *mr,
-  struct Object *owner,
+  Object *owner,
   const char *name,
   uint64_t size,
   uint64_t align,
@@ -1005,7 +1005,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
  * RAM memory region to be migrated; that is the responsibility of the caller.
  */
 void memory_region_init_ram_from_fd(MemoryRegion *mr,
-struct Object *owner,
+Object *owner,
 const char *name,
 uint64_t size,
 bool share,
@@ -1030,7 +1030,7 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
  * RAM memory region to be migrated; that is the responsibility of the caller.
  */
 void memory_region_init_ram_ptr(MemoryRegion *mr,
-struct Object *owner,
+Object *owner,
 const char *name,

[PULL 07/22] MAINTAINERS: Fix the location of tools manuals

2021-03-10 Thread Laurent Vivier
From: Wainer dos Santos Moschetta 

The qemu-img.rst, qemu-nbd.rst, virtfs-proxy-helper.rst, qemu-trace-stap.rst,
and virtiofsd.rst manuals were moved to docs/tools, so this update MAINTAINERS
accordingly.

Fixes: a08b4a9fe6c ("docs: Move tools documentation to tools manual")
Signed-off-by: Wainer dos Santos Moschetta 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Thomas Huth 
Message-Id: <20210204135425.1380280-1-waine...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 MAINTAINERS | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index f22d83c17823..ad28f37bc5ff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1862,7 +1862,7 @@ S: Odd Fixes
 F: hw/9pfs/
 X: hw/9pfs/xen-9p*
 F: fsdev/
-F: docs/interop/virtfs-proxy-helper.rst
+F: docs/tools/virtfs-proxy-helper.rst
 F: tests/qtest/virtio-9p-test.c
 T: git https://gitlab.com/gkurz/qemu.git 9p-next
 T: git https://github.com/cschoenebeck/qemu.git 9p.next
@@ -1893,7 +1893,7 @@ S: Supported
 F: tools/virtiofsd/*
 F: hw/virtio/vhost-user-fs*
 F: include/hw/virtio/vhost-user-fs.h
-F: docs/interop/virtiofsd.rst
+F: docs/tools/virtiofsd.rst
 
 virtio-input
 M: Gerd Hoffmann 
@@ -2200,7 +2200,7 @@ F: block/
 F: hw/block/
 F: include/block/
 F: qemu-img*
-F: docs/interop/qemu-img.rst
+F: docs/tools/qemu-img.rst
 F: qemu-io*
 F: tests/qemu-iotests/
 F: util/qemu-progress.c
@@ -2656,7 +2656,7 @@ F: qapi/trace.json
 F: scripts/tracetool.py
 F: scripts/tracetool/
 F: scripts/qemu-trace-stap*
-F: docs/interop/qemu-trace-stap.rst
+F: docs/tools/qemu-trace-stap.rst
 F: docs/devel/tracing.txt
 T: git https://github.com/stefanha/qemu.git tracing
 
@@ -3047,7 +3047,7 @@ F: include/block/nbd*
 F: qemu-nbd.*
 F: blockdev-nbd.c
 F: docs/interop/nbd.txt
-F: docs/interop/qemu-nbd.rst
+F: docs/tools/qemu-nbd.rst
 T: git https://repo.or.cz/qemu/ericb.git nbd
 
 NFS
-- 
2.29.2




[PULL 14/22] seccomp: Replace the word 'blacklist'

2021-03-10 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

Follow the inclusive terminology from the "Conscious Language in your
Open Source Projects" guidelines [*] and replace the word "blacklist"
appropriately.

[*] https://github.com/conscious-lang/conscious-lang-docs/blob/main/faq.md

Reviewed-by: Daniel P. Berrangé 
Acked-by: Eduardo Otubo 
Reviewed-by: Alex Bennée 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Thomas Huth 
Message-Id: <20210303184644.1639691-4-phi...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 softmmu/qemu-seccomp.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/softmmu/qemu-seccomp.c b/softmmu/qemu-seccomp.c
index 377ef6937ca5..9c29d9cf007e 100644
--- a/softmmu/qemu-seccomp.c
+++ b/softmmu/qemu-seccomp.c
@@ -45,8 +45,8 @@ const struct scmp_arg_cmp sched_setscheduler_arg[] = {
 { .arg = 1, .op = SCMP_CMP_NE, .datum_a = SCHED_IDLE }
 };
 
-static const struct QemuSeccompSyscall blacklist[] = {
-/* default set of syscalls to blacklist */
+static const struct QemuSeccompSyscall denylist[] = {
+/* default set of syscalls that should get blocked */
 { SCMP_SYS(reboot), QEMU_SECCOMP_SET_DEFAULT },
 { SCMP_SYS(swapon), QEMU_SECCOMP_SET_DEFAULT },
 { SCMP_SYS(swapoff),QEMU_SECCOMP_SET_DEFAULT },
@@ -175,18 +175,18 @@ static int seccomp_start(uint32_t seccomp_opts, Error 
**errp)
 goto seccomp_return;
 }
 
-for (i = 0; i < ARRAY_SIZE(blacklist); i++) {
+for (i = 0; i < ARRAY_SIZE(denylist); i++) {
 uint32_t action;
-if (!(seccomp_opts & blacklist[i].set)) {
+if (!(seccomp_opts & denylist[i].set)) {
 continue;
 }
 
-action = qemu_seccomp_get_action(blacklist[i].set);
-rc = seccomp_rule_add_array(ctx, action, blacklist[i].num,
-blacklist[i].narg, blacklist[i].arg_cmp);
+action = qemu_seccomp_get_action(denylist[i].set);
+rc = seccomp_rule_add_array(ctx, action, denylist[i].num,
+denylist[i].narg, denylist[i].arg_cmp);
 if (rc < 0) {
 error_setg_errno(errp, -rc,
- "failed to add seccomp blacklist rules");
+ "failed to add seccomp denylist rules");
 goto seccomp_return;
 }
 }
-- 
2.29.2




[PULL 09/22] fuzz-test: remove unneccessary debugging flags

2021-03-10 Thread Laurent Vivier
From: Alexander Bulekov 

These flags cause the output to look strange for 'make check', and
they aren't needed to reproduce bugs, if they reappear.

Suggested-by: Peter Maydell 
Signed-off-by: Alexander Bulekov 
Reviewed-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20210216181316.794276-1-alx...@bu.edu>
Signed-off-by: Laurent Vivier 
---
 tests/qtest/fuzz-test.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tests/qtest/fuzz-test.c b/tests/qtest/fuzz-test.c
index cdb1100a0b81..6f161c93be71 100644
--- a/tests/qtest/fuzz-test.c
+++ b/tests/qtest/fuzz-test.c
@@ -39,8 +39,7 @@ static void test_lp1878642_pci_bus_get_irq_level_assert(void)
 QTestState *s;
 
 s = qtest_init("-M pc-q35-5.0 "
-   "-nographic -monitor none -serial none "
-   "-d guest_errors -trace pci*");
+   "-nographic -monitor none -serial none");
 
 qtest_outl(s, 0xcf8, 0x8400f841);
 qtest_outl(s, 0xcfc, 0xebed205d);
-- 
2.29.2




[PULL 11/22] virtio-gpu: Adjust code space style

2021-03-10 Thread Laurent Vivier
From: lijiejun 

Fix code style. Operator needs align with eight spaces, and delete line space.

Signed-off-by: lijiejun 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <1615292050-108748-1-git-send-email-a_lijie...@163.com>
Signed-off-by: Laurent Vivier 
---
 hw/display/virtio-gpu-3d.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c
index 9eb489077b17..d98964858e13 100644
--- a/hw/display/virtio-gpu-3d.c
+++ b/hw/display/virtio-gpu-3d.c
@@ -438,7 +438,7 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
 break;
 case VIRTIO_GPU_CMD_RESOURCE_FLUSH:
 virgl_cmd_resource_flush(g, cmd);
-   break;
+break;
 case VIRTIO_GPU_CMD_RESOURCE_UNREF:
 virgl_cmd_resource_unref(g, cmd);
 break;
@@ -456,7 +456,6 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
 case VIRTIO_GPU_CMD_GET_CAPSET:
 virgl_cmd_get_capset(g, cmd);
 break;
-
 case VIRTIO_GPU_CMD_GET_DISPLAY_INFO:
 virtio_gpu_get_display_info(g, cmd);
 break;
-- 
2.29.2




[PULL 15/22] qemu-options: Replace the word 'blacklist'

2021-03-10 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

Follow the inclusive terminology from the "Conscious Language in your
Open Source Projects" guidelines [*] and replace the word "blacklist"
appropriately.

[*] https://github.com/conscious-lang/conscious-lang-docs/blob/main/faq.md

Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Thomas Huth 
Message-Id: <20210303184644.1639691-5-phi...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 qemu-options.hx | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index c324633fcaad..622d3bfa5a7d 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4299,12 +4299,12 @@ DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \
 "use 'obsolete' to allow obsolete system calls that are 
provided\n" \
 "by the kernel, but typically no longer used by 
modern\n" \
 "C library implementations.\n" \
-"use 'elevateprivileges' to allow or deny QEMU process to 
elevate\n" \
-"its privileges by blacklisting all set*uid|gid system 
calls.\n" \
+"use 'elevateprivileges' to allow or deny the QEMU process 
ability\n" \
+"to elevate privileges using set*uid|gid system 
calls.\n" \
 "The value 'children' will deny set*uid|gid system 
calls for\n" \
 "main QEMU process but will allow forks and execves to 
run unprivileged\n" \
 "use 'spawn' to avoid QEMU to spawn new threads or 
processes by\n" \
-" blacklisting *fork and execve\n" \
+" blocking *fork and execve\n" \
 "use 'resourcecontrol' to disable process affinity and 
schedular priority\n",
 QEMU_ARCH_ALL)
 SRST
-- 
2.29.2




[PULL 12/22] ui: Replace the word 'whitelist'

2021-03-10 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

Follow the inclusive terminology from the "Conscious Language in your
Open Source Projects" guidelines [*] and replace the words "whitelist"
appropriately.

[*] https://github.com/conscious-lang/conscious-lang-docs/blob/main/faq.md

Reviewed-by: Gerd Hoffmann 
Reviewed-by: Alex Bennée 
Reviewed-by: Thomas Huth 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20210303184644.1639691-2-phi...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 ui/console.c   | 2 +-
 ui/vnc-auth-sasl.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index 171a7bf14b94..c2fdf975b6b3 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1724,7 +1724,7 @@ bool dpy_gfx_check_format(QemuConsole *con,
 return false;
 }
 } else {
-/* default is to whitelist native 32 bpp only */
+/* default is to allow native 32 bpp only */
 if (format != qemu_default_pixman_format(32, true)) {
 return false;
 }
diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
index f67111a3662a..df7dc08e9fc5 100644
--- a/ui/vnc-auth-sasl.c
+++ b/ui/vnc-auth-sasl.c
@@ -288,7 +288,7 @@ static int protocol_client_auth_sasl_step(VncState *vs, 
uint8_t *data, size_t le
 goto authreject;
 }
 
-/* Check username whitelist ACL */
+/* Check the username access control list */
 if (vnc_auth_sasl_check_access(vs) < 0) {
 goto authreject;
 }
@@ -409,7 +409,7 @@ static int protocol_client_auth_sasl_start(VncState *vs, 
uint8_t *data, size_t l
 goto authreject;
 }
 
-/* Check username whitelist ACL */
+/* Check the username access control list */
 if (vnc_auth_sasl_check_access(vs) < 0) {
 goto authreject;
 }
-- 
2.29.2




[PULL 04/22] target/hexagon/gen_tcg_funcs: Fix a typo

2021-03-10 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Taylor Simpson 
Message-Id: <20210225181507.3624509-1-f4...@amsat.org>
Signed-off-by: Laurent Vivier 
---
 target/hexagon/gen_tcg_funcs.py | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index fe4d8e57303a..db9f663a778e 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -35,7 +35,7 @@ def gen_decl_ea_tcg(f, tag):
 def gen_free_ea_tcg(f):
 f.write("tcg_temp_free(EA);\n")
 
-def genptr_decl_pair_writeble(f, tag, regtype, regid, regno):
+def genptr_decl_pair_writable(f, tag, regtype, regid, regno):
 regN="%s%sN" % (regtype,regid)
 f.write("TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \
 (regtype, regid))
@@ -54,7 +54,7 @@ def genptr_decl_pair_writeble(f, tag, regtype, regid, regno):
  (regN, regN))
 f.write("}\n")
 
-def genptr_decl_writeble(f, tag, regtype, regid, regno):
+def genptr_decl_writable(f, tag, regtype, regid, regno):
 regN="%s%sN" % (regtype,regid)
 f.write("TCGv %s%sV = tcg_temp_local_new();\n" % \
 (regtype, regid))
@@ -78,12 +78,12 @@ def genptr_decl(f, tag, regtype, regid, regno):
 f.write("const int %s = insn->regno[%d];\n" % \
 (regN, regno))
 elif (regid in {"dd", "ee", "xx", "yy"}):
-genptr_decl_pair_writeble(f, tag, regtype, regid, regno)
+genptr_decl_pair_writable(f, tag, regtype, regid, regno)
 elif (regid in {"s", "t", "u", "v"}):
 f.write("TCGv %s%sV = hex_gpr[insn->regno[%d]];\n" % \
 (regtype, regid, regno))
 elif (regid in {"d", "e", "x", "y"}):
-genptr_decl_writeble(f, tag, regtype, regid, regno)
+genptr_decl_writable(f, tag, regtype, regid, regno)
 else:
 print("Bad register parse: ", regtype, regid)
 elif (regtype == "P"):
@@ -91,7 +91,7 @@ def genptr_decl(f, tag, regtype, regid, regno):
 f.write("TCGv %s%sV = hex_pred[insn->regno[%d]];\n" % \
 (regtype, regid, regno))
 elif (regid in {"d", "e", "x"}):
-genptr_decl_writeble(f, tag, regtype, regid, regno)
+genptr_decl_writable(f, tag, regtype, regid, regno)
 else:
 print("Bad register parse: ", regtype, regid)
 elif (regtype == "C"):
@@ -101,14 +101,14 @@ def genptr_decl(f, tag, regtype, regid, regno):
 f.write("const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \
 (regN, regno))
 elif (regid == "dd"):
-genptr_decl_pair_writeble(f, tag, regtype, regid, regno)
+genptr_decl_pair_writable(f, tag, regtype, regid, regno)
 elif (regid == "s"):
 f.write("TCGv %s%sV = tcg_temp_local_new();\n" % \
 (regtype, regid))
 f.write("const int %s%sN = insn->regno[%d] + HEX_REG_SA0;\n" % 
\
 (regtype, regid, regno))
 elif (regid == "d"):
-genptr_decl_writeble(f, tag, regtype, regid, regno)
+genptr_decl_writable(f, tag, regtype, regid, regno)
 else:
 print("Bad register parse: ", regtype, regid)
 elif (regtype == "M"):
-- 
2.29.2




[PULL 18/22] hw/lm32/Kconfig: Introduce CONFIG_LM32_EVR for lm32-evr/uclinux boards

2021-03-10 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

We want to be able to use the 'LM32' config for architecture
specific features. Introduce CONFIG_LM32_EVR to select the
lm32-evr / lm32-uclinux boards.

Reviewed-by: Alex Bennée 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20210221225626.2589247-2-f4...@amsat.org>
Signed-off-by: Laurent Vivier 
---
 default-configs/devices/lm32-softmmu.mak | 2 +-
 hw/lm32/Kconfig  | 6 +-
 hw/lm32/meson.build  | 2 +-
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/default-configs/devices/lm32-softmmu.mak 
b/default-configs/devices/lm32-softmmu.mak
index 115b3e34c983..1bce3f6e8b64 100644
--- a/default-configs/devices/lm32-softmmu.mak
+++ b/default-configs/devices/lm32-softmmu.mak
@@ -8,5 +8,5 @@ CONFIG_SEMIHOSTING=y
 
 # Boards:
 #
-CONFIG_LM32=y
+CONFIG_LM32_EVR=y
 CONFIG_MILKYMIST=y
diff --git a/hw/lm32/Kconfig b/hw/lm32/Kconfig
index ed2e3060b040..20c36edc402c 100644
--- a/hw/lm32/Kconfig
+++ b/hw/lm32/Kconfig
@@ -1,7 +1,6 @@
 config LM32
 bool
 select PTIMER
-select PFLASH_CFI02
 
 config MILKYMIST
 bool
@@ -12,3 +11,8 @@ config MILKYMIST
 select FRAMEBUFFER
 select SD
 select USB_OHCI
+
+config LM32_EVR
+bool
+select LM32
+select PFLASH_CFI02
diff --git a/hw/lm32/meson.build b/hw/lm32/meson.build
index 8caf0a727ff8..42d6f8db3d97 100644
--- a/hw/lm32/meson.build
+++ b/hw/lm32/meson.build
@@ -1,6 +1,6 @@
 lm32_ss = ss.source_set()
 # LM32 boards
-lm32_ss.add(when: 'CONFIG_LM32', if_true: files('lm32_boards.c'))
+lm32_ss.add(when: 'CONFIG_LM32_EVR', if_true: files('lm32_boards.c'))
 lm32_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist.c'))
 
 hw_arch += {'lm32': lm32_ss}
-- 
2.29.2




[PULL 17/22] qemu-common.h: Update copyright string to 2021

2021-03-10 Thread Laurent Vivier
From: Peter Maydell 

Update the common copyright string that we use in
-version reports, About dialogs, etc, to 2021.

Signed-off-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Laurent Vivier 
Message-Id: <20210309162258.28633-1-peter.mayd...@linaro.org>
Signed-off-by: Laurent Vivier 
---
 include/qemu-common.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/qemu-common.h b/include/qemu-common.h
index 654621444ecf..73bcf763ed82 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -13,7 +13,7 @@
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
 /* Copyright string for -version arguments, About dialogs, etc */
-#define QEMU_COPYRIGHT "Copyright (c) 2003-2020 " \
+#define QEMU_COPYRIGHT "Copyright (c) 2003-2021 " \
 "Fabrice Bellard and the QEMU Project developers"
 
 /* Bug reporting information for --help arguments, About dialogs, etc */
-- 
2.29.2




[PULL 19/22] hw/lm32/Kconfig: Rename CONFIG_LM32 -> CONFIG_LM32_DEVICES

2021-03-10 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

We want to be able to use the 'LM32' config for architecture
specific features. As CONFIG_LM32 is only used to select
peripherals, rename it CONFIG_LM32_DEVICES.

Reviewed-by: Alex Bennée 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20210221225626.2589247-3-f4...@amsat.org>
Signed-off-by: Laurent Vivier 
---
 hw/char/meson.build  | 4 ++--
 hw/intc/meson.build  | 2 +-
 hw/lm32/Kconfig  | 4 ++--
 hw/timer/meson.build | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/char/meson.build b/hw/char/meson.build
index afe9a0af88c1..7ba38dbd965f 100644
--- a/hw/char/meson.build
+++ b/hw/char/meson.build
@@ -8,8 +8,8 @@ softmmu_ss.add(when: 'CONFIG_IMX', if_true: 
files('imx_serial.c'))
 softmmu_ss.add(when: 'CONFIG_IPACK', if_true: files('ipoctal232.c'))
 softmmu_ss.add(when: 'CONFIG_ISA_BUS', if_true: files('parallel-isa.c'))
 softmmu_ss.add(when: 'CONFIG_ISA_DEBUG', if_true: files('debugcon.c'))
-softmmu_ss.add(when: 'CONFIG_LM32', if_true: files('lm32_juart.c'))
-softmmu_ss.add(when: 'CONFIG_LM32', if_true: files('lm32_uart.c'))
+softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_juart.c'))
+softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_uart.c'))
 softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-uart.c'))
 softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_uart.c'))
 softmmu_ss.add(when: 'CONFIG_PARALLEL', if_true: files('parallel.c'))
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index b3d9345a0d2e..8df3656419e3 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -14,7 +14,7 @@ softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: 
files('heathrow_pic.c'))
 softmmu_ss.add(when: 'CONFIG_I8259', if_true: files('i8259_common.c', 
'i8259.c'))
 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_avic.c', 'imx_gpcv2.c'))
 softmmu_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic_common.c'))
-softmmu_ss.add(when: 'CONFIG_LM32', if_true: files('lm32_pic.c'))
+softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_pic.c'))
 softmmu_ss.add(when: 'CONFIG_OPENPIC', if_true: files('openpic.c'))
 softmmu_ss.add(when: 'CONFIG_PL190', if_true: files('pl190.c'))
 softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_intc.c'))
diff --git a/hw/lm32/Kconfig b/hw/lm32/Kconfig
index 20c36edc402c..518c84ed5084 100644
--- a/hw/lm32/Kconfig
+++ b/hw/lm32/Kconfig
@@ -1,4 +1,4 @@
-config LM32
+config LM32_DEVICES
 bool
 select PTIMER
 
@@ -14,5 +14,5 @@ config MILKYMIST
 
 config LM32_EVR
 bool
-select LM32
+select LM32_DEVICES
 select PFLASH_CFI02
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
index 26c2701fd78f..a2372629f001 100644
--- a/hw/timer/meson.build
+++ b/hw/timer/meson.build
@@ -19,7 +19,7 @@ softmmu_ss.add(when: 'CONFIG_HPET', if_true: files('hpet.c'))
 softmmu_ss.add(when: 'CONFIG_I8254', if_true: files('i8254_common.c', 
'i8254.c'))
 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_epit.c'))
 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_gpt.c'))
-softmmu_ss.add(when: 'CONFIG_LM32', if_true: files('lm32_timer.c'))
+softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_timer.c'))
 softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-sysctl.c'))
 softmmu_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gictimer.c'))
 softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-timer.c'))
-- 
2.29.2




[PULL 16/22] tests/fp/fp-test: Replace the word 'blacklist'

2021-03-10 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

Follow the inclusive terminology from the "Conscious Language in your
Open Source Projects" guidelines [*] and replace the word "blacklist"
appropriately.

[*] https://github.com/conscious-lang/conscious-lang-docs/blob/main/faq.md

Acked-by: Alex Bennée 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Thomas Huth 
Message-Id: <20210303184644.1639691-6-phi...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 tests/fp/fp-test.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
index 06ffebd6db17..5a4cad8c8b23 100644
--- a/tests/fp/fp-test.c
+++ b/tests/fp/fp-test.c
@@ -123,7 +123,7 @@ static void not_implemented(void)
 fprintf(stderr, "Not implemented.\n");
 }
 
-static bool blacklisted(unsigned op, int rmode)
+static bool is_allowed(unsigned op, int rmode)
 {
 /* odd has not been implemented for any 80-bit ops */
 if (rmode == softfloat_round_odd) {
@@ -161,10 +161,10 @@ static bool blacklisted(unsigned op, int rmode)
 case F32_TO_EXTF80:
 case F64_TO_EXTF80:
 case F128_TO_EXTF80:
-return true;
+return false;
 }
 }
-return false;
+return true;
 }
 
 static void do_testfloat(int op, int rmode, bool exact)
@@ -194,7 +194,7 @@ static void do_testfloat(int op, int rmode, bool exact)
 verCases_writeFunctionName(stderr);
 fputs("\n", stderr);
 
-if (blacklisted(op, rmode)) {
+if (!is_allowed(op, rmode)) {
 not_implemented();
 return;
 }
-- 
2.29.2




[PULL 13/22] scripts/tracetool: Replace the word 'whitelist'

2021-03-10 Thread Laurent Vivier
From: Philippe Mathieu-Daudé 

Follow the inclusive terminology from the "Conscious Language in your
Open Source Projects" guidelines [*] and replace the words "whitelist"
appropriately.

[*] https://github.com/conscious-lang/conscious-lang-docs/blob/main/faq.md

Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Alex Bennée 
Reviewed-by: Thomas Huth 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Stefan Hajnoczi 
Message-Id: <20210303184644.1639691-3-phi...@redhat.com>
Signed-off-by: Laurent Vivier 
---
 scripts/tracetool/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 96b1cd69a52c..5bc94d95cfc7 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -100,7 +100,7 @@ def validate_type(name):
 if bit == "const":
 continue
 if bit not in ALLOWED_TYPES:
-raise ValueError("Argument type '%s' is not in whitelist. "
+raise ValueError("Argument type '%s' is not allowed. "
  "Only standard C types and fixed size integer "
  "types should be used. struct, union, and "
  "other complex pointer types should be "
-- 
2.29.2




Re: [PULL 00/22] Trivial branch for 6.0 patches

2021-03-10 Thread Laurent Vivier
Peter,

my "git publish" has failed at patch 20 with:

Requested action aborted
Mails per session limit exceeded.

I think my email provider has added new limits :(

can you merge this PR without I have to resend it?

Thanks,
Laurent

Le 10/03/2021 à 22:44, Laurent Vivier a écrit :
> The following changes since commit b2ae1009d7cca2701e17eae55ae2d44fd22c942a:
> 
>   Merge remote-tracking branch 'remotes/mcayland/tags/qemu-sparc-20210307' in=
> to staging (2021-03-09 13:50:35 +)
> 
> are available in the Git repository at:
> 
>   git://github.com/vivier/qemu.git tags/trivial-branch-for-6.0-pull-request
> 
> for you to fetch changes up to 538f049704e9b7a07eeaf326af772fdd30d89576:
> 
>   sysemu: Let VMChangeStateHandler take boolean 'running' argument (2021-03-0=
> 9 23:13:57 +0100)
> 
> ----
> Pull request trivial patches 20210310
> 
> 
> 
> Alexander Bulekov (1):
>   fuzz-test: remove unneccessary debugging flags
> 
> Eric Blake (1):
>   scsi: Silence gcc warning
> 
> Markus Armbruster (2):
>   backends/dbus-vmstate: Fix short read error handling
>   vhost_user_gpu: Drop dead check for g_malloc() failure
> 
> Michael Tokarev (1):
>   Various spelling fixes
> 
> Peter Maydell (1):
>   qemu-common.h: Update copyright string to 2021
> 
> Philippe Mathieu-Daud=C3=A9 (13):
>   hw/elf_ops: Fix a typo
>   target/hexagon/gen_tcg_funcs: Fix a typo
>   exec/memory: Use struct Object typedef
>   ui: Replace the word 'whitelist'
>   scripts/tracetool: Replace the word 'whitelist'
>   seccomp: Replace the word 'blacklist'
>   qemu-options: Replace the word 'blacklist'
>   tests/fp/fp-test: Replace the word 'blacklist'
>   hw/lm32/Kconfig: Introduce CONFIG_LM32_EVR for lm32-evr/uclinux boards
>   hw/lm32/Kconfig: Rename CONFIG_LM32 -> CONFIG_LM32_DEVICES
>   hw/lm32/Kconfig: Have MILKYMIST select LM32_DEVICES
>   sysemu/runstate: Let runstate_is_running() return bool
>   sysemu: Let VMChangeStateHandler take boolean 'running' argument
> 
> Thomas Huth (1):
>   net: Use id_generate() in the network subsystem, too
> 
> Wainer dos Santos Moschetta (1):
>   MAINTAINERS: Fix the location of tools manuals
> 
> lijiejun (1):
>   virtio-gpu: Adjust code space style
> 
>  MAINTAINERS  | 10 
>  accel/xen/xen-all.c  |  2 +-
>  audio/audio.c|  2 +-
>  backends/dbus-vmstate.c  |  5 +++-
>  block/block-backend.c|  2 +-
>  default-configs/devices/lm32-softmmu.mak |  2 +-
>  disas/nanomips.cpp   |  2 +-
>  gdbstub.c|  2 +-
>  hw/block/pflash_cfi01.c  |  2 +-
>  hw/block/virtio-blk.c|  2 +-
>  hw/char/meson.build  |  4 +--
>  hw/display/qxl.c |  2 +-
>  hw/display/vhost-user-gpu.c  |  1 -
>  hw/display/virtio-gpu-3d.c   |  3 +--
>  hw/i386/kvm/clock.c  |  2 +-
>  hw/i386/kvm/i8254.c  |  2 +-
>  hw/i386/kvmvapic.c   |  2 +-
>  hw/i386/xen/xen-hvm.c|  2 +-
>  hw/ide/core.c|  2 +-
>  hw/intc/arm_gicv3_its_kvm.c  |  2 +-
>  hw/intc/arm_gicv3_kvm.c  |  2 +-
>  hw/intc/meson.build  |  2 +-
>  hw/intc/spapr_xive_kvm.c |  2 +-
>  hw/lm32/Kconfig  | 10 +---
>  hw/lm32/meson.build  |  2 +-
>  hw/misc/mac_via.c|  2 +-
>  hw/misc/trace-events |  2 +-
>  hw/net/allwinner-sun8i-emac.c|  2 +-
>  hw/net/e1000e_core.c |  2 +-
>  hw/nvram/spapr_nvram.c   |  2 +-
>  hw/ppc/pnv_bmc.c |  2 +-
>  hw/ppc/pnv_xscom.c   |  2 +-
>  hw/ppc/ppc.c |  2 +-
>  hw/ppc/ppc_booke.c   |  2 +-
>  hw/s390x/tod-kvm.c   |  2 +-
>  hw/scsi/scsi-bus.c   |  2 +-
>  hw/scsi/scsi-disk.c  |  1 +
>  hw/timer/meson.build |  2 +-
>  hw/usb/ccid-card-emulated.c  |  2 +-
>  hw/usb/hcd-ehci.c|  2 +-
>  hw/usb/hcd-ohci.c|  2 +-
>  hw/usb/host-libusb.c |  2 +-
>  hw/usb/redirect.c|  2 +-
>  hw/vfio/migration.c  

Re: [PATCH v3 1/3] target/arm: Add support for FEAT_TLBIRANGE

2021-03-10 Thread Rebecca Cran

On 3/10/21 12:24 PM, Richard Henderson wrote:

On 3/9/21 6:29 PM, Rebecca Cran wrote:

+void tlb_flush_page_range_by_mmuidx(CPUState *cpu, target_ulong addr,
+    unsigned int num_pages, uint16_t 
idxmap)


I am not keen on this interface.  I think you should take either 
start+end addresses (inclusive) or start+length (in bytes).


Using num_pages, and as an unsigned int, seems too easy to fail when 
applied to a different guest.



+{
+  /*
+   * We currently do a full flush, but for performance this should be
+   * updated to only flush the requested pages, taking TBI into account.
+   */
+    tlb_flush_by_mmuidx(cpu, idxmap);
+}


And if you're going to cop-out like this, you might as well just do it 
in target/arm and not add these new interfaces at all.



+#ifdef TARGET_AARCH64
+static unsigned int tlbi_aa64_range_get_num_pages(CPUARMState *env,
+  uint64_t value,
+  uint64_t addr)
+{
+    unsigned int page_size;
+    unsigned int page_shift;
+    unsigned int page_size_granule;
+    uint64_t num;
+    uint64_t scale;
+    uint64_t exponent;
+    uint64_t high_addr;
+
+    num = (value >> 39) & 0xF;
+    scale = (value >> 44) & 0x3;
+    page_size_granule = (value >> 46) & 0x3;


extract64()


+
+    switch (page_size_granule) {
+    case 1:
+  page_size = 4096;
+  page_shift = 12;
+  break;
+    case 2:
+  page_size = 16384;
+  page_shift = 14;
+  break;
+    case 3:
+  page_size = 65536;
+  page_shift = 16;
+  break;
+    default:
+  qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
+    page_size_granule);
+
+  raise_exception(env, EXCP_UDEF, syn_uncategorized(),
+  exception_target_el(env));


You can't raise an exception from here, because you don't have all of 
the context for unwinding the tcg state.  Which you cannot access from 
within the callback of an ARMCPRegInfo.


The manual says that if TG does not correspond to the granule size of 
the actual translation then "the architecture does not require that the 
instruction invalidates any entries".  "Reserved" can be safely assumed 
to "not correspond", so I think you could just as easily return 0 here, 
after logging the guest error.




+    high_addr = addr + (((num + 1) << exponent) * page_size);
+
+    return (high_addr - addr) >> page_shift;


I'll note that it would be much easier for you to return a byte value 
for the length, and that you don't actually need to pass in addr at all.



+    uint64_t addr = (value & 0xFUL) << TARGET_PAGE_BITS;


The manual does not explicitly say, but I'm certain that this should be 
a signed address, when regime_has_2_ranges().  Otherwise it would be 
impossible to flush a range of kernel addresses.


But all of this is moot if we're just going to flush all pages.  At 
which point you might as well simply re-use tlbi_aa64_vmalle1_write et 
al.  Place your TODO comment in front of tlbirange_reginfo[] instead of 
buried n-levels further down.


Thanks for the comments. I'll continue working on the full/proper 
implementation (including changing the interface to remove num_pages) 
and send out a v4.


--
Rebecca Cran



[PATCH] hw/riscv: Fix OT IBEX reset vector

2021-03-10 Thread Alexander Wagner
The IBEX documentation [1] specifies the reset vector to be "the most
significant 3 bytes of the boot address and the reset value (0x80) as
the least significant byte".

[1] 
https://github.com/lowRISC/ibex/blob/master/doc/03_reference/exception_interrupts.rst

Signed-off-by: Alexander Wagner 
---
 hw/riscv/opentitan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index e168bffe69..ca4c1be6f6 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -120,7 +120,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 &error_abort);
 object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus,
 &error_abort);
-object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x8090, 
&error_abort);
+object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x8080, 
&error_abort);
 sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_abort);
 
 /* Boot ROM */
-- 
2.25.1




Re: [PATCH 2/3] memory: Provide 'base address' argument to mtree_print_mr()

2021-03-10 Thread Mark Cave-Ayland

On 09/03/2021 21:54, Philippe Mathieu-Daudé wrote:


+Peter/Mark/Edgar for SoC modelling

On 3/9/21 10:39 AM, Philippe Mathieu-Daudé wrote:

Hi Peter,

On 3/9/21 12:40 AM, Peter Xu wrote:> On Sat, Mar 06, 2021 at 12:54:13AM
+0100, Philippe Mathieu-Daudé wrote:

@@ -3188,14 +3188,15 @@ void mtree_info(bool flatview, bool dispatch_tree, bool 
owner, bool disabled)
  
  QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {

  qemu_printf("address-space: %s\n", as->name);
-mtree_print_mr(as->root, 1, 0, &ml_head, owner, disabled);
+mtree_print_mr(as->root, 1, 0, as->root->addr,


Root MR of any address space should have mr->addr==0, right?

I'm slightly confused on what this patch wanted to do if so, since then "base"
will always be zero..  Or am I wrong?


That is what I am expecting too... Maybe the problem is elsewhere
when I create the address space... The simpler way to
figure it out is add an assertion. I haven't figure out my
issue yet, I'll follow up later with a proof-of-concept series
which triggers the assertion.


To trigger I simply use:

mydevice_realize()
{
   memory_region_init(&mr, obj, name, size);

   address_space_init(&as, &mr, name);
   // here we have as.root.addr = 0

   sysbus_init_mmio(sbd, &mr);
}

soc_realize()
{
 ...
 sysbus_realize(SYS_BUS_DEVICE(&mydevice), &error_abort);
 sysbus_mmio_map(SYS_BUS_DEVICE(&mydevice), 0, NONZERO_ADDRESS);
 ...
}

sysbus_mmio_map
-> sysbus_mmio_map_common
-> memory_region_add_subregion
   -> memory_region_add_subregion_common

Which does:

static void memory_region_add_subregion_common(MemoryRegion *mr,
hwaddr offset,
MemoryRegion *subregion)
{
 assert(!subregion->container);
 subregion->container = mr;
 subregion->addr = offset;
 // subregion = &as.root
 // offset = NONZERO_ADDRESS
 // so here as.root.addr becomes non-zero

Is that use case incorrect? If so:
- where to add the proper assertions to avoid having address spaces
   with non-zero base address?
- what is the proper design?

Else what should we fix?


I think I've seen something like this before with the sun4u IOMMU - I tried to get 
the offset of the IOMMU address space memory region from its parent in 
sun4u_translate_iommu() but I ended up getting back an absolute address instead. I 
think the conclusion I came to was that it wouldn't work with a memory region at the 
root of an address space, so I'd be interested to know what the behaviour here should be.


In terms of soc_realize() I believe there are 2 options for getting the memory 
region: 1) use object_resolve_path_component() to retrieve the memory region as a QOM 
property or 2) use sysbus_mmio_get_region(). Once you have a reference to the memory 
region you can add it to the parent using memory_region_add_subregion() as needed. 
There is an existing example of 2) in hw/sparc64/sun4u.c in ebus_realize().



ATB,

Mark.



Re: [PATCH 6/7] mac_via: fix 60Hz VIA1 timer interval

2021-03-10 Thread Mark Cave-Ayland

On 10/03/2021 13:24, Laurent Vivier wrote:


Le 10/03/2021 à 14:10, Laurent Vivier a écrit :

Le 10/03/2021 à 13:56, Laurent Vivier a écrit :

Le 10/03/2021 à 13:32, BALATON Zoltan a écrit :

On Wed, 10 Mar 2021, Mark Cave-Ayland wrote:

The 60Hz timer is initialised using timer_new_ns() meaning that the timer
interval should be measured in ns, and therefore its period is a thousand
times too short.

Signed-off-by: Mark Cave-Ayland 
---
hw/misc/mac_via.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index f994fefa7c..c6e1552a59 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -302,8 +302,8 @@ static void via1_sixty_hz_update(MOS6522Q800VIA1State *v1s)
     MOS6522State *s = MOS6522(v1s);

     /* 60 Hz irq */
-    v1s->next_sixty_hz = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 16630) /
-  16630 * 16630;
+    v1s->next_sixty_hz = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1663) /
+  1663 * 1663;


Can you put this magic number in a #define maybe also rewriting it in a way 
that shows it
corresponds to a 60 Hz interval. (There's NANOSECONDS_PER_SECOND defined in 
include/qemu/timer.h
that could be used for that, there's also SCALE_MS that might replace 1000 * 
1000 elsewhere in this
file). Also NANOSECONDS_PER_SECOND / 60 is 1666, should that value be used 
here instead?


In fact, the Mac Frequency is not exactly 60 Hz, in docs we can find 60.147 Hz, 
in kernel 60.15 Hz.
I Think there are several ways to compute it...



In fact, we can read:

"the vertical retrace frequency is approximately 60.15 Hz, resulting in a 
period of approximately
16.63 milliseconds"

https://developer.apple.com/library/archive/documentation/mac/pdf/Processes/Vertical_Retrace_Mgr.pdf


The exact value is 16625800 ns

"Macintosh Family Hardware Reference" ISBN 0-201-19255-1
"The video interface"
p. 13-3

"[...] This means the full frame is redisplayed every 370 scan lines, or once every 
166625.8 µs."


Thanks Laurent! Given that the exact precision is 6 digits I don't think it's 
possible to make use of conversion macros without either making it harder to read or 
reducing the precision.


I think the best solution here would be to #define VIA1_60HZ_TIMER_PERIOD_NS with a 
comment containing the above reference, and use that in the period calculation. Would 
that be sufficient?



ATB,

Mark.



Re: [PULL 00/20] ppc-for-6.0 queue 20210310

2021-03-10 Thread David Gibson
On Wed, Mar 10, 2021 at 12:43:53PM +0800, Bin Meng wrote:
> Hi David,
> 
> On Wed, Mar 10, 2021 at 12:10 PM David Gibson
>  wrote:
> >
> > The following changes since commit b2ae1009d7cca2701e17eae55ae2d44fd22c942a:
> >
> >   Merge remote-tracking branch 'remotes/mcayland/tags/qemu-sparc-20210307' 
> > into staging (2021-03-09 13:50:35 +)
> >
> > are available in the Git repository at:
> >
> >   https://gitlab.com/dgibson/qemu.git tags/ppc-for-6.0-20210310
> >
> > for you to fetch changes up to eb7f80fd26d73e7e1af105431da58971b1dba517:
> >
> >   spapr.c: send QAPI event when memory hotunplug fails (2021-03-10 09:07:09 
> > +1100)
> >
> > 
> > ppc patch queue for 2021-03-10
> >
> > Next batch of patches for the ppc target and machine types.  Includes:
> >  * Several cleanups for sm501 from Peter Maydell
> >  * An update to the SLOF guest firmware
> >  * Improved handling of hotplug failures in spapr, associated cleanups
> >to the hotplug handling code
> >  * Several etsec fixes and cleanups from Bin Meng
> >  * Assorted other fixes and cleanups
> >
> > 
> > Alexey Kardashevskiy (1):
> >   pseries: Update SLOF firmware image
> >
> > Bin Meng (2):
> >   hw/net: fsl_etsec: Fix build error when HEX_DUMP is on
> >   hw/ppc: e500: Add missing  in the eTSEC node
> 
> It seems the following patch was missing?
> http://patchwork.ozlabs.org/project/qemu-devel/patch/1613660319-76960-1-git-send-email-bmeng...@gmail.com/

Huh, sorry.  I don't know how that dropped out of my tree.

I don't really want to delay this batch, so can you resend please, and
I'll include it in the next batch.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH 6/7] mac_via: fix 60Hz VIA1 timer interval

2021-03-10 Thread BALATON Zoltan

On Wed, 10 Mar 2021, Mark Cave-Ayland wrote:

On 10/03/2021 13:24, Laurent Vivier wrote:

Le 10/03/2021 à 14:10, Laurent Vivier a écrit :

Le 10/03/2021 à 13:56, Laurent Vivier a écrit :

Le 10/03/2021 à 13:32, BALATON Zoltan a écrit :

On Wed, 10 Mar 2021, Mark Cave-Ayland wrote:
The 60Hz timer is initialised using timer_new_ns() meaning that the 
timer
interval should be measured in ns, and therefore its period is a 
thousand

times too short.

Signed-off-by: Mark Cave-Ayland 
---
hw/misc/mac_via.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index f994fefa7c..c6e1552a59 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -302,8 +302,8 @@ static void 
via1_sixty_hz_update(MOS6522Q800VIA1State *v1s)

     MOS6522State *s = MOS6522(v1s);

     /* 60 Hz irq */
-    v1s->next_sixty_hz = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 
16630) /

-  16630 * 16630;
+    v1s->next_sixty_hz = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 
1663) /

+  1663 * 1663;


Can you put this magic number in a #define maybe also rewriting it in a 
way that shows it
corresponds to a 60 Hz interval. (There's NANOSECONDS_PER_SECOND defined 
in include/qemu/timer.h
that could be used for that, there's also SCALE_MS that might replace 
1000 * 1000 elsewhere in this
file). Also NANOSECONDS_PER_SECOND / 60 is 1666, should that value 
be used here instead?


In fact, the Mac Frequency is not exactly 60 Hz, in docs we can find 
60.147 Hz, in kernel 60.15 Hz.

I Think there are several ways to compute it...



In fact, we can read:

"the vertical retrace frequency is approximately 60.15 Hz, resulting in a 
period of approximately

16.63 milliseconds"

https://developer.apple.com/library/archive/documentation/mac/pdf/Processes/Vertical_Retrace_Mgr.pdf


The exact value is 16625800 ns

"Macintosh Family Hardware Reference" ISBN 0-201-19255-1
"The video interface"
p. 13-3

"[...] This means the full frame is redisplayed every 370 scan lines, or 
once every 166625.8 µs."


Thanks Laurent! Given that the exact precision is 6 digits I don't think it's 
possible to make use of conversion macros without either making it harder to 
read or reducing the precision.


I think the best solution here would be to #define VIA1_60HZ_TIMER_PERIOD_NS 
with a comment containing the above reference, and use that in the period 
calculation. Would that be sufficient?


Yes, I think that would make this a lot clearer than having this number 
without explanation so that would be sufficient.


Is this referred to as 60Hz timer in the hardware docs? Because that name 
is a bit misleading when it's actually not exactly 60Hz. But in the 
previous patch VBlank which this was called before was also found 
misleading so I can't think of a better name. Not sure if calling it 
compat_vblank would be too verbose or any better. Maybe you can just add a 
comment explaining what this is somewhere where it's defined or near the 
update function and then it does not matter what you call it, the comment 
should explain why it's not quite sixty_hz. I'm also OK with calling it 
sixty_hz just though if there's a way to give it a less confusing name you 
could consider that but I don't have a better name either so feel free to 
ignore this.


Regards,
BALATON Zoltan

[PATCH 03/26] meson: Split out fpu/meson.build

2021-03-10 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 meson.build | 4 +---
 fpu/meson.build | 1 +
 2 files changed, 2 insertions(+), 3 deletions(-)
 create mode 100644 fpu/meson.build

diff --git a/meson.build b/meson.build
index f884a62682..c8a5ca65e5 100644
--- a/meson.build
+++ b/meson.build
@@ -1934,9 +1934,6 @@ subdir('softmmu')
 common_ss.add(capstone)
 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
 specific_ss.add(files('exec-vary.c'))
-specific_ss.add(when: 'CONFIG_TCG', if_true: files(
-  'fpu/softfloat.c',
-))
 
 subdir('backends')
 subdir('disas')
@@ -1946,6 +1943,7 @@ subdir('net')
 subdir('replay')
 subdir('hw')
 subdir('tcg')
+subdir('fpu')
 subdir('accel')
 subdir('plugins')
 subdir('bsd-user')
diff --git a/fpu/meson.build b/fpu/meson.build
new file mode 100644
index 00..1a9992ded5
--- /dev/null
+++ b/fpu/meson.build
@@ -0,0 +1 @@
+specific_ss.add(when: 'CONFIG_TCG', if_true: files('softfloat.c'))
-- 
2.25.1




[PATCH 04/26] tcg: Re-order tcg_region_init vs tcg_prologue_init

2021-03-10 Thread Richard Henderson
Instead of delaying tcg_region_init until after tcg_prologue_init
is complete, do tcg_region_init first and let tcg_prologue_init
shrink the first region by the size of the generated prologue.

Signed-off-by: Richard Henderson 
---
 accel/tcg/tcg-all.c   | 11 -
 accel/tcg/translate-all.c |  3 +++
 bsd-user/main.c   |  1 -
 linux-user/main.c |  1 -
 tcg/tcg.c | 52 ++-
 5 files changed, 22 insertions(+), 46 deletions(-)

diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index e378c2db73..f132033999 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -111,17 +111,6 @@ static int tcg_init(MachineState *ms)
 
 tcg_exec_init(s->tb_size * 1024 * 1024, s->splitwx_enabled);
 mttcg_enabled = s->mttcg_enabled;
-
-/*
- * Initialize TCG regions only for softmmu.
- *
- * This needs to be done later for user mode, because the prologue
- * generation needs to be delayed so that GUEST_BASE is already set.
- */
-#ifndef CONFIG_USER_ONLY
-tcg_region_init();
-#endif /* !CONFIG_USER_ONLY */
-
 return 0;
 }
 
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index f32df8b240..b9057567f4 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1339,6 +1339,9 @@ void tcg_exec_init(unsigned long tb_size, int splitwx)
splitwx, &error_fatal);
 assert(ok);
 
+/* TODO: allocating regions is hand-in-glove with code_gen_buffer. */
+tcg_region_init();
+
 #if defined(CONFIG_SOFTMMU)
 /* There's no guest base to take into account, so go ahead and
initialize the prologue now.  */
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 798aba512c..3669d2b89e 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -994,7 +994,6 @@ int main(int argc, char **argv)
generating the prologue until now so that the prologue can take
the real value of GUEST_BASE into account.  */
 tcg_prologue_init(tcg_ctx);
-tcg_region_init();
 
 /* build Task State */
 memset(ts, 0, sizeof(TaskState));
diff --git a/linux-user/main.c b/linux-user/main.c
index 4f4746dce8..1bc48ca954 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -850,7 +850,6 @@ int main(int argc, char **argv, char **envp)
generating the prologue until now so that the prologue can take
the real value of GUEST_BASE into account.  */
 tcg_prologue_init(tcg_ctx);
-tcg_region_init();
 
 target_cpu_copy_regs(env, regs);
 
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 2991112829..0a2e5710de 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1204,32 +1204,18 @@ TranslationBlock *tcg_tb_alloc(TCGContext *s)
 
 void tcg_prologue_init(TCGContext *s)
 {
-size_t prologue_size, total_size;
-void *buf0, *buf1;
+size_t prologue_size;
 
 /* Put the prologue at the beginning of code_gen_buffer.  */
-buf0 = s->code_gen_buffer;
-total_size = s->code_gen_buffer_size;
-s->code_ptr = buf0;
-s->code_buf = buf0;
+tcg_region_assign(s, 0);
+s->code_ptr = s->code_gen_ptr;
+s->code_buf = s->code_gen_ptr;
 s->data_gen_ptr = NULL;
 
-/*
- * The region trees are not yet configured, but tcg_splitwx_to_rx
- * needs the bounds for an assert.
- */
-region.start = buf0;
-region.end = buf0 + total_size;
-
 #ifndef CONFIG_TCG_INTERPRETER
-tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(buf0);
+tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(s->code_ptr);
 #endif
 
-/* Compute a high-water mark, at which we voluntarily flush the buffer
-   and start over.  The size here is arbitrary, significantly larger
-   than we expect the code generation for any one opcode to require.  */
-s->code_gen_highwater = s->code_gen_buffer + (total_size - TCG_HIGHWATER);
-
 #ifdef TCG_TARGET_NEED_POOL_LABELS
 s->pool_labels = NULL;
 #endif
@@ -1246,32 +1232,32 @@ void tcg_prologue_init(TCGContext *s)
 }
 #endif
 
-buf1 = s->code_ptr;
+prologue_size = tcg_current_code_size(s);
+
 #ifndef CONFIG_TCG_INTERPRETER
-flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(buf0), (uintptr_t)buf0,
-tcg_ptr_byte_diff(buf1, buf0));
+flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf),
+(uintptr_t)s->code_buf, prologue_size);
 #endif
 
-/* Deduct the prologue from the buffer.  */
-prologue_size = tcg_current_code_size(s);
-s->code_gen_ptr = buf1;
-s->code_gen_buffer = buf1;
-s->code_buf = buf1;
-total_size -= prologue_size;
-s->code_gen_buffer_size = total_size;
+/* Deduct the prologue from the first region.  */
+region.start = s->code_ptr;
 
-tcg_register_jit(tcg_splitwx_to_rx(s->code_gen_buffer), total_size);
+/* Recompute boundaries of the first region. */
+tcg_region_assign(s, 0);
+
+tcg_register_jit(tcg_splitwx_to_rx(region.start),
+ regi

[PATCH 00/26] tcg: Workaround macOS 11.2 mprotect bug

2021-03-10 Thread Richard Henderson
Supercedes: 20210210105527.74943-1-r.bolsha...@yadro.com
("util/osdep: Avoid mprotect() RWX->NONE on Big Sur 11.2")

It took a few more patches than imagined to unify the two
places in which we manipulate the tcg code_gen buffer, but
the result is surely cleaner.

There's a lot more that could be done to clean up this part
of tcg too.  I tried to not get too side-tracked, but didn't
wholly succeed.


r~


Richard Henderson (26):
  meson: Split out tcg/meson.build
  meson: Move disas/tci.c to disas/meson.build
  meson: Split out fpu/meson.build
  tcg: Re-order tcg_region_init vs tcg_prologue_init
  tcg: Remove error return from tcg_region_initial_alloc__locked
  tcg: Split out tcg_region_initial_alloc
  tcg: Split out tcg_region_prologue_set
  tcg: Split out region.c
  accel/tcg: Inline cpu_gen_init
  accel/tcg: Move alloc_code_gen_buffer to tcg/region.c
  accel/tcg: Rename tcg_init to tcg_init_machine
  tcg: Create tcg_init
  accel/tcg: Merge tcg_exec_init into tcg_init_machine
  accel/tcg: Pass down max_cpus to tcg_init
  tcg: Introduce tcg_max_ctxs
  tcg: Move MAX_CODE_GEN_BUFFER_SIZE to tcg-target.h
  tcg: Replace region.end with region.total_size
  tcg: Tidy tcg_n_regions
  tcg: Tidy split_cross_256mb
  tcg: Allocate code_gen_buffer into struct tcg_region_state
  tcg: Return the map protection from alloc_code_gen_buffer
  tcg: Sink qemu_madvise call to common code
  tcg: Do not set guard pages in the rx buffer
  util/osdep: Add qemu_mprotect_rw
  tcg: Merge buffer protection and guard page protection
  tcg: When allocating for !splitwx, begin with PROT_NONE

 meson.build   |  12 +-
 accel/tcg/internal.h  |   2 +
 include/qemu/osdep.h  |   1 +
 include/sysemu/tcg.h  |   2 -
 include/tcg/tcg.h |   3 +-
 tcg/aarch64/tcg-target.h  |   1 +
 tcg/arm/tcg-target.h  |   1 +
 tcg/i386/tcg-target.h |   2 +
 tcg/internal.h|  39 ++
 tcg/mips/tcg-target.h |   6 +
 tcg/ppc/tcg-target.h  |   2 +
 tcg/riscv/tcg-target.h|   1 +
 tcg/s390/tcg-target.h |   3 +
 tcg/sparc/tcg-target.h|   1 +
 tcg/tci/tcg-target.h  |   1 +
 accel/tcg/tcg-all.c   |  33 +-
 accel/tcg/translate-all.c | 436 +
 bsd-user/main.c   |   1 -
 linux-user/main.c |   1 -
 tcg/region.c  | 959 ++
 tcg/tcg.c | 610 ++--
 util/osdep.c  |   9 +
 disas/meson.build |   2 +
 fpu/meson.build   |   1 +
 tcg/meson.build   |  14 +
 25 files changed, 1104 insertions(+), 1039 deletions(-)
 create mode 100644 tcg/internal.h
 create mode 100644 tcg/region.c
 create mode 100644 fpu/meson.build
 create mode 100644 tcg/meson.build

-- 
2.25.1




[PATCH 05/26] tcg: Remove error return from tcg_region_initial_alloc__locked

2021-03-10 Thread Richard Henderson
All callers immediately assert on error, so move the assert
into the function itself.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 19 ++-
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 0a2e5710de..2b631fccdf 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -720,9 +720,10 @@ static bool tcg_region_alloc(TCGContext *s)
  * Perform a context's first region allocation.
  * This function does _not_ increment region.agg_size_full.
  */
-static inline bool tcg_region_initial_alloc__locked(TCGContext *s)
+static void tcg_region_initial_alloc__locked(TCGContext *s)
 {
-return tcg_region_alloc__locked(s);
+bool err = tcg_region_alloc__locked(s);
+g_assert(!err);
 }
 
 /* Call from a safe-work context */
@@ -737,9 +738,7 @@ void tcg_region_reset_all(void)
 
 for (i = 0; i < n_ctxs; i++) {
 TCGContext *s = qatomic_read(&tcg_ctxs[i]);
-bool err = tcg_region_initial_alloc__locked(s);
-
-g_assert(!err);
+tcg_region_initial_alloc__locked(s);
 }
 qemu_mutex_unlock(®ion.lock);
 
@@ -874,11 +873,7 @@ void tcg_region_init(void)
 
 /* In user-mode we support only one ctx, so do the initial allocation now 
*/
 #ifdef CONFIG_USER_ONLY
-{
-bool err = tcg_region_initial_alloc__locked(tcg_ctx);
-
-g_assert(!err);
-}
+tcg_region_initial_alloc__locked(tcg_ctx);
 #endif
 }
 
@@ -940,7 +935,6 @@ void tcg_register_thread(void)
 MachineState *ms = MACHINE(qdev_get_machine());
 TCGContext *s = g_malloc(sizeof(*s));
 unsigned int i, n;
-bool err;
 
 *s = tcg_init_ctx;
 
@@ -964,8 +958,7 @@ void tcg_register_thread(void)
 
 tcg_ctx = s;
 qemu_mutex_lock(®ion.lock);
-err = tcg_region_initial_alloc__locked(tcg_ctx);
-g_assert(!err);
+tcg_region_initial_alloc__locked(s);
 qemu_mutex_unlock(®ion.lock);
 }
 #endif /* !CONFIG_USER_ONLY */
-- 
2.25.1




[PATCH 09/26] accel/tcg: Inline cpu_gen_init

2021-03-10 Thread Richard Henderson
It consists of one function call and has only one caller.

Signed-off-by: Richard Henderson 
---
 accel/tcg/translate-all.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index b9057567f4..6d3184e7da 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -245,11 +245,6 @@ static void page_table_config_init(void)
 assert(v_l2_levels >= 0);
 }
 
-static void cpu_gen_init(void)
-{
-tcg_context_init(&tcg_init_ctx);
-}
-
 /* Encode VAL as a signed leb128 sequence at P.
Return P incremented past the encoded value.  */
 static uint8_t *encode_sleb128(uint8_t *p, target_long val)
@@ -1331,7 +1326,7 @@ void tcg_exec_init(unsigned long tb_size, int splitwx)
 bool ok;
 
 tcg_allowed = true;
-cpu_gen_init();
+tcg_context_init(&tcg_init_ctx);
 page_init();
 tb_htable_init();
 
-- 
2.25.1




[PATCH 01/26] meson: Split out tcg/meson.build

2021-03-10 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 meson.build |  9 ++---
 tcg/meson.build | 13 +
 2 files changed, 15 insertions(+), 7 deletions(-)
 create mode 100644 tcg/meson.build

diff --git a/meson.build b/meson.build
index adeec153d9..8bc472ddeb 100644
--- a/meson.build
+++ b/meson.build
@@ -1936,14 +1936,8 @@ specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), 
capstone)
 specific_ss.add(files('exec-vary.c'))
 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
   'fpu/softfloat.c',
-  'tcg/optimize.c',
-  'tcg/tcg-common.c',
-  'tcg/tcg-op-gvec.c',
-  'tcg/tcg-op-vec.c',
-  'tcg/tcg-op.c',
-  'tcg/tcg.c',
 ))
-specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 
'tcg/tci.c'))
+specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c'))
 
 subdir('backends')
 subdir('disas')
@@ -1952,6 +1946,7 @@ subdir('monitor')
 subdir('net')
 subdir('replay')
 subdir('hw')
+subdir('tcg')
 subdir('accel')
 subdir('plugins')
 subdir('bsd-user')
diff --git a/tcg/meson.build b/tcg/meson.build
new file mode 100644
index 00..84064a341e
--- /dev/null
+++ b/tcg/meson.build
@@ -0,0 +1,13 @@
+tcg_ss = ss.source_set()
+
+tcg_ss.add(files(
+  'optimize.c',
+  'tcg.c',
+  'tcg-common.c',
+  'tcg-op.c',
+  'tcg-op-gvec.c',
+  'tcg-op-vec.c',
+))
+tcg_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('tci.c'))
+
+specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
-- 
2.25.1




[PATCH 02/26] meson: Move disas/tci.c to disas/meson.build

2021-03-10 Thread Richard Henderson
There's no reason to do this in the main meson.build.

Signed-off-by: Richard Henderson 
---
 meson.build   | 1 -
 disas/meson.build | 2 ++
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 8bc472ddeb..f884a62682 100644
--- a/meson.build
+++ b/meson.build
@@ -1937,7 +1937,6 @@ specific_ss.add(files('exec-vary.c'))
 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
   'fpu/softfloat.c',
 ))
-specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c'))
 
 subdir('backends')
 subdir('disas')
diff --git a/disas/meson.build b/disas/meson.build
index 4c8da01877..b7b659bf88 100644
--- a/disas/meson.build
+++ b/disas/meson.build
@@ -23,3 +23,5 @@ common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
 common_ss.add(when: 'CONFIG_SPARC_DIS', if_true: files('sparc.c'))
 common_ss.add(when: 'CONFIG_XTENSA_DIS', if_true: files('xtensa.c'))
 common_ss.add(when: capstone, if_true: files('capstone.c'))
+
+specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('tci.c'))
-- 
2.25.1




[PATCH 08/26] tcg: Split out region.c

2021-03-10 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/internal.h  |  37 
 tcg/region.c| 570 
 tcg/tcg.c   | 545 +
 tcg/meson.build |   1 +
 4 files changed, 611 insertions(+), 542 deletions(-)
 create mode 100644 tcg/internal.h
 create mode 100644 tcg/region.c

diff --git a/tcg/internal.h b/tcg/internal.h
new file mode 100644
index 00..b1dda343c2
--- /dev/null
+++ b/tcg/internal.h
@@ -0,0 +1,37 @@
+/*
+ * Internal declarations for Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef TCG_INTERNAL_H
+#define TCG_INTERNAL_H 1
+
+#define TCG_HIGHWATER 1024
+
+extern TCGContext **tcg_ctxs;
+extern unsigned int n_tcg_ctxs;
+
+bool tcg_region_alloc(TCGContext *s);
+void tcg_region_initial_alloc(TCGContext *s);
+void tcg_region_prologue_set(TCGContext *s);
+
+#endif /* TCG_INTERNAL_H */
diff --git a/tcg/region.c b/tcg/region.c
new file mode 100644
index 00..af45a0174e
--- /dev/null
+++ b/tcg/region.c
@@ -0,0 +1,570 @@
+/*
+ * Memory region management for Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "exec/exec-all.h"
+#include "tcg/tcg.h"
+#if !defined(CONFIG_USER_ONLY)
+#include "hw/boards.h"
+#endif
+#include "internal.h"
+
+
+struct tcg_region_tree {
+QemuMutex lock;
+GTree *tree;
+/* padding to avoid false sharing is computed at run-time */
+};
+
+/*
+ * We divide code_gen_buffer into equally-sized "regions" that TCG threads
+ * dynamically allocate from as demand dictates. Given appropriate region
+ * sizing, this minimizes flushes even when some TCG threads generate a lot
+ * more code than others.
+ */
+struct tcg_region_state {
+QemuMutex lock;
+
+/* fields set at init time */
+void *start;
+void *start_aligned;
+void *end;
+size_t n;
+size_t size; /* size of one region */
+size_t stride; /* .size + guard size */
+
+/* fields protected by the lock */
+size_t current; /* current region index */
+size_t agg_size_full; /* aggregate size of full regions */
+};
+
+static struct tcg_region_state region;
+
+/*
+ * This is an array of struct tcg_region_tree's, with padding.
+ * We use void * to simplify the computation of region_trees[i]; each
+ * struct is found every tree_size bytes.
+ */
+static void *region_trees;
+static size_t tree_size;
+
+/* compare a pointer @ptr and a tb_tc @s */
+static int ptr_cmp_tb_tc(const void *ptr, const struct tb_tc *s)
+{
+if (ptr >= s->ptr + s->size) {
+return 1;
+} else if (ptr < s->ptr) {
+return -1;
+}
+return 0;
+}
+
+static gint tb_tc_cmp(gconstpointer ap, gconstpointer bp)
+{
+const struct tb_tc *a = ap;
+const struct tb_t

[PATCH 10/26] accel/tcg: Move alloc_code_gen_buffer to tcg/region.c

2021-03-10 Thread Richard Henderson
Buffer management is integral to tcg.  Do not leave the allocation
to code outside of tcg/.  This is code movement, with further
cleanups to follow.

Signed-off-by: Richard Henderson 
---
 include/tcg/tcg.h |   2 +-
 accel/tcg/translate-all.c | 414 +
 tcg/region.c  | 421 +-
 3 files changed, 418 insertions(+), 419 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 0f0695e90d..7a435bf807 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -874,7 +874,7 @@ void *tcg_malloc_internal(TCGContext *s, int size);
 void tcg_pool_reset(TCGContext *s);
 TranslationBlock *tcg_tb_alloc(TCGContext *s);
 
-void tcg_region_init(void);
+void tcg_region_init(size_t tb_size, int splitwx);
 void tb_destroy(TranslationBlock *tb);
 void tcg_region_reset_all(void);
 
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 6d3184e7da..4071edda16 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -18,7 +18,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu/units.h"
 #include "qemu-common.h"
 
 #define NO_CPU_IO_DEFS
@@ -51,7 +50,6 @@
 #include "exec/tb-hash.h"
 #include "exec/translate-all.h"
 #include "qemu/bitmap.h"
-#include "qemu/error-report.h"
 #include "qemu/qemu-print.h"
 #include "qemu/timer.h"
 #include "qemu/main-loop.h"
@@ -895,408 +893,6 @@ static void page_lock_pair(PageDesc **ret_p1, 
tb_page_addr_t phys1,
 }
 }
 
-/* Minimum size of the code gen buffer.  This number is randomly chosen,
-   but not so small that we can't have a fair number of TB's live.  */
-#define MIN_CODE_GEN_BUFFER_SIZE (1 * MiB)
-
-/* Maximum size of the code gen buffer we'd like to use.  Unless otherwise
-   indicated, this is constrained by the range of direct branches on the
-   host cpu, as used by the TCG implementation of goto_tb.  */
-#if defined(__x86_64__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
-#elif defined(__sparc__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
-#elif defined(__powerpc64__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
-#elif defined(__powerpc__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (32 * MiB)
-#elif defined(__aarch64__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
-#elif defined(__s390x__)
-  /* We have a +- 4GB range on the branches; leave some slop.  */
-# define MAX_CODE_GEN_BUFFER_SIZE  (3 * GiB)
-#elif defined(__mips__)
-  /* We have a 256MB branch region, but leave room to make sure the
- main executable is also within that region.  */
-# define MAX_CODE_GEN_BUFFER_SIZE  (128 * MiB)
-#else
-# define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)
-#endif
-
-#if TCG_TARGET_REG_BITS == 32
-#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (32 * MiB)
-#ifdef CONFIG_USER_ONLY
-/*
- * For user mode on smaller 32 bit systems we may run into trouble
- * allocating big chunks of data in the right place. On these systems
- * we utilise a static code generation buffer directly in the binary.
- */
-#define USE_STATIC_CODE_GEN_BUFFER
-#endif
-#else /* TCG_TARGET_REG_BITS == 64 */
-#ifdef CONFIG_USER_ONLY
-/*
- * As user-mode emulation typically means running multiple instances
- * of the translator don't go too nuts with our default code gen
- * buffer lest we make things too hard for the OS.
- */
-#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (128 * MiB)
-#else
-/*
- * We expect most system emulation to run one or two guests per host.
- * Users running large scale system emulation may want to tweak their
- * runtime setup via the tb-size control on the command line.
- */
-#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (1 * GiB)
-#endif
-#endif
-
-#define DEFAULT_CODE_GEN_BUFFER_SIZE \
-  (DEFAULT_CODE_GEN_BUFFER_SIZE_1 < MAX_CODE_GEN_BUFFER_SIZE \
-   ? DEFAULT_CODE_GEN_BUFFER_SIZE_1 : MAX_CODE_GEN_BUFFER_SIZE)
-
-static size_t size_code_gen_buffer(size_t tb_size)
-{
-/* Size the buffer.  */
-if (tb_size == 0) {
-size_t phys_mem = qemu_get_host_physmem();
-if (phys_mem == 0) {
-tb_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
-} else {
-tb_size = MIN(DEFAULT_CODE_GEN_BUFFER_SIZE, phys_mem / 8);
-}
-}
-if (tb_size < MIN_CODE_GEN_BUFFER_SIZE) {
-tb_size = MIN_CODE_GEN_BUFFER_SIZE;
-}
-if (tb_size > MAX_CODE_GEN_BUFFER_SIZE) {
-tb_size = MAX_CODE_GEN_BUFFER_SIZE;
-}
-return tb_size;
-}
-
-#ifdef __mips__
-/* In order to use J and JAL within the code_gen_buffer, we require
-   that the buffer not cross a 256MB boundary.  */
-static inline bool cross_256mb(void *addr, size_t size)
-{
-return ((uintptr_t)addr ^ ((uintptr_t)addr + size)) & ~0x0ffful;
-}
-
-/* We weren't able to allocate a buffer without crossing that boundary,
-   so make do with the larger portion of the buffer that doesn't cross.
-   Returns the new base of the buffer, and adjusts code_gen_buffer_size.  */
-static inline void *split_cross_256mb(void *buf1, size_t size1)
-{
-void *buf2 = (void *)(((uintptr_t)buf

[PATCH 13/26] accel/tcg: Merge tcg_exec_init into tcg_init_machine

2021-03-10 Thread Richard Henderson
There is only one caller, and shortly we will need access
to the MachineState, which tcg_init_machine already has.

Signed-off-by: Richard Henderson 
---
 accel/tcg/internal.h  |  2 ++
 include/sysemu/tcg.h  |  2 --
 accel/tcg/tcg-all.c   | 14 +-
 accel/tcg/translate-all.c | 21 ++---
 4 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
index e9c145e0fb..881bc1ede0 100644
--- a/accel/tcg/internal.h
+++ b/accel/tcg/internal.h
@@ -16,5 +16,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc,
   int cflags);
 
 void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
+void page_init(void);
+void tb_htable_init(void);
 
 #endif /* ACCEL_TCG_INTERNAL_H */
diff --git a/include/sysemu/tcg.h b/include/sysemu/tcg.h
index 00349fb18a..53352450ff 100644
--- a/include/sysemu/tcg.h
+++ b/include/sysemu/tcg.h
@@ -8,8 +8,6 @@
 #ifndef SYSEMU_TCG_H
 #define SYSEMU_TCG_H
 
-void tcg_exec_init(unsigned long tb_size, int splitwx);
-
 #ifdef CONFIG_TCG
 extern bool tcg_allowed;
 #define tcg_enabled() (tcg_allowed)
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 30d81ff7f5..0e83acbfe5 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -32,6 +32,7 @@
 #include "qemu/error-report.h"
 #include "qemu/accel.h"
 #include "qapi/qapi-builtin-visit.h"
+#include "internal.h"
 
 struct TCGState {
 AccelState parent_obj;
@@ -109,8 +110,19 @@ static int tcg_init_machine(MachineState *ms)
 {
 TCGState *s = TCG_STATE(current_accel());
 
-tcg_exec_init(s->tb_size * 1024 * 1024, s->splitwx_enabled);
+tcg_allowed = true;
 mttcg_enabled = s->mttcg_enabled;
+
+page_init();
+tb_htable_init();
+tcg_init(s->tb_size * 1024 * 1024, s->splitwx_enabled);
+
+#if defined(CONFIG_SOFTMMU)
+/* There's no guest base to take into account, so go ahead and
+   initialize the prologue now.  */
+tcg_prologue_init(tcg_ctx);
+#endif
+
 return 0;
 }
 
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 050b4bff46..40aeecf611 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -408,7 +408,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, 
bool will_exit)
 return false;
 }
 
-static void page_init(void)
+void page_init(void)
 {
 page_size_init();
 page_table_config_init();
@@ -907,30 +907,13 @@ static bool tb_cmp(const void *ap, const void *bp)
 a->page_addr[1] == b->page_addr[1];
 }
 
-static void tb_htable_init(void)
+void tb_htable_init(void)
 {
 unsigned int mode = QHT_MODE_AUTO_RESIZE;
 
 qht_init(&tb_ctx.htable, tb_cmp, CODE_GEN_HTABLE_SIZE, mode);
 }
 
-/* Must be called before using the QEMU cpus. 'tb_size' is the size
-   (in bytes) allocated to the translation buffer. Zero means default
-   size. */
-void tcg_exec_init(unsigned long tb_size, int splitwx)
-{
-tcg_allowed = true;
-page_init();
-tb_htable_init();
-tcg_init(tb_size, splitwx);
-
-#if defined(CONFIG_SOFTMMU)
-/* There's no guest base to take into account, so go ahead and
-   initialize the prologue now.  */
-tcg_prologue_init(tcg_ctx);
-#endif
-}
-
 /* call with @p->lock held */
 static inline void invalidate_page_bitmap(PageDesc *p)
 {
-- 
2.25.1




[PATCH 07/26] tcg: Split out tcg_region_prologue_set

2021-03-10 Thread Richard Henderson
This has only one user, but will make more sense after some
code motion.

Always leave the tcg_init_ctx initialized to the first region,
in preparation for tcg_prologue_init().  This also requires
that we don't re-allocate the region for the first cpu, lest
we hit the assertion for total number of regions allocated .

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 37 ++---
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 3316a22bde..5b3525d52a 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -880,10 +880,26 @@ void tcg_region_init(void)
 
 tcg_region_trees_init();
 
-/* In user-mode we support only one ctx, so do the initial allocation now 
*/
-#ifdef CONFIG_USER_ONLY
-tcg_region_initial_alloc__locked(tcg_ctx);
-#endif
+/*
+ * Leave the initial context initialized to the first region.
+ * This will be the context into which we generate the prologue.
+ * It is also the only context for CONFIG_USER_ONLY.
+ */
+tcg_region_initial_alloc__locked(&tcg_init_ctx);
+}
+
+static void tcg_region_prologue_set(TCGContext *s)
+{
+/* Deduct the prologue from the first region.  */
+g_assert(region.start == s->code_gen_buffer);
+region.start = s->code_ptr;
+
+/* Recompute boundaries of the first region. */
+tcg_region_assign(s, 0);
+
+/* Register the balance of the buffer with gdb. */
+tcg_register_jit(tcg_splitwx_to_rx(region.start),
+ region.end - region.start);
 }
 
 #ifdef CONFIG_DEBUG_TCG
@@ -963,10 +979,10 @@ void tcg_register_thread(void)
 
 if (n > 0) {
 alloc_tcg_plugin_context(s);
+tcg_region_initial_alloc(s);
 }
 
 tcg_ctx = s;
-tcg_region_initial_alloc(s);
 }
 #endif /* !CONFIG_USER_ONLY */
 
@@ -1206,8 +1222,6 @@ void tcg_prologue_init(TCGContext *s)
 {
 size_t prologue_size;
 
-/* Put the prologue at the beginning of code_gen_buffer.  */
-tcg_region_assign(s, 0);
 s->code_ptr = s->code_gen_ptr;
 s->code_buf = s->code_gen_ptr;
 s->data_gen_ptr = NULL;
@@ -1239,14 +1253,7 @@ void tcg_prologue_init(TCGContext *s)
 (uintptr_t)s->code_buf, prologue_size);
 #endif
 
-/* Deduct the prologue from the first region.  */
-region.start = s->code_ptr;
-
-/* Recompute boundaries of the first region. */
-tcg_region_assign(s, 0);
-
-tcg_register_jit(tcg_splitwx_to_rx(region.start),
- region.end - region.start);
+tcg_region_prologue_set(s);
 
 #ifdef DEBUG_DISAS
 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
-- 
2.25.1




[PATCH 14/26] accel/tcg: Pass down max_cpus to tcg_init

2021-03-10 Thread Richard Henderson
Start removing the include of hw/boards.h from tcg/.
Pass down the max_cpus value from tcg_init_machine,
where we have the MachineState already.

Signed-off-by: Richard Henderson 
---
 include/tcg/tcg.h   |  2 +-
 tcg/internal.h  |  2 +-
 accel/tcg/tcg-all.c | 10 +-
 tcg/region.c| 32 +++-
 tcg/tcg.c   | 10 --
 5 files changed, 26 insertions(+), 30 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 3ad77ec34d..a0122c0dd3 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -906,7 +906,7 @@ static inline void *tcg_malloc(int size)
 }
 }
 
-void tcg_init(size_t tb_size, int splitwx);
+void tcg_init(size_t tb_size, int splitwx, unsigned max_cpus);
 void tcg_register_thread(void);
 void tcg_prologue_init(TCGContext *s);
 void tcg_func_start(TCGContext *s);
diff --git a/tcg/internal.h b/tcg/internal.h
index f13c564d9b..fcfeca232f 100644
--- a/tcg/internal.h
+++ b/tcg/internal.h
@@ -30,7 +30,7 @@
 extern TCGContext **tcg_ctxs;
 extern unsigned int n_tcg_ctxs;
 
-void tcg_region_init(size_t tb_size, int splitwx);
+void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus);
 bool tcg_region_alloc(TCGContext *s);
 void tcg_region_initial_alloc(TCGContext *s);
 void tcg_region_prologue_set(TCGContext *s);
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 0e83acbfe5..d2f2ddb844 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -32,6 +32,9 @@
 #include "qemu/error-report.h"
 #include "qemu/accel.h"
 #include "qapi/qapi-builtin-visit.h"
+#if !defined(CONFIG_USER_ONLY)
+#include "hw/boards.h"
+#endif
 #include "internal.h"
 
 struct TCGState {
@@ -109,13 +112,18 @@ bool mttcg_enabled;
 static int tcg_init_machine(MachineState *ms)
 {
 TCGState *s = TCG_STATE(current_accel());
+#ifdef CONFIG_USER_ONLY
+unsigned max_cpus = 1;
+#else
+unsigned max_cpus = ms->smp.max_cpus;
+#endif
 
 tcg_allowed = true;
 mttcg_enabled = s->mttcg_enabled;
 
 page_init();
 tb_htable_init();
-tcg_init(s->tb_size * 1024 * 1024, s->splitwx_enabled);
+tcg_init(s->tb_size * 1024 * 1024, s->splitwx_enabled, max_cpus);
 
 #if defined(CONFIG_SOFTMMU)
 /* There's no guest base to take into account, so go ahead and
diff --git a/tcg/region.c b/tcg/region.c
index 8d88144a22..04b699da63 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -27,9 +27,6 @@
 #include "qapi/error.h"
 #include "exec/exec-all.h"
 #include "tcg/tcg.h"
-#if !defined(CONFIG_USER_ONLY)
-#include "hw/boards.h"
-#endif
 #include "internal.h"
 
 
@@ -366,27 +363,20 @@ void tcg_region_reset_all(void)
 tcg_region_tree_reset_all();
 }
 
+static size_t tcg_n_regions(unsigned max_cpus)
+{
 #ifdef CONFIG_USER_ONLY
-static size_t tcg_n_regions(void)
-{
 return 1;
-}
 #else
-/*
- * It is likely that some vCPUs will translate more code than others, so we
- * first try to set more regions than max_cpus, with those regions being of
- * reasonable size. If that's not possible we make do by evenly dividing
- * the code_gen_buffer among the vCPUs.
- */
-static size_t tcg_n_regions(void)
-{
+/*
+ * It is likely that some vCPUs will translate more code than others,
+ * so we first try to set more regions than max_cpus, with those regions
+ * being of reasonable size. If that's not possible we make do by evenly
+ * dividing the code_gen_buffer among the vCPUs.
+ */
 size_t i;
 
 /* Use a single region if all we have is one vCPU thread */
-#if !defined(CONFIG_USER_ONLY)
-MachineState *ms = MACHINE(qdev_get_machine());
-unsigned int max_cpus = ms->smp.max_cpus;
-#endif
 if (max_cpus == 1 || !qemu_tcg_mttcg_enabled()) {
 return 1;
 }
@@ -405,8 +395,8 @@ static size_t tcg_n_regions(void)
 }
 /* If we can't, then just allocate one region per vCPU thread */
 return max_cpus;
-}
 #endif
+}
 
 /* Minimum size of the code gen buffer.  This number is randomly chosen,
but not so small that we can't have a fair number of TB's live.  */
@@ -838,7 +828,7 @@ static bool alloc_code_gen_buffer(size_t size, int splitwx, 
Error **errp)
  * in practice. Multi-threaded guests share most if not all of their translated
  * code, which makes parallel code generation less appealing than in softmmu.
  */
-void tcg_region_init(size_t tb_size, int splitwx)
+void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus)
 {
 void *buf, *aligned;
 size_t size;
@@ -856,7 +846,7 @@ void tcg_region_init(size_t tb_size, int splitwx)
 buf = tcg_init_ctx.code_gen_buffer;
 size = tcg_init_ctx.code_gen_buffer_size;
 page_size = qemu_real_host_page_size;
-n_regions = tcg_n_regions();
+n_regions = tcg_n_regions(max_cpus);
 
 /* The first region will be 'aligned - buf' bytes larger than the others */
 aligned = QEMU_ALIGN_PTR_UP(buf, page_size);
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 65a63bda8a..a89d8f6b81 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -576,7 +576,7 @@ 

[PATCH 06/26] tcg: Split out tcg_region_initial_alloc

2021-03-10 Thread Richard Henderson
This has only one user, and currently needs an ifdef,
but will make more sense after some code motion.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 2b631fccdf..3316a22bde 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -726,6 +726,15 @@ static void tcg_region_initial_alloc__locked(TCGContext *s)
 g_assert(!err);
 }
 
+#ifndef CONFIG_USER_ONLY
+static void tcg_region_initial_alloc(TCGContext *s)
+{
+qemu_mutex_lock(®ion.lock);
+tcg_region_initial_alloc__locked(s);
+qemu_mutex_unlock(®ion.lock);
+}
+#endif
+
 /* Call from a safe-work context */
 void tcg_region_reset_all(void)
 {
@@ -957,9 +966,7 @@ void tcg_register_thread(void)
 }
 
 tcg_ctx = s;
-qemu_mutex_lock(®ion.lock);
-tcg_region_initial_alloc__locked(s);
-qemu_mutex_unlock(®ion.lock);
+tcg_region_initial_alloc(s);
 }
 #endif /* !CONFIG_USER_ONLY */
 
-- 
2.25.1




[PATCH 18/26] tcg: Tidy tcg_n_regions

2021-03-10 Thread Richard Henderson
Compute the value using straight division and bounds,
rather than a loop.  Pass in tb_size rather than reading
from tcg_init_ctx.code_gen_buffer_size,

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 29 -
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 7fb24f6b60..57017c1e80 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -363,38 +363,33 @@ void tcg_region_reset_all(void)
 tcg_region_tree_reset_all();
 }
 
-static size_t tcg_n_regions(unsigned max_cpus)
+static size_t tcg_n_regions(size_t tb_size, unsigned max_cpus)
 {
 #ifdef CONFIG_USER_ONLY
 return 1;
 #else
+size_t n_regions;
+
 /*
  * It is likely that some vCPUs will translate more code than others,
  * so we first try to set more regions than max_cpus, with those regions
  * being of reasonable size. If that's not possible we make do by evenly
  * dividing the code_gen_buffer among the vCPUs.
  */
-size_t i;
-
 /* Use a single region if all we have is one vCPU thread */
 if (max_cpus == 1 || !qemu_tcg_mttcg_enabled()) {
 return 1;
 }
 
-/* Try to have more regions than max_cpus, with each region being >= 2 MB 
*/
-for (i = 8; i > 0; i--) {
-size_t regions_per_thread = i;
-size_t region_size;
-
-region_size = tcg_init_ctx.code_gen_buffer_size;
-region_size /= max_cpus * regions_per_thread;
-
-if (region_size >= 2 * 1024u * 1024) {
-return max_cpus * regions_per_thread;
-}
+/*
+ * Try to have more regions than max_cpus, with each region being >= 2 MB.
+ * If we can't, then just allocate one region per vCPU thread.
+ */
+n_regions = tb_size / (2 * MiB);
+if (n_regions <= max_cpus) {
+return max_cpus;
 }
-/* If we can't, then just allocate one region per vCPU thread */
-return max_cpus;
+return MIN(n_regions, max_cpus * 8);
 #endif
 }
 
@@ -826,7 +821,7 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 buf = tcg_init_ctx.code_gen_buffer;
 total_size = tcg_init_ctx.code_gen_buffer_size;
 page_size = qemu_real_host_page_size;
-n_regions = tcg_n_regions(max_cpus);
+n_regions = tcg_n_regions(total_size, max_cpus);
 
 /* The first region will be 'aligned - buf' bytes larger than the others */
 aligned = QEMU_ALIGN_PTR_UP(buf, page_size);
-- 
2.25.1




[PATCH 20/26] tcg: Allocate code_gen_buffer into struct tcg_region_state

2021-03-10 Thread Richard Henderson
Do not mess around with setting values within tcg_init_ctx.
Put the values into 'region' directly, which is where they
will live for the lifetime of the program.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 61 ++--
 1 file changed, 26 insertions(+), 35 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index f719a3edf3..d7ad1be1f9 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -520,8 +520,8 @@ static bool alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 }
 qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
 
-tcg_ctx->code_gen_buffer = buf;
-tcg_ctx->code_gen_buffer_size = size;
+region.start_aligned = buf;
+region.total_size = size;
 return true;
 }
 #elif defined(_WIN32)
@@ -542,8 +542,8 @@ static bool alloc_code_gen_buffer(size_t size, int splitwx, 
Error **errp)
 return false;
 }
 
-tcg_ctx->code_gen_buffer = buf;
-tcg_ctx->code_gen_buffer_size = size;
+region.start_aligned = buf;
+region.total_size = size;
 return true;
 }
 #else
@@ -558,7 +558,6 @@ static bool alloc_code_gen_buffer_anon(size_t size, int 
prot,
  "allocate %zu bytes for jit buffer", size);
 return false;
 }
-tcg_ctx->code_gen_buffer_size = size;
 
 #ifdef __mips__
 if (cross_256mb(buf, size)) {
@@ -596,7 +595,8 @@ static bool alloc_code_gen_buffer_anon(size_t size, int 
prot,
 /* Request large pages for the buffer.  */
 qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
 
-tcg_ctx->code_gen_buffer = buf;
+region.start_aligned = buf;
+region.total_size = size;
 return true;
 }
 
@@ -617,8 +617,8 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 return false;
 }
 /* The size of the mapping may have been adjusted. */
-size = tcg_ctx->code_gen_buffer_size;
-buf_rx = tcg_ctx->code_gen_buffer;
+buf_rx = region.start_aligned;
+size = region.total_size;
 #endif
 
 buf_rw = qemu_memfd_alloc("tcg-jit", size, 0, &fd, errp);
@@ -640,8 +640,8 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 #endif
 
 close(fd);
-tcg_ctx->code_gen_buffer = buf_rw;
-tcg_ctx->code_gen_buffer_size = size;
+region.start_aligned = buf_rw;
+region.total_size = size;
 tcg_splitwx_diff = buf_rx - buf_rw;
 
 /* Request large pages for the buffer and the splitwx.  */
@@ -692,7 +692,7 @@ static bool alloc_code_gen_buffer_splitwx_vmremap(size_t 
size, Error **errp)
 return false;
 }
 
-buf_rw = (mach_vm_address_t)tcg_ctx->code_gen_buffer;
+buf_rw = region.start_aligned;
 buf_rx = 0;
 ret = mach_vm_remap(mach_task_self(),
 &buf_rx,
@@ -804,11 +804,8 @@ static bool alloc_code_gen_buffer(size_t size, int 
splitwx, Error **errp)
  */
 void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus)
 {
-void *buf, *aligned, *end;
-size_t total_size;
 size_t page_size;
 size_t region_size;
-size_t n_regions;
 size_t i;
 uintptr_t splitwx_diff;
 bool ok;
@@ -817,39 +814,33 @@ void tcg_region_init(size_t tb_size, int splitwx, 
unsigned max_cpus)
splitwx, &error_fatal);
 assert(ok);
 
-buf = tcg_init_ctx.code_gen_buffer;
-total_size = tcg_init_ctx.code_gen_buffer_size;
-page_size = qemu_real_host_page_size;
-n_regions = tcg_n_regions(total_size, max_cpus);
-
-/* The first region will be 'aligned - buf' bytes larger than the others */
-aligned = QEMU_ALIGN_PTR_UP(buf, page_size);
-g_assert(aligned < tcg_init_ctx.code_gen_buffer + total_size);
-
 /*
  * Make region_size a multiple of page_size, using aligned as the start.
  * As a result of this we might end up with a few extra pages at the end of
  * the buffer; we will assign those to the last region.
  */
-region_size = (total_size - (aligned - buf)) / n_regions;
+region.n = tcg_n_regions(region.total_size, max_cpus);
+page_size = qemu_real_host_page_size;
+region_size = region.total_size / region.n;
 region_size = QEMU_ALIGN_DOWN(region_size, page_size);
 
 /* A region must have at least 2 pages; one code, one guard */
 g_assert(region_size >= 2 * page_size);
+region.stride = region_size;
+
+/* Reserve space for guard pages. */
+region.size = region_size - page_size;
+region.total_size -= page_size;
+
+/*
+ * The first region will be smaller than the others, via the prologue,
+ * which has yet to be allocated.  For now, the first region begins at
+ * the page boundary.
+ */
+region.start = region.start_aligned;
 
 /* init the region struct */
 qemu_mutex_init(®ion.lock);
-region.n = n_regions;
-region.size = region_size - page_size;
-region.stride = region_size;
-region.start = buf;
-region.start_aligned = aligned;
-/* page-align the end, since its la

[PATCH 11/26] accel/tcg: Rename tcg_init to tcg_init_machine

2021-03-10 Thread Richard Henderson
We shortly want to use tcg_init for something else.
Since the hook is called init_machine, match that.

Signed-off-by: Richard Henderson 
---
 accel/tcg/tcg-all.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index f132033999..30d81ff7f5 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -105,7 +105,7 @@ static void tcg_accel_instance_init(Object *obj)
 
 bool mttcg_enabled;
 
-static int tcg_init(MachineState *ms)
+static int tcg_init_machine(MachineState *ms)
 {
 TCGState *s = TCG_STATE(current_accel());
 
@@ -189,7 +189,7 @@ static void tcg_accel_class_init(ObjectClass *oc, void 
*data)
 {
 AccelClass *ac = ACCEL_CLASS(oc);
 ac->name = "tcg";
-ac->init_machine = tcg_init;
+ac->init_machine = tcg_init_machine;
 ac->allowed = &tcg_allowed;
 
 object_class_property_add_str(oc, "thread",
-- 
2.25.1




[PATCH 17/26] tcg: Replace region.end with region.total_size

2021-03-10 Thread Richard Henderson
A size is easier to work with than an end point,
particularly during initial buffer allocation.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 29 +
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 8fba0724e5..7fb24f6b60 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -48,7 +48,7 @@ struct tcg_region_state {
 /* fields set at init time */
 void *start;
 void *start_aligned;
-void *end;
+size_t total_size; /* size of entire buffer */
 size_t n;
 size_t size; /* size of one region */
 size_t stride; /* .size + guard size */
@@ -279,7 +279,7 @@ static void tcg_region_bounds(size_t curr_region, void 
**pstart, void **pend)
 start = region.start;
 }
 if (curr_region == region.n - 1) {
-end = region.end;
+end = region.start_aligned + region.total_size;
 }
 
 *pstart = start;
@@ -810,8 +810,8 @@ static bool alloc_code_gen_buffer(size_t size, int splitwx, 
Error **errp)
  */
 void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus)
 {
-void *buf, *aligned;
-size_t size;
+void *buf, *aligned, *end;
+size_t total_size;
 size_t page_size;
 size_t region_size;
 size_t n_regions;
@@ -824,19 +824,20 @@ void tcg_region_init(size_t tb_size, int splitwx, 
unsigned max_cpus)
 assert(ok);
 
 buf = tcg_init_ctx.code_gen_buffer;
-size = tcg_init_ctx.code_gen_buffer_size;
+total_size = tcg_init_ctx.code_gen_buffer_size;
 page_size = qemu_real_host_page_size;
 n_regions = tcg_n_regions(max_cpus);
 
 /* The first region will be 'aligned - buf' bytes larger than the others */
 aligned = QEMU_ALIGN_PTR_UP(buf, page_size);
-g_assert(aligned < tcg_init_ctx.code_gen_buffer + size);
+g_assert(aligned < tcg_init_ctx.code_gen_buffer + total_size);
+
 /*
  * Make region_size a multiple of page_size, using aligned as the start.
  * As a result of this we might end up with a few extra pages at the end of
  * the buffer; we will assign those to the last region.
  */
-region_size = (size - (aligned - buf)) / n_regions;
+region_size = (total_size - (aligned - buf)) / n_regions;
 region_size = QEMU_ALIGN_DOWN(region_size, page_size);
 
 /* A region must have at least 2 pages; one code, one guard */
@@ -850,9 +851,11 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 region.start = buf;
 region.start_aligned = aligned;
 /* page-align the end, since its last page will be a guard page */
-region.end = QEMU_ALIGN_PTR_DOWN(buf + size, page_size);
+end = QEMU_ALIGN_PTR_DOWN(buf + total_size, page_size);
 /* account for that last guard page */
-region.end -= page_size;
+end -= page_size;
+total_size = end - aligned;
+region.total_size = total_size;
 
 /* set guard pages */
 splitwx_diff = tcg_splitwx_diff;
@@ -890,7 +893,7 @@ void tcg_region_prologue_set(TCGContext *s)
 
 /* Register the balance of the buffer with gdb. */
 tcg_register_jit(tcg_splitwx_to_rx(region.start),
- region.end - region.start);
+ region.start_aligned + region.total_size - region.start);
 }
 
 /*
@@ -931,8 +934,10 @@ size_t tcg_code_capacity(void)
 
 /* no need for synchronization; these variables are set at init time */
 guard_size = region.stride - region.size;
-capacity = region.end + guard_size - region.start;
-capacity -= region.n * (guard_size + TCG_HIGHWATER);
+capacity = region.total_size;
+capacity -= (region.n - 1) * guard_size;
+capacity -= region.n * TCG_HIGHWATER;
+
 return capacity;
 }
 
-- 
2.25.1




[PATCH 22/26] tcg: Sink qemu_madvise call to common code

2021-03-10 Thread Richard Henderson
Move the call out of the N versions of alloc_code_gen_buffer
and into tcg_region_init.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index f25ec1ecad..7640aac243 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -518,7 +518,6 @@ static int alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 error_setg_errno(errp, errno, "mprotect of jit buffer");
 return false;
 }
-qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
 
 region.start_aligned = buf;
 region.total_size = size;
@@ -594,9 +593,6 @@ static int alloc_code_gen_buffer_anon(size_t size, int prot,
 }
 #endif
 
-/* Request large pages for the buffer.  */
-qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
-
 region.start_aligned = buf;
 region.total_size = size;
 return prot;
@@ -646,9 +642,6 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 region.total_size = size;
 tcg_splitwx_diff = buf_rx - buf_rw;
 
-/* Request large pages for the buffer and the splitwx.  */
-qemu_madvise(buf_rw, size, QEMU_MADV_HUGEPAGE);
-qemu_madvise(buf_rx, size, QEMU_MADV_HUGEPAGE);
 return PROT_READ | PROT_WRITE;
 
  fail_rx:
@@ -817,6 +810,13 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
   splitwx, &error_fatal);
 assert(have_prot >= 0);
 
+/* Request large pages for the buffer and the splitwx.  */
+qemu_madvise(region.start_aligned, region.total_size, QEMU_MADV_HUGEPAGE);
+if (tcg_splitwx_diff) {
+qemu_madvise(region.start_aligned + tcg_splitwx_diff,
+ region.total_size, QEMU_MADV_HUGEPAGE);
+}
+
 /*
  * Make region_size a multiple of page_size, using aligned as the start.
  * As a result of this we might end up with a few extra pages at the end of
-- 
2.25.1




[PATCH 12/26] tcg: Create tcg_init

2021-03-10 Thread Richard Henderson
Perform both tcg_context_init and tcg_region_init.
Do not leave this split to the caller.

Signed-off-by: Richard Henderson 
---
 include/tcg/tcg.h | 3 +--
 tcg/internal.h| 1 +
 accel/tcg/translate-all.c | 3 +--
 tcg/tcg.c | 9 -
 4 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 7a435bf807..3ad77ec34d 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -874,7 +874,6 @@ void *tcg_malloc_internal(TCGContext *s, int size);
 void tcg_pool_reset(TCGContext *s);
 TranslationBlock *tcg_tb_alloc(TCGContext *s);
 
-void tcg_region_init(size_t tb_size, int splitwx);
 void tb_destroy(TranslationBlock *tb);
 void tcg_region_reset_all(void);
 
@@ -907,7 +906,7 @@ static inline void *tcg_malloc(int size)
 }
 }
 
-void tcg_context_init(TCGContext *s);
+void tcg_init(size_t tb_size, int splitwx);
 void tcg_register_thread(void);
 void tcg_prologue_init(TCGContext *s);
 void tcg_func_start(TCGContext *s);
diff --git a/tcg/internal.h b/tcg/internal.h
index b1dda343c2..f13c564d9b 100644
--- a/tcg/internal.h
+++ b/tcg/internal.h
@@ -30,6 +30,7 @@
 extern TCGContext **tcg_ctxs;
 extern unsigned int n_tcg_ctxs;
 
+void tcg_region_init(size_t tb_size, int splitwx);
 bool tcg_region_alloc(TCGContext *s);
 void tcg_region_initial_alloc(TCGContext *s);
 void tcg_region_prologue_set(TCGContext *s);
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 4071edda16..050b4bff46 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -920,10 +920,9 @@ static void tb_htable_init(void)
 void tcg_exec_init(unsigned long tb_size, int splitwx)
 {
 tcg_allowed = true;
-tcg_context_init(&tcg_init_ctx);
 page_init();
 tb_htable_init();
-tcg_region_init(tb_size, splitwx);
+tcg_init(tb_size, splitwx);
 
 #if defined(CONFIG_SOFTMMU)
 /* There's no guest base to take into account, so go ahead and
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 10a571d41c..65a63bda8a 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -576,8 +576,9 @@ static void process_op_defs(TCGContext *s);
 static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
 TCGReg reg, const char *name);
 
-void tcg_context_init(TCGContext *s)
+static void tcg_context_init(void)
 {
+TCGContext *s = &tcg_init_ctx;
 int op, total_args, n, i;
 TCGOpDef *def;
 TCGArgConstraint *args_ct;
@@ -654,6 +655,12 @@ void tcg_context_init(TCGContext *s)
 cpu_env = temp_tcgv_ptr(ts);
 }
 
+void tcg_init(size_t tb_size, int splitwx)
+{
+tcg_context_init();
+tcg_region_init(tb_size, splitwx);
+}
+
 /*
  * Allocate TBs right before their corresponding translated code, making
  * sure that TBs and code are on different cache lines.
-- 
2.25.1




[PATCH 16/26] tcg: Move MAX_CODE_GEN_BUFFER_SIZE to tcg-target.h

2021-03-10 Thread Richard Henderson
Remove the ifdef ladder and move each define into the
appropriate header file.

Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.h |  1 +
 tcg/arm/tcg-target.h |  1 +
 tcg/i386/tcg-target.h|  2 ++
 tcg/mips/tcg-target.h|  6 ++
 tcg/ppc/tcg-target.h |  2 ++
 tcg/riscv/tcg-target.h   |  1 +
 tcg/s390/tcg-target.h|  3 +++
 tcg/sparc/tcg-target.h   |  1 +
 tcg/tci/tcg-target.h |  1 +
 tcg/region.c | 32 ++--
 10 files changed, 24 insertions(+), 26 deletions(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 5ec30dba25..ef55f7c185 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -15,6 +15,7 @@
 
 #define TCG_TARGET_INSN_UNIT_SIZE  4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 24
+#define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
 #undef TCG_TARGET_STACK_GROWSUP
 
 typedef enum {
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 8d1fee6327..b9a85d0f83 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -60,6 +60,7 @@ extern int arm_arch;
 #undef TCG_TARGET_STACK_GROWSUP
 #define TCG_TARGET_INSN_UNIT_SIZE 4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 16
+#define MAX_CODE_GEN_BUFFER_SIZE  UINT32_MAX
 
 typedef enum {
 TCG_REG_R0 = 0,
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index b693d3692d..ac10066c3e 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -31,9 +31,11 @@
 #ifdef __x86_64__
 # define TCG_TARGET_REG_BITS  64
 # define TCG_TARGET_NB_REGS   32
+# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
 #else
 # define TCG_TARGET_REG_BITS  32
 # define TCG_TARGET_NB_REGS   24
+# define MAX_CODE_GEN_BUFFER_SIZE  UINT32_MAX
 #endif
 
 typedef enum {
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index c2c32fb38f..e81e824cab 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -39,6 +39,12 @@
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 16
 #define TCG_TARGET_NB_REGS 32
 
+/*
+ * We have a 256MB branch region, but leave room to make sure the
+ * main executable is also within that region.
+ */
+#define MAX_CODE_GEN_BUFFER_SIZE  (128 * MiB)
+
 typedef enum {
 TCG_REG_ZERO = 0,
 TCG_REG_AT,
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index d1339afc66..c13ed5640a 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -27,8 +27,10 @@
 
 #ifdef _ARCH_PPC64
 # define TCG_TARGET_REG_BITS  64
+# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
 #else
 # define TCG_TARGET_REG_BITS  32
+# define MAX_CODE_GEN_BUFFER_SIZE  (32 * MiB)
 #endif
 
 #define TCG_TARGET_NB_REGS 64
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 727c8df418..87ea94666b 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -34,6 +34,7 @@
 #define TCG_TARGET_INSN_UNIT_SIZE 4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 20
 #define TCG_TARGET_NB_REGS 32
+#define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)
 
 typedef enum {
 TCG_REG_ZERO,
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 641464eea4..b04b72b7eb 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -28,6 +28,9 @@
 #define TCG_TARGET_INSN_UNIT_SIZE 2
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 19
 
+/* We have a +- 4GB range on the branches; leave some slop.  */
+#define MAX_CODE_GEN_BUFFER_SIZE  (3 * GiB)
+
 typedef enum TCGReg {
 TCG_REG_R0 = 0,
 TCG_REG_R1,
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index f66f5d07dc..86bb9a2d39 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -30,6 +30,7 @@
 #define TCG_TARGET_INSN_UNIT_SIZE 4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
 #define TCG_TARGET_NB_REGS 32
+#define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
 
 typedef enum {
 TCG_REG_G0 = 0,
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 9c0021a26f..03cf527cb4 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -43,6 +43,7 @@
 #define TCG_TARGET_INTERPRETER 1
 #define TCG_TARGET_INSN_UNIT_SIZE 1
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
+#define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)
 
 #if UINTPTR_MAX == UINT32_MAX
 # define TCG_TARGET_REG_BITS 32
diff --git a/tcg/region.c b/tcg/region.c
index e3fbf6a7e7..8fba0724e5 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -398,34 +398,14 @@ static size_t tcg_n_regions(unsigned max_cpus)
 #endif
 }
 
-/* Minimum size of the code gen buffer.  This number is randomly chosen,
-   but not so small that we can't have a fair number of TB's live.  */
+/*
+ * Minimum size of the code gen buffer.  This number is randomly chosen,
+ * but not so small that we can't have a fair number of TB's live.
+ *
+ * Maximum size is defined in tcg-target.h.
+ */
 #define MIN_CODE_GEN_BUFFER_SIZE (1 * MiB)
 
-/* Maximum size of the code gen buffer we'd like to use.  Unless otherwise
-   indicated, this is constrained by the range of direct branches on the
-   host cpu, as used by the TCG implementation of goto_tb.  */
-#if defined(__

[PATCH 23/26] tcg: Do not set guard pages in the rx buffer

2021-03-10 Thread Richard Henderson
We only need guard pages in the rw buffer to avoid buffer overruns.
Let the rx buffer keep large pages all the way through.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 7640aac243..93d03076d1 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -803,7 +803,6 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 size_t page_size;
 size_t region_size;
 size_t i;
-uintptr_t splitwx_diff;
 int have_prot;
 
 have_prot = alloc_code_gen_buffer(size_code_gen_buffer(tb_size),
@@ -845,8 +844,7 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 /* init the region struct */
 qemu_mutex_init(®ion.lock);
 
-/* set guard pages */
-splitwx_diff = tcg_splitwx_diff;
+/* Set guard pages.  No need to do this for the rx_buf, only the rw_buf. */
 for (i = 0; i < region.n; i++) {
 void *start, *end;
 int rc;
@@ -854,10 +852,6 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 tcg_region_bounds(i, &start, &end);
 rc = qemu_mprotect_none(end, page_size);
 g_assert(!rc);
-if (splitwx_diff) {
-rc = qemu_mprotect_none(end + splitwx_diff, page_size);
-g_assert(!rc);
-}
 }
 
 tcg_region_trees_init();
-- 
2.25.1




[PATCH 19/26] tcg: Tidy split_cross_256mb

2021-03-10 Thread Richard Henderson
Return output buffer and size via output pointer arguments,
rather than returning size via tcg_ctx->code_gen_buffer_size.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 57017c1e80..f719a3edf3 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -464,7 +464,8 @@ static inline bool cross_256mb(void *addr, size_t size)
 /* We weren't able to allocate a buffer without crossing that boundary,
so make do with the larger portion of the buffer that doesn't cross.
Returns the new base of the buffer, and adjusts code_gen_buffer_size.  */
-static inline void *split_cross_256mb(void *buf1, size_t size1)
+static inline void split_cross_256mb(void **obuf, size_t *osize,
+ void *buf1, size_t size1)
 {
 void *buf2 = (void *)(((uintptr_t)buf1 + size1) & ~0x0ffful);
 size_t size2 = buf1 + size1 - buf2;
@@ -475,8 +476,8 @@ static inline void *split_cross_256mb(void *buf1, size_t 
size1)
 buf1 = buf2;
 }
 
-tcg_ctx->code_gen_buffer_size = size1;
-return buf1;
+*obuf = buf1;
+*osize = size1;
 }
 #endif
 
@@ -506,12 +507,10 @@ static bool alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 if (size > tb_size) {
 size = QEMU_ALIGN_DOWN(tb_size, qemu_real_host_page_size);
 }
-tcg_ctx->code_gen_buffer_size = size;
 
 #ifdef __mips__
 if (cross_256mb(buf, size)) {
-buf = split_cross_256mb(buf, size);
-size = tcg_ctx->code_gen_buffer_size;
+split_cross_256mb(&buf, &size, buf, size);
 }
 #endif
 
@@ -522,6 +521,7 @@ static bool alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
 
 tcg_ctx->code_gen_buffer = buf;
+tcg_ctx->code_gen_buffer_size = size;
 return true;
 }
 #elif defined(_WIN32)
@@ -580,8 +580,7 @@ static bool alloc_code_gen_buffer_anon(size_t size, int 
prot,
 /* fallthru */
 default:
 /* Split the original buffer.  Free the smaller half.  */
-buf2 = split_cross_256mb(buf, size);
-size2 = tcg_ctx->code_gen_buffer_size;
+split_cross_256mb(&buf2, &size2, buf, size);
 if (buf == buf2) {
 munmap(buf + size2, size - size2);
 } else {
-- 
2.25.1




[PATCH 15/26] tcg: Introduce tcg_max_ctxs

2021-03-10 Thread Richard Henderson
Finish the divorce of tcg/ from hw/, and do not take
the max cpu value from MachineState; just rememver what
we were passed in tcg_init.

Signed-off-by: Richard Henderson 
---
 tcg/internal.h |  3 ++-
 tcg/region.c   |  6 +++---
 tcg/tcg.c  | 23 ++-
 3 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/tcg/internal.h b/tcg/internal.h
index fcfeca232f..f9906523da 100644
--- a/tcg/internal.h
+++ b/tcg/internal.h
@@ -28,7 +28,8 @@
 #define TCG_HIGHWATER 1024
 
 extern TCGContext **tcg_ctxs;
-extern unsigned int n_tcg_ctxs;
+extern unsigned int tcg_cur_ctxs;
+extern unsigned int tcg_max_ctxs;
 
 void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus);
 bool tcg_region_alloc(TCGContext *s);
diff --git a/tcg/region.c b/tcg/region.c
index 04b699da63..e3fbf6a7e7 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -347,7 +347,7 @@ void tcg_region_initial_alloc(TCGContext *s)
 /* Call from a safe-work context */
 void tcg_region_reset_all(void)
 {
-unsigned int n_ctxs = qatomic_read(&n_tcg_ctxs);
+unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs);
 unsigned int i;
 
 qemu_mutex_lock(®ion.lock);
@@ -922,7 +922,7 @@ void tcg_region_prologue_set(TCGContext *s)
  */
 size_t tcg_code_size(void)
 {
-unsigned int n_ctxs = qatomic_read(&n_tcg_ctxs);
+unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs);
 unsigned int i;
 size_t total;
 
@@ -958,7 +958,7 @@ size_t tcg_code_capacity(void)
 
 size_t tcg_tb_phys_invalidate_count(void)
 {
-unsigned int n_ctxs = qatomic_read(&n_tcg_ctxs);
+unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs);
 unsigned int i;
 size_t total = 0;
 
diff --git a/tcg/tcg.c b/tcg/tcg.c
index a89d8f6b81..a82d3a0861 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -44,11 +44,6 @@
 #include "cpu.h"
 
 #include "exec/exec-all.h"
-
-#if !defined(CONFIG_USER_ONLY)
-#include "hw/boards.h"
-#endif
-
 #include "tcg/tcg-op.h"
 
 #if UINTPTR_MAX == UINT32_MAX
@@ -155,7 +150,8 @@ static int tcg_out_ldst_finalize(TCGContext *s);
 #endif
 
 TCGContext **tcg_ctxs;
-unsigned int n_tcg_ctxs;
+unsigned int tcg_cur_ctxs;
+unsigned int tcg_max_ctxs;
 TCGv_env cpu_env = 0;
 const void *tcg_code_gen_epilogue;
 uintptr_t tcg_splitwx_diff;
@@ -475,7 +471,6 @@ void tcg_register_thread(void)
 #else
 void tcg_register_thread(void)
 {
-MachineState *ms = MACHINE(qdev_get_machine());
 TCGContext *s = g_malloc(sizeof(*s));
 unsigned int i, n;
 
@@ -491,8 +486,8 @@ void tcg_register_thread(void)
 }
 
 /* Claim an entry in tcg_ctxs */
-n = qatomic_fetch_inc(&n_tcg_ctxs);
-g_assert(n < ms->smp.max_cpus);
+n = qatomic_fetch_inc(&tcg_cur_ctxs);
+g_assert(n < tcg_max_ctxs);
 qatomic_set(&tcg_ctxs[n], s);
 
 if (n > 0) {
@@ -643,9 +638,11 @@ static void tcg_context_init(unsigned max_cpus)
  */
 #ifdef CONFIG_USER_ONLY
 tcg_ctxs = &tcg_ctx;
-n_tcg_ctxs = 1;
+tcg_cur_ctxs = 1;
+tcg_max_ctxs = 1;
 #else
-tcg_ctxs = g_new(TCGContext *, max_cpus);
+tcg_max_ctxs = max_cpus;
+tcg_ctxs = g_new0(TCGContext *, max_cpus);
 #endif
 
 tcg_debug_assert(!tcg_regset_test_reg(s->reserved_regs, TCG_AREG0));
@@ -3937,7 +3934,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 static inline
 void tcg_profile_snapshot(TCGProfile *prof, bool counters, bool table)
 {
-unsigned int n_ctxs = qatomic_read(&n_tcg_ctxs);
+unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs);
 unsigned int i;
 
 for (i = 0; i < n_ctxs; i++) {
@@ -4000,7 +3997,7 @@ void tcg_dump_op_count(void)
 
 int64_t tcg_cpu_exec_time(void)
 {
-unsigned int n_ctxs = qatomic_read(&n_tcg_ctxs);
+unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs);
 unsigned int i;
 int64_t ret = 0;
 
-- 
2.25.1




[PATCH 26/26] tcg: When allocating for !splitwx, begin with PROT_NONE

2021-03-10 Thread Richard Henderson
There's a change in mprotect() behaviour [1] in the latest macOS
on M1 and it's not yet clear if it's going to be fixed by Apple.

In this case, instead of changing permissions of N guard pages,
we change permissions of N rwx regions.  The same number of
syscalls are required either way.

[1] https://gist.github.com/hikalium/75ae822466ee4da13cbbe486498a191f

Buglink: https://bugs.launchpad.net/qemu/+bug/1914849
Signed-off-by: Richard Henderson 
---
 tcg/region.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 5b46172fb5..3ffea215a2 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -749,12 +749,15 @@ static int alloc_code_gen_buffer(size_t size, int 
splitwx, Error **errp)
 error_free_or_abort(errp);
 }
 
-prot = PROT_READ | PROT_WRITE | PROT_EXEC;
+/*
+ * macOS 11.2 has a bug (Apple Feedback FB8994773) in which mprotect
+ * rejects a permission change from RWX -> NONE when reserving the
+ * guard pages later.  We can go the other way with the same number
+ * of syscalls, so always begin with PROT_NONE.
+ */
+prot = PROT_NONE;
 flags = MAP_PRIVATE | MAP_ANONYMOUS;
-#ifdef CONFIG_TCG_INTERPRETER
-/* The tcg interpreter does not need execute permission. */
-prot = PROT_READ | PROT_WRITE;
-#elif defined(CONFIG_DARWIN)
+#ifdef CONFIG_DARWIN
 /* Applicable to both iOS and macOS (Apple Silicon). */
 if (!splitwx) {
 flags |= MAP_JIT;
-- 
2.25.1




[PATCH 21/26] tcg: Return the map protection from alloc_code_gen_buffer

2021-03-10 Thread Richard Henderson
Change the interface from a boolean error indication to a
negative error vs a non-negative protection.  For the moment
this is only interface change, not making use of the new data.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 63 +++-
 1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index d7ad1be1f9..f25ec1ecad 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -485,14 +485,14 @@ static inline void split_cross_256mb(void **obuf, size_t 
*osize,
 static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE]
 __attribute__((aligned(CODE_GEN_ALIGN)));
 
-static bool alloc_code_gen_buffer(size_t tb_size, int splitwx, Error **errp)
+static int alloc_code_gen_buffer(size_t tb_size, int splitwx, Error **errp)
 {
 void *buf, *end;
 size_t size;
 
 if (splitwx > 0) {
 error_setg(errp, "jit split-wx not supported");
-return false;
+return -1;
 }
 
 /* page-align the beginning and end of the buffer */
@@ -522,16 +522,17 @@ static bool alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 
 region.start_aligned = buf;
 region.total_size = size;
-return true;
+
+return PROT_READ | PROT_WRITE;
 }
 #elif defined(_WIN32)
-static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
+static int alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
 {
 void *buf;
 
 if (splitwx > 0) {
 error_setg(errp, "jit split-wx not supported");
-return false;
+return -1;
 }
 
 buf = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT,
@@ -544,11 +545,12 @@ static bool alloc_code_gen_buffer(size_t size, int 
splitwx, Error **errp)
 
 region.start_aligned = buf;
 region.total_size = size;
-return true;
+
+return PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 }
 #else
-static bool alloc_code_gen_buffer_anon(size_t size, int prot,
-   int flags, Error **errp)
+static int alloc_code_gen_buffer_anon(size_t size, int prot,
+  int flags, Error **errp)
 {
 void *buf;
 
@@ -556,7 +558,7 @@ static bool alloc_code_gen_buffer_anon(size_t size, int 
prot,
 if (buf == MAP_FAILED) {
 error_setg_errno(errp, errno,
  "allocate %zu bytes for jit buffer", size);
-return false;
+return -1;
 }
 
 #ifdef __mips__
@@ -597,7 +599,7 @@ static bool alloc_code_gen_buffer_anon(size_t size, int 
prot,
 
 region.start_aligned = buf;
 region.total_size = size;
-return true;
+return prot;
 }
 
 #ifndef CONFIG_TCG_INTERPRETER
@@ -611,9 +613,9 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 
 #ifdef __mips__
 /* Find space for the RX mapping, vs the 256MiB regions. */
-if (!alloc_code_gen_buffer_anon(size, PROT_NONE,
-MAP_PRIVATE | MAP_ANONYMOUS |
-MAP_NORESERVE, errp)) {
+if (alloc_code_gen_buffer_anon(size, PROT_NONE,
+   MAP_PRIVATE | MAP_ANONYMOUS |
+   MAP_NORESERVE, errp) < 0) {
 return false;
 }
 /* The size of the mapping may have been adjusted. */
@@ -647,7 +649,7 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 /* Request large pages for the buffer and the splitwx.  */
 qemu_madvise(buf_rw, size, QEMU_MADV_HUGEPAGE);
 qemu_madvise(buf_rx, size, QEMU_MADV_HUGEPAGE);
-return true;
+return PROT_READ | PROT_WRITE;
 
  fail_rx:
 error_setg_errno(errp, errno, "failed to map shared memory for execute");
@@ -661,7 +663,7 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 if (fd >= 0) {
 close(fd);
 }
-return false;
+return -1;
 }
 #endif /* CONFIG_POSIX */
 
@@ -680,7 +682,7 @@ extern kern_return_t mach_vm_remap(vm_map_t target_task,
vm_prot_t *max_protection,
vm_inherit_t inheritance);
 
-static bool alloc_code_gen_buffer_splitwx_vmremap(size_t size, Error **errp)
+static int alloc_code_gen_buffer_splitwx_vmremap(size_t size, Error **errp)
 {
 kern_return_t ret;
 mach_vm_address_t buf_rw, buf_rx;
@@ -689,7 +691,7 @@ static bool alloc_code_gen_buffer_splitwx_vmremap(size_t 
size, Error **errp)
 /* Map the read-write portion via normal anon memory. */
 if (!alloc_code_gen_buffer_anon(size, PROT_READ | PROT_WRITE,
 MAP_PRIVATE | MAP_ANONYMOUS, errp)) {
-return false;
+return -1;
 }
 
 buf_rw = region.start_aligned;
@@ -709,23 +711,23 @@ static bool alloc_code_gen_buffer_splitwx_vmremap(size_t 
size, Error **errp)
 /* TODO: Convert "ret" to a human readable error message. */
 error_setg(errp, "vm_remap for jit splitwx failed

[PATCH 25/26] tcg: Merge buffer protection and guard page protection

2021-03-10 Thread Richard Henderson
Do not handle protections on a case-by-case basis in the
various alloc_code_gen_buffer instances; do it within a
single loop in tcg_region_init.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 40 +---
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 93d03076d1..5b46172fb5 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -514,11 +514,6 @@ static int alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 }
 #endif
 
-if (qemu_mprotect_rwx(buf, size)) {
-error_setg_errno(errp, errno, "mprotect of jit buffer");
-return false;
-}
-
 region.start_aligned = buf;
 region.total_size = size;
 
@@ -802,8 +797,7 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 {
 size_t page_size;
 size_t region_size;
-size_t i;
-int have_prot;
+int have_prot, need_prot;
 
 have_prot = alloc_code_gen_buffer(size_code_gen_buffer(tb_size),
   splitwx, &error_fatal);
@@ -844,14 +838,38 @@ void tcg_region_init(size_t tb_size, int splitwx, 
unsigned max_cpus)
 /* init the region struct */
 qemu_mutex_init(®ion.lock);
 
-/* Set guard pages.  No need to do this for the rx_buf, only the rw_buf. */
-for (i = 0; i < region.n; i++) {
+/*
+ * Set guard pages.  No need to do this for the rx_buf, only the rw_buf.
+ * Work with the page protections set up with the initial mapping.
+ */
+need_prot = PAGE_READ | PAGE_WRITE;
+#ifndef CONFIG_TCG_INTERPRETER
+if (tcg_splitwx_diff == 0) {
+need_prot |= PAGE_EXEC;
+}
+#endif
+for (size_t i = 0, n = region.n; i < n; i++) {
 void *start, *end;
 int rc;
 
 tcg_region_bounds(i, &start, &end);
-rc = qemu_mprotect_none(end, page_size);
-g_assert(!rc);
+if (have_prot != need_prot) {
+if (need_prot == (PAGE_READ | PAGE_WRITE | PAGE_EXEC)) {
+rc = qemu_mprotect_rwx(start, end - start);
+} else if (need_prot == (PAGE_READ | PAGE_WRITE)) {
+rc = qemu_mprotect_rw(start, end - start);
+} else {
+g_assert_not_reached();
+}
+if (rc) {
+error_setg_errno(&error_fatal, errno,
+ "mprotect of jit buffer");
+}
+}
+if (have_prot != 0) {
+/* If guard-page permissions don't change, it isn't fatal. */
+(void)qemu_mprotect_none(end, page_size);
+}
 }
 
 tcg_region_trees_init();
-- 
2.25.1




[RFC] tests/migration: introduce multifd into guestperf toolkit

2021-03-10 Thread huangy81
From: Hyman 

Current guestperf tool does not support multifd migration,
introducing it is good idea so that we can compare the
performence of all type of migration.

Signed-off-by: Hyman 
---
 tests/migration/guestperf/comparison.py | 14 ++
 tests/migration/guestperf/engine.py | 16 
 tests/migration/guestperf/scenario.py   | 12 ++--
 tests/migration/guestperf/shell.py  | 10 +-
 4 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/tests/migration/guestperf/comparison.py 
b/tests/migration/guestperf/comparison.py
index ba2edbe..088e1a7 100644
--- a/tests/migration/guestperf/comparison.py
+++ b/tests/migration/guestperf/comparison.py
@@ -121,4 +121,18 @@ def __init__(self, name, scenarios):
 Scenario("compr-xbzrle-cache-50",
  compression_xbzrle=True, compression_xbzrle_cache=50),
 ]),
+
+
+# Looking at effect of multifd with
+# varying numbers of channels
+Comparison("compr-multifd", scenarios = [
+Scenario("compr-multifd-channels-2",
+ multifd=True, multifd_channels=2),
+Scenario("compr-multifd-channels-32",
+ multifd=True, multifd_channels=32),
+Scenario("compr-multifd-channels-64",
+ multifd=True, multifd_channels=64),
+Scenario("compr-multifd-channels-128",
+ multifd=True, multifd_channels=128),
+]),
 ]
diff --git a/tests/migration/guestperf/engine.py 
b/tests/migration/guestperf/engine.py
index 83bfc3b..2a7f1ac 100644
--- a/tests/migration/guestperf/engine.py
+++ b/tests/migration/guestperf/engine.py
@@ -186,6 +186,22 @@ def _migrate(self, hardware, scenario, src, dst, 
connect_uri):
value=(hardware._mem * 1024 * 1024 * 1024 / 100 
*
   scenario._compression_xbzrle_cache))
 
+if scenario._multifd:
+resp = src.command("migrate-set-capabilities",
+   capabilities = [
+   { "capability": "multifd",
+ "state": True }
+   ])
+resp = src.command("migrate-set-parameters",
+   multifd_channels=scenario._multifd_channels)
+resp = dst.command("migrate-set-capabilities",
+   capabilities = [
+   { "capability": "multifd",
+ "state": True }
+   ])
+resp = dst.command("migrate-set-parameters",
+   multifd_channels=scenario._multifd_channels)
+
 resp = src.command("migrate", uri=connect_uri)
 
 post_copy = False
diff --git a/tests/migration/guestperf/scenario.py 
b/tests/migration/guestperf/scenario.py
index 28ef36c..de70d9b 100644
--- a/tests/migration/guestperf/scenario.py
+++ b/tests/migration/guestperf/scenario.py
@@ -29,7 +29,8 @@ def __init__(self, name,
  post_copy=False, post_copy_iters=5,
  auto_converge=False, auto_converge_step=10,
  compression_mt=False, compression_mt_threads=1,
- compression_xbzrle=False, compression_xbzrle_cache=10):
+ compression_xbzrle=False, compression_xbzrle_cache=10,
+ multifd=False, multifd_channels=2):
 
 self._name = name
 
@@ -56,6 +57,9 @@ def __init__(self, name,
 self._compression_xbzrle = compression_xbzrle
 self._compression_xbzrle_cache = compression_xbzrle_cache # percentage 
of guest RAM
 
+self._multifd = multifd
+self._multifd_channels = multifd_channels
+
 def serialize(self):
 return {
 "name": self._name,
@@ -73,6 +77,8 @@ def serialize(self):
 "compression_mt_threads": self._compression_mt_threads,
 "compression_xbzrle": self._compression_xbzrle,
 "compression_xbzrle_cache": self._compression_xbzrle_cache,
+"multifd": self._multifd,
+"multifd_channels": self._multifd_channels,
 }
 
 @classmethod
@@ -92,4 +98,6 @@ def deserialize(cls, data):
 data["compression_mt"],
 data["compression_mt_threads"],
 data["compression_xbzrle"],
-data["compression_xbzrle_cache"])
+data["compression_xbzrle_cache"],
+data["multifd"],
+data["multifd_channels"])
diff --git a/tests/migration/guestperf/shell.py 
b/tests/migration/guestperf/shell.py
index f83..5ee0369 100644
--- a/tests/migration/guestperf/shell.py
+++ b/tests/migration/guestperf/shell.py
@@ -122,6 +122,11 @@ def __init__(self):
 parser.add_argument("--compression-xbzrle", dest="compression_xbzrle", 
default=False, action="store_true")
 parser.add_argument("--compression-xbzrle-cache", 
dest="compression_xbzrle_cache", default=10, type=int)
 
+parse

[PATCH 24/26] util/osdep: Add qemu_mprotect_rw

2021-03-10 Thread Richard Henderson
For --enable-tcg-interpreter on Windows, we will need this.

Signed-off-by: Richard Henderson 
---
 include/qemu/osdep.h | 1 +
 util/osdep.c | 9 +
 2 files changed, 10 insertions(+)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index ba15be9c56..5cc2e57bdf 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -494,6 +494,7 @@ void sigaction_invoke(struct sigaction *action,
 #endif
 
 int qemu_madvise(void *addr, size_t len, int advice);
+int qemu_mprotect_rw(void *addr, size_t size);
 int qemu_mprotect_rwx(void *addr, size_t size);
 int qemu_mprotect_none(void *addr, size_t size);
 
diff --git a/util/osdep.c b/util/osdep.c
index 66d01b9160..42a0a4986a 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -97,6 +97,15 @@ static int qemu_mprotect__osdep(void *addr, size_t size, int 
prot)
 #endif
 }
 
+int qemu_mprotect_rw(void *addr, size_t size)
+{
+#ifdef _WIN32
+return qemu_mprotect__osdep(addr, size, PAGE_READWRITE);
+#else
+return qemu_mprotect__osdep(addr, size, PROT_READ | PROT_WRITE);
+#endif
+}
+
 int qemu_mprotect_rwx(void *addr, size_t size)
 {
 #ifdef _WIN32
-- 
2.25.1




Re: [PATCH 16/26] tcg: Move MAX_CODE_GEN_BUFFER_SIZE to tcg-target.h

2021-03-10 Thread BALATON Zoltan

On Wed, 10 Mar 2021, Richard Henderson wrote:

Remove the ifdef ladder and move each define into the
appropriate header file.

Signed-off-by: Richard Henderson 
---
tcg/aarch64/tcg-target.h |  1 +
tcg/arm/tcg-target.h |  1 +
tcg/i386/tcg-target.h|  2 ++
tcg/mips/tcg-target.h|  6 ++
tcg/ppc/tcg-target.h |  2 ++
tcg/riscv/tcg-target.h   |  1 +
tcg/s390/tcg-target.h|  3 +++
tcg/sparc/tcg-target.h   |  1 +
tcg/tci/tcg-target.h |  1 +
tcg/region.c | 32 ++--
10 files changed, 24 insertions(+), 26 deletions(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 5ec30dba25..ef55f7c185 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -15,6 +15,7 @@

#define TCG_TARGET_INSN_UNIT_SIZE  4
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 24
+#define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
#undef TCG_TARGET_STACK_GROWSUP

typedef enum {
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 8d1fee6327..b9a85d0f83 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -60,6 +60,7 @@ extern int arm_arch;
#undef TCG_TARGET_STACK_GROWSUP
#define TCG_TARGET_INSN_UNIT_SIZE 4
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 16
+#define MAX_CODE_GEN_BUFFER_SIZE  UINT32_MAX

typedef enum {
TCG_REG_R0 = 0,
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index b693d3692d..ac10066c3e 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -31,9 +31,11 @@
#ifdef __x86_64__
# define TCG_TARGET_REG_BITS  64
# define TCG_TARGET_NB_REGS   32
+# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
#else
# define TCG_TARGET_REG_BITS  32
# define TCG_TARGET_NB_REGS   24
+# define MAX_CODE_GEN_BUFFER_SIZE  UINT32_MAX
#endif

typedef enum {
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index c2c32fb38f..e81e824cab 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -39,6 +39,12 @@
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 16
#define TCG_TARGET_NB_REGS 32

+/*
+ * We have a 256MB branch region, but leave room to make sure the
+ * main executable is also within that region.
+ */
+#define MAX_CODE_GEN_BUFFER_SIZE  (128 * MiB)
+
typedef enum {
TCG_REG_ZERO = 0,
TCG_REG_AT,
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index d1339afc66..c13ed5640a 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -27,8 +27,10 @@

#ifdef _ARCH_PPC64
# define TCG_TARGET_REG_BITS  64
+# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
#else
# define TCG_TARGET_REG_BITS  32
+# define MAX_CODE_GEN_BUFFER_SIZE  (32 * MiB)
#endif

#define TCG_TARGET_NB_REGS 64
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 727c8df418..87ea94666b 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -34,6 +34,7 @@
#define TCG_TARGET_INSN_UNIT_SIZE 4
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 20
#define TCG_TARGET_NB_REGS 32
+#define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)

typedef enum {
TCG_REG_ZERO,
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 641464eea4..b04b72b7eb 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -28,6 +28,9 @@
#define TCG_TARGET_INSN_UNIT_SIZE 2
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 19

+/* We have a +- 4GB range on the branches; leave some slop.  */
+#define MAX_CODE_GEN_BUFFER_SIZE  (3 * GiB)
+
typedef enum TCGReg {
TCG_REG_R0 = 0,
TCG_REG_R1,
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index f66f5d07dc..86bb9a2d39 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -30,6 +30,7 @@
#define TCG_TARGET_INSN_UNIT_SIZE 4
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
#define TCG_TARGET_NB_REGS 32
+#define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)

typedef enum {
TCG_REG_G0 = 0,
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 9c0021a26f..03cf527cb4 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -43,6 +43,7 @@
#define TCG_TARGET_INTERPRETER 1
#define TCG_TARGET_INSN_UNIT_SIZE 1
#define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
+#define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)

#if UINTPTR_MAX == UINT32_MAX
# define TCG_TARGET_REG_BITS 32
diff --git a/tcg/region.c b/tcg/region.c
index e3fbf6a7e7..8fba0724e5 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -398,34 +398,14 @@ static size_t tcg_n_regions(unsigned max_cpus)
#endif
}

-/* Minimum size of the code gen buffer.  This number is randomly chosen,
-   but not so small that we can't have a fair number of TB's live.  */
+/*
+ * Minimum size of the code gen buffer.  This number is randomly chosen,
+ * but not so small that we can't have a fair number of TB's live.
+ *
+ * Maximum size is defined in tcg-target.h.
+ */
#define MIN_CODE_GEN_BUFFER_SIZE (1 * MiB)

-/* Maximum size of the code gen buffer we'd like to use.  Unless otherwise
-   indicated, this is constrained by the range of direct branches on the
-   host cpu, as used by the TCG implementation of goto_tb.  */


This comment about constraints seems to 

Re: [PATCH 1/2] hw/mips/jazz: Use generic I/O bus via get_system_io()

2021-03-10 Thread Jiaxun Yang



On Thu, Mar 11, 2021, at 3:12 AM, Philippe Mathieu-Daudé wrote:
> No need to create a local ISA I/O MemoryRegion, use get_system_io().
> 
> This partly reverts commit 5c63bcf7501527b844f61624957bdba254d75bfc.
> 
> Signed-off-by: Philippe Mathieu-Daudé 

No luck to boot arcboot with current jazz :-(

https://virtuallyfun.com/wordpress/2011/03/06/windows-nt-4-0-mips-revisited/

> ---
>  hw/mips/jazz.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
>
-- 
- Jiaxun



Re: [PATCH 00/26] tcg: Workaround macOS 11.2 mprotect bug

2021-03-10 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20210311002156.253711-1-richard.hender...@linaro.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20210311002156.253711-1-richard.hender...@linaro.org
Subject: [PATCH 00/26] tcg: Workaround macOS 11.2 mprotect bug

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/20210311002156.253711-1-richard.hender...@linaro.org -> 
patchew/20210311002156.253711-1-richard.hender...@linaro.org
Switched to a new branch 'test'
6270444 tcg: When allocating for !splitwx, begin with PROT_NONE
20dd554 tcg: Merge buffer protection and guard page protection
996417b util/osdep: Add qemu_mprotect_rw
f390fd1 tcg: Do not set guard pages in the rx buffer
cec5119 tcg: Sink qemu_madvise call to common code
ef8fa42 tcg: Return the map protection from alloc_code_gen_buffer
3c9cf4e tcg: Allocate code_gen_buffer into struct tcg_region_state
1d71ed2 tcg: Tidy split_cross_256mb
f288a3a tcg: Tidy tcg_n_regions
af5f973 tcg: Replace region.end with region.total_size
436e7dd tcg: Move MAX_CODE_GEN_BUFFER_SIZE to tcg-target.h
9d9a3a8 tcg: Introduce tcg_max_ctxs
c907f41 accel/tcg: Pass down max_cpus to tcg_init
cadcc5d accel/tcg: Merge tcg_exec_init into tcg_init_machine
39b8dcc tcg: Create tcg_init
f194472 accel/tcg: Rename tcg_init to tcg_init_machine
752c003 accel/tcg: Move alloc_code_gen_buffer to tcg/region.c
88e88ed accel/tcg: Inline cpu_gen_init
68c020a tcg: Split out region.c
f2468f3 tcg: Split out tcg_region_prologue_set
9260a2b tcg: Split out tcg_region_initial_alloc
d3885f1 tcg: Remove error return from tcg_region_initial_alloc__locked
39905cc tcg: Re-order tcg_region_init vs tcg_prologue_init
56a4e11 meson: Split out fpu/meson.build
bc597a2 meson: Move disas/tci.c to disas/meson.build
90e5198 meson: Split out tcg/meson.build

=== OUTPUT BEGIN ===
1/26 Checking commit 90e51984ec1e (meson: Split out tcg/meson.build)
Use of uninitialized value $acpi_testexpected in string eq at 
./scripts/checkpatch.pl line 1529.
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#43: 
new file mode 100644

total: 0 errors, 1 warnings, 35 lines checked

Patch 1/26 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
2/26 Checking commit bc597a225ec0 (meson: Move disas/tci.c to disas/meson.build)
3/26 Checking commit 56a4e116d3ed (meson: Split out fpu/meson.build)
Use of uninitialized value $acpi_testexpected in string eq at 
./scripts/checkpatch.pl line 1529.
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#15: 
new file mode 100644

total: 0 errors, 1 warnings, 17 lines checked

Patch 3/26 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
4/26 Checking commit 39905cc9e118 (tcg: Re-order tcg_region_init vs 
tcg_prologue_init)
5/26 Checking commit d3885f17f769 (tcg: Remove error return from 
tcg_region_initial_alloc__locked)
6/26 Checking commit 9260a2be69f4 (tcg: Split out tcg_region_initial_alloc)
7/26 Checking commit f2468f31fb8e (tcg: Split out tcg_region_prologue_set)
8/26 Checking commit 68c020a8c929 (tcg: Split out region.c)
Use of uninitialized value $acpi_testexpected in string eq at 
./scripts/checkpatch.pl line 1529.
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#17: 
new file mode 100644

total: 0 errors, 1 warnings, 1189 lines checked

Patch 8/26 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
9/26 Checking commit 88e88ed26587 (accel/tcg: Inline cpu_gen_init)
10/26 Checking commit 752c0035d065 (accel/tcg: Move alloc_code_gen_buffer to 
tcg/region.c)
WARNING: Block comments use a leading /* on a separate line
#499: FILE: tcg/region.c:411:
+/* Minimum size of the code gen buffer.  This number is randomly chosen,

WARNING: Block comments use * on subsequent lines
#500: FILE: tcg/region.c:412:
+/* Minimum size of the code gen buffer.  This number is randomly chosen,
+   but not so small that we can't have a fair number of TB's live.  */

WARNING: Block comments use a trailing */ on a separate line
#500: FILE: tcg/region.c:412:
+   but not so small that we can't have a fair number of TB's live.  */

WARNING: Block comments use a leading /* on a separate line
#503: FILE: tcg/region.c:415:
+/* Maximum size of the code gen buffer we'd like to use.  Unless otherwise

WARNING: Block comments use * on subsequent lines
#504: FILE: tcg/region.c:416:
+/* Maximu

Re: [PATCH] vfio: Support host translation granule size

2021-03-10 Thread Keqian Zhu
Hi Alex,

On 2021/3/11 4:24, Alex Williamson wrote:
> On Wed, 10 Mar 2021 15:19:33 +0800
> Kunkun Jiang  wrote:
> 
>> Hi Alex,
>>
>> On 2021/3/10 7:17, Alex Williamson wrote:
>>> On Thu, 4 Mar 2021 21:34:46 +0800
>>> Kunkun Jiang  wrote:
>>>  
 The cpu_physical_memory_set_dirty_lebitmap() can quickly deal with
 the dirty pages of memory by bitmap-traveling, regardless of whether
 the bitmap is aligned correctly or not.

 cpu_physical_memory_set_dirty_lebitmap() supports pages in bitmap of
 host page size. So it'd better to set bitmap_pgsize to host page size
 to support more translation granule sizes.

 Fixes: 87ea529c502 (vfio: Get migration capability flags for container)
 Signed-off-by: Kunkun Jiang 
 ---
   hw/vfio/common.c | 44 ++--
   1 file changed, 22 insertions(+), 22 deletions(-)

 diff --git a/hw/vfio/common.c b/hw/vfio/common.c
 index 6ff1daa763..69fb5083a4 100644
 --- a/hw/vfio/common.c
 +++ b/hw/vfio/common.c
 @@ -378,7 +378,7 @@ static int vfio_dma_unmap_bitmap(VFIOContainer 
 *container,
   {
   struct vfio_iommu_type1_dma_unmap *unmap;
   struct vfio_bitmap *bitmap;
 -uint64_t pages = TARGET_PAGE_ALIGN(size) >> TARGET_PAGE_BITS;
 +uint64_t pages = REAL_HOST_PAGE_ALIGN(size) / 
 qemu_real_host_page_size;
   int ret;
   
   unmap = g_malloc0(sizeof(*unmap) + sizeof(*bitmap));
 @@ -390,12 +390,12 @@ static int vfio_dma_unmap_bitmap(VFIOContainer 
 *container,
   bitmap = (struct vfio_bitmap *)&unmap->data;
   
   /*
 - * cpu_physical_memory_set_dirty_lebitmap() expects pages in bitmap of
 - * TARGET_PAGE_SIZE to mark those dirty. Hence set bitmap_pgsize to
 - * TARGET_PAGE_SIZE.
 + * cpu_physical_memory_set_dirty_lebitmap() supports pages in bitmap 
 of
 + * qemu_real_host_page_size to mark those dirty. Hence set 
 bitmap_pgsize
 + * to qemu_real_host_page_size.  
>>>
>>> I don't see that this change is well supported by the code,
>>> cpu_physical_memory_set_dirty_lebitmap() seems to operate on  
>> Yes, cpu_physical_memory_set_dirty_lebitmap() is finally to operate on
>> TARGET_PAGE_SIZE. But actually it supports pages in bitmap of
>> qemu_real_host_page_size to mark those dirty. It uses
>> "hpratio = qemu_real_host_page_size / TARGET_PAGE_SIZE" to adapt to
>> different translation granule size(e.g. 4K 2M 1G).
> 
> Thanks for the explanation, it becomes more clear but I'm still a
> little confused.  It appears that
> cpu_physical_memory_set_dirty_lebitmap() requires a bitmap in terms of
> qemu_real_host_page_size which is translated to target pages using
> hpratio.  It's not clear to me by the explanation here and in the
> commit log that we're technically using the wrong page size reference
> for this function.
> 
>>> TARGET_PAGE_SIZE, and the next three patch chunks take a detour through
>>> memory listener code that seem unrelated to the change described in the
>>> commit log.  This claims to fix something, what is actually broken?
>>> Thanks,
>>>
>>> Alex  
>> This patch 87ea529c502 (vfio: Get migration capability flags for container)
>> is the start of the bug. The code of [1](marked below) restricts the host
>> page size must be TARGET_PAGE_SIZE(e.g. 4K) to set
>> container->dirty_pages_supported = true. It is inappropriate to limit the
>> page size to TARGET_PAGE_SIZE.
> 
> Right, the noted code requires that vfio supports the target page size,
> which for all practical purposes implies an hpratio = 1 currently.
> That unnecessarily restricts migration support to cases where target and
> host use the same page size, but this change allows migration in any
> case where vfio dirty bitmap supports the host page size, which is
> effectively any case where the device supports migration.  However, the
> hpratio calculation requires that qemu_real_host_page_size is >=
> TARGET_PAGE_SIZE, otherwise the value becomes zero and it appears we'd
> only ever dirty the target zero page.  Is this configuration restricted
> elsewhere, ex. 64K guest on 4K host?  Exchanging an unnecessary
> restriction for allowing a buggy configuration isn't a good trade-off.
> Thanks,
FYI, The restriction that (qemu_real_host_page_size is >= TARGET_PAGE_SIZE) has 
already
existed. As in the kvm_init(), we have an assert: assert(TARGET_PAGE_SIZE <= 
qemu_real_host_page_size);

As I understand, the TARGET_PAGE_SIZE is an architecture specific value,
and not affected by the page size of guest OS. For arm64, it is fixed to be
12 bit(4K), while the qemu_real_host_page_size depends on host kernel 
configuration,
it can be 4K, 16K or 64K.

IIUC, the kernel vfio/iommu_type1 actually reports supported page_size of dirty 
log
to be host_page_size, so if host use 16K or 64K, Qemu will refuse to support 
vfio migration.

Thanks,
Keqian



> 
> Alex
> 
*/

Re: [PULL 00/20] ppc-for-6.0 queue 20210310

2021-03-10 Thread Bin Meng
On Thu, Mar 11, 2021 at 7:01 AM David Gibson
 wrote:
>
> On Wed, Mar 10, 2021 at 12:43:53PM +0800, Bin Meng wrote:
> > Hi David,
> >
> > On Wed, Mar 10, 2021 at 12:10 PM David Gibson
> >  wrote:
> > >
> > > The following changes since commit 
> > > b2ae1009d7cca2701e17eae55ae2d44fd22c942a:
> > >
> > >   Merge remote-tracking branch 
> > > 'remotes/mcayland/tags/qemu-sparc-20210307' into staging (2021-03-09 
> > > 13:50:35 +)
> > >
> > > are available in the Git repository at:
> > >
> > >   https://gitlab.com/dgibson/qemu.git tags/ppc-for-6.0-20210310
> > >
> > > for you to fetch changes up to eb7f80fd26d73e7e1af105431da58971b1dba517:
> > >
> > >   spapr.c: send QAPI event when memory hotunplug fails (2021-03-10 
> > > 09:07:09 +1100)
> > >
> > > 
> > > ppc patch queue for 2021-03-10
> > >
> > > Next batch of patches for the ppc target and machine types.  Includes:
> > >  * Several cleanups for sm501 from Peter Maydell
> > >  * An update to the SLOF guest firmware
> > >  * Improved handling of hotplug failures in spapr, associated cleanups
> > >to the hotplug handling code
> > >  * Several etsec fixes and cleanups from Bin Meng
> > >  * Assorted other fixes and cleanups
> > >
> > > 
> > > Alexey Kardashevskiy (1):
> > >   pseries: Update SLOF firmware image
> > >
> > > Bin Meng (2):
> > >   hw/net: fsl_etsec: Fix build error when HEX_DUMP is on
> > >   hw/ppc: e500: Add missing  in the eTSEC node
> >
> > It seems the following patch was missing?
> > http://patchwork.ozlabs.org/project/qemu-devel/patch/1613660319-76960-1-git-send-email-bmeng...@gmail.com/
>
> Huh, sorry.  I don't know how that dropped out of my tree.
>
> I don't really want to delay this batch, so can you resend please, and
> I'll include it in the next batch.

Sure, will resend.

Regards,
Bin



Re: [RFC PATCH 18/21] contrib/gitdm: Add Wind River to the domain map

2021-03-10 Thread Bin Meng
Hi Philippe,

On Thu, Oct 8, 2020 at 7:13 PM Bin Meng  wrote:
>
> Hi Philippe,
>
> On Mon, Oct 5, 2020 at 2:05 AM Philippe Mathieu-Daudé  wrote:
> >
> > There is a number of contributors from this domain,
> > add its own entry to the gitdm domain map.
> >
> > Cc: Bill Paul 
> > Cc: Bin Meng 
> > Cc: Bin Meng 
> > Cc: Jason Wessel 
> > Cc: Jim Somerville 
> > Cc: Tiejun Chen 
> > Cc: Vlad Lungu 
> > Cc: Yiting Wang 
> > Signed-off-by: Philippe Mathieu-Daudé 
> > ---
> > One Reviewed-by/Ack-by from someone from this domain
> > should be sufficient to get this patch merged.
> >
> > Ben, can you confirm your bmeng...@gmail.com address?
> > Should it be considered 'individual contribution' instead?
>
> Yes, I think so. Thanks for the patch.
>
> Otherwise,
>
> Acked-by: Bin Meng 

I see this patch was not applied. Anything else needed to move on?

Regards,
Bin



Re: [PULL 00/20] ppc-for-6.0 queue 20210310

2021-03-10 Thread David Gibson
On Wed, Mar 10, 2021 at 03:09:46PM +0100, Ivan Warren wrote:
> Hey there,
> 
> Any chance the MSR[SF] mixed code issue fix gets addressed at some point ?
> 
> (Apparently there was a fix but it was breaking some tests for some unknown
> reason)...

Sorry, I've forgotten this issue.  If you had a patch, can you resend
it please.

> 
> --Ivan
> 
> On 3/10/2021 5:09 AM, David Gibson wrote:
> > The following changes since commit b2ae1009d7cca2701e17eae55ae2d44fd22c942a:
> > 
> >Merge remote-tracking branch 'remotes/mcayland/tags/qemu-sparc-20210307' 
> > into staging (2021-03-09 13:50:35 +)
> > 
> > are available in the Git repository at:
> > 
> >https://gitlab.com/dgibson/qemu.git tags/ppc-for-6.0-20210310
> > 
> > for you to fetch changes up to eb7f80fd26d73e7e1af105431da58971b1dba517:
> > 
> >spapr.c: send QAPI event when memory hotunplug fails (2021-03-10 
> > 09:07:09 +1100)
> > 
> > 
> > ppc patch queue for 2021-03-10
> > 
> > Next batch of patches for the ppc target and machine types.  Includes:
> >   * Several cleanups for sm501 from Peter Maydell
> >   * An update to the SLOF guest firmware
> >   * Improved handling of hotplug failures in spapr, associated cleanups
> > to the hotplug handling code
> >   * Several etsec fixes and cleanups from Bin Meng
> >   * Assorted other fixes and cleanups
> > 
> > 
> > Alexey Kardashevskiy (1):
> >pseries: Update SLOF firmware image
> > 
> > Bin Meng (2):
> >hw/net: fsl_etsec: Fix build error when HEX_DUMP is on
> >hw/ppc: e500: Add missing  in the eTSEC node
> > 
> > Cédric Le Goater (1):
> >docs/system: Extend PPC section
> > 
> > Daniel Henrique Barboza (11):
> >spapr_drc.c: do not call spapr_drc_detach() in drc_isolate_logical()
> >spapr_drc.c: use spapr_drc_release() in isolate_physical/set_unusable
> >spapr: rename spapr_drc_detach() to spapr_drc_unplug_request()
> >spapr_drc.c: introduce unplug_timeout_timer
> >spapr_drc.c: add hotunplug timeout for CPUs
> >spapr_drc.c: use DRC reconfiguration to cleanup DIMM unplug state
> >spapr.c: add 'unplug already in progress' message for PHB unplug
> >spapr_pci.c: add 'unplug already in progress' message for PCI unplug
> >qemu_timer.c: add timer_deadline_ms() helper
> >spapr.c: remove duplicated assert in spapr_memory_unplug_request()
> >spapr.c: send QAPI event when memory hotunplug fails
> > 
> > Fabiano Rosas (1):
> >target/ppc: Fix bcdsub. emulation when result overflows
> > 
> > Peter Maydell (3):
> >hw/display/sm501: Remove dead code for non-32-bit RGB surfaces
> >hw/display/sm501: Expand out macros in template header
> >hw/display/sm501: Inline template header into C file
> > 
> > Vitaly Cheptsov (1):
> >target/ppc: fix icount support on Book-e vms accessing SPRs
> > 
> >   docs/system/ppc/embedded.rst  |  10 ++
> >   docs/system/ppc/powermac.rst  |  34 +++
> >   docs/system/ppc/powernv.rst   | 193 
> > ++
> >   docs/system/ppc/prep.rst  |  18 
> >   docs/system/ppc/pseries.rst   |  12 +++
> >   docs/system/target-ppc.rst|  53 +++
> >   hw/display/sm501.c| 160 +++
> >   hw/display/sm501_template.h   | 131 --
> >   hw/net/fsl_etsec/etsec.c  |   1 +
> >   hw/net/fsl_etsec/rings.c  |   1 +
> >   hw/ppc/e500.c |   1 +
> >   hw/ppc/spapr.c|  67 -
> >   hw/ppc/spapr_drc.c| 110 --
> >   hw/ppc/spapr_pci.c|   8 +-
> >   hw/ppc/trace-events   |   2 +-
> >   include/hw/ppc/spapr.h|   1 +
> >   include/hw/ppc/spapr_drc.h|   7 +-
> >   include/qemu/timer.h  |   8 ++
> >   pc-bios/README|   2 +-
> >   pc-bios/slof.bin  | Bin 968368 -> 96 bytes
> >   roms/SLOF |   2 +-
> >   target/ppc/int_helper.c   |  13 ++-
> >   target/ppc/translate_init.c.inc   |  36 +++
> >   tests/tcg/configure.sh|   6 ++
> >   tests/tcg/ppc64/Makefile.target   |  13 +++

Re: [PATCH v4 00/78] target/arm: Implement SVE2

2021-03-10 Thread Richard Henderson

On 3/10/21 2:17 PM, Peter Maydell wrote:

On Tue, 9 Mar 2021 at 16:20, Richard Henderson
 wrote:


After a 6-month hiatus, sve2 is back.  This time, with RISU
testing vs FVP 11.13.36.

Based-on: 20210309155305.11301-1-richard.hender...@linaro.org
("target/arm: sve1 fixes")


Are you hoping to squeeze this into 6.0, or can I delay
review of it in favour of for-6.0 stuff ?


I didn't expect to get it into 6.0.  Too much too late.


r~




Question about edge-triggered interrupt

2021-03-10 Thread LIU Zhiwei

Hi folks,

Currently, I am writing an interrupt controller (CLIC) for RISC-V. I 
can't find a good way to process edge-triggered interrupt.


According to edge-triggered definition, if I select an edge-triggered  
interrupt to serve , it will clean its pending status. However after 
serving the interrupt,  there is no chance to select other pending 
interrupts.


I have two methods.

1. One is to add a timer for interrupt controller, so that every
   pending interrupt can be served at some point.
2. The other is that  always pull a pending interrupt to serve at the
   interrupt return instruction.

But both are not so good. The first one we can not server the interrupts 
immediately. The second one we have to add some

code when executing the guest code.

I want to know if there is a better way to handle edge-triggered 
interrupt on QEMU.


Thanks very much for your reading and look forward to your response.

Zhiwei




Re: [RFC PATCH v3 02/10] net: Pad short frames to minimum size before send from SLiRP/TAP

2021-03-10 Thread Jason Wang



On 2021/3/9 6:13 下午, Peter Maydell wrote:

On Tue, 9 Mar 2021 at 09:01, Bin Meng  wrote:

Hi Jason,

On Tue, Mar 9, 2021 at 5:00 PM Bin Meng  wrote:

Hi Jason,

On Tue, Mar 9, 2021 at 4:57 PM Jason Wang  wrote:


On 2021/3/9 4:35 下午, Bin Meng wrote:

Hi Jason,

On Tue, Mar 9, 2021 at 4:23 PM Jason Wang  wrote:

On 2021/3/8 6:22 下午, Peter Maydell wrote:

I think the key thing we need to do here is make a decision
and be clear about what we're doing. There are three options
I can see:

(1) we say that the net API demands that backends pad
packets they emit to the minimum ethernet frame length
unless they specifically are intending to emit a short frame,
and we fix any backends that don't comply (or equivalently,
add support in the core code for a backend to mark itself
as "I don't pad; please do it for me").

(2) we say that the networking subsystem doesn't support
short packets, and just have the common code always enforce
padding short frames to the minimum length somewhere between
when it receives a packet from a backend and passes it to
a NIC model.

(3) we say that it's the job of the NIC models to pad
short frames as they see them coming in.

I'm not sure how much value we can gain from (1). So (2) looks better to me.

Bin or Philippe, want to send a new version?


I think this series does what (2) asks for. Or am I missing anything?


It only did the padding for user/TAP.

(hit send too soon ...)

Ah, so we want this:

if (sender->info->type != NET_CLIENT_DRIVER_NIC)

correct?

No, option (2) is "always pad short packets regardless of
sender->info->type". Even if a NIC driver sends out a short
packet, we want to pad it, because we might be feeding it to
something that assumes it does not see short packets.

thanks
-- PMM



So I'm not sure this is correct. There're NIC that has its own logic 
that choose whether to pad the frame during TX (e.g e1000).


And after a discussion 10 years ago [1]. Michael (cced) seems to want to 
keep the padding logic in the NIC itself (probably with a generic helper 
in the core). Since 1) the padding is only required for ethernet 2) 
virito-net doesn't need that (it can pass incomplete packet by design).


Thanks

[1] 
https://patchwork.ozlabs.org/project/qemu-devel/patch/1284842625-13920-1-git-send-email-stefa...@linux.vnet.ibm.com/










Re: [PATCH v2 07/12] hw/block/pflash_cfi02: Factor out pflash_reset_state_machine()

2021-03-10 Thread Bin Meng
On Thu, Mar 11, 2021 at 1:36 AM Philippe Mathieu-Daudé
 wrote:
>
> There is multiple places resetting the internal state machine.
> Factor the code out in a new pflash_reset_state_machine() method.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/block/pflash_cfi02.c | 20 +++-
>  1 file changed, 11 insertions(+), 9 deletions(-)
>

Reviewed-by: Bin Meng 



Re: [PATCH v2 08/12] hw/block/pflash_cfi02: Add DeviceReset method

2021-03-10 Thread Bin Meng
On Thu, Mar 11, 2021 at 1:22 AM Philippe Mathieu-Daudé
 wrote:
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/block/pflash_cfi02.c | 8 
>  1 file changed, 8 insertions(+)
>

Reviewed-by: Bin Meng 



Re: [PATCH v2 11/12] hw/block/pflash_cfi01: Correct the type of PFlashCFI01.ro

2021-03-10 Thread Bin Meng
On Thu, Mar 11, 2021 at 1:28 AM Philippe Mathieu-Daudé
 wrote:
>
> From: David Edmondson 
>
> PFlashCFI01.ro is a bool, declare it as such.
>
> Signed-off-by: David Edmondson 
> Reviewed-by: Philippe Mathieu-Daudé 
> Message-Id: <20210216142721.1985543-3-david.edmond...@oracle.com>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/block/pflash_cfi01.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>

Reviewed-by: Bin Meng 



Re: [PATCH v2 12/12] hw/block/pflash_cfi: Replace DPRINTF with trace events

2021-03-10 Thread Bin Meng
On Thu, Mar 11, 2021 at 1:43 AM Philippe Mathieu-Daudé
 wrote:
>
> From: David Edmondson 
>
> Rather than having a device specific debug implementation in
> pflash_cfi01.c and pflash_cfi02.c, use the standard tracing facility.
>
> Signed-off-by: David Edmondson 
> Reviewed-by: Philippe Mathieu-Daudé 
> Message-Id: <20210216142721.1985543-2-david.edmond...@oracle.com>
> [PMD: Rebased]
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/block/pflash_cfi01.c | 81 +
>  hw/block/pflash_cfi02.c | 78 ---
>  hw/block/trace-events   | 41 -
>  3 files changed, 95 insertions(+), 105 deletions(-)
>

Reviewed-by: Bin Meng 



Re: [PATCH v2 10/12] hw/block/pflash_cfi01: Extract pflash_mode_read_array()

2021-03-10 Thread Bin Meng
On Thu, Mar 11, 2021 at 1:37 AM Philippe Mathieu-Daudé
 wrote:
>
> The same pattern is used when setting the flash in READ_ARRAY mode:
> - Set the state machine command to READ_ARRAY
> - Reset the write_cycle counter
> - Reset the memory region in ROMD
>
> Refactor the current code by extracting this pattern.
> It is used three times:
>
> - On a read access (on invalid command).
>
> - On a write access (on command failure, error, or explicitly asked)
>
> - When the device is initialized. Here the ROMD mode is hidden
>   by the memory_region_init_rom_device() call.
>
> Reviewed-by: Alistair Francis 
> Reviewed-by: David Edmondson 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/block/pflash_cfi01.c | 40 +---
>  1 file changed, 17 insertions(+), 23 deletions(-)
>
> diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
> index 2618e00926d..32c9b289715 100644
> --- a/hw/block/pflash_cfi01.c
> +++ b/hw/block/pflash_cfi01.c
> @@ -115,6 +115,19 @@ static const VMStateDescription vmstate_pflash = {
>  }
>  };
>
> +static void pflash_mode_read_array(PFlashCFI01 *pfl)
> +{
> +trace_pflash_mode_read_array();

Duplicated trace calls

> +/*
> + * The command 0x00 is not assigned by the CFI open standard,
> + * but QEMU historically uses it for the READ_ARRAY command (0xff).
> + */
> +trace_pflash_mode_read_array();
> +pfl->cmd = 0x00;
> +pfl->wcycle = 0;
> +memory_region_rom_device_set_romd(&pfl->mem, true);
> +}
> +
>  /*
>   * Perform a CFI query based on the bank width of the flash.
>   * If this code is called we know we have a device_width set for
> @@ -283,12 +296,7 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr 
> offset,
>  default:
>  /* This should never happen : reset state & treat it as a read */
>  DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
> -pfl->wcycle = 0;
> -/*
> - * The command 0x00 is not assigned by the CFI open standard,
> - * but QEMU historically uses it for the READ_ARRAY command (0xff).
> - */
> -pfl->cmd = 0x00;
> +pflash_mode_read_array(pfl);

This adds a memory_region_rom_device_set_romd() call compared to the
original codes. Please double check if this is correct.

>  /* fall through to read code */
>  case 0x00: /* This model reset value for READ_ARRAY (not CFI compliant) 
> */
>  /* Flash area read */
> @@ -663,10 +671,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
>"\n", __func__, offset, pfl->wcycle, pfl->cmd, value);
>
>   mode_read_array:
> -trace_pflash_mode_read_array();
> -memory_region_rom_device_set_romd(&pfl->mem, true);
> -pfl->wcycle = 0;
> -pfl->cmd = 0x00; /* This model reset value for READ_ARRAY (not CFI) */
> +pflash_mode_read_array(pfl);
>  }
>
>
> @@ -872,13 +877,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
> **errp)
>  pfl->max_device_width = pfl->device_width;
>  }
>
> -pfl->wcycle = 0;
> -/*
> - * The command 0x00 is not assigned by the CFI open standard,
> - * but QEMU historically uses it for the READ_ARRAY command (0xff).
> - */
> -pfl->cmd = 0x00;
>  pfl->status = 0x80; /* WSM ready */
> +pflash_mode_read_array(pfl);

ditto

>  pflash_cfi01_fill_cfi_table(pfl);
>  }
>
> @@ -887,13 +887,7 @@ static void pflash_cfi01_system_reset(DeviceState *dev)
>  PFlashCFI01 *pfl = PFLASH_CFI01(dev);
>
>  trace_pflash_reset();
> -/*
> - * The command 0x00 is not assigned by the CFI open standard,
> - * but QEMU historically uses it for the READ_ARRAY command (0xff).
> - */
> -pfl->cmd = 0x00;
> -pfl->wcycle = 0;
> -memory_region_rom_device_set_romd(&pfl->mem, true);
> +pflash_mode_read_array(pfl);
>  /*
>   * The WSM ready timer occurs at most 150ns after system reset.
>   * This model deliberately ignores this delay.

Regards,
Bin



  1   2   3   4   5   >