[PATCH v4] fuzz: add oss-fuzz build-script

2020-06-11 Thread Alexander Bulekov
It is neater to keep this in the QEMU repo, since any change that
requires an update to the oss-fuzz build configuration, can make the
necessary changes in the same series.

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Alexander Bulekov 
Reviewed-by: Darren Kenny 
---

v4: adds fatal() for error-handling, as suggested by Darren

 MAINTAINERS   |   1 +
 scripts/oss-fuzz/build.sh | 105 ++
 2 files changed, 106 insertions(+)
 create mode 100755 scripts/oss-fuzz/build.sh

diff --git a/MAINTAINERS b/MAINTAINERS
index 3abe3faa4e..094a37ebb3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2336,6 +2336,7 @@ R: Bandan Das 
 R: Stefan Hajnoczi 
 S: Maintained
 F: tests/qtest/fuzz/
+F: scripts/oss-fuzz/
 
 Register API
 M: Alistair Francis 
diff --git a/scripts/oss-fuzz/build.sh b/scripts/oss-fuzz/build.sh
new file mode 100755
index 00..f5cee3d67e
--- /dev/null
+++ b/scripts/oss-fuzz/build.sh
@@ -0,0 +1,105 @@
+#!/bin/sh -e
+#
+# OSS-Fuzz build script. See:
+# https://google.github.io/oss-fuzz/getting-started/new-project-guide/#buildsh
+#
+# The file is consumed by:
+# https://github.com/google/oss-fuzz/blob/master/projects/qemu/Dockerfiles
+#
+# This code is licensed under the GPL version 2 or later.  See
+# the COPYING file in the top-level directory.
+#
+
+# build project
+# e.g.
+# ./autogen.sh
+# ./configure
+# make -j$(nproc) all
+
+# build fuzzers
+# e.g.
+# $CXX $CXXFLAGS -std=c++11 -Iinclude \
+# /path/to/name_of_fuzzer.cc -o $OUT/name_of_fuzzer \
+# $LIB_FUZZING_ENGINE /path/to/library.a
+
+fatal () {
+echo "Error : ${*}, exiting."
+exit 1
+}
+
+OSS_FUZZ_BUILD_DIR="./build-oss-fuzz/"
+
+# There seems to be a bug in clang-11 (used for builds on oss-fuzz) :
+#   accel/tcg/cputlb.o: In function `load_memop':
+#   accel/tcg/cputlb.c:1505: undefined reference to `qemu_build_not_reached'
+#
+# When building with optimization, the compiler is expected to prove that the
+# statement cannot be reached, and remove it. For some reason clang-11 doesn't
+# remove it, resulting in an unresolved reference to qemu_build_not_reached
+# Undefine the __OPTIMIZE__ macro which compiler.h relies on to choose whether
+# to " #define qemu_build_not_reached()  g_assert_not_reached() "
+EXTRA_CFLAGS="$CFLAGS -U __OPTIMIZE__"
+
+if ! { [ -e "./COPYING" ] &&
+   [ -e "./MAINTAINERS" ] &&
+   [ -e "./Makefile" ] &&
+   [ -e "./docs" ] &&
+   [ -e "./VERSION" ] &&
+   [ -e "./linux-user" ] &&
+   [ -e "./softmmu" ];} ; then
+fatal "Please run the script from the top of the QEMU tree"
+fi
+
+mkdir -p $OSS_FUZZ_BUILD_DIR || fatal "mkdir $OSS_FUZZ_BUILD_DIR failed"
+cd $OSS_FUZZ_BUILD_DIR || fatal "cd $OSS_FUZZ_BUILD_DIR failed"
+
+
+if [ -z ${LIB_FUZZING_ENGINE+x} ]; then
+LIB_FUZZING_ENGINE="-fsanitize=fuzzer"
+fi
+
+if [ -z ${OUT+x} ]; then
+DEST_DIR=$(realpath "./DEST_DIR")
+else
+DEST_DIR=$OUT
+fi
+
+mkdir -p "$DEST_DIR/lib/"  # Copy the shared libraries here
+
+# Build once to get the list of dynamic lib paths, and copy them over
+../configure --disable-werror --cc="$CC" --cxx="$CXX" \
+--extra-cflags="$EXTRA_CFLAGS"
+
+if ! make CONFIG_FUZZ=y CFLAGS="$LIB_FUZZING_ENGINE" "-j$(nproc)" \
+i386-softmmu/fuzz; then
+fatal "Build failed. Please specify a compiler with fuzzing support"\
+  "using the \$CC and \$CXX environemnt variables, or specify a"\
+  "\$LIB_FUZZING_ENGINE compatible with your compiler"\
+  "\nFor example: CC=clang CXX=clang++ $0"
+fi
+
+for i in $(ldd ./i386-softmmu/qemu-fuzz-i386 | cut -f3 -d' '); do
+cp "$i" "$DEST_DIR/lib/"
+done
+rm ./i386-softmmu/qemu-fuzz-i386
+
+# Build a second time to build the final binary with correct rpath
+../configure --bindir="$DEST_DIR" --datadir="$DEST_DIR/data/" --disable-werror 
\
+--cc="$CC" --cxx="$CXX" --extra-cflags="$EXTRA_CFLAGS" \
+--extra-ldflags="-Wl,-rpath,'\$\$ORIGIN/lib'"
+make CONFIG_FUZZ=y CFLAGS="$LIB_FUZZING_ENGINE" "-j$(nproc)" i386-softmmu/fuzz
+
+# Copy over the datadir
+cp  -r ../pc-bios/ "$DEST_DIR/pc-bios"
+
+# Run the fuzzer with no arguments, to print the help-string and get the list
+# of available fuzz-targets. Copy over the qemu-fuzz-i386, naming it according
+# to each available fuzz target (See 05509c8e6d fuzz: select fuzz target using
+# executable name)
+for target in $(./i386-softmmu/qemu-fuzz-i386 | awk '$1 ~ /\*/  {print $2}');
+do
+cp ./i386-softmmu/qemu-fuzz-i386 "$DEST_DIR/qemu-fuzz-i386-target-$target"
+done
+
+echo "Done. The fuzzers are located in $DEST_DIR"
+exit 0
-- 
2.26.2




[Bug 1882851] Re: QEMU video freezes with "Guest disabled display" (virtio driver)

2020-06-11 Thread Diego Viola
** Attachment added: "bisectlog.txt"
   
https://bugs.launchpad.net/qemu/+bug/1882851/+attachment/5383160/+files/bisectlog.txt

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1882851

Title:
  QEMU video freezes with "Guest disabled display" (virtio driver)

Status in QEMU:
  New

Bug description:
  I am using Arch Linux as my Guest and Host OS, after starting qemu
  with the following command:

$ qemu-system-x86_64 -enable-kvm -hda arch-zoom.qcow2 -m 4G -vga
  virtio

  and waiting for a screen blank, I get this message:

Guest disabled display

  And nothing happens after that, I can move the mouse or hit any key,
  and the message is still there.

  I can still reboot the VM but that's not optimal.

  I can reproduce this with the latest QEMU release (5.0.0) or git master, 
  I also tried this with older releases (4.0.0, 3.0.0) and the issue is still 
there.

  I can't reproduce this with other video drivers (std, qxl).

  With std/qxl the screen will blank a bit and then continue as normal.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1882851/+subscriptions



[Bug 1882851] Re: QEMU video freezes with "Guest disabled display" (virtio driver)

2020-06-11 Thread Diego Viola
OK, I was able to bisect, here is the result:

[diego@arch-zoom linux]$ git bisect bad
3954ff10e06e4fbc548fc02ff1fcaaac3228fed5 is the first bad commit
commit 3954ff10e06e4fbc548fc02ff1fcaaac3228fed5
Author: Gerd Hoffmann 
Date:   Thu Dec 12 13:53:44 2019 +0100

drm/virtio: skip set_scanout if framebuffer didn't change

v2: also check src rect (Chia-I Wu).

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Chia-I Wu 
Link: 
http://patchwork.freedesktop.org/patch/msgid/20191212125346.8334-2-kra...@redhat.com

 drivers/gpu/drm/virtio/virtgpu_plane.c | 35 --
 1 file changed, 21 insertions(+), 14 deletions(-)
[diego@arch-zoom linux]$

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1882851

Title:
  QEMU video freezes with "Guest disabled display" (virtio driver)

Status in QEMU:
  New

Bug description:
  I am using Arch Linux as my Guest and Host OS, after starting qemu
  with the following command:

$ qemu-system-x86_64 -enable-kvm -hda arch-zoom.qcow2 -m 4G -vga
  virtio

  and waiting for a screen blank, I get this message:

Guest disabled display

  And nothing happens after that, I can move the mouse or hit any key,
  and the message is still there.

  I can still reboot the VM but that's not optimal.

  I can reproduce this with the latest QEMU release (5.0.0) or git master, 
  I also tried this with older releases (4.0.0, 3.0.0) and the issue is still 
there.

  I can't reproduce this with other video drivers (std, qxl).

  With std/qxl the screen will blank a bit and then continue as normal.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1882851/+subscriptions



Re: [PATCH 0/5] linux-user: Support extended clone(CLONE_VM)

2020-06-11 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200612014606.147691-1-...@google.com/



Hi,

This series failed the docker-quick@centos7 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===

+++ /tmp/qemu-test/build/tests/qemu-iotests/041.out.bad 2020-06-12 
03:41:14.015076859 +
@@ -1,5 +1,30 @@
-
+WARNING:qemu.machine:qemu received signal 9: 
/tmp/qemu-test/build/tests/qemu-iotests/../../x86_64-softmmu/qemu-system-x86_64 
-display none -vga none -chardev 
socket,id=mon,path=/tmp/tmp.YHsXXgjzyL/qemu-22509-monitor.sock -mon 
chardev=mon,mode=control -qtest 
unix:path=/tmp/tmp.YHsXXgjzyL/qemu-22509-qtest.sock -accel qtest -nodefaults 
-display none -accel qtest -drive 
if=virtio,id=drive0,file=/tmp/qemu-test/test.img,format=qcow2,cache=writeback,aio=threads,node-name=top,backing.node-name=base
 -drive if=ide,id=drive1,media=cdrom
+..E.
+==
+ERROR: test_pause (__main__.TestSingleBlockdev)
+--
+Traceback (most recent call last):
+  File "041", line 108, in test_pause
---
 Ran 104 tests
 
-OK
+FAILED (errors=1)
  TESTiotest-qcow2: 042
  TESTiotest-qcow2: 043
  TESTiotest-qcow2: 046
---
Not run: 259
Failures: 041
Failed 1 of 119 iotests
make: *** [check-tests/check-block.sh] Error 1
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 665, in 
sys.exit(main())
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=0b953bb4c5534a2f9f54bbb077c4a060', '-u', 
'1003', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew2/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-fy1xwr_z/src/docker-src.2020-06-11-23.31.14.29203:/var/tmp/qemu:z,ro',
 'qemu:centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=0b953bb4c5534a2f9f54bbb077c4a060
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-fy1xwr_z/src'
make: *** [docker-run-test-quick@centos7] Error 2

real17m15.344s
user0m8.554s


The full log is available at
http://patchew.org/logs/20200612014606.147691-1-...@google.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH 9/9] migration/ram: calculate un/encoded_size only whenneeded.

2020-06-11 Thread maozy




On 6/12/20 3:05 AM, Dr. David Alan Gilbert wrote:

* Mao Zhongyi (maozhon...@cmss.chinamobile.com) wrote:

Signed-off-by: Mao Zhongyi 
---
  migration/ram.c | 9 +
  1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 41cc530d9d..ca20030b64 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -910,14 +910,15 @@ static void migration_update_rates(RAMState *rs, int64_t 
end_time)
  xbzrle_counters.cache_miss_rate = (double)(xbzrle_counters.cache_miss 
-
  rs->xbzrle_cache_miss_prev) / page_count;
  rs->xbzrle_cache_miss_prev = xbzrle_counters.cache_miss;
-encoded_size = (xbzrle_counters.pages - rs->xbzrle_pages_prev) *
- TARGET_PAGE_SIZE;
-encoded_size = xbzrle_counters.bytes - rs->xbzrle_bytes_prev;
  if (xbzrle_counters.pages == rs->xbzrle_pages_prev) {
  xbzrle_counters.encoding_rate = 0;
-} else if (!encoded_size) {
+} else if (xbzrle_counters.bytes == rs->xbzrle_bytes_prev) {


No, I don't think this change is worth it - this is really just the same
as 'encoded_size', and then we may as well keep the two together.


ok, thanks, let's keep 'encode_size' here.

BTW, this change borrows from the behavior of comppressed:

...
compressed_size = compression_counters.compressed_size -
  rs->compressed_size_prev;
if (compressed_size) {
double uncompressed_size = (compression_counters.pages -
rs->compress_pages_prev) * 
TARGET_PAGE_SIZE;


/* Compression-Ratio = Uncompressed-size / Compressed-size */
compression_counters.compression_rate =
uncompressed_size / 
compressed_size;

...


It splits 'compressed_size' and 'uncompressed_size', and calculates
'uncompressed_size' only when needed. Although 'unencoded_size' is
calculated, it is not necessarily used. if you think this split is
unnecessary, just discard it, so do I need to drop this patch and
resend the v2?

Thanks,
Mao



Dave


  xbzrle_counters.encoding_rate = UINT64_MAX;
  } else {
+unencoded_size = (xbzrle_counters.pages - rs->xbzrle_pages_prev) *
+ TARGET_PAGE_SIZE;
+encoded_size = xbzrle_counters.bytes - rs->xbzrle_bytes_prev;
+
  xbzrle_counters.encoding_rate = unencoded_size / encoded_size;
  }
  rs->xbzrle_pages_prev = xbzrle_counters.pages;
--
2.17.1





--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK








RE: [PATCH] kvm: support to get/set dirty log initial-all-set capability

2020-06-11 Thread Zhoujian (jay)



> -Original Message-
> From: Paolo Bonzini [mailto:pbonz...@redhat.com]
> Sent: Wednesday, March 18, 2020 6:48 PM
> To: Zhoujian (jay) ; qemu-devel@nongnu.org;
> k...@vger.kernel.org
> Cc: m...@redhat.com; coh...@redhat.com; pet...@redhat.com; wangxin (U)
> ; Huangweidong (C)
> ; Liujinsong (Paul) 
> Subject: Re: [PATCH] kvm: support to get/set dirty log initial-all-set 
> capability
> 
> On 04/03/20 03:55, Jay Zhou wrote:
> > Since the new capability KVM_DIRTY_LOG_INITIALLY_SET of
> > KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 has been introduced in the kernel,
> > tweak the userspace side to detect and enable this capability.
> >
> > Signed-off-by: Jay Zhou 
> > ---
> >  accel/kvm/kvm-all.c   | 21 ++---
> >  linux-headers/linux/kvm.h |  3 +++
> >  2 files changed, 17 insertions(+), 7 deletions(-)
> >
> > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index
> > 439a4efe52..45ab25be63 100644
> > --- a/accel/kvm/kvm-all.c
> > +++ b/accel/kvm/kvm-all.c
> > @@ -100,7 +100,7 @@ struct KVMState
> >  bool kernel_irqchip_required;
> >  OnOffAuto kernel_irqchip_split;
> >  bool sync_mmu;
> > -bool manual_dirty_log_protect;
> > +uint64_t manual_dirty_log_protect;
> >  /* The man page (and posix) say ioctl numbers are signed int, but
> >   * they're not.  Linux, glibc and *BSD all treat ioctl numbers as
> >   * unsigned, and treating them as signed here can break things */
> > @@ -1882,6 +1882,7 @@ static int kvm_init(MachineState *ms)
> >  int ret;
> >  int type = 0;
> >  const char *kvm_type;
> > +uint64_t dirty_log_manual_caps;
> >
> >  s = KVM_STATE(ms->accelerator);
> >
> > @@ -2007,14 +2008,20 @@ static int kvm_init(MachineState *ms)
> >  s->coalesced_pio = s->coalesced_mmio &&
> > kvm_check_extension(s,
> KVM_CAP_COALESCED_PIO);
> >
> > -s->manual_dirty_log_protect =
> > +dirty_log_manual_caps =
> >  kvm_check_extension(s,
> KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
> > -if (s->manual_dirty_log_protect) {
> > -ret = kvm_vm_enable_cap(s,
> KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0, 1);
> > +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
> KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 "
> > -"but failed.  Falling back to the legacy mode. ");
> > -s->manual_dirty_log_protect = false;
> > +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;
> >  }
> >  }
> >
> > diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
> > index 265099100e..3cb71c2b19 100644
> > --- a/linux-headers/linux/kvm.h
> > +++ b/linux-headers/linux/kvm.h
> > @@ -1628,4 +1628,7 @@ struct kvm_hyperv_eventfd {
> >  #define KVM_HYPERV_CONN_ID_MASK0x00ff
> >  #define KVM_HYPERV_EVENTFD_DEASSIGN(1 << 0)
> >
> > +#define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE(1 << 0)
> > +#define KVM_DIRTY_LOG_INITIALLY_SET(1 << 1)
> > +
> >  #endif /* __LINUX_KVM_H */
> >
> 
> Queued, thanks.
> 

Hi Paolo,

It seems that this patch isn't included in your last pull request...
If there's something else to be done, please let me know.

Regards,
Jay Zhou



[PATCH 5/6] audio/jack: honour the enable state of the audio device

2020-06-11 Thread Geoffrey McRae
Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 29 +
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index 249cbd3265..b2b53985ae 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -56,7 +56,7 @@ typedef struct QJackClient {
 AudiodevJackPerDirectionOptions *opt;
 
 bool out;
-bool finished;
+bool enabled;
 bool connect_ports;
 int  packets;
 
@@ -271,9 +271,17 @@ static int qjack_process(jack_nframes_t nframes, void *arg)
 }
 
 if (c->out) {
-qjack_buffer_read_l(>fifo, buffers, nframes);
+if (likely(c->enabled)) {
+qjack_buffer_read_l(>fifo, buffers, nframes);
+} else {
+for(int i = 0; i < c->nchannels; ++i) {
+memset(buffers[i], 0, nframes * sizeof(float));
+}
+}
 } else {
-qjack_buffer_write_l(>fifo, buffers, nframes);
+if (likely(c->enabled)) {
+qjack_buffer_write_l(>fifo, buffers, nframes);
+}
 }
 
 return 0;
@@ -314,8 +322,8 @@ static void qjack_client_recover(QJackClient *c)
 if (c->state == QJACK_STATE_DISCONNECTED &&
 c->packets % 100 == 0) {
 
-/* if not finished then attempt to recover */
-if (!c->finished) {
+/* if enabled then attempt to recover */
+if (c->enabled) {
 dolog("attempting to reconnect to server\n");
 qjack_client_init(c);
 }
@@ -387,7 +395,6 @@ static int qjack_client_init(QJackClient *c)
 char client_name[jack_client_name_size()];
 jack_options_t options = JackNullOption;
 
-c->finished  = false;
 c->connect_ports = true;
 
 snprintf(client_name, sizeof(client_name), "%s-%s",
@@ -483,8 +490,10 @@ static int qjack_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 }
 
 jo->c.out   = true;
+jo->c.enabled   = false;
 jo->c.nchannels = as->nchannels;
 jo->c.opt   = dev->u.jack.out;
+
 int ret = qjack_client_init(>c);
 if (ret != 0) {
 return ret;
@@ -519,8 +528,10 @@ static int qjack_init_in(HWVoiceIn *hw, struct audsettings 
*as,
 }
 
 ji->c.out   = false;
+ji->c.enabled   = false;
 ji->c.nchannels = as->nchannels;
 ji->c.opt   = dev->u.jack.in;
+
 int ret = qjack_client_init(>c);
 if (ret != 0) {
 return ret;
@@ -568,23 +579,25 @@ static void qjack_client_fini(QJackClient *c)
 static void qjack_fini_out(HWVoiceOut *hw)
 {
 QJackOut *jo = (QJackOut *)hw;
-jo->c.finished = true;
 qjack_client_fini(>c);
 }
 
 static void qjack_fini_in(HWVoiceIn *hw)
 {
 QJackIn *ji = (QJackIn *)hw;
-ji->c.finished = true;
 qjack_client_fini(>c);
 }
 
 static void qjack_enable_out(HWVoiceOut *hw, bool enable)
 {
+QJackOut *jo = (QJackOut *)hw;
+jo->c.enabled = enable;
 }
 
 static void qjack_enable_in(HWVoiceIn *hw, bool enable)
 {
+QJackIn *ji = (QJackIn *)hw;
+ji->c.enabled = enable;
 }
 
 static int qjack_thread_creator(jack_native_thread_t *thread,
-- 
2.20.1




[PATCH 6/6] audio/jack: simplify the re-init code path

2020-06-11 Thread Geoffrey McRae
Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index b2b53985ae..72ed7c4929 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -395,6 +395,10 @@ static int qjack_client_init(QJackClient *c)
 char client_name[jack_client_name_size()];
 jack_options_t options = JackNullOption;
 
+if (c->state == QJACK_STATE_RUNNING) {
+return 0;
+}
+
 c->connect_ports = true;
 
 snprintf(client_name, sizeof(client_name), "%s-%s",
@@ -485,9 +489,7 @@ static int qjack_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 QJackOut *jo  = (QJackOut *)hw;
 Audiodev *dev = (Audiodev *)drv_opaque;
 
-if (jo->c.state != QJACK_STATE_DISCONNECTED) {
-return 0;
-}
+qjack_client_fini(>c);
 
 jo->c.out   = true;
 jo->c.enabled   = false;
@@ -523,9 +525,7 @@ static int qjack_init_in(HWVoiceIn *hw, struct audsettings 
*as,
 QJackIn  *ji  = (QJackIn *)hw;
 Audiodev *dev = (Audiodev *)drv_opaque;
 
-if (ji->c.state != QJACK_STATE_DISCONNECTED) {
-return 0;
-}
+qjack_client_fini(>c);
 
 ji->c.out   = false;
 ji->c.enabled   = false;
-- 
2.20.1




[PATCH 4/6] audio/jack: do not remove ports when finishing

2020-06-11 Thread Geoffrey McRae
This fixes a hang when there is a communications issue with the JACK
server. Simply closing the connection is enough to completely clean up
and as such we do not need to remove the ports first.

Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index 58c7344497..249cbd3265 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -548,9 +548,6 @@ static void qjack_client_fini(QJackClient *c)
 {
 switch (c->state) {
 case QJACK_STATE_RUNNING:
-for (int i = 0; i < c->nchannels; ++i) {
-jack_port_unregister(c->client, c->port[i]);
-}
 jack_deactivate(c->client);
 /* fallthrough */
 
-- 
2.20.1




[PATCH 3/6] audio/jack: remove invalid set of input support bool

2020-06-11 Thread Geoffrey McRae
Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index fb8efd7af7..58c7344497 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -607,9 +607,6 @@ static int qjack_thread_creator(jack_native_thread_t 
*thread,
 static void *qjack_init(Audiodev *dev)
 {
 assert(dev->driver == AUDIODEV_DRIVER_JACK);
-
-dev->u.jack.has_in = false;
-
 return dev;
 }
 
-- 
2.20.1




[PATCH 2/6] audio/jack: remove unused stopped state

2020-06-11 Thread Geoffrey McRae
Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index d0b6f748f2..fb8efd7af7 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -38,7 +38,6 @@ struct QJack;
 
 typedef enum QJackState {
 QJACK_STATE_DISCONNECTED,
-QJACK_STATE_STOPPED,
 QJACK_STATE_RUNNING,
 QJACK_STATE_SHUTDOWN
 }
@@ -549,9 +548,6 @@ static void qjack_client_fini(QJackClient *c)
 {
 switch (c->state) {
 case QJACK_STATE_RUNNING:
-/* fallthrough */
-
-case QJACK_STATE_STOPPED:
 for (int i = 0; i < c->nchannels; ++i) {
 jack_port_unregister(c->client, c->port[i]);
 }
-- 
2.20.1




[PATCH 0/6] audio/jack: fixes to overall jack behaviour

2020-06-11 Thread Geoffrey McRae
Sorry for the spam, resubmitted due to missing subject on this cover
letter. Seems patchew.org can't find the associated patches without it.

This patch set addresses several issues that cause inconsistent
behaviour in the guest when the sound device is stopped and started or
the JACK server stops responding on the host.

Geoffrey McRae (6):
  audio/jack: fix invalid minimum buffer size check
  audio/jack: remove unused stopped state
  audio/jack: remove invalid set of input support bool
  audio/jack: do not remove ports when finishing
  audio/jack: honour the enable state of the audio device
  audio/jack: simplify the re-init code path

 audio/jackaudio.c | 73 ---
 1 file changed, 38 insertions(+), 35 deletions(-)

-- 
2.20.1




[PATCH 1/6] audio/jack: fix invalid minimum buffer size check

2020-06-11 Thread Geoffrey McRae
Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index 722ddb1dfe..d0b6f748f2 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -434,17 +434,6 @@ static int qjack_client_init(QJackClient *c)
 jack_set_xrun_callback(c->client, qjack_xrun, c);
 jack_on_shutdown(c->client, qjack_shutdown, c);
 
-/*
- * ensure the buffersize is no smaller then 512 samples, some (all?) qemu
- * virtual devices do not work correctly otherwise
- */
-if (c->buffersize < 512) {
-c->buffersize = 512;
-}
-
-/* create a 2 period buffer */
-qjack_buffer_create(>fifo, c->nchannels, c->buffersize * 2);
-
 /* allocate and register the ports */
 c->port = g_malloc(sizeof(jack_port_t *) * c->nchannels);
 for (int i = 0; i < c->nchannels; ++i) {
@@ -468,6 +457,17 @@ static int qjack_client_init(QJackClient *c)
 jack_activate(c->client);
 c->buffersize = jack_get_buffer_size(c->client);
 
+/*
+ * ensure the buffersize is no smaller then 512 samples, some (all?) qemu
+ * virtual devices do not work correctly otherwise
+ */
+if (c->buffersize < 512) {
+c->buffersize = 512;
+}
+
+/* create a 2 period buffer */
+qjack_buffer_create(>fifo, c->nchannels, c->buffersize * 2);
+
 qjack_client_connect_ports(c);
 c->state = QJACK_STATE_RUNNING;
 return 0;
-- 
2.20.1




Re: [PULL 000/115] Huge miscellaneous pull request for 2020-06-11

2020-06-11 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200611194449.31468-1-pbonz...@redhat.com/



Hi,

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

Message-id: 20200611194449.31468-1-pbonz...@redhat.com
Subject: [PULL 000/115] Huge miscellaneous pull request for 2020-06-11
Type: series

=== 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/20200612014606.147691-1-...@google.com -> 
patchew/20200612014606.147691-1-...@google.com
Switched to a new branch 'test'
b258374 target/i386: Remove obsolete TODO file
ed8ffec stubs: move Xen stubs to accel/
9da3214 replay: fix replay shutdown for console mode
8cf1910 exec/cpu-common: Move MUSB specific typedefs to 'hw/usb/hcd-musb.h'
b4bf922 hw/usb: Move device-specific declarations to new 'hcd-musb.h' header
5988475 exec/memory: Remove unused MemoryRegionMmio type
79d4c74 checkpatch: reversed logic with acpi test checks
11943a6 target/i386: sev: Unify SEVState and SevGuestState
722d1df target/i386: sev: Remove redundant handle field
ef7e4eb target/i386: sev: Remove redundant policy field
c0fa653 target/i386: sev: Remove redundant cbitpos and reduced_phys_bits fields
832d459 target/i386: sev: Partial cleanup to sev_state global
560d42b target/i386: sev: Embed SEVState in SevGuestState
56fe4d8 target/i386: sev: Rename QSevGuestInfo
4902392 target/i386: sev: Move local structure definitions into .c file
b8dc835 target/i386: sev: Remove unused QSevGuestInfoClass
5ec6d66 xen: fix build without pci passthrough
93262a0 i386: hvf: Drop HVFX86EmulatorState
b52a4bf i386: hvf: Move mmio_buf into CPUX86State
20208b4 i386: hvf: Move lazy_flags into CPUX86State
df05641 i386: hvf: Drop regs in HVFX86EmulatorState
e978983 i386: hvf: Drop copy of RFLAGS defines
0141723 i386: hvf: Drop rflags from HVFX86EmulatorState
e1de961 i386: hvf: Drop fetch_rip from HVFX86EmulatorState
ed88ce7 i386: hvf: Use IP from CPUX86State
ddb005d i386: hvf: Use ins_len to advance IP
c4d282b i386: hvf: Drop unused variable
b587a1b i386: hvf: Drop useless declarations in sysemu
7e1a493 i386: hvf: Move HVFState definition into hvf
709b437 target/ppc: Restrict PPCVirtualHypervisorClass to system-mode
238000a sysemu/hvf: Only declare hvf_allowed when HVF is available
3b8e276 sysemu/tcg: Only declare tcg_allowed when TCG is available
acb8d15 sysemu/accel: Restrict machine methods to system-mode
f9bd95e target/i386: correct fix for pcmpxstrx substring search
136df11 target/i386: fix IEEE x87 floating-point exception raising
f843bd2 exec: set map length to zero when returning NULL
3bd81db configure: Do not ignore malloc value
98e8ed2 qemu/thread: Mark qemu_thread_exit() with 'noreturn' attribute
3f5bb0f memory: Make 'info mtree' not display disabled regions by default
a3aaf5e util/oslib: Returns the real thread identifier on FreeBSD and NetBSD
6aa0a68 target/i386: define a new MSR based feature word - 
FEAT_PERF_CAPABILITIES
f21430a i386: Remove unused define's from hax and hvf
c130d2b replay: implement fair mutex
06644d9 hw/i386/amd_iommu: Fix the reserved bits definition of IOMMU commands
0abe63e tests: machine-none-test: Enable MicroBlaze testing
85f319e chardev/char-socket: Properly make qio connections non blocking
d0110c6 KVM: Kick resamplefd for split kernel irqchip
1ead965 KVM: Pass EventNotifier into kvm_irqchip_assign_irqfd
2b7dab6 vfio/pci: Use kvm_irqchip_add_irqfd_notifier_gsi() for irqfds
dd32581 x86/cpu: Enable AVX512_VP2INTERSECT cpu feature
7ee3b5d hw/i386/vmport: Allow QTest use without crashing
c79f240 target/i386: fix fisttpl, fisttpll handling of out-of-range values
7e360a8 target/i386: fix fbstp handling of out-of-range values
9f11ae8 target/i386: fix fbstp handling of negative zero
59ce66a target/i386: fix fxam handling of invalid encodings
68d8ffc target/i386: fix floating-point load-constant rounding
8d4006e hw/elf_ops: Do not ignore write failures when loading ELF
3a3c475 disas: Let disas::read_memory() handler return EIO on error
6bfda5f exec: Propagate cpu_memory_rw_debug() error
63d6911 exec: Let address_space_read/write_cached() propagate MemTxResult
85733ec target/i386: fix fscale handling of rounding precision
22d5344 target/i386: fix fscale handling of infinite exponents
d9e4f5b target/i386: fix fscale handling of invalid exponent encodings
23a2034 target/i386: fix fscale handling of signaling NaN
e197304 target/i386: implement special cases for fxtract
3aed295 megasas: use unsigned type for positive numeric fields
ca61e75 megasas: avoid NULL pointer dereference
dc1d959 megasas: use unsigned type for reply_queue_head and check index
7af8d9c i386/kvm: fix a use-after-free when vcpu plug/unplug
e79558f hax: Dynamic 

[PATCH 5/5] linux-user: Add PDEATHSIG test for clone process hierarchy.

2020-06-11 Thread Josh Kunz
Certain process-level linux features like subreapers, and PDEATHSIG,
depend on the guest's process hierarchy being emulated correctly on the
host. This change adds a test that makes sure PDEATHSIG works for a
guest process created with `clone`.

Signed-off-by: Josh Kunz 
---
 tests/tcg/multiarch/Makefile.target |   3 +
 tests/tcg/multiarch/linux-test.c| 160 ++--
 2 files changed, 153 insertions(+), 10 deletions(-)

diff --git a/tests/tcg/multiarch/Makefile.target 
b/tests/tcg/multiarch/Makefile.target
index cb49cc9ccb..d937b4c59b 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -60,3 +60,6 @@ endif
 
 # Update TESTS
 TESTS += $(MULTIARCH_TESTS)
+
+# linux-test.c depends on -pthread.
+LDFLAGS += -pthread
diff --git a/tests/tcg/multiarch/linux-test.c b/tests/tcg/multiarch/linux-test.c
index a7723556c2..1824a5a0c2 100644
--- a/tests/tcg/multiarch/linux-test.c
+++ b/tests/tcg/multiarch/linux-test.c
@@ -20,16 +20,19 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -41,6 +44,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define STACK_SIZE 16384
 
@@ -368,14 +372,12 @@ static void test_pipe(void)
 chk_error(close(fds[1]));
 }
 
-static int thread1_res;
-static int thread2_res;
-
 static int thread1_func(void *arg)
 {
+int *res = (int *) arg;
 int i;
 for(i=0;i<5;i++) {
-thread1_res++;
+(*res)++;
 usleep(10 * 1000);
 }
 return 0;
@@ -383,9 +385,10 @@ static int thread1_func(void *arg)
 
 static int thread2_func(void *arg)
 {
+int *res = (int *) arg;
 int i;
 for(i=0;i<6;i++) {
-thread2_res++;
+(*res)++;
 usleep(10 * 1000);
 }
 return 0;
@@ -405,25 +408,27 @@ static void test_clone(void)
 uint8_t *stack1, *stack2;
 pid_t pid1, pid2;
 
+int t1 = 0, t2 = 0;
+
 stack1 = malloc(STACK_SIZE);
 pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE,
CLONE_VM | SIGCHLD,
-"hello1"));
+));
 
 stack2 = malloc(STACK_SIZE);
 pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE,
CLONE_VM | CLONE_FS | CLONE_FILES |
CLONE_SIGHAND | CLONE_SYSVSEM | SIGCHLD,
-   "hello2"));
+   ));
 
 wait_for_child(pid1);
 free(stack1);
 wait_for_child(pid2);
 free(stack2);
 
-if (thread1_res != 5 ||
-thread2_res != 6)
+if (t1 != 5 || t2 != 6) {
 error("clone");
+}
 }
 
 /***/
@@ -562,6 +567,7 @@ static void test_clone_signal_count(void)
  * SIGCHLD.
  */
 chk_error(waitpid(pid, , __WCLONE));
+free(child_stack);
 
 chk_error(sigaction(SIGRTMIN, , NULL));
 
@@ -571,6 +577,139 @@ static void test_clone_signal_count(void)
 }
 }
 
+struct test_clone_pdeathsig_info {
+uint8_t *child_stack;
+pthread_mutex_t notify_test_mutex;
+pthread_cond_t notify_test_cond;
+pthread_mutex_t notify_parent_mutex;
+pthread_cond_t notify_parent_cond;
+bool signal_received;
+};
+
+static int test_clone_pdeathsig_child(void *arg)
+{
+struct test_clone_pdeathsig_info *info =
+(struct test_clone_pdeathsig_info *) arg;
+sigset_t wait_on, block_all;
+siginfo_t sinfo;
+struct timespec timeout;
+int ret;
+
+/* Block all signals, so SIGUSR1 will be pending when we wait on it. */
+sigfillset(_all);
+chk_error(sigprocmask(SIG_BLOCK, _all, NULL));
+
+chk_error(prctl(PR_SET_PDEATHSIG, SIGUSR1));
+
+pthread_mutex_lock(>notify_parent_mutex);
+pthread_cond_broadcast(>notify_parent_cond);
+pthread_mutex_unlock(>notify_parent_mutex);
+
+sigemptyset(_on);
+sigaddset(_on, SIGUSR1);
+timeout.tv_sec = 0;
+timeout.tv_nsec = 300 * 1000 * 1000;  /* 300ms */
+
+ret = sigtimedwait(_on, , );
+
+if (ret < 0 && errno != EAGAIN) {
+error("%m (ret=%d, errno=%d/%s)", ret, errno, strerror(errno));
+}
+if (ret == SIGUSR1) {
+info->signal_received = true;
+}
+pthread_mutex_lock(>notify_test_mutex);
+pthread_cond_broadcast(>notify_test_cond);
+pthread_mutex_unlock(>notify_test_mutex);
+_exit(0);
+}
+
+static int test_clone_pdeathsig_parent(void *arg)
+{
+struct test_clone_pdeathsig_info *info =
+(struct test_clone_pdeathsig_info *) arg;
+
+pthread_mutex_lock(>notify_parent_mutex);
+
+chk_error(clone(
+test_clone_pdeathsig_child,
+info->child_stack + STACK_SIZE,
+CLONE_VM,
+info
+));
+
+/* No need to reap the child, it will get reaped by init. */
+
+/* Wait for the child to signal that they have set up PDEATHSIG. */
+

[PATCH 2/5] linux-user: Make fd_trans task-specific.

2020-06-11 Thread Josh Kunz
The file-descriptor translation subsystem used by QEMU uses some global
variables to track file descriptors an their associated state. In the
future (when clone is implemented) it may be possible to have two
processes that share memory, but have a unique set of file descriptors.
This change associates the file-descriptor translation table with the
per-task TaskState structure. Since many tasks will share file
descriptors (e.g., threads), a structure similar to the existing structure is
used. Each task has a pointer to a global table. That table can be
shared by multiple tasks, or changed if a task needs to use a different
FD table.

Signed-off-by: Josh Kunz 
---
 linux-user/Makefile.objs   |  2 +-
 linux-user/fd-trans-tbl.c  | 13 +++
 linux-user/fd-trans-type.h | 17 +
 linux-user/fd-trans.c  |  3 --
 linux-user/fd-trans.h  | 75 --
 linux-user/main.c  |  1 +
 linux-user/qemu.h  | 24 
 linux-user/syscall.c   | 12 ++
 8 files changed, 115 insertions(+), 32 deletions(-)
 create mode 100644 linux-user/fd-trans-tbl.c
 create mode 100644 linux-user/fd-trans-type.h

diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
index d6788f012c..d19102e244 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -1,7 +1,7 @@
 obj-y = main.o syscall.o strace.o mmap.o signal.o \
elfload.o linuxload.o uaccess.o uname.o \
safe-syscall.o $(TARGET_ABI_DIR)/signal.o \
-$(TARGET_ABI_DIR)/cpu_loop.o exit.o fd-trans.o clone.o
+$(TARGET_ABI_DIR)/cpu_loop.o exit.o fd-trans.o clone.o fd-trans-tbl.o
 
 obj-$(TARGET_HAS_BFLT) += flatload.o
 obj-$(TARGET_I386) += vm86.o
diff --git a/linux-user/fd-trans-tbl.c b/linux-user/fd-trans-tbl.c
new file mode 100644
index 00..6afe91096e
--- /dev/null
+++ b/linux-user/fd-trans-tbl.c
@@ -0,0 +1,13 @@
+#include "qemu/osdep.h"
+#include "fd-trans.h"
+
+struct fd_trans_table *fd_trans_table_clone(struct fd_trans_table *tbl)
+{
+struct fd_trans_table *new_tbl = g_new0(struct fd_trans_table, 1);
+new_tbl->fd_max = tbl->fd_max;
+new_tbl->entries = g_new0(TargetFdTrans*, tbl->fd_max);
+memcpy(new_tbl->entries,
+   tbl->entries,
+   sizeof(*new_tbl->entries) * tbl->fd_max);
+return new_tbl;
+}
diff --git a/linux-user/fd-trans-type.h b/linux-user/fd-trans-type.h
new file mode 100644
index 00..06c4427642
--- /dev/null
+++ b/linux-user/fd-trans-type.h
@@ -0,0 +1,17 @@
+#ifndef FD_TRANS_TYPE_H
+#define FD_TRANS_TYPE_H
+
+/*
+ * Break out the TargetFdTrans typedefs into a separate file, to break
+ * the circular dependency between qemu.h and fd-trans.h.
+ */
+
+typedef abi_long (*TargetFdDataFunc)(void *, size_t);
+typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t);
+typedef struct TargetFdTrans {
+TargetFdDataFunc host_to_target_data;
+TargetFdDataFunc target_to_host_data;
+TargetFdAddrFunc target_to_host_addr;
+} TargetFdTrans;
+
+#endif /* FD_TRANS_TYPE_H */
diff --git a/linux-user/fd-trans.c b/linux-user/fd-trans.c
index c0687c52e6..c552034a5e 100644
--- a/linux-user/fd-trans.c
+++ b/linux-user/fd-trans.c
@@ -261,9 +261,6 @@ enum {
 QEMU___RTA_MAX
 };
 
-TargetFdTrans **target_fd_trans;
-unsigned int target_fd_max;
-
 static void tswap_nlmsghdr(struct nlmsghdr *nlh)
 {
 nlh->nlmsg_len = tswap32(nlh->nlmsg_len);
diff --git a/linux-user/fd-trans.h b/linux-user/fd-trans.h
index a3fcdaabc7..07ae04dad7 100644
--- a/linux-user/fd-trans.h
+++ b/linux-user/fd-trans.h
@@ -16,38 +16,45 @@
 #ifndef FD_TRANS_H
 #define FD_TRANS_H
 
-typedef abi_long (*TargetFdDataFunc)(void *, size_t);
-typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t);
-typedef struct TargetFdTrans {
-TargetFdDataFunc host_to_target_data;
-TargetFdDataFunc target_to_host_data;
-TargetFdAddrFunc target_to_host_addr;
-} TargetFdTrans;
+#include "qemu.h"
+#include "fd-trans-type.h"
 
-extern TargetFdTrans **target_fd_trans;
-
-extern unsigned int target_fd_max;
+/*
+ * Return a duplicate of the given fd_trans_table. This function always
+ * succeeds. Ownership of the pointed-to table is yielded to the caller. The
+ * caller is responsible for freeing the table when it is no longer in-use.
+ */
+struct fd_trans_table *fd_trans_table_clone(struct fd_trans_table *tbl);
 
 static inline TargetFdDataFunc fd_trans_target_to_host_data(int fd)
 {
-if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
-return target_fd_trans[fd]->target_to_host_data;
+TaskState *ts = (TaskState *)thread_cpu->opaque;
+struct fd_trans_table *tbl = ts->fd_trans_tbl;
+
+if (fd >= 0 && fd < tbl->fd_max && tbl->entries[fd]) {
+return tbl->entries[fd]->target_to_host_data;
 }
 return NULL;
 }
 
 static inline TargetFdDataFunc fd_trans_host_to_target_data(int fd)
 {
-if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
-return 

[PATCH 4/5] linux-user: Support CLONE_VM and extended clone options

2020-06-11 Thread Josh Kunz
The `clone` system call can be used to create new processes that share
attributes with their parents, such as virtual memory, file
system location, file descriptor tables, etc. These can be useful to a
variety of guest programs.

Before this patch, QEMU had support for a limited set of these attributes.
Basically the ones needed for threads, and the options used by fork.
This change adds support for all flag combinations involving CLONE_VM.
In theory, almost all clone options could be supported, but invocations
not using CLONE_VM are likely to run afoul of linux-user's inherently
multi-threaded design.

To add this support, this patch updates the `qemu_clone` helper. An
overview of the mechanism used to support general `clone` options with
CLONE_VM is described below.

This patch also enables by-default the `clone` unit-tests in
tests/tcg/multiarch/linux-test.c, and adds an additional test for duplicate
exit signals, based on a bug found during development.

!! Overview

Adding support for CLONE_VM is tricky. The parent and guest process will
share an address space (similar to threads), so the emulator must
coordinate between the parent and the child. Currently, QEMU relies
heavily on Thread Local Storage (TLS) as part of this coordination
strategy. For threads, this works fine, because libc manages the
thread-local data region used for TLS, when we create new threads using
`pthread_create`. Ideally we could use the same mechanism for
"process-local storage" needed to allow the parent/child processes to
emulate in tandem. Unfortunately TLS is tightly integrated into libc.
The only way to create TLS data regions is via the `pthread_create` API
which also spawns a new thread (rather than a new processes, which is
what we want). Worse still, TLS itself is a complicated arch-specific
feature that is tightly integrated into the rest of libc and the dynamic
linker. Re-implementing TLS support for QEMU would likely require a
special dynamic linker / libc. Alternatively, the popular libcs could be
extended, to allow for users to create TLS regions without creating
threads. Even if major libcs decide to add this support, QEMU will still
need a temporary work around until those libcs are widely deployed. It's
also unclear if libcs will be interested in supporting this case, since
TLS image creation is generally deeply integrated with thread setup.

In this patch, I've employed an alternative approach: spawning a thread
an "stealing" its TLS image for use in the child process. This approach
leaves a dangling thread while the TLS image is in use, but by design
that thread will not become schedulable until after the TLS data is no
longer in-use by the child (as described in a moment). Therefore, it
should cause relatively minimal overhead. When considered in the larger
context, this seems like a reasonable tradeoff.

A major complication of this approach knowing when it is safe to clean up
the stack, and TLS image, used by a child process. When a child is
created with `CLONE_VM` its stack, and TLS data, need to remain valid
until that child has either exited, or successfully called `execve` (on
`execve` the child is given a new VMM by the kernel). One approach would
be to use `waitid(WNOWAIT)` (the `WNOWAIT` allows the guest to reap the
child). The problem is that the `wait` family of calls only waits for
termination. The pattern of `clone() ... execve()` for long running
child processes is pretty common. If we waited for child processes to
exit, it's likely we would end up using substantially more memory, and
keep the suspended TLS thread around much longer than necessary.
Instead, in this patch, I've used an "trampoline" process. The real
parent first clones a trampoline, the trampoline then clones the
ultimate child using the `CLONE_VFORK` option. `CLONE_VFORK` suspends
the trampoline process until the child has exited, or called `execve`.
Once the trampoline is re-scheduled, we know it is safe to clean up
after the child. This creates one more suspended process, but typically,
the trampoline only exists for a short period of time.

!! CLONE_VM setup, step by step

1. First, the suspended thread whose TLS we will use is created using
   `pthread_create`. The thread fetches and returns it's "TLS pointer"
   (an arch-specific value given to the kernel) to the parent. It then
   blocks on a lock to prevent its TLS data from being cleaned up.
   Ultimately the lock will be unlocked by the trampoline once the child
   exits.
2. Once the TLS thread has fetched the TLS pointer, it notifies the real
   parent thread, which calls `clone()` to create the trampoline
   process. For ease of implementation, the TLS image is set for the
   trampoline process during this step. This allows the trampoline to
   use functions that require TLS if needed (e.g., printf). TLS location
   is inherited when a new child is spawned, so this TLS data will
   automatically be inherited by the child.
3. Once the trampoline has been spawned, it 

[PATCH 0/5] linux-user: Support extended clone(CLONE_VM)

2020-06-11 Thread Josh Kunz
This patch series implements extended support for the `clone` system
call. As best I can tell, any option combination including `CLONE_VM`
should be supported with the addition of this patch series. The
implementation is described in greater detail in the patches themselves.

Testing:

  * All targets built on x86_64.
  * `make check` and `make check-tcg` are passing. Additional tests have
been added to `linux-test.c` to validate clone behavior.

Caveats:

  * This series touches, but does not fix, several bits of code that are
racey (namely the sigact table and the fd trans table).
  * `exit_group` does not perform the appropriate cleanup for non-thread
children created with `CLONE_VM`. CPUs for such children are never
cleaned up. The correct implementation of exit-group is non-trivial
(since it also needs to track/handle cleanup for threads in the
clone'd child process). Also, I don't fully understand the
interaction between QOM<->linux-user. My naive implementation based
on the current implementation `exit(2)` was regularly crashing. If
maintainers have suggestions for better ways to handle exit_group,
they would be greatly appreciated. 
  * execve does not clean up the CPUs of clone'd children, for the same
reasons as `exit_group`.

Josh Kunz (5):
  linux-user: Refactor do_fork to use new `qemu_clone`
  linux-user: Make fd_trans task-specific.
  linux-user: Make sigact_table part of the task state.
  linux-user: Support CLONE_VM and extended clone options
  linux-user: Add PDEATHSIG test for clone process hierarchy.

 linux-user/Makefile.objs|   2 +-
 linux-user/clone.c  | 565 
 linux-user/clone.h  |  27 ++
 linux-user/fd-trans-tbl.c   |  13 +
 linux-user/fd-trans-type.h  |  17 +
 linux-user/fd-trans.c   |   3 -
 linux-user/fd-trans.h   |  75 ++--
 linux-user/main.c   |   1 +
 linux-user/qemu.h   |  49 +++
 linux-user/signal.c |  84 -
 linux-user/syscall.c| 452 --
 tests/tcg/multiarch/Makefile.target |   3 +
 tests/tcg/multiarch/linux-test.c| 227 ++-
 13 files changed, 1264 insertions(+), 254 deletions(-)
 create mode 100644 linux-user/clone.c
 create mode 100644 linux-user/clone.h
 create mode 100644 linux-user/fd-trans-tbl.c
 create mode 100644 linux-user/fd-trans-type.h

-- 
2.27.0.290.gba653c62da-goog




[PATCH 3/5] linux-user: Make sigact_table part of the task state.

2020-06-11 Thread Josh Kunz
sigact_table stores the signal handlers for the given process. Once we
support CLONE_VM, two tasks using the same virtual memory may need
different signal handler tables (e.g., if CLONE_SIGHAND is not
provided). Here we make sigact_table part of the TaskState, so it can be
duplicated as needed when cloning children.

Signed-off-by: Josh Kunz 
---
 linux-user/qemu.h|  8 
 linux-user/signal.c  | 35 +++
 linux-user/syscall.c | 17 +
 3 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 989e01ad8d..54bf4f47be 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -177,6 +177,12 @@ typedef struct TaskState {
  * the table itself should be guarded.
  */
 struct fd_trans_table *fd_trans_tbl;
+
+/*
+ * A table containing signal actions for the target. It should have at
+ * least TARGET_NSIG entries
+ */
+struct target_sigaction *sigact_tbl;
 } __attribute__((aligned(16))) TaskState;
 
 extern char *exec_path;
@@ -419,7 +425,9 @@ void print_syscall_ret(int num, abi_long arg1);
  */
 void print_taken_signal(int target_signum, const target_siginfo_t *tinfo);
 
+
 /* signal.c */
+struct target_sigaction *sigact_table_clone(struct target_sigaction *orig);
 void process_pending_signals(CPUArchState *cpu_env);
 void signal_init(void);
 int queue_signal(CPUArchState *env, int sig, int si_type,
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 8cf51ffecd..dc98def6d1 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -25,7 +25,13 @@
 #include "trace.h"
 #include "signal-common.h"
 
-static struct target_sigaction sigact_table[TARGET_NSIG];
+struct target_sigaltstack target_sigaltstack_used = {
+.ss_sp = 0,
+.ss_size = 0,
+.ss_flags = TARGET_SS_DISABLE,
+};
+
+typedef struct target_sigaction sigact_table[TARGET_NSIG];
 
 static void host_signal_handler(int host_signum, siginfo_t *info,
 void *puc);
@@ -542,6 +548,11 @@ static void signal_table_init(void)
 }
 }
 
+struct target_sigaction *sigact_table_clone(struct target_sigaction *orig)
+{
+return memcpy(g_new(sigact_table, 1), orig, sizeof(sigact_table));
+}
+
 void signal_init(void)
 {
 TaskState *ts = (TaskState *)thread_cpu->opaque;
@@ -556,6 +567,12 @@ void signal_init(void)
 /* Set the signal mask from the host mask. */
 sigprocmask(0, 0, >signal_mask);
 
+/*
+ * Set all host signal handlers. ALL signals are blocked during
+ * the handlers to serialize them.
+ */
+ts->sigact_tbl = (struct target_sigaction *) g_new0(sigact_table, 1);
+
 sigfillset(_mask);
 act.sa_flags = SA_SIGINFO;
 act.sa_sigaction = host_signal_handler;
@@ -568,9 +585,9 @@ void signal_init(void)
 host_sig = target_to_host_signal(i);
 sigaction(host_sig, NULL, );
 if (oact.sa_sigaction == (void *)SIG_IGN) {
-sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
+ts->sigact_tbl[i - 1]._sa_handler = TARGET_SIG_IGN;
 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
-sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
+ts->sigact_tbl[i - 1]._sa_handler = TARGET_SIG_DFL;
 }
 /* If there's already a handler installed then something has
gone horribly wrong, so don't even try to handle that case.  */
@@ -608,11 +625,12 @@ void force_sig(int sig)
 #if !defined(TARGET_RISCV)
 void force_sigsegv(int oldsig)
 {
+TaskState *ts = (TaskState *)thread_cpu->opaque;
 if (oldsig == SIGSEGV) {
 /* Make sure we don't try to deliver the signal again; this will
  * end up with handle_pending_signal() calling dump_core_and_abort().
  */
-sigact_table[oldsig - 1]._sa_handler = TARGET_SIG_DFL;
+ts->sigact_tbl[oldsig - 1]._sa_handler = TARGET_SIG_DFL;
 }
 force_sig(TARGET_SIGSEGV);
 }
@@ -837,6 +855,7 @@ int do_sigaction(int sig, const struct target_sigaction 
*act,
 struct sigaction act1;
 int host_sig;
 int ret = 0;
+TaskState* ts = (TaskState *)thread_cpu->opaque;
 
 trace_signal_do_sigaction_guest(sig, TARGET_NSIG);
 
@@ -848,7 +867,7 @@ int do_sigaction(int sig, const struct target_sigaction 
*act,
 return -TARGET_ERESTARTSYS;
 }
 
-k = _table[sig - 1];
+k = >sigact_tbl[sig - 1];
 if (oact) {
 __put_user(k->_sa_handler, >_sa_handler);
 __put_user(k->sa_flags, >sa_flags);
@@ -930,7 +949,7 @@ static void handle_pending_signal(CPUArchState *cpu_env, 
int sig,
 sa = NULL;
 handler = TARGET_SIG_IGN;
 } else {
-sa = _table[sig - 1];
+sa = >sigact_tbl[sig - 1];
 handler = sa->_sa_handler;
 }
 
@@ -1022,9 +1041,9 @@ void process_pending_signals(CPUArchState *cpu_env)
  * looping round and round indefinitely.
  */
 if (sigismember(>signal_mask, 

[PATCH 1/5] linux-user: Refactor do_fork to use new `qemu_clone`

2020-06-11 Thread Josh Kunz
This is pre-work for adding full support for the `CLONE_VM` `clone`
flag. In a follow-up patch, we'll add support to `clone.c` for
`clone_vm`-type clones beyond threads. CLONE_VM support is more
complicated, so first we're splitting existing clone mechanisms
(pthread_create, and fork) into a separate file.

Signed-off-by: Josh Kunz 
---
 linux-user/Makefile.objs |   2 +-
 linux-user/clone.c   | 152 
 linux-user/clone.h   |  27 +++
 linux-user/syscall.c | 376 +++
 4 files changed, 365 insertions(+), 192 deletions(-)
 create mode 100644 linux-user/clone.c
 create mode 100644 linux-user/clone.h

diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
index 1940910a73..d6788f012c 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -1,7 +1,7 @@
 obj-y = main.o syscall.o strace.o mmap.o signal.o \
elfload.o linuxload.o uaccess.o uname.o \
safe-syscall.o $(TARGET_ABI_DIR)/signal.o \
-$(TARGET_ABI_DIR)/cpu_loop.o exit.o fd-trans.o
+$(TARGET_ABI_DIR)/cpu_loop.o exit.o fd-trans.o clone.o
 
 obj-$(TARGET_HAS_BFLT) += flatload.o
 obj-$(TARGET_I386) += vm86.o
diff --git a/linux-user/clone.c b/linux-user/clone.c
new file mode 100644
index 00..f02ae8c464
--- /dev/null
+++ b/linux-user/clone.c
@@ -0,0 +1,152 @@
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "clone.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const unsigned long NEW_STACK_SIZE = 0x4UL;
+
+/*
+ * A completion tracks an event that can be completed. It's based on the
+ * kernel concept with the same name, but implemented with userspace locks.
+ */
+struct completion {
+/* done is set once this completion has been completed. */
+bool done;
+/* mu syncronizes access to this completion. */
+pthread_mutex_t mu;
+/* cond is used to broadcast completion status to awaiting threads. */
+pthread_cond_t cond;
+};
+
+static void completion_init(struct completion *c)
+{
+c->done = false;
+pthread_mutex_init(>mu, NULL);
+pthread_cond_init(>cond, NULL);
+}
+
+/*
+ * Block until the given completion finishes. Returns immediately if the
+ * completion has already finished.
+ */
+static void completion_await(struct completion *c)
+{
+pthread_mutex_lock(>mu);
+if (c->done) {
+pthread_mutex_unlock(>mu);
+return;
+}
+pthread_cond_wait(>cond, >mu);
+assert(c->done && "returned from cond wait without being marked as done");
+pthread_mutex_unlock(>mu);
+}
+
+/*
+ * Finish the completion. Unblocks all awaiters.
+ */
+static void completion_finish(struct completion *c)
+{
+pthread_mutex_lock(>mu);
+assert(!c->done && "trying to finish an already finished completion");
+c->done = true;
+pthread_cond_broadcast(>cond);
+pthread_mutex_unlock(>mu);
+}
+
+struct clone_thread_info {
+struct completion running;
+int tid;
+int (*callback)(void *);
+void *payload;
+};
+
+static void *clone_thread_run(void *raw_info)
+{
+struct clone_thread_info *info = (struct clone_thread_info *) raw_info;
+info->tid = syscall(SYS_gettid);
+
+/*
+ * Save out callback/payload since lifetime of info is only guaranteed
+ * until we finish the completion.
+ */
+int (*callback)(void *) = info->callback;
+void *payload = info->payload;
+completion_finish(>running);
+
+_exit(callback(payload));
+}
+
+static int clone_thread(int flags, int (*callback)(void *), void *payload)
+{
+struct clone_thread_info info;
+pthread_attr_t attr;
+int ret;
+pthread_t thread_unused;
+
+memset(, 0, sizeof(info));
+
+completion_init();
+info.callback = callback;
+info.payload = payload;
+
+(void)pthread_attr_init();
+(void)pthread_attr_setstacksize(, NEW_STACK_SIZE);
+(void)pthread_attr_setdetachstate(, PTHREAD_CREATE_DETACHED);
+
+ret = pthread_create(_unused, , clone_thread_run, (void *) 
);
+/* pthread_create returns errors directly, instead of via errno. */
+if (ret != 0) {
+errno = ret;
+ret = -1;
+} else {
+completion_await();
+ret = info.tid;
+}
+
+pthread_attr_destroy();
+return ret;
+}
+
+int qemu_clone(int flags, int (*callback)(void *), void *payload)
+{
+int ret;
+
+if (clone_flags_are_thread(flags)) {
+/*
+ * The new process uses the same flags as pthread_create, so we can
+ * use pthread_create directly. This is an optimization.
+ */
+return clone_thread(flags, callback, payload);
+}
+
+if (clone_flags_are_fork(flags)) {
+/*
+ * Special case a true `fork` clone call. This is so we can take
+ * advantage of special pthread_atfork handlers in libraries we
+ * depend on (e.g., glibc). Without this, existing users of `fork`
+ * in multi-threaded environments 

[PATCH 3/6] audio/jack: remove invalid set of input support bool

2020-06-11 Thread Geoffrey McRae
Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index fb8efd7af7..58c7344497 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -607,9 +607,6 @@ static int qjack_thread_creator(jack_native_thread_t 
*thread,
 static void *qjack_init(Audiodev *dev)
 {
 assert(dev->driver == AUDIODEV_DRIVER_JACK);
-
-dev->u.jack.has_in = false;
-
 return dev;
 }
 
-- 
2.20.1




[PATCH 4/6] audio/jack: do not remove ports when finishing

2020-06-11 Thread Geoffrey McRae
This fixes a hang when there is a communications issue with the JACK
server. Simply closing the connection is enough to completely clean up
and as such we do not need to remove the ports first.

Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index 58c7344497..249cbd3265 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -548,9 +548,6 @@ static void qjack_client_fini(QJackClient *c)
 {
 switch (c->state) {
 case QJACK_STATE_RUNNING:
-for (int i = 0; i < c->nchannels; ++i) {
-jack_port_unregister(c->client, c->port[i]);
-}
 jack_deactivate(c->client);
 /* fallthrough */
 
-- 
2.20.1




[PATCH 2/6] audio/jack: remove unused stopped state

2020-06-11 Thread Geoffrey McRae
Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index d0b6f748f2..fb8efd7af7 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -38,7 +38,6 @@ struct QJack;
 
 typedef enum QJackState {
 QJACK_STATE_DISCONNECTED,
-QJACK_STATE_STOPPED,
 QJACK_STATE_RUNNING,
 QJACK_STATE_SHUTDOWN
 }
@@ -549,9 +548,6 @@ static void qjack_client_fini(QJackClient *c)
 {
 switch (c->state) {
 case QJACK_STATE_RUNNING:
-/* fallthrough */
-
-case QJACK_STATE_STOPPED:
 for (int i = 0; i < c->nchannels; ++i) {
 jack_port_unregister(c->client, c->port[i]);
 }
-- 
2.20.1




[PATCH 5/6] audio/jack: honour the enable state of the audio device

2020-06-11 Thread Geoffrey McRae
Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 29 +
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index 249cbd3265..b2b53985ae 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -56,7 +56,7 @@ typedef struct QJackClient {
 AudiodevJackPerDirectionOptions *opt;
 
 bool out;
-bool finished;
+bool enabled;
 bool connect_ports;
 int  packets;
 
@@ -271,9 +271,17 @@ static int qjack_process(jack_nframes_t nframes, void *arg)
 }
 
 if (c->out) {
-qjack_buffer_read_l(>fifo, buffers, nframes);
+if (likely(c->enabled)) {
+qjack_buffer_read_l(>fifo, buffers, nframes);
+} else {
+for(int i = 0; i < c->nchannels; ++i) {
+memset(buffers[i], 0, nframes * sizeof(float));
+}
+}
 } else {
-qjack_buffer_write_l(>fifo, buffers, nframes);
+if (likely(c->enabled)) {
+qjack_buffer_write_l(>fifo, buffers, nframes);
+}
 }
 
 return 0;
@@ -314,8 +322,8 @@ static void qjack_client_recover(QJackClient *c)
 if (c->state == QJACK_STATE_DISCONNECTED &&
 c->packets % 100 == 0) {
 
-/* if not finished then attempt to recover */
-if (!c->finished) {
+/* if enabled then attempt to recover */
+if (c->enabled) {
 dolog("attempting to reconnect to server\n");
 qjack_client_init(c);
 }
@@ -387,7 +395,6 @@ static int qjack_client_init(QJackClient *c)
 char client_name[jack_client_name_size()];
 jack_options_t options = JackNullOption;
 
-c->finished  = false;
 c->connect_ports = true;
 
 snprintf(client_name, sizeof(client_name), "%s-%s",
@@ -483,8 +490,10 @@ static int qjack_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 }
 
 jo->c.out   = true;
+jo->c.enabled   = false;
 jo->c.nchannels = as->nchannels;
 jo->c.opt   = dev->u.jack.out;
+
 int ret = qjack_client_init(>c);
 if (ret != 0) {
 return ret;
@@ -519,8 +528,10 @@ static int qjack_init_in(HWVoiceIn *hw, struct audsettings 
*as,
 }
 
 ji->c.out   = false;
+ji->c.enabled   = false;
 ji->c.nchannels = as->nchannels;
 ji->c.opt   = dev->u.jack.in;
+
 int ret = qjack_client_init(>c);
 if (ret != 0) {
 return ret;
@@ -568,23 +579,25 @@ static void qjack_client_fini(QJackClient *c)
 static void qjack_fini_out(HWVoiceOut *hw)
 {
 QJackOut *jo = (QJackOut *)hw;
-jo->c.finished = true;
 qjack_client_fini(>c);
 }
 
 static void qjack_fini_in(HWVoiceIn *hw)
 {
 QJackIn *ji = (QJackIn *)hw;
-ji->c.finished = true;
 qjack_client_fini(>c);
 }
 
 static void qjack_enable_out(HWVoiceOut *hw, bool enable)
 {
+QJackOut *jo = (QJackOut *)hw;
+jo->c.enabled = enable;
 }
 
 static void qjack_enable_in(HWVoiceIn *hw, bool enable)
 {
+QJackIn *ji = (QJackIn *)hw;
+ji->c.enabled = enable;
 }
 
 static int qjack_thread_creator(jack_native_thread_t *thread,
-- 
2.20.1




[PATCH 1/6] audio/jack: fix invalid minimum buffer size check

2020-06-11 Thread Geoffrey McRae
Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index 722ddb1dfe..d0b6f748f2 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -434,17 +434,6 @@ static int qjack_client_init(QJackClient *c)
 jack_set_xrun_callback(c->client, qjack_xrun, c);
 jack_on_shutdown(c->client, qjack_shutdown, c);
 
-/*
- * ensure the buffersize is no smaller then 512 samples, some (all?) qemu
- * virtual devices do not work correctly otherwise
- */
-if (c->buffersize < 512) {
-c->buffersize = 512;
-}
-
-/* create a 2 period buffer */
-qjack_buffer_create(>fifo, c->nchannels, c->buffersize * 2);
-
 /* allocate and register the ports */
 c->port = g_malloc(sizeof(jack_port_t *) * c->nchannels);
 for (int i = 0; i < c->nchannels; ++i) {
@@ -468,6 +457,17 @@ static int qjack_client_init(QJackClient *c)
 jack_activate(c->client);
 c->buffersize = jack_get_buffer_size(c->client);
 
+/*
+ * ensure the buffersize is no smaller then 512 samples, some (all?) qemu
+ * virtual devices do not work correctly otherwise
+ */
+if (c->buffersize < 512) {
+c->buffersize = 512;
+}
+
+/* create a 2 period buffer */
+qjack_buffer_create(>fifo, c->nchannels, c->buffersize * 2);
+
 qjack_client_connect_ports(c);
 c->state = QJACK_STATE_RUNNING;
 return 0;
-- 
2.20.1




[PATCH 6/6] audio/jack: simplify the re-init code path

2020-06-11 Thread Geoffrey McRae
Signed-off-by: Geoffrey McRae 
---
 audio/jackaudio.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index b2b53985ae..72ed7c4929 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -395,6 +395,10 @@ static int qjack_client_init(QJackClient *c)
 char client_name[jack_client_name_size()];
 jack_options_t options = JackNullOption;
 
+if (c->state == QJACK_STATE_RUNNING) {
+return 0;
+}
+
 c->connect_ports = true;
 
 snprintf(client_name, sizeof(client_name), "%s-%s",
@@ -485,9 +489,7 @@ static int qjack_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 QJackOut *jo  = (QJackOut *)hw;
 Audiodev *dev = (Audiodev *)drv_opaque;
 
-if (jo->c.state != QJACK_STATE_DISCONNECTED) {
-return 0;
-}
+qjack_client_fini(>c);
 
 jo->c.out   = true;
 jo->c.enabled   = false;
@@ -523,9 +525,7 @@ static int qjack_init_in(HWVoiceIn *hw, struct audsettings 
*as,
 QJackIn  *ji  = (QJackIn *)hw;
 Audiodev *dev = (Audiodev *)drv_opaque;
 
-if (ji->c.state != QJACK_STATE_DISCONNECTED) {
-return 0;
-}
+qjack_client_fini(>c);
 
 ji->c.out   = false;
 ji->c.enabled   = false;
-- 
2.20.1




[PATCH 0/6] *** SUBJECT HERE ***

2020-06-11 Thread Geoffrey McRae
This patch set addresses several issues that cause inconsistent
behaviour in the guest when the sound device is stopped and started or
the JACK server stops responding on the host.

Geoffrey McRae (6):
  audio/jack: fix invalid minimum buffer size check
  audio/jack: remove unused stopped state
  audio/jack: remove invalid set of input support bool
  audio/jack: do not remove ports when finishing
  audio/jack: honour the enable state of the audio device
  audio/jack: simplify the re-init code path

 audio/jackaudio.c | 73 ---
 1 file changed, 38 insertions(+), 35 deletions(-)

-- 
2.20.1




[PATCH v7 6/9] qcow2_format.py: Dump bitmap table serialized entries

2020-06-11 Thread Andrey Shinkevich
Add bitmap table information to the QCOW2 metadata dump.
It extends the output of the test case #291

Bitmap name   bitmap-1
...
Bitmap table   typeoffset   size
0  serialized  4718592  65536
1  serialized  4294967296   65536
2  serialized  5348033147437056 65536
3  serialized  1379227385882214465536
4  serialized  4718592  65536
5  serialized  4294967296   65536
6  serialized  4503608217305088 65536
7  serialized  1407374883553280065536

Signed-off-by: Andrey Shinkevich 
Reviewed-by: Eric Blake 
---
 tests/qemu-iotests/291.out | 50 ++
 tests/qemu-iotests/qcow2_format.py | 40 ++
 2 files changed, 90 insertions(+)

diff --git a/tests/qemu-iotests/291.out b/tests/qemu-iotests/291.out
index d847419..595327c 100644
--- a/tests/qemu-iotests/291.out
+++ b/tests/qemu-iotests/291.out
@@ -42,6 +42,16 @@ type  1
 granularity_bits  19
 name_size 2
 extra_data_size   0
+Bitmap table   typeoffset   size
+0  serialized  5046272  65536
+1  all-zeroes  065536
+2  all-zeroes  065536
+3  all-zeroes  065536
+4  all-zeroes  065536
+5  all-zeroes  065536
+6  all-zeroes  065536
+7  all-zeroes  065536
+
 
 Bitmap name   b2
 flag  auto
@@ -53,6 +63,16 @@ type  1
 granularity_bits  16
 name_size 2
 extra_data_size   0
+Bitmap table   typeoffset   size
+0  serialized  5177344  65536
+1  all-zeroes  065536
+2  all-zeroes  065536
+3  all-zeroes  065536
+4  all-zeroes  065536
+5  all-zeroes  065536
+6  all-zeroes  065536
+7  all-zeroes  065536
+
 
 
 === Bitmap preservation not possible to non-qcow2 ===
@@ -128,6 +148,16 @@ type  1
 granularity_bits  19
 name_size 2
 extra_data_size   0
+Bitmap table   typeoffset   size
+0  serialized  4587520  65536
+1  all-zeroes  065536
+2  all-zeroes  065536
+3  all-zeroes  065536
+4  all-zeroes  065536
+5  all-zeroes  065536
+6  all-zeroes  065536
+7  all-zeroes  065536
+
 
 Bitmap name   b2
 flag  auto
@@ -139,6 +169,16 @@ type  1
 granularity_bits  16
 name_size 2
 extra_data_size   0
+Bitmap table   typeoffset   size
+0  serialized  4718592  65536
+1  serialized  4294967296   65536
+2  serialized  5348033147437056 65536
+3  serialized  1379227385882214465536
+4  serialized  4718592  65536
+5  serialized  4294967296   65536
+6  serialized  4503608217305088 65536
+7  serialized  1407374883553280065536
+
 
 Bitmap name   b0
 table size8 (bytes)
@@ -149,6 +189,16 @@ type  1
 granularity_bits  16
 name_size 2
 extra_data_size   0
+Bitmap table   typeoffset   size
+0  serialized  5242880  65536
+1  all-zeroes  065536
+2  all-zeroes  065536
+3  all-zeroes  065536
+4  all-zeroes  065536
+5  all-zeroes  065536
+6  all-zeroes  065536
+7  all-zeroes  065536
+
 
 
 === Check bitmap contents ===
diff --git a/tests/qemu-iotests/qcow2_format.py 

[PATCH v7 5/9] qcow2_format.py: pass cluster size to substructures

2020-06-11 Thread Andrey Shinkevich
The cluster size of an image is the QcowHeader class member and may be
obtained by dependent extension structures such as Qcow2BitmapExt for
further bitmap table details print.

Signed-off-by: Andrey Shinkevich 
---
 tests/qemu-iotests/qcow2_format.py | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index 90eff92..eb99119 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -116,6 +116,10 @@ class Qcow2BitmapExt(Qcow2Struct):
 ('u64', '{:#x}', 'bitmap_directory_offset')
 )
 
+def __init__(self, data, cluster_size):
+super().__init__(data=data)
+self.cluster_size = cluster_size
+
 def read_bitmap_directory(self, fd):
 self.bitmaps = []
 fd.seek(self.bitmap_directory_offset)
@@ -123,7 +127,8 @@ class Qcow2BitmapExt(Qcow2Struct):
 
 for n in range(self.nb_bitmaps):
 buf = fd.read(buf_size)
-dir_entry = Qcow2BitmapDirEntry(data=buf)
+dir_entry = Qcow2BitmapDirEntry(data=buf,
+cluster_size=self.cluster_size)
 fd.seek(dir_entry.extra_data_size, FROM_CURRENT)
 bitmap_name = fd.read(dir_entry.name_size)
 dir_entry.name = bitmap_name.decode('ascii')
@@ -159,8 +164,9 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
 ('u32', '{}','extra_data_size')
 )
 
-def __init__(self, data):
+def __init__(self, data, cluster_size):
 super().__init__(data=data)
+self.cluster_size = cluster_size
 
 self.bitmap_table_bytes = self.bitmap_table_size \
 * struct.calcsize('Q')
@@ -205,11 +211,13 @@ class QcowHeaderExtension(Qcow2Struct):
 # then padding to next multiply of 8
 )
 
-def __init__(self, magic=None, length=None, data=None, fd=None):
+def __init__(self, magic=None, length=None, data=None, fd=None,
+ cluster_size=None):
 """
 Support both loading from fd and creation from user data.
 For fd-based creation current position in a file will be used to read
 the data.
+The cluster_size value may be obtained by dependent structures.
 
 This should be somehow refactored and functionality should be moved to
 superclass (to allow creation of any qcow2 struct), but then, fields
@@ -243,7 +251,8 @@ class QcowHeaderExtension(Qcow2Struct):
 self.data_str = data_str
 
 if self.magic == QCOW2_EXT_MAGIC_BITMAPS:
-self.obj = Qcow2BitmapExt(data=self.data)
+self.obj = Qcow2BitmapExt(data=self.data,
+  cluster_size=cluster_size)
 else:
 self.obj = None
 
@@ -318,7 +327,7 @@ class QcowHeader(Qcow2Struct):
 end = self.cluster_size
 
 while fd.tell() < end:
-ext = QcowHeaderExtension(fd=fd)
+ext = QcowHeaderExtension(fd=fd, cluster_size=self.cluster_size)
 if ext.magic == 0:
 break
 else:
-- 
1.8.3.1




[PATCH v7 2/9] qcow2: Fix capitalization of header extension constant.

2020-06-11 Thread Andrey Shinkevich
Make the capitalization of the hexadecimal numbers consistent for the
QCOW2 header extension constants in docs/interop/qcow2.txt.

Suggested-by: Eric Blake 
Signed-off-by: Andrey Shinkevich 
---
 block/qcow2.c  | 2 +-
 docs/interop/qcow2.txt | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 0cd2e67..80dfe5f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -66,7 +66,7 @@ typedef struct {
 } QEMU_PACKED QCowExtension;
 
 #define  QCOW2_EXT_MAGIC_END 0
-#define  QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA
+#define  QCOW2_EXT_MAGIC_BACKING_FORMAT 0xe2792aca
 #define  QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
 #define  QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
 #define  QCOW2_EXT_MAGIC_BITMAPS 0x23852875
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
index cb72346..f072e27 100644
--- a/docs/interop/qcow2.txt
+++ b/docs/interop/qcow2.txt
@@ -231,7 +231,7 @@ be stored. Each extension has a structure like the 
following:
 
 Byte  0 -  3:   Header extension type:
 0x - End of the header extension area
-0xE2792ACA - Backing file format name string
+0xe2792aca - Backing file format name string
 0x6803f857 - Feature name table
 0x23852875 - Bitmaps extension
 0x0537be77 - Full disk encryption header pointer
-- 
1.8.3.1




[PATCH v7 9/9] qcow2_format.py: support dumping metadata in JSON format

2020-06-11 Thread Andrey Shinkevich
Implementation of dumping QCOW2 image metadata.
The sample output:
{
"Header_extensions": [
{
"name": "Feature table",
"magic": 1745090647,
"length": 192,
"data_str": ""
},
{
"name": "Bitmaps",
"magic": 595929205,
"length": 24,
"data": {
"nb_bitmaps": 2,
"reserved32": 0,
"bitmap_directory_size": 64,
"bitmap_directory_offset": 1048576,
"entries": [
{
"name": "bitmap-1",
"bitmap_table_offset": 589824,
"bitmap_table_size": 1,
"flags": [
"auto"
],
"type": 1,
"granularity_bits": 16,
"name_size": 8,
"extra_data_size": 0,
"bitmap_table": {
"table_entries": [
{
"type": "serialized",
"offset": 655360
},
...

Suggested-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Andrey Shinkevich 
---
 tests/qemu-iotests/qcow2_format.py | 60 ++
 1 file changed, 60 insertions(+)

diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index bdd5f68..35daec9 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -18,6 +18,15 @@
 
 import struct
 import string
+import json
+
+
+class ComplexEncoder(json.JSONEncoder):
+def default(self, obj):
+if hasattr(obj, 'get_fields_dict'):
+return obj.get_fields_dict()
+else:
+return json.JSONEncoder.default(self, obj)
 
 
 class Qcow2Field:
@@ -95,6 +104,11 @@ class Qcow2Struct(metaclass=Qcow2StructMeta):
 self.fields_dict = self.__dict__.copy()
 
 def dump(self, dump_json=None):
+if dump_json:
+print(json.dumps(self.get_fields_dict(), indent=4,
+ cls=ComplexEncoder))
+return
+
 for f in self.fields:
 value = self.__dict__[f[2]]
 if isinstance(f[1], str):
@@ -150,6 +164,9 @@ class Qcow2BitmapExt(Qcow2Struct):
 for bm in self.bitmaps:
 bm.dump_bitmap_dir_entry(dump_json)
 
+def get_fields_dict(self):
+return self.fields_dict
+
 
 BME_FLAG_IN_USE = 1 << 0
 BME_FLAG_AUTO = 1 << 1
@@ -202,6 +219,12 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
 super().dump()
 self.bitmap_table.print_bitmap_table(self.cluster_size)
 
+def get_fields_dict(self):
+bmp_name = dict(name=self.name)
+bme_dict = {**bmp_name, **self.fields_dict}
+bme_dict['flags'] = self.bitmap_flags
+return bme_dict
+
 
 class Qcow2BitmapTableEntry:
 
@@ -217,6 +240,9 @@ class Qcow2BitmapTableEntry:
 else:
 self.type = 'all-zeroes'
 
+def get_fields_dict(self):
+return dict(type=self.type, offset=self.offset)
+
 
 class Qcow2BitmapTable:
 
@@ -232,6 +258,18 @@ class Qcow2BitmapTable:
 print(f'{i:<14} {entry.type:<15} {entry.offset:<24} 
{cluster_size}')
 print("")
 
+def get_fields_dict(self):
+return dict(table_entries=self.entries)
+
+
+class Qcow2HeaderExtensionsDoc:
+
+def __init__(self, extensions):
+self.extensions = extensions
+
+def get_fields_dict(self):
+return dict(Header_extensions=self.extensions)
+
 
 QCOW2_EXT_MAGIC_BITMAPS = 0x23852875
 
@@ -247,6 +285,9 @@ class QcowHeaderExtension(Qcow2Struct):
 0x44415441: 'Data file'
 }
 
+def get_fields_dict(self):
+return self.mapping.get(self.value, "")
+
 fields = (
 ('u32', Magic, 'magic'),
 ('u32', '{}', 'length')
@@ -307,6 +348,16 @@ class QcowHeaderExtension(Qcow2Struct):
 else:
 self.obj.dump(dump_json)
 
+def get_fields_dict(self):
+ext_name = dict(name=self.Magic(self.magic))
+he_dict = {**ext_name, **self.fields_dict}
+if self.obj is not None:
+he_dict.update(data=self.obj)
+else:
+he_dict.update(data_str=self.data_str)
+
+return he_dict
+
 @classmethod
 def create(cls, magic, data):
 return QcowHeaderExtension(magic, len(data), data)
@@ -409,7 +460,16 @@ class QcowHeader(Qcow2Struct):
 fd.write(buf)
 
 def dump_extensions(self, dump_json=None):
+if dump_json:
+ext_doc = Qcow2HeaderExtensionsDoc(self.extensions)
+print(json.dumps(ext_doc.get_fields_dict(), indent=4,
+ cls=ComplexEncoder))
+return
+
 for ex in self.extensions:
   

[PATCH v7 0/9] iotests: Dump QCOW2 dirty bitmaps metadata

2020-06-11 Thread Andrey Shinkevich
Note: based on the Vladimir's series
  [v5 00/13] iotests: Dump QCOW2 dirty bitmaps metadata

Add dirty bitmap information to QCOW2 metadata dump in the qcow2_format.py.

v7:
  01: Fix for magic hexadecimal output in 291
  02: Bitmap table output format improvement.
  03: Incremental change in the test 291 output.

v6:
  01: Fixing capitalization of header extension constant.
  (Suggested by Eric)
  02: The cluster size global variable discarded and passed as a parameter.
  03: Re-based to Vladimir's v5 series.
  04: The code of passing qcow2.py JSON format key moved to separate patch.
  05: Making dict(s) for dumping in JSON format was substituted with a copy
  of __dict__.

v5: The Vladimir's preliminary series
v4: The Vladimir's preliminary series

Andrey Shinkevich (9):
  iotests: Fix for magic hexadecimal output in 291
  qcow2: Fix capitalization of header extension constant.
  qcow2_format.py: make printable data an extension class member
  qcow2_format.py: Dump bitmap directory information
  qcow2_format.py: pass cluster size to substructures
  qcow2_format.py: Dump bitmap table serialized entries
  qcow2.py: Introduce '-j' key to dump in JSON format
  qcow2_format.py: collect fields to dump in JSON format
  qcow2_format.py: support dumping metadata in JSON format

 block/qcow2.c  |   2 +-
 docs/interop/qcow2.txt |   2 +-
 tests/qemu-iotests/291.out | 112 ++-
 tests/qemu-iotests/qcow2.py|  20 +++-
 tests/qemu-iotests/qcow2_format.py | 217 ++---
 5 files changed, 327 insertions(+), 26 deletions(-)

-- 
1.8.3.1




[PATCH v7 8/9] qcow2_format.py: collect fields to dump in JSON format

2020-06-11 Thread Andrey Shinkevich
As __dict__ is being extended with class members we do not want to
print in JSON format dump, make a light copy of the initial __dict__
and extend the copy by adding lists we have to print in the JSON
output.

Signed-off-by: Andrey Shinkevich 
---
 tests/qemu-iotests/qcow2_format.py | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index a19f3b3..bdd5f68 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -92,6 +92,8 @@ class Qcow2Struct(metaclass=Qcow2StructMeta):
 self.__dict__ = dict((field[2], values[i])
  for i, field in enumerate(self.fields))
 
+self.fields_dict = self.__dict__.copy()
+
 def dump(self, dump_json=None):
 for f in self.fields:
 value = self.__dict__[f[2]]
@@ -102,7 +104,6 @@ class Qcow2Struct(metaclass=Qcow2StructMeta):
 
 print('{:<25} {}'.format(f[2], value_str))
 
-
 # seek relative to the current position in the file
 FROM_CURRENT = 1
 
@@ -142,6 +143,7 @@ class Qcow2BitmapExt(Qcow2Struct):
 
 def load(self, fd):
 self.read_bitmap_directory(fd)
+self.fields_dict.update(entries=self.bitmaps)
 
 def dump(self, dump_json=None):
 super().dump(dump_json)
@@ -189,6 +191,7 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
 table_size = self.bitmap_table_bytes * struct.calcsize('Q')
 table = [e[0] for e in struct.iter_unpack('>Q', fd.read(table_size))]
 self.bitmap_table = Qcow2BitmapTable(table)
+self.fields_dict.update(bitmap_table=self.bitmap_table)
 
 def dump_bitmap_dir_entry(self, dump_json=None):
 print()
-- 
1.8.3.1




[PATCH v7 4/9] qcow2_format.py: Dump bitmap directory information

2020-06-11 Thread Andrey Shinkevich
Read and dump entries from the bitmap directory of QCOW2 image.
It extends the output in the test case #291.

Header extension:
magic 0x23852875 (Bitmaps)
...
Bitmap name   bitmap-1
flag  auto
table size8 (bytes)
bitmap_table_offset   0x9
bitmap_table_size 1
flags 0
type  1
granularity_bits  16
name_size 8
extra_data_size   0

Suggested-by: Kevin Wolf 
Signed-off-by: Andrey Shinkevich 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 tests/qemu-iotests/291.out | 52 ++
 tests/qemu-iotests/qcow2_format.py | 75 ++
 2 files changed, 127 insertions(+)

diff --git a/tests/qemu-iotests/291.out b/tests/qemu-iotests/291.out
index ccfcdc5..d847419 100644
--- a/tests/qemu-iotests/291.out
+++ b/tests/qemu-iotests/291.out
@@ -33,6 +33,27 @@ reserved320
 bitmap_directory_size 0x40
 bitmap_directory_offset   0x51
 
+Bitmap name   b1
+table size8 (bytes)
+bitmap_table_offset   0x4e
+bitmap_table_size 1
+flags 0
+type  1
+granularity_bits  19
+name_size 2
+extra_data_size   0
+
+Bitmap name   b2
+flag  auto
+table size8 (bytes)
+bitmap_table_offset   0x50
+bitmap_table_size 1
+flags 2
+type  1
+granularity_bits  16
+name_size 2
+extra_data_size   0
+
 
 === Bitmap preservation not possible to non-qcow2 ===
 
@@ -98,6 +119,37 @@ reserved320
 bitmap_directory_size 0x60
 bitmap_directory_offset   0x52
 
+Bitmap name   b1
+table size8 (bytes)
+bitmap_table_offset   0x47
+bitmap_table_size 1
+flags 0
+type  1
+granularity_bits  19
+name_size 2
+extra_data_size   0
+
+Bitmap name   b2
+flag  auto
+table size8 (bytes)
+bitmap_table_offset   0x49
+bitmap_table_size 1
+flags 2
+type  1
+granularity_bits  16
+name_size 2
+extra_data_size   0
+
+Bitmap name   b0
+table size8 (bytes)
+bitmap_table_offset   0x51
+bitmap_table_size 1
+flags 0
+type  1
+granularity_bits  16
+name_size 2
+extra_data_size   0
+
 
 === Check bitmap contents ===
 
diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index d4f..90eff92 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -103,6 +103,10 @@ class Qcow2Struct(metaclass=Qcow2StructMeta):
 print('{:<25} {}'.format(f[2], value_str))
 
 
+# seek relative to the current position in the file
+FROM_CURRENT = 1
+
+
 class Qcow2BitmapExt(Qcow2Struct):
 
 fields = (
@@ -112,6 +116,73 @@ class Qcow2BitmapExt(Qcow2Struct):
 ('u64', '{:#x}', 'bitmap_directory_offset')
 )
 
+def read_bitmap_directory(self, fd):
+self.bitmaps = []
+fd.seek(self.bitmap_directory_offset)
+buf_size = struct.calcsize(Qcow2BitmapDirEntry.fmt)
+
+for n in range(self.nb_bitmaps):
+buf = fd.read(buf_size)
+dir_entry = Qcow2BitmapDirEntry(data=buf)
+fd.seek(dir_entry.extra_data_size, FROM_CURRENT)
+bitmap_name = fd.read(dir_entry.name_size)
+dir_entry.name = bitmap_name.decode('ascii')
+self.bitmaps.append(dir_entry)
+entry_raw_size = dir_entry.bitmap_dir_entry_raw_size()
+shift = ((entry_raw_size + 7) & ~7) - entry_raw_size
+fd.seek(shift, FROM_CURRENT)
+
+def load(self, fd):
+self.read_bitmap_directory(fd)
+
+def dump(self):
+super().dump()
+for bm in self.bitmaps:
+bm.dump_bitmap_dir_entry()
+
+
+BME_FLAG_IN_USE = 1 << 0
+BME_FLAG_AUTO = 1 << 1
+
+
+class Qcow2BitmapDirEntry(Qcow2Struct):
+
+name = ''
+
+fields = (
+('u64', '{:#x}', 'bitmap_table_offset'),
+('u32', '{}','bitmap_table_size'),
+('u32', '{}','flags'),
+('u8',  '{}','type'),
+('u8',  '{}','granularity_bits'),
+('u16', '{}','name_size'),
+('u32', '{}','extra_data_size')
+)
+
+def __init__(self, data):
+super().__init__(data=data)
+
+self.bitmap_table_bytes = self.bitmap_table_size \
+* struct.calcsize('Q')
+
+self.bitmap_flags = []
+if (self.flags & BME_FLAG_IN_USE):
+self.bitmap_flags.append("in-use")
+if (self.flags & 

[PATCH v7 1/9] iotests: Fix for magic hexadecimal output in 291

2020-06-11 Thread Andrey Shinkevich
This issue was introduced in the earlier patch:
"qcow2_format: refactor QcowHeaderExtension as a subclass of
Qcow2Struct".

Signed-off-by: Andrey Shinkevich 
---
 tests/qemu-iotests/291.out | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tests/qemu-iotests/291.out b/tests/qemu-iotests/291.out
index 1d4f9cd..ccfcdc5 100644
--- a/tests/qemu-iotests/291.out
+++ b/tests/qemu-iotests/291.out
@@ -16,17 +16,17 @@ wrote 1048576/1048576 bytes at offset 2097152
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 Check resulting qcow2 header extensions:
 Header extension:
-magic 3799591626 (Backing format)
+magic 0xe2792aca (Backing format)
 length5
 data  'qcow2'
 
 Header extension:
-magic 1745090647 (Feature table)
+magic 0x6803f857 (Feature table)
 length336
 data  
 
 Header extension:
-magic 595929205 (Bitmaps)
+magic 0x23852875 (Bitmaps)
 length24
 nb_bitmaps2
 reserved320
@@ -86,12 +86,12 @@ Format specific information:
 corrupt: false
 Check resulting qcow2 header extensions:
 Header extension:
-magic 1745090647 (Feature table)
+magic 0x6803f857 (Feature table)
 length336
 data  
 
 Header extension:
-magic 595929205 (Bitmaps)
+magic 0x23852875 (Bitmaps)
 length24
 nb_bitmaps3
 reserved320
-- 
1.8.3.1




[PATCH v7 3/9] qcow2_format.py: make printable data an extension class member

2020-06-11 Thread Andrey Shinkevich
Let us differ binary data type from string one for the extension data
variable and keep the string as the QcowHeaderExtension class member.

Signed-off-by: Andrey Shinkevich 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 tests/qemu-iotests/qcow2_format.py | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index 0f65fd1..d4f 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -164,6 +164,13 @@ class QcowHeaderExtension(Qcow2Struct):
 self.data = fd.read(padded)
 assert self.data is not None
 
+data_str = self.data[:self.length]
+if all(c in string.printable.encode('ascii') for c in data_str):
+data_str = f"'{ data_str.decode('ascii') }'"
+else:
+data_str = ''
+self.data_str = data_str
+
 if self.magic == QCOW2_EXT_MAGIC_BITMAPS:
 self.obj = Qcow2BitmapExt(data=self.data)
 else:
@@ -173,12 +180,7 @@ class QcowHeaderExtension(Qcow2Struct):
 super().dump()
 
 if self.obj is None:
-data = self.data[:self.length]
-if all(c in string.printable.encode('ascii') for c in data):
-data = f"'{ data.decode('ascii') }'"
-else:
-data = ''
-print(f'{"data":<25} {data}')
+print(f'{"data":<25} {self.data_str}')
 else:
 self.obj.dump()
 
-- 
1.8.3.1




[PATCH v7 7/9] qcow2.py: Introduce '-j' key to dump in JSON format

2020-06-11 Thread Andrey Shinkevich
Add the command key to the qcow2.py arguments list to dump QCOW2
metadata in JSON format. Here is the suggested way to do that. The
implementation of the dump in JSON format is in the patch that follows.

Signed-off-by: Andrey Shinkevich 
---
 tests/qemu-iotests/qcow2.py| 20 +++-
 tests/qemu-iotests/qcow2_format.py | 18 +-
 2 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/tests/qemu-iotests/qcow2.py b/tests/qemu-iotests/qcow2.py
index 8c187e9..b08d8fc 100755
--- a/tests/qemu-iotests/qcow2.py
+++ b/tests/qemu-iotests/qcow2.py
@@ -24,16 +24,19 @@ from qcow2_format import (
 )
 
 
+dump_json = False
+
+
 def cmd_dump_header(fd):
 h = QcowHeader(fd)
-h.dump()
+h.dump(dump_json)
 print()
-h.dump_extensions()
+h.dump_extensions(dump_json)
 
 
 def cmd_dump_header_exts(fd):
 h = QcowHeader(fd)
-h.dump_extensions()
+h.dump_extensions(dump_json)
 
 
 def cmd_set_header(fd, name, value):
@@ -132,6 +135,11 @@ cmds = [
 
 
 def main(filename, cmd, args):
+global dump_json
+dump_json = '-j' in sys.argv
+if dump_json:
+sys.argv.remove('-j')
+args.remove('-j')
 fd = open(filename, "r+b")
 try:
 for name, handler, num_args, desc in cmds:
@@ -149,12 +157,14 @@ def main(filename, cmd, args):
 
 
 def usage():
-print("Usage: %s   [, ...]" % sys.argv[0])
+print("Usage: %s   [, ...] [, ...]" % sys.argv[0])
 print("")
 print("Supported commands:")
 for name, handler, num_args, desc in cmds:
 print("%-20s - %s" % (name, desc))
-
+print("")
+print("Supported keys:")
+print("%-20s - %s" % ('-j', 'Dump in JSON format'))
 
 if __name__ == '__main__':
 if len(sys.argv) < 3:
diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index c1c2773..a19f3b3 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -92,7 +92,7 @@ class Qcow2Struct(metaclass=Qcow2StructMeta):
 self.__dict__ = dict((field[2], values[i])
  for i, field in enumerate(self.fields))
 
-def dump(self):
+def dump(self, dump_json=None):
 for f in self.fields:
 value = self.__dict__[f[2]]
 if isinstance(f[1], str):
@@ -143,10 +143,10 @@ class Qcow2BitmapExt(Qcow2Struct):
 def load(self, fd):
 self.read_bitmap_directory(fd)
 
-def dump(self):
-super().dump()
+def dump(self, dump_json=None):
+super().dump(dump_json)
 for bm in self.bitmaps:
-bm.dump_bitmap_dir_entry()
+bm.dump_bitmap_dir_entry(dump_json)
 
 
 BME_FLAG_IN_USE = 1 << 0
@@ -190,7 +190,7 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
 table = [e[0] for e in struct.iter_unpack('>Q', fd.read(table_size))]
 self.bitmap_table = Qcow2BitmapTable(table)
 
-def dump_bitmap_dir_entry(self):
+def dump_bitmap_dir_entry(self, dump_json=None):
 print()
 print(f'{"Bitmap name":<25} {self.name}')
 for fl in self.bitmap_flags:
@@ -296,13 +296,13 @@ class QcowHeaderExtension(Qcow2Struct):
 else:
 self.obj = None
 
-def dump(self):
+def dump(self, dump_json=None):
 super().dump()
 
 if self.obj is None:
 print(f'{"data":<25} {self.data_str}')
 else:
-self.obj.dump()
+self.obj.dump(dump_json)
 
 @classmethod
 def create(cls, magic, data):
@@ -405,8 +405,8 @@ class QcowHeader(Qcow2Struct):
 buf = buf[0:header_bytes-1]
 fd.write(buf)
 
-def dump_extensions(self):
+def dump_extensions(self, dump_json=None):
 for ex in self.extensions:
 print('Header extension:')
-ex.dump()
+ex.dump(dump_json)
 print()
-- 
1.8.3.1




Re: [PATCH] tests: disassemble-asm.sh: generate AML in readable format

2020-06-11 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200611165112.30979-1-...@redhat.com/



Hi,

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

Message-id: 20200611165112.30979-1-...@redhat.com
Subject: [PATCH] tests: disassemble-asm.sh: generate AML in readable format
Type: series

=== 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
Switched to a new branch 'test'
96571e6 tests: disassemble-asm.sh: generate AML in readable format

=== OUTPUT BEGIN ===
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#16: 
new file mode 100755

WARNING: line over 80 characters
#30: FILE: tests/data/acpi/disassemle-aml.sh:10:
+echo "Usage: ./tests/data/acpi/disassemle-aml.sh [-o 
]"

ERROR: trailing whitespace
#33: FILE: tests/data/acpi/disassemle-aml.sh:13:
+$

ERROR: trailing whitespace
#70: FILE: tests/data/acpi/disassemle-aml.sh:50:
+iasl -d -p ${asl} ${extra} ${aml} $

total: 2 errors, 2 warnings, 52 lines checked

Commit 96571e631bfb (tests: disassemble-asm.sh: generate AML in readable 
format) has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


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

[PATCH] target/i386: reimplement f2xm1 using floatx80 operations

2020-06-11 Thread Joseph Myers
The x87 f2xm1 emulation is currently based around conversion to
double.  This is inherently unsuitable for a good emulation of any
floatx80 operation, even before considering that it is a particularly
naive implementation using double (computing with pow and then
subtracting 1 rather than attempting a better emulation using expm1).

Reimplement using the soft-float operations, including additions and
multiplications with higher precision where appropriate to limit
accumulation of errors.  I considered reusing some of the m68k code
for transcendental operations, but the instructions don't generally
correspond exactly to x87 operations (for example, m68k has 2^x and
e^x - 1, but not 2^x - 1); to avoid possible accumulation of errors
from applying multiple such operations each rounding to floatx80
precision, I wrote a direct implementation of 2^x - 1 instead.  It
would be possible in principle to make the implementation more
efficient by doing the intermediate operations directly with
significands, signs and exponents and not packing / unpacking floatx80
format for each operation, but that would make it significantly more
complicated and it's not clear that's worthwhile; the m68k emulation
doesn't try to do that.

A test is included with many randomly generated inputs.  The
assumption of the test is that the result in round-to-nearest mode
should always be one of the two closest floating-point numbers to the
mathematical value of 2^x - 1; the implementation aims to do somewhat
better than that (about 70 correct bits before rounding).  I haven't
investigated how accurate hardware is.

Signed-off-by: Joseph Myers 

---

This patch depends on at least some of my previous x87 emulation fixes
being present (probably only the ones in the recent pull request; I
don't think it depends on any of the most recent series fixing fprem
and fprem1).  I expect to make similar fixes for fyl2xp1, fyl2x and
fpatan.  (The other transcendental instructions (fcos, fptan, fsin,
fsincos) may follow, but as a lower priority, as I'm aiming at getting
reasonable glibc test results under QEMU and those trigonometric
instructions - with their documented semantics that they are defined
to do range reduction using a specific 66-bit approximation to pi -
aren't used in glibc.)

checkpatch.pl has its usual false-positive complaints about hex
floating-point constants in the testcase.  It also complains about
lines over 80 columns in that test; I can reformat the test if
desired, but it's not clear line length matters for such a randomly
generated table of test inputs and expected results.

---
 target/i386/fpu_helper.c |  385 +-
 tests/tcg/i386/test-i386-f2xm1.c | 1140 ++
 2 files changed, 1522 insertions(+), 3 deletions(-)
 create mode 100644 tests/tcg/i386/test-i386-f2xm1.c

diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c
index 0e531e3821..8f34ea9776 100644
--- a/target/i386/fpu_helper.c
+++ b/target/i386/fpu_helper.c
@@ -25,6 +25,7 @@
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "fpu/softfloat.h"
+#include "fpu/softfloat-macros.h"
 
 #ifdef CONFIG_SOFTMMU
 #include "hw/irq.h"
@@ -836,12 +837,390 @@ void helper_fbst_ST0(CPUX86State *env, target_ulong ptr)
 merge_exception_flags(env, old_flags);
 }
 
+/* 128-bit significand of log(2).  */
+#define ln2_sig_high 0xb17217f7d1cf79abULL
+#define ln2_sig_low 0xc9e3b39803f2f6afULL
+
+/*
+ * Polynomial coefficients for an approximation to (2^x - 1) / x, on
+ * the interval [-1/64, 1/64].
+ */
+#define f2xm1_coeff_0 make_floatx80(0x3ffe, 0xb17217f7d1cf79acULL)
+#define f2xm1_coeff_0_low make_floatx80(0xbfbc, 0xd87edabf495b3762ULL)
+#define f2xm1_coeff_1 make_floatx80(0x3ffc, 0xf5fdeffc162c7543ULL)
+#define f2xm1_coeff_2 make_floatx80(0x3ffa, 0xe35846b82505fcc7ULL)
+#define f2xm1_coeff_3 make_floatx80(0x3ff8, 0x9d955b7dd273b899ULL)
+#define f2xm1_coeff_4 make_floatx80(0x3ff5, 0xaec3ff3c4ef4ac0cULL)
+#define f2xm1_coeff_5 make_floatx80(0x3ff2, 0xa184897c3a7f0de9ULL)
+#define f2xm1_coeff_6 make_floatx80(0x3fee, 0xffe634d0ec30d504ULL)
+#define f2xm1_coeff_7 make_floatx80(0x3feb, 0xb160111d2db515e4ULL)
+
+struct f2xm1_data {
+/*
+ * A value very close to a multiple of 1/32, such that 2^t and 2^t - 1
+ * are very close to exact floatx80 values.
+ */
+floatx80 t;
+/* The value of 2^t.  */
+floatx80 exp2;
+/* The value of 2^t - 1.  */
+floatx80 exp2m1;
+};
+
+static const struct f2xm1_data f2xm1_table[65] = {
+{ make_floatx80(0xbfff, 0x8000ULL),
+  make_floatx80(0x3ffe, 0x8000ULL),
+  make_floatx80(0xbffe, 0x8000ULL) },
+{ make_floatx80(0xbffe, 0xf8002e7eULL),
+  make_floatx80(0x3ffe, 0x82cd8698ac2b9160ULL),
+  make_floatx80(0xbffd, 0xfa64f2cea7a8dd40ULL) },
+{ make_floatx80(0xbffe, 0xefffe960ULL),
+  make_floatx80(0x3ffe, 0x85aac367cc488345ULL),
+  make_floatx80(0xbffd, 0xf4aa7930676ef976ULL) },
+

Re: [PATCH 00/10] target/arm: Convert 2-reg-scalar to decodetree

2020-06-11 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200611144529.8873-1-peter.mayd...@linaro.org/



Hi,

This series failed the docker-mingw@fedora build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#! /bin/bash
export ARCH=x86_64
make docker-image-fedora V=1 NETWORK=1
time make docker-test-mingw@fedora J=14 NETWORK=1
=== TEST SCRIPT END ===

  CC  aarch64-softmmu/target/arm/psci.o
  CC  aarch64-softmmu/target/arm/translate-a64.o
  CC  aarch64-softmmu/target/arm/helper-a64.o
/tmp/qemu-test/src/target/arm/neon-dp.decode:416: error: ('definition has 0 
bits',)
make[1]: *** [/tmp/qemu-test/src/target/arm/Makefile.objs:27: 
target/arm/decode-neon-dp.inc.c] Error 1
make[1]: *** Waiting for unfinished jobs
  GEN aarch64-softmmu/target/arm/decode-sve.inc.c
  GEN x86_64-softmmu/qemu-system-x86_64.exe
make: *** [Makefile:527: aarch64-softmmu/all] Error 2
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 665, in 
sys.exit(main())
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=a093840cf7c04ee4bf8dfca6073b2aea', '-u', 
'1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-asai5w4d/src/docker-src.2020-06-11-19.39.07.24908:/var/tmp/qemu:z,ro',
 'qemu:fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=a093840cf7c04ee4bf8dfca6073b2aea
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-asai5w4d/src'
make: *** [docker-run-test-mingw@fedora] Error 2

real3m22.484s
user0m8.758s


The full log is available at
http://patchew.org/logs/20200611144529.8873-1-peter.mayd...@linaro.org/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [PATCH 00/10] target/arm: Convert 2-reg-scalar to decodetree

2020-06-11 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200611144529.8873-1-peter.mayd...@linaro.org/



Hi,

This series failed the docker-quick@centos7 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===

  CC  aarch64-softmmu/target/arm/helper-a64.o
  GEN aarch64-softmmu/target/arm/decode-sve.inc.c
  CC  aarch64-softmmu/target/arm/sve_helper.o
/tmp/qemu-test/src/target/arm/neon-dp.decode:416: error: ('definition has 0 
bits',)
  CC  aarch64-softmmu/target/arm/pauth_helper.o
make[1]: *** [target/arm/decode-neon-dp.inc.c] Error 1
make[1]: *** Waiting for unfinished jobs
make: *** [aarch64-softmmu/all] Error 2
Traceback (most recent call last):
  File "./tests/docker/docker.py", line 665, in 
sys.exit(main())
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', 
'--label', 'com.qemu.instance.uuid=652e5daeb9d74258b3b1583fbf30fe7a', '-u', 
'1003', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', 
'-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 
'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', 
'/home/patchew2/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', 
'/var/tmp/patchew-tester-tmp-plvski0d/src/docker-src.2020-06-11-19.13.01.2188:/var/tmp/qemu:z,ro',
 'qemu:centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit 
status 2.
filter=--filter=label=com.qemu.instance.uuid=652e5daeb9d74258b3b1583fbf30fe7a
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-plvski0d/src'
make: *** [docker-run-test-quick@centos7] Error 2

real3m6.470s
user0m8.159s


The full log is available at
http://patchew.org/logs/20200611144529.8873-1-peter.mayd...@linaro.org/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[Bug 1882851] Re: QEMU video freezes with "Guest disabled display" (virtio driver)

2020-06-11 Thread Diego Viola
I can reproduce it with current linux git master[1].

1. git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1882851

Title:
  QEMU video freezes with "Guest disabled display" (virtio driver)

Status in QEMU:
  New

Bug description:
  I am using Arch Linux as my Guest and Host OS, after starting qemu
  with the following command:

$ qemu-system-x86_64 -enable-kvm -hda arch-zoom.qcow2 -m 4G -vga
  virtio

  and waiting for a screen blank, I get this message:

Guest disabled display

  And nothing happens after that, I can move the mouse or hit any key,
  and the message is still there.

  I can still reboot the VM but that's not optimal.

  I can reproduce this with the latest QEMU release (5.0.0) or git master, 
  I also tried this with older releases (4.0.0, 3.0.0) and the issue is still 
there.

  I can't reproduce this with other video drivers (std, qxl).

  With std/qxl the screen will blank a bit and then continue as normal.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1882851/+subscriptions



[PATCH v2 11/12] hw/arm: Wire up BMC boot flash for npcm750-evb and quanta-gsj

2020-06-11 Thread Havard Skinnemoen
This allows these NPCM7xx-based boards to boot from a flash image, e.g.
one built with OpenBMC. For example like this:

IMAGE=${OPENBMC}/build/tmp/deploy/images/gsj/image-bmc
qemu-system-arm -machine quanta-gsj -nographic \
-bios ~/qemu/bootrom/npcm7xx_bootrom.bin \
-drive file=${IMAGE},if=mtd,bus=0,unit=0,format=raw,snapshot=on

Change-Id: I158a4d9952c0e90f2b1b7280443a7305b6ae57cf
Reviewed-by: Tyrone Ting 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/npcm7xx_boards.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 86e18af2d7..1ec772fa59 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -18,6 +18,7 @@
 #include "hw/arm/boot.h"
 #include "hw/arm/npcm7xx.h"
 #include "hw/core/cpu.h"
+#include "hw/qdev-properties.h"
 #include "qapi/error.h"
 #include "qemu/units.h"
 
@@ -40,6 +41,20 @@ static void npcm7xx_load_kernel(MachineState *machine, 
NPCM7xxState *soc)
 arm_load_kernel(>cpu[0], machine, _binfo);
 }
 
+static void npcm7xx_connect_flash(NPCM7xxFIUState *fiu, int cs_no,
+  const char *flash_type, DriveInfo *dinfo) {
+DeviceState *flash;
+qemu_irq flash_cs;
+
+flash = ssi_create_slave_no_init(fiu->spi, flash_type);
+qdev_prop_set_drive(flash, "drive", blk_by_legacy_dinfo(dinfo),
+_abort);
+qdev_init_nofail(flash);
+
+flash_cs = qdev_get_gpio_in_named(flash, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(fiu), cs_no, flash_cs);
+}
+
 static NPCM7xxState *npcm7xx_create_soc(MachineState *machine)
 {
 NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_GET_CLASS(machine);
@@ -57,18 +72,30 @@ static NPCM7xxState *npcm7xx_create_soc(MachineState 
*machine)
 static void npcm750_evb_init(MachineState *machine)
 {
 NPCM7xxState *soc;
+DriveInfo *dinfo;
 
 soc = npcm7xx_create_soc(machine);
 
+dinfo = drive_get(IF_MTD, 0, 0);
+if (dinfo) {
+npcm7xx_connect_flash(>fiu[0], 0, "w25q256", dinfo);
+}
+
 npcm7xx_load_kernel(machine, soc);
 }
 
 static void quanta_gsj_init(MachineState *machine)
 {
 NPCM7xxState *soc;
+DriveInfo *dinfo;
 
 soc = npcm7xx_create_soc(machine);
 
+dinfo = drive_get(IF_MTD, 0, 0);
+if (dinfo) {
+npcm7xx_connect_flash(>fiu[0], 0, "mx25l25635e", dinfo);
+}
+
 npcm7xx_load_kernel(machine, soc);
 }
 
-- 
2.27.0.290.gba653c62da-goog




[PATCH v2 12/12] docs/system: Add Nuvoton machine documentation

2020-06-11 Thread Havard Skinnemoen
Change-Id: I88e437cb22a8441e0c0e672dfb57568ac81172d8
Signed-off-by: Havard Skinnemoen 
---
 docs/system/arm/nuvoton.rst | 89 +
 docs/system/target-arm.rst  |  1 +
 2 files changed, 90 insertions(+)
 create mode 100644 docs/system/arm/nuvoton.rst

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
new file mode 100644
index 00..1ca34c0051
--- /dev/null
+++ b/docs/system/arm/nuvoton.rst
@@ -0,0 +1,89 @@
+Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
+=
+
+The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
+designed to be used as Baseboard Management Controllers (BMCs) in various
+servers. They all feature one or two ARM Cortex A9 CPU cores, as well as an
+assortment of peripherals targeted for either Enterprise or Data Center /
+Hyperscale applications. The former is a superset of the latter, so NPCM750 has
+all the peripherals of NPCM730 and more.
+
+.. _Nuvoton iBMC: https://www.nuvoton.com/products/cloud-computing/ibmc/
+
+The NPCM750 SoC has two Cortex A9 cores and is targeted for the Enterprise
+segment. The following machines are based on this chip :
+
+- ``npcm750-evb``   Nuvoton NPCM750 Evaluation board
+
+The NPCM730 SoC has two Cortex A9 cores and is targeted for Data Center and
+Hyperscale applications. The following machines are based on this chip :
+
+- ``quanta-gsj``Quanta GSJ server BMC
+
+There are also two more SoCs, NPCM710 and NPCM705, which are single-core
+variants of NPCM750 and NPCM730, respectively. These are currently not
+supported by QEMU.
+
+Supported devices
+-
+
+ * SMP (Dual Core Cortex-A9)
+ * Cortex-A9MPCore built-in peripherals: SCU, GIC, Global Timer, Private Timer
+   and Watchdog.
+ * SRAM, ROM and DRAM mappings
+ * System Global Control Registers (GCR)
+ * Clock and reset controller (CLK)
+ * Timer controller (TIM)
+ * Serial ports (16550-based)
+ * DDR4 memory controller (dummy interface indicating memory training is done)
+ * OTP controllers (no protection features)
+ * Flash Interface Unit (FIU; no protection features)
+
+Missing devices
+---
+
+ * GPIO controller
+ * LPC/eSPI host-to-BMC interface, including
+
+   * Keyboard and mouse controller interface (KBCI)
+   * Keyboard Controller Style (KCS) channels
+   * BIOS POST code FIFO
+   * System Wake-up Control (SWC)
+   * Shared memory (SHM)
+   * eSPI slave interface
+
+ * Ethernet controllers (GMAC and EMC)
+ * USB host (USBH)
+ * USB device (USBD)
+ * SMBus controller (SMBF)
+ * Peripheral SPI controller (PSPI)
+ * Analog to Digital Converter (ADC)
+ * SD/MMC host
+ * Random Number Generator (RNG)
+ * PECI interface
+ * Pulse Width Modulation (PWM)
+ * Tachometer
+ * PCI and PCIe root complex and bridges
+ * VDM and MCTP support
+ * Serial I/O expansion
+ * LPC/eSPI host
+ * Coprocessor
+ * Graphics
+ * Video capture
+ * Encoding compression engine
+ * Security features
+
+Boot options
+
+
+The Nuvoton machines can boot from an OpenBMC firmware image, or directly into
+a kernel using the ``-kernel`` option.
+
+Booting a full firmware image requires a Boot ROM specified via the ``-bios``
+option to QEMU. The firmware image should be attached as an MTD drive. Example 
:
+
+.. code-block:: bash
+
+  $ qemu-system-arm -machine quanta-gsj -nographic \
+  -bios npcm7xx_bootrom.bin \
+  -drive file=image-bmc,if=mtd,bus=0,unit=0,format=raw
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index 1bd477a293..38a9daa9b9 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -84,6 +84,7 @@ undocumented; you can get a complete list by running
arm/aspeed
arm/musicpal
arm/nseries
+   arm/nuvoton
arm/orangepi
arm/palm
arm/xscale
-- 
2.27.0.290.gba653c62da-goog




[PATCH v2 09/12] hw/mem: Stubbed out NPCM7xx Memory Controller model

2020-06-11 Thread Havard Skinnemoen
This just implements the bare minimum to cause the boot block to skip
memory intialization.

Change-Id: I26fd5f3b2af5d07a24911e7e58789f7b52f78d71
Reviewed-by: Tyrone Ting 
Signed-off-by: Havard Skinnemoen 
---
 MAINTAINERS |  2 +
 hw/arm/npcm7xx.c| 11 +
 hw/mem/Makefile.objs|  1 +
 hw/mem/npcm7xx_mc.c | 83 +
 include/hw/arm/npcm7xx.h|  2 +
 include/hw/mem/npcm7xx_mc.h | 35 
 6 files changed, 134 insertions(+)
 create mode 100644 hw/mem/npcm7xx_mc.c
 create mode 100644 include/hw/mem/npcm7xx_mc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 9814e7b4c4..9a289366ba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -727,10 +727,12 @@ M: Tyrone Ting 
 L: qemu-...@nongnu.org
 S: Supported
 F: hw/arm/npcm7xx*
+F: hw/mem/npcm7xx*
 F: hw/misc/npcm7xx*
 F: hw/nvram/npcm7xx*
 F: hw/timer/npcm7xx*
 F: include/hw/arm/npcm7xx*
+F: include/hw/mem/npcm7xx*
 F: include/hw/misc/npcm7xx*
 F: include/hw/nvram/npcm7xx*
 F: include/hw/timer/npcm7xx*
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index f9e3b5842b..54d84bafa1 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -46,6 +46,7 @@
 #define NPCM7XX_CPUP_BA (0xF03FE000)
 #define NPCM7XX_GCR_BA  (0xF080)
 #define NPCM7XX_CLK_BA  (0xF0801000)
+#define NPCM7XX_MC_BA   (0xF0824000)
 
 /* Memory blocks at the end of the address space */
 #define NPCM7XX_RAM2_BA (0xFFFD)
@@ -161,6 +162,8 @@ static void npcm7xx_init(Object *obj)
   sizeof(s->key_storage), TYPE_NPCM7XX_KEY_STORAGE);
 sysbus_init_child_obj(obj, "otp2", OBJECT(>fuse_array),
   sizeof(s->fuse_array), TYPE_NPCM7XX_FUSE_ARRAY);
+sysbus_init_child_obj(obj, "mc", OBJECT(>mc), sizeof(s->mc),
+  TYPE_NPCM7XX_MC);
 
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
 sysbus_init_child_obj(obj, "tim[*]", OBJECT(>tim[i]),
@@ -258,6 +261,14 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(>fuse_array), 0, NPCM7XX_OTP2_BA);
 npcm7xx_init_fuses(s);
 
+/* Fake Memory Controller (MC) */
+object_property_set_bool(OBJECT(>mc), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>mc), 0, NPCM7XX_MC_BA);
+
 /* Timer Modules (TIM) */
 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_tim_addr) != ARRAY_SIZE(s->tim));
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
index 56345befd0..9a33ef7b35 100644
--- a/hw/mem/Makefile.objs
+++ b/hw/mem/Makefile.objs
@@ -1,3 +1,4 @@
 common-obj-$(CONFIG_DIMM) += pc-dimm.o
 common-obj-y += memory-device.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_mc.o
 common-obj-$(CONFIG_NVDIMM) += nvdimm.o
diff --git a/hw/mem/npcm7xx_mc.c b/hw/mem/npcm7xx_mc.c
new file mode 100644
index 00..03a7fb53dc
--- /dev/null
+++ b/hw/mem/npcm7xx_mc.c
@@ -0,0 +1,83 @@
+/*
+ * Nuvoton NPCM7xx Memory Controller stub
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/mem/npcm7xx_mc.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+#define NPCM7XX_MC_REGS_SIZE (4 * KiB)
+
+static uint64_t npcm7xx_mc_read(void *opaque, hwaddr addr, unsigned int size)
+{
+/*
+ * If bits 8..11 @ offset 0 are not zero, the boot block thinks the memory
+ * controller has already been initialized and will skip DDR training.
+ */
+if (addr == 0) {
+return 0x100;
+}
+
+qemu_log_mask(LOG_UNIMP, "%s: mostly unimplemented\n", __func__);
+
+return 0;
+}
+
+static void npcm7xx_mc_write(void *opaque, hwaddr addr, uint64_t v,
+ unsigned int size)
+{
+qemu_log_mask(LOG_UNIMP, "%s: mostly unimplemented\n", __func__);
+}
+
+static const MemoryRegionOps npcm7xx_mc_ops = {
+.read = npcm7xx_mc_read,
+.write = npcm7xx_mc_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void npcm7xx_mc_realize(DeviceState *dev, Error **errp)
+{
+NPCM7xxMCState *s = NPCM7XX_MC(dev);
+
+memory_region_init_io(>mmio, OBJECT(s), _mc_ops, s, "regs",
+  NPCM7XX_MC_REGS_SIZE);
+sysbus_init_mmio(>parent, >mmio);
+}
+
+static void npcm7xx_mc_class_init(ObjectClass *klass, void *data)
+{
+

[PATCH v2 08/12] hw/nvram: NPCM7xx OTP device model

2020-06-11 Thread Havard Skinnemoen
This supports reading and writing OTP fuses and keys. Only fuse reading
has been tested. Protection is not implemented.

Change-Id: Ie67d7e2ed5e1010061b7383c71a8ba0611794103
Reviewed-by: Avi Fishman 
Signed-off-by: Havard Skinnemoen 
---
 MAINTAINERS|   2 +
 hw/arm/npcm7xx.c   |  32 +++
 hw/nvram/Makefile.objs |   1 +
 hw/nvram/npcm7xx_otp.c | 391 +
 include/hw/arm/npcm7xx.h   |   3 +
 include/hw/nvram/npcm7xx_otp.h |  93 
 6 files changed, 522 insertions(+)
 create mode 100644 hw/nvram/npcm7xx_otp.c
 create mode 100644 include/hw/nvram/npcm7xx_otp.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 077c86643c..9814e7b4c4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -728,9 +728,11 @@ L: qemu-...@nongnu.org
 S: Supported
 F: hw/arm/npcm7xx*
 F: hw/misc/npcm7xx*
+F: hw/nvram/npcm7xx*
 F: hw/timer/npcm7xx*
 F: include/hw/arm/npcm7xx*
 F: include/hw/misc/npcm7xx*
+F: include/hw/nvram/npcm7xx*
 F: include/hw/timer/npcm7xx*
 
 nSeries
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 417bc16b5c..f9e3b5842b 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -37,6 +37,10 @@
 #define NPCM7XX_MMIO_BA (0x8000)
 #define NPCM7XX_MMIO_SZ (0x7FFD)
 
+/* OTP key storage and fuse strap array */
+#define NPCM7XX_OTP1_BA (0xF0189000)
+#define NPCM7XX_OTP2_BA (0xF018a000)
+
 /* Core system modules. */
 #define NPCM7XX_L2C_BA  (0xF03FC000)
 #define NPCM7XX_CPUP_BA (0xF03FE000)
@@ -121,6 +125,15 @@ void npcm7xx_write_secondary_boot(ARMCPU *cpu, const 
struct arm_boot_info *info)
NPCM7XX_SMP_LOADER_START);
 }
 
+static void npcm7xx_init_fuses(NPCM7xxState *s)
+{
+NPCM7xxClass *nc = NPCM7XX_GET_CLASS(s);
+uint32_t value;
+
+value = tswap32(nc->disabled_modules);
+npcm7xx_otp_array_write(>fuse_array, , 64, sizeof(value));
+}
+
 static qemu_irq npcm7xx_irq(NPCM7xxState *s, int n)
 {
 return qdev_get_gpio_in(DEVICE(>a9mpcore), n);
@@ -144,6 +157,10 @@ static void npcm7xx_init(Object *obj)
   TYPE_NPCM7XX_GCR);
 sysbus_init_child_obj(obj, "clk", OBJECT(>clk), sizeof(s->clk),
   TYPE_NPCM7XX_CLK);
+sysbus_init_child_obj(obj, "otp1", OBJECT(>key_storage),
+  sizeof(s->key_storage), TYPE_NPCM7XX_KEY_STORAGE);
+sysbus_init_child_obj(obj, "otp2", OBJECT(>fuse_array),
+  sizeof(s->fuse_array), TYPE_NPCM7XX_FUSE_ARRAY);
 
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
 sysbus_init_child_obj(obj, "tim[*]", OBJECT(>tim[i]),
@@ -226,6 +243,21 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 }
 sysbus_mmio_map(SYS_BUS_DEVICE(>clk), 0, NPCM7XX_CLK_BA);
 
+/* OTP key storage and fuse strap array */
+object_property_set_bool(OBJECT(>key_storage), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>key_storage), 0, NPCM7XX_OTP1_BA);
+object_property_set_bool(OBJECT(>fuse_array), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>fuse_array), 0, NPCM7XX_OTP2_BA);
+npcm7xx_init_fuses(s);
+
 /* Timer Modules (TIM) */
 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_tim_addr) != ARRAY_SIZE(s->tim));
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
diff --git a/hw/nvram/Makefile.objs b/hw/nvram/Makefile.objs
index f3ad921382..0270f0bbf7 100644
--- a/hw/nvram/Makefile.objs
+++ b/hw/nvram/Makefile.objs
@@ -4,5 +4,6 @@ common-obj-$(CONFIG_AT24C) += eeprom_at24c.o
 common-obj-y += fw_cfg.o
 common-obj-$(CONFIG_CHRP_NVRAM) += chrp_nvram.o
 common-obj-$(CONFIG_MAC_NVRAM) += mac_nvram.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_otp.o
 common-obj-$(CONFIG_NRF51_SOC) += nrf51_nvm.o
 obj-$(CONFIG_PSERIES) += spapr_nvram.o
diff --git a/hw/nvram/npcm7xx_otp.c b/hw/nvram/npcm7xx_otp.c
new file mode 100644
index 00..71fc728a2d
--- /dev/null
+++ b/hw/nvram/npcm7xx_otp.c
@@ -0,0 +1,391 @@
+/*
+ * Nuvoton NPCM7xx OTP (Fuse Array) Interface
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/nvram/npcm7xx_otp.h"
+#include "qapi/error.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+/* Each module has 4 KiB of register space. Only a fraction of it is used. */
+#define NPCM7XX_OTP_REGS_SIZE (4 * KiB)
+
+/* Register field definitions. 

[PATCH v2 10/12] hw/ssi: NPCM7xx Flash Interface Unit device model

2020-06-11 Thread Havard Skinnemoen
This implements a device model for the NPCM7xx SPI flash controller.

Direct reads and writes, and user-mode transactions have been tested in
various modes. Protection features are not implemented yet.

All the FIU instances are available in the SoC's address space,
regardless of whether or not they're connected to actual flash chips.

Change-Id: Ia4985761931714c6ca35b505f47aef3f4008c1d8
Reviewed-by: Tyrone Ting 
Signed-off-by: Havard Skinnemoen 
---
 MAINTAINERS  |   2 +
 hw/arm/Kconfig   |   1 +
 hw/arm/npcm7xx.c |  59 +
 hw/ssi/Makefile.objs |   1 +
 hw/ssi/npcm7xx_fiu.c | 497 +++
 hw/ssi/trace-events  |   9 +
 include/hw/arm/npcm7xx.h |   2 +
 include/hw/ssi/npcm7xx_fiu.h |  99 +++
 8 files changed, 670 insertions(+)
 create mode 100644 hw/ssi/npcm7xx_fiu.c
 create mode 100644 include/hw/ssi/npcm7xx_fiu.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 9a289366ba..8a5c08c2c2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -730,11 +730,13 @@ F: hw/arm/npcm7xx*
 F: hw/mem/npcm7xx*
 F: hw/misc/npcm7xx*
 F: hw/nvram/npcm7xx*
+F: hw/ssi/npcm7xx*
 F: hw/timer/npcm7xx*
 F: include/hw/arm/npcm7xx*
 F: include/hw/mem/npcm7xx*
 F: include/hw/misc/npcm7xx*
 F: include/hw/nvram/npcm7xx*
+F: include/hw/ssi/npcm7xx*
 F: include/hw/timer/npcm7xx*
 
 nSeries
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 3738c1f5cd..8cc99f6190 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -360,6 +360,7 @@ config NPCM7XX
 select ARM_GIC
 select PL310  # cache controller
 select SERIAL
+select SSI
 select UNIMP
 
 config FSL_IMX25
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 54d84bafa1..50319d0d33 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -98,6 +98,37 @@ static const hwaddr npcm7xx_uart_addr[] = {
 0xF0004000,
 };
 
+static const hwaddr npcm7xx_fiu0_flash_addr[] = {
+0x8000,
+0x8800,
+};
+
+static const hwaddr npcm7xx_fiu3_flash_addr[] = {
+0xa000,
+0xa800,
+0xb000,
+0xb800,
+};
+
+static const struct {
+const char *name;
+hwaddr regs_addr;
+int cs_count;
+const hwaddr *flash_addr;
+} npcm7xx_fiu[] = {
+{
+.name = "fiu0",
+.regs_addr = 0xfb00,
+.cs_count = ARRAY_SIZE(npcm7xx_fiu0_flash_addr),
+.flash_addr = npcm7xx_fiu0_flash_addr,
+}, {
+.name = "fiu3",
+.regs_addr = 0xc000,
+.cs_count = ARRAY_SIZE(npcm7xx_fiu3_flash_addr),
+.flash_addr = npcm7xx_fiu3_flash_addr,
+},
+};
+
 void npcm7xx_write_secondary_boot(ARMCPU *cpu, const struct arm_boot_info 
*info)
 {
 /*
@@ -169,6 +200,13 @@ static void npcm7xx_init(Object *obj)
 sysbus_init_child_obj(obj, "tim[*]", OBJECT(>tim[i]),
   sizeof(s->tim[i]), TYPE_NPCM7XX_TIMER);
 }
+
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
+for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
+sysbus_init_child_obj(obj, npcm7xx_fiu[i].name,
+  OBJECT(>fiu[i]), sizeof(s->fiu[i]),
+  TYPE_NPCM7XX_FIU);
+}
 }
 
 static void npcm7xx_realize(DeviceState *dev, Error **errp)
@@ -297,6 +335,27 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
serial_hd(i), DEVICE_LITTLE_ENDIAN);
 }
 
+/* Flash Interface Unit (FIU) */
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
+for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
+Object *o = OBJECT(>fiu[i]);
+int j;
+
+object_property_set_int(o, npcm7xx_fiu[i].cs_count, "cs-count",
+_abort);
+object_property_set_bool(o, true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+
+sysbus_mmio_map(SYS_BUS_DEVICE(o), 0, npcm7xx_fiu[i].regs_addr);
+for (j = 0; j < npcm7xx_fiu[i].cs_count; j++) {
+sysbus_mmio_map(SYS_BUS_DEVICE(o), j + 1,
+npcm7xx_fiu[i].flash_addr[j]);
+}
+}
+
 /* RAM2 (SRAM) */
 memory_region_init_ram(>sram, OBJECT(dev), "ram2",
NPCM7XX_RAM2_SZ, );
diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 07a85f1967..cab48e72c9 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -5,6 +5,7 @@ common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
 common-obj-$(CONFIG_MSF2) += mss-spi.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_fiu.o
 
 common-obj-$(CONFIG_OMAP) += omap_spi.o
 common-obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/npcm7xx_fiu.c b/hw/ssi/npcm7xx_fiu.c
new file mode 100644
index 00..dd7e1c8a4e
--- /dev/null
+++ b/hw/ssi/npcm7xx_fiu.c
@@ -0,0 +1,497 @@
+/*
+ * Nuvoton NPCM7xx Flash Interface Unit (FIU)
+ *
+ * 

[PATCH v2 04/12] hw/timer: Add NPCM7xx Timer device model

2020-06-11 Thread Havard Skinnemoen
The NPCM730 and NPCM750 SoCs have three timer modules each holding five
timers and some shared registers (e.g. interrupt status).

Each timer runs at 25 MHz divided by a prescaler, and counts down from a
configurable initial value to zero. When zero is reached, the interrupt
flag for the timer is set, and the timer is disabled (one-shot mode) or
reloaded from its initial value (periodic mode).

This implementation is sufficient to boot a Linux kernel configured for
NPCM750. Note that the kernel does not seem to actually turn on the
interrupts.

Change-Id: I4305fc6bd81b81930737a9c06d0f7dd06f017797
Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Signed-off-by: Havard Skinnemoen 
---
 MAINTAINERS  |   2 +
 hw/timer/Makefile.objs   |   1 +
 hw/timer/npcm7xx_timer.c | 437 +++
 hw/timer/trace-events|   5 +
 include/hw/timer/npcm7xx_timer.h |  95 +++
 5 files changed, 540 insertions(+)
 create mode 100644 hw/timer/npcm7xx_timer.c
 create mode 100644 include/hw/timer/npcm7xx_timer.h

diff --git a/MAINTAINERS b/MAINTAINERS
index efe7f499e3..97d24b1443 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -727,7 +727,9 @@ M: Tyrone Ting 
 L: qemu-...@nongnu.org
 S: Supported
 F: hw/misc/npcm7xx*
+F: hw/timer/npcm7xx*
 F: include/hw/misc/npcm7xx*
+F: include/hw/timer/npcm7xx*
 
 nSeries
 M: Andrzej Zaborowski 
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index dece235fd7..6ea6d644ad 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -14,6 +14,7 @@ common-obj-$(CONFIG_IMX) += imx_epit.o
 common-obj-$(CONFIG_IMX) += imx_gpt.o
 common-obj-$(CONFIG_LM32) += lm32_timer.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_timer.o
 common-obj-$(CONFIG_NRF51_SOC) += nrf51_timer.o
 
 common-obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
new file mode 100644
index 00..9aae4b09b9
--- /dev/null
+++ b/hw/timer/npcm7xx_timer.c
@@ -0,0 +1,437 @@
+/*
+ * Nuvoton NPCM7xx Timer Controller
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/irq.h"
+#include "hw/timer/npcm7xx_timer.h"
+#include "qemu/bitops.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "qemu/units.h"
+#include "trace.h"
+
+/* Register field definitions. */
+#define NPCM7XX_TCSR_CENBIT(30)
+#define NPCM7XX_TCSR_IE BIT(29)
+#define NPCM7XX_TCSR_PERIODIC   BIT(27)
+#define NPCM7XX_TCSR_CRST   BIT(26)
+#define NPCM7XX_TCSR_CACT   BIT(25)
+#define NPCM7XX_TCSR_RSVD   0x2100
+#define NPCM7XX_TCSR_PRESCALE_START 0
+#define NPCM7XX_TCSR_PRESCALE_LEN   8
+
+/* The reference clock frequency is always 25 MHz. */
+#define NPCM7XX_TIMER_REF_HZ(2500)
+
+/* Return the value by which to divide the reference clock rate. */
+static uint32_t npcm7xx_timer_prescaler(const NPCM7xxTimer *t)
+{
+return extract32(t->tcsr, NPCM7XX_TCSR_PRESCALE_START,
+ NPCM7XX_TCSR_PRESCALE_LEN) + 1;
+}
+
+/* Convert a timer cycle count to a time interval in nanoseconds. */
+static int64_t npcm7xx_timer_count_to_ns(NPCM7xxTimer *t, uint32_t count)
+{
+int64_t ns = count;
+
+ns *= NANOSECONDS_PER_SECOND / NPCM7XX_TIMER_REF_HZ;
+ns *= npcm7xx_timer_prescaler(t);
+
+return ns;
+}
+
+/* Convert a time interval in nanoseconds to a timer cycle count. */
+static uint32_t npcm7xx_timer_ns_to_count(NPCM7xxTimer *t, int64_t ns)
+{
+int64_t count;
+
+count = ns / (NANOSECONDS_PER_SECOND / NPCM7XX_TIMER_REF_HZ);
+count /= npcm7xx_timer_prescaler(t);
+
+return count;
+}
+
+/*
+ * Raise the interrupt line if there's a pending interrupt and interrupts are
+ * enabled for this timer. If not, lower it.
+ */
+static void npcm7xx_timer_check_interrupt(NPCM7xxTimer *t)
+{
+NPCM7xxTimerCtrlState *tc = t->ctrl;
+/* Find the array index of this timer. */
+int index = t - tc->timer;
+
+g_assert(index >= 0 && index < NPCM7XX_TIMERS_PER_CTRL);
+
+if ((t->tcsr & NPCM7XX_TCSR_IE) && (tc->tisr & BIT(index))) {
+qemu_irq_raise(t->irq);
+trace_npcm7xx_timer_irq(DEVICE(tc)->canonical_path, index, 1);
+} else {
+qemu_irq_lower(t->irq);
+trace_npcm7xx_timer_irq(DEVICE(tc)->canonical_path, index, 0);
+}
+}
+
+/* Start or resume the timer. */
+static void 

[PATCH v2 07/12] hw/arm: Load -bios image as a boot ROM for npcm7xx

2020-06-11 Thread Havard Skinnemoen
If a -bios option is specified on the command line, load the image into
the internal ROM memory region, which contains the first instructions
run by the CPU after reset.

A minimal Apache-2.0-licensed boot ROM can be found at

https://github.com/google/vbootrom

It is by no means feature complete, but it is enough to launch the
Nuvoton bootblock[1] from offset 0 in the flash, which in turn will
launch u-boot and finally the Linux kernel.

[1] https://github.com/Nuvoton-Israel/bootblock

Change-Id: I41eae4fc7786d33f532c14087e930bf1b5012562
Reviewed-by: Tyrone Ting 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/npcm7xx.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index a5dbf08c00..417bc16b5c 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -22,6 +22,7 @@
 #include "hw/misc/unimp.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
+#include "qemu-common.h"
 #include "qemu/units.h"
 #include "sysemu/sysemu.h"
 
@@ -270,6 +271,22 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 }
 memory_region_add_subregion(get_system_memory(), NPCM7XX_ROM_BA, >irom);
 
+if (bios_name) {
+g_autofree char *filename = NULL;
+int ret;
+
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+if (!filename) {
+error_setg(errp, "Could not find ROM image '%s'", bios_name);
+return;
+}
+ret = load_image_mr(filename, >irom);
+if (ret < 0) {
+error_setg(errp, "Failed to load ROM image '%s'", filename);
+return;
+}
+}
+
 /* External DDR4 SDRAM */
 memory_region_add_subregion(get_system_memory(), NPCM7XX_DRAM_BA, s->dram);
 }
-- 
2.27.0.290.gba653c62da-goog




[PATCH v2 05/12] hw/arm: Add NPCM730 and NPCM750 SoC models

2020-06-11 Thread Havard Skinnemoen
The Nuvoton NPCM7xx SoC family are used to implement Baseboard
Management Controllers in servers. While the family includes four SoCs,
this patch implements limited support for two of them: NPCM730 (targeted
for Data Center applications) and NPCM750 (targeted for Enterprise
applications).

This patch includes little more than the bare minimum needed to boot a
Linux kernel built with NPCM7xx support in direct-kernel mode:

  - Two Cortex-A9 CPU cores with built-in periperhals.
  - Global Configuration Registers.
  - Clock Management.
  - 3 Timer Modules with 5 timers each.
  - 4 serial ports.

The chips themselves have a lot more features, some of which will be
added to the model at a later stage.

Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Signed-off-by: Havard Skinnemoen 
---
 MAINTAINERS  |   2 +
 hw/arm/Makefile.objs |   1 +
 hw/arm/npcm7xx.c | 330 +++
 include/hw/arm/npcm7xx.h |  80 ++
 4 files changed, 413 insertions(+)
 create mode 100644 hw/arm/npcm7xx.c
 create mode 100644 include/hw/arm/npcm7xx.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 97d24b1443..077c86643c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -726,8 +726,10 @@ M: Havard Skinnemoen 
 M: Tyrone Ting 
 L: qemu-...@nongnu.org
 S: Supported
+F: hw/arm/npcm7xx*
 F: hw/misc/npcm7xx*
 F: hw/timer/npcm7xx*
+F: include/hw/arm/npcm7xx*
 F: include/hw/misc/npcm7xx*
 F: include/hw/timer/npcm7xx*
 
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 534a6a119e..13d163a599 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -41,6 +41,7 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_STM32F405_SOC) += stm32f405_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zynqmp.o xlnx-zcu102.o
 obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o xlnx-versal-virt.o
+obj-$(CONFIG_NPCM7XX) += npcm7xx.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
new file mode 100644
index 00..a5dbf08c00
--- /dev/null
+++ b/hw/arm/npcm7xx.c
@@ -0,0 +1,330 @@
+/*
+ * Nuvoton NPCM7xx SoC family.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "exec/address-spaces.h"
+#include "hw/arm/npcm7xx.h"
+#include "hw/char/serial.h"
+#include "hw/loader.h"
+#include "hw/misc/unimp.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/units.h"
+#include "sysemu/sysemu.h"
+
+/* The first half of the address space is reserved for DDR4 DRAM. */
+#define NPCM7XX_DRAM_BA (0x)
+#define NPCM7XX_DRAM_SZ (2 * GiB)
+
+/*
+ * This covers the whole MMIO space. We'll use this to catch any MMIO accesses
+ * that aren't handled by any device.
+ */
+#define NPCM7XX_MMIO_BA (0x8000)
+#define NPCM7XX_MMIO_SZ (0x7FFD)
+
+/* Core system modules. */
+#define NPCM7XX_L2C_BA  (0xF03FC000)
+#define NPCM7XX_CPUP_BA (0xF03FE000)
+#define NPCM7XX_GCR_BA  (0xF080)
+#define NPCM7XX_CLK_BA  (0xF0801000)
+
+/* Memory blocks at the end of the address space */
+#define NPCM7XX_RAM2_BA (0xFFFD)
+#define NPCM7XX_RAM2_SZ (128 * KiB)
+#define NPCM7XX_ROM_BA  (0x)
+#define NPCM7XX_ROM_SZ  (64 * KiB)
+
+/*
+ * Interrupt lines going into the GIC. This does not include internal Cortex-A9
+ * interrupts.
+ */
+enum NPCM7xxInterrupt {
+NPCM7XX_UART0_IRQ   = 2,
+NPCM7XX_UART1_IRQ,
+NPCM7XX_UART2_IRQ,
+NPCM7XX_UART3_IRQ,
+NPCM7XX_TIMER0_IRQ  = 32,   /* Timer Module 0 */
+NPCM7XX_TIMER1_IRQ,
+NPCM7XX_TIMER2_IRQ,
+NPCM7XX_TIMER3_IRQ,
+NPCM7XX_TIMER4_IRQ,
+NPCM7XX_TIMER5_IRQ, /* Timer Module 1 */
+NPCM7XX_TIMER6_IRQ,
+NPCM7XX_TIMER7_IRQ,
+NPCM7XX_TIMER8_IRQ,
+NPCM7XX_TIMER9_IRQ,
+NPCM7XX_TIMER10_IRQ,/* Timer Module 2 */
+NPCM7XX_TIMER11_IRQ,
+NPCM7XX_TIMER12_IRQ,
+NPCM7XX_TIMER13_IRQ,
+NPCM7XX_TIMER14_IRQ,
+};
+
+/* Total number of GIC interrupts, including internal Cortex-A9 interrupts. */
+#define NPCM7XX_NUM_IRQ (160)
+
+/* Register base address for each Timer Module */
+static const hwaddr npcm7xx_tim_addr[] = {
+0xF0008000,
+0xF0009000,
+0xF000A000,
+};
+
+/* Register base address for each 16550 UART */
+static const hwaddr npcm7xx_uart_addr[] = {
+0xF0001000,
+0xF0002000,
+0xF0003000,
+0xF0004000,
+};
+
+void 

[PATCH v2 06/12] hw/arm: Add two NPCM7xx-based machines

2020-06-11 Thread Havard Skinnemoen
This adds two new machines, both supported by OpenBMC:

  - npcm750-evb: Nuvoton NPCM750 Evaluation Board.
  - quanta-gsj: A board with a NPCM730 chip.

They rely on the NPCM7xx SoC device to do the heavy lifting. They are
almost completely identical at the moment, apart from the SoC type,
which currently only changes the reset contents of one register
(GCR.MDLR), but they might grow apart a bit more as more functionality
is added.

Both machines can boot the Linux kernel into /bin/sh.

Change-Id: I852dd93020f849888979bc659a32d5da37ab9915
Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/Makefile.objs |   2 +-
 hw/arm/npcm7xx_boards.c  | 141 +++
 include/hw/arm/npcm7xx.h |  19 ++
 3 files changed, 161 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/npcm7xx_boards.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 13d163a599..c333548ce1 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -41,7 +41,7 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_STM32F405_SOC) += stm32f405_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zynqmp.o xlnx-zcu102.o
 obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o xlnx-versal-virt.o
-obj-$(CONFIG_NPCM7XX) += npcm7xx.o
+obj-$(CONFIG_NPCM7XX) += npcm7xx.o npcm7xx_boards.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
new file mode 100644
index 00..86e18af2d7
--- /dev/null
+++ b/hw/arm/npcm7xx_boards.c
@@ -0,0 +1,141 @@
+/*
+ * Machine definitions for boards featuring an NPCM7xx SoC.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/arm/boot.h"
+#include "hw/arm/npcm7xx.h"
+#include "hw/core/cpu.h"
+#include "qapi/error.h"
+#include "qemu/units.h"
+
+static struct arm_boot_info npcm7xx_binfo = {
+.loader_start   = NPCM7XX_LOADER_START,
+.smp_loader_start   = NPCM7XX_SMP_LOADER_START,
+.smp_bootreg_addr   = NPCM7XX_SMP_BOOTREG_ADDR,
+.gic_cpu_if_addr= NPCM7XX_GIC_CPU_IF_ADDR,
+.write_secondary_boot = npcm7xx_write_secondary_boot,
+.board_id   = -1,
+};
+
+static void npcm7xx_load_kernel(MachineState *machine, NPCM7xxState *soc)
+{
+NPCM7xxClass *sc = NPCM7XX_GET_CLASS(soc);
+
+npcm7xx_binfo.ram_size = machine->ram_size;
+npcm7xx_binfo.nb_cpus = sc->num_cpus;
+
+arm_load_kernel(>cpu[0], machine, _binfo);
+}
+
+static NPCM7xxState *npcm7xx_create_soc(MachineState *machine)
+{
+NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_GET_CLASS(machine);
+NPCM7xxState *soc;
+
+soc = NPCM7XX(object_new_with_props(nmc->soc_type, OBJECT(machine), "soc",
+_abort, NULL));
+object_property_set_link(OBJECT(soc), OBJECT(machine->ram), "dram",
+ _abort);
+object_property_set_bool(OBJECT(soc), true, "realized", _abort);
+
+return soc;
+}
+
+static void npcm750_evb_init(MachineState *machine)
+{
+NPCM7xxState *soc;
+
+soc = npcm7xx_create_soc(machine);
+
+npcm7xx_load_kernel(machine, soc);
+}
+
+static void quanta_gsj_init(MachineState *machine)
+{
+NPCM7xxState *soc;
+
+soc = npcm7xx_create_soc(machine);
+
+npcm7xx_load_kernel(machine, soc);
+}
+
+static void npcm7xx_set_soc_type(NPCM7xxMachineClass *nmc, const char *type)
+{
+NPCM7xxClass *sc = NPCM7XX_CLASS(object_class_by_name(type));
+MachineClass *mc = MACHINE_CLASS(nmc);
+
+nmc->soc_type = type;
+mc->default_cpus = mc->min_cpus = mc->max_cpus = sc->num_cpus;
+}
+
+static void npcm7xx_machine_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+
+mc->no_floppy   = 1;
+mc->no_cdrom= 1;
+mc->no_parallel = 1;
+mc->default_ram_id  = "ram";
+}
+
+/*
+ * Schematics:
+ * 
https://github.com/Nuvoton-Israel/nuvoton-info/blob/master/npcm7xx-poleg/evaluation-board/board_deliverables/NPCM750x_EB_ver.A1.1_COMPLETE.pdf
+ */
+static void npcm750_evb_machine_class_init(ObjectClass *oc, void *data)
+{
+NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc);
+MachineClass *mc = MACHINE_CLASS(oc);
+
+npcm7xx_set_soc_type(nmc, TYPE_NPCM750);
+
+mc->desc= "Nuvoton NPCM750 Evaluation Board (Cortex A9)";
+mc->init= npcm750_evb_init;
+mc->default_ram_size = 512 * MiB;
+};
+
+static void 

[PATCH v2 02/12] hw/misc: Add NPCM7xx System Global Control Registers device model

2020-06-11 Thread Havard Skinnemoen
Implement a device model for the System Global Control Registers in the
NPCM730 and NPCM750 BMC SoCs.

This is primarily used to enable SMP boot (the boot ROM spins reading
the SCRPAD register) and DDR memory initialization; other registers are
best effort for now.

The reset values of the MDLR and PWRON registers are determined by the
SoC variant (730 vs 750) and board straps respectively.

Change-Id: Ifeb596be28f4d5463f0b386df38b357677d1
Reviewed-by: Joel Stanley 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 MAINTAINERS   |   8 ++
 hw/misc/Makefile.objs |   1 +
 hw/misc/npcm7xx_gcr.c | 211 ++
 hw/misc/trace-events  |   4 +
 include/hw/misc/npcm7xx_gcr.h |  76 
 5 files changed, 300 insertions(+)
 create mode 100644 hw/misc/npcm7xx_gcr.c
 create mode 100644 include/hw/misc/npcm7xx_gcr.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 3abe3faa4e..efe7f499e3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -721,6 +721,14 @@ S: Odd Fixes
 F: hw/arm/musicpal.c
 F: docs/system/arm/musicpal.rst
 
+Nuvoton NPCM7xx
+M: Havard Skinnemoen 
+M: Tyrone Ting 
+L: qemu-...@nongnu.org
+S: Supported
+F: hw/misc/npcm7xx*
+F: include/hw/misc/npcm7xx*
+
 nSeries
 M: Andrzej Zaborowski 
 M: Peter Maydell 
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 5aaca8a039..40a9d1c01e 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -51,6 +51,7 @@ common-obj-$(CONFIG_IMX) += imx_rngc.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 common-obj-$(CONFIG_MAINSTONE) += mst_fpga.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_gcr.o
 common-obj-$(CONFIG_OMAP) += omap_clk.o
 common-obj-$(CONFIG_OMAP) += omap_gpmc.o
 common-obj-$(CONFIG_OMAP) += omap_l4.o
diff --git a/hw/misc/npcm7xx_gcr.c b/hw/misc/npcm7xx_gcr.c
new file mode 100644
index 00..af03bf4a01
--- /dev/null
+++ b/hw/misc/npcm7xx_gcr.c
@@ -0,0 +1,211 @@
+/*
+ * Nuvoton NPCM7xx System Global Control Registers.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/misc/npcm7xx_gcr.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+#include "trace.h"
+
+static const uint32_t cold_reset_values[NPCM7XX_GCR_NR_REGS] = {
+[NPCM7XX_GCR_PDID]  = 0x04A92750,   /* Poleg A1 */
+[NPCM7XX_GCR_MISCPE]= 0x,
+[NPCM7XX_GCR_SPSWC] = 0x0003,
+[NPCM7XX_GCR_INTCR] = 0x035E,
+[NPCM7XX_GCR_HIFCR] = 0x004E,
+[NPCM7XX_GCR_INTCR2]= (1U << 19),   /* DDR initialized */
+[NPCM7XX_GCR_RESSR] = 0x8000,
+[NPCM7XX_GCR_DSCNT] = 0x00c0,
+[NPCM7XX_GCR_DAVCLVLR]  = 0x5A00F3CF,
+[NPCM7XX_GCR_SCRPAD]= 0x0008,
+[NPCM7XX_GCR_USB1PHYCTL]= 0x034730E4,
+[NPCM7XX_GCR_USB2PHYCTL]= 0x034730E4,
+};
+
+static uint64_t npcm7xx_gcr_read(void *opaque, hwaddr offset, unsigned size)
+{
+uint32_t reg = offset / sizeof(uint32_t);
+NPCM7xxGCRState *s = opaque;
+
+if (reg >= NPCM7XX_GCR_NR_REGS) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: offset 0x%04x out of range\n",
+  __func__, (unsigned int)offset);
+return 0;
+}
+
+trace_npcm7xx_gcr_read(offset, s->regs[reg]);
+
+return s->regs[reg];
+}
+
+static void npcm7xx_gcr_write(void *opaque, hwaddr offset,
+  uint64_t v, unsigned size)
+{
+uint32_t reg = offset / sizeof(uint32_t);
+NPCM7xxGCRState *s = opaque;
+uint32_t value = v;
+
+trace_npcm7xx_gcr_write(offset, value);
+
+if (reg >= NPCM7XX_GCR_NR_REGS) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: offset 0x%04x out of range\n",
+  __func__, (unsigned int)offset);
+return;
+}
+
+switch (reg) {
+case NPCM7XX_GCR_PDID:
+case NPCM7XX_GCR_PWRON:
+case NPCM7XX_GCR_INTSR:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: register @ 0x%04x is read-only\n",
+  __func__, (unsigned int)offset);
+return;
+
+case NPCM7XX_GCR_RESSR:
+case NPCM7XX_GCR_CP2BST:
+/* Write 1 to clear */
+value = s->regs[reg] & ~value;
+break;
+
+case NPCM7XX_GCR_RLOCKR1:
+case NPCM7XX_GCR_MDLR:
+/* Write 1 to set */
+value |= s->regs[reg];
+break;
+};
+
+s->regs[reg] = value;
+}
+
+static const struct MemoryRegionOps 

[PATCH v2 01/12] npcm7xx: Add config symbol

2020-06-11 Thread Havard Skinnemoen
Add a config symbol for the NPCM7xx BMC SoC family that subsequent
patches can use in Makefiles.

Change-Id: I6e4d5c58716cb6fe4ea5d06f148beeafda55f9a5
Reviewed-by: Tyrone Ting 
Acked-by: Joel Stanley 
Signed-off-by: Havard Skinnemoen 
---
 default-configs/arm-softmmu.mak | 1 +
 hw/arm/Kconfig  | 8 
 2 files changed, 9 insertions(+)

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 8fc09a4a51..9a94ebd0be 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -27,6 +27,7 @@ CONFIG_GUMSTIX=y
 CONFIG_SPITZ=y
 CONFIG_TOSA=y
 CONFIG_Z2=y
+CONFIG_NPCM7XX=y
 CONFIG_COLLIE=y
 CONFIG_ASPEED_SOC=y
 CONFIG_NETDUINO2=y
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 9afa6eee79..3738c1f5cd 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -354,6 +354,14 @@ config XLNX_VERSAL
 select VIRTIO_MMIO
 select UNIMP
 
+config NPCM7XX
+bool
+select A9MPCORE
+select ARM_GIC
+select PL310  # cache controller
+select SERIAL
+select UNIMP
+
 config FSL_IMX25
 bool
 select IMX
-- 
2.27.0.290.gba653c62da-goog




[PATCH v2 03/12] hw/misc: Add NPCM7xx Clock Controller device model

2020-06-11 Thread Havard Skinnemoen
Enough functionality to boot the Linux kernel has been implemented. This
includes:

  - Correct power-on reset values so the various clock rates can be
accurately calculated.
  - Clock enables stick around when written.

In addition, a best effort attempt to implement SECCNT and CNTR25M was
made even though I don't think the kernel needs them.

Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 hw/misc/Makefile.objs |   1 +
 hw/misc/npcm7xx_clk.c | 216 ++
 hw/misc/trace-events  |   4 +
 include/hw/misc/npcm7xx_clk.h |  65 ++
 4 files changed, 286 insertions(+)
 create mode 100644 hw/misc/npcm7xx_clk.c
 create mode 100644 include/hw/misc/npcm7xx_clk.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 40a9d1c01e..2e74803005 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -51,6 +51,7 @@ common-obj-$(CONFIG_IMX) += imx_rngc.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 common-obj-$(CONFIG_MAINSTONE) += mst_fpga.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_clk.o
 common-obj-$(CONFIG_NPCM7XX) += npcm7xx_gcr.o
 common-obj-$(CONFIG_OMAP) += omap_clk.o
 common-obj-$(CONFIG_OMAP) += omap_gpmc.o
diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c
new file mode 100644
index 00..2348683305
--- /dev/null
+++ b/hw/misc/npcm7xx_clk.c
@@ -0,0 +1,216 @@
+/*
+ * Nuvoton NPCM7xx Clock Control Registers.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/misc/npcm7xx_clk.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "qemu/units.h"
+#include "trace.h"
+
+#define PLLCON_LOKI BIT(31)
+#define PLLCON_LOKS BIT(30)
+#define PLLCON_PWDENBIT(12)
+
+/*
+ * These reset values were taken from version 0.91 of the NPCM750R data sheet.
+ *
+ * All are loaded on power-up reset. CLKENx and SWRSTR should also be loaded on
+ * core domain reset, but this reset type is not yet supported by QEMU.
+ */
+static const uint32_t cold_reset_values[NPCM7XX_CLK_NR_REGS] = {
+[NPCM7XX_CLK_CLKEN1]= 0x,
+[NPCM7XX_CLK_CLKSEL]= 0x004a,
+[NPCM7XX_CLK_CLKDIV1]   = 0x5413f855,
+[NPCM7XX_CLK_PLLCON0]   = 0x00222101 | PLLCON_LOKI,
+[NPCM7XX_CLK_PLLCON1]   = 0x00202101 | PLLCON_LOKI,
+[NPCM7XX_CLK_IPSRST1]   = 0x1000,
+[NPCM7XX_CLK_IPSRST2]   = 0x8000,
+[NPCM7XX_CLK_CLKEN2]= 0x,
+[NPCM7XX_CLK_CLKDIV2]   = 0xaa4f8f9f,
+[NPCM7XX_CLK_CLKEN3]= 0x,
+[NPCM7XX_CLK_IPSRST3]   = 0x0300,
+[NPCM7XX_CLK_WD0RCR]= 0x,
+[NPCM7XX_CLK_WD1RCR]= 0x,
+[NPCM7XX_CLK_WD2RCR]= 0x,
+[NPCM7XX_CLK_SWRSTC1]   = 0x0003,
+[NPCM7XX_CLK_PLLCON2]   = 0x00c02105 | PLLCON_LOKI,
+[NPCM7XX_CLK_CORSTC]= 0x0403,
+[NPCM7XX_CLK_PLLCONG]   = 0x01228606 | PLLCON_LOKI,
+[NPCM7XX_CLK_AHBCKFI]   = 0x00c8,
+};
+
+static uint64_t npcm7xx_clk_read(void *opaque, hwaddr offset, unsigned size)
+{
+uint32_t reg = offset / sizeof(uint32_t);
+NPCM7xxCLKState *s = opaque;
+int64_t now_ns;
+uint32_t value = 0;
+
+if (reg >= NPCM7XX_CLK_NR_REGS) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: offset 0x%04x out of range\n",
+  __func__, (unsigned int)offset);
+return 0;
+}
+
+switch (reg) {
+case NPCM7XX_CLK_SWRSTR:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: register @ 0x%04x is write-only\n",
+  __func__, (unsigned int)offset);
+break;
+
+case NPCM7XX_CLK_SECCNT:
+now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+value = (now_ns - s->ref_ns) / NANOSECONDS_PER_SECOND;
+break;
+
+case NPCM7XX_CLK_CNTR25M:
+now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+/*
+ * This register counts 25 MHz cycles, updating every 640 ns. It rolls
+ * over to zero every second.
+ *
+ * The 4 LSBs are always zero: (1e9 / 640) << 4 = 2500.
+ */
+value = (((now_ns - s->ref_ns) / 640) << 4) % 2500;
+break;
+
+default:
+value = s->regs[reg];
+break;
+};
+
+trace_npcm7xx_clk_read(offset, value);
+
+return value;
+}
+
+static void npcm7xx_clk_write(void *opaque, hwaddr 

[PATCH v2 00/12] Add Nuvoton NPCM730/NPCM750 SoCs and two BMC machines

2020-06-11 Thread Havard Skinnemoen
This patch series models enough of the Nuvoton NPCM730 and NPCM750 SoCs to boot
an OpenBMC image built for quanta-gsj. This includes device models for:

  - Global Configuration Registers
  - Clock Control
  - Timers
  - Fuses
  - Memory Controller
  - Flash Controller

These modules, along with the existing Cortex A9 CPU cores and built-in
peripherals, are integrated into a NPCM730 or NPCM750 SoC, which in turn form
the foundation for the quanta-gsj and npcm750-evb machines, respectively. The
two SoCs are very similar; the only difference is that NPCM730 is missing some
peripherals that NPCM750 has, and which are not considered essential for
datacenter use (e.g. graphics controllers). For more information, see

https://www.nuvoton.com/products/cloud-computing/ibmc/

Both quanta-gsj and npcm750-evb correspond to real boards supported by OpenBMC.
While this initial series uses a stripped-down kernel for testing, future
series will be tested using OpenBMC images built from public sources. I'm
currently putting the finishing touches on flash controller support, which is
necessary to boot a full OpenBMC image, and will be enabled by the next series.

The patches in this series were developed by Google and reviewed by Nuvoton. We
will be maintaining the machine and peripheral support together.

The data sheet for these SoCs is not generally available. Please let me know if
more comments are needed to understand the device behavior.

Changes since v1 (requested by reviewers):

  - Clarify the source of CLK reset values.
  - Made smpboot a constant byte array, eliinated byte swapping.
  - NPCM7xxState now stores an array of ARMCPUs, not pointers to ARMCPUs.
  - Clarify why EL3 is disabled.
  - Introduce NPCM7XX_NUM_IRQ constant.
  - Set the number of CPUs according to SoC variant, and disallow command line
overrides (i.e. you can no longer override the number of CPUs with the -smp
parameter). This is trying to follow the spirit of
https://patchwork.kernel.org/patch/11595407/.
  - Switch register operations to DEVICE_LITTLE_ENDIAN throughout.
  - Machine documentation added (new patch).

Changes since v1 to support flash booting:

  - GCR reset value changes to get past memory initialization when booting
from flash (patches 2 and 5):
  - INTCR2 now indicates that the DDR controller is initialized.
  - INTCR3 is initialized according to DDR memory size. A realize()
method was implemented to achieve this.
  - Refactor the machine initialization a bit to make it easier to drop in
machine-specific flash initialization (patch 6).
  - Extend the series with additional patches to enable booting from flash:
  - Boot ROM (through the -bios option).
  - OTP (fuse) controller.
  - Memory Controller stub (just enough to skip memory training).
  - Flash controller.
  - Board-specific flash initialization.

Thanks for reviewing,

Havard

Havard Skinnemoen (12):
  npcm7xx: Add config symbol
  hw/misc: Add NPCM7xx System Global Control Registers device model
  hw/misc: Add NPCM7xx Clock Controller device model
  hw/timer: Add NPCM7xx Timer device model
  hw/arm: Add NPCM730 and NPCM750 SoC models
  hw/arm: Add two NPCM7xx-based machines
  hw/arm: Load -bios image as a boot ROM for npcm7xx
  hw/nvram: NPCM7xx OTP device model
  hw/mem: Stubbed out NPCM7xx Memory Controller model
  hw/ssi: NPCM7xx Flash Interface Unit device model
  hw/arm: Wire up BMC boot flash for npcm750-evb and quanta-gsj
  docs/system: Add Nuvoton machine documentation

 MAINTAINERS  |  18 ++
 default-configs/arm-softmmu.mak  |   1 +
 docs/system/arm/nuvoton.rst  |  89 ++
 docs/system/target-arm.rst   |   1 +
 hw/arm/Kconfig   |   9 +
 hw/arm/Makefile.objs |   1 +
 hw/arm/npcm7xx.c | 449 
 hw/arm/npcm7xx_boards.c  | 168 +++
 hw/mem/Makefile.objs |   1 +
 hw/mem/npcm7xx_mc.c  |  83 ++
 hw/misc/Makefile.objs|   2 +
 hw/misc/npcm7xx_clk.c| 216 ++
 hw/misc/npcm7xx_gcr.c| 211 +
 hw/misc/trace-events |   8 +
 hw/nvram/Makefile.objs   |   1 +
 hw/nvram/npcm7xx_otp.c   | 391 
 hw/ssi/Makefile.objs |   1 +
 hw/ssi/npcm7xx_fiu.c | 497 +++
 hw/ssi/trace-events  |   9 +
 hw/timer/Makefile.objs   |   1 +
 hw/timer/npcm7xx_timer.c | 437 +++
 hw/timer/trace-events|   5 +
 include/hw/arm/npcm7xx.h | 106 +++
 include/hw/mem/npcm7xx_mc.h  |  35 +++
 include/hw/misc/npcm7xx_clk.h|  65 
 include/hw/misc/npcm7xx_gcr.h|  76 +
 include/hw/nvram/npcm7xx_otp.h   |  93 ++
 include/hw/ssi/npcm7xx_fiu.h |  99 ++
 include/hw/timer/npcm7xx_timer.h |  95 ++
 29 files changed, 3168 insertions(+)
 create mode 100644 

Re: [PATCH v6 1/8] qcow2: Fix capitalization of header extension constant.

2020-06-11 Thread Eric Blake

On 6/11/20 4:19 PM, Andrey Shinkevich wrote:

Make the capitalization of the hexadecimal numbers consistent for the
QCOW2 header extension constants in docs/interop/qcow2.txt.

Suggested-by: Eric Blake 
Signed-off-by: Andrey Shinkevich 
---
  block/qcow2.c  | 2 +-
  docs/interop/qcow2.txt | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)



tests/qemu-iotests/114 has an instance that could be adjusted as well 
(no change to 114.out).


With that added,
Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PULL v2 0/3] NBD patches through 2020-06-09

2020-06-11 Thread Peter Maydell
On Wed, 10 Jun 2020 at 19:07, Eric Blake  wrote:
>
> The following changes since commit 31d321c2b3574dcc74e9f6411af06bca6b5d10f4:
>
>   Merge remote-tracking branch 
> 'remotes/philmd-gitlab/tags/sparc-next-20200609' into staging (2020-06-09 
> 17:29:47 +0100)
>
> are available in the Git repository at:
>
>   https://repo.or.cz/qemu/ericb.git tags/pull-nbd-2020-06-09-v2
>
> for you to fetch changes up to 5c86bdf1208916ece0b87e1151c9b48ee54faa3e:
>
>   block: Call attention to truncation of long NBD exports (2020-06-10 
> 12:58:59 -0500)
>
> In v2: patch 2 adjusted per review (only sending the changed patch)
>
> 
> NBD patches for 2020-06-09
>
> - fix iotest 194 race
> - fix CVE-2020-10761: server DoS from assertion on long NBD error messages
>



Applied, thanks.

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

-- PMM



[PATCH v6 0/8] iotests: Dump QCOW2 dirty bitmaps metadata

2020-06-11 Thread Andrey Shinkevich
Note: based on the Vladimir's series
  [v5 00/13] iotests: Dump QCOW2 dirty bitmaps metadata

Add dirty bitmap information to QCOW2 metadata dump in the qcow2_format.py.

v6:
  01: Fixing capitalization of header extension constant.
  (Suggested by Eric)
  02: The cluster size global variable discarded and passed as a parameter.
  03: Re-based to Vladimir's v5 series.
  04: The code of passing qcow2.py JSON format key moved to separate patch.
  05: Making dict(s) for dumping in JSON format was substituted with a copy
  of __dict__.

v5: The Vladimir's preliminary series
v4: The Vladimir's preliminary series

Andrey Shinkevich (8):
  qcow2: Fix capitalization of header extension constant.
  qcow2_format.py: make printable data an extension class member
  qcow2_format.py: Dump bitmap directory info
  qcow2_format.py: pass cluster size to substructures
  qcow2_format.py: Dump bitmap table serialized entries
  qcow2.py: Introduce '-j' key to dump in JSON format
  qcow2_format.py: collect fields to dump in JSON format
  qcow2_format.py: support dumping metadata in JSON  format

 block/qcow2.c  |   2 +-
 docs/interop/qcow2.txt |   2 +-
 tests/qemu-iotests/qcow2.py|  20 +++-
 tests/qemu-iotests/qcow2_format.py | 219 ++---
 4 files changed, 222 insertions(+), 21 deletions(-)

-- 
1.8.3.1




[PATCH v6 1/8] qcow2: Fix capitalization of header extension constant.

2020-06-11 Thread Andrey Shinkevich
Make the capitalization of the hexadecimal numbers consistent for the
QCOW2 header extension constants in docs/interop/qcow2.txt.

Suggested-by: Eric Blake 
Signed-off-by: Andrey Shinkevich 
---
 block/qcow2.c  | 2 +-
 docs/interop/qcow2.txt | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 0cd2e67..80dfe5f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -66,7 +66,7 @@ typedef struct {
 } QEMU_PACKED QCowExtension;
 
 #define  QCOW2_EXT_MAGIC_END 0
-#define  QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA
+#define  QCOW2_EXT_MAGIC_BACKING_FORMAT 0xe2792aca
 #define  QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
 #define  QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
 #define  QCOW2_EXT_MAGIC_BITMAPS 0x23852875
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
index cb72346..f072e27 100644
--- a/docs/interop/qcow2.txt
+++ b/docs/interop/qcow2.txt
@@ -231,7 +231,7 @@ be stored. Each extension has a structure like the 
following:
 
 Byte  0 -  3:   Header extension type:
 0x - End of the header extension area
-0xE2792ACA - Backing file format name string
+0xe2792aca - Backing file format name string
 0x6803f857 - Feature name table
 0x23852875 - Bitmaps extension
 0x0537be77 - Full disk encryption header pointer
-- 
1.8.3.1




[PATCH v6 3/8] qcow2_format.py: Dump bitmap directory info

2020-06-11 Thread Andrey Shinkevich
Read and dump entries from the bitmap directory of QCOW2 image with the
script qcow2.py.

Header extension:
magic 0x23852875 (Bitmaps)
...
Bitmap name   bitmap-1
flag  auto
table size8 (bytes)
bitmap_table_offset   0x9
bitmap_table_size 1
flags 0
type  1
granularity_bits  16
name_size 8
extra_data_size   0

Suggested-by: Kevin Wolf 
Signed-off-by: Andrey Shinkevich 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 tests/qemu-iotests/qcow2_format.py | 75 ++
 1 file changed, 75 insertions(+)

diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index d4f..a7868a7 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -103,6 +103,10 @@ class Qcow2Struct(metaclass=Qcow2StructMeta):
 print('{:<25} {}'.format(f[2], value_str))
 
 
+# seek relative to the current position in the file
+FROM_CURRENT = 1
+
+
 class Qcow2BitmapExt(Qcow2Struct):
 
 fields = (
@@ -112,6 +116,73 @@ class Qcow2BitmapExt(Qcow2Struct):
 ('u64', '{:#x}', 'bitmap_directory_offset')
 )
 
+def read_bitmap_directory(self, fd):
+self.bitmaps = []
+fd.seek(self.bitmap_directory_offset)
+buf_size = struct.calcsize(Qcow2BitmapDirEntry.fmt)
+
+for n in range(self.nb_bitmaps):
+buf = fd.read(buf_size)
+dir_entry = Qcow2BitmapDirEntry(data=buf)
+fd.seek(dir_entry.extra_data_size, FROM_CURRENT)
+bitmap_name = fd.read(dir_entry.name_size)
+dir_entry.name = bitmap_name.decode('ascii')
+self.bitmaps.append(dir_entry)
+entry_raw_size = dir_entry.bitmap_dir_entry_raw_size()
+shift = ((entry_raw_size + 7) & ~7) - entry_raw_size
+fd.seek(shift, FROM_CURRENT)
+
+def load(self, fd):
+self.read_bitmap_directory(fd)
+
+def dump(self):
+super().dump()
+for bm in self.bitmaps:
+bm.dump_bitmap_dir_entry()
+
+
+BME_FLAG_IN_USE = 1 << 0
+BME_FLAG_AUTO = 1 << 1
+
+
+class Qcow2BitmapDirEntry(Qcow2Struct):
+
+name = ''
+
+fields = (
+('u64', '{:#x}', 'bitmap_table_offset'),
+('u32', '{}','bitmap_table_size'),
+('u32', '{}','flags'),
+('u8',  '{}','type'),
+('u8',  '{}','granularity_bits'),
+('u16', '{}','name_size'),
+('u32', '{}','extra_data_size')
+)
+
+def __init__(self, data):
+super().__init__(data=data)
+
+self.bitmap_table_bytes = self.bitmap_table_size \
+* struct.calcsize('Q')
+
+self.bitmap_flags = []
+if (self.flags & BME_FLAG_IN_USE):
+self.bitmap_flags.append("in-use")
+if (self.flags & BME_FLAG_AUTO):
+self.bitmap_flags.append("auto")
+
+def bitmap_dir_entry_raw_size(self):
+return struct.calcsize(self.fmt) + self.name_size + \
+self.extra_data_size
+
+def dump_bitmap_dir_entry(self):
+print()
+print(f'{"Bitmap name":<25} {self.name}')
+for fl in self.bitmap_flags:
+print(f'{"flag":<25} {fl}')
+print(f'{"table size ":<25} {self.bitmap_table_bytes} {"(bytes)"}')
+super().dump()
+
 
 QCOW2_EXT_MAGIC_BITMAPS = 0x23852875
 
@@ -253,6 +324,10 @@ class QcowHeader(Qcow2Struct):
 else:
 self.extensions.append(ext)
 
+for ext in self.extensions:
+if ext.obj is not None:
+ext.obj.load(fd)
+
 def update_extensions(self, fd):
 
 fd.seek(self.header_length)
-- 
1.8.3.1




[PATCH v6 5/8] qcow2_format.py: Dump bitmap table serialized entries

2020-06-11 Thread Andrey Shinkevich
Add bitmap table information to the QCOW2 metadata dump.

Bitmap name   bitmap-1
...
Bitmap tabletypeoffset  size
0   serialized  0xa 65536
1   all-zeroes  0x0 65536
2   all-zeroes  0x0 65536
3   all-zeroes  0x0 65536
4   all-zeroes  0x0 65536
5   all-zeroes  0x0 65536
6   all-zeroes  0x0 65536
7   all-zeroes  0x0 65536

Signed-off-by: Andrey Shinkevich 
Reviewed-by: Eric Blake 
---
 tests/qemu-iotests/qcow2_format.py | 42 ++
 1 file changed, 42 insertions(+)

diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index 6589f68..2e7c058 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -137,6 +137,9 @@ class Qcow2BitmapExt(Qcow2Struct):
 shift = ((entry_raw_size + 7) & ~7) - entry_raw_size
 fd.seek(shift, FROM_CURRENT)
 
+for bm in self.bitmaps:
+bm.read_bitmap_table(fd)
+
 def load(self, fd):
 self.read_bitmap_directory(fd)
 
@@ -181,6 +184,12 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
 return struct.calcsize(self.fmt) + self.name_size + \
 self.extra_data_size
 
+def read_bitmap_table(self, fd):
+fd.seek(self.bitmap_table_offset)
+table_size = self.bitmap_table_bytes * struct.calcsize('Q')
+table = [e[0] for e in struct.iter_unpack('>Q', fd.read(table_size))]
+self.bitmap_table = Qcow2BitmapTable(table)
+
 def dump_bitmap_dir_entry(self):
 print()
 print(f'{"Bitmap name":<25} {self.name}')
@@ -188,6 +197,39 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
 print(f'{"flag":<25} {fl}')
 print(f'{"table size ":<25} {self.bitmap_table_bytes} {"(bytes)"}')
 super().dump()
+self.bitmap_table.print_bitmap_table(self.cluster_size)
+
+
+class Qcow2BitmapTableEntry:
+
+BME_TABLE_ENTRY_OFFSET_MASK = 0x00fffe00
+BME_TABLE_ENTRY_FLAG_ALL_ONES = 1
+bmte_type = ['all-zeroes', 'all-ones', 'serialized']
+
+def __init__(self, entry):
+self.offset = entry & self.BME_TABLE_ENTRY_OFFSET_MASK
+if self.offset:
+self.type = 'serialized'
+elif entry & self.BME_TABLE_ENTRY_FLAG_ALL_ONES:
+self.type = 'all-ones'
+else:
+self.type = 'all-zeroes'
+
+
+class Qcow2BitmapTable:
+
+def __init__(self, raw_table):
+self.entries = []
+for entry in raw_table:
+self.entries.append(Qcow2BitmapTableEntry(entry))
+
+def print_bitmap_table(self, cluster_size):
+bitmap_table = enumerate(self.entries)
+print("Bitmap table\ttype\t\toffset\t\tsize")
+for i, entry in bitmap_table:
+print("\t%-4d\t%s\t%#x\t\t%d" % (i, entry.type, entry.offset,
+ cluster_size))
+print("")
 
 
 QCOW2_EXT_MAGIC_BITMAPS = 0x23852875
-- 
1.8.3.1




[PATCH v6 8/8] qcow2_format.py: support dumping metadata in JSON format

2020-06-11 Thread Andrey Shinkevich
Implementation of dumping QCOW2 image metadata.
The sample output:
{
"Header_extensions": [
{
"name": "Feature table",
"magic": 1745090647,
"length": 192,
"data_str": ""
},
{
"name": "Bitmaps",
"magic": 595929205,
"length": 24,
"data": {
"nb_bitmaps": 2,
"reserved32": 0,
"bitmap_directory_size": 64,
"bitmap_directory_offset": 1048576,
"entries": [
{
"name": "bitmap-1",
"bitmap_table_offset": 589824,
"bitmap_table_size": 1,
"flags": [
"auto"
],
"type": 1,
"granularity_bits": 16,
"name_size": 8,
"extra_data_size": 0,
"bitmap_table": {
"table_entries": [
{
"type": "serialized",
"offset": 655360
},
...

Suggested-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Andrey Shinkevich 
---
 tests/qemu-iotests/qcow2_format.py | 60 ++
 1 file changed, 60 insertions(+)

diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index bb2f13b..d87f8e0 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -18,6 +18,15 @@
 
 import struct
 import string
+import json
+
+
+class ComplexEncoder(json.JSONEncoder):
+def default(self, obj):
+if hasattr(obj, 'get_fields_dict'):
+return obj.get_fields_dict()
+else:
+return json.JSONEncoder.default(self, obj)
 
 
 class Qcow2Field:
@@ -95,6 +104,11 @@ class Qcow2Struct(metaclass=Qcow2StructMeta):
 self.fields_dict = self.__dict__.copy()
 
 def dump(self, dump_json=None):
+if dump_json:
+print(json.dumps(self.get_fields_dict(), indent=4,
+ cls=ComplexEncoder))
+return
+
 for f in self.fields:
 value = self.__dict__[f[2]]
 if isinstance(f[1], str):
@@ -150,6 +164,9 @@ class Qcow2BitmapExt(Qcow2Struct):
 for bm in self.bitmaps:
 bm.dump_bitmap_dir_entry(dump_json)
 
+def get_fields_dict(self):
+return self.fields_dict
+
 
 BME_FLAG_IN_USE = 1 << 0
 BME_FLAG_AUTO = 1 << 1
@@ -202,6 +219,12 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
 super().dump()
 self.bitmap_table.print_bitmap_table(self.cluster_size)
 
+def get_fields_dict(self):
+bmp_name = dict(name=self.name)
+bme_dict = {**bmp_name, **self.fields_dict}
+bme_dict['flags'] = self.bitmap_flags
+return bme_dict
+
 
 class Qcow2BitmapTableEntry:
 
@@ -218,6 +241,9 @@ class Qcow2BitmapTableEntry:
 else:
 self.type = 'all-zeroes'
 
+def get_fields_dict(self):
+return dict(type=self.type, offset=self.offset)
+
 
 class Qcow2BitmapTable:
 
@@ -234,6 +260,18 @@ class Qcow2BitmapTable:
  cluster_size))
 print("")
 
+def get_fields_dict(self):
+return dict(table_entries=self.entries)
+
+
+class Qcow2HeaderExtensionsDoc:
+
+def __init__(self, extensions):
+self.extensions = extensions
+
+def get_fields_dict(self):
+return dict(Header_extensions=self.extensions)
+
 
 QCOW2_EXT_MAGIC_BITMAPS = 0x23852875
 
@@ -249,6 +287,9 @@ class QcowHeaderExtension(Qcow2Struct):
 0x44415441: 'Data file'
 }
 
+def get_fields_dict(self):
+return self.mapping.get(self.value, "")
+
 fields = (
 ('u32', Magic, 'magic'),
 ('u32', '{}', 'length')
@@ -309,6 +350,16 @@ class QcowHeaderExtension(Qcow2Struct):
 else:
 self.obj.dump(dump_json)
 
+def get_fields_dict(self):
+ext_name = dict(name=self.Magic(self.magic))
+he_dict = {**ext_name, **self.fields_dict}
+if self.obj is not None:
+he_dict.update(data=self.obj)
+else:
+he_dict.update(data_str=self.data_str)
+
+return he_dict
+
 @classmethod
 def create(cls, magic, data):
 return QcowHeaderExtension(magic, len(data), data)
@@ -411,7 +462,16 @@ class QcowHeader(Qcow2Struct):
 fd.write(buf)
 
 def dump_extensions(self, dump_json=None):
+if dump_json:
+ext_doc = Qcow2HeaderExtensionsDoc(self.extensions)
+print(json.dumps(ext_doc.get_fields_dict(), indent=4,
+ cls=ComplexEncoder))
+return
+
 for ex in self.extensions:
 print('Header 

[PATCH v6 7/8] qcow2_format.py: collect fields to dump in JSON format

2020-06-11 Thread Andrey Shinkevich
As __dict__ is being extended with class members we do not want to
print in JSON format dump, make a light copy of the initial __dict__
and extend the copy by adding lists we have to print in the JSON
output.

Signed-off-by: Andrey Shinkevich 
---
 tests/qemu-iotests/qcow2_format.py | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index 95db7a9..bb2f13b 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -92,6 +92,8 @@ class Qcow2Struct(metaclass=Qcow2StructMeta):
 self.__dict__ = dict((field[2], values[i])
  for i, field in enumerate(self.fields))
 
+self.fields_dict = self.__dict__.copy()
+
 def dump(self, dump_json=None):
 for f in self.fields:
 value = self.__dict__[f[2]]
@@ -102,7 +104,6 @@ class Qcow2Struct(metaclass=Qcow2StructMeta):
 
 print('{:<25} {}'.format(f[2], value_str))
 
-
 # seek relative to the current position in the file
 FROM_CURRENT = 1
 
@@ -142,6 +143,7 @@ class Qcow2BitmapExt(Qcow2Struct):
 
 def load(self, fd):
 self.read_bitmap_directory(fd)
+self.fields_dict.update(entries=self.bitmaps)
 
 def dump(self, dump_json=None):
 super().dump(dump_json)
@@ -189,6 +191,7 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
 table_size = self.bitmap_table_bytes * struct.calcsize('Q')
 table = [e[0] for e in struct.iter_unpack('>Q', fd.read(table_size))]
 self.bitmap_table = Qcow2BitmapTable(table)
+self.fields_dict.update(bitmap_table=self.bitmap_table)
 
 def dump_bitmap_dir_entry(self, dump_json=None):
 print()
-- 
1.8.3.1




[PATCH v6 2/8] qcow2_format.py: make printable data an extension class member

2020-06-11 Thread Andrey Shinkevich
Let us differ binary data type from string one for the extension data
variable and keep the string as the QcowHeaderExtension class member.

Signed-off-by: Andrey Shinkevich 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 tests/qemu-iotests/qcow2_format.py | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index 0f65fd1..d4f 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -164,6 +164,13 @@ class QcowHeaderExtension(Qcow2Struct):
 self.data = fd.read(padded)
 assert self.data is not None
 
+data_str = self.data[:self.length]
+if all(c in string.printable.encode('ascii') for c in data_str):
+data_str = f"'{ data_str.decode('ascii') }'"
+else:
+data_str = ''
+self.data_str = data_str
+
 if self.magic == QCOW2_EXT_MAGIC_BITMAPS:
 self.obj = Qcow2BitmapExt(data=self.data)
 else:
@@ -173,12 +180,7 @@ class QcowHeaderExtension(Qcow2Struct):
 super().dump()
 
 if self.obj is None:
-data = self.data[:self.length]
-if all(c in string.printable.encode('ascii') for c in data):
-data = f"'{ data.decode('ascii') }'"
-else:
-data = ''
-print(f'{"data":<25} {data}')
+print(f'{"data":<25} {self.data_str}')
 else:
 self.obj.dump()
 
-- 
1.8.3.1




[PATCH v6 6/8] qcow2.py: Introduce '-j' key to dump in JSON format

2020-06-11 Thread Andrey Shinkevich
Add the command key to the qcow2.py arguments list to dump QCOW2
metadata in JSON format. Here is the suggested way to do that. The
implementation of the dump in JSON format is in the patch that follows.

Signed-off-by: Andrey Shinkevich 
---
 tests/qemu-iotests/qcow2.py| 20 +++-
 tests/qemu-iotests/qcow2_format.py | 18 +-
 2 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/tests/qemu-iotests/qcow2.py b/tests/qemu-iotests/qcow2.py
index 8c187e9..b08d8fc 100755
--- a/tests/qemu-iotests/qcow2.py
+++ b/tests/qemu-iotests/qcow2.py
@@ -24,16 +24,19 @@ from qcow2_format import (
 )
 
 
+dump_json = False
+
+
 def cmd_dump_header(fd):
 h = QcowHeader(fd)
-h.dump()
+h.dump(dump_json)
 print()
-h.dump_extensions()
+h.dump_extensions(dump_json)
 
 
 def cmd_dump_header_exts(fd):
 h = QcowHeader(fd)
-h.dump_extensions()
+h.dump_extensions(dump_json)
 
 
 def cmd_set_header(fd, name, value):
@@ -132,6 +135,11 @@ cmds = [
 
 
 def main(filename, cmd, args):
+global dump_json
+dump_json = '-j' in sys.argv
+if dump_json:
+sys.argv.remove('-j')
+args.remove('-j')
 fd = open(filename, "r+b")
 try:
 for name, handler, num_args, desc in cmds:
@@ -149,12 +157,14 @@ def main(filename, cmd, args):
 
 
 def usage():
-print("Usage: %s   [, ...]" % sys.argv[0])
+print("Usage: %s   [, ...] [, ...]" % sys.argv[0])
 print("")
 print("Supported commands:")
 for name, handler, num_args, desc in cmds:
 print("%-20s - %s" % (name, desc))
-
+print("")
+print("Supported keys:")
+print("%-20s - %s" % ('-j', 'Dump in JSON format'))
 
 if __name__ == '__main__':
 if len(sys.argv) < 3:
diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index 2e7c058..95db7a9 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -92,7 +92,7 @@ class Qcow2Struct(metaclass=Qcow2StructMeta):
 self.__dict__ = dict((field[2], values[i])
  for i, field in enumerate(self.fields))
 
-def dump(self):
+def dump(self, dump_json=None):
 for f in self.fields:
 value = self.__dict__[f[2]]
 if isinstance(f[1], str):
@@ -143,10 +143,10 @@ class Qcow2BitmapExt(Qcow2Struct):
 def load(self, fd):
 self.read_bitmap_directory(fd)
 
-def dump(self):
-super().dump()
+def dump(self, dump_json=None):
+super().dump(dump_json)
 for bm in self.bitmaps:
-bm.dump_bitmap_dir_entry()
+bm.dump_bitmap_dir_entry(dump_json)
 
 
 BME_FLAG_IN_USE = 1 << 0
@@ -190,7 +190,7 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
 table = [e[0] for e in struct.iter_unpack('>Q', fd.read(table_size))]
 self.bitmap_table = Qcow2BitmapTable(table)
 
-def dump_bitmap_dir_entry(self):
+def dump_bitmap_dir_entry(self, dump_json=None):
 print()
 print(f'{"Bitmap name":<25} {self.name}')
 for fl in self.bitmap_flags:
@@ -298,13 +298,13 @@ class QcowHeaderExtension(Qcow2Struct):
 else:
 self.obj = None
 
-def dump(self):
+def dump(self, dump_json=None):
 super().dump()
 
 if self.obj is None:
 print(f'{"data":<25} {self.data_str}')
 else:
-self.obj.dump()
+self.obj.dump(dump_json)
 
 @classmethod
 def create(cls, magic, data):
@@ -407,8 +407,8 @@ class QcowHeader(Qcow2Struct):
 buf = buf[0:header_bytes-1]
 fd.write(buf)
 
-def dump_extensions(self):
+def dump_extensions(self, dump_json=None):
 for ex in self.extensions:
 print('Header extension:')
-ex.dump()
+ex.dump(dump_json)
 print()
-- 
1.8.3.1




[PATCH v6 4/8] qcow2_format.py: pass cluster size to substructures

2020-06-11 Thread Andrey Shinkevich
The cluster size of an image is the QcowHeader class member and may be
obtained by dependent extension structures such as Qcow2BitmapExt for
further bitmap table details print.

Signed-off-by: Andrey Shinkevich 
---
 tests/qemu-iotests/qcow2_format.py | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/tests/qemu-iotests/qcow2_format.py 
b/tests/qemu-iotests/qcow2_format.py
index a7868a7..6589f68 100644
--- a/tests/qemu-iotests/qcow2_format.py
+++ b/tests/qemu-iotests/qcow2_format.py
@@ -116,6 +116,10 @@ class Qcow2BitmapExt(Qcow2Struct):
 ('u64', '{:#x}', 'bitmap_directory_offset')
 )
 
+def __init__(self, data, cluster_size):
+super().__init__(data=data)
+self.cluster_size = cluster_size
+
 def read_bitmap_directory(self, fd):
 self.bitmaps = []
 fd.seek(self.bitmap_directory_offset)
@@ -123,7 +127,8 @@ class Qcow2BitmapExt(Qcow2Struct):
 
 for n in range(self.nb_bitmaps):
 buf = fd.read(buf_size)
-dir_entry = Qcow2BitmapDirEntry(data=buf)
+dir_entry = Qcow2BitmapDirEntry(data=buf,
+cluster_size=self.cluster_size)
 fd.seek(dir_entry.extra_data_size, FROM_CURRENT)
 bitmap_name = fd.read(dir_entry.name_size)
 dir_entry.name = bitmap_name.decode('ascii')
@@ -159,8 +164,9 @@ class Qcow2BitmapDirEntry(Qcow2Struct):
 ('u32', '{}','extra_data_size')
 )
 
-def __init__(self, data):
+def __init__(self, data, cluster_size):
 super().__init__(data=data)
+self.cluster_size = cluster_size
 
 self.bitmap_table_bytes = self.bitmap_table_size \
 * struct.calcsize('Q')
@@ -205,11 +211,13 @@ class QcowHeaderExtension(Qcow2Struct):
 # then padding to next multiply of 8
 )
 
-def __init__(self, magic=None, length=None, data=None, fd=None):
+def __init__(self, magic=None, length=None, data=None, fd=None,
+ cluster_size=None):
 """
 Support both loading from fd and creation from user data.
 For fd-based creation current position in a file will be used to read
 the data.
+The cluster_size value may be obtained by dependent structures.
 
 This should be somehow refactored and functionality should be moved to
 superclass (to allow creation of any qcow2 struct), but then, fields
@@ -243,7 +251,8 @@ class QcowHeaderExtension(Qcow2Struct):
 self.data_str = data_str
 
 if self.magic == QCOW2_EXT_MAGIC_BITMAPS:
-self.obj = Qcow2BitmapExt(data=self.data)
+self.obj = Qcow2BitmapExt(data=self.data,
+  cluster_size=cluster_size)
 else:
 self.obj = None
 
@@ -318,7 +327,7 @@ class QcowHeader(Qcow2Struct):
 end = self.cluster_size
 
 while fd.tell() < end:
-ext = QcowHeaderExtension(fd=fd)
+ext = QcowHeaderExtension(fd=fd, cluster_size=self.cluster_size)
 if ext.magic == 0:
 break
 else:
-- 
1.8.3.1




Re: [PATCH v3 1/2] PCI: vmd: Filter resource type bits from shadow register

2020-06-11 Thread Derrick, Jonathan
On Fri, 2020-05-29 at 17:18 +0100, Lorenzo Pieralisi wrote:
> On Fri, May 29, 2020 at 03:53:37PM +, Derrick, Jonathan wrote:
> > On Fri, 2020-05-29 at 11:33 +0100, Lorenzo Pieralisi wrote:
> > > On Wed, May 27, 2020 at 11:02:39PM -0400, Jon Derrick wrote:
> > > > Versions of VMD with the Host Physical Address shadow register use this
> > > > register to calculate the bus address offset needed to do guest
> > > > passthrough of the domain. This register shadows the Host Physical
> > > > Address registers including the resource type bits. After calculating
> > > > the offset, the extra resource type bits lead to the VMD resources being
> > > > over-provisioned at the front and under-provisioned at the back.
> > > > 
> > > > Example:
> > > > pci 1:80:02.0: reg 0x10: [mem 0xf801fffc-0xf803fffb 64bit]
> > > > 
> > > > Expected:
> > > > pci 1:80:02.0: reg 0x10: [mem 0xf802-0xf803 64bit]
> > > > 
> > > > If other devices are mapped in the over-provisioned front, it could lead
> > > > to resource conflict issues with VMD or those devices.
> > > > 
> > > > Fixes: a1a30170138c9 ("PCI: vmd: Fix shadow offsets to reflect spec 
> > > > changes")
> > > > Signed-off-by: Jon Derrick 
> > > > ---
> > > >  drivers/pci/controller/vmd.c | 6 --
> > > >  1 file changed, 4 insertions(+), 2 deletions(-)
> > > 
> > > Hi Jon,
> > > 
> > > it looks like I can take this patch for v5.8 whereas patch 2 depends
> > > on the QEMU changes acceptance and should probably wait.
> > > 
> > > Please let me know your thoughts asap and I will try to at least
> > > squeeze this patch in.
> > > 
> > > Lorenzo
> > 
> > Hi Lorenzo,
> > 
> > This is fine. Please take Patch 1.
> > Patch 2 is harmless without the QEMU changes, but may always need a
> > different approach.
> 
> Pulled patch 1 into pci/vmd, thanks.
> 
> Lorenzo

Hi Lorenzo,

Alex has pr-ed the QEMU patch [1]
Is it too late to pull patch 2/2 for v5.8?

[1] 
https://github.com/awilliam/qemu-vfio/releases/tag/vfio-update-20200611.0


[PULL 106/115] target/i386: sev: Remove redundant policy field

2020-06-11 Thread Paolo Bonzini
From: David Gibson 

SEVState::policy is set from the final value of the policy field in the
parameter structure for the KVM_SEV_LAUNCH_START ioctl().  But, AFAICT
that ioctl() won't ever change it from the original supplied value which
comes from SevGuestState::policy.

So, remove this field and just use SevGuestState::policy directly.

Signed-off-by: David Gibson 
Reviewed-by: Richard Henderson 
Message-Id: <20200604064219.436242-8-da...@gibson.dropbear.id.au>
Signed-off-by: Paolo Bonzini 
---
 target/i386/sev.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index d25af37136..4b261beaa7 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -39,7 +39,6 @@ struct SEVState {
 uint8_t api_major;
 uint8_t api_minor;
 uint8_t build_id;
-uint32_t policy;
 uint64_t me_mask;
 uint32_t handle;
 int sev_fd;
@@ -397,7 +396,7 @@ sev_get_info(void)
 info->api_major = sev_guest->state.api_major;
 info->api_minor = sev_guest->state.api_minor;
 info->build_id = sev_guest->state.build_id;
-info->policy = sev_guest->state.policy;
+info->policy = sev_guest->policy;
 info->state = sev_guest->state.state;
 info->handle = sev_guest->state.handle;
 }
@@ -520,8 +519,7 @@ sev_launch_start(SevGuestState *sev)
 
 start->handle = object_property_get_int(OBJECT(sev), "handle",
 _abort);
-start->policy = object_property_get_int(OBJECT(sev), "policy",
-_abort);
+start->policy = sev->policy;
 if (sev->session_file) {
 if (sev_read_file_base64(sev->session_file, , ) < 0) {
 goto out;
@@ -550,7 +548,6 @@ sev_launch_start(SevGuestState *sev)
 _abort);
 sev_set_guest_state(sev, SEV_STATE_LAUNCH_UPDATE);
 s->handle = start->handle;
-s->policy = start->policy;
 ret = 0;
 
 out:
-- 
2.26.2





[PULL 113/115] replay: fix replay shutdown for console mode

2020-06-11 Thread Paolo Bonzini
From: Pavel Dovgalyuk 

When QEMU is used without any graphical window,
QEMU execution is terminated with the signal (e.g., Ctrl-C).
Signal processing in QEMU does not include
qemu_system_shutdown_request call. That is why shutdown
event is not recorded by record/replay in this case.
This patch adds shutdown event to the end of the record log.
Now every replay will shutdown the machine at the end.

Signed-off-by: Pavel Dovgalyuk 
Message-Id: <159012995470.27967.18129611453659045726.stgit@pasha-ThinkPad-X280>
Signed-off-by: Paolo Bonzini 
---
 replay/replay.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/replay/replay.c b/replay/replay.c
index 706c7b4f4b..7d93746c73 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -366,6 +366,11 @@ void replay_finish(void)
 /* finalize the file */
 if (replay_file) {
 if (replay_mode == REPLAY_MODE_RECORD) {
+/*
+ * Can't do it in the signal handler, therefore
+ * add shutdown event here for the case of Ctrl-C.
+ */
+replay_shutdown_request(SHUTDOWN_CAUSE_HOST_SIGNAL);
 /* write end event */
 replay_put_event(EVENT_END);
 
-- 
2.26.2





[PULL 109/115] checkpatch: reversed logic with acpi test checks

2020-06-11 Thread Paolo Bonzini
From: "Michael S. Tsirkin" 

Logic reversed: allowed list should just be ignored. Instead we
only take that into account :(

Fixes: e11b06a880ca ("checkpatch: ignore allowed diff list")
Signed-off-by: Michael S. Tsirkin 
Message-Id: <20200602053614.54745-1-...@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Eric Auger 
Tested-by: Eric Auger 
Signed-off-by: Paolo Bonzini 
---
 scripts/checkpatch.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 0ba213e9f2..2d2e922d89 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1267,7 +1267,7 @@ sub checkfilename {
 # files and when changing tests.
if ($name =~ m#^tests/data/acpi/# and not $name =~ m#^\.sh$#) {
$$acpi_testexpected = $name;
-   } elsif ($name =~ m#^tests/qtest/bios-tables-test-allowed-diff.h$#) {
+   } elsif ($name !~ m#^tests/qtest/bios-tables-test-allowed-diff.h$#) {
$$acpi_nontestexpected = $name;
}
if (defined $$acpi_testexpected and defined $$acpi_nontestexpected) {
-- 
2.26.2





[PATCH 1/1] util/getauxval: Porting to FreeBSD getauxval feature

2020-06-11 Thread David CARLIER



0001-util-getauxval-Porting-to-FreeBSD-the-getauxval-feat.patch
Description: Binary data


[PULL 108/115] target/i386: sev: Unify SEVState and SevGuestState

2020-06-11 Thread Paolo Bonzini
From: David Gibson 

SEVState is contained with SevGuestState.  We've now fixed redundancies
and name conflicts, so there's no real point to the nested structure.  Just
move all the fields of SEVState into SevGuestState.

This eliminates the SEVState structure, which as a bonus removes the
confusion with the SevState enum.

Signed-off-by: David Gibson 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20200604064219.436242-10-da...@gibson.dropbear.id.au>
Signed-off-by: Paolo Bonzini 
---
 target/i386/sev.c | 79 ---
 1 file changed, 34 insertions(+), 45 deletions(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index 24e2dea9b8..d273174ad3 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -35,18 +35,6 @@
 
 typedef struct SevGuestState SevGuestState;
 
-struct SEVState {
-uint8_t api_major;
-uint8_t api_minor;
-uint8_t build_id;
-uint64_t me_mask;
-int sev_fd;
-SevState state;
-gchar *measurement;
-};
-
-typedef struct SEVState SEVState;
-
 /**
  * SevGuestState:
  *
@@ -70,7 +58,13 @@ struct SevGuestState {
 
 /* runtime state */
 uint32_t handle;
-SEVState state;
+uint8_t api_major;
+uint8_t api_minor;
+uint8_t build_id;
+uint64_t me_mask;
+int sev_fd;
+SevState state;
+gchar *measurement;
 };
 
 #define DEFAULT_GUEST_POLICY0x1 /* disable debug */
@@ -158,7 +152,7 @@ static bool
 sev_check_state(const SevGuestState *sev, SevState state)
 {
 assert(sev);
-return sev->state.state == state ? true : false;
+return sev->state == state ? true : false;
 }
 
 static void
@@ -167,9 +161,9 @@ sev_set_guest_state(SevGuestState *sev, SevState new_state)
 assert(new_state < SEV_STATE__MAX);
 assert(sev);
 
-trace_kvm_sev_change_state(SevState_str(sev->state.state),
+trace_kvm_sev_change_state(SevState_str(sev->state),
SevState_str(new_state));
-sev->state.state = new_state;
+sev->state = new_state;
 }
 
 static void
@@ -368,7 +362,7 @@ sev_enabled(void)
 uint64_t
 sev_get_me_mask(void)
 {
-return sev_guest ? sev_guest->state.me_mask : ~0;
+return sev_guest ? sev_guest->me_mask : ~0;
 }
 
 uint32_t
@@ -392,11 +386,11 @@ sev_get_info(void)
 info->enabled = sev_enabled();
 
 if (info->enabled) {
-info->api_major = sev_guest->state.api_major;
-info->api_minor = sev_guest->state.api_minor;
-info->build_id = sev_guest->state.build_id;
+info->api_major = sev_guest->api_major;
+info->api_minor = sev_guest->api_minor;
+info->build_id = sev_guest->build_id;
 info->policy = sev_guest->policy;
-info->state = sev_guest->state.state;
+info->state = sev_guest->state;
 info->handle = sev_guest->handle;
 }
 
@@ -507,7 +501,6 @@ sev_read_file_base64(const char *filename, guchar **data, 
gsize *len)
 static int
 sev_launch_start(SevGuestState *sev)
 {
-SEVState *s = >state;
 gsize sz;
 int ret = 1;
 int fw_error, rc;
@@ -535,7 +528,7 @@ sev_launch_start(SevGuestState *sev)
 }
 
 trace_kvm_sev_launch_start(start->policy, session, dh_cert);
-rc = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, _error);
+rc = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_START, start, _error);
 if (rc < 0) {
 error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
 __func__, ret, fw_error, fw_error_to_str(fw_error));
@@ -566,7 +559,7 @@ sev_launch_update_data(SevGuestState *sev, uint8_t *addr, 
uint64_t len)
 update.uaddr = (__u64)(unsigned long)addr;
 update.len = len;
 trace_kvm_sev_launch_update_data(addr, len);
-ret = sev_ioctl(sev->state.sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA,
+ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA,
 , _error);
 if (ret) {
 error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
@@ -582,7 +575,6 @@ sev_launch_get_measure(Notifier *notifier, void *unused)
 SevGuestState *sev = sev_guest;
 int ret, error;
 guchar *data;
-SEVState *s = >state;
 struct kvm_sev_launch_measure *measurement;
 
 if (!sev_check_state(sev, SEV_STATE_LAUNCH_UPDATE)) {
@@ -592,7 +584,7 @@ sev_launch_get_measure(Notifier *notifier, void *unused)
 measurement = g_new0(struct kvm_sev_launch_measure, 1);
 
 /* query the measurement blob length */
-ret = sev_ioctl(sev->state.sev_fd, KVM_SEV_LAUNCH_MEASURE,
+ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_MEASURE,
 measurement, );
 if (!measurement->len) {
 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
@@ -604,7 +596,7 @@ sev_launch_get_measure(Notifier *notifier, void *unused)
 measurement->uaddr = (unsigned long)data;
 
 /* get the measurement blob */
-ret = sev_ioctl(sev->state.sev_fd, KVM_SEV_LAUNCH_MEASURE,
+ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_MEASURE,
  

[PULL 103/115] target/i386: sev: Embed SEVState in SevGuestState

2020-06-11 Thread Paolo Bonzini
From: David Gibson 

Currently SevGuestState contains only configuration information.  For
runtime state another non-QOM struct SEVState is allocated separately.

Simplify things by instead embedding the SEVState structure in
SevGuestState.

Signed-off-by: David Gibson 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20200604064219.436242-5-da...@gibson.dropbear.id.au>
Signed-off-by: Paolo Bonzini 
---
 target/i386/sev.c | 54 +--
 1 file changed, 29 insertions(+), 25 deletions(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index b6ed719fb5..b4ab9720d6 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -35,6 +35,22 @@
 
 typedef struct SevGuestState SevGuestState;
 
+struct SEVState {
+uint8_t api_major;
+uint8_t api_minor;
+uint8_t build_id;
+uint32_t policy;
+uint64_t me_mask;
+uint32_t cbitpos;
+uint32_t reduced_phys_bits;
+uint32_t handle;
+int sev_fd;
+SevState state;
+gchar *measurement;
+};
+
+typedef struct SEVState SEVState;
+
 /**
  * SevGuestState:
  *
@@ -48,6 +64,7 @@ typedef struct SevGuestState SevGuestState;
 struct SevGuestState {
 Object parent_obj;
 
+/* configuration parameters */
 char *sev_device;
 uint32_t policy;
 uint32_t handle;
@@ -55,25 +72,11 @@ struct SevGuestState {
 char *session_file;
 uint32_t cbitpos;
 uint32_t reduced_phys_bits;
-};
 
-struct SEVState {
-SevGuestState *sev_info;
-uint8_t api_major;
-uint8_t api_minor;
-uint8_t build_id;
-uint32_t policy;
-uint64_t me_mask;
-uint32_t cbitpos;
-uint32_t reduced_phys_bits;
-uint32_t handle;
-int sev_fd;
-SevState state;
-gchar *measurement;
+/* runtime state */
+SEVState state;
 };
 
-typedef struct SEVState SEVState;
-
 #define DEFAULT_GUEST_POLICY0x1 /* disable debug */
 #define DEFAULT_SEV_DEVICE  "/dev/sev"
 
@@ -506,12 +509,12 @@ sev_read_file_base64(const char *filename, guchar **data, 
gsize *len)
 }
 
 static int
-sev_launch_start(SEVState *s)
+sev_launch_start(SevGuestState *sev)
 {
+SEVState *s = >state;
 gsize sz;
 int ret = 1;
 int fw_error, rc;
-SevGuestState *sev = s->sev_info;
 struct kvm_sev_launch_start *start;
 guchar *session = NULL, *dh_cert = NULL;
 
@@ -686,6 +689,7 @@ sev_vm_state_change(void *opaque, int running, RunState 
state)
 void *
 sev_guest_init(const char *id)
 {
+SevGuestState *sev;
 SEVState *s;
 char *devname;
 int ret, fw_error;
@@ -693,27 +697,27 @@ sev_guest_init(const char *id)
 uint32_t host_cbitpos;
 struct sev_user_data_status status = {};
 
-sev_state = s = g_new0(SEVState, 1);
-s->sev_info = lookup_sev_guest_info(id);
-if (!s->sev_info) {
+sev = lookup_sev_guest_info(id);
+if (!sev) {
 error_report("%s: '%s' is not a valid '%s' object",
  __func__, id, TYPE_SEV_GUEST);
 goto err;
 }
 
+sev_state = s = >state;
 s->state = SEV_STATE_UNINIT;
 
 host_cpuid(0x801F, 0, NULL, , NULL, NULL);
 host_cbitpos = ebx & 0x3f;
 
-s->cbitpos = object_property_get_int(OBJECT(s->sev_info), "cbitpos", NULL);
+s->cbitpos = object_property_get_int(OBJECT(sev), "cbitpos", NULL);
 if (host_cbitpos != s->cbitpos) {
 error_report("%s: cbitpos check failed, host '%d' requested '%d'",
  __func__, host_cbitpos, s->cbitpos);
 goto err;
 }
 
-s->reduced_phys_bits = object_property_get_int(OBJECT(s->sev_info),
+s->reduced_phys_bits = object_property_get_int(OBJECT(sev),
 "reduced-phys-bits", NULL);
 if (s->reduced_phys_bits < 1) {
 error_report("%s: reduced_phys_bits check failed, it should be >=1,"
@@ -723,7 +727,7 @@ sev_guest_init(const char *id)
 
 s->me_mask = ~(1UL << s->cbitpos);
 
-devname = object_property_get_str(OBJECT(s->sev_info), "sev-device", NULL);
+devname = object_property_get_str(OBJECT(sev), "sev-device", NULL);
 s->sev_fd = open(devname, O_RDWR);
 if (s->sev_fd < 0) {
 error_report("%s: Failed to open %s '%s'", __func__,
@@ -754,7 +758,7 @@ sev_guest_init(const char *id)
 goto err;
 }
 
-ret = sev_launch_start(s);
+ret = sev_launch_start(sev);
 if (ret) {
 error_report("%s: failed to create encryption context", __func__);
 goto err;
-- 
2.26.2





[PULL 105/115] target/i386: sev: Remove redundant cbitpos and reduced_phys_bits fields

2020-06-11 Thread Paolo Bonzini
From: David Gibson 

The SEVState structure has cbitpos and reduced_phys_bits fields which are
simply copied from the SevGuestState structure and never changed.  Now that
SEVState is embedded in SevGuestState we can just access the original copy
directly.

Signed-off-by: David Gibson 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20200604064219.436242-7-da...@gibson.dropbear.id.au>
Signed-off-by: Paolo Bonzini 
---
 target/i386/sev.c | 19 +++
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index 9e8ab7b056..d25af37136 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -41,8 +41,6 @@ struct SEVState {
 uint8_t build_id;
 uint32_t policy;
 uint64_t me_mask;
-uint32_t cbitpos;
-uint32_t reduced_phys_bits;
 uint32_t handle;
 int sev_fd;
 SevState state;
@@ -378,13 +376,13 @@ sev_get_me_mask(void)
 uint32_t
 sev_get_cbit_position(void)
 {
-return sev_guest ? sev_guest->state.cbitpos : 0;
+return sev_guest ? sev_guest->cbitpos : 0;
 }
 
 uint32_t
 sev_get_reduced_phys_bits(void)
 {
-return sev_guest ? sev_guest->state.reduced_phys_bits : 0;
+return sev_guest ? sev_guest->reduced_phys_bits : 0;
 }
 
 SevInfo *
@@ -713,22 +711,19 @@ sev_guest_init(const char *id)
 host_cpuid(0x801F, 0, NULL, , NULL, NULL);
 host_cbitpos = ebx & 0x3f;
 
-s->cbitpos = object_property_get_int(OBJECT(sev), "cbitpos", NULL);
-if (host_cbitpos != s->cbitpos) {
+if (host_cbitpos != sev->cbitpos) {
 error_report("%s: cbitpos check failed, host '%d' requested '%d'",
- __func__, host_cbitpos, s->cbitpos);
+ __func__, host_cbitpos, sev->cbitpos);
 goto err;
 }
 
-s->reduced_phys_bits = object_property_get_int(OBJECT(sev),
-"reduced-phys-bits", NULL);
-if (s->reduced_phys_bits < 1) {
+if (sev->reduced_phys_bits < 1) {
 error_report("%s: reduced_phys_bits check failed, it should be >=1,"
- " requested '%d'", __func__, s->reduced_phys_bits);
+ " requested '%d'", __func__, sev->reduced_phys_bits);
 goto err;
 }
 
-s->me_mask = ~(1UL << s->cbitpos);
+s->me_mask = ~(1UL << sev->cbitpos);
 
 devname = object_property_get_str(OBJECT(sev), "sev-device", NULL);
 s->sev_fd = open(devname, O_RDWR);
-- 
2.26.2





[PULL 102/115] target/i386: sev: Rename QSevGuestInfo

2020-06-11 Thread Paolo Bonzini
From: David Gibson 

At the moment this is a purely passive object which is just a container for
information used elsewhere, hence the name.  I'm going to change that
though, so as a preliminary rename it to SevGuestState.

That name risks confusion with both SEVState and SevState, but I'll be
working on that in following patches.

Signed-off-by: David Gibson 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20200604064219.436242-4-da...@gibson.dropbear.id.au>
Signed-off-by: Paolo Bonzini 
---
 target/i386/sev.c | 87 ---
 1 file changed, 44 insertions(+), 43 deletions(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index 53def5f41a..b6ed719fb5 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -29,22 +29,23 @@
 #include "trace.h"
 #include "migration/blocker.h"
 
-#define TYPE_QSEV_GUEST_INFO "sev-guest"
-#define QSEV_GUEST_INFO(obj)  \
-OBJECT_CHECK(QSevGuestInfo, (obj), TYPE_QSEV_GUEST_INFO)
+#define TYPE_SEV_GUEST "sev-guest"
+#define SEV_GUEST(obj)  \
+OBJECT_CHECK(SevGuestState, (obj), TYPE_SEV_GUEST)
 
-typedef struct QSevGuestInfo QSevGuestInfo;
+typedef struct SevGuestState SevGuestState;
 
 /**
- * QSevGuestInfo:
+ * SevGuestState:
  *
- * The QSevGuestInfo object is used for creating a SEV guest.
+ * The SevGuestState object is used for creating and managing a SEV
+ * guest.
  *
  * # $QEMU \
  * -object sev-guest,id=sev0 \
  * -machine ...,memory-encryption=sev0
  */
-struct QSevGuestInfo {
+struct SevGuestState {
 Object parent_obj;
 
 char *sev_device;
@@ -57,7 +58,7 @@ struct QSevGuestInfo {
 };
 
 struct SEVState {
-QSevGuestInfo *sev_info;
+SevGuestState *sev_info;
 uint8_t api_major;
 uint8_t api_minor;
 uint8_t build_id;
@@ -235,82 +236,82 @@ static struct RAMBlockNotifier sev_ram_notifier = {
 };
 
 static void
-qsev_guest_finalize(Object *obj)
+sev_guest_finalize(Object *obj)
 {
 }
 
 static char *
-qsev_guest_get_session_file(Object *obj, Error **errp)
+sev_guest_get_session_file(Object *obj, Error **errp)
 {
-QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+SevGuestState *s = SEV_GUEST(obj);
 
 return s->session_file ? g_strdup(s->session_file) : NULL;
 }
 
 static void
-qsev_guest_set_session_file(Object *obj, const char *value, Error **errp)
+sev_guest_set_session_file(Object *obj, const char *value, Error **errp)
 {
-QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+SevGuestState *s = SEV_GUEST(obj);
 
 s->session_file = g_strdup(value);
 }
 
 static char *
-qsev_guest_get_dh_cert_file(Object *obj, Error **errp)
+sev_guest_get_dh_cert_file(Object *obj, Error **errp)
 {
-QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+SevGuestState *s = SEV_GUEST(obj);
 
 return g_strdup(s->dh_cert_file);
 }
 
 static void
-qsev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp)
+sev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp)
 {
-QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+SevGuestState *s = SEV_GUEST(obj);
 
 s->dh_cert_file = g_strdup(value);
 }
 
 static char *
-qsev_guest_get_sev_device(Object *obj, Error **errp)
+sev_guest_get_sev_device(Object *obj, Error **errp)
 {
-QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+SevGuestState *sev = SEV_GUEST(obj);
 
 return g_strdup(sev->sev_device);
 }
 
 static void
-qsev_guest_set_sev_device(Object *obj, const char *value, Error **errp)
+sev_guest_set_sev_device(Object *obj, const char *value, Error **errp)
 {
-QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+SevGuestState *sev = SEV_GUEST(obj);
 
 sev->sev_device = g_strdup(value);
 }
 
 static void
-qsev_guest_class_init(ObjectClass *oc, void *data)
+sev_guest_class_init(ObjectClass *oc, void *data)
 {
 object_class_property_add_str(oc, "sev-device",
-  qsev_guest_get_sev_device,
-  qsev_guest_set_sev_device);
+  sev_guest_get_sev_device,
+  sev_guest_set_sev_device);
 object_class_property_set_description(oc, "sev-device",
 "SEV device to use");
 object_class_property_add_str(oc, "dh-cert-file",
-  qsev_guest_get_dh_cert_file,
-  qsev_guest_set_dh_cert_file);
+  sev_guest_get_dh_cert_file,
+  sev_guest_set_dh_cert_file);
 object_class_property_set_description(oc, "dh-cert-file",
 "guest owners DH certificate (encoded with base64)");
 object_class_property_add_str(oc, "session-file",
-  qsev_guest_get_session_file,
-  qsev_guest_set_session_file);
+  sev_guest_get_session_file,
+  

[PULL 096/115] i386: hvf: Move lazy_flags into CPUX86State

2020-06-11 Thread Paolo Bonzini
From: Roman Bolshakov 

The lazy flags are still needed for instruction decoder.

Signed-off-by: Roman Bolshakov 
Message-Id: <20200528193758.51454-12-r.bolsha...@yadro.com>
Signed-off-by: Paolo Bonzini 
Reviewed-by: Philippe Mathieu-Daudé 
---
 include/sysemu/hvf.h|  7 +
 target/i386/cpu.h   |  2 ++
 target/i386/hvf/x86.h   |  6 
 target/i386/hvf/x86_flags.c | 57 ++---
 4 files changed, 37 insertions(+), 35 deletions(-)

diff --git a/include/sysemu/hvf.h b/include/sysemu/hvf.h
index 2af32e505e..9e09144a64 100644
--- a/include/sysemu/hvf.h
+++ b/include/sysemu/hvf.h
@@ -21,10 +21,17 @@
 #include 
 #include 
 #include "target/i386/cpu.h"
+#include "exec/cpu-defs.h"
+
 uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
  int reg);
 extern bool hvf_allowed;
 #define hvf_enabled() (hvf_allowed)
+
+typedef struct hvf_lazy_flags {
+target_ulong result;
+target_ulong auxbits;
+} hvf_lazy_flags;
 #else /* !CONFIG_HVF */
 #define hvf_enabled() 0
 #define hvf_get_supported_cpuid(func, idx, reg) 0
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c2b8bdcbde..86f4da1b66 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -20,6 +20,7 @@
 #ifndef I386_CPU_H
 #define I386_CPU_H
 
+#include "sysemu/hvf.h"
 #include "sysemu/tcg.h"
 #include "cpu-qom.h"
 #include "hyperv-proto.h"
@@ -1597,6 +1598,7 @@ typedef struct CPUX86State {
 struct kvm_nested_state *nested_state;
 #endif
 #if defined(CONFIG_HVF)
+hvf_lazy_flags hvf_lflags;
 HVFX86EmulatorState *hvf_emul;
 #endif
 
diff --git a/target/i386/hvf/x86.h b/target/i386/hvf/x86.h
index 6048b5cc74..2363616c07 100644
--- a/target/i386/hvf/x86.h
+++ b/target/i386/hvf/x86.h
@@ -228,14 +228,8 @@ typedef struct x68_segment_selector {
 };
 } __attribute__ ((__packed__)) x68_segment_selector;
 
-typedef struct lazy_flags {
-target_ulong result;
-target_ulong auxbits;
-} lazy_flags;
-
 /* Definition of hvf_x86_state is here */
 struct HVFX86EmulatorState {
-struct lazy_flags   lflags;
 uint8_t mmio_buf[4096];
 };
 
diff --git a/target/i386/hvf/x86_flags.c b/target/i386/hvf/x86_flags.c
index 1152cd7234..5ca4f41f5c 100644
--- a/target/i386/hvf/x86_flags.c
+++ b/target/i386/hvf/x86_flags.c
@@ -63,7 +63,7 @@
 #define SET_FLAGS_OSZAPC_SIZE(size, lf_carries, lf_result) { \
 target_ulong temp = ((lf_carries) & (LF_MASK_AF)) | \
 (((lf_carries) >> (size - 2)) << LF_BIT_PO); \
-env->hvf_emul->lflags.result = (target_ulong)(int##size##_t)(lf_result); \
+env->hvf_lflags.result = (target_ulong)(int##size##_t)(lf_result); \
 if ((size) == 32) { \
 temp = ((lf_carries) & ~(LF_MASK_PDB | LF_MASK_SD)); \
 } else if ((size) == 16) { \
@@ -73,7 +73,7 @@
 } else { \
 VM_PANIC("unimplemented");  \
 } \
-env->hvf_emul->lflags.auxbits = (target_ulong)(uint32_t)temp; \
+env->hvf_lflags.auxbits = (target_ulong)(uint32_t)temp; \
 }
 
 /* carries, result */
@@ -100,10 +100,10 @@
 } else { \
 VM_PANIC("unimplemented");  \
 } \
-env->hvf_emul->lflags.result = (target_ulong)(int##size##_t)(lf_result); \
-target_ulong delta_c = (env->hvf_emul->lflags.auxbits ^ temp) & 
LF_MASK_CF; \
+env->hvf_lflags.result = (target_ulong)(int##size##_t)(lf_result); \
+target_ulong delta_c = (env->hvf_lflags.auxbits ^ temp) & LF_MASK_CF; \
 delta_c ^= (delta_c >> 1); \
-env->hvf_emul->lflags.auxbits = (target_ulong)(uint32_t)(temp ^ delta_c); \
+env->hvf_lflags.auxbits = (target_ulong)(uint32_t)(temp ^ delta_c); \
 }
 
 /* carries, result */
@@ -117,9 +117,8 @@
 void SET_FLAGS_OC(CPUX86State *env, uint32_t new_of, uint32_t new_cf)
 {
 uint32_t temp_po = new_of ^ new_cf;
-env->hvf_emul->lflags.auxbits &= ~(LF_MASK_PO | LF_MASK_CF);
-env->hvf_emul->lflags.auxbits |= (temp_po << LF_BIT_PO) |
- (new_cf << LF_BIT_CF);
+env->hvf_lflags.auxbits &= ~(LF_MASK_PO | LF_MASK_CF);
+env->hvf_lflags.auxbits |= (temp_po << LF_BIT_PO) | (new_cf << LF_BIT_CF);
 }
 
 void SET_FLAGS_OSZAPC_SUB32(CPUX86State *env, uint32_t v1, uint32_t v2,
@@ -215,27 +214,27 @@ void SET_FLAGS_OSZAPC_LOGIC8(CPUX86State *env, uint8_t 
v1, uint8_t v2,
 
 bool get_PF(CPUX86State *env)
 {
-uint32_t temp = (255 & env->hvf_emul->lflags.result);
-temp = temp ^ (255 & (env->hvf_emul->lflags.auxbits >> LF_BIT_PDB));
+uint32_t temp = (255 & env->hvf_lflags.result);
+temp = temp ^ (255 & (env->hvf_lflags.auxbits >> LF_BIT_PDB));
 temp = (temp ^ (temp >> 4)) & 0x0F;
 return (0x9669U >> temp) & 1;
 }
 
 void set_PF(CPUX86State *env, bool val)
 {
-uint32_t temp = (255 & env->hvf_emul->lflags.result) ^ (!val);
-env->hvf_emul->lflags.auxbits &= ~(LF_MASK_PDB);
-env->hvf_emul->lflags.auxbits |= (temp << LF_BIT_PDB);
+uint32_t temp = (255 & env->hvf_lflags.result) ^ (!val);
+env->hvf_lflags.auxbits &= ~(LF_MASK_PDB);
+

Re: [PULL v2 00/16] Trivial branch for 5.1 patches

2020-06-11 Thread Peter Maydell
On Wed, 10 Jun 2020 at 14:12, Laurent Vivier  wrote:
>
> The following changes since commit 49ee11555262a256afec592dfed7c5902d5eefd2:
>
>   Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.1-pull-=
> request' into staging (2020-06-08 11:04:57 +0100)
>
> are available in the Git repository at:
>
>   git://github.com/vivier/qemu.git tags/trivial-branch-for-5.1-pull-request
>
> for you to fetch changes up to fe18e6eecdd45d3dff0c8968cbb07c5e02fbe4c8:
>
>   semihosting: remove the pthread include which seems unused (2020-06-10 11:2=
> 9:44 +0200)
>
> 
> Trivial branch pull request 20200610
>
> Convert DPRINTF() to traces or qemu_logs
> Use IEC binary prefix definitions
> Use qemu_semihosting_log_out() in target/unicore32
> Some code and doc cleanup


Applied, thanks.

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

-- PMM



[PULL 094/115] i386: hvf: Drop copy of RFLAGS defines

2020-06-11 Thread Paolo Bonzini
From: Roman Bolshakov 

Use the ones provided in target/i386/cpu.h instead.

Signed-off-by: Roman Bolshakov 
Message-Id: <20200528193758.51454-10-r.bolsha...@yadro.com>
Signed-off-by: Paolo Bonzini 
---
 target/i386/hvf/x86.c|  2 +-
 target/i386/hvf/x86.h| 20 
 target/i386/hvf/x86_decode.c | 16 +++-
 target/i386/hvf/x86_task.c   |  2 +-
 4 files changed, 9 insertions(+), 31 deletions(-)

diff --git a/target/i386/hvf/x86.c b/target/i386/hvf/x86.c
index 7ebb5b45bd..fdb11c8db9 100644
--- a/target/i386/hvf/x86.c
+++ b/target/i386/hvf/x86.c
@@ -131,7 +131,7 @@ bool x86_is_v8086(struct CPUState *cpu)
 {
 X86CPU *x86_cpu = X86_CPU(cpu);
 CPUX86State *env = _cpu->env;
-return x86_is_protected(cpu) && (env->eflags & RFLAGS_VM);
+return x86_is_protected(cpu) && (env->eflags & VM_MASK);
 }
 
 bool x86_is_long_mode(struct CPUState *cpu)
diff --git a/target/i386/hvf/x86.h b/target/i386/hvf/x86.h
index e309b8f203..f0d03faff9 100644
--- a/target/i386/hvf/x86.h
+++ b/target/i386/hvf/x86.h
@@ -42,26 +42,6 @@ typedef struct x86_register {
 };
 } __attribute__ ((__packed__)) x86_register;
 
-typedef enum x86_rflags {
-RFLAGS_CF   = (1L << 0),
-RFLAGS_PF   = (1L << 2),
-RFLAGS_AF   = (1L << 4),
-RFLAGS_ZF   = (1L << 6),
-RFLAGS_SF   = (1L << 7),
-RFLAGS_TF   = (1L << 8),
-RFLAGS_IF   = (1L << 9),
-RFLAGS_DF   = (1L << 10),
-RFLAGS_OF   = (1L << 11),
-RFLAGS_IOPL = (3L << 12),
-RFLAGS_NT   = (1L << 14),
-RFLAGS_RF   = (1L << 16),
-RFLAGS_VM   = (1L << 17),
-RFLAGS_AC   = (1L << 18),
-RFLAGS_VIF  = (1L << 19),
-RFLAGS_VIP  = (1L << 20),
-RFLAGS_ID   = (1L << 21),
-} x86_rflags;
-
 typedef enum x86_reg_cr0 {
 CR0_PE =(1L << 0),
 CR0_MP =(1L << 1),
diff --git a/target/i386/hvf/x86_decode.c b/target/i386/hvf/x86_decode.c
index d881542181..34c5e3006c 100644
--- a/target/i386/hvf/x86_decode.c
+++ b/target/i386/hvf/x86_decode.c
@@ -697,15 +697,13 @@ static void decode_db_4(CPUX86State *env, struct 
x86_decode *decode)
 
 
 #define RFLAGS_MASK_NONE0
-#define RFLAGS_MASK_OSZAPC  (RFLAGS_OF | RFLAGS_SF | RFLAGS_ZF | RFLAGS_AF | \
- RFLAGS_PF | RFLAGS_CF)
-#define RFLAGS_MASK_LAHF(RFLAGS_SF | RFLAGS_ZF | RFLAGS_AF | RFLAGS_PF | \
- RFLAGS_CF)
-#define RFLAGS_MASK_CF  (RFLAGS_CF)
-#define RFLAGS_MASK_IF  (RFLAGS_IF)
-#define RFLAGS_MASK_TF  (RFLAGS_TF)
-#define RFLAGS_MASK_DF  (RFLAGS_DF)
-#define RFLAGS_MASK_ZF  (RFLAGS_ZF)
+#define RFLAGS_MASK_OSZAPC  (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
+#define RFLAGS_MASK_LAHF(CC_S | CC_Z | CC_A | CC_P | CC_C)
+#define RFLAGS_MASK_CF  (CC_C)
+#define RFLAGS_MASK_IF  (IF_MASK)
+#define RFLAGS_MASK_TF  (TF_MASK)
+#define RFLAGS_MASK_DF  (DF_MASK)
+#define RFLAGS_MASK_ZF  (CC_Z)
 
 struct decode_tbl _1op_inst[] = {
 {0x0, X86_DECODE_CMD_ADD, 1, true, decode_modrm_rm, decode_modrm_reg, NULL,
diff --git a/target/i386/hvf/x86_task.c b/target/i386/hvf/x86_task.c
index 6ea8508946..6f04478b3a 100644
--- a/target/i386/hvf/x86_task.c
+++ b/target/i386/hvf/x86_task.c
@@ -158,7 +158,7 @@ void vmx_handle_task_switch(CPUState *cpu, 
x68_segment_selector tss_sel, int rea
 }
 
 if (reason == TSR_IRET)
-env->eflags &= ~RFLAGS_NT;
+env->eflags &= ~NT_MASK;
 
 if (reason != TSR_CALL && reason != TSR_IDT_GATE)
 old_tss_sel.sel = 0x;
-- 
2.26.2





[PULL 091/115] i386: hvf: Use IP from CPUX86State

2020-06-11 Thread Paolo Bonzini
From: Roman Bolshakov 

Drop and replace rip field from HVFX86EmulatorState in favor of eip from
common CPUX86State.

Signed-off-by: Roman Bolshakov 
Message-Id: <20200528193758.51454-7-r.bolsha...@yadro.com>
Signed-off-by: Paolo Bonzini 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/i386/hvf/hvf.c|  6 +--
 target/i386/hvf/x86.h|  3 --
 target/i386/hvf/x86_decode.c |  6 +--
 target/i386/hvf/x86_emu.c| 86 ++--
 target/i386/hvf/x86_task.c   |  4 +-
 5 files changed, 51 insertions(+), 54 deletions(-)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 8ff1d25521..45ae55dd27 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -797,7 +797,7 @@ int hvf_vcpu_exec(CPUState *cpu)
 } else {
 RAX(env) = (uint64_t)val;
 }
-RIP(env) += ins_len;
+env->eip += ins_len;
 store_regs(cpu);
 break;
 } else if (!string && !in) {
@@ -871,7 +871,7 @@ int hvf_vcpu_exec(CPUState *cpu)
 } else {
 simulate_wrmsr(cpu);
 }
-RIP(env) += ins_len;
+env->eip += ins_len;
 store_regs(cpu);
 break;
 }
@@ -907,7 +907,7 @@ int hvf_vcpu_exec(CPUState *cpu)
 error_report("Unrecognized CR %d", cr);
 abort();
 }
-RIP(env) += ins_len;
+env->eip += ins_len;
 store_regs(cpu);
 break;
 }
diff --git a/target/i386/hvf/x86.h b/target/i386/hvf/x86.h
index 56fcde13c6..e3ab7c5137 100644
--- a/target/i386/hvf/x86.h
+++ b/target/i386/hvf/x86.h
@@ -294,7 +294,6 @@ typedef struct lazy_flags {
 /* Definition of hvf_x86_state is here */
 struct HVFX86EmulatorState {
 uint64_t fetch_rip;
-uint64_t rip;
 struct x86_register regs[16];
 struct x86_reg_flags   rflags;
 struct lazy_flags   lflags;
@@ -302,8 +301,6 @@ struct HVFX86EmulatorState {
 };
 
 /* useful register access  macros */
-#define RIP(cpu)(cpu->hvf_emul->rip)
-#define EIP(cpu)((uint32_t)cpu->hvf_emul->rip)
 #define RFLAGS(cpu) (cpu->hvf_emul->rflags.rflags)
 #define EFLAGS(cpu) (cpu->hvf_emul->rflags.eflags)
 
diff --git a/target/i386/hvf/x86_decode.c b/target/i386/hvf/x86_decode.c
index 77c346605f..a590088f54 100644
--- a/target/i386/hvf/x86_decode.c
+++ b/target/i386/hvf/x86_decode.c
@@ -75,7 +75,7 @@ static inline uint64_t decode_bytes(CPUX86State *env, struct 
x86_decode *decode,
 VM_PANIC_EX("%s invalid size %d\n", __func__, size);
 break;
 }
-target_ulong va  = linear_rip(env_cpu(env), RIP(env)) + decode->len;
+target_ulong va  = linear_rip(env_cpu(env), env->eip) + decode->len;
 vmx_read_mem(env_cpu(env), , va, size);
 decode->len += size;
 
@@ -1771,7 +1771,7 @@ void calc_modrm_operand32(CPUX86State *env, struct 
x86_decode *decode,
 ptr += get_sib_val(env, decode, );
 } else if (!decode->modrm.mod && 5 == decode->modrm.rm) {
 if (x86_is_long_mode(env_cpu(env))) {
-ptr += RIP(env) + decode->len;
+ptr += env->eip + decode->len;
 } else {
 ptr = decode->displacement;
 }
@@ -1807,7 +1807,7 @@ void calc_modrm_operand64(CPUX86State *env, struct 
x86_decode *decode,
 if (4 == rm) {
 ptr = get_sib_val(env, decode, ) + offset;
 } else if (0 == mod && 5 == rm) {
-ptr = RIP(env) + decode->len + (int32_t) offset;
+ptr = env->eip + decode->len + (int32_t) offset;
 } else {
 ptr = get_reg_val(env, src, decode->rex.rex, decode->rex.b, 8) +
   (int64_t) offset;
diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c
index 92ab815f5d..0efd9f9928 100644
--- a/target/i386/hvf/x86_emu.c
+++ b/target/i386/hvf/x86_emu.c
@@ -267,49 +267,49 @@ static void exec_mov(struct CPUX86State *env, struct 
x86_decode *decode)
 write_val_ext(env, decode->op[0].ptr, decode->op[1].val,
   decode->operand_size);
 
-RIP(env) += decode->len;
+env->eip += decode->len;
 }
 
 static void exec_add(struct CPUX86State *env, struct x86_decode *decode)
 {
 EXEC_2OP_FLAGS_CMD(env, decode, +, SET_FLAGS_OSZAPC_ADD, true);
-RIP(env) += decode->len;
+env->eip += decode->len;
 }
 
 static void exec_or(struct CPUX86State *env, struct x86_decode *decode)
 {
 EXEC_2OP_FLAGS_CMD(env, decode, |, SET_FLAGS_OSZAPC_LOGIC, true);
-RIP(env) += decode->len;
+env->eip += decode->len;
 }
 
 static void exec_adc(struct CPUX86State *env, struct x86_decode *decode)
 {
 EXEC_2OP_FLAGS_CMD(env, decode, +get_CF(env)+, SET_FLAGS_OSZAPC_ADD, true);
-RIP(env) += decode->len;
+env->eip += decode->len;
 }
 
 static void exec_sbb(struct CPUX86State *env, struct x86_decode *decode)
 {
 EXEC_2OP_FLAGS_CMD(env, decode, -get_CF(env)-, SET_FLAGS_OSZAPC_SUB, true);
-RIP(env) += decode->len;
+

[PULL 069/115] KVM: Kick resamplefd for split kernel irqchip

2020-06-11 Thread Paolo Bonzini
From: Peter Xu 

This is majorly only for X86 because that's the only one that supports
split irqchip for now.

When the irqchip is split, we face a dilemma that KVM irqfd will be
enabled, however the slow irqchip is still running in the userspace.
It means that the resamplefd in the kernel irqfds won't take any
effect and it will miss to ack INTx interrupts on EOIs.

One example is split irqchip with VFIO INTx, which will break if we
use the VFIO INTx fast path.

This patch can potentially supports the VFIO fast path again for INTx,
that the IRQ delivery will still use the fast path, while we don't
need to trap MMIOs in QEMU for the device to emulate the EIOs (see the
callers of vfio_eoi() hook).  However the EOI of the INTx will still
need to be done from the userspace by caching all the resamplefds in
QEMU and kick properly for IOAPIC EOI broadcast.

This is tricky because in this case the userspace ioapic irr &
remote-irr will be bypassed.  However such a change will greatly boost
performance for assigned devices using INTx irqs (TCP_RR boosts 46%
after this patch applied).

When the userspace is responsible for the resamplefd kickup, don't
register it on the kvm_irqfd anymore, because on newer kernels (after
commit 654f1f13ea56, 5.2+) the KVM_IRQFD will fail if with both split
irqchip and resamplefd.  This will make sure that the fast path will
work for all supported kernels.

https://patchwork.kernel.org/patch/10738541/#22609933

Suggested-by: Paolo Bonzini 
Signed-off-by: Peter Xu 
Message-Id: <20200318145204.74483-5-pet...@redhat.com>
Signed-off-by: Paolo Bonzini 
---
 accel/kvm/kvm-all.c| 79 --
 accel/kvm/trace-events |  1 +
 hw/intc/ioapic.c   | 19 ++
 include/sysemu/kvm.h   |  4 +++
 4 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index b048c10af9..f24d7da783 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -160,9 +160,59 @@ static const KVMCapabilityInfo kvm_required_capabilites[] 
= {
 static NotifierList kvm_irqchip_change_notifiers =
 NOTIFIER_LIST_INITIALIZER(kvm_irqchip_change_notifiers);
 
+struct KVMResampleFd {
+int gsi;
+EventNotifier *resample_event;
+QLIST_ENTRY(KVMResampleFd) node;
+};
+typedef struct KVMResampleFd KVMResampleFd;
+
+/*
+ * Only used with split irqchip where we need to do the resample fd
+ * kick for the kernel from userspace.
+ */
+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 inline void kvm_resample_fd_remove(int gsi)
+{
+KVMResampleFd *rfd;
+
+QLIST_FOREACH(rfd, _resample_fd_list, node) {
+if (rfd->gsi == gsi) {
+QLIST_REMOVE(rfd, node);
+g_free(rfd);
+break;
+}
+}
+}
+
+static inline void kvm_resample_fd_insert(int gsi, EventNotifier *event)
+{
+KVMResampleFd *rfd = g_new0(KVMResampleFd, 1);
+
+rfd->gsi = gsi;
+rfd->resample_event = event;
+
+QLIST_INSERT_HEAD(_resample_fd_list, rfd, node);
+}
+
+void kvm_resample_fd_notify(int gsi)
+{
+KVMResampleFd *rfd;
+
+QLIST_FOREACH(rfd, _resample_fd_list, node) {
+if (rfd->gsi == gsi) {
+event_notifier_set(rfd->resample_event);
+trace_kvm_resample_fd_notify(gsi);
+return;
+}
+}
+}
+
 int kvm_get_max_memslots(void)
 {
 KVMState *s = KVM_STATE(current_accel());
@@ -1676,8 +1726,33 @@ static int kvm_irqchip_assign_irqfd(KVMState *s, 
EventNotifier *event,
 };
 
 if (rfd != -1) {
-irqfd.flags |= KVM_IRQFD_FLAG_RESAMPLE;
-irqfd.resamplefd = rfd;
+assert(assign);
+if (kvm_irqchip_is_split()) {
+/*
+ * When the slow irqchip (e.g. IOAPIC) is in the
+ * userspace, KVM kernel resamplefd will not work because
+ * the EOI of the interrupt will be delivered to userspace
+ * instead, so the KVM kernel resamplefd kick will be
+ * skipped.  The userspace here mimics what the kernel
+ * provides with resamplefd, remember the resamplefd and
+ * kick it when we receive EOI of this IRQ.
+ *
+ * This is hackery because IOAPIC is mostly bypassed
+ * (except EOI broadcasts) when irqfd is used.  However
+ * this can bring much performance back for split irqchip
+ * with INTx IRQs (for VFIO, this gives 93% perf of the
+ * full fast path, which is 46% perf boost comparing to
+ * the INTx slow path).
+ */
+kvm_resample_fd_insert(virq, resample);
+} else {
+irqfd.flags |= KVM_IRQFD_FLAG_RESAMPLE;
+irqfd.resamplefd = rfd;
+}
+} else if (!assign) {
+if 

Re: [PATCH v3 0/6] Add strace support for printing arguments of selected syscalls

2020-06-11 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20200611155109.3648-1-filip.boz...@syrmia.com/



Hi,

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

Message-id: 20200611155109.3648-1-filip.boz...@syrmia.com
Subject: [PATCH v3 0/6] Add strace support for printing arguments of selected 
syscalls
Type: series

=== 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
Switched to a new branch 'test'
013fd5b linux-user: Add strace support for printing arguments of fallocate()
5e6db1c linux-user: Add strace support for printing arguments of 
chown()/lchown()
1a68f0d linux-user: Add strace support for printing arguments of lseek()
f6287a2 linux-user: Add strace support for printing argument of syscalls used 
for extended attributes
a6be0b5 linux-user: Add strace support for a group of syscalls
065de90 linux-user: Extend strace support to enable argument printing after 
syscall execution

=== OUTPUT BEGIN ===
1/6 Checking commit 065de9028073 (linux-user: Extend strace support to enable 
argument printing after syscall execution)
2/6 Checking commit a6be0b55e6e5 (linux-user: Add strace support for a group of 
syscalls)
3/6 Checking commit f6287a23537e (linux-user: Add strace support for printing 
argument of syscalls used for extended attributes)
4/6 Checking commit 1a68f0dc91b3 (linux-user: Add strace support for printing 
arguments of lseek())
5/6 Checking commit 5e6db1ccb67c (linux-user: Add strace support for printing 
arguments of chown()/lchown())
6/6 Checking commit 013fd5b8be2f (linux-user: Add strace support for printing 
arguments of fallocate())
ERROR: storage class should be at the beginning of the declaration
#70: FILE: linux-user/strace.c:1147:
+UNUSED static struct flags falloc_flags[] = {

total: 1 errors, 0 warnings, 104 lines checked

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

=== OUTPUT END ===

Test command exited with code: 1


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

[PULL 088/115] i386: hvf: Drop useless declarations in sysemu

2020-06-11 Thread Paolo Bonzini
From: Roman Bolshakov 

They're either declared elsewhere or have no use.

While at it, rename _hvf_cpu_synchronize_post_init() to
do_hvf_cpu_synchronize_post_init().

Signed-off-by: Roman Bolshakov 
Message-Id: <20200528193758.51454-3-r.bolsha...@yadro.com>
Signed-off-by: Paolo Bonzini 
Reviewed-by: Philippe Mathieu-Daudé 
---
 include/sysemu/hvf.h  | 22 --
 target/i386/hvf/hvf.c |  7 ---
 2 files changed, 4 insertions(+), 25 deletions(-)

diff --git a/include/sysemu/hvf.h b/include/sysemu/hvf.h
index 644bdfc722..2af32e505e 100644
--- a/include/sysemu/hvf.h
+++ b/include/sysemu/hvf.h
@@ -30,35 +30,13 @@ extern bool hvf_allowed;
 #define hvf_get_supported_cpuid(func, idx, reg) 0
 #endif /* !CONFIG_HVF */
 
-/* Disable HVF if |disable| is 1, otherwise, enable it iff it is supported by
- * the host CPU. Use hvf_enabled() after this to get the result. */
-void hvf_disable(int disable);
-
-/* Returns non-0 if the host CPU supports the VMX "unrestricted guest" feature
- * which allows the virtual CPU to directly run in "real mode". If true, this
- * allows QEMU to run several vCPU threads in parallel (see cpus.c). Otherwise,
- * only a a single TCG thread can run, and it will call HVF to run the current
- * instructions, except in case of "real mode" (paging disabled, typically at
- * boot time), or MMIO operations. */
-
-int hvf_sync_vcpus(void);
-
 int hvf_init_vcpu(CPUState *);
 int hvf_vcpu_exec(CPUState *);
-int hvf_smp_cpu_exec(CPUState *);
 void hvf_cpu_synchronize_state(CPUState *);
 void hvf_cpu_synchronize_post_reset(CPUState *);
 void hvf_cpu_synchronize_post_init(CPUState *);
-void _hvf_cpu_synchronize_post_init(CPUState *, run_on_cpu_data);
-
 void hvf_vcpu_destroy(CPUState *);
-void hvf_raise_event(CPUState *);
-/* void hvf_reset_vcpu_state(void *opaque); */
 void hvf_reset_vcpu(CPUState *);
-void vmx_update_tpr(CPUState *);
-void update_apic_tpr(CPUState *);
-int hvf_put_registers(CPUState *);
-void vmx_clear_int_window_exiting(CPUState *cpu);
 
 #define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf")
 
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index d72543dc31..9ccdb7e7c7 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -251,7 +251,7 @@ void vmx_update_tpr(CPUState *cpu)
 }
 }
 
-void update_apic_tpr(CPUState *cpu)
+static void update_apic_tpr(CPUState *cpu)
 {
 X86CPU *x86_cpu = X86_CPU(cpu);
 int tpr = rreg(cpu->hvf_fd, HV_X86_TPR) >> 4;
@@ -312,7 +312,8 @@ void hvf_cpu_synchronize_post_reset(CPUState *cpu_state)
 run_on_cpu(cpu_state, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
 }
 
-void _hvf_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg)
+static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
+ run_on_cpu_data arg)
 {
 CPUState *cpu_state = cpu;
 hvf_put_registers(cpu_state);
@@ -321,7 +322,7 @@ void _hvf_cpu_synchronize_post_init(CPUState *cpu, 
run_on_cpu_data arg)
 
 void hvf_cpu_synchronize_post_init(CPUState *cpu_state)
 {
-run_on_cpu(cpu_state, _hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
+run_on_cpu(cpu_state, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
 }
 
 static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t 
ept_qual)
-- 
2.26.2





[PULL 111/115] hw/usb: Move device-specific declarations to new 'hcd-musb.h' header

2020-06-11 Thread Paolo Bonzini
From: Philippe Mathieu-Daudé 

Move the declarations for the MUSB-HDRC USB2.0 OTG compliant core
into a separate header.

Reviewed-by: Peter Maydell 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20200601141536.15192-3-f4...@amsat.org>
Signed-off-by: Paolo Bonzini 
---
 hw/usb/hcd-musb.c |  1 +
 hw/usb/tusb6010.c |  1 +
 include/hw/usb.h  | 30 -
 include/hw/usb/hcd-musb.h | 46 +++
 4 files changed, 48 insertions(+), 30 deletions(-)
 create mode 100644 include/hw/usb/hcd-musb.h

diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c
index c29fbef6fc..5ab13feb3a 100644
--- a/hw/usb/hcd-musb.c
+++ b/hw/usb/hcd-musb.c
@@ -23,6 +23,7 @@
 #include "qemu/osdep.h"
 #include "qemu/timer.h"
 #include "hw/usb.h"
+#include "hw/usb/hcd-musb.h"
 #include "hw/irq.h"
 #include "hw/hw.h"
 
diff --git a/hw/usb/tusb6010.c b/hw/usb/tusb6010.c
index 17580876c6..27eb28d3e4 100644
--- a/hw/usb/tusb6010.c
+++ b/hw/usb/tusb6010.c
@@ -23,6 +23,7 @@
 #include "qemu/module.h"
 #include "qemu/timer.h"
 #include "hw/usb.h"
+#include "hw/usb/hcd-musb.h"
 #include "hw/arm/omap.h"
 #include "hw/hw.h"
 #include "hw/irq.h"
diff --git a/include/hw/usb.h b/include/hw/usb.h
index 1cf1cd9584..e2128c7c45 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -474,36 +474,6 @@ bool usb_host_dev_is_scsi_storage(USBDevice *usbdev);
 
 #define VM_USB_HUB_SIZE 8
 
-/* hw/usb/hdc-musb.c */
-
-enum musb_irq_source_e {
-musb_irq_suspend = 0,
-musb_irq_resume,
-musb_irq_rst_babble,
-musb_irq_sof,
-musb_irq_connect,
-musb_irq_disconnect,
-musb_irq_vbus_request,
-musb_irq_vbus_error,
-musb_irq_rx,
-musb_irq_tx,
-musb_set_vbus,
-musb_set_session,
-/* Add new interrupts here */
-musb_irq_max, /* total number of interrupts defined */
-};
-
-typedef struct MUSBState MUSBState;
-
-extern CPUReadMemoryFunc * const musb_read[];
-extern CPUWriteMemoryFunc * const musb_write[];
-
-MUSBState *musb_init(DeviceState *parent_device, int gpio_base);
-void musb_reset(MUSBState *s);
-uint32_t musb_core_intr_get(MUSBState *s);
-void musb_core_intr_clear(MUSBState *s, uint32_t mask);
-void musb_set_size(MUSBState *s, int epnum, int size, int is_tx);
-
 /* usb-bus.c */
 
 #define TYPE_USB_BUS "usb-bus"
diff --git a/include/hw/usb/hcd-musb.h b/include/hw/usb/hcd-musb.h
new file mode 100644
index 00..26b50132ff
--- /dev/null
+++ b/include/hw/usb/hcd-musb.h
@@ -0,0 +1,46 @@
+/*
+ * "Inventra" High-speed Dual-Role Controller (MUSB-HDRC), Mentor Graphics,
+ * USB2.0 OTG compliant core used in various chips.
+ *
+ * Only host-mode and non-DMA accesses are currently supported.
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Written by Andrzej Zaborowski 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_USB_MUSB_H
+#define HW_USB_MUSB_H
+
+#include "exec/cpu-common.h"
+
+enum musb_irq_source_e {
+musb_irq_suspend = 0,
+musb_irq_resume,
+musb_irq_rst_babble,
+musb_irq_sof,
+musb_irq_connect,
+musb_irq_disconnect,
+musb_irq_vbus_request,
+musb_irq_vbus_error,
+musb_irq_rx,
+musb_irq_tx,
+musb_set_vbus,
+musb_set_session,
+/* Add new interrupts here */
+musb_irq_max /* total number of interrupts defined */
+};
+
+extern CPUReadMemoryFunc * const musb_read[];
+extern CPUWriteMemoryFunc * const musb_write[];
+
+typedef struct MUSBState MUSBState;
+
+MUSBState *musb_init(DeviceState *parent_device, int gpio_base);
+void musb_reset(MUSBState *s);
+uint32_t musb_core_intr_get(MUSBState *s);
+void musb_core_intr_clear(MUSBState *s, uint32_t mask);
+void musb_set_size(MUSBState *s, int epnum, int size, int is_tx);
+
+#endif
-- 
2.26.2





[PULL 050/115] megasas: use unsigned type for positive numeric fields

2020-06-11 Thread Paolo Bonzini
From: Prasad J Pandit 

Use unsigned type for the MegasasState fields which hold positive
numeric values.

Signed-off-by: Prasad J Pandit 
Reviewed-by: Darren Kenny 
Message-Id: <20200513192540.1583887-4-ppan...@redhat.com>
Signed-off-by: Paolo Bonzini 
---
 hw/scsi/megasas.c | 38 +++---
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index b531d88a9b..634af0bbb8 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -86,34 +86,34 @@ typedef struct MegasasState {
 MemoryRegion queue_io;
 uint32_t frame_hi;
 
-int fw_state;
+uint32_t fw_state;
 uint32_t fw_sge;
 uint32_t fw_cmds;
 uint32_t flags;
-int fw_luns;
-int intr_mask;
-int doorbell;
-int busy;
-int diag;
-int adp_reset;
+uint32_t fw_luns;
+uint32_t intr_mask;
+uint32_t doorbell;
+uint32_t busy;
+uint32_t diag;
+uint32_t adp_reset;
 OnOffAuto msi;
 OnOffAuto msix;
 
 MegasasCmd *event_cmd;
-int event_locale;
+uint16_t event_locale;
 int event_class;
-int event_count;
-int shutdown_event;
-int boot_event;
+uint32_t event_count;
+uint32_t shutdown_event;
+uint32_t boot_event;
 
 uint64_t sas_addr;
 char *hba_serial;
 
 uint64_t reply_queue_pa;
 void *reply_queue;
-int reply_queue_len;
+uint16_t reply_queue_len;
 uint16_t reply_queue_head;
-int reply_queue_tail;
+uint16_t reply_queue_tail;
 uint64_t consumer_pa;
 uint64_t producer_pa;
 
@@ -2259,9 +2259,9 @@ static const VMStateDescription vmstate_megasas_gen1 = {
 VMSTATE_PCI_DEVICE(parent_obj, MegasasState),
 VMSTATE_MSIX(parent_obj, MegasasState),
 
-VMSTATE_INT32(fw_state, MegasasState),
-VMSTATE_INT32(intr_mask, MegasasState),
-VMSTATE_INT32(doorbell, MegasasState),
+VMSTATE_UINT32(fw_state, MegasasState),
+VMSTATE_UINT32(intr_mask, MegasasState),
+VMSTATE_UINT32(doorbell, MegasasState),
 VMSTATE_UINT64(reply_queue_pa, MegasasState),
 VMSTATE_UINT64(consumer_pa, MegasasState),
 VMSTATE_UINT64(producer_pa, MegasasState),
@@ -2278,9 +2278,9 @@ static const VMStateDescription vmstate_megasas_gen2 = {
 VMSTATE_PCI_DEVICE(parent_obj, MegasasState),
 VMSTATE_MSIX(parent_obj, MegasasState),
 
-VMSTATE_INT32(fw_state, MegasasState),
-VMSTATE_INT32(intr_mask, MegasasState),
-VMSTATE_INT32(doorbell, MegasasState),
+VMSTATE_UINT32(fw_state, MegasasState),
+VMSTATE_UINT32(intr_mask, MegasasState),
+VMSTATE_UINT32(doorbell, MegasasState),
 VMSTATE_UINT64(reply_queue_pa, MegasasState),
 VMSTATE_UINT64(consumer_pa, MegasasState),
 VMSTATE_UINT64(producer_pa, MegasasState),
-- 
2.26.2





[PULL 086/115] target/ppc: Restrict PPCVirtualHypervisorClass to system-mode

2020-06-11 Thread Paolo Bonzini
From: Philippe Mathieu-Daudé 

The code related to PPC Virtual Hypervisor is pointless in user-mode.

Acked-by: David Gibson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20200526172427.17460-5-f4...@amsat.org>
Signed-off-by: Paolo Bonzini 
---
 target/ppc/cpu.h|  4 ++--
 target/ppc/kvm_ppc.h| 22 +++---
 target/ppc/translate_init.inc.c |  4 
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 1988b436cb..e7d382ac10 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1202,6 +1202,7 @@ PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
 PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr);
 PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc);
 
+#ifndef CONFIG_USER_ONLY
 struct PPCVirtualHypervisorClass {
 InterfaceClass parent;
 void (*hypercall)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu);
@@ -1215,10 +1216,8 @@ struct PPCVirtualHypervisorClass {
 void (*hpte_set_r)(PPCVirtualHypervisor *vhyp, hwaddr ptex, uint64_t pte1);
 void (*get_pate)(PPCVirtualHypervisor *vhyp, ppc_v3_pate_t *entry);
 target_ulong (*encode_hpt_for_kvm_pr)(PPCVirtualHypervisor *vhyp);
-#ifndef CONFIG_USER_ONLY
 void (*cpu_exec_enter)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu);
 void (*cpu_exec_exit)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu);
-#endif
 };
 
 #define TYPE_PPC_VIRTUAL_HYPERVISOR "ppc-virtual-hypervisor"
@@ -1230,6 +1229,7 @@ struct PPCVirtualHypervisorClass {
 #define PPC_VIRTUAL_HYPERVISOR_GET_CLASS(obj) \
 OBJECT_GET_CLASS(PPCVirtualHypervisorClass, (obj), \
  TYPE_PPC_VIRTUAL_HYPERVISOR)
+#endif /* CONFIG_USER_ONLY */
 
 void ppc_cpu_do_interrupt(CPUState *cpu);
 bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index fcaf745516..701c0c262b 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -280,6 +280,17 @@ static inline bool kvmppc_has_cap_spapr_vfio(void)
 return false;
 }
 
+static inline void kvmppc_read_hptes(ppc_hash_pte64_t *hptes,
+ hwaddr ptex, int n)
+{
+abort();
+}
+
+static inline void kvmppc_write_hpte(hwaddr ptex, uint64_t pte0, uint64_t pte1)
+{
+abort();
+}
+
 #endif /* !CONFIG_USER_ONLY */
 
 static inline bool kvmppc_has_cap_epr(void)
@@ -310,17 +321,6 @@ static inline int kvmppc_load_htab_chunk(QEMUFile *f, int 
fd, uint32_t index,
 abort();
 }
 
-static inline void kvmppc_read_hptes(ppc_hash_pte64_t *hptes,
- hwaddr ptex, int n)
-{
-abort();
-}
-
-static inline void kvmppc_write_hpte(hwaddr ptex, uint64_t pte0, uint64_t pte1)
-{
-abort();
-}
-
 static inline bool kvmppc_has_cap_fixup_hcalls(void)
 {
 abort();
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 38cb773ab4..a40888411c 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10942,16 +10942,20 @@ static const TypeInfo ppc_cpu_type_info = {
 .class_init = ppc_cpu_class_init,
 };
 
+#ifndef CONFIG_USER_ONLY
 static const TypeInfo ppc_vhyp_type_info = {
 .name = TYPE_PPC_VIRTUAL_HYPERVISOR,
 .parent = TYPE_INTERFACE,
 .class_size = sizeof(PPCVirtualHypervisorClass),
 };
+#endif
 
 static void ppc_cpu_register_types(void)
 {
 type_register_static(_cpu_type_info);
+#ifndef CONFIG_USER_ONLY
 type_register_static(_vhyp_type_info);
+#endif
 }
 
 type_init(ppc_cpu_register_types)
-- 
2.26.2





[PULL 099/115] xen: fix build without pci passthrough

2020-06-11 Thread Paolo Bonzini
From: Anthony PERARD 

Xen PCI passthrough support may not be available and thus the global
variable "has_igd_gfx_passthru" might be compiled out. Common code
should not access it in that case.

Unfortunately, we can't use CONFIG_XEN_PCI_PASSTHROUGH directly in
xen-common.c so this patch instead move access to the
has_igd_gfx_passthru variable via function and those functions are
also implemented as stubs. The stubs will be used when QEMU is built
without passthrough support.

Now, when one will want to enable igd-passthru via the -machine
property, they will get an error message if QEMU is built without
passthrough support.

Fixes: 46472d82322d0 ('xen: convert "-machine igd-passthru" to an accelerator 
property')
Reported-by: Roger Pau Monné 
Signed-off-by: Anthony PERARD 
Message-Id: <20200603160442.3151170-1-anthony.per...@citrix.com>
Signed-off-by: Paolo Bonzini 
---
 accel/xen/xen-all.c  |  4 ++--
 hw/Makefile.objs |  2 +-
 hw/i386/pc_piix.c|  2 +-
 hw/xen/Makefile.objs |  3 ++-
 hw/xen/xen_pt.c  | 12 +++-
 hw/xen/xen_pt.h  |  6 --
 hw/xen/xen_pt_stub.c | 22 ++
 7 files changed, 43 insertions(+), 8 deletions(-)
 create mode 100644 hw/xen/xen_pt_stub.c

diff --git a/accel/xen/xen-all.c b/accel/xen/xen-all.c
index f3edc65ec9..0c24d4b191 100644
--- a/accel/xen/xen-all.c
+++ b/accel/xen/xen-all.c
@@ -137,12 +137,12 @@ static void xen_change_state_handler(void *opaque, int 
running,
 
 static bool xen_get_igd_gfx_passthru(Object *obj, Error **errp)
 {
-return has_igd_gfx_passthru;
+return xen_igd_gfx_pt_enabled();
 }
 
 static void xen_set_igd_gfx_passthru(Object *obj, bool value, Error **errp)
 {
-has_igd_gfx_passthru = value;
+xen_igd_gfx_pt_set(value, errp);
 }
 
 static void xen_setup_post(MachineState *ms, AccelState *accel)
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 660e2b4373..4cbe5e4e57 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -35,7 +35,7 @@ devices-dirs-y += usb/
 devices-dirs-$(CONFIG_VFIO) += vfio/
 devices-dirs-y += virtio/
 devices-dirs-y += watchdog/
-devices-dirs-y += xen/
+devices-dirs-$(CONFIG_XEN) += xen/
 devices-dirs-$(CONFIG_MEM_DEVICE) += mem/
 devices-dirs-$(CONFIG_NUBUS) += nubus/
 devices-dirs-y += semihosting/
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index eea964e72b..054d3aa9f7 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -377,7 +377,7 @@ static void pc_init_isa(MachineState *machine)
 #ifdef CONFIG_XEN
 static void pc_xen_hvm_init_pci(MachineState *machine)
 {
-const char *pci_type = has_igd_gfx_passthru ?
+const char *pci_type = xen_igd_gfx_pt_enabled() ?
 TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE : 
TYPE_I440FX_PCI_DEVICE;
 
 pc_init1(machine,
diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index 340b2c5096..3fc715e595 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,6 +1,7 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o 
xen-bus.o xen-bus-helper.o xen-backend.o
+common-obj-y += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-bus.o 
xen-bus-helper.o xen-backend.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o 
xen_pt_graphics.o xen_pt_msi.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt_load_rom.o
+obj-$(call $(lnot, $(CONFIG_XEN_PCI_PASSTHROUGH))) += xen_pt_stub.o
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index 81d5ad8da7..ab84443d5e 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -65,7 +65,17 @@
 #include "qemu/range.h"
 #include "exec/address-spaces.h"
 
-bool has_igd_gfx_passthru;
+static bool has_igd_gfx_passthru;
+
+bool xen_igd_gfx_pt_enabled(void)
+{
+return has_igd_gfx_passthru;
+}
+
+void xen_igd_gfx_pt_set(bool value, Error **errp)
+{
+has_igd_gfx_passthru = value;
+}
 
 #define XEN_PT_NR_IRQS (256)
 static uint8_t xen_pt_mapped_machine_irq[XEN_PT_NR_IRQS] = {0};
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 179775db7b..6e9cec95f3 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -5,6 +5,9 @@
 #include "hw/pci/pci.h"
 #include "xen-host-pci-device.h"
 
+bool xen_igd_gfx_pt_enabled(void);
+void xen_igd_gfx_pt_set(bool value, Error **errp);
+
 void xen_pt_log(const PCIDevice *d, const char *f, ...) GCC_FMT_ATTR(2, 3);
 
 #define XEN_PT_ERR(d, _f, _a...) xen_pt_log(d, "%s: Error: "_f, __func__, ##_a)
@@ -322,10 +325,9 @@ extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
 unsigned int domain,
 unsigned int bus, unsigned int 
slot,
 unsigned int function);
-extern bool has_igd_gfx_passthru;
 static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
 {
-return (has_igd_gfx_passthru
+return (xen_igd_gfx_pt_enabled()
 && ((dev->class_code >> 0x8) == 

[PULL 114/115] stubs: move Xen stubs to accel/

2020-06-11 Thread Paolo Bonzini
Keep them close to the other accelerator-dependent stubs, so as to remove
stubs that are not needed by tools.

Signed-off-by: Paolo Bonzini 
---
 accel/stubs/Makefile.objs |  1 +
 stubs/xen-hvm.c => accel/stubs/xen-stub.c | 14 +++---
 stubs/Makefile.objs   |  2 --
 stubs/xen-common.c| 13 -
 4 files changed, 8 insertions(+), 22 deletions(-)
 rename stubs/xen-hvm.c => accel/stubs/xen-stub.c (74%)
 delete mode 100644 stubs/xen-common.c

diff --git a/accel/stubs/Makefile.objs b/accel/stubs/Makefile.objs
index 3894caf95d..bbd14e71fb 100644
--- a/accel/stubs/Makefile.objs
+++ b/accel/stubs/Makefile.objs
@@ -3,3 +3,4 @@ obj-$(call lnot,$(CONFIG_HVF))  += hvf-stub.o
 obj-$(call lnot,$(CONFIG_WHPX)) += whpx-stub.o
 obj-$(call lnot,$(CONFIG_KVM))  += kvm-stub.o
 obj-$(call lnot,$(CONFIG_TCG))  += tcg-stub.o
+obj-$(call lnot,$(CONFIG_XEN))  += xen-stub.o
diff --git a/stubs/xen-hvm.c b/accel/stubs/xen-stub.c
similarity index 74%
rename from stubs/xen-hvm.c
rename to accel/stubs/xen-stub.c
index 6954a5b696..dcca4e678a 100644
--- a/stubs/xen-hvm.c
+++ b/accel/stubs/xen-stub.c
@@ -1,18 +1,18 @@
 /*
- * Copyright (C) 2010   Citrix Ltd.
+ * Copyright (C) 2014   Citrix Systems UK Ltd.
  *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
  */
 
 #include "qemu/osdep.h"
 #include "hw/xen/xen.h"
-#include "exec/memory.h"
 #include "qapi/qapi-commands-misc.h"
 
+void xenstore_store_pv_console_info(int i, Chardev *chr)
+{
+}
+
 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
 {
 return -1;
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index c1e43ac68f..28e48171d1 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -49,7 +49,5 @@ stub-obj-y += target-get-monitor-def.o
 stub-obj-y += target-monitor-defs.o
 stub-obj-y += uuid.o
 stub-obj-y += vm-stop.o
-stub-obj-y += xen-common.o
-stub-obj-y += xen-hvm.o
 
 endif # CONFIG_SOFTMMU || CONFIG_TOOLS
diff --git a/stubs/xen-common.c b/stubs/xen-common.c
deleted file mode 100644
index f5efcae362..00
--- a/stubs/xen-common.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (C) 2014   Citrix Systems UK Ltd.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "hw/xen/xen.h"
-
-void xenstore_store_pv_console_info(int i, Chardev *chr)
-{
-}
-- 
2.26.2





[PULL 115/115] target/i386: Remove obsolete TODO file

2020-06-11 Thread Paolo Bonzini
From: Thomas Huth 

The last real change to this file is from 2012, so it is very likely
that this file is completely out-of-date and ignored today. Let's
simply remove it to avoid confusion if someone finds it by accident.

Signed-off-by: Thomas Huth 
Message-Id: <20200611172445.5177-1-th...@redhat.com>
Signed-off-by: Paolo Bonzini 
---
 target/i386/TODO | 31 ---
 1 file changed, 31 deletions(-)
 delete mode 100644 target/i386/TODO

diff --git a/target/i386/TODO b/target/i386/TODO
deleted file mode 100644
index a8d69cf87f..00
--- a/target/i386/TODO
+++ /dev/null
@@ -1,31 +0,0 @@
-Correctness issues:
-
-- some eflags manipulation incorrectly reset the bit 0x2.
-- SVM: test, cpu save/restore, SMM save/restore. 
-- x86_64: lcall/ljmp intel/amd differences ?
-- better code fetch (different exception handling + CS.limit support)
-- user/kernel PUSHL/POPL in helper.c
-- add missing cpuid tests
-- return UD exception if LOCK prefix incorrectly used
-- test ldt limit < 7 ?
-- fix some 16 bit sp push/pop overflow (pusha/popa, lcall lret)
-- full support of segment limit/rights 
-- full x87 exception support
-- improve x87 bit exactness (use bochs code ?)
-- DRx register support
-- CR0.AC emulation
-- SSE alignment checks
-
-Optimizations/Features:
-
-- add SVM nested paging support
-- add VMX support
-- add AVX support
-- add SSE5 support
-- fxsave/fxrstor AMD extensions
-- improve monitor/mwait support
-- faster EFLAGS update: consider SZAP, C, O can be updated separately
-  with a bit field in CC_OP and more state variables.
-- evaluate x87 stack pointer statically
-- find a way to avoid translating several time the same TB if CR0.TS
-  is set or not.
-- 
2.26.2




[PULL 085/115] sysemu/hvf: Only declare hvf_allowed when HVF is available

2020-06-11 Thread Paolo Bonzini
From: Philippe Mathieu-Daudé 

When HVF is not available, the hvf_allowed variable does not exist.

Reviewed-by: Edgar E. Iglesias 
Reviewed-by: Cornelia Huck 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Roman Bolshakov 
Message-Id: <20200526172427.17460-4-f4...@amsat.org>
Signed-off-by: Paolo Bonzini 
---
 include/sysemu/hvf.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/sysemu/hvf.h b/include/sysemu/hvf.h
index d211e808e9..fe95743124 100644
--- a/include/sysemu/hvf.h
+++ b/include/sysemu/hvf.h
@@ -18,7 +18,6 @@
 #include "exec/memory.h"
 #include "sysemu/accel.h"
 
-extern bool hvf_allowed;
 #ifdef CONFIG_HVF
 #include 
 #include 
@@ -26,11 +25,12 @@ extern bool hvf_allowed;
 #include "target/i386/cpu.h"
 uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
  int reg);
+extern bool hvf_allowed;
 #define hvf_enabled() (hvf_allowed)
-#else
+#else /* !CONFIG_HVF */
 #define hvf_enabled() 0
 #define hvf_get_supported_cpuid(func, idx, reg) 0
-#endif
+#endif /* !CONFIG_HVF */
 
 /* hvf_slot flags */
 #define HVF_SLOT_LOG (1 << 0)
-- 
2.26.2





[PULL 110/115] exec/memory: Remove unused MemoryRegionMmio type

2020-06-11 Thread Paolo Bonzini
From: Philippe Mathieu-Daudé 

Since commit 62a0db942dec ('memory: Remove old_mmio accessors')
this structure is unused. Remove it.

Suggested-by: Peter Maydell 
Reviewed-by: Peter Maydell 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20200601141536.15192-2-f4...@amsat.org>
Signed-off-by: Paolo Bonzini 
---
 include/exec/memory.h | 6 --
 1 file changed, 6 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index af8ca7824e..7207025bd4 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -50,12 +50,6 @@
 extern bool global_dirty_log;
 
 typedef struct MemoryRegionOps MemoryRegionOps;
-typedef struct MemoryRegionMmio MemoryRegionMmio;
-
-struct MemoryRegionMmio {
-CPUReadMemoryFunc *read[3];
-CPUWriteMemoryFunc *write[3];
-};
 
 typedef struct IOMMUTLBEntry IOMMUTLBEntry;
 
-- 
2.26.2





[PULL 112/115] exec/cpu-common: Move MUSB specific typedefs to 'hw/usb/hcd-musb.h'

2020-06-11 Thread Paolo Bonzini
From: Philippe Mathieu-Daudé 

The CPUReadMemoryFunc/CPUWriteMemoryFunc typedefs are legacy
remnant from before the conversion to MemoryRegions.
Since they are now only used in tusb6010.c and hcd-musb.c,
move them to "hw/usb/musb.h" and rename them appropriately.

Suggested-by: Peter Maydell 
Reviewed-by: Peter Maydell 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20200601141536.15192-4-f4...@amsat.org>
Signed-off-by: Paolo Bonzini 
---
 hw/usb/hcd-musb.c | 4 ++--
 include/exec/cpu-common.h | 3 ---
 include/hw/usb/hcd-musb.h | 9 +
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c
index 5ab13feb3a..85f5ff5bd4 100644
--- a/hw/usb/hcd-musb.c
+++ b/hw/usb/hcd-musb.c
@@ -1540,13 +1540,13 @@ static void musb_writew(void *opaque, hwaddr addr, 
uint32_t value)
 };
 }
 
-CPUReadMemoryFunc * const musb_read[] = {
+MUSBReadFunc * const musb_read[] = {
 musb_readb,
 musb_readh,
 musb_readw,
 };
 
-CPUWriteMemoryFunc * const musb_write[] = {
+MUSBWriteFunc * const musb_write[] = {
 musb_writeb,
 musb_writeh,
 musb_writew,
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index b47e5630e7..d5e285d2b5 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -43,9 +43,6 @@ extern ram_addr_t ram_size;
 
 /* memory API */
 
-typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
-typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
-
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
 /* This should not be used by devices.  */
 ram_addr_t qemu_ram_addr_from_host(void *ptr);
diff --git a/include/hw/usb/hcd-musb.h b/include/hw/usb/hcd-musb.h
index 26b50132ff..c874b9f292 100644
--- a/include/hw/usb/hcd-musb.h
+++ b/include/hw/usb/hcd-musb.h
@@ -13,8 +13,6 @@
 #ifndef HW_USB_MUSB_H
 #define HW_USB_MUSB_H
 
-#include "exec/cpu-common.h"
-
 enum musb_irq_source_e {
 musb_irq_suspend = 0,
 musb_irq_resume,
@@ -32,8 +30,11 @@ enum musb_irq_source_e {
 musb_irq_max /* total number of interrupts defined */
 };
 
-extern CPUReadMemoryFunc * const musb_read[];
-extern CPUWriteMemoryFunc * const musb_write[];
+/* TODO convert hcd-musb to QOM/qdev and remove MUSBReadFunc/MUSBWriteFunc */
+typedef void MUSBWriteFunc(void *opaque, hwaddr addr, uint32_t value);
+typedef uint32_t MUSBReadFunc(void *opaque, hwaddr addr);
+extern MUSBReadFunc * const musb_read[];
+extern MUSBWriteFunc * const musb_write[];
 
 typedef struct MUSBState MUSBState;
 
-- 
2.26.2





[PULL 080/115] exec: set map length to zero when returning NULL

2020-06-11 Thread Paolo Bonzini
From: Prasad J Pandit 

When mapping physical memory into host's virtual address space,
'address_space_map' may return NULL if BounceBuffer is in_use.
Set and return '*plen = 0' to avoid later NULL pointer dereference.

Reported-by: Alexander Bulekov 
Fixes: https://bugs.launchpad.net/qemu/+bug/1878259
Suggested-by: Paolo Bonzini 
Suggested-by: Peter Maydell 
Signed-off-by: Prasad J Pandit 
Message-Id: <20200526111743.428367-1-ppan...@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Paolo Bonzini 
---
 exec.c| 1 +
 include/exec/memory.h | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/exec.c b/exec.c
index 9cbde85d8c..778263f1c6 100644
--- a/exec.c
+++ b/exec.c
@@ -3540,6 +3540,7 @@ void *address_space_map(AddressSpace *as,
 
 if (!memory_access_is_direct(mr, is_write)) {
 if (atomic_xchg(_use, true)) {
+*plen = 0;
 return NULL;
 }
 /* Avoid unbounded allocations */
diff --git a/include/exec/memory.h b/include/exec/memory.h
index bd7fdd6081..af8ca7824e 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -2314,7 +2314,8 @@ bool address_space_access_valid(AddressSpace *as, hwaddr 
addr, hwaddr len,
 /* address_space_map: map a physical memory region into a host virtual address
  *
  * May map a subset of the requested range, given by and returned in @plen.
- * May return %NULL if resources needed to perform the mapping are exhausted.
+ * May return %NULL and set *@plen to zero(0), if resources needed to perform
+ * the mapping are exhausted.
  * Use only for reads OR writes - not for read-modify-write operations.
  * Use cpu_register_map_client() to know when retrying the map operation is
  * likely to succeed.
-- 
2.26.2





[PULL 081/115] target/i386: fix IEEE x87 floating-point exception raising

2020-06-11 Thread Paolo Bonzini
From: Joseph Myers 

Most x87 instruction implementations fail to raise the expected IEEE
floating-point exceptions because they do nothing to convert the
exception state from the softfloat machinery into the exception flags
in the x87 status word.  There is special-case handling of division to
raise the divide-by-zero exception, but that handling is itself buggy:
it raises the exception in inappropriate cases (inf / 0 and nan / 0,
which should not raise any exceptions, and 0 / 0, which should raise
"invalid" instead).

Fix this by converting the floating-point exceptions raised during an
operation by the softfloat machinery into exceptions in the x87 status
word (passing through the existing fpu_set_exception function for
handling related to trapping exceptions).  There are special cases
where some functions convert to integer internally but exceptions from
that conversion are not always correct exceptions for the instruction
to raise.

There might be scope for some simplification if the softfloat
exception state either could always be assumed to be in sync with the
state in the status word, or could always be ignored at the start of
each instruction and just set to 0 then; I haven't looked into that in
detail, and it might run into interactions with the various ways the
emulation does not yet handle trapping exceptions properly.  I think
the approach taken here, of saving the softfloat state, setting
exceptions there to 0 and then merging the old exceptions back in
after carrying out the operation, is conservatively safe.

Signed-off-by: Joseph Myers 
Message-Id: 
Signed-off-by: Paolo Bonzini 
---
 target/i386/fpu_helper.c | 126 +++-
 tests/tcg/i386/test-i386-fp-exceptions.c | 831 +++
 2 files changed, 926 insertions(+), 31 deletions(-)
 create mode 100644 tests/tcg/i386/test-i386-fp-exceptions.c

diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c
index 9c93f385b1..8ef5b463ea 100644
--- a/target/i386/fpu_helper.c
+++ b/target/i386/fpu_helper.c
@@ -161,12 +161,32 @@ static void fpu_set_exception(CPUX86State *env, int mask)
 }
 }
 
+static inline uint8_t save_exception_flags(CPUX86State *env)
+{
+uint8_t old_flags = get_float_exception_flags(>fp_status);
+set_float_exception_flags(0, >fp_status);
+return old_flags;
+}
+
+static void merge_exception_flags(CPUX86State *env, uint8_t old_flags)
+{
+uint8_t new_flags = get_float_exception_flags(>fp_status);
+float_raise(old_flags, >fp_status);
+fpu_set_exception(env,
+  ((new_flags & float_flag_invalid ? FPUS_IE : 0) |
+   (new_flags & float_flag_divbyzero ? FPUS_ZE : 0) |
+   (new_flags & float_flag_overflow ? FPUS_OE : 0) |
+   (new_flags & float_flag_underflow ? FPUS_UE : 0) |
+   (new_flags & float_flag_inexact ? FPUS_PE : 0) |
+   (new_flags & float_flag_input_denormal ? FPUS_DE : 0)));
+}
+
 static inline floatx80 helper_fdiv(CPUX86State *env, floatx80 a, floatx80 b)
 {
-if (floatx80_is_zero(b)) {
-fpu_set_exception(env, FPUS_ZE);
-}
-return floatx80_div(a, b, >fp_status);
+uint8_t old_flags = save_exception_flags(env);
+floatx80 ret = floatx80_div(a, b, >fp_status);
+merge_exception_flags(env, old_flags);
+return ret;
 }
 
 static void fpu_raise_exception(CPUX86State *env, uintptr_t retaddr)
@@ -183,6 +203,7 @@ static void fpu_raise_exception(CPUX86State *env, uintptr_t 
retaddr)
 
 void helper_flds_FT0(CPUX86State *env, uint32_t val)
 {
+uint8_t old_flags = save_exception_flags(env);
 union {
 float32 f;
 uint32_t i;
@@ -190,10 +211,12 @@ void helper_flds_FT0(CPUX86State *env, uint32_t val)
 
 u.i = val;
 FT0 = float32_to_floatx80(u.f, >fp_status);
+merge_exception_flags(env, old_flags);
 }
 
 void helper_fldl_FT0(CPUX86State *env, uint64_t val)
 {
+uint8_t old_flags = save_exception_flags(env);
 union {
 float64 f;
 uint64_t i;
@@ -201,6 +224,7 @@ void helper_fldl_FT0(CPUX86State *env, uint64_t val)
 
 u.i = val;
 FT0 = float64_to_floatx80(u.f, >fp_status);
+merge_exception_flags(env, old_flags);
 }
 
 void helper_fildl_FT0(CPUX86State *env, int32_t val)
@@ -210,6 +234,7 @@ void helper_fildl_FT0(CPUX86State *env, int32_t val)
 
 void helper_flds_ST0(CPUX86State *env, uint32_t val)
 {
+uint8_t old_flags = save_exception_flags(env);
 int new_fpstt;
 union {
 float32 f;
@@ -221,10 +246,12 @@ void helper_flds_ST0(CPUX86State *env, uint32_t val)
 env->fpregs[new_fpstt].d = float32_to_floatx80(u.f, >fp_status);
 env->fpstt = new_fpstt;
 env->fptags[new_fpstt] = 0; /* validate stack entry */
+merge_exception_flags(env, old_flags);
 }
 
 void helper_fldl_ST0(CPUX86State *env, uint64_t val)
 {
+uint8_t old_flags = save_exception_flags(env);
 int new_fpstt;
 union {
 float64 f;
@@ -236,6 +263,7 @@ void 

[PULL 107/115] target/i386: sev: Remove redundant handle field

2020-06-11 Thread Paolo Bonzini
From: David Gibson 

The user can explicitly specify a handle via the "handle" property wired
to SevGuestState::handle.  That gets passed to the KVM_SEV_LAUNCH_START
ioctl() which may update it, the final value being copied back to both
SevGuestState::handle and SEVState::handle.

AFAICT, nothing will be looking SEVState::handle before it and
SevGuestState::handle have been updated from the ioctl().  So, remove the
field and just use SevGuestState::handle directly.

Signed-off-by: David Gibson 
Reviewed-by: Richard Henderson 
Message-Id: <20200604064219.436242-9-da...@gibson.dropbear.id.au>
Signed-off-by: Paolo Bonzini 
---
 target/i386/sev.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index 4b261beaa7..24e2dea9b8 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -40,7 +40,6 @@ struct SEVState {
 uint8_t api_minor;
 uint8_t build_id;
 uint64_t me_mask;
-uint32_t handle;
 int sev_fd;
 SevState state;
 gchar *measurement;
@@ -64,13 +63,13 @@ struct SevGuestState {
 /* configuration parameters */
 char *sev_device;
 uint32_t policy;
-uint32_t handle;
 char *dh_cert_file;
 char *session_file;
 uint32_t cbitpos;
 uint32_t reduced_phys_bits;
 
 /* runtime state */
+uint32_t handle;
 SEVState state;
 };
 
@@ -398,7 +397,7 @@ sev_get_info(void)
 info->build_id = sev_guest->state.build_id;
 info->policy = sev_guest->policy;
 info->state = sev_guest->state.state;
-info->handle = sev_guest->state.handle;
+info->handle = sev_guest->handle;
 }
 
 return info;
@@ -517,8 +516,7 @@ sev_launch_start(SevGuestState *sev)
 
 start = g_new0(struct kvm_sev_launch_start, 1);
 
-start->handle = object_property_get_int(OBJECT(sev), "handle",
-_abort);
+start->handle = sev->handle;
 start->policy = sev->policy;
 if (sev->session_file) {
 if (sev_read_file_base64(sev->session_file, , ) < 0) {
@@ -544,10 +542,8 @@ sev_launch_start(SevGuestState *sev)
 goto out;
 }
 
-object_property_set_int(OBJECT(sev), start->handle, "handle",
-_abort);
 sev_set_guest_state(sev, SEV_STATE_LAUNCH_UPDATE);
-s->handle = start->handle;
+sev->handle = start->handle;
 ret = 0;
 
 out:
-- 
2.26.2





[PULL 092/115] i386: hvf: Drop fetch_rip from HVFX86EmulatorState

2020-06-11 Thread Paolo Bonzini
From: Roman Bolshakov 

The field is used to print address of instructions that have no parser
in decode_invalid(). RIP from VMCS is saved into fetch_rip before
decoding starts but it's also saved into env->eip in load_regs().
Therefore env->eip can be used instead of fetch_rip.

While at it, correct address printed in decode_invalid(). It prints an
address before the unknown instruction.

Signed-off-by: Roman Bolshakov 
Message-Id: <20200528193758.51454-8-r.bolsha...@yadro.com>
Signed-off-by: Paolo Bonzini 
---
 target/i386/hvf/hvf.c| 6 --
 target/i386/hvf/x86.h| 1 -
 target/i386/hvf/x86_decode.c | 3 +--
 3 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 45ae55dd27..416a6fae7c 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -767,8 +767,6 @@ int hvf_vcpu_exec(CPUState *cpu)
 struct x86_decode decode;
 
 load_regs(cpu);
-env->hvf_emul->fetch_rip = rip;
-
 decode_instruction(env, );
 exec_instruction(env, );
 store_regs(cpu);
@@ -809,8 +807,6 @@ int hvf_vcpu_exec(CPUState *cpu)
 struct x86_decode decode;
 
 load_regs(cpu);
-env->hvf_emul->fetch_rip = rip;
-
 decode_instruction(env, );
 assert(ins_len == decode.len);
 exec_instruction(env, );
@@ -915,8 +911,6 @@ int hvf_vcpu_exec(CPUState *cpu)
 struct x86_decode decode;
 
 load_regs(cpu);
-env->hvf_emul->fetch_rip = rip;
-
 decode_instruction(env, );
 exec_instruction(env, );
 store_regs(cpu);
diff --git a/target/i386/hvf/x86.h b/target/i386/hvf/x86.h
index e3ab7c5137..411e4b6599 100644
--- a/target/i386/hvf/x86.h
+++ b/target/i386/hvf/x86.h
@@ -293,7 +293,6 @@ typedef struct lazy_flags {
 
 /* Definition of hvf_x86_state is here */
 struct HVFX86EmulatorState {
-uint64_t fetch_rip;
 struct x86_register regs[16];
 struct x86_reg_flags   rflags;
 struct lazy_flags   lflags;
diff --git a/target/i386/hvf/x86_decode.c b/target/i386/hvf/x86_decode.c
index a590088f54..d881542181 100644
--- a/target/i386/hvf/x86_decode.c
+++ b/target/i386/hvf/x86_decode.c
@@ -29,8 +29,7 @@
 
 static void decode_invalid(CPUX86State *env, struct x86_decode *decode)
 {
-printf("%llx: failed to decode instruction ", env->hvf_emul->fetch_rip -
-   decode->len);
+printf("%llx: failed to decode instruction ", env->eip);
 for (int i = 0; i < decode->opcode_len; i++) {
 printf("%x ", decode->opcode[i]);
 }
-- 
2.26.2





[PULL 058/115] disas: Let disas::read_memory() handler return EIO on error

2020-06-11 Thread Paolo Bonzini
From: Philippe Mathieu-Daudé 

Both cpu_memory_rw_debug() and address_space_read() return
an error on failed transaction. Check the returned value,
and return EIO in case of error.

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Paolo Bonzini 
---
 disas.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/disas.c b/disas.c
index 45285d3f63..c1397d3933 100644
--- a/disas.c
+++ b/disas.c
@@ -39,9 +39,11 @@ target_read_memory (bfd_vma memaddr,
 struct disassemble_info *info)
 {
 CPUDebug *s = container_of(info, CPUDebug, info);
+int r;
 
-cpu_memory_rw_debug(s->cpu, memaddr, myaddr, length, 0);
-return 0;
+r = cpu_memory_rw_debug(s->cpu, memaddr, myaddr, length, 0);
+
+return r ? EIO : 0;
 }
 
 /* Print an error message.  We can assume that this is in response to
@@ -718,10 +720,11 @@ physical_read_memory(bfd_vma memaddr, bfd_byte *myaddr, 
int length,
  struct disassemble_info *info)
 {
 CPUDebug *s = container_of(info, CPUDebug, info);
+MemTxResult res;
 
-address_space_read(s->cpu->as, memaddr, MEMTXATTRS_UNSPECIFIED,
-   myaddr, length);
-return 0;
+res = address_space_read(s->cpu->as, memaddr, MEMTXATTRS_UNSPECIFIED,
+ myaddr, length);
+return res == MEMTX_OK ? 0 : EIO;
 }
 
 /* Disassembler for the monitor.  */
-- 
2.26.2





[PULL 082/115] target/i386: correct fix for pcmpxstrx substring search

2020-06-11 Thread Paolo Bonzini
From: Joseph Myers 

This corrects a bug introduced in my previous fix for SSE4.2 pcmpestri
/ pcmpestrm / pcmpistri / pcmpistrm substring search, commit
ae35eea7e4a9f21dd147406dfbcd0c4c6aaf2a60.

That commit fixed a bug that showed up in four GCC tests with one libc
implementation.  The tests in question generate random inputs to the
intrinsics and compare results to a C implementation, but they only
test 1024 possible random inputs, and when the tests use the cases of
those instructions that work with word rather than byte inputs, it's
easy to have problematic cases that show up much less frequently than
that.  Thus, testing with a different libc implementation, and so a
different random number generator, showed up a problem with the
previous patch.

When investigating the previous test failures, I found the description
of these instructions in the Intel manuals (starting from computing a
16x16 or 8x8 set of comparison results) confusing and hard to match up
with the more optimized implementation in QEMU, and referred to AMD
manuals which described the instructions in a different way.  Those
AMD descriptions are very explicit that the whole of the string being
searched for must be found in the other operand, not running off the
end of that operand; they say "If the prototype and the SUT are equal
in length, the two strings must be identical for the comparison to be
TRUE.".  However, that statement is incorrect.

In my previous commit message, I noted:

  The operation in this case is a search for a string (argument d to
  the helper) in another string (argument s to the helper); if a copy
  of d at a particular position would run off the end of s, the
  resulting output bit should be 0 whether or not the strings match in
  the region where they overlap, but the QEMU implementation was
  wrongly comparing only up to the point where s ends and counting it
  as a match if an initial segment of d matched a terminal segment of
  s.  Here, "run off the end of s" means that some byte of d would
  overlap some byte outside of s; thus, if d has zero length, it is
  considered to match everywhere, including after the end of s.

The description "some byte of d would overlap some byte outside of s"
is accurate only when understood to refer to overlapping some byte
*within the 16-byte operand* but at or after the zero terminator; it
is valid to run over the end of s if the end of s is the end of the
16-byte operand.  So the fix in the previous patch for the case of d
being empty was correct, but the other part of that patch was not
correct (as it never allowed partial matches even at the end of the
16-byte operand).  Nor was the code before the previous patch correct
for the case of d nonempty, as it would always have allowed partial
matches at the end of s.

Fix with a partial revert of my previous change, combined with
inserting a check for the special case of s having maximum length to
determine where it is necessary to check for matches.

In the added test, test 1 is for the case of empty strings, which
failed before my 2017 patch, test 2 is for the bug introduced by my
2017 patch and test 3 deals with the case where a match of an initial
segment at the end of the string is not valid when the string ends
before the end of the 16-byte operand (that is, the case that would be
broken by a simple revert of the non-empty-string part of my 2017
patch).

Signed-off-by: Joseph Myers 
Message-Id: 
Signed-off-by: Paolo Bonzini 
---
 target/i386/ops_sse.h|  4 ++--
 tests/tcg/i386/Makefile.target   |  3 +++
 tests/tcg/i386/test-i386-pcmpistri.c | 33 
 3 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 tests/tcg/i386/test-i386-pcmpistri.c

diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h
index 01d6017412..14f2b16abd 100644
--- a/target/i386/ops_sse.h
+++ b/target/i386/ops_sse.h
@@ -2089,10 +2089,10 @@ static inline unsigned pcmpxstrx(CPUX86State *env, Reg 
*d, Reg *s,
 res = (2 << upper) - 1;
 break;
 }
-for (j = valids - validd; j >= 0; j--) {
+for (j = valids == upper ? valids : valids - validd; j >= 0; j--) {
 res <<= 1;
 v = 1;
-for (i = validd; i >= 0; i--) {
+for (i = MIN(valids - j, validd); i >= 0; i--) {
 v &= (pcmp_val(s, ctrl, i + j) == pcmp_val(d, ctrl, i));
 }
 res |= v;
diff --git a/tests/tcg/i386/Makefile.target b/tests/tcg/i386/Makefile.target
index 43ee2e181e..de5a3a275f 100644
--- a/tests/tcg/i386/Makefile.target
+++ b/tests/tcg/i386/Makefile.target
@@ -10,6 +10,9 @@ ALL_X86_TESTS=$(I386_SRCS:.c=)
 SKIP_I386_TESTS=test-i386-ssse3
 X86_64_TESTS:=$(filter test-i386-ssse3, $(ALL_X86_TESTS))
 
+test-i386-pcmpistri: CFLAGS += -msse4.2
+test-i386-pcmpistri: QEMU_OPTS += -cpu max
+
 #
 # hello-i386 is a barebones app
 #
diff --git a/tests/tcg/i386/test-i386-pcmpistri.c 

[PULL 073/115] replay: implement fair mutex

2020-06-11 Thread Paolo Bonzini
From: Pavel Dovgalyuk 

In record/replay icount mode main loop thread and vCPU thread
do not perform simultaneously. They take replay mutex to synchronize
the actions. Sometimes vCPU thread waits for locking the mutex for
very long time, because main loop releases the mutex and takes it
back again. Standard qemu mutex do not provide the ordering
capabilities.

This patch adds a "queue" for replay mutex. Therefore thread ordering
becomes more "fair". Threads are executed in the same order as
they are trying to take the mutex.

Signed-off-by: Pavel Dovgalyuk 
Message-Id: <158823802979.28101.9340462887738957616.stgit@pasha-ThinkPad-X280>
Signed-off-by: Paolo Bonzini 
---
 replay/replay-internal.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/replay/replay-internal.c b/replay/replay-internal.c
index eba8246aae..2e8a3e947a 100644
--- a/replay/replay-internal.c
+++ b/replay/replay-internal.c
@@ -22,6 +22,9 @@
It also protects replay events queue which stores events to be
written or read to the log. */
 static QemuMutex lock;
+/* Condition and queue for fair ordering of mutex lock requests. */
+static QemuCond mutex_cond;
+static unsigned long mutex_head, mutex_tail;
 
 /* File for replay writing */
 static bool write_error;
@@ -197,9 +200,10 @@ static __thread bool replay_locked;
 void replay_mutex_init(void)
 {
 qemu_mutex_init();
+qemu_cond_init(_cond);
 /* Hold the mutex while we start-up */
-qemu_mutex_lock();
 replay_locked = true;
+++mutex_tail;
 }
 
 bool replay_mutex_locked(void)
@@ -211,10 +215,16 @@ bool replay_mutex_locked(void)
 void replay_mutex_lock(void)
 {
 if (replay_mode != REPLAY_MODE_NONE) {
+unsigned long id;
 g_assert(!qemu_mutex_iothread_locked());
 g_assert(!replay_mutex_locked());
 qemu_mutex_lock();
+id = mutex_tail++;
+while (id != mutex_head) {
+qemu_cond_wait(_cond, );
+}
 replay_locked = true;
+qemu_mutex_unlock();
 }
 }
 
@@ -222,7 +232,10 @@ void replay_mutex_unlock(void)
 {
 if (replay_mode != REPLAY_MODE_NONE) {
 g_assert(replay_mutex_locked());
+qemu_mutex_lock();
+++mutex_head;
 replay_locked = false;
+qemu_cond_broadcast(_cond);
 qemu_mutex_unlock();
 }
 }
-- 
2.26.2





[PULL 089/115] i386: hvf: Drop unused variable

2020-06-11 Thread Paolo Bonzini
From: Roman Bolshakov 

Signed-off-by: Roman Bolshakov 
Message-Id: <20200528193758.51454-5-r.bolsha...@yadro.com>
Signed-off-by: Paolo Bonzini 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/i386/hvf/x86.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/target/i386/hvf/x86.h b/target/i386/hvf/x86.h
index c95d5b2116..56fcde13c6 100644
--- a/target/i386/hvf/x86.h
+++ b/target/i386/hvf/x86.h
@@ -293,7 +293,6 @@ typedef struct lazy_flags {
 
 /* Definition of hvf_x86_state is here */
 struct HVFX86EmulatorState {
-int interruptable;
 uint64_t fetch_rip;
 uint64_t rip;
 struct x86_register regs[16];
-- 
2.26.2





[PULL 100/115] target/i386: sev: Remove unused QSevGuestInfoClass

2020-06-11 Thread Paolo Bonzini
From: David Gibson 

This structure is nothing but an empty wrapper around the parent class,
which by QOM conventions means we don't need it at all.

Signed-off-by: David Gibson 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20200604064219.436242-2-da...@gibson.dropbear.id.au>
Signed-off-by: Paolo Bonzini 
---
 target/i386/sev.c  | 1 -
 target/i386/sev_i386.h | 5 -
 2 files changed, 6 deletions(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index 51cdbe5496..2312510cf2 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -287,7 +287,6 @@ static const TypeInfo qsev_guest_info = {
 .name = TYPE_QSEV_GUEST_INFO,
 .instance_size = sizeof(QSevGuestInfo),
 .instance_finalize = qsev_guest_finalize,
-.class_size = sizeof(QSevGuestInfoClass),
 .class_init = qsev_guest_class_init,
 .instance_init = qsev_guest_init,
 .interfaces = (InterfaceInfo[]) {
diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h
index 8ada9d385d..4f193642ac 100644
--- a/target/i386/sev_i386.h
+++ b/target/i386/sev_i386.h
@@ -41,7 +41,6 @@ extern char *sev_get_launch_measurement(void);
 extern SevCapability *sev_get_capabilities(void);
 
 typedef struct QSevGuestInfo QSevGuestInfo;
-typedef struct QSevGuestInfoClass QSevGuestInfoClass;
 
 /**
  * QSevGuestInfo:
@@ -64,10 +63,6 @@ struct QSevGuestInfo {
 uint32_t reduced_phys_bits;
 };
 
-struct QSevGuestInfoClass {
-ObjectClass parent_class;
-};
-
 struct SEVState {
 QSevGuestInfo *sev_info;
 uint8_t api_major;
-- 
2.26.2





  1   2   3   4   5   >