Re: [PATCH v4 2/3] linux-user/syscall: Add support for clock_gettime64/clock_settime64

2020-03-04 Thread Aleksandar Markovic
1:53 AM Sre, 04.03.2020. Alistair Francis  је
написао/ла:
>
> Add support for the clock_gettime64/clock_settime64 syscalls. Currently
> we only support these syscalls when running on 64-bit hosts.
>

For clarity, "Currently we only support" should be replaced with "This
patch supports only".

> Signed-off-by: Alistair Francis 
> ---
>  linux-user/syscall.c | 43 +++
>  1 file changed, 43 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index c000fb07c5..82468e018d 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -1236,6 +1236,22 @@ static inline abi_long
target_to_host_timespec(struct timespec *host_ts,
>  }
>  #endif
>
> +#if defined(TARGET_NR_clock_settime64) && HOST_LONG_BITS == 64
> +static inline abi_long target_to_host_timespec64(struct timespec
*host_ts,
> + abi_ulong target_addr)
> +{
> +struct target_timespec *target_ts;
> +
> +if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) {
> +return -TARGET_EFAULT;
> +}
> +__get_user(host_ts->tv_sec, &target_ts->tv_sec);
> +__get_user(host_ts->tv_nsec, &target_ts->tv_nsec);
> +unlock_user_struct(target_ts, target_addr, 0);
> +return 0;
> +}
> +#endif
> +
>  static inline abi_long host_to_target_timespec(abi_ulong target_addr,
> struct timespec *host_ts)
>  {
> @@ -11465,6 +11481,20 @@ static abi_long do_syscall1(void *cpu_env, int
num, abi_long arg1,
>  return ret;
>  }
>  #endif
> +#ifdef TARGET_NR_clock_settime64
> +# if HOST_LONG_BITS == 64
> +case TARGET_NR_clock_settime64:
> +{
> +struct timespec ts;
> +
> +ret = target_to_host_timespec64(&ts, arg2);
> +if (!is_error(ret)) {
> +ret = get_errno(clock_settime(arg1, &ts));
> +}
> +return ret;
> +}
> +# endif
> +#endif
>  #ifdef TARGET_NR_clock_gettime
>  case TARGET_NR_clock_gettime:
>  {
> @@ -11476,6 +11506,19 @@ static abi_long do_syscall1(void *cpu_env, int
num, abi_long arg1,
>  return ret;
>  }
>  #endif
> +#ifdef TARGET_NR_clock_gettime64
> +# if HOST_LONG_BITS == 64
> +case TARGET_NR_clock_gettime64:
> +{
> +struct timespec ts;
> +ret = get_errno(clock_gettime(arg1, &ts));
> +if (!is_error(ret)) {
> +ret = host_to_target_timespec64(arg2, &ts);
> +}
> +return ret;
> +}
> +# endif
> +#endif
>  #ifdef TARGET_NR_clock_getres
>  case TARGET_NR_clock_getres:
>  {
> --

Nice patch for the first version, still I think the patch could be much
better.

Why not support 32-bit hosts? If a 32-bit host supports
clock_time64(), the mapping is obvious. If not, the implementation
could be "best effort" based, using host's clock_time().

Regards,
Aleksandar

> 2.25.1
>
>


Re: [PATCH 4/4] qapi: Brush off some (py)lint

2020-03-04 Thread Markus Armbruster
John Snow  writes:

> On 2/27/20 9:45 AM, Markus Armbruster wrote:
>> Signed-off-by: Markus Armbruster 
>
> I wrote some pylint cleanup for iotests recently, too. Are you targeting
> a subset of pylint errors to clean here?
>
> (Do any files pass 100%?)

Surely you're joking, Mr. Snow!

I'm chipping away at pylint's gripes.  I ran it with the following
messages disabled:

bad-whitespace,
fixme,
invalid-name,
missing-docstring,
too-few-public-methods,
too-many-arguments,
too-many-branches,
too-many-instance-attributes,
too-many-lines,
too-many-locals,
too-many-statements,
unused-argument,
unused-wildcard-import,

These are not all obviously useless.  They're just not what I want to
focus on right now.

Remaining:

1 x C0330: Wrong continued indentation (remove 19 spaces).

Accident, will fix in v2.

8 x R0201: Method could be a function (no-self-use)

Yes, but the override in a sub-class does use self.

2 x W0212: Access to a protected member _body of a client class 
(protected-access)

Needs cleanup, but not now.

6 x W0401: Wildcard import qapi.common (wildcard-import)

Not sure I care.  I'd prefer not to have more wildcard imports,
though.

2 x W0603: Using the global statement (global-statement)

Cleanup is non-trivial.  Not now.

I also ran pycodestyle-3:

1 x E127 continuation line over-indented for visual indent

Same as pylint's C0330, will fix in v2.

3 x E261 at least two spaces before inline comment

I blame Emacs.  Left for another day.

8 x E501 line too long

Left for another day.

1 x E713 test for membership should be 'not in'

I missed that one, will fix in v2.

> Consider checking in a pylintrc file that lets others run the same
> subset of pylint tests as you are doing so that we can prevent future
> regressions.

Working towards it, slowly.

> Take a peek at [PATCH v6 0/9] iotests: use python logging​
>
> Thanks for this series. I had a very similar series sitting waiting to
> go out, but this goes further in a few places.

Thanks!




RE: [PATCH 0/2] net/colo-compare.c: Expose more COLO internal

2020-03-04 Thread Zhang, Chen
Hi all,

Please give me some comments, this patch need by users(QNAP...).

Thanks
Zhang Chen

> -Original Message-
> From: Zhang, Chen 
> Sent: Monday, February 24, 2020 4:58 AM
> To: Jason Wang ; qemu-dev  de...@nongnu.org>
> Cc: Zhang Chen ; Dr . David Alan Gilbert
> ; Daniel Cho ; Zhang, Chen
> 
> Subject: [PATCH 0/2] net/colo-compare.c: Expose more COLO internal
> 
> From: Zhang Chen 
> 
> Make a way to config COLO parameter detailed according to user cases and
> environment.
> 
> Zhang Chen (2):
>   net/colo-compare.c: Expose "compare_timeout" to user
>   net/colo-compare.c: Expose "expired_scan_cycle" to user
> 
>  net/colo-compare.c | 95
> +++---
>  qemu-options.hx|  6 ++-
>  2 files changed, 94 insertions(+), 7 deletions(-)
> 
> --
> 2.17.1




RE: [PATCH V4 0/5] Introduce Advanced Watch Dog module

2020-03-04 Thread Zhang, Chen
> >>> Subject: Re: [PATCH V4 0/5] Introduce Advanced Watch Dog module
> >>>
> >>>
> >>> On 2020/1/19 下午5:10, Zhang, Chen wrote:
>  Hi~
> 
>  Anyone have comments about this module?
> >>> Hi Chen:
> >>>
> >>> I will take a look at this series.
> >> Sorry for slow reply due to CNY and extend leave.
> >> OK, waiting your comments~ Thanks~
> >>
> >>> Two general questions:
> >>>
> >>> - if it can detect more than network stall, it should not belong to
> >>> /net
> >> This module use network connection status to detect all the issue(Host to
> Guest/Host to Host/Host to Admin...).
> >> The target is more than network but all use network way. So it is looks a
> tricky problem.
> >
> > Ok.
> >
> >
> >>> - need to convince libvirt guys for this proposal, since usually
> >>> it's the duty of upper layer instead of qemu itself
> >>>
> >> Yes, It looks a upper layer responsibility, but In the cover latter I have
> explained the reason why we need this in Qemu.
> >>try to make this module as simple as possible. This module give upper
> layer software a new way to connect/monitoring Qemu.
> >> And due to all the COLO code implement in Qemu side, Many customer
> >> want to use this FT solution without other dependencies, it is very easy to
> integrated to real product.
> >>
> >> Thanks
> >> Zhang Chen
> >
> > I would like to hear from libvirt about such design.
> 
> 
> Hi Jason,
> 
> OK. I add the libvirt mailing list in this thread.
> 
> The full mail discussion and patches:
> 
> https://lists.nongnu.org/archive/html/qemu-devel/2020-02/msg02611.html
> 
> 
> By the way, I noticed Eric is libvirt maintianer.
> 
> Hi Eric and Paolo, Can you give some comments about this series?
> 
> 

No news for a while...
We already have some users(Cloud Service Provider) try to use is module in 
their product.
But they also need to follow the Qemu upstream code.

Thanks
Zhang Chen


> Thanks
> 
> Zhang Chen
> 
> 
> >
> > Thanks
> >



Re: [PATCH v4 02/11] monitor/hmp: uninline add_init_drive

2020-03-04 Thread Maxim Levitsky
On Tue, 2020-03-03 at 18:10 +0100, Kevin Wolf wrote:
> Am 30.01.2020 um 13:34 hat Maxim Levitsky geschrieben:
> > This is only used by hmp_drive_add.
> > The code is just a bit shorter this way.
> > 
> > No functional changes
> > 
> > Signed-off-by: Maxim Levitsky 
> > Reviewed-by: Markus Armbruster 
> 
> Shouldn't the subject say "inline" rather than "uninline"?
> 
> Kevin

Oh, you are absolutely correct. I don't know why I even now thought
about this that way.

Best regards,
Maxim Levitsky




Re: [PATCH] vhost-vsock: fix error message output

2020-03-04 Thread Stefano Garzarella
On Sun, Mar 01, 2020 at 01:03:06PM +0100, Nick Erdmann wrote:
> error_setg_errno takes a positive error number, so we should not invert
> errno's sign.
> 
> Signed-off-by: Nick Erdmann 
> ---
>  hw/virtio/vhost-vsock.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c
> index 66da96583b..9f9093e196 100644
> --- a/hw/virtio/vhost-vsock.c
> +++ b/hw/virtio/vhost-vsock.c
> @@ -325,7 +325,7 @@ static void vhost_vsock_device_realize(DeviceState *dev, 
> Error **errp)
>  } else {
>  vhostfd = open("/dev/vhost-vsock", O_RDWR);
>  if (vhostfd < 0) {
> -error_setg_errno(errp, -errno,
> +error_setg_errno(errp, errno,
>   "vhost-vsock: failed to open vhost device");
>  return;
>  }

Reviewed-by: Stefano Garzarella 

Thanks,
Stefano




Re: [PATCH v4 07/11] monitor/hmp: move hmp_snapshot_* to block-hmp-cmds.c hmp_snapshot_blkdev is from GPLv2 version of the hmp-cmds.c thus have to change the licence to GPLv2

2020-03-04 Thread Maxim Levitsky
On Tue, 2020-03-03 at 18:15 +0100, Kevin Wolf wrote:
> Am 30.01.2020 um 13:34 hat Maxim Levitsky geschrieben:
> > Signed-off-by: Maxim Levitsky 
> > Reviewed-by: Dr. David Alan Gilbert 
> 
> Very long subject line. I suppose the license notice should be in the
> body instead.
> 
> >  block/monitor/block-hmp-cmds.c | 56 --
> >  include/block/block-hmp-cmds.h |  4 +++
> >  include/monitor/hmp.h  |  3 --
> >  monitor/hmp-cmds.c | 47 
> >  4 files changed, 58 insertions(+), 52 deletions(-)
> > 
> > diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
> > index 8e8288c2f1..b83687196f 100644
> > --- a/block/monitor/block-hmp-cmds.c
> > +++ b/block/monitor/block-hmp-cmds.c
> > @@ -1,10 +1,13 @@
> >  /*
> >   * Blockdev HMP commands
> >   *
> > + *  Authors:
> > + *  Anthony Liguori   
> > + *
> >   * Copyright (c) 2003-2008 Fabrice Bellard
> >   *
> > - * This work is licensed under the terms of the GNU GPL, version 2 or
> > - * later.  See the COPYING file in the top-level directory.
> > + * This work is licensed under the terms of the GNU GPL, version 2.
> > + * See the COPYING file in the top-level directory.
> 
> Please also copy the next paragraph of the license header:
> 
>  * Contributions after 2012-01-13 are licensed under the terms of the
>  * GNU GPL, version 2 or (at your option) any later version.
> 
> Kevin
Will do,
Best regards,
Maxim Levitsky




Re: [PATCH v2 00/30] Configurable policy for handling deprecated interfaces

2020-03-04 Thread Markus Armbruster
Peter Maydell  writes:

> On Tue, 3 Mar 2020 at 16:37, Markus Armbruster  wrote:
>>
>> Based-on: <20200227144531.24309-1-arm...@redhat.com>
>>
>> This series extends QMP introspection to cover deprecation.
>> Additionally, new option -compat lets you configure what to do when
>> deprecated interfaces get used.  This is intended for testing users of
>> the management interfaces.  It is experimental.
>
> How much do you think this is likely to affect the
> generate-rst-from-qapi-docs series? I'd really like
> that to go in for this release, but this looks like
> it's shaping up to be a big conflict :-(

I paused reviewing your series to post this one, because "I'd really
like that to go in for this release" :)

My series touches 21 existing commented definitions in qapi/, six more
in tests/qapi-schema/doc-good.json, and adds new module
qapi/compat.json.  Consolidated diff appended.

Rule of thumb for reducing conflict resolution labor: the bigger manual
change goes first.  Yours is bigger, but I don't remember how manual it
is.

Let's try to get both series reviewed, then figure out together how to
get them merged with the least pain.



$ git-diff -p --stat master posted/qapi-features \*.json
 qapi/block-core.json| 69 +++--
 qapi/block.json |  9 ++--
 qapi/char.json  |  1 +
 qapi/compat.json| 52 +++
 qapi/control.json   | 11 ++--
 qapi/introspect.json| 26 +-
 qapi/machine.json   | 34 ++--
 qapi/migration.json | 36 -
 qapi/misc.json  | 13 ++---
 qapi/qapi-schema.json   |  1 +
 tests/qapi-schema/doc-good.json | 22 +++-
 tests/qapi-schema/features-deprecated-type.json |  3 ++
 tests/qapi-schema/qapi-schema-test.json | 48 +++--
 13 files changed, 239 insertions(+), 86 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 85e27bb61f..bade02760c 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -297,7 +297,7 @@
 #
 # @encrypted: true if the backing device is encrypted
 #
-# @encryption_key_missing: Deprecated; always false
+# @encryption_key_missing: always false
 #
 # @detect_zeroes: detect and optimize zero writes (Since 2.1)
 #
@@ -363,13 +363,19 @@
 # @dirty-bitmaps: dirty bitmaps information (only present if node
 # has one or more dirty bitmaps) (Since 4.2)
 #
+# Features:
+# @deprecated: Member @encryption_key_missing is deprecated.  It is
+# always false.
+#
 # Since: 0.14.0
 #
 ##
 { 'struct': 'BlockDeviceInfo',
   'data': { 'file': 'str', '*node-name': 'str', 'ro': 'bool', 'drv': 'str',
 '*backing_file': 'str', 'backing_file_depth': 'int',
-'encrypted': 'bool', 'encryption_key_missing': 'bool',
+'encrypted': 'bool',
+'encryption_key_missing': { 'type': 'bool',
+'features': [ 'deprecated' ] },
 'detect_zeroes': 'BlockdevDetectZeroesOptions',
 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
@@ -475,7 +481,7 @@
 #
 # @granularity: granularity of the dirty bitmap in bytes (since 1.4)
 #
-# @status: Deprecated in favor of @recording and @locked. (since 2.4)
+# @status: current status of the dirty bitmap (since 2.4)
 #
 # @recording: true if the bitmap is recording new writes from the guest.
 # Replaces `active` and `disabled` statuses. (since 4.0)
@@ -492,11 +498,17 @@
 #@busy to be false. This bitmap cannot be used. To remove
 #it, use @block-dirty-bitmap-remove. (Since 4.0)
 #
+# Features:
+# @deprecated: Member @status is deprecated.  Use @recording and
+# @locked instead.
+#
 # Since: 1.3
 ##
 { 'struct': 'BlockDirtyInfo',
   'data': {'*name': 'str', 'count': 'int', 'granularity': 'uint32',
-   'recording': 'bool', 'busy': 'bool', 'status': 'DirtyBitmapStatus',
+   'recording': 'bool', 'busy': 'bool',
+   'status': { 'type': 'DirtyBitmapStatus',
+   'features': [ 'deprecated' ] },
'persistent': 'bool', '*inconsistent': 'bool' } }
 
 ##
@@ -659,7 +671,6 @@
 #
 # @dirty-bitmaps: dirty bitmaps information (only present if the
 # driver has one or more dirty bitmaps) (Since 2.0)
-# Deprecated in 4.2; see BlockDeviceInfo instead.
 #
 # @io-status: @BlockDeviceIoStatus. Only present if the device
 # supports it and the VM is configured to stop on errors
@@ -669,13 +680,18 @@
 # @inserted: @BlockDeviceInfo describing the device if media is
 #present
 #
+# Features:
+# @deprecated: Member @dirty-bitmaps is deprecated.  Use @inserted
+#   

Re: [PATCH 1/2] misc: Replace zero-length arrays with flexible array member (automatic)

2020-03-04 Thread David Hildenbrand
On 04.03.20 01:51, Philippe Mathieu-Daudé wrote:
> Description copied from Linux kernel commit from Gustavo A. R. Silva
> (see [3]):
> 
> --v-- description start --v--
> 
>   The current codebase makes use of the zero-length array language
>   extension to the C90 standard, but the preferred mechanism to
>   declare variable-length types such as these ones is a flexible
>   array member [1], introduced in C99:
> 
>   struct foo {
>   int stuff;
>   struct boo array[];
>   };
> 
>   By making use of the mechanism above, we will get a compiler
>   warning in case the flexible array does not occur last in the
>   structure, which will help us prevent some kind of undefined
>   behavior bugs from being unadvertenly introduced [2] to the
>   Linux codebase from now on.
> 
> --^-- description end --^--
> 
> Do the similar housekeeping in the QEMU codebase (which uses
> C99 since commit 7be41675f7cb).
> 
> All these instances of code were found with the help of the
> following Coccinelle script:
> 
>   @@
>   identifier s, a;
>   type T;
>   @@
>struct s {
>   ...
>   -   T a[0];
>   +   T a[];
>   };
>   @@
>   identifier s, a;
>   type T;
>   @@
>struct s {
>   ...
>   -   T a[0];
>   +   T a[];
>} QEMU_PACKED;
> 
> [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
> [2] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76497732932f
> [3] 
> https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/commit/?id=17642a2fbd2c1
> 
> Inspired-by: Gustavo A. R. Silva 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  bsd-user/qemu.h   |  2 +-
>  contrib/libvhost-user/libvhost-user.h |  2 +-
>  hw/m68k/bootinfo.h|  2 +-
>  hw/scsi/srp.h |  6 +++---
>  hw/xen/xen_pt.h   |  2 +-
>  include/hw/acpi/acpi-defs.h   | 12 ++--
>  include/hw/arm/smmu-common.h  |  2 +-
>  include/hw/i386/intel_iommu.h |  3 ++-
>  include/hw/virtio/virtio-iommu.h  |  2 +-
>  include/sysemu/cryptodev.h|  2 +-
>  include/tcg/tcg.h |  2 +-
>  pc-bios/s390-ccw/bootmap.h|  2 +-
>  pc-bios/s390-ccw/sclp.h   |  2 +-
>  tests/qtest/libqos/ahci.h |  2 +-
>  block/linux-aio.c |  2 +-
>  hw/acpi/nvdimm.c  |  6 +++---
>  hw/dma/soc_dma.c  |  2 +-
>  hw/i386/x86.c |  2 +-
>  hw/misc/omap_l4.c |  2 +-
>  hw/nvram/eeprom93xx.c |  2 +-
>  hw/rdma/vmw/pvrdma_qp_ops.c   |  4 ++--
>  hw/usb/dev-network.c  |  2 +-
>  hw/usb/dev-smartcard-reader.c |  4 ++--
>  hw/virtio/virtio.c|  4 ++--
>  net/queue.c   |  2 +-
>  25 files changed, 38 insertions(+), 37 deletions(-)
> 
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index 09e8aed9c7..f8bb1e5459 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -95,7 +95,7 @@ typedef struct TaskState {
>  struct sigqueue *first_free; /* first free siginfo queue entry */
>  int signal_pending; /* non zero if a signal may be pending */
>  
> -uint8_t stack[0];
> +uint8_t stack[];
>  } __attribute__((aligned(16))) TaskState;
>  
>  void init_task_state(TaskState *ts);
> diff --git a/contrib/libvhost-user/libvhost-user.h 
> b/contrib/libvhost-user/libvhost-user.h
> index 6fc8000e99..f30394fab6 100644
> --- a/contrib/libvhost-user/libvhost-user.h
> +++ b/contrib/libvhost-user/libvhost-user.h
> @@ -286,7 +286,7 @@ typedef struct VuVirtqInflight {
>  uint16_t used_idx;
>  
>  /* Used to track the state of each descriptor in descriptor table */
> -VuDescStateSplit desc[0];
> +VuDescStateSplit desc[];
>  } VuVirtqInflight;
>  
>  typedef struct VuVirtqInflightDesc {
> diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h
> index 5f8ded2686..c954270aad 100644
> --- a/hw/m68k/bootinfo.h
> +++ b/hw/m68k/bootinfo.h
> @@ -14,7 +14,7 @@
>  struct bi_record {
>  uint16_t tag;/* tag ID */
>  uint16_t size;   /* size of record */
> -uint32_t data[0];/* data */
> +uint32_t data[]; /* data */
>  };
>  
>  /* machine independent tags */
> diff --git a/hw/scsi/srp.h b/hw/scsi/srp.h
> index d27f31d2d5..54c954badd 100644
> --- a/hw/scsi/srp.h
> +++ b/hw/scsi/srp.h
> @@ -112,7 +112,7 @@ struct srp_direct_buf {
>  struct srp_indirect_buf {
>  struct srp_direct_buftable_desc;
>  uint32_t len;
> -struct srp_direct_bufdesc_list[0];
> +struct srp_direct_bufdesc_list[];
>  } QEMU_PACKED;
>  
>  enum {
> @@ -211,7 +211,7 @@ struct srp_cmd {
>  uint8_treserved4;
>  uint8_tadd_cdb_len;
>  uint8_tcdb[16];
> -uint8_tadd_data[0];
> +uint8_tadd_data[];
>  } QEMU_PACKED;
>  
>  enum {
> @@ -241,7 +241,7 @@ struct srp_rsp {
>  uint32_t   data_in_res_cnt;
>  

Re: [PATCH 2/2] misc: Replace zero-length arrays with flexible array member (manual)

2020-03-04 Thread David Hildenbrand
On 04.03.20 01:58, Philippe Mathieu-Daudé wrote:
> Description copied from Linux kernel commit from Gustavo A. R. Silva
> (see [3]):
> 
> --v-- description start --v--
> 
>   The current codebase makes use of the zero-length array language
>   extension to the C90 standard, but the preferred mechanism to
>   declare variable-length types such as these ones is a flexible
>   array member [1], introduced in C99:
> 
>   struct foo {
>   int stuff;
>   struct boo array[];
>   };
> 
>   By making use of the mechanism above, we will get a compiler
>   warning in case the flexible array does not occur last in the
>   structure, which will help us prevent some kind of undefined
>   behavior bugs from being unadvertenly introduced [2] to the
>   Linux codebase from now on.
> 
> --^-- description end --^--
> 
> Do the similar housekeeping in the QEMU codebase (which uses
> C99 since commit 7be41675f7cb).
> 
> All these instances of code were found with the help of the
> following command (then manual analysis):
> 
>   git grep -F '[0];'
> 
> [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
> [2] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76497732932f
> [3] 
> https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/commit/?id=17642a2fbd2c1
> 
> Inspired-by: Gustavo A. R. Silva 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  docs/interop/vhost-user.rst   | 4 ++--
>  block/qed.h   | 2 +-
>  include/hw/acpi/acpi-defs.h   | 4 ++--
>  include/hw/boards.h   | 2 +-
>  include/hw/s390x/event-facility.h | 2 +-
>  include/hw/s390x/sclp.h   | 8 
>  block/vmdk.c  | 2 +-
>  hw/char/sclpconsole-lm.c  | 2 +-
>  hw/char/sclpconsole.c | 2 +-
>  hw/s390x/virtio-ccw.c | 2 +-
>  target/s390x/ioinst.c | 2 +-
>  11 files changed, 16 insertions(+), 16 deletions(-)
> 
> diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
> index 401652397c..3b1b6602c7 100644
> --- a/docs/interop/vhost-user.rst
> +++ b/docs/interop/vhost-user.rst
> @@ -568,7 +568,7 @@ For split virtqueue, queue region can be implemented as:
>uint16_t used_idx;
>  
>/* Used to track the state of each descriptor in descriptor table */
> -  DescStateSplit desc[0];
> +  DescStateSplit desc[];
>} QueueRegionSplit;
>  
>  To track inflight I/O, the queue region should be processed as follows:
> @@ -690,7 +690,7 @@ For packed virtqueue, queue region can be implemented as:
>uint8_t padding[7];
>  
>/* Used to track the state of each descriptor fetched from descriptor 
> ring */
> -  DescStatePacked desc[0];
> +  DescStatePacked desc[];
>} QueueRegionPacked;
>  
>  To track inflight I/O, the queue region should be processed as follows:
> diff --git a/block/qed.h b/block/qed.h
> index 42c115d822..87428ba00e 100644
> --- a/block/qed.h
> +++ b/block/qed.h
> @@ -103,7 +103,7 @@ typedef struct {
>  } QEMU_PACKED QEDHeader;
>  
>  typedef struct {
> -uint64_t offsets[0];/* in bytes */
> +uint64_t offsets[]; /* in bytes */
>  } QEDTable;
>  
>  /* The L2 cache is a simple write-through cache for L2 structures */
> diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
> index 19f7ba7b70..c13327fa78 100644
> --- a/include/hw/acpi/acpi-defs.h
> +++ b/include/hw/acpi/acpi-defs.h
> @@ -152,7 +152,7 @@ typedef struct AcpiSerialPortConsoleRedirection
>   */
>  struct AcpiRsdtDescriptorRev1 {
>  ACPI_TABLE_HEADER_DEF   /* ACPI common table header */
> -uint32_t table_offset_entry[0];  /* Array of pointers to other */
> +uint32_t table_offset_entry[];  /* Array of pointers to other */
>  /* ACPI tables */
>  } QEMU_PACKED;
>  typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1;
> @@ -162,7 +162,7 @@ typedef struct AcpiRsdtDescriptorRev1 
> AcpiRsdtDescriptorRev1;
>   */
>  struct AcpiXsdtDescriptorRev2 {
>  ACPI_TABLE_HEADER_DEF   /* ACPI common table header */
> -uint64_t table_offset_entry[0];  /* Array of pointers to other */
> +uint64_t table_offset_entry[];  /* Array of pointers to other */
>  /* ACPI tables */
>  } QEMU_PACKED;
>  typedef struct AcpiXsdtDescriptorRev2 AcpiXsdtDescriptorRev2;
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 9bc42dfb22..c96120d15f 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -71,7 +71,7 @@ typedef struct CPUArchId {
>   */
>  typedef struct {
>  int len;
> -CPUArchId cpus[0];
> +CPUArchId cpus[];
>  } CPUArchIdList;
>  
>  /**
> diff --git a/include/hw/s390x/event-facility.h 
> b/include/hw/s390x/event-facility.h
> index bdc32a3c09..700a610f33 100644
> --- a/include/hw/s390x/event-facility.h
> +++ b/include/hw/s390x/event-facility.h
> @@ -122,7 +122,7 @@ typedef struct MDBO {
>  
>  typedef struct MDB {
>  MdbHeader header;
> -MDBO mdbo[0];
> +M

Re: [PATCH RFC 2/4] intc/s390_flic_kvm.c: Use kvm_device_ioctl() instead of ioctl()

2020-03-04 Thread Christian Borntraeger



On 03.03.20 15:19, David Hildenbrand wrote:
> Let's use the official variant, which will e.g., trace the call.
> 
> Cc: Cornelia Huck 
> Cc: Halil Pasic 
> Cc: Christian Borntraeger 
> Cc: qemu-s3...@nongnu.org
> Signed-off-by: David Hildenbrand 
> ---
>  hw/intc/s390_flic_kvm.c | 22 +++---
>  1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
> index a306b26faa..5151582ba0 100644
> --- a/hw/intc/s390_flic_kvm.c
> +++ b/hw/intc/s390_flic_kvm.c
> @@ -68,7 +68,7 @@ static int flic_get_all_irqs(KVMS390FLICState *flic,
>  };
>  int rc;
>  
> -rc = ioctl(flic->fd, KVM_GET_DEVICE_ATTR, &attr);
> +rc = kvm_device_ioctl(flic->fd, KVM_GET_DEVICE_ATTR, &attr);
>  
>  return rc == -1 ? -errno : rc;
>  }
> @@ -80,7 +80,7 @@ static void flic_enable_pfault(KVMS390FLICState *flic)
>  };
>  int rc;
>  
> -rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
> +rc = kvm_device_ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
>  
>  if (rc) {
>  fprintf(stderr, "flic: couldn't enable pfault\n");
> @@ -94,7 +94,7 @@ static void flic_disable_wait_pfault(KVMS390FLICState *flic)
>  };
>  int rc;
>  
> -rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
> +rc = kvm_device_ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
>  
>  if (rc) {
>  fprintf(stderr, "flic: couldn't disable pfault\n");
> @@ -118,7 +118,7 @@ static int flic_enqueue_irqs(void *buf, uint64_t len,
>  .attr = len,
>  };
>  
> -rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
> +rc = kvm_device_ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
>  
>  return rc ? -errno : 0;

This is no longer necessary as this is done by kvm_device_ioctl, no?

Same for other location.s




Re: [PATCH RFC 2/4] intc/s390_flic_kvm.c: Use kvm_device_ioctl() instead of ioctl()

2020-03-04 Thread David Hildenbrand
On 04.03.20 09:22, Christian Borntraeger wrote:
> 
> 
> On 03.03.20 15:19, David Hildenbrand wrote:
>> Let's use the official variant, which will e.g., trace the call.
>>
>> Cc: Cornelia Huck 
>> Cc: Halil Pasic 
>> Cc: Christian Borntraeger 
>> Cc: qemu-s3...@nongnu.org
>> Signed-off-by: David Hildenbrand 
>> ---
>>  hw/intc/s390_flic_kvm.c | 22 +++---
>>  1 file changed, 11 insertions(+), 11 deletions(-)
>>
>> diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
>> index a306b26faa..5151582ba0 100644
>> --- a/hw/intc/s390_flic_kvm.c
>> +++ b/hw/intc/s390_flic_kvm.c
>> @@ -68,7 +68,7 @@ static int flic_get_all_irqs(KVMS390FLICState *flic,
>>  };
>>  int rc;
>>  
>> -rc = ioctl(flic->fd, KVM_GET_DEVICE_ATTR, &attr);
>> +rc = kvm_device_ioctl(flic->fd, KVM_GET_DEVICE_ATTR, &attr);
>>  
>>  return rc == -1 ? -errno : rc;
>>  }
>> @@ -80,7 +80,7 @@ static void flic_enable_pfault(KVMS390FLICState *flic)
>>  };
>>  int rc;
>>  
>> -rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
>> +rc = kvm_device_ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
>>  
>>  if (rc) {
>>  fprintf(stderr, "flic: couldn't enable pfault\n");
>> @@ -94,7 +94,7 @@ static void flic_disable_wait_pfault(KVMS390FLICState 
>> *flic)
>>  };
>>  int rc;
>>  
>> -rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
>> +rc = kvm_device_ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
>>  
>>  if (rc) {
>>  fprintf(stderr, "flic: couldn't disable pfault\n");
>> @@ -118,7 +118,7 @@ static int flic_enqueue_irqs(void *buf, uint64_t len,
>>  .attr = len,
>>  };
>>  
>> -rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
>> +rc = kvm_device_ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);
>>  
>>  return rc ? -errno : 0;
> 
> This is no longer necessary as this is done by kvm_device_ioctl, no?
> 
> Same for other location.s
> 

Right, missed that. Thanks for pointing that out!

-- 
Thanks,

David / dhildenb




Re: [PATCH v16 00/10] VIRTIO-IOMMU device

2020-03-04 Thread Auger Eric
Hi Zhangfei,

On 3/4/20 7:08 AM, Zhangfei Gao wrote:
> On Tue, Mar 3, 2020 at 5:41 PM Auger Eric  wrote:
>>
>> Hi Zhangfei,
>> On 3/3/20 4:23 AM, Zhangfei Gao wrote:
>>> Hi Eric
>>>
>>> On Thu, Feb 27, 2020 at 9:50 PM Auger Eric  wrote:

 Hi Daniel,

 On 2/27/20 12:17 PM, Daniel P. Berrangé wrote:
> On Fri, Feb 14, 2020 at 02:27:35PM +0100, Eric Auger wrote:
>> This series implements the QEMU virtio-iommu device.
>>
>> This matches the v0.12 spec (voted) and the corresponding
>> virtio-iommu driver upstreamed in 5.3. All kernel dependencies
>> are resolved for DT integration. The virtio-iommu can be
>> instantiated in ARM virt using:
>>
>> "-device virtio-iommu-pci".
>
> Is there any more documentation besides this ?

 not yet in qemu.
>
> I'm wondering on the intended usage of this, and its relation
> or pros/cons vs other iommu devices

 Maybe if you want to catch up on the topic, looking at the very first
 kernel RFC may be a good starting point. Motivation, pros & cons were
 discussed in that thread (hey, April 2017!)
 https://lists.linuxfoundation.org/pipermail/iommu/2017-April/021217.html

 on ARM we have SMMUv3 emulation. But the VFIO integration is not
 possible because SMMU does not have any "caching mode" and my nested
 paging kernel series is blocked. So the only solution to integrate with
 VFIO is looming virtio-iommu.

 In general the pros that were put forward are: virtio-iommu is
 architecture agnostic, removes the burden to accurately model complex
 device states, driver can support virtualization specific optimizations
 without being constrained by production driver maintenance. Cons is perf
 and mem footprint if we do not consider any optimization.

 You can have a look at

 http://events17.linuxfoundation.org/sites/events/files/slides/viommu_arm.pdf

>>> Thanks for the patches.
>>>
>>> Could I ask one question?
>>> To support vSVA and pasid in guest, which direction you recommend,
>>> virtio-iommu or vSMMU (your nested paging)
>>>
>>> Do we still have any obstacles?
>> you can ask the question but not sure I can answer ;-)
>>
>> 1) SMMUv3 2stage implementation is blocked by Will at kernel level.
>>
>> Despite this situation I may/can respin as Marvell said they were
>> interested in this effort. If you are also interested in (I know you
>> tested it several times and I am grateful to you for that), please reply
>> to:
>> [PATCH v9 00/14] SMMUv3 Nested Stage Setup (IOMMU part)
>> (https://patchwork.kernel.org/cover/11039871/) and say you are
>> interested in that work so that maintainers are aware there are
>> potential users.
>>
>> At the moment I have not supported multiple CDs because it introduced
>> other dependencies.
>>
>> 2) virtio-iommu
>>
>> So only virtio-iommu dt boot on machvirt is currently supported. For non
>> DT, Jean respinned his kernel series
>> "[PATCH v2 0/3] virtio-iommu on x86 and non-devicetree platforms" as you
>> may know. However non DT integration still is controversial. Michael is
>> pushing for putting the binding info the PCI config space. Joerg
>> yesterday challenged this solution and said he would prefer ACPI
>> integration. ACPI support depends on ACPI spec update & vote anyway.
>>
>> To support PASID at virtio-iommu level you also need virtio-iommu API
>> extensions to be proposed and written + kernel works. So that's a long
>> road. I will let Jean-Philippe comment on that.
>>
>> I would just say that Intel is working on nested paging solution with
>> their emulated intel-iommu. We can help them getting that upstream and
>> partly benefit from this work.
>>
>>> Would you mind give some breakdown.
>>> Jean mentioned PASID still not supported in QEMU.
>> Do you mean support of multiple CDs in the emulated SMMU? That's a thing
>> I could implement quite easily. What is more tricky is how to test it.
> 
> Thanks Eric
> 
> Discussed with Jean before, here are some obstacles for vSVA via nested 
> paging.
> Do you think they are still big issues?
> 
> Copy "
> * PASID support in QEMU, I don't think there is anything yet
> // this is not a big issue as your comments.
> 
> * Page response support in VFIO and QEMU. With Eric's series we can
> inject recoverable faults into the guest, but there is no channel for
> the guest to RESUME the stall after fixing it.
I guess this matches a command sent through the SMMUv3 command queue
(CMD_PRI_RESP) that should be trapped by QEMU and injected to the
physical SMMU, right?

I think everybody misses that injection path and that's not specific to
virtio-iommu. PRS is not currently addressed by in-flight Intel's kernel
series ([PATCH V9 00/10] Nested Shared Virtual Address (SVA) VT-d
support) either.

I think the topic is complex enough to separate the concerns and try to
move forward in incremental steps hence my efforts to push for simple
nested use case. Can'

Re: [PATCH] hw/ide: Remove status register read side effect

2020-03-04 Thread BALATON Zoltan

On Wed, 4 Mar 2020, jasper.low...@bt.com wrote:

cmd646_update_irq() only seems to raise PCI interrupt, should it also
have
an option to use INT 14 and 15 in legacy mode similar to what my
patch
does for via-ide?


Looking through /qemu/hw/ide/cmd646.c it doesn't look like QEMU has
support for legacy mode. At the very least, it looks like we default to
PCI native mode:

static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
...
pci_conf[PCI_CLASS_PROG] = 0x8f;
...

To add support for legacy mode it would require changing
cmd646_update_irq() and maybe cmd646_set_irq() so that interrupts are
conditionally raised on IRQ14 and/or IRQ15 when the ports are in legacy
mode.


Ah yes, same problem as with via-ide. With current ISA IDE and PCI device 
emulation code in QEMU it's not easy to emulate both modes but maybe we 
don't need that either. (So we can avoid changing ISA and PCI QEMU parts 
that are widely used and risk breaking something else by that.) The 
Solaris driver does seem to use native mode because it could find io 
addresses in PCI BARs to talk to the controller just did not get 
interrupts if I got that right. Then maybe PCI interrupts are not routed 
as expected by the driver which could be due to


- difference in PCI bridge emulation,
- where the controller is connected
- or how firmware describes it in device tree
- or how it configures it

compared to real hardware. Unless it also has some pecularity similar to 
pegasos2 with native mode and ISA interrupts. Checking on real hardware 
should reveal these differences so maybe that's the best way to find out. 
As for seeing what the firmware does Sun's OpenBoot is open sourced so 
maybe what that does could be checked but probably not easy to find out in 
Forth.


Here are a few Linux logs I've found that suggest on a Sun Ultra 5/10 IDE 
is on irq 4 for both channels, but not sure how PCI interrupt ends up 
there though. Does that match what QEMU does?


http://gavinduley.org/interests/computing/sundmesg.html
https://lists.debian.org/debian-boot/2004/10/msg00864.html
https://forums.gentoo.org/viewtopic-t-473614-start-0.html

Regards,
BALATON Zoltan



Re: [PATCH] optionrom/pvh: scan entire RSDP Area

2020-03-04 Thread Stefano Garzarella
CCing Paolo

On Tue, Mar 03, 2020 at 02:52:47AM -0800, Joe Richey wrote:
> From: Joe Richey 
> 
> Right now the PVH option rom scans for the RSDP from 0xE to
> 0xE1FFF. This is probobly a typo, it should scan from 0xE to
> 0xF.
> 
> This is actually an issue on some QEMU versions/machines. For example,
> when I run QEMU the RSDP is placed at 0xf5ad0 which will not be picked
> up by the current implementation.
> 
> This bug still allows a Linux guest to boot (in most configurations) as
> the kernel will just scan for the RSDP if one isn't provided.
> 
> Signed-off-by: Joe Richey 
> ---
>  pc-bios/optionrom/pvh_main.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/pc-bios/optionrom/pvh_main.c b/pc-bios/optionrom/pvh_main.c
> index a015e1bf22..28e79d7fc4 100644
> --- a/pc-bios/optionrom/pvh_main.c
> +++ b/pc-bios/optionrom/pvh_main.c
> @@ -29,7 +29,7 @@ asm (".code32"); /* this code will be executed in protected 
> mode */
>  
>  #define RSDP_SIGNATURE  0x2052545020445352LL /* "RSD PTR " */
>  #define RSDP_AREA_ADDR  0x000E
> -#define RSDP_AREA_SIZE  2048
> +#define RSDP_AREA_SIZE  0x0002
>  #define EBDA_BASE_ADDR  0x040E
>  #define EBDA_SIZE   1024
>  

The patch LGTM!

When I wrote this code I followed [1], where it is written that it can
be found in the "memory region from 0x000E to 0x000F", so it
should be a typo.

Thanks for fixing it!


Fixes: 2785dc7b17 ("optionrom: add new PVH option rom")
Reviewed-by: Stefano Garzarella 


[1] https://wiki.osdev.org/RSDP#Detecting_the_RSDP




Re: [PATCH] pc-bios: s390x: Save iplb location in lowcore

2020-03-04 Thread Janosch Frank
On 3/3/20 5:13 PM, David Hildenbrand wrote:
> On 03.03.20 16:50, Janosch Frank wrote:
>> The POP states that for a list directed IPL the IPLB is stored into
>> memory by the machine loader and its address is stored at offset 0x14
>> of the lowcore.
>>
>> ZIPL currently uses the address in offset 0x14 to access the IPLB and
>> acquire flags about secure boot. If the IPLB address points into
>> memory which has an unsupported mix of flags set, ZIPL will panic
>> instead of booting the OS.
>>
>> As the lowcore can have quite a high entropy for a guest that did drop
>> out of protected mode (i.e. rebooted) we encountered the ZIPL panic
>> quite often.
> 
> How did this ever work? Or does this only become relevant with secure boot?

I'd guess that until secure boot ZIPL never touched this and with it we
never hit the right combination of flags to trigger a ZIPL panic.

This way of getting to the IPLB was used before diag308 was available,
i.e. way before KVM got to IBM Z. It looks like ZIPL only uses it for
secure boot for some reason and hence we never implemented it before.

I'm also in discussion with the ZIPL developers to make this more robust.

> 
> Fixes: ? Or has this always been broken?

See above

> 
>>
>> Signed-off-by: Janosch Frank 
>> Tested-by: Marc Hartmayer 
>> ---
>>  pc-bios/s390-ccw/jump2ipl.c  |  1 +
>>  pc-bios/s390-ccw/main.c  |  8 +++-
>>  pc-bios/s390-ccw/netmain.c   |  1 +
>>  pc-bios/s390-ccw/s390-arch.h | 10 --
>>  pc-bios/s390-ccw/s390-ccw.h  |  1 +
>>  5 files changed, 18 insertions(+), 3 deletions(-)
>>
>> diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
>> index da13c43cc0..4eba2510b0 100644
>> --- a/pc-bios/s390-ccw/jump2ipl.c
>> +++ b/pc-bios/s390-ccw/jump2ipl.c
>> @@ -35,6 +35,7 @@ void jump_to_IPL_code(uint64_t address)
>>  {
>>  /* store the subsystem information _after_ the bootmap was loaded */
>>  write_subsystem_identification();
>> +write_iplb_location();
>>  
>>  /* prevent unknown IPL types in the guest */
>>  if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
>> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
>> index a21b386280..4e65b411e1 100644
>> --- a/pc-bios/s390-ccw/main.c
>> +++ b/pc-bios/s390-ccw/main.c
>> @@ -9,6 +9,7 @@
>>   */
>>  
>>  #include "libc.h"
>> +#include "helper.h"
>>  #include "s390-arch.h"
>>  #include "s390-ccw.h"
>>  #include "cio.h"
>> @@ -22,7 +23,7 @@ QemuIplParameters qipl;
>>  IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
>>  static bool have_iplb;
>>  static uint16_t cutype;
>> -LowCore const *lowcore; /* Yes, this *is* a pointer to address 0 */
>> +LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
>>  
>>  #define LOADPARM_PROMPT "PROMPT  "
>>  #define LOADPARM_EMPTY  ""
>> @@ -42,6 +43,11 @@ void write_subsystem_identification(void)
>>  *zeroes = 0;
>>  }
>>  
>> +void write_iplb_location(void)
>> +{
>> +lowcore->ptr_iplb = ptr2u32(&iplb);
>> +}
>> +
>>  void panic(const char *string)
>>  {
>>  sclp_print(string);
>> diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
>> index f2dcc01e27..309ffa30d9 100644
>> --- a/pc-bios/s390-ccw/netmain.c
>> +++ b/pc-bios/s390-ccw/netmain.c
>> @@ -40,6 +40,7 @@
>>  #define DEFAULT_TFTP_RETRIES 20
>>  
>>  extern char _start[];
>> +void write_iplb_location(void) {}
>>  
>>  #define KERNEL_ADDR ((void *)0L)
>>  #define KERNEL_MAX_SIZE ((long)_start)
>> diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
>> index 504fc7c2f0..5f36361c02 100644
>> --- a/pc-bios/s390-ccw/s390-arch.h
>> +++ b/pc-bios/s390-ccw/s390-arch.h
>> @@ -36,7 +36,13 @@ typedef struct LowCore {
>>  /* prefix area: defined by architecture */
>>  PSWLegacy   ipl_psw;  /* 0x000 */
>>  uint32_tccw1[2];  /* 0x008 */
>> -uint32_tccw2[2];  /* 0x010 */
>> +union {
>> +uint32_tccw2[2];  /* 0x010 */
>> +struct {
>> +uint32_t reserved10;
>> +uint32_t ptr_iplb;
>> +};
>> +};
>>  uint8_t pad1[0x80 - 0x18];/* 0x018 */
>>  uint32_text_params;   /* 0x080 */
>>  uint16_tcpu_addr; /* 0x084 */
>> @@ -85,7 +91,7 @@ typedef struct LowCore {
>>  PSW io_new_psw;   /* 0x1f0 */
>>  } __attribute__((packed, aligned(8192))) LowCore;
>>  
>> -extern LowCore const *lowcore;
>> +extern LowCore *lowcore;
>>  
>>  static inline void set_prefix(uint32_t address)
>>  {
>> diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
>> index 11bce7d73c..21f27e7990 100644
>> --- a/pc-bios/s390-ccw/s390-ccw.h
>> +++ b/pc-bios/s390-ccw/s390-ccw.h
>> @@ -57,6 +57,7 @@ void consume_io_int(void);
>>  /* main.c */
>>  void panic(const char *string);
>>  void write_subsystem_identification(void);
>> +void write_iplb_location(void);
>

Re: [PATCH 2/2] misc: Replace zero-length arrays with flexible array member (manual)

2020-03-04 Thread Philippe Mathieu-Daudé

On 3/4/20 1:58 AM, Philippe Mathieu-Daudé wrote:

Description copied from Linux kernel commit from Gustavo A. R. Silva
(see [3]):

--v-- description start --v--

   The current codebase makes use of the zero-length array language
   extension to the C90 standard, but the preferred mechanism to
   declare variable-length types such as these ones is a flexible
   array member [1], introduced in C99:

   struct foo {
   int stuff;
   struct boo array[];
   };

   By making use of the mechanism above, we will get a compiler
   warning in case the flexible array does not occur last in the
   structure, which will help us prevent some kind of undefined
   behavior bugs from being unadvertenly introduced [2] to the
   Linux codebase from now on.

--^-- description end --^--

Do the similar housekeeping in the QEMU codebase (which uses
C99 since commit 7be41675f7cb).

All these instances of code were found with the help of the
following command (then manual analysis):

   git grep -F '[0];'

[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76497732932f
[3] 
https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/commit/?id=17642a2fbd2c1

Inspired-by: Gustavo A. R. Silva 
Signed-off-by: Philippe Mathieu-Daudé 
---
  docs/interop/vhost-user.rst   | 4 ++--
  block/qed.h   | 2 +-
  include/hw/acpi/acpi-defs.h   | 4 ++--
  include/hw/boards.h   | 2 +-
  include/hw/s390x/event-facility.h | 2 +-
  include/hw/s390x/sclp.h   | 8 
  block/vmdk.c  | 2 +-
  hw/char/sclpconsole-lm.c  | 2 +-
  hw/char/sclpconsole.c | 2 +-
  hw/s390x/virtio-ccw.c | 2 +-
  target/s390x/ioinst.c | 2 +-
  11 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
index 401652397c..3b1b6602c7 100644
--- a/docs/interop/vhost-user.rst
+++ b/docs/interop/vhost-user.rst
@@ -568,7 +568,7 @@ For split virtqueue, queue region can be implemented as:
uint16_t used_idx;
  
/* Used to track the state of each descriptor in descriptor table */

-  DescStateSplit desc[0];
+  DescStateSplit desc[];
} QueueRegionSplit;
  
  To track inflight I/O, the queue region should be processed as follows:

@@ -690,7 +690,7 @@ For packed virtqueue, queue region can be implemented as:
uint8_t padding[7];
  
/* Used to track the state of each descriptor fetched from descriptor ring */

-  DescStatePacked desc[0];
+  DescStatePacked desc[];
} QueueRegionPacked;
  
  To track inflight I/O, the queue region should be processed as follows:

diff --git a/block/qed.h b/block/qed.h
index 42c115d822..87428ba00e 100644
--- a/block/qed.h
+++ b/block/qed.h
@@ -103,7 +103,7 @@ typedef struct {
  } QEMU_PACKED QEDHeader;
  
  typedef struct {

-uint64_t offsets[0];/* in bytes */
+uint64_t offsets[]; /* in bytes */


Apparently this one is incorrect, it triggers:

GCC:
block/qed.h:106:14: error: flexible array member in otherwise empty struct

Clang:
block/qed.h:106:14: error: flexible array member 'offsets' not allowed 
in otherwise empty struct



  } QEDTable;
  
  /* The L2 cache is a simple write-through cache for L2 structures */

diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 19f7ba7b70..c13327fa78 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -152,7 +152,7 @@ typedef struct AcpiSerialPortConsoleRedirection
   */
  struct AcpiRsdtDescriptorRev1 {
  ACPI_TABLE_HEADER_DEF   /* ACPI common table header */
-uint32_t table_offset_entry[0];  /* Array of pointers to other */
+uint32_t table_offset_entry[];  /* Array of pointers to other */
  /* ACPI tables */
  } QEMU_PACKED;
  typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1;
@@ -162,7 +162,7 @@ typedef struct AcpiRsdtDescriptorRev1 
AcpiRsdtDescriptorRev1;
   */
  struct AcpiXsdtDescriptorRev2 {
  ACPI_TABLE_HEADER_DEF   /* ACPI common table header */
-uint64_t table_offset_entry[0];  /* Array of pointers to other */
+uint64_t table_offset_entry[];  /* Array of pointers to other */
  /* ACPI tables */
  } QEMU_PACKED;
  typedef struct AcpiXsdtDescriptorRev2 AcpiXsdtDescriptorRev2;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 9bc42dfb22..c96120d15f 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -71,7 +71,7 @@ typedef struct CPUArchId {
   */
  typedef struct {
  int len;
-CPUArchId cpus[0];
+CPUArchId cpus[];
  } CPUArchIdList;
  
  /**

diff --git a/include/hw/s390x/event-facility.h 
b/include/hw/s390x/event-facility.h
index bdc32a3c09..700a610f33 100644
--- a/include/hw/s390x/event-facility.h
+++ b/include/hw/s390x/event-facility.h
@@ -122,7 +122,7 @@ typedef struct MDBO {
  
  typedef struct MDB {

  Md

Re: [PATCH v2 00/30] Configurable policy for handling deprecated interfaces

2020-03-04 Thread Peter Maydell
On Wed, 4 Mar 2020 at 08:18, Markus Armbruster  wrote:
> Peter Maydell  writes:
> > How much do you think this is likely to affect the
> > generate-rst-from-qapi-docs series? I'd really like
> > that to go in for this release, but this looks like
> > it's shaping up to be a big conflict :-(
>
> I paused reviewing your series to post this one, because "I'd really
> like that to go in for this release" :)
>
> My series touches 21 existing commented definitions in qapi/, six more
> in tests/qapi-schema/doc-good.json, and adds new module
> qapi/compat.json.  Consolidated diff appended.
>
> Rule of thumb for reducing conflict resolution labor: the bigger manual
> change goes first.  Yours is bigger, but I don't remember how manual it
> is.

We got pretty much all the manual changes I needed into
master already, so all that's left really is the script parts.
The conflicts would basically be where this series affects
the generate-docs parts of the scripts -- any changes here
to doc.py are basically dead-code-walking and would need
to be done over again in the equivalent code for rust generation.
But looking at the diffstat
 scripts/qapi/doc.py   |  16 +-
so hopefully it won't be too bad.

thanks
-- PMM



Re: [PATCH] pc-bios: s390x: Save iplb location in lowcore

2020-03-04 Thread David Hildenbrand
On 04.03.20 09:59, Janosch Frank wrote:
> On 3/3/20 5:13 PM, David Hildenbrand wrote:
>> On 03.03.20 16:50, Janosch Frank wrote:
>>> The POP states that for a list directed IPL the IPLB is stored into
>>> memory by the machine loader and its address is stored at offset 0x14
>>> of the lowcore.
>>>
>>> ZIPL currently uses the address in offset 0x14 to access the IPLB and
>>> acquire flags about secure boot. If the IPLB address points into
>>> memory which has an unsupported mix of flags set, ZIPL will panic
>>> instead of booting the OS.
>>>
>>> As the lowcore can have quite a high entropy for a guest that did drop
>>> out of protected mode (i.e. rebooted) we encountered the ZIPL panic
>>> quite often.
>>
>> How did this ever work? Or does this only become relevant with secure boot?
> 
> I'd guess that until secure boot ZIPL never touched this and with it we
> never hit the right combination of flags to trigger a ZIPL panic.
> 
> This way of getting to the IPLB was used before diag308 was available,
> i.e. way before KVM got to IBM Z. It looks like ZIPL only uses it for
> secure boot for some reason and hence we never implemented it before.
> 
> I'm also in discussion with the ZIPL developers to make this more robust.
> 

Thanks for the clarification!

[...]

> 
> Do you want to add a patch or shall I add it to my cleanup series?

Would be great if you could add a cleanup.

-- 
Thanks,

David / dhildenb




Re: [PATCH v3 00/33] Convert qemu-doc to rST

2020-03-04 Thread Kashyap Chamarthy
On Tue, Mar 03, 2020 at 05:35:01PM +, Peter Maydell wrote:
> On Fri, 28 Feb 2020 at 15:36, Peter Maydell  wrote:
> >
> > Hi; this series does a complete conversion of qemu-doc from
> > Texinfo to rST, including the hxtool-generated parts and
> > creation of the qemu.1 manpage from rST.
> >
> 
> Advance notice: I would like to put these into a pull
> request at the end of this week. This is your opportunity
> to say "that would be a bad idea", "I need X more time
> to review it", etc :-)

I tried to probe some of the generated docs; I couldn't spot something
that is glaring.  (Granted, I didn't spend a _whole_ lot of time.)

And I'm with Paolo — yes, let's get this merged, and address other
issues as follow-ups :-)

-- 
/kashyap




Re: [PATCH] virtio-serial-bus: do cleanup on the error path in realize() to avoid memleaks

2020-03-04 Thread Markus Armbruster
Pan Nengyuan  writes:

> port->bh forgot to delete on the error path, this patch add it to fix 
> memleaks. It's easy to reproduce as follow(add a same nr port):
> {'execute': 'device_add', 'arguments': {'id': 'virtio_serial_pci0', 
> 'driver': 'virtio-serial-pci', 'bus': 'pci.0', 'addr': '0x5'}, 'id': 
> 'yVkZcGgV'}
> {'execute': 'device_add', 'arguments': {'id': 'port1', 'driver': 
> 'virtserialport', 'name': 'port1', 'chardev': 'channel1', 'bus': 
> 'virtio_serial_pci0.0', 'nr': 1}, 'id': '3dXdUgJA'}
> {'execute': 'device_add', 'arguments': {'id': 'port2', 'driver': 
> 'virtserialport', 'name': 'port2', 'chardev': 'channel2', 'bus': 
> 'virtio_serial_pci0.0', 'nr': 1}, 'id': 'qLzcCkob'}
> {'execute': 'device_add', 'arguments': {'id': 'port2', 'driver': 
> 'virtserialport', 'name': 'port2', 'chardev': 'channel2', 'bus': 
> 'virtio_serial_pci0.0', 'nr': 2}, 'id': 'qLzcCkob'}
>
> The leak stack:
> Direct leak of 40 byte(s) in 1 object(s) allocated from:
> #0 0x7f04a8008ae8 in __interceptor_malloc (/lib64/libasan.so.5+0xefae8)
> #1 0x7f04a73cf1d5 in g_malloc (/lib64/libglib-2.0.so.0+0x531d5)
> #2 0x56273eaee484 in aio_bh_new /mnt/sdb/backup/qemu/util/async.c:125
> #3 0x56273eafe9a8 in qemu_bh_new /mnt/sdb/backup/qemu/util/main-loop.c:532
> #4 0x56273d52e62e in virtser_port_device_realize 
> /mnt/sdb/backup/qemu/hw/char/virtio-serial-bus.c:946
> #5 0x56273dcc5040 in device_set_realized 
> /mnt/sdb/backup/qemu/hw/core/qdev.c:891
> #6 0x56273e5ebbce in property_set_bool 
> /mnt/sdb/backup/qemu/qom/object.c:2238
> #7 0x56273e5e5a9c in object_property_set 
> /mnt/sdb/backup/qemu/qom/object.c:1324
> #8 0x56273e5ef5f8 in object_property_set_qobject 
> /mnt/sdb/backup/qemu/qom/qom-qobject.c:26
> #9 0x56273e5e5e6a in object_property_set_bool 
> /mnt/sdb/backup/qemu/qom/object.c:1390
> #10 0x56273daa40de in qdev_device_add 
> /mnt/sdb/backup/qemu/qdev-monitor.c:680
> #11 0x56273daa53e9 in qmp_device_add 
> /mnt/sdb/backup/qemu/qdev-monitor.c:805
>
> Reported-by: Euler Robot 
> Signed-off-by: Pan Nengyuan 

Fixes: 199646d81522509ac2dba6d28c31e8c7d807bc93

> ---
>  hw/char/virtio-serial-bus.c | 14 +-
>  1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
> index 941ed5aca9..563b845f71 100644
> --- a/hw/char/virtio-serial-bus.c
> +++ b/hw/char/virtio-serial-bus.c
> @@ -957,13 +957,13 @@ static void virtser_port_device_realize(DeviceState 
> *dev, Error **errp)
>  if (find_port_by_id(port->vser, port->id)) {
>  error_setg(errp, "virtio-serial-bus: A port already exists at id %u",
> port->id);
> -return;
> +goto fail;
>  }
>  
>  if (port->name != NULL && find_port_by_name(port->name)) {
>  error_setg(errp, "virtio-serial-bus: A port already exists by name 
> %s",
> port->name);
> -return;
> +goto fail;
>  }
>  
>  if (port->id == VIRTIO_CONSOLE_BAD_ID) {
> @@ -974,7 +974,7 @@ static void virtser_port_device_realize(DeviceState *dev, 
> Error **errp)
>  if (port->id == VIRTIO_CONSOLE_BAD_ID) {
>  error_setg(errp, "virtio-serial-bus: Maximum port limit for "
>   "this device reached");
> -return;
> +goto fail;
>  }
>  }
>  }
> @@ -983,16 +983,20 @@ static void virtser_port_device_realize(DeviceState 
> *dev, Error **errp)
>  if (port->id >= max_nr_ports) {
>  error_setg(errp, "virtio-serial-bus: Out-of-range port id specified, 
> "
>   "max. allowed: %u", max_nr_ports - 1);
> -return;
> +goto fail;
>  }
>  
>  vsc->realize(dev, &err);
>  if (err != NULL) {
>  error_propagate(errp, err);
> -return;
> +goto fail;
>  }
>  
>  port->elem = NULL;
> +return;
> +
> +fail:
> +qemu_bh_delete(port->bh);
>  }
>  
>  static void virtser_port_device_plug(HotplugHandler *hotplug_dev,

Looks correct to me.

However, I wonder whether we could simply create port->bh later.  It's
for use by virtio_serial_throttle_port(), called on incoming migration
via virtio_serial_load_device(), virtio_load(), virtio_device_get().  It
runs flush_queued_data(), which does nothing unless
virtio_queue_ready(port->ovq).

Note that virtio_queue_ready() dereferences its argument.  It's safe
only after virtser_port_device_plug() set port->ovq.  I'd expect that to
be possible only while the device is realized.  If that's correct, we
could simply create port->bh last in virtser_port_device_realize().




Re: [PATCH v2 00/30] Configurable policy for handling deprecated interfaces

2020-03-04 Thread Markus Armbruster
Peter Maydell  writes:

> On Wed, 4 Mar 2020 at 08:18, Markus Armbruster  wrote:
>> Peter Maydell  writes:
>> > How much do you think this is likely to affect the
>> > generate-rst-from-qapi-docs series? I'd really like
>> > that to go in for this release, but this looks like
>> > it's shaping up to be a big conflict :-(
>>
>> I paused reviewing your series to post this one, because "I'd really
>> like that to go in for this release" :)
>>
>> My series touches 21 existing commented definitions in qapi/, six more
>> in tests/qapi-schema/doc-good.json, and adds new module
>> qapi/compat.json.  Consolidated diff appended.
>>
>> Rule of thumb for reducing conflict resolution labor: the bigger manual
>> change goes first.  Yours is bigger, but I don't remember how manual it
>> is.
>
> We got pretty much all the manual changes I needed into
> master already, so all that's left really is the script parts.
> The conflicts would basically be where this series affects
> the generate-docs parts of the scripts -- any changes here
> to doc.py are basically dead-code-walking and would need
> to be done over again in the equivalent code for rust generation.
> But looking at the diffstat
>  scripts/qapi/doc.py   |  16 +-
> so hopefully it won't be too bad.

Not bad at all: two patches, both trivial for this file:

$ git-log --patch master..posted/qapi-features scripts/qapi/doc.py
commit 63daae3c1da9a7d8a189a9dfc80804c812b3f6af
Author: Markus Armbruster 
Date:   Fri Oct 18 11:23:40 2019 +0200

qapi: Consistently put @features parameter right after @ifcond

Signed-off-by: Markus Armbruster 

diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
index 36e823338b..92f584edcf 100644
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -249,8 +249,8 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor):
 texi_members(doc, 'Values',
  member_func=texi_enum_value)))
 
-def visit_object_type(self, name, info, ifcond, base, members, variants,
-  features):
+def visit_object_type(self, name, info, ifcond, features,
+  base, members, variants):
 doc = self.cur_doc
 if base and base.is_implicit():
 base = None
@@ -262,9 +262,9 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor):
 self._gen.add(texi_type('Alternate', doc, ifcond,
 texi_members(doc, 'Members')))
 
-def visit_command(self, name, info, ifcond, arg_type, ret_type, gen,
-  success_response, boxed, allow_oob, allow_preconfig,
-  features):
+def visit_command(self, name, info, ifcond, features,
+  arg_type, ret_type, gen, success_response, boxed,
+  allow_oob, allow_preconfig):
 doc = self.cur_doc
 self._gen.add(texi_msg('Command', doc, ifcond,
texi_arguments(doc,

commit 9e101e2b1803f326df46e42d88bae9f281da9fe4
Author: Markus Armbruster 
Date:   Tue Oct 15 14:33:24 2019 +0200

qapi: Add feature flags to remaining definitions

In v4.1.0, we added feature flags just to struct types (commit
6a8c0b5102^..f3ed93d545), to satisfy an immediate need (commit
c9d4070991 "file-posix: Add dynamic-auto-read-only QAPI feature").  In
v4.2.0, we added them to commands (commit 23394b4c39 "qapi: Add
feature flags to commands") to satisfy another immediate need (commit
d76744e65e "qapi: Allow introspecting fix for savevm's cooperation
with blockdev").

Add them to the remaining definitions: enumeration types, union types,
alternate types, and events.

Signed-off-by: Markus Armbruster 

diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
index 1787a53d91..36e823338b 100644
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -243,7 +243,7 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor):
 def write(self, output_dir):
 self._gen.write(output_dir)
 
-def visit_enum_type(self, name, info, ifcond, members, prefix):
+def visit_enum_type(self, name, info, ifcond, features, members, prefix):
 doc = self.cur_doc
 self._gen.add(texi_type('Enum', doc, ifcond,
 texi_members(doc, 'Values',
@@ -257,7 +257,7 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor):
 self._gen.add(texi_type('Object', doc, ifcond,
 texi_members(doc, 'Members', base, variants)))
 
-def visit_alternate_type(self, name, info, ifcond, variants):
+def visit_alternate_type(self, name, info, ifcond, features, variants):
 doc = self.cur_doc
 self._gen.add(texi_type('Alternate', doc, ifcond,
 texi_members(doc, 'Members')))
@@ -270,7 +270,7 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor):
texi_arguments(doc,

Re: [PATCH 0/2] block: bdrv_reopen() with backing file in different AioContext

2020-03-04 Thread Peter Krempa
On Thu, Feb 27, 2020 at 19:18:02 +0100, Kevin Wolf wrote:
> Kevin Wolf (2):
>   iotests: Refactor blockdev-reopen test for iothreads
>   block: bdrv_reopen() with backing file in different AioContext

Thanks for the patches. It fixes the problem we've talked about:

Tested-by: Peter Krempa 




Re: [PATCH] dp8393x: Mask EOL bit from descriptor addresses, take 2

2020-03-04 Thread Laurent Vivier
Le 04/03/2020 à 04:23, Finn Thain a écrit :
> A portion of a recent patch got lost due to a merge snafu. That patch is
> now commit 88f632fbb1 ("dp8393x: Mask EOL bit from descriptor addresses").
> This patch restores the portion that got lost.
> 
> Signed-off-by: Finn Thain 
> ---
>  hw/net/dp8393x.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> index 8a3504d962..81fc13ee9f 100644
> --- a/hw/net/dp8393x.c
> +++ b/hw/net/dp8393x.c
> @@ -525,8 +525,8 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
>   * (4 + 3 * s->regs[SONIC_TFC]),
> MEMTXATTRS_UNSPECIFIED, s->data,
> size);
> -s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0) & ~0x1;
> -if (dp8393x_get(s, width, 0) & SONIC_DESC_EOL) {
> +s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0);
> +if (s->regs[SONIC_CTDA] & SONIC_DESC_EOL) {
>  /* EOL detected */
>  break;
>  }
> 

Reviewed-by: Laurent Vivier 



Re: Best practices to handle shared objects through qemu upgrades?

2020-03-04 Thread Christian Ehrhardt
On Fri, Nov 1, 2019 at 10:34 AM Daniel P. Berrangé 
wrote:

> On Fri, Nov 01, 2019 at 08:14:08AM +0100, Christian Ehrhardt wrote:
> > Hi everyone,
> > we've got a bug report recently - on handling qemu .so's through
> > upgrades - that got me wondering how to best handle it.
> > After checking with Paolo yesterday that there is no obvious solution
> > that I missed we agreed this should be brought up on the list for
> > wider discussion.
> > Maybe there already is a good best practise out there, or if it
> > doesn't exist we might want to agree upon one going forward.
> > Let me outline the case and the ideas brought up so far.
> >
> > Case
> > - You have qemu representing a Guest
> > - Due to other constraints e.g. PT you can't live migrate (which would
> > be preferred)
> > - You haven't used a specific shared object yet - lets say RBD storage
> > driver as example
> > - Qemu gets an update, packaging replaces the .so files on disk
> > - The Qemu process and the .so files on disk now have a mismatch in
> $buildid
> > - If you hotplug an RBD device it will fail to load the (now new) .so
>
> What happens when it fails to load ?  Does the user get a graceful
> error message or does QEMU abort ? I'd hope the former.
>
> >
> > On almost any other service than "qemu representing a VM" the answer
> > is "restart it", some even re-exec in place to keep things up and
> > running.
> >
> > Ideas so far:
> > a) Modules are checked by build-id, so keep them in a per build-id dir
> on disk
> >   - qemu could be made looking preferred in -$buildid dir first
> >   - do not remove the packages with .so's on upgrades
> >   - needs a not-too-complex way to detect which buildids running qemu
> processes
> > have for packaging to be able to "autoclean later"
> >   - Needs some dependency juggling for Distro packaging but IMHO can be
> made
> > to work if above simple "probing buildid of running qemu" would exist
>
> So this needs a bunch of special QEMU hacks in package mgmt tools
> to prevent the package upgrade & cleanup later. This does not look
> like a viable strategy to me.
>
> >
> > b) Preload the modules before upgrade
> >   - One could load the .so files before upgrade
> >   - The open file reference will keep the content around even with the
> > on disk file gone
> >   - lacking a 'load-module' command that would require fake hotplugs
> > which seems wrong
> >   - Required additional upgrade pre-planning
> >   - kills most benefits of modular code without an actual need for it
> > being loaded
>
> Well there's two benefits to modular approach
>
>  - Allow a single build to be selectively installed on a host or container
>image, such that the install disk footprint is reduced
>  - Allow a faster startup such that huge RBD libraries dont slow down
>startup of VMs not using RBD disks.
>
> Preloading the modules before upgrade doesn't have to the second benefit.
> We just have to make sure the pre loading doesn't impact the VM startup
> performance.
>
> IOW, register a SIGUSR2 handler which preloads all modules it finds on
> disk. Have a pre-uninstall option on the .so package that sends SIGUSR2
> to all QEMU processes. The challenge of course is that signals are
> async. You might suggest a QMP command, but only 1 process can have the
> QMP monitor open at any time and that's libvirt. Adding a second QMP
> monitor instance is possible but kind of gross for this purpose.
>
> Another option would be to pre-load the modules during startup, but
> do it asynchronously, so that its not blocking overall VM startup.
> eg just before starting the mainloop, spawn a background thread to
> load all remaining modules.
>
> This will potentially degrade performance of the guest CPUs a bit,
> but avoids the latency spike from being synchronous in the startup
> path.
>
>
> > c) go back to non modular build
> >   - No :-)
> >
> > d) anything else out there?
>
> e) Don't do upgrades on a host with running VMs :-)
>
>Upgrades can break the running VM even ignoring this particular
>QEMU module scenario.
>
> f) Simply document that if you upgrade with running VMs that some
>features like hotplug of RBD will become unavialable. Users can
>then avoid upgrades if that matters to them.
>

Hi,
I've come back to this after a while and now think all the pre-load or
load-command Ideas we had were in vain.
They would be overly complex and need a lot of integration into different
places to trigger them.
All of that would not be well integrated in the trigger of the issue itself
which usually is a package upgrade.

But qemu already does try to load modules from different places and with a
slight extension there I think we could
provide something that packaging (the actual place knowing about upgrades)
can use to avoid this issue.

I'll reply to this thread with a patch for your consideration in a few
minutes.

There is already a Ubuntu 20.04 test build with the qemu and packaging
changes in [1].
The related Debian/Ubun

[PATCH] modules: load modules from versioned /var/run dir

2020-03-04 Thread Christian Ehrhardt
On upgrades the old .so files usually are replaced. But on the other
hand since a qemu process represents a guest instance it is usually kept
around.

That makes late addition of dynamic features e.g. 'hot-attach of a ceph
disk' fail by trying to load a new version of e.f. block-rbd.so into an
old still running qemu binary.

This adds a fallback to also load modules from a versioned directory in the
temporary /var/run path. That way qemu is providing a way for packaging
to store modules of an upgraded qemu package as needed until the next reboot.

An example how that can then be used in packaging can be seen in:
https://git.launchpad.net/~paelzer/ubuntu/+source/qemu/log/?h=bug-1847361-miss-old-so-on-upgrade-UBUNTU

Fixes: https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/1847361
Signed-off-by: Christian Ehrhardt 
---
 util/module.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/util/module.c b/util/module.c
index 236a7bb52a..d2446104be 100644
--- a/util/module.c
+++ b/util/module.c
@@ -19,6 +19,7 @@
 #endif
 #include "qemu/queue.h"
 #include "qemu/module.h"
+#include "qemu-version.h"
 
 typedef struct ModuleEntry
 {
@@ -170,6 +171,7 @@ bool module_load_one(const char *prefix, const char 
*lib_name)
 #ifdef CONFIG_MODULES
 char *fname = NULL;
 char *exec_dir;
+char *version_dir;
 const char *search_dir;
 char *dirs[4];
 char *module_name;
@@ -201,6 +203,11 @@ bool module_load_one(const char *prefix, const char 
*lib_name)
 dirs[n_dirs++] = g_strdup_printf("%s", CONFIG_QEMU_MODDIR);
 dirs[n_dirs++] = g_strdup_printf("%s/..", exec_dir ? : "");
 dirs[n_dirs++] = g_strdup_printf("%s", exec_dir ? : "");
+version_dir = g_strcanon(g_strdup(QEMU_PKGVERSION),
+ G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "+-.~",
+ '_');
+dirs[n_dirs++] = g_strdup_printf("/var/run/qemu/%s", version_dir);
+
 assert(n_dirs <= ARRAY_SIZE(dirs));
 
 g_free(exec_dir);
-- 
2.25.1




Re: [PATCH 0/2] block: bdrv_reopen() with backing file in different AioContext

2020-03-04 Thread Kevin Wolf
Am 04.03.2020 um 10:29 hat Peter Krempa geschrieben:
> On Thu, Feb 27, 2020 at 19:18:02 +0100, Kevin Wolf wrote:
> > Kevin Wolf (2):
> >   iotests: Refactor blockdev-reopen test for iothreads
> >   block: bdrv_reopen() with backing file in different AioContext
> 
> Thanks for the patches. It fixes the problem we've talked about:
> 
> Tested-by: Peter Krempa 

Thanks for testing, applied to the block branch.

Kevin




Re: [PATCH v4 2/3] linux-user/syscall: Add support for clock_gettime64/clock_settime64

2020-03-04 Thread Laurent Vivier
Le 04/03/2020 à 01:44, Alistair Francis a écrit :
> Add support for the clock_gettime64/clock_settime64 syscalls. Currently
> we only support these syscalls when running on 64-bit hosts.
> 
> Signed-off-by: Alistair Francis 
> ---
>  linux-user/syscall.c | 43 +++
>  1 file changed, 43 insertions(+)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index c000fb07c5..82468e018d 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -1236,6 +1236,22 @@ static inline abi_long target_to_host_timespec(struct 
> timespec *host_ts,
>  }
>  #endif
>  
> +#if defined(TARGET_NR_clock_settime64) && HOST_LONG_BITS == 64

Remove the "HOST_LONG_BITS == 64"

> +static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
> + abi_ulong target_addr)
> +{
> +struct target_timespec *target_ts;

Use target__kernel_timespec that uses 64bit fields.

target_timespec uses long, and on 32bit archs it's a 32bit field (and
_time64 syscalls are only available on 32bit archs).


> +
> +if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) {
> +return -TARGET_EFAULT;
> +}
> +__get_user(host_ts->tv_sec, &target_ts->tv_sec);
> +__get_user(host_ts->tv_nsec, &target_ts->tv_nsec);
> +unlock_user_struct(target_ts, target_addr, 0);
> +return 0;
> +}
> +#endif
> +
>  static inline abi_long host_to_target_timespec(abi_ulong target_addr,
> struct timespec *host_ts)
>  {
> @@ -11465,6 +11481,20 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  return ret;
>  }
>  #endif
> +#ifdef TARGET_NR_clock_settime64
> +# if HOST_LONG_BITS == 64

Remove this check ...

> +case TARGET_NR_clock_settime64:
> +{
> +struct timespec ts;
> +
> +ret = target_to_host_timespec64(&ts, arg2);

.. and if your host is 64bit or is using _time64 syscall the field of
timespec would be 64bit and clock_settime uses the _time64 syscall.
In the other case (32bit clock_settime()), the fields will be rounded
(it will work until year 2038...) :)

> +if (!is_error(ret)) {
> +ret = get_errno(clock_settime(arg1, &ts));
> +}
> +return ret;
> +}
> +# endif
> +#endif
>  #ifdef TARGET_NR_clock_gettime
>  case TARGET_NR_clock_gettime:
>  {
> @@ -11476,6 +11506,19 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  return ret;
>  }
>  #endif
> +#ifdef TARGET_NR_clock_gettime64
> +# if HOST_LONG_BITS == 64

ditto

> +case TARGET_NR_clock_gettime64:
> +{
> +struct timespec ts;
> +ret = get_errno(clock_gettime(arg1, &ts));
> +if (!is_error(ret)) {
> +ret = host_to_target_timespec64(arg2, &ts);
> +}
> +return ret;
> +}
> +# endif
> +#endif
>  #ifdef TARGET_NR_clock_getres
>  case TARGET_NR_clock_getres:
>  {
> 

Thanks,
Laurent



[PULL 1/9] tests/vm: use $(PYTHON) consistently

2020-03-04 Thread Alex Bennée
From: Robert Foley 

Change Makefile.include to use $(PYTHON) so for vm-boot-ssh to be
consistent with other cases like vm-build.

Signed-off-by: Robert Foley 
Reviewed-by: Alex Bennée 
Reviewed-by: Peter Puhov 
Signed-off-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20200219163537.22098-2-robert.fo...@linaro.org>
Message-Id: <20200303150622.20133-2-alex.ben...@linaro.org>

diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include
index 9e7c46a4735..778e5067554 100644
--- a/tests/vm/Makefile.include
+++ b/tests/vm/Makefile.include
@@ -80,7 +80,7 @@ vm-boot-serial-%: $(IMAGES_DIR)/%.img
 
 vm-boot-ssh-%: $(IMAGES_DIR)/%.img
$(call quiet-command, \
-   $(SRC_PATH)/tests/vm/$* \
+   $(PYTHON) $(SRC_PATH)/tests/vm/$* \
$(if $(J),--jobs $(J)) \
--image "$<" \
--interactive \
-- 
2.20.1




[PULL 6/9] travis: enable tools build on OS X

2020-03-04 Thread Alex Bennée
From: Laurent Vivier 

As we can build tools on OS X we should check we don't break build
when we submit new codes.

Signed-off-by: Laurent Vivier 
Signed-off-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20200302154630.45620-3-lviv...@redhat.com>
Message-Id: <20200303150622.20133-7-alex.ben...@linaro.org>

diff --git a/.travis.yml b/.travis.yml
index 9867272177d..70a24bf2fc8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -273,6 +273,7 @@ jobs:
 
 - name: "OSX Xcode 10.3"
   env:
+- BASE_CONFIG="--disable-docs --enable-tools"
 - 
CONFIG="--target-list=i386-softmmu,ppc-softmmu,ppc64-softmmu,m68k-softmmu,x86_64-softmmu"
   os: osx
   osx_image: xcode10.3
-- 
2.20.1




[PULL 0/9] testing updates (tests/vm and acceptance tweaks)

2020-03-04 Thread Alex Bennée
The following changes since commit abfa865014ab17941eb1fcb7cc2fa293a25843c4:

  Merge remote-tracking branch 
'remotes/dgilbert-gitlab/tags/pull-virtiofs-20200303' into staging (2020-03-03 
15:20:12 +)

are available in the Git repository at:

  https://github.com/stsquad/qemu.git tags/pull-testing-040320-1

for you to fetch changes up to c2e09ad8cdf4705a91eb6c20a9f3d4d90a0f46aa:

  travis.yml: install python3 numpy and opencv libraries (2020-03-04 09:57:33 
+)


Testing updates

  - some clean-ups for tests/vm
  - enable tools build for MacOSX
  - bump avocado to a newer version
  - bump travis env for avocado


Alex Bennée (3):
  configure: detect and report genisoimage
  tests/acceptance: bump avocado requirements to 76.0
  travis.yml: install python3 numpy and opencv libraries

Laurent Vivier (1):
  travis: enable tools build on OS X

Robert Foley (5):
  tests/vm: use $(PYTHON) consistently
  tests/vm: Debug mode shows ssh output.
  tests/vm: increased max timeout for vm boot.
  tests/vm: give wait_ssh() option to wait for root
  tests/vm: Added gen_cloud_init_iso() to basevm.py

 configure | 13 ++
 .travis.yml   |  6 -
 tests/requirements.txt|  2 +-
 tests/vm/Makefile.include | 16 +
 tests/vm/basevm.py| 61 ---
 tests/vm/centos   | 33 +
 tests/vm/ubuntu.i386  | 37 +---
 7 files changed, 91 insertions(+), 77 deletions(-)

-- 
2.20.1




[PULL 2/9] tests/vm: Debug mode shows ssh output.

2020-03-04 Thread Alex Bennée
From: Robert Foley 

Add changes to tests/vm/basevm.py so that during debug mode we show ssh output.

Signed-off-by: Robert Foley 
Reviewed-by: Peter Puhov 
Reviewed-by: Alex Bennée 
Signed-off-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20200219163537.22098-3-robert.fo...@linaro.org>
Message-Id: <20200303150622.20133-3-alex.ben...@linaro.org>

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 4dee6647e6e..c99725b8c0d 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -120,11 +120,16 @@ class BaseVM(object):
 return fname
 
 def _ssh_do(self, user, cmd, check):
-ssh_cmd = ["ssh", "-q", "-t",
+ssh_cmd = ["ssh",
+   "-t",
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=" + os.devnull,
"-o", "ConnectTimeout=1",
"-p", self.ssh_port, "-i", self._ssh_key_file]
+# If not in debug mode, set ssh to quiet mode to
+# avoid printing the results of commands.
+if not self.debug:
+ssh_cmd.append("-q")
 for var in self.envvars:
 ssh_cmd += ['-o', "SendEnv=%s" % var ]
 assert not isinstance(cmd, str)
-- 
2.20.1




[PULL 3/9] tests/vm: increased max timeout for vm boot.

2020-03-04 Thread Alex Bennée
From: Robert Foley 

Add change to increase timeout waiting for VM to boot.
Needed for some emulation cases where it can take longer
than 5 minutes to boot.

Signed-off-by: Robert Foley 
Reviewed-by: Alex Bennée 
Reviewed-by: Peter Puhov 
Signed-off-by: Alex Bennée 
Message-Id: <20200219163537.22098-4-robert.fo...@linaro.org>
Message-Id: <20200303150622.20133-4-alex.ben...@linaro.org>

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index c99725b8c0d..5ca445e29af 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -57,6 +57,10 @@ class BaseVM(object):
 poweroff = "poweroff"
 # enable IPv6 networking
 ipv6 = True
+# Scale up some timeouts under TCG.
+# 4 is arbitrary, but greater than 2,
+# since we found we need to wait more than twice as long.
+tcg_ssh_timeout_multiplier = 4
 def __init__(self, debug=False, vcpus=None):
 self._guest = None
 self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-",
@@ -309,6 +313,9 @@ class BaseVM(object):
 sys.stderr.write("### %s ...\n" % text)
 
 def wait_ssh(self, seconds=300):
+# Allow more time for VM to boot under TCG.
+if not kvm_available(self.arch):
+seconds *= self.tcg_ssh_timeout_multiplier
 starttime = datetime.datetime.now()
 endtime = starttime + datetime.timedelta(seconds=seconds)
 guest_up = False
-- 
2.20.1




[PULL 5/9] tests/vm: Added gen_cloud_init_iso() to basevm.py

2020-03-04 Thread Alex Bennée
From: Robert Foley 

This method was located in both centos and ubuntu.i386.

Signed-off-by: Robert Foley 
Reviewed-by: Alex Bennée 
Reviewed-by: Peter Puhov 
Signed-off-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20200219163537.22098-6-robert.fo...@linaro.org>
Message-Id: <20200303150622.20133-6-alex.ben...@linaro.org>

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 7f268922685..8400b0e07f6 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -345,6 +345,46 @@ class BaseVM(object):
 def qmp(self, *args, **kwargs):
 return self._guest.qmp(*args, **kwargs)
 
+def gen_cloud_init_iso(self):
+cidir = self._tmpdir
+mdata = open(os.path.join(cidir, "meta-data"), "w")
+name = self.name.replace(".","-")
+mdata.writelines(["instance-id: {}-vm-0\n".format(name),
+  "local-hostname: {}-guest\n".format(name)])
+mdata.close()
+udata = open(os.path.join(cidir, "user-data"), "w")
+print("guest user:pw {}:{}".format(self._config['guest_user'],
+   self._config['guest_pass']))
+udata.writelines(["#cloud-config\n",
+  "chpasswd:\n",
+  "  list: |\n",
+  "root:%s\n" % self._config['root_pass'],
+  "%s:%s\n" % (self._config['guest_user'],
+   self._config['guest_pass']),
+  "  expire: False\n",
+  "users:\n",
+  "  - name: %s\n" % self._config['guest_user'],
+  "sudo: ALL=(ALL) NOPASSWD:ALL\n",
+  "ssh-authorized-keys:\n",
+  "- %s\n" % self._config['ssh_pub_key'],
+  "  - name: root\n",
+  "ssh-authorized-keys:\n",
+  "- %s\n" % self._config['ssh_pub_key'],
+  "locale: en_US.UTF-8\n"])
+proxy = os.environ.get("http_proxy")
+if not proxy is None:
+udata.writelines(["apt:\n",
+  "  proxy: %s" % proxy])
+udata.close()
+subprocess.check_call(["genisoimage", "-output", "cloud-init.iso",
+   "-volid", "cidata", "-joliet", "-rock",
+   "user-data", "meta-data"],
+   cwd=cidir,
+   stdin=self._devnull, stdout=self._stdout,
+   stderr=self._stdout)
+
+return os.path.join(cidir, "cloud-init.iso")
+
 def parse_args(vmcls):
 
 def get_default_jobs():
diff --git a/tests/vm/centos b/tests/vm/centos
index a41ff109eb5..0ad4ecf4190 100755
--- a/tests/vm/centos
+++ b/tests/vm/centos
@@ -31,37 +31,6 @@ class CentosVM(basevm.BaseVM):
 make docker-test-mingw@fedora  {verbose} J={jobs} NETWORK=1;
 """
 
-def _gen_cloud_init_iso(self):
-cidir = self._tmpdir
-mdata = open(os.path.join(cidir, "meta-data"), "w")
-mdata.writelines(["instance-id: centos-vm-0\n",
-  "local-hostname: centos-guest\n"])
-mdata.close()
-udata = open(os.path.join(cidir, "user-data"), "w")
-udata.writelines(["#cloud-config\n",
-  "chpasswd:\n",
-  "  list: |\n",
-  "root:%s\n" % self.ROOT_PASS,
-  "%s:%s\n" % (self.GUEST_USER, self.GUEST_PASS),
-  "  expire: False\n",
-  "users:\n",
-  "  - name: %s\n" % self.GUEST_USER,
-  "sudo: ALL=(ALL) NOPASSWD:ALL\n",
-  "ssh-authorized-keys:\n",
-  "- %s\n" % basevm.SSH_PUB_KEY,
-  "  - name: root\n",
-  "ssh-authorized-keys:\n",
-  "- %s\n" % basevm.SSH_PUB_KEY,
-  "locale: en_US.UTF-8\n"])
-udata.close()
-subprocess.check_call(["genisoimage", "-output", "cloud-init.iso",
-   "-volid", "cidata", "-joliet", "-rock",
-   "user-data", "meta-data"],
-   cwd=cidir,
-   stdin=self._devnull, stdout=self._stdout,
-   stderr=self._stdout)
-return os.path.join(cidir, "cloud-init.iso")
-
 def build_image(self, img):
 cimg = 
self._download_with_cache("https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1802.qcow2.xz";)
 img_tmp = img + ".tmp"
@@ -69,7 +38,7 @@ class CentosVM(basevm.BaseVM):
 subprocess.check_call(["ln", "-f", cimg, img_tmp + ".xz"])
 subprocess.check_call(["xz", "--keep", "

[PULL 4/9] tests/vm: give wait_ssh() option to wait for root

2020-03-04 Thread Alex Bennée
From: Robert Foley 

Allow wait_ssh to wait for root user to be ready.
This solves the issue where we perform a wait_ssh()
successfully, but the root user is not yet ready
to be logged in.

Signed-off-by: Robert Foley 
Reviewed-by: Alex Bennée 
Reviewed-by: Peter Puhov 
Signed-off-by: Alex Bennée 
Message-Id: <20200219163537.22098-5-robert.fo...@linaro.org>
Message-Id: <20200303150622.20133-5-alex.ben...@linaro.org>

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 5ca445e29af..7f268922685 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -312,7 +312,7 @@ class BaseVM(object):
 def print_step(self, text):
 sys.stderr.write("### %s ...\n" % text)
 
-def wait_ssh(self, seconds=300):
+def wait_ssh(self, wait_root=False, seconds=300):
 # Allow more time for VM to boot under TCG.
 if not kvm_available(self.arch):
 seconds *= self.tcg_ssh_timeout_multiplier
@@ -320,7 +320,10 @@ class BaseVM(object):
 endtime = starttime + datetime.timedelta(seconds=seconds)
 guest_up = False
 while datetime.datetime.now() < endtime:
-if self.ssh("exit 0") == 0:
+if wait_root and self.ssh_root("exit 0") == 0:
+guest_up = True
+break
+elif self.ssh("exit 0") == 0:
 guest_up = True
 break
 seconds = (endtime - datetime.datetime.now()).total_seconds()
-- 
2.20.1




[PULL 8/9] tests/acceptance: bump avocado requirements to 76.0

2020-03-04 Thread Alex Bennée
If we want to use @skipUnless decorations on the class we need a
newer version of avocado.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Message-Id: <20200303150622.20133-9-alex.ben...@linaro.org>

diff --git a/tests/requirements.txt b/tests/requirements.txt
index a2a587223a9..f4f1736a086 100644
--- a/tests/requirements.txt
+++ b/tests/requirements.txt
@@ -1,4 +1,4 @@
 # Add Python module requirements, one per line, to be installed
 # in the tests/venv Python virtual environment. For more info,
 # refer to: https://pip.pypa.io/en/stable/user_guide/#id1
-avocado-framework==72.0
+avocado-framework==76.0
-- 
2.20.1




[PULL 7/9] configure: detect and report genisoimage

2020-03-04 Thread Alex Bennée
This is used for some of the vm-build tests so lets detect it and
behave sanely when it is not installed.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Message-Id: <20200303150622.20133-8-alex.ben...@linaro.org>

diff --git a/configure b/configure
index 7b373bc0bb8..fab6281eb70 100755
--- a/configure
+++ b/configure
@@ -936,6 +936,17 @@ do
 fi
 done
 
+# Check for ancillary tools used in testing
+genisoimage=
+for binary in genisoimage
+do
+if has $binary
+then
+genisoimage=$(command -v "$binary")
+break
+fi
+done
+
 : ${smbd=${SMBD-/usr/sbin/smbd}}
 
 # Default objcc to clang if available, otherwise use CC
@@ -6567,6 +6578,7 @@ echo "python$python ($python_version)"
 if test "$docs" != "no"; then
 echo "sphinx-build  $sphinx_build"
 fi
+echo "genisoimage   $genisoimage"
 echo "slirp support $slirp $(echo_version $slirp $slirp_version)"
 if test "$slirp" != "no" ; then
 echo "smbd  $smbd"
@@ -7616,6 +7628,7 @@ echo "INSTALL_PROG=$install -c -m 0755" >> 
$config_host_mak
 echo "INSTALL_LIB=$install -c -m 0644" >> $config_host_mak
 echo "PYTHON=$python" >> $config_host_mak
 echo "SPHINX_BUILD=$sphinx_build" >> $config_host_mak
+echo "GENISOIMAGE=$genisoimage" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
 if $iasl -h > /dev/null 2>&1; then
   echo "IASL=$iasl" >> $config_host_mak
diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include
index 778e5067554..1bf9693d195 100644
--- a/tests/vm/Makefile.include
+++ b/tests/vm/Makefile.include
@@ -2,7 +2,11 @@
 
 .PHONY: vm-build-all vm-clean-all
 
-IMAGES := ubuntu.i386 freebsd netbsd openbsd centos fedora
+IMAGES := freebsd netbsd openbsd centos fedora
+ifneq ($(GENISOIMAGE),)
+IMAGES += ubuntu.i386 centos
+endif
+
 IMAGES_DIR := $(HOME)/.cache/qemu-vm/images
 IMAGE_FILES := $(patsubst %, $(IMAGES_DIR)/%.img, $(IMAGES))
 
@@ -12,12 +16,16 @@ IMAGE_FILES := $(patsubst %, $(IMAGES_DIR)/%.img, $(IMAGES))
 vm-help vm-test:
@echo "vm-help: Test QEMU in preconfigured virtual machines"
@echo
-   @echo "  vm-build-ubuntu.i386- Build QEMU in ubuntu i386 VM"
@echo "  vm-build-freebsd- Build QEMU in FreeBSD VM"
@echo "  vm-build-netbsd - Build QEMU in NetBSD VM"
@echo "  vm-build-openbsd- Build QEMU in OpenBSD VM"
-   @echo "  vm-build-centos - Build QEMU in CentOS VM, 
with Docker"
@echo "  vm-build-fedora - Build QEMU in Fedora VM"
+ifneq ($(GENISOIMAGE),)
+   @echo "  vm-build-centos - Build QEMU in CentOS VM, 
with Docker"
+   @echo "  vm-build-ubuntu.i386- Build QEMU in ubuntu i386 VM"
+else
+   @echo "  (install genisoimage to build centos/ubuntu images)"
+endif
@echo ""
@echo "  vm-build-all- Build QEMU in all VMs"
@echo "  vm-clean-all- Clean up VM images"
-- 
2.20.1




[PATCH] python/qemu/qmp.py: QMP debug with VM label

2020-03-04 Thread Oksana Vohchana
QEMUMachine writes some messages to the default logger.
But it sometimes to hard the read the output if we have requested to
more than one VM.
This patch adds name in QMP command if it needs and labels with it in
debug mode.

Signed-off-by: Oksana Vohchana 
---
 python/qemu/machine.py | 8 
 python/qemu/qmp.py | 9 ++---
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/python/qemu/machine.py b/python/qemu/machine.py
index 183d8f3d38..060e68f06b 100644
--- a/python/qemu/machine.py
+++ b/python/qemu/machine.py
@@ -391,7 +391,7 @@ class QEMUMachine(object):
 self._qmp_set = False
 self._qmp = None
 
-def qmp(self, cmd, conv_keys=True, **args):
+def qmp(self, cmd, conv_keys=True, vm_name=None, **args):
 """
 Invoke a QMP command and return the response dict
 """
@@ -402,15 +402,15 @@ class QEMUMachine(object):
 else:
 qmp_args[key] = value
 
-return self._qmp.cmd(cmd, args=qmp_args)
+return self._qmp.cmd(cmd, args=qmp_args, vm_name=vm_name)
 
-def command(self, cmd, conv_keys=True, **args):
+def command(self, cmd, conv_keys=True, vm_name=None, **args):
 """
 Invoke a QMP command.
 On success return the response dict.
 On failure raise an exception.
 """
-reply = self.qmp(cmd, conv_keys, **args)
+reply = self.qmp(cmd, conv_keys, vm_name, **args)
 if reply is None:
 raise qmp.QMPError("Monitor is closed")
 if "error" in reply:
diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py
index f40586eedd..96b455b53f 100644
--- a/python/qemu/qmp.py
+++ b/python/qemu/qmp.py
@@ -180,11 +180,12 @@ class QEMUMonitorProtocol:
 self.__sockfile = self.__sock.makefile()
 return self.__negotiate_capabilities()
 
-def cmd_obj(self, qmp_cmd):
+def cmd_obj(self, qmp_cmd, vm_name=None):
 """
 Send a QMP command to the QMP Monitor.
 
 @param qmp_cmd: QMP command to be sent as a Python dict
+@param vm_name: name for the virtual machine (string)
 @return QMP response as a Python dict or None if the connection has
 been closed
 """
@@ -196,10 +197,12 @@ class QEMUMonitorProtocol:
 return None
 raise err
 resp = self.__json_read()
+if vm_name:
+self.logger.debug("<<< {'vm_name' : %s }",  vm_name)
 self.logger.debug("<<< %s", resp)
 return resp
 
-def cmd(self, name, args=None, cmd_id=None):
+def cmd(self, name, args=None, cmd_id=None, vm_name=None):
 """
 Build a QMP command and send it to the QMP Monitor.
 
@@ -212,7 +215,7 @@ class QEMUMonitorProtocol:
 qmp_cmd['arguments'] = args
 if cmd_id:
 qmp_cmd['id'] = cmd_id
-return self.cmd_obj(qmp_cmd)
+return self.cmd_obj(qmp_cmd, vm_name)
 
 def command(self, cmd, **kwds):
 """
-- 
2.21.1




[PULL 9/9] travis.yml: install python3 numpy and opencv libraries

2020-03-04 Thread Alex Bennée
These are used for the acceptance framebuffer tests to count Tux. As
we need slightly newer python3 for opencv we bump up to bionic.

Signed-off-by: Alex Bennée 

Message-Id: <20200303150622.20133-10-alex.ben...@linaro.org>

diff --git a/.travis.yml b/.travis.yml
index 70a24bf2fc8..b92798ac3b9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -313,6 +313,7 @@ jobs:
 
 # Acceptance (Functional) tests
 - name: "GCC check-acceptance"
+  dist: bionic
   env:
 - 
CONFIG="--target-list=aarch64-softmmu,alpha-softmmu,arm-softmmu,m68k-softmmu,microblaze-softmmu,mips-softmmu,mips64el-softmmu,nios2-softmmu,or1k-softmmu,ppc-softmmu,ppc64-softmmu,s390x-softmmu,sparc-softmmu,x86_64-softmmu,xtensa-softmmu"
 - TEST_CMD="make check-acceptance"
@@ -323,7 +324,9 @@ jobs:
   packages:
 - python3-pil
 - python3-pip
-- python3.5-venv
+- python3-numpy
+- python3-opencv
+- python3-venv
 - rpm2cpio
 - tesseract-ocr
 - tesseract-ocr-eng
-- 
2.20.1




Re: [PATCH v5 14/50] mutli-process: build remote command line args

2020-03-04 Thread Dr. David Alan Gilbert
* Jagannathan Raman (jag.ra...@oracle.com) wrote:
> From: Elena Ufimtseva 
> 
> Signed-off-by: Elena Ufimtseva 
> Signed-off-by: Jagannathan Raman 
> Signed-off-by: John G Johnson 
> ---
>  v4 -> v5:
>   - Added "exec" suboption to get the executable's name
>   - Addressed feedback about variable names
>   - Removed redundant check for spawning a process
> 
>  hw/proxy/qemu-proxy.c | 68 
> +--
>  include/hw/proxy/qemu-proxy.h |  2 +-
>  2 files changed, 54 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
> index 828bbd7..d792e86 100644
> --- a/hw/proxy/qemu-proxy.c
> +++ b/hw/proxy/qemu-proxy.c
> @@ -19,19 +19,50 @@
>  
>  static void pci_proxy_dev_realize(PCIDevice *dev, Error **errp);
>  
> +static int add_argv(char *opts_str, char **argv, int argc)
> +{
> +int max_args = 64;

...

> +
> +static int make_argv(char *opts_str, char **argv, int argc)
> +{
> +int max_args = 64;

.

> +
>  static int remote_spawn(PCIProxyDev *pdev, const char *opts,
>  const char *exec_name, Error **errp)
>  {
> -char *args[3];
>  pid_t rpid;
>  int fd[2] = {-1, -1};
>  Error *local_error = NULL;
> +char *argv[64];


Magic '64' in a lot of places; that should be one constant somewhere
(if it's actually needed).

Dave


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




Re: [PATCH v5 12/50] multi-process: remote process initialization

2020-03-04 Thread Dr. David Alan Gilbert
* Jagannathan Raman (jag.ra...@oracle.com) wrote:
> Adds the handler to process message from QEMU,
> Initialize remote process main loop, handles SYNC_SYSMEM
> message by updating its "system_memory" container using
> shared file descriptors received from QEMU.
> 
> Signed-off-by: John G Johnson 
> Signed-off-by: Elena Ufimtseva 
> Signed-off-by: Jagannathan Raman 
> ---
>  v4 -> v5:
>   - We checked if we could use functions already defined in
> util/main-loop.c instead of using g_main_loop_run. However,
> we couldn't find a suitable function that's generic enough
> to do this. All of them have emulator code embedded in them
> which is not used by the remote process. We are therefore
> not making any change to this patch
> 
>  remote/remote-main.c | 85 
> 
>  1 file changed, 85 insertions(+)
> 
> diff --git a/remote/remote-main.c b/remote/remote-main.c
> index ecf30e0..56315cd 100644
> --- a/remote/remote-main.c
> +++ b/remote/remote-main.c
> @@ -12,6 +12,7 @@
>  #include "qemu-common.h"
>  
>  #include 
> +#include 
>  
>  #include "qemu/module.h"
>  #include "remote/pcihost.h"
> @@ -19,12 +20,96 @@
>  #include "hw/boards.h"
>  #include "hw/qdev-core.h"
>  #include "qemu/main-loop.h"
> +#include "remote/memory.h"
> +#include "io/mpqemu-link.h"
> +#include "qapi/error.h"
> +#include "qemu/main-loop.h"
> +#include "sysemu/cpus.h"
> +#include "qemu-common.h"
> +#include "hw/pci/pci.h"
> +#include "qemu/thread.h"
> +#include "qemu/main-loop.h"
> +#include "qemu/config-file.h"
> +#include "sysemu/sysemu.h"
> +#include "block/block.h"
> +#include "exec/ramlist.h"
> +
> +static MPQemuLinkState *mpqemu_link;
> +PCIDevice *remote_pci_dev;
> +
> +static void process_msg(GIOCondition cond, MPQemuChannel *chan)
> +{
> +MPQemuMsg *msg = NULL;
> +Error *err = NULL;
> +
> +if ((cond & G_IO_HUP) || (cond & G_IO_ERR)) {
> +goto finalize_loop;
> +}
> +
> +msg = g_malloc0(sizeof(MPQemuMsg));
> +
> +if (mpqemu_msg_recv(msg, chan) < 0) {
> +error_setg(&err, "Failed to receive message");

Please give error messages more context, e.g. the device or process name
or something like that so that; it helps when we get a user
reporting a crash and they report 'Unknown command' in their log, but
then we have to figure out where to point them.

> +goto finalize_loop;
> +}
> +
> +switch (msg->cmd) {
> +case INIT:
> +break;
> +case PCI_CONFIG_WRITE:
> +break;
> +case PCI_CONFIG_READ:
> +break;
> +default:
> +error_setg(&err, "Unknown command");
> +goto finalize_loop;
> +}
> +
> +g_free(msg->data2);
> +g_free(msg);
> +
> +return;
> +
> +finalize_loop:
> +if (err) {
> +error_report_err(err);
> +}
> +g_free(msg);
> +mpqemu_link_finalize(mpqemu_link);
> +mpqemu_link = NULL;
> +}
>  
>  int main(int argc, char *argv[])
>  {
> +Error *err = NULL;
> +
>  module_call_init(MODULE_INIT_QOM);
>  
> +bdrv_init_with_whitelist();
> +
> +if (qemu_init_main_loop(&err)) {
> +error_report_err(err);
> +return -EBUSY;
> +}
> +
> +qemu_init_cpu_loop();
> +
> +page_size_init();
> +
> +qemu_mutex_init(&ram_list.mutex);
> +

So these are some subset of the things from qemu_init; I guess
we'll have to be careful when we add stuff to vl.c to think what should
also be added here.

Dave

>  current_machine = 
> MACHINE(REMOTE_MACHINE(object_new(TYPE_REMOTE_MACHINE)));
>  
> +mpqemu_link = mpqemu_link_create();
> +if (!mpqemu_link) {
> +printf("Could not create MPQemu link\n");
> +return -1;
> +}
> +
> +mpqemu_init_channel(mpqemu_link, &mpqemu_link->com, STDIN_FILENO);
> +mpqemu_link_set_callback(mpqemu_link, process_msg);
> +
> +mpqemu_start_coms(mpqemu_link);
> +
>  return 0;
>  }
> -- 
> 1.8.3.1
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH v6 18/18] docs: add Orange Pi PC document

2020-03-04 Thread Alex Bennée


Niek Linnenbank  writes:

> The Xunlong Orange Pi PC machine is a functional ARM machine
> based on the Allwinner H3 System-on-Chip. It supports mainline
> Linux, U-Boot, NetBSD and is covered by acceptance tests.
>
> This commit adds a documentation text file with a description
> of the machine and instructions for the user.

This is great, thanks for taking the time to include documentation.

>
> Signed-off-by: Niek Linnenbank 
> ---
>  docs/orangepi.rst | 226
> ++

I suspect there is a better place to put this is than the top level. I
wonder if it should be docs/specs?

>  MAINTAINERS   |   1 +
>  2 files changed, 227 insertions(+)
>  create mode 100644 docs/orangepi.rst
>
> diff --git a/docs/orangepi.rst b/docs/orangepi.rst
> new file mode 100644
> index 00..a9b46f553c
> --- /dev/null
> +++ b/docs/orangepi.rst
> @@ -0,0 +1,226 @@
> +=
> +Orange Pi PC Machine Type
> +=
> +
> +The Xunlong Orange Pi PC is an Allwinner H3 System on Chip
> +based embedded computer with mainline support in both U-Boot
> +and Linux. The board comes with a Quad Core Cortex A7 @ 1.3GHz,
> +1GiB RAM, 100Mbit ethernet, USB, SD/MMC, USB, HDMI and
> +various other I/O.

When Peter's document PR goes in later this week there will also be a:

  docs/system/target-arm.rst

which would benefit from a section for the Orange Pi in it.

> +
> +Supported devices
> +-
> +
> +The Orange Pi PC machine supports the following devices:
> +
> + * SMP (Quad Core Cortex A7)
> + * Generic Interrupt Controller configuration
> + * SRAM mappings
> + * SDRAM controller
> + * Real Time Clock
> + * Timer device (re-used from Allwinner A10)
> + * UART
> + * SD/MMC storage controller
> + * EMAC ethernet

Do we ever exercise the ethernet in the acceptance tests? I see we have
some that boots a full OS but boot console only seems to touch the
serial console.



-- 
Alex Bennée



Re: [PATCH v5 15/50] multi-process: PCI BAR read/write handling for proxy & remote endpoints

2020-03-04 Thread Dr. David Alan Gilbert
* Jagannathan Raman (jag.ra...@oracle.com) wrote:
> Proxy device object implements handler for PCI BAR writes and reads. The 
> handler
> uses BAR_WRITE/BAR_READ message to communicate to the remote process with the 
> BAR address and
> value to be written/read.
> The remote process implements handler for BAR_WRITE/BAR_READ message.
> 
> Signed-off-by: Jagannathan Raman 
> Signed-off-by: Elena Ufimtseva 
> Signed-off-by: John G Johnson 
> ---
>  hw/proxy/qemu-proxy.c | 65 ++
>  include/hw/proxy/qemu-proxy.h | 22 +++--
>  include/io/mpqemu-link.h  | 12 +++
>  remote/remote-main.c  | 73 
> +++
>  4 files changed, 170 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
> index d792e86..b17d9bb 100644
> --- a/hw/proxy/qemu-proxy.c
> +++ b/hw/proxy/qemu-proxy.c
> @@ -262,3 +262,68 @@ static void pci_proxy_dev_realize(PCIDevice *device, 
> Error **errp)
>  dev->get_proxy_sock = get_proxy_sock;
>  dev->init_proxy = init_proxy;
>  }
> +
> +static void send_bar_access_msg(PCIProxyDev *dev, MemoryRegion *mr,
> +bool write, hwaddr addr, uint64_t *val,
> +unsigned size, bool memory)
> +{
> +MPQemuLinkState *mpqemu_link = dev->mpqemu_link;
> +MPQemuMsg msg;
> +int wait;
> +
> +memset(&msg, 0, sizeof(MPQemuMsg));
> +
> +msg.bytestream = 0;
> +msg.size = sizeof(msg.data1);
> +msg.data1.bar_access.addr = mr->addr + addr;
> +msg.data1.bar_access.size = size;
> +msg.data1.bar_access.memory = memory;
> +
> +if (write) {
> +msg.cmd = BAR_WRITE;
> +msg.data1.bar_access.val = *val;
> +} else {
> +wait = GET_REMOTE_WAIT;
> +
> +msg.cmd = BAR_READ;
> +msg.num_fds = 1;
> +msg.fds[0] = wait;
> +}
> +
> +mpqemu_msg_send(&msg, mpqemu_link->com);
> +
> +if (!write) {
> +*val = wait_for_remote(wait);
> +PUT_REMOTE_WAIT(wait);
> +}
> +}
> +
> +void proxy_default_bar_write(void *opaque, hwaddr addr, uint64_t val,
> + unsigned size)
> +{
> +ProxyMemoryRegion *pmr = opaque;
> +
> +send_bar_access_msg(pmr->dev, &pmr->mr, true, addr, &val, size,
> +pmr->memory);
> +}
> +
> +uint64_t proxy_default_bar_read(void *opaque, hwaddr addr, unsigned size)
> +{
> +ProxyMemoryRegion *pmr = opaque;
> +uint64_t val;
> +
> +send_bar_access_msg(pmr->dev, &pmr->mr, false, addr, &val, size,
> +pmr->memory);
> +
> + return val;
> +}
> +
> +const MemoryRegionOps proxy_default_ops = {
> +.read = proxy_default_bar_read,
> +.write = proxy_default_bar_write,
> +.endianness = DEVICE_NATIVE_ENDIAN,
> +.impl = {
> +.min_access_size = 1,
> +.max_access_size = 1,
> +},
> +};
> diff --git a/include/hw/proxy/qemu-proxy.h b/include/hw/proxy/qemu-proxy.h
> index 29fa2e9..44e370e 100644
> --- a/include/hw/proxy/qemu-proxy.h
> +++ b/include/hw/proxy/qemu-proxy.h
> @@ -22,7 +22,19 @@
>  #define PCI_PROXY_DEV_GET_CLASS(obj) \
>  OBJECT_GET_CLASS(PCIProxyDevClass, (obj), TYPE_PCI_PROXY_DEV)
>  
> -typedef struct PCIProxyDev {
> +typedef struct PCIProxyDev PCIProxyDev;
> +
> +typedef struct ProxyMemoryRegion {
> +PCIProxyDev *dev;
> +MemoryRegion mr;
> +bool memory;
> +bool present;
> +uint8_t type;
> +} ProxyMemoryRegion;
> +
> +extern const MemoryRegionOps proxy_default_ops;
> +
> +struct PCIProxyDev {
>  PCIDevice parent_dev;
>  
>  MPQemuLinkState *mpqemu_link;
> @@ -41,7 +53,8 @@ typedef struct PCIProxyDev {
>  void (*init_proxy) (PCIDevice *dev, char *command, char *exec_name,
>  bool need_spawn, Error **errp);
>  
> -} PCIProxyDev;
> +ProxyMemoryRegion region[PCI_NUM_REGIONS];
> +};
>  
>  typedef struct PCIProxyDevClass {
>  PCIDeviceClass parent_class;
> @@ -51,4 +64,9 @@ typedef struct PCIProxyDevClass {
>  char *command;
>  } PCIProxyDevClass;
>  
> +void proxy_default_bar_write(void *opaque, hwaddr addr, uint64_t val,
> + unsigned size);
> +
> +uint64_t proxy_default_bar_read(void *opaque, hwaddr addr, unsigned size);
> +
>  #endif /* QEMU_PROXY_H */
> diff --git a/include/io/mpqemu-link.h b/include/io/mpqemu-link.h
> index 5a2be48..1a7738e 100644
> --- a/include/io/mpqemu-link.h
> +++ b/include/io/mpqemu-link.h
> @@ -38,6 +38,8 @@
>   * PCI_CONFIG_READPCI configuration space read
>   * PCI_CONFIG_WRITE   PCI configuration space write
>   * SYNC_SYSMEM  Shares QEMU's RAM with remote device's RAM
> + * BAR_WRITEWrites to PCI BAR region
> + * BAR_READ Reads from PCI BAR region
>   *
>   * proc_cmd_t enum type to specify the command to be executed on the remote
>   * device.
> @@ -47,6 +49,8 @@ typedef enum {
>  PCI_CONFIG_READ,
>  PCI_CONFIG_WRITE,
> 

Re: [PATCH v5 14/50] mutli-process: build remote command line args

2020-03-04 Thread Daniel P . Berrangé
On Mon, Mar 02, 2020 at 02:39:37PM -0800, Elena Ufimtseva wrote:
> On Mon, Mar 02, 2020 at 05:47:45PM +, Daniel P. Berrangé wrote:
> > On Mon, Mar 02, 2020 at 06:36:13PM +0100, Philippe Mathieu-Daudé wrote:
> > > typo "multi" in patch subject.
> > >
> Thank Philippe, will fix.
>  
> > > On 2/24/20 9:55 PM, Jagannathan Raman wrote:
> > > > From: Elena Ufimtseva 
> > > > 
> > > > Signed-off-by: Elena Ufimtseva 
> > > > Signed-off-by: Jagannathan Raman 
> > > > Signed-off-by: John G Johnson 
> > > > ---
> > > >   v4 -> v5:
> > > >- Added "exec" suboption to get the executable's name
> > > >- Addressed feedback about variable names
> > > >- Removed redundant check for spawning a process
> > > > 
> > > >   hw/proxy/qemu-proxy.c | 68 
> > > > +--
> > > >   include/hw/proxy/qemu-proxy.h |  2 +-
> > > >   2 files changed, 54 insertions(+), 16 deletions(-)
> > > > 
> > > > diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
> > > > index 828bbd7..d792e86 100644
> > > > --- a/hw/proxy/qemu-proxy.c
> > > > +++ b/hw/proxy/qemu-proxy.c
> > > > @@ -19,19 +19,50 @@
> > > >   static void pci_proxy_dev_realize(PCIDevice *dev, Error **errp);
> > > > +static int add_argv(char *opts_str, char **argv, int argc)
> > > > +{
> > > > +int max_args = 64;
> > > > +
> > > > +if (argc < max_args - 1) {
> > > > +argv[argc++] = opts_str;
> > > > +argv[argc] = 0;
> > > > +} else {
> > > > +return 0;
> > > > +}
> > > > +
> > > > +return argc;
> > > > +}
> > > > +
> > > > +static int make_argv(char *opts_str, char **argv, int argc)
> > > > +{
> > > > +int max_args = 64;
> > > > +
> > > > +char *p2 = strtok(opts_str, " ");
> > > > +while (p2 && argc < max_args - 1) {
> > > > +argv[argc++] = p2;
> > > > +p2 = strtok(0, " ");
> > > > +}
> > > > +argv[argc] = 0;
> > > 
> > > Is there a GLib function to do that?
> >
> 
> Hi Daniel
> 
> > g_shell_parse_argv() perhaps
> >
> 
> Thanks for the suggestion.
> 
> >   https://developer.gnome.org/glib/stable/glib-Shell-related-Utilities.html
> > 
> > 
> > Though my preference would be to avoid the need to do this at all, by
> > not accepting a raw shell command line string in the first place.
> >
> Can you please clarify? Did you mean that it would be better if Qemu somehow
> verifies the options and then passes it to a remote process via a message?

I've not been able to trace the code paths back all the way, so I can't
point to where I think needs fixing. I assuming that something, somewhere
in this patch series should starts out with a binary name and a list of argv
as an array of char *. ie a "char **argv".  At some point this array gets
mashed together into a single 'char *' string where all the argv are separated
by a space. This patch now tries to parse this and turn it back into a
"char **argv" array.

So my key point is that we should try hard to avoid this intermediate
shell command line string stage entirely. Always keep the argv in an array
form, and never mash them together such that they then need parsing again.

I understand this is probably more complex, because we're having to pass
this across processes, via QemuOpts IIUC, but I still believe it is important
to have this data kept in array format if at all practical.

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: [PATCH v6 1/9] iotests: do a light delinting

2020-03-04 Thread Kevin Wolf
Am 03.03.2020 um 22:25 hat John Snow geschrieben:
> 
> 
> On 2/27/20 7:59 AM, Max Reitz wrote:
> > On 27.02.20 01:06, John Snow wrote:
> >> This doesn't fix everything in here, but it does help clean up the
> >> pylint report considerably.
> >>
> >> This should be 100% style changes only; the intent is to make pylint
> >> more useful by working on establishing a baseline for iotests that we
> >> can gate against in the future. This will be important if (when?) we
> >> begin adding type hints to our code base.

I'm not sure I understand this connection. mypy doesn't care about
style.

> >> Signed-off-by: John Snow 
> >> ---
> >>  tests/qemu-iotests/iotests.py | 88 ++-
> >>  1 file changed, 45 insertions(+), 43 deletions(-)
> > 
> > I feel like I’m the wrongest person there is for reviewing a Python
> > style-fixing patch, but here I am and so here I go:
> 
> No, it's good.

Max can't be the wrongest person for it because that's already me.

> >> diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
> >> index 8815052eb5..e8a0ea14fc 100644
> >> --- a/tests/qemu-iotests/iotests.py
> >> +++ b/tests/qemu-iotests/iotests.py
> > 
> > [...]
> > 
> >> @@ -245,8 +243,7 @@ def qemu_nbd_early_pipe(*args):
> >>' '.join(qemu_nbd_args + ['--fork'] + 
> >> list(args
> >>  if exitcode == 0:
> >>  return exitcode, ''
> >> -else:
> >> -return exitcode, subp.communicate()[0]
> >> +return exitcode, subp.communicate()[0]
> > 
> > If we want to make such a change (which I don’t doubt we want), I think
> > it should be the other way around: Make the condition “exitcode != 0”,
> > so the final return is the return for the successful case.  (Just
> > because I think that’s how we usually do it, at least in the qemu code?)
> > 
> > [...]
> > 
> 
> Yes, makes sense. I was behaving a little more mechanically.

Here and...

> >> @@ -756,12 +750,13 @@ def assert_block_path(self, root, path, 
> >> expected_node, graph=None):
> >>  assert node is not None, 'Cannot follow path %s%s' % (root, 
> >> path)
> >>  
> >>  try:
> >> -node_id = next(edge['child'] for edge in graph['edges'] \
> >> - if edge['parent'] == 
> >> node['id'] and
> >> -edge['name'] == 
> >> child_name)
> >> +node_id = next(edge['child'] for edge in graph['edges']
> >> +   if edge['parent'] == node['id'] and
> >> +   edge['name'] == child_name)
> > 
> > I don’t mind the if alignment, but I do mind not aligning the third line
> > to the “edge” above it (i.e. the third line is part of the condition, so
> > I’d align it to the “if” condition).
> > 
> > But then again it’s nothing new that I like to disagree with commonly
> > agreed-upon Python coding styles, so.
> > 
> > [...]
> > 
> 
> OK, that can be addressed by highlighting the sub-expression with
> parentheses:
> 
> node_id = next(edge['child'] for edge in graph['edges']
>if (edge['parent'] == node['id'] and
>edge['name'] == child_name))

...here I must say that while I think Max's suggestions feel like an
improvement to me over the patch, I actually like the current code best
in both cases.

In fact, after scanning your patch, I feel it's actually the majority of
changes that pylint wants that aren't an improvement... Maybe this just
underlines the fact that I am the wrongest person to review such patches
and not Max. Though I'm surprised that I'm generally not the person who
introduces the code violating the rules, and I don't have the impression
in this thread that anyone is eager to defend pylint's opinion.

Now I ran pylint myself and it prints some even more ridiculous warnings
like variable names being too short for its liking. I guess this means
that if we want to run it without warnings or errors, we need to use a
config file anyway to disable the worst parts.

And if we have a config file anyway, maybe we can more selectively
enable the checks that we actually want?

Kevin




Re: [PATCH 0/2] misc: Replace zero-length arrays with flexible array member

2020-03-04 Thread Paolo Bonzini
On 04/03/20 01:51, Philippe Mathieu-Daudé wrote:
> This is a tree-wide cleanup inspired by a Linux kernel commit
> (from Gustavo A. R. Silva).
> 
> --v-- description start --v--
> 
>   The current codebase makes use of the zero-length array language
>   extension to the C90 standard, but the preferred mechanism to
>   declare variable-length types such as these ones is a flexible
>   array member [1], introduced in C99:
> 
>   struct foo {
>   int stuff;
>   struct boo array[];
>   };
> 
>   By making use of the mechanism above, we will get a compiler
>   warning in case the flexible array does not occur last in the
>   structure, which will help us prevent some kind of undefined
>   behavior bugs from being unadvertenly introduced [2] to the
>   Linux codebase from now on.
> 
> --^-- description end --^--
> 
> Do the similar housekeeping in the QEMU codebase (which uses
> C99 since commit 7be41675f7cb).
> 
> The first patch is done with the help of a coccinelle semantic
> patch. However Coccinelle does not recognize:
> 
>   struct foo {
>   int stuff;
>   struct boo array[];
>   } QEMU_PACKED;
> 
> but does recognize:
> 
>   struct QEMU_PACKED foo {
>   int stuff;
>   struct boo array[];
>   };
> 
> I'm not sure why, neither it is worth refactoring all QEMU
> structures to use the attributes before the structure name,
> so I did the 2nd patch manually.
> 
> Anyway this is annoying, because many structures are not handled
> by coccinelle. Maybe this needs to be reported to upstream
> coccinelle?
> 
> I used spatch 1.0.8 with:
> 
>   -I include --include-headers \
>   --macro-file scripts/cocci-macro-file.h \
>   --keep-comments --indent 4
> 
> Regards,
> 
> Phil.
> 
> Philippe Mathieu-Daudé (2):
>   misc: Replace zero-length arrays with flexible array member
> (automatic)
>   misc: Replace zero-length arrays with flexible array member (manual)
> 
>  docs/interop/vhost-user.rst   |  4 ++--
>  block/qed.h   |  2 +-
>  bsd-user/qemu.h   |  2 +-
>  contrib/libvhost-user/libvhost-user.h |  2 +-
>  hw/m68k/bootinfo.h|  2 +-
>  hw/scsi/srp.h |  6 +++---
>  hw/xen/xen_pt.h   |  2 +-
>  include/hw/acpi/acpi-defs.h   | 16 
>  include/hw/arm/smmu-common.h  |  2 +-
>  include/hw/boards.h   |  2 +-
>  include/hw/i386/intel_iommu.h |  3 ++-
>  include/hw/s390x/event-facility.h |  2 +-
>  include/hw/s390x/sclp.h   |  8 
>  include/hw/virtio/virtio-iommu.h  |  2 +-
>  include/sysemu/cryptodev.h|  2 +-
>  include/tcg/tcg.h |  2 +-
>  pc-bios/s390-ccw/bootmap.h|  2 +-
>  pc-bios/s390-ccw/sclp.h   |  2 +-
>  tests/qtest/libqos/ahci.h |  2 +-
>  block/linux-aio.c |  2 +-
>  block/vmdk.c  |  2 +-
>  hw/acpi/nvdimm.c  |  6 +++---
>  hw/char/sclpconsole-lm.c  |  2 +-
>  hw/char/sclpconsole.c |  2 +-
>  hw/dma/soc_dma.c  |  2 +-
>  hw/i386/x86.c |  2 +-
>  hw/misc/omap_l4.c |  2 +-
>  hw/nvram/eeprom93xx.c |  2 +-
>  hw/rdma/vmw/pvrdma_qp_ops.c   |  4 ++--
>  hw/s390x/virtio-ccw.c |  2 +-
>  hw/usb/dev-network.c  |  2 +-
>  hw/usb/dev-smartcard-reader.c |  4 ++--
>  hw/virtio/virtio.c|  4 ++--
>  net/queue.c   |  2 +-
>  target/s390x/ioinst.c |  2 +-
>  35 files changed, 54 insertions(+), 53 deletions(-)
> 

Queued (minus the qed part).

Paolo




Re: New Hardware model emulation

2020-03-04 Thread Priyamvad Acharya
Hi,
I have commented all the lines of other hardware models except custom
device line *" common-obj-$(CONFIG_TESTPCI) += testpci.o "*.
But when I run *make* I get errors  similar to error shown in file which I
have shared with you in previous replies.

Thanks,
Priyamvad

On Wed, 4 Mar 2020 at 02:05, Stefan Hajnoczi  wrote:

> On Tue, Mar 3, 2020 at 5:12 PM Priyamvad Acharya
>  wrote:
> > > These errors are probably due to the Makefile.objs changes in your
> commit:
> >
> > If I am not wrong, we need to add a rule i.e "
> common-obj-$(CONFIG_TESTPCI) += testpci.o " in Makefile.objs to compile
> custom device in Qemu.
> > Shall I should remove that rule to remove the errors?
>
> No, keep that line.  All the other changes to Makefile.objs in that
> commit seem spurious though and should be removed.
>
> Stefan
>


Re: New Hardware model emulation

2020-03-04 Thread Stefan Hajnoczi
On Wed, Mar 4, 2020 at 11:16 AM Priyamvad Acharya
 wrote:
> I have commented all the lines of other hardware models except custom device 
> line " common-obj-$(CONFIG_TESTPCI) += testpci.o ".
> But when I run make I get errors  similar to error shown in file which I have 
> shared with you in previous replies.

Try this:
1. Start with a fresh qemu.git tree (no modifications) and check that
it compiles successfully.
2. Add testpci.c and add the testpci.o line to Makefile.objs.
3. Compilation should succeed now.

Stefan



Re: New Hardware model emulation

2020-03-04 Thread Priyamvad Acharya
 > I have commented all the lines of other hardware models except custom
device line *" common-obj-$(CONFIG_TESTPCI) += testpci.o "*.
> But when I run *make* I get errors  similar to error shown in file which
I have shared with you in previous replies.
Above custom device I am building for Qemu ARM(32 bit architecture)

When I tried building  custom devicefor Qemu RISCV(32 bit architecture),
*make* get successfully executed and I get my custom device *.o and .d *files
in build/hw/misc directory.

I think there might be some problems with missing libraries for ARM
architecture ?




On Wed, 4 Mar 2020 at 16:45, Priyamvad Acharya 
wrote:

> Hi,
> I have commented all the lines of other hardware models except custom
> device line *" common-obj-$(CONFIG_TESTPCI) += testpci.o "*.
> But when I run *make* I get errors  similar to error shown in file which
> I have shared with you in previous replies.
>
> Thanks,
> Priyamvad
>
> On Wed, 4 Mar 2020 at 02:05, Stefan Hajnoczi  wrote:
>
>> On Tue, Mar 3, 2020 at 5:12 PM Priyamvad Acharya
>>  wrote:
>> > > These errors are probably due to the Makefile.objs changes in your
>> commit:
>> >
>> > If I am not wrong, we need to add a rule i.e "
>> common-obj-$(CONFIG_TESTPCI) += testpci.o " in Makefile.objs to compile
>> custom device in Qemu.
>> > Shall I should remove that rule to remove the errors?
>>
>> No, keep that line.  All the other changes to Makefile.objs in that
>> commit seem spurious though and should be removed.
>>
>> Stefan
>>
>


Re: [PATCH v4 5/5] iotests: 287: add qcow2 compression type test

2020-03-04 Thread Vladimir Sementsov-Ogievskiy

03.03.2020 16:34, Denis Plotnikov wrote:

The test checks fulfilling qcow2 requiriements for the compression
type feature and zstd compression type operability.

Signed-off-by: Denis Plotnikov 
---
  tests/qemu-iotests/287 | 127 +
  tests/qemu-iotests/287.out |  43 +
  tests/qemu-iotests/group   |   1 +
  3 files changed, 171 insertions(+)
  create mode 100755 tests/qemu-iotests/287
  create mode 100644 tests/qemu-iotests/287.out

diff --git a/tests/qemu-iotests/287 b/tests/qemu-iotests/287
new file mode 100755
index 00..39cb665c85
--- /dev/null
+++ b/tests/qemu-iotests/287


[..]


+# Test: using zstd compression, write to and read from an image
+echo
+echo "=== Testing reading and writing with zstd ==="
+echo
+
+CLUSTER_SIZE=65536
+IMGOPTS='compression_type=zstd' _make_test_img 64M


As I understand, you should define env variable assignments on the same line
with _make_test_img so that they be passed to it, like
CLUSTER_SIZE=65536 IMGOPTS='compression_type=zstd' _make_test_img 64M

with this:
Reviewed-by: Vladimir Sementsov-Ogievskiy 


+$QEMU_IO -c "write -c -P 0xAC 65536 64k " "$TEST_IMG" | _filter_qemu_io


you may s/65536/64k/


+$QEMU_IO -c "read -P 0xAC 65536 65536 " "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -v 131070 8 " "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -v 65534 8" "$TEST_IMG" | _filter_qemu_io
+



[..]


--
Best regards,
Vladimir



[PATCH v6 00/18] s390x: Protected Virtualization support

2020-03-04 Thread Janosch Frank
Most of the QEMU changes for PV are related to the new IPL type with
subcodes 8 - 10 and the execution of the necessary Ultravisor calls to
IPL secure guests. Note that we can only boot into secure mode from
normal mode, i.e. stfle 161 is not active in secure mode.

The other changes related to data gathering for emulation and
disabling addressing checks in secure mode, as well as CPU resets.

v6:
* diag308 rc numbers were changed by architecture
* IPL pv block received one more reserved field by architecture
* Officially added the bios patch to the series
* Dropped picked constant rename patch

v5:
* Moved docs into docs/system
* Some more enable/disable changes
* Moved enablement/disablement of pv in separate functions
* Some review fixes

v4:
* Sync with KVM changes
* Review changes

V3:
* Use dedicated functions to access SIDA
* Smaller cleanups and segfault fixes
* Error reporting for Ultravisor calls
* Inject of RC of diag308 subcode 10 fails

V2:
* Split out cleanups
* Internal PV state tracking
* Review feedback

Christian Borntraeger (1):
  s390x: Add unpack facility feature to GA1

Janosch Frank (17):
  Sync pv
  s390x: protvirt: Add diag308 subcodes 8 - 10
  s390x: protvirt: Support unpack facility
  s390x: protvirt: Add migration blocker
  s390x: protvirt: Handle diag 308 subcodes 0,1,3,4
  s390x: protvirt: Inhibit balloon when switching to protected mode
  s390x: protvirt: KVM intercept changes
  s390x: Add SIDA memory ops
  s390x: protvirt: Move STSI data over SIDAD
  s390x: protvirt: SCLP interpretation
  s390x: protvirt: Set guest IPL PSW
  s390x: protvirt: Move diag 308 data over SIDAD
  s390x: protvirt: Disable address checks for PV guest IO emulation
  s390x: protvirt: Move IO control structures over SIDA
  s390x: protvirt: Handle SIGP store status correctly
  docs: Add protvirt docs
  pc-bios: s390x: Save iplb location in lowcore

 docs/system/index.rst   |   1 +
 docs/system/protvirt.rst|  57 +++
 hw/s390x/Makefile.objs  |   1 +
 hw/s390x/ipl.c  |  80 ++-
 hw/s390x/ipl.h  |  34 +++
 hw/s390x/pv.c   | 106 
 hw/s390x/pv.h   |  34 +++
 hw/s390x/s390-virtio-ccw.c  | 145 +++-
 hw/s390x/sclp.c |  17 
 include/hw/s390x/s390-virtio-ccw.h  |   1 +
 include/hw/s390x/sclp.h |   2 +
 linux-headers/linux/kvm.h   |  45 -
 pc-bios/s390-ccw/jump2ipl.c |   1 +
 pc-bios/s390-ccw/main.c |   8 +-
 pc-bios/s390-ccw/netmain.c  |   1 +
 pc-bios/s390-ccw/s390-arch.h|  10 +-
 pc-bios/s390-ccw/s390-ccw.h |   1 +
 target/s390x/cpu.c  |  27 --
 target/s390x/cpu.h  |   8 +-
 target/s390x/cpu_features_def.inc.h |   1 +
 target/s390x/diag.c |  60 ++--
 target/s390x/gen-features.c |   1 +
 target/s390x/helper.c   |   4 +
 target/s390x/ioinst.c   | 113 +++---
 target/s390x/kvm.c  |  54 ++-
 target/s390x/kvm_s390x.h|   2 +
 target/s390x/mmu_helper.c   |  14 +++
 target/s390x/sigp.c |   1 +
 28 files changed, 762 insertions(+), 67 deletions(-)
 create mode 100644 docs/system/protvirt.rst
 create mode 100644 hw/s390x/pv.c
 create mode 100644 hw/s390x/pv.h

-- 
2.20.1




[PATCH v6 06/18] s390x: protvirt: Inhibit balloon when switching to protected mode

2020-03-04 Thread Janosch Frank
Ballooning in protected VMs can only be done when the guest shares the
pages it gives to the host. If pages are not shared, the integrity
checks will fail once those pages have been altered and are given back
to the guest.

Hence, until we have a solution for this in the guest kernel, we
inhibit ballooning when switching into protected mode and reverse that
once we move out of it.

Signed-off-by: Janosch Frank 
Reviewed-by: David Hildenbrand 
---
 hw/s390x/s390-virtio-ccw.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 038bad54cd..b039178004 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -41,6 +41,7 @@
 #include "hw/qdev-properties.h"
 #include "hw/s390x/tod.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/balloon.h"
 #include "hw/s390x/pv.h"
 #include 
 #include "migration/blocker.h"
@@ -335,6 +336,7 @@ static void s390_machine_unprotect(S390CcwMachineState *ms)
 ms->pv = false;
 }
 migrate_del_blocker(pv_mig_blocker);
+qemu_balloon_inhibit(false);
 }
 
 static int s390_machine_protect(S390CcwMachineState *ms)
@@ -343,6 +345,7 @@ static int s390_machine_protect(S390CcwMachineState *ms)
 CPUState *t;
 int rc = -1;
 
+qemu_balloon_inhibit(true);
 if (!pv_mig_blocker) {
 error_setg(&pv_mig_blocker,
"protected VMs are currently not migrateable.");
-- 
2.20.1




[PATCH v6 01/18] Sync pv

2020-03-04 Thread Janosch Frank
Signed-off-by: Janosch Frank 
---
 linux-headers/linux/kvm.h | 43 +--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 265099100e..e36f761194 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -474,8 +474,11 @@ struct kvm_s390_mem_op {
__u32 size; /* amount of bytes */
__u32 op;   /* type of operation */
__u64 buf;  /* buffer in userspace */
-   __u8 ar;/* the access register number */
-   __u8 reserved[31];  /* should be set to 0 */
+   union {
+   __u8 ar;/* the access register number */
+   __u32 sida_offset; /* offset into the sida */
+   __u8 reserved[32]; /* should be set to 0 */
+   };
 };
 /* types for kvm_s390_mem_op->op */
 #define KVM_S390_MEMOP_LOGICAL_READ0
@@ -1010,6 +1013,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_ARM_NISV_TO_USER 177
 #define KVM_CAP_ARM_INJECT_EXT_DABT 178
 #define KVM_CAP_S390_VCPU_RESETS 179
+#define KVM_CAP_S390_PROTECTED 180
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1478,6 +1482,41 @@ struct kvm_enc_region {
 #define KVM_S390_NORMAL_RESET  _IO(KVMIO,   0xc3)
 #define KVM_S390_CLEAR_RESET   _IO(KVMIO,   0xc4)
 
+struct kvm_s390_pv_sec_parm {
+   __u64 origin;
+   __u64 length;
+};
+
+struct kvm_s390_pv_unp {
+   __u64 addr;
+   __u64 size;
+   __u64 tweak;
+};
+
+enum pv_cmd_id {
+   KVM_PV_ENABLE,
+   KVM_PV_DISABLE,
+   KVM_PV_VM_SET_SEC_PARMS,
+   KVM_PV_VM_UNPACK,
+   KVM_PV_VM_VERIFY,
+   KVM_PV_VM_PREP_RESET,
+   KVM_PV_VM_UNSHARE_ALL,
+   KVM_PV_VCPU_CREATE,
+   KVM_PV_VCPU_DESTROY,
+};
+
+struct kvm_pv_cmd {
+   __u32 cmd;  /* Command to be executed */
+   __u16 rc;   /* Ultravisor return code */
+   __u16 rrc;  /* Ultravisor return reason code */
+   __u64 data; /* Data or address */
+   __u32 flags;/* flags for future extensions. Must be 0 for now */
+   __u32 reserved[3];
+};
+
+/* Available with KVM_CAP_S390_PROTECTED */
+#define KVM_S390_PV_COMMAND_IOWR(KVMIO, 0xc5, struct kvm_pv_cmd)
+
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
/* Guest initialization commands */
-- 
2.20.1




[PATCH v6 11/18] s390x: protvirt: Set guest IPL PSW

2020-03-04 Thread Janosch Frank
Handling of CPU reset and setting of the IPL psw from guest storage at
offset 0 is done by a Ultravisor call. Let's only fetch it if
necessary.

Signed-off-by: Janosch Frank 
Reviewed-by: Thomas Huth 
---
 target/s390x/cpu.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 69b1cc5dfc..7840e784f1 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -78,16 +78,21 @@ static bool s390_cpu_has_work(CPUState *cs)
 static void s390_cpu_load_normal(CPUState *s)
 {
 S390CPU *cpu = S390_CPU(s);
-uint64_t spsw = ldq_phys(s->as, 0);
-
-cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL;
-/*
- * Invert short psw indication, so SIE will report a specification
- * exception if it was not set.
- */
-cpu->env.psw.mask ^= PSW_MASK_SHORTPSW;
-cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR;
+CPUS390XState *env = &cpu->env;
+uint64_t spsw;
 
+if (!env->pv) {
+spsw = ldq_phys(s->as, 0);
+cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL;
+/*
+ * Invert short psw indication, so SIE will report a specification
+ * exception if it was not set.
+ */
+cpu->env.psw.mask ^= PSW_MASK_SHORTPSW;
+cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR;
+} else {
+s390_cpu_set_state(S390_CPU_STATE_LOAD, cpu);
+}
 s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
 }
 #endif
-- 
2.20.1




[PATCH v6 03/18] s390x: protvirt: Support unpack facility

2020-03-04 Thread Janosch Frank
When a guest has saved a ipib of type 5 and calls diagnose308 with
subcode 10, we have to setup the protected processing environment via
Ultravisor calls. The calls are done by KVM and are exposed via an
API.

The following steps are necessary:
1. Enable protected mode for the VM (register it and its cpus with the 
Ultravisor)
2. Forward the secure header to the Ultravisor (has all information on
how to decrypt the image and VM information)
3. Protect image pages from the host and decrypt them
4. Verify the image integrity

Only after step 4 a protected VM is allowed to run.

Signed-off-by: Janosch Frank 
Signed-off-by: Christian Borntraeger  [Changes
to machine]
---
 hw/s390x/Makefile.objs  |   1 +
 hw/s390x/ipl.c  |  33 +
 hw/s390x/ipl.h  |   2 +
 hw/s390x/pv.c   | 106 
 hw/s390x/pv.h   |  34 +
 hw/s390x/s390-virtio-ccw.c  |  91 
 include/hw/s390x/s390-virtio-ccw.h  |   1 +
 target/s390x/cpu.c  |   4 ++
 target/s390x/cpu.h  |   1 +
 target/s390x/cpu_features_def.inc.h |   1 +
 10 files changed, 274 insertions(+)
 create mode 100644 hw/s390x/pv.c
 create mode 100644 hw/s390x/pv.h

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index e02ed80b68..a46a1c7894 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -31,6 +31,7 @@ obj-y += tod-qemu.o
 obj-$(CONFIG_KVM) += tod-kvm.o
 obj-$(CONFIG_KVM) += s390-skeys-kvm.o
 obj-$(CONFIG_KVM) += s390-stattrib-kvm.o
+obj-$(CONFIG_KVM) += pv.o
 obj-y += s390-ccw.o
 obj-y += ap-device.o
 obj-y += ap-bridge.o
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 80c6ab233a..3b241ea549 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -33,6 +33,7 @@
 #include "qemu/cutils.h"
 #include "qemu/option.h"
 #include "exec/exec-all.h"
+#include "pv.h"
 
 #define KERN_IMAGE_START0x01UL
 #define LINUX_MAGIC_ADDR0x010008UL
@@ -676,6 +677,38 @@ static void s390_ipl_prepare_qipl(S390CPU *cpu)
 cpu_physical_memory_unmap(addr, len, 1, len);
 }
 
+int s390_ipl_prepare_pv_header(void)
+{
+S390IPLState *ipl = get_ipl_device();
+IPLBlockPV *ipib_pv = &ipl->iplb_pv.pv;
+void *hdr = g_malloc(ipib_pv->pv_header_len);
+int rc;
+
+cpu_physical_memory_read(ipib_pv->pv_header_addr, hdr,
+ ipib_pv->pv_header_len);
+rc = s390_pv_set_sec_parms((uint64_t)hdr,
+  ipib_pv->pv_header_len);
+g_free(hdr);
+return rc;
+}
+
+int s390_ipl_pv_unpack(void)
+{
+int i, rc = 0;
+S390IPLState *ipl = get_ipl_device();
+IPLBlockPV *ipib_pv = &ipl->iplb_pv.pv;
+
+for (i = 0; i < ipib_pv->num_comp; i++) {
+rc = s390_pv_unpack(ipib_pv->components[i].addr,
+TARGET_PAGE_ALIGN(ipib_pv->components[i].size),
+ipib_pv->components[i].tweak_pref);
+if (rc) {
+break;
+}
+}
+return rc;
+}
+
 void s390_ipl_prepare_cpu(S390CPU *cpu)
 {
 S390IPLState *ipl = get_ipl_device();
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index 04be63cee1..ad8090a02c 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -105,6 +105,8 @@ typedef union IplParameterBlock IplParameterBlock;
 int s390_ipl_set_loadparm(uint8_t *loadparm);
 int s390_ipl_pv_check_components(IplParameterBlock *iplb);
 void s390_ipl_update_diag308(IplParameterBlock *iplb);
+int s390_ipl_prepare_pv_header(void);
+int s390_ipl_pv_unpack(void);
 void s390_ipl_prepare_cpu(S390CPU *cpu);
 IplParameterBlock *s390_ipl_get_iplb(void);
 IplParameterBlock *s390_ipl_get_iplb_secure(void);
diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
new file mode 100644
index 00..50b68b6c34
--- /dev/null
+++ b/hw/s390x/pv.c
@@ -0,0 +1,106 @@
+/*
+ * Secure execution functions
+ *
+ * Copyright IBM Corp. 2020
+ * Author(s):
+ *  Janosch Frank 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+#include "qemu/osdep.h"
+#include 
+
+#include 
+
+#include "qemu/error-report.h"
+#include "sysemu/kvm.h"
+#include "pv.h"
+
+const char *cmd_names[] = {
+"VM_ENABLE",
+"VM_DISABLE",
+"VM_SET_SEC_PARAMS",
+"VM_UNPACK",
+"VM_VERIFY",
+"VM_PREP_RESET",
+"VM_UNSHARE_ALL",
+NULL
+};
+
+static int s390_pv_cmd(uint32_t cmd, void *data)
+{
+int rc;
+struct kvm_pv_cmd pv_cmd = {
+.cmd = cmd,
+.data = (uint64_t)data,
+};
+
+rc = kvm_vm_ioctl(kvm_state, KVM_S390_PV_COMMAND, &pv_cmd);
+if (rc) {
+error_report("KVM PV command %d (%s) failed: header rc %x rrc %x "
+ "IOCTL rc: %d", cmd, cmd_names[cmd], pv_cmd.rc, 
pv_cmd.rrc,
+ rc);
+}
+return rc;
+}
+
+static void s390_pv_cmd_exit(uint32_t cmd, void *data)
+{
+int r

[PATCH v6 02/18] s390x: protvirt: Add diag308 subcodes 8 - 10

2020-03-04 Thread Janosch Frank
For diag308 subcodes 8 - 10 we have a new ipib of type 5. The ipib
holds the address and length of the secure execution header, as well
as a list of guest components.

Each component is a block of memory, for example kernel or initrd,
which needs to be decrypted by the Ultravisor in order to run a
protected VM. The secure execution header instructs the Ultravisor on
how to handle the protected VM and its components.

Subcodes 8 and 9 are similiar to 5 and 6 and subcode 10 will finally
start the protected guest.

Subcodes 8-10 are not valid in protected mode, we have to do a subcode
3 and then the 8 and 10 combination for a protected reboot.

Signed-off-by: Janosch Frank 
---
 hw/s390x/ipl.c  | 47 ++---
 hw/s390x/ipl.h  | 32 ++
 target/s390x/diag.c | 26 ++---
 3 files changed, 99 insertions(+), 6 deletions(-)

diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 9c1ecd423c..80c6ab233a 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -538,15 +538,55 @@ static bool is_virtio_scsi_device(IplParameterBlock *iplb)
 return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI);
 }
 
+int s390_ipl_pv_check_components(IplParameterBlock *iplb)
+{
+int i;
+IPLBlockPV *ipib_pv = &iplb->pv;
+
+if (ipib_pv->num_comp == 0) {
+return -EINVAL;
+}
+
+for (i = 0; i < ipib_pv->num_comp; i++) {
+/* Addr must be 4k aligned */
+if (ipib_pv->components[i].addr & ~TARGET_PAGE_MASK) {
+return -EINVAL;
+}
+
+/* Tweak prefix is monotonously increasing with each component */
+if (i < ipib_pv->num_comp - 1 &&
+ipib_pv->components[i].tweak_pref >
+ipib_pv->components[i + 1].tweak_pref) {
+return -EINVAL;
+}
+}
+return 0;
+}
+
 void s390_ipl_update_diag308(IplParameterBlock *iplb)
 {
 S390IPLState *ipl = get_ipl_device();
 
-ipl->iplb = *iplb;
-ipl->iplb_valid = true;
+if (iplb->pbt == S390_IPL_TYPE_PV) {
+ipl->iplb_pv = *iplb;
+ipl->iplb_valid_pv = true;
+} else {
+ipl->iplb = *iplb;
+ipl->iplb_valid = true;
+}
 ipl->netboot = is_virtio_net_device(iplb);
 }
 
+IplParameterBlock *s390_ipl_get_iplb_secure(void)
+{
+S390IPLState *ipl = get_ipl_device();
+
+if (!ipl->iplb_valid_pv) {
+return NULL;
+}
+return &ipl->iplb_pv;
+}
+
 IplParameterBlock *s390_ipl_get_iplb(void)
 {
 S390IPLState *ipl = get_ipl_device();
@@ -561,7 +601,8 @@ void s390_ipl_reset_request(CPUState *cs, enum s390_reset 
reset_type)
 {
 S390IPLState *ipl = get_ipl_device();
 
-if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL) {
+if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL ||
+reset_type == S390_RESET_PV) {
 /* use CPU 0 for full resets */
 ipl->reset_cpu_index = 0;
 } else {
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index d4813105db..04be63cee1 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -15,6 +15,24 @@
 #include "cpu.h"
 #include "hw/qdev-core.h"
 
+struct IPLBlockPVComp {
+uint64_t tweak_pref;
+uint64_t addr;
+uint64_t size;
+} QEMU_PACKED;
+typedef struct IPLBlockPVComp IPLBlockPVComp;
+
+struct IPLBlockPV {
+uint8_t  reserved[87];
+uint8_t  version;
+uint32_t reserved70;
+uint32_t num_comp;
+uint64_t pv_header_addr;
+uint64_t pv_header_len;
+struct IPLBlockPVComp components[];
+} QEMU_PACKED;
+typedef struct IPLBlockPV IPLBlockPV;
+
 struct IplBlockCcw {
 uint8_t  reserved0[85];
 uint8_t  ssid;
@@ -71,6 +89,7 @@ union IplParameterBlock {
 union {
 IplBlockCcw ccw;
 IplBlockFcp fcp;
+IPLBlockPV pv;
 IplBlockQemuScsi scsi;
 };
 } QEMU_PACKED;
@@ -84,9 +103,11 @@ union IplParameterBlock {
 typedef union IplParameterBlock IplParameterBlock;
 
 int s390_ipl_set_loadparm(uint8_t *loadparm);
+int s390_ipl_pv_check_components(IplParameterBlock *iplb);
 void s390_ipl_update_diag308(IplParameterBlock *iplb);
 void s390_ipl_prepare_cpu(S390CPU *cpu);
 IplParameterBlock *s390_ipl_get_iplb(void);
+IplParameterBlock *s390_ipl_get_iplb_secure(void);
 
 enum s390_reset {
 /* default is a reset not triggered by a CPU e.g. issued by QMP */
@@ -94,6 +115,7 @@ enum s390_reset {
 S390_RESET_REIPL,
 S390_RESET_MODIFIED_CLEAR,
 S390_RESET_LOAD_NORMAL,
+S390_RESET_PV,
 };
 void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type);
 void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type);
@@ -133,6 +155,7 @@ struct S390IPLState {
 /*< private >*/
 DeviceState parent_obj;
 IplParameterBlock iplb;
+IplParameterBlock iplb_pv;
 QemuIplParameters qipl;
 uint64_t start_addr;
 uint64_t compat_start_addr;
@@ -140,6 +163,7 @@ struct S390IPLState {
 uint64_t compat_bios_start_addr;
 bool enf

[PATCH v6 04/18] s390x: protvirt: Add migration blocker

2020-03-04 Thread Janosch Frank
Migration is not yet supported.

Signed-off-by: Janosch Frank 
---
 hw/s390x/s390-virtio-ccw.c | 33 -
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index dd39890f89..272531a9ee 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -43,6 +43,9 @@
 #include "sysemu/sysemu.h"
 #include "hw/s390x/pv.h"
 #include 
+#include "migration/blocker.h"
+
+static Error *pv_mig_blocker;
 
 S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
 {
@@ -324,19 +327,30 @@ static void s390_machine_unprotect(S390CcwMachineState 
*ms)
 {
 CPUState *t;
 
-if (!ms->pv)
-return;
-s390_pv_vm_disable();
-CPU_FOREACH(t) {
-S390_CPU(t)->env.pv = false;
+if (ms->pv) {
+s390_pv_vm_disable();
+CPU_FOREACH(t) {
+S390_CPU(t)->env.pv = false;
+}
+ms->pv = false;
 }
-ms->pv = false;
+migrate_del_blocker(pv_mig_blocker);
 }
 
 static int s390_machine_protect(S390CcwMachineState *ms)
 {
+static Error *local_err;
 CPUState *t;
-int rc;
+int rc = -1;
+
+if (!pv_mig_blocker) {
+error_setg(&pv_mig_blocker,
+   "protected VMs are currently not migrateable.");
+}
+migrate_add_blocker(pv_mig_blocker, &local_err);
+if (local_err) {
+goto out_err;
+}
 
 /* Create SE VM */
 rc = s390_pv_vm_enable();
@@ -440,11 +454,12 @@ static void s390_machine_reset(MachineState *machine)
 
 if (s390_machine_protect(ms)) {
 s390_machine_inject_pv_error(cs);
-s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
-return;
+goto pv_err;
 }
 
 run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
+pv_err:
+s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
 break;
 default:
 g_assert_not_reached();
-- 
2.20.1




[PATCH v6 08/18] s390x: Add SIDA memory ops

2020-03-04 Thread Janosch Frank
Protected guests save the instruction control blocks in the SIDA
instead of QEMU/KVM directly accessing the guest's memory.

Let's introduce new functions to access the SIDA.

Signed-off-by: Janosch Frank 
---
 linux-headers/linux/kvm.h |  2 ++
 target/s390x/cpu.h|  7 ++-
 target/s390x/kvm.c| 25 +
 target/s390x/kvm_s390x.h  |  2 ++
 target/s390x/mmu_helper.c | 14 ++
 5 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index e36f761194..c30344ab00 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -483,6 +483,8 @@ struct kvm_s390_mem_op {
 /* types for kvm_s390_mem_op->op */
 #define KVM_S390_MEMOP_LOGICAL_READ0
 #define KVM_S390_MEMOP_LOGICAL_WRITE   1
+#define KVM_S390_MEMOP_SIDA_READ   2
+#define KVM_S390_MEMOP_SIDA_WRITE  3
 /* flags for kvm_s390_mem_op->flags */
 #define KVM_S390_MEMOP_F_CHECK_ONLY(1ULL << 0)
 #define KVM_S390_MEMOP_F_INJECT_EXCEPTION  (1ULL << 1)
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 7e4d9d267c..2578c838f8 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -824,7 +824,12 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, 
uint8_t ar, void *hostbuf,
 #define s390_cpu_virt_mem_check_write(cpu, laddr, ar, len)   \
 s390_cpu_virt_mem_rw(cpu, laddr, ar, NULL, len, true)
 void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra);
-
+int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset,  void *hostbuf,
+   int len, bool is_write);
+#define s390_cpu_pv_mem_read(cpu, offset, dest, len)\
+s390_cpu_pv_mem_rw(cpu, offset, dest, len, false)
+#define s390_cpu_pv_mem_write(cpu, offset, dest, len)   \
+s390_cpu_pv_mem_rw(cpu, offset, dest, len, true)
 
 /* sigp.c */
 int s390_cpu_restart(S390CPU *cpu);
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index eec0b92479..cdcd538b4f 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -154,6 +154,7 @@ static int cap_ri;
 static int cap_gs;
 static int cap_hpage_1m;
 static int cap_vcpu_resets;
+static int cap_protected;
 
 static int active_cmma;
 
@@ -346,6 +347,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
 cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
 cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS);
+cap_protected = kvm_check_extension(s, KVM_CAP_S390_PROTECTED);
 
 if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
 || !kvm_check_extension(s, KVM_CAP_S390_COW)) {
@@ -846,6 +848,29 @@ int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, 
void *hostbuf,
 return ret;
 }
 
+int kvm_s390_mem_op_pv(S390CPU *cpu, uint64_t offset, void *hostbuf,
+   int len, bool is_write)
+{
+struct kvm_s390_mem_op mem_op = {
+.sida_offset = offset,
+.size = len,
+.op = is_write ? KVM_S390_MEMOP_SIDA_WRITE
+   : KVM_S390_MEMOP_SIDA_READ,
+.buf = (uint64_t)hostbuf,
+};
+int ret;
+
+if (!cap_mem_op || !cap_protected) {
+return -ENOSYS;
+}
+
+ret = kvm_vcpu_ioctl(CPU(cpu), KVM_S390_MEM_OP, &mem_op);
+if (ret < 0) {
+error_report("KVM_S390_MEM_OP failed: %s", strerror(-ret));
+}
+return ret;
+}
+
 /*
  * Legacy layout for s390:
  * Older S390 KVM requires the topmost vma of the RAM to be
diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
index 0b21789796..9c38f6ccce 100644
--- a/target/s390x/kvm_s390x.h
+++ b/target/s390x/kvm_s390x.h
@@ -19,6 +19,8 @@ void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct 
kvm_s390_irq *irq);
 void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code);
 int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
 int len, bool is_write);
+int kvm_s390_mem_op_pv(S390CPU *cpu, vaddr addr, void *hostbuf, int len,
+   bool is_write);
 void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code);
 int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
 void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index 0be2f300bb..7d9f3059cd 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -474,6 +474,20 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int 
nr_pages,
 return 0;
 }
 
+int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf,
+   int len, bool is_write)
+{
+int ret;
+
+if (kvm_enabled()) {
+ret = kvm_s390_mem_op_pv(cpu, offset, hostbuf, len, is_write);
+} else {
+/* Protected Virtualization is a KVM/Hardware only feature */
+g_assert_not_reached();
+}
+return ret;
+}
+
 /**
  * s390_cpu_virt_mem_rw:
  * @laddr: the logical start address
-- 
2.20.1

[PATCH v6 07/18] s390x: protvirt: KVM intercept changes

2020-03-04 Thread Janosch Frank
Secure guests no longer intercept with code 4 for an instruction
interception. Instead they have codes 104 and 108 for secure
instruction interception and secure instruction notification
respectively.

The 104 mirrors the 4 interception.

The 108 is a notification interception to let KVM and QEMU know that
something changed and we need to update tracking information or
perform specific tasks. It's currently taken for the following
instructions:

* stpx (To inform about the changed prefix location)
* sclp (On incorrect SCCB values, so we can inject a IRQ)
* sigp (All but "stop and store status")
* diag308 (Subcodes 0/1)

Signed-off-by: Janosch Frank 
Reviewed-by: David Hildenbrand 
---
 target/s390x/kvm.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index 1d6fd6a27b..eec0b92479 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -115,6 +115,8 @@
 #define ICPT_CPU_STOP   0x28
 #define ICPT_OPEREXC0x2c
 #define ICPT_IO 0x40
+#define ICPT_PV_INSTR   0x68
+#define ICPT_PV_INSTR_NOTIFICATION  0x6c
 
 #define NR_LOCAL_IRQS 32
 /*
@@ -1693,6 +1695,8 @@ static int handle_intercept(S390CPU *cpu)
 (long)cs->kvm_run->psw_addr);
 switch (icpt_code) {
 case ICPT_INSTRUCTION:
+case ICPT_PV_INSTR:
+case ICPT_PV_INSTR_NOTIFICATION:
 r = handle_instruction(cpu, run);
 break;
 case ICPT_PROGRAM:
-- 
2.20.1




[PATCH v6 05/18] s390x: protvirt: Handle diag 308 subcodes 0,1,3,4

2020-03-04 Thread Janosch Frank
As we now have access to the protection state of the cpus, we can
implement special handling of diag 308 subcodes for cpus in the
protected state.

For subcodes 0 and 1 we need to unshare all pages before continuing,
so the guest doesn't accidentally expose data when dumping.

For subcode 3/4 we tear down the protected VM and reboot into
unprotected mode. We do not provide a secure reboot.

Before we can do the unshare calls, we need to mark all cpus as
stopped.

Signed-off-by: Janosch Frank 
---
 hw/s390x/s390-virtio-ccw.c | 36 +---
 target/s390x/diag.c|  4 
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 272531a9ee..038bad54cd 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -397,12 +397,27 @@ static void s390_machine_inject_pv_error(CPUState *cs)
 env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
 }
 
+static void s390_pv_prepare_reset(CPUS390XState *env)
+{
+CPUState *cs;
+
+if (!env->pv) {
+return;
+}
+CPU_FOREACH(cs) {
+s390_cpu_set_state(S390_CPU_STATE_STOPPED, S390_CPU(cs));
+}
+s390_pv_unshare();
+s390_pv_perf_clear_reset();
+}
+
 static void s390_machine_reset(MachineState *machine)
 {
 enum s390_reset reset_type;
 CPUState *cs, *t;
 S390CPU *cpu;
 S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
+CPUS390XState *env;
 
 /* get the reset parameters, reset them once done */
 s390_ipl_get_reset_request(&cs, &reset_type);
@@ -411,10 +426,15 @@ static void s390_machine_reset(MachineState *machine)
 s390_cmma_reset();
 
 cpu = S390_CPU(cs);
+env = &cpu->env;
 
 switch (reset_type) {
 case S390_RESET_EXTERNAL:
 case S390_RESET_REIPL:
+if (ms->pv) {
+s390_machine_unprotect(ms);
+}
+
 qemu_devices_reset();
 s390_crypto_reset();
 
@@ -422,21 +442,31 @@ static void s390_machine_reset(MachineState *machine)
 run_on_cpu(cs, s390_do_cpu_ipl, RUN_ON_CPU_NULL);
 break;
 case S390_RESET_MODIFIED_CLEAR:
+/*
+ * Susbsystem reset needs to be done before we unshare memory
+ * and loose access to VIRTIO structures in guest memory.
+ */
+subsystem_reset();
+s390_crypto_reset();
+s390_pv_prepare_reset(env);
 CPU_FOREACH(t) {
 run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
 }
-subsystem_reset();
-s390_crypto_reset();
 run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
 break;
 case S390_RESET_LOAD_NORMAL:
+/*
+ * Susbsystem reset needs to be done before we unshare memory
+ * and loose access to VIRTIO structures in guest memory.
+ */
+subsystem_reset();
+s390_pv_prepare_reset(env);
 CPU_FOREACH(t) {
 if (t == cs) {
 continue;
 }
 run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
 }
-subsystem_reset();
 run_on_cpu(cs, s390_do_cpu_initial_reset, RUN_ON_CPU_NULL);
 run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
 break;
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index 945b263f0a..a6cd1ea260 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -67,6 +67,10 @@ int handle_diag_288(CPUS390XState *env, uint64_t r1, 
uint64_t r3)
 static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr,
   uintptr_t ra, bool write)
 {
+/* Handled by the Ultravisor */
+if (env->pv) {
+return 0;
+}
 if ((r1 & 1) || (addr & ~TARGET_PAGE_MASK)) {
 s390_program_interrupt(env, PGM_SPECIFICATION, ra);
 return -1;
-- 
2.20.1




[PATCH v6 14/18] s390x: protvirt: Move IO control structures over SIDA

2020-03-04 Thread Janosch Frank
For protected guests, we need to put the IO emulation results into the
SIDA, so SIE will write them into the guest at the next entry.

Signed-off-by: Janosch Frank 
---
 target/s390x/ioinst.c | 87 ++-
 1 file changed, 61 insertions(+), 26 deletions(-)

diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
index e4102430aa..330b04d79a 100644
--- a/target/s390x/ioinst.c
+++ b/target/s390x/ioinst.c
@@ -129,9 +129,13 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, 
uint32_t ipb, uintptr_t ra)
 s390_program_interrupt(env, PGM_SPECIFICATION, ra);
 return;
 }
-if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
-s390_cpu_virt_mem_handle_exc(cpu, ra);
-return;
+if (env->pv) {
+s390_cpu_pv_mem_read(cpu, addr, &schib, sizeof(schib));
+} else {
+if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
+s390_cpu_virt_mem_handle_exc(cpu, ra);
+return;
+}
 }
 if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
 !ioinst_schib_valid(&schib)) {
@@ -186,9 +190,13 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, 
uint32_t ipb, uintptr_t ra)
 s390_program_interrupt(env, PGM_SPECIFICATION, ra);
 return;
 }
-if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
-s390_cpu_virt_mem_handle_exc(cpu, ra);
-return;
+if (env->pv) {
+s390_cpu_pv_mem_read(cpu, addr, &orig_orb, sizeof(orb));
+} else {
+if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
+s390_cpu_virt_mem_handle_exc(cpu, ra);
+return;
+}
 }
 copy_orb_from_guest(&orb, &orig_orb);
 if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
@@ -222,14 +230,19 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, 
uintptr_t ra)
 cc = css_do_stcrw(&crw);
 /* 0 - crw stored, 1 - zeroes stored */
 
-if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
+if (env->pv) {
+s390_cpu_pv_mem_write(cpu, addr, &crw, sizeof(crw));
 setcc(cpu, cc);
 } else {
-if (cc == 0) {
-/* Write failed: requeue CRW since STCRW is suppressing */
-css_undo_stcrw(&crw);
+if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
+setcc(cpu, cc);
+} else {
+if (cc == 0) {
+/* Write failed: requeue CRW since STCRW is suppressing */
+css_undo_stcrw(&crw);
+}
+s390_cpu_virt_mem_handle_exc(cpu, ra);
 }
-s390_cpu_virt_mem_handle_exc(cpu, ra);
 }
 }
 
@@ -251,6 +264,9 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, 
uint32_t ipb,
 }
 
 if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
+if (env->pv) {
+return;
+}
 /*
  * As operand exceptions have a lower priority than access exceptions,
  * we check whether the memory area is writeable (injecting the
@@ -283,14 +299,19 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, 
uint32_t ipb,
 }
 }
 if (cc != 3) {
-if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
-sizeof(schib)) != 0) {
-s390_cpu_virt_mem_handle_exc(cpu, ra);
-return;
+if (env->pv) {
+s390_cpu_pv_mem_write(cpu, addr, &schib, sizeof(schib));
+} else {
+if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
+sizeof(schib)) != 0) {
+s390_cpu_virt_mem_handle_exc(cpu, ra);
+return;
+}
 }
 } else {
 /* Access exceptions have a higher priority than cc3 */
-if (s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
+if (!env->pv &&
+s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
 s390_cpu_virt_mem_handle_exc(cpu, ra);
 return;
 }
@@ -327,15 +348,20 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, 
uint32_t ipb, uintptr_t ra)
 }
 /* 0 - status pending, 1 - not status pending, 3 - not operational */
 if (cc != 3) {
-if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
-s390_cpu_virt_mem_handle_exc(cpu, ra);
-return -EFAULT;
+if (env->pv) {
+s390_cpu_pv_mem_write(cpu, addr, &irb, irb_len);
+} else {
+if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
+s390_cpu_virt_mem_handle_exc(cpu, ra);
+return -EFAULT;
+}
 }
 css_do_tsch_update_subch(sch);
 } else {
 irb_len = sizeof(irb) - sizeof(irb.emw);
 /* Access exceptions have a higher priority than c

[PATCH v6 17/18] docs: Add protvirt docs

2020-03-04 Thread Janosch Frank
Lets add some documentation for the Protected VM functionality.

Signed-off-by: Janosch Frank 
---
 docs/system/index.rst|  1 +
 docs/system/protvirt.rst | 57 
 2 files changed, 58 insertions(+)
 create mode 100644 docs/system/protvirt.rst

diff --git a/docs/system/index.rst b/docs/system/index.rst
index 1a4b2c82ac..d2dc63b973 100644
--- a/docs/system/index.rst
+++ b/docs/system/index.rst
@@ -16,3 +16,4 @@ Contents:
 
qemu-block-drivers
vfio-ap
+   protvirt
diff --git a/docs/system/protvirt.rst b/docs/system/protvirt.rst
new file mode 100644
index 00..a1902cc47c
--- /dev/null
+++ b/docs/system/protvirt.rst
@@ -0,0 +1,57 @@
+Protected Virtualization on s390x
+=
+
+The memory and most of the register contents of Protected Virtual
+Machines (PVMs) are inaccessible to the hypervisor, effectively
+prohibiting VM introspection when the VM is running. At rest, PVMs are
+encrypted and can only be decrypted by the firmware of specific IBM Z
+machines.
+
+
+Prerequisites
+-
+
+To run PVMs, you need to have a machine with the Protected
+Virtualization feature, which is indicated by the Ultravisor Call
+facility (stfle bit 158). This is a KVM only feature, therefore you
+need a KVM which is able to support PVMs and activate the Ultravisor
+initialization by setting `prot_virt=1` on the kernel command line.
+
+If those requirements are met, the capability `KVM_CAP_S390_PROTECTED`
+will indicate that KVM can support PVMs on that LPAR.
+
+
+QEMU Settings
+-
+
+To indicate to the VM that it can move into protected mode, the
+`Unpack facility` (stfle bit 161) needs to be part of the cpu model of
+the VM.
+
+All I/O devices need to use the IOMMU.
+Passthrough (vfio) devices are currently not supported.
+
+Host huge page backings are not supported. The guest however can use
+huge pages as indicated by its facilities.
+
+
+Boot Process
+
+
+A secure guest image can be both booted from disk and using the QEMU
+command line. Booting from disk is done by the unmodified s390-ccw
+BIOS. I.e., the bootmap is interpreted and a number of components is
+read into memory and control is transferred to one of the components
+(zipl stage3), which does some fixups and then transfers control to
+some program residing in guest memory, which is normally the OS
+kernel. The secure image has another component prepended (stage3a)
+which uses the new diag308 subcodes 8 and 10 to trigger the transition
+into secure mode.
+
+Booting from the command line requires that the file passed
+via -kernel has the same memory layout as would result from the disk
+boot. This memory layout includes the encrypted components (kernel,
+initrd, cmdline), the stage3a loader and metadata. In case this boot
+method is used, the command line options -initrd and -cmdline are
+ineffective.  The preparation of secure guest image is done by a
+program (name tbd) of the s390-tools package.
-- 
2.20.1




[PATCH v6 10/18] s390x: protvirt: SCLP interpretation

2020-03-04 Thread Janosch Frank
SCLP for a protected guest is done over the SIDAD, so we need to use
the s390_cpu_virt_mem_* functions to access the SIDAD instead of guest
memory when reading/writing SCBs.

To not confuse the sclp emulation, we set 0x4000 as the SCCB address,
since the function that injects the sclp external interrupt would
reject a zero sccb address.

Signed-off-by: Janosch Frank 
---
 hw/s390x/sclp.c | 17 +
 include/hw/s390x/sclp.h |  2 ++
 target/s390x/kvm.c  |  5 +
 3 files changed, 24 insertions(+)

diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index af0bfbc2ec..5136f5fcbe 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -193,6 +193,23 @@ static void sclp_execute(SCLPDevice *sclp, SCCB *sccb, 
uint32_t code)
 }
 }
 
+#define SCLP_PV_DUMMY_ADDR 0x4000
+int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb,
+uint32_t code)
+{
+SCLPDevice *sclp = get_sclp_device();
+SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
+SCCB work_sccb;
+hwaddr sccb_len = sizeof(SCCB);
+
+s390_cpu_pv_mem_read(env_archcpu(env), 0, &work_sccb, sccb_len);
+sclp_c->execute(sclp, &work_sccb, code);
+s390_cpu_pv_mem_write(env_archcpu(env), 0, &work_sccb,
+  be16_to_cpu(work_sccb.h.length));
+sclp_c->service_interrupt(sclp, SCLP_PV_DUMMY_ADDR);
+return 0;
+}
+
 int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
 {
 SCLPDevice *sclp = get_sclp_device();
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index c54413b78c..c0a3faa37d 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -217,5 +217,7 @@ void s390_sclp_init(void);
 void sclp_service_interrupt(uint32_t sccb);
 void raise_irq_cpu_hotplug(void);
 int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code);
+int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb,
+uint32_t code);
 
 #endif
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index 43fc0c088b..a4cbdc5fc6 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -1226,6 +1226,11 @@ static void kvm_sclp_service_call(S390CPU *cpu, struct 
kvm_run *run,
 sccb = env->regs[ipbh0 & 0xf];
 code = env->regs[(ipbh0 & 0xf0) >> 4];
 
+if (run->s390_sieic.icptcode == ICPT_PV_INSTR) {
+sclp_service_call_protected(env, sccb, code);
+return;
+}
+
 r = sclp_service_call(env, sccb, code);
 if (r < 0) {
 kvm_s390_program_interrupt(cpu, -r);
-- 
2.20.1




[PATCH v6 16/18] s390x: Add unpack facility feature to GA1

2020-03-04 Thread Janosch Frank
From: Christian Borntraeger 

The unpack facility is an indication that diagnose 308 subcodes 8-10
are available to the guest. That means, that the guest can put itself
into protected mode.

Once it is in protected mode, the hardware stops any attempt of VM
introspection by the hypervisor.

Some features are currently not supported in protected mode:
 * Passthrough devices
 * Migration
 * Huge page backings

Signed-off-by: Christian Borntraeger 
---
 target/s390x/gen-features.c | 1 +
 target/s390x/kvm.c  | 5 +
 2 files changed, 6 insertions(+)

diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index 6278845b12..8ddeebc544 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -562,6 +562,7 @@ static uint16_t full_GEN15_GA1[] = {
 S390_FEAT_GROUP_MSA_EXT_9,
 S390_FEAT_GROUP_MSA_EXT_9_PCKMO,
 S390_FEAT_ETOKEN,
+S390_FEAT_UNPACK,
 };
 
 /* Default features (in order of release)
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index a4cbdc5fc6..bf807793bc 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -2396,6 +2396,11 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, 
Error **errp)
 clear_bit(S390_FEAT_BPB, model->features);
 }
 
+/* we do have the IPL enhancements */
+if (cap_protected) {
+set_bit(S390_FEAT_UNPACK, model->features);
+}
+
 /* We emulate a zPCI bus and AEN, therefore we don't need HW support */
 set_bit(S390_FEAT_ZPCI, model->features);
 set_bit(S390_FEAT_ADAPTER_EVENT_NOTIFICATION, model->features);
-- 
2.20.1




[PATCH v6 18/18] pc-bios: s390x: Save iplb location in lowcore

2020-03-04 Thread Janosch Frank
The POP states that for a list directed IPL the IPLB is stored into
memory by the machine loader and its address is stored at offset 0x14
of the lowcore.

ZIPL currently uses the address in offset 0x14 to access the IPLB and
acquire flags about secure boot. If the IPLB address points into
memory which has an unsupported mix of flags set, ZIPL will panic
instead of booting the OS.

As the lowcore can have quite a high entropy for a guest that did drop
out of protected mode (i.e. rebooted) we encountered the ZIPL panic
quite often.

Signed-off-by: Janosch Frank 
Tested-by: Marc Hartmayer 
---
 pc-bios/s390-ccw/jump2ipl.c  |  1 +
 pc-bios/s390-ccw/main.c  |  8 +++-
 pc-bios/s390-ccw/netmain.c   |  1 +
 pc-bios/s390-ccw/s390-arch.h | 10 --
 pc-bios/s390-ccw/s390-ccw.h  |  1 +
 5 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
index da13c43cc0..4eba2510b0 100644
--- a/pc-bios/s390-ccw/jump2ipl.c
+++ b/pc-bios/s390-ccw/jump2ipl.c
@@ -35,6 +35,7 @@ void jump_to_IPL_code(uint64_t address)
 {
 /* store the subsystem information _after_ the bootmap was loaded */
 write_subsystem_identification();
+write_iplb_location();
 
 /* prevent unknown IPL types in the guest */
 if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index a21b386280..4e65b411e1 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -9,6 +9,7 @@
  */
 
 #include "libc.h"
+#include "helper.h"
 #include "s390-arch.h"
 #include "s390-ccw.h"
 #include "cio.h"
@@ -22,7 +23,7 @@ QemuIplParameters qipl;
 IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
 static bool have_iplb;
 static uint16_t cutype;
-LowCore const *lowcore; /* Yes, this *is* a pointer to address 0 */
+LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
 
 #define LOADPARM_PROMPT "PROMPT  "
 #define LOADPARM_EMPTY  ""
@@ -42,6 +43,11 @@ void write_subsystem_identification(void)
 *zeroes = 0;
 }
 
+void write_iplb_location(void)
+{
+lowcore->ptr_iplb = ptr2u32(&iplb);
+}
+
 void panic(const char *string)
 {
 sclp_print(string);
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index f2dcc01e27..309ffa30d9 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -40,6 +40,7 @@
 #define DEFAULT_TFTP_RETRIES 20
 
 extern char _start[];
+void write_iplb_location(void) {}
 
 #define KERNEL_ADDR ((void *)0L)
 #define KERNEL_MAX_SIZE ((long)_start)
diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
index 504fc7c2f0..5f36361c02 100644
--- a/pc-bios/s390-ccw/s390-arch.h
+++ b/pc-bios/s390-ccw/s390-arch.h
@@ -36,7 +36,13 @@ typedef struct LowCore {
 /* prefix area: defined by architecture */
 PSWLegacy   ipl_psw;  /* 0x000 */
 uint32_tccw1[2];  /* 0x008 */
-uint32_tccw2[2];  /* 0x010 */
+union {
+uint32_tccw2[2];  /* 0x010 */
+struct {
+uint32_t reserved10;
+uint32_t ptr_iplb;
+};
+};
 uint8_t pad1[0x80 - 0x18];/* 0x018 */
 uint32_text_params;   /* 0x080 */
 uint16_tcpu_addr; /* 0x084 */
@@ -85,7 +91,7 @@ typedef struct LowCore {
 PSW io_new_psw;   /* 0x1f0 */
 } __attribute__((packed, aligned(8192))) LowCore;
 
-extern LowCore const *lowcore;
+extern LowCore *lowcore;
 
 static inline void set_prefix(uint32_t address)
 {
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 11bce7d73c..21f27e7990 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -57,6 +57,7 @@ void consume_io_int(void);
 /* main.c */
 void panic(const char *string);
 void write_subsystem_identification(void);
+void write_iplb_location(void);
 extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
 unsigned int get_loadparm_index(void);
 
-- 
2.20.1




[PATCH v6 12/18] s390x: protvirt: Move diag 308 data over SIDAD

2020-03-04 Thread Janosch Frank
For protected guests the IPIB is written/read to/from the satellite
block, so we need those accesses to go through
s390_cpu_pv_mem_read/write().

Signed-off-by: Janosch Frank 
---
 target/s390x/diag.c | 30 +++---
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index a6cd1ea260..444c88ef15 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -87,6 +87,7 @@ static int diag308_parm_check(CPUS390XState *env, uint64_t 
r1, uint64_t addr,
 void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t 
ra)
 {
 CPUState *cs = env_cpu(env);
+S390CPU *cpu = S390_CPU(cs);
 uint64_t addr =  env->regs[r1];
 uint64_t subcode = env->regs[r3];
 IplParameterBlock *iplb;
@@ -118,13 +119,22 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, 
uint64_t r3, uintptr_t ra)
 return;
 }
 iplb = g_new0(IplParameterBlock, 1);
-cpu_physical_memory_read(addr, iplb, sizeof(iplb->len));
+if (!env->pv) {
+cpu_physical_memory_read(addr, iplb, sizeof(iplb->len));
+} else {
+s390_cpu_pv_mem_read(cpu, 0, iplb, sizeof(iplb->len));
+}
+
 if (!iplb_valid_len(iplb)) {
 env->regs[r1 + 1] = DIAG_308_RC_INVALID;
 goto out;
 }
 
-cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
+if (!env->pv) {
+cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
+} else {
+s390_cpu_pv_mem_read(cpu, 0, iplb, be32_to_cpu(iplb->len));
+}
 
 if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb) &&
 !(iplb_valid_pv(iplb) && !s390_ipl_pv_check_components(iplb))) {
@@ -136,7 +146,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, 
uint64_t r3, uintptr_t ra)
 env->regs[r1 + 1] = DIAG_308_RC_OK;
 out:
 g_free(iplb);
-return;
+break;
 case DIAG308_STORE:
 case DIAG308_PV_STORE:
 if (diag308_parm_check(env, r1, addr, ra, true)) {
@@ -147,12 +157,18 @@ out:
 } else {
 iplb = s390_ipl_get_iplb();
 }
-if (iplb) {
-cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));
-env->regs[r1 + 1] = DIAG_308_RC_OK;
-} else {
+if (!iplb) {
 env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
+return;
 }
+
+if (!env->pv) {
+cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));
+} else {
+s390_cpu_pv_mem_write(cpu, 0, iplb, be32_to_cpu(iplb->len));
+}
+
+env->regs[r1 + 1] = DIAG_308_RC_OK;
 break;
 case DIAG308_PV_START:
 iplb = s390_ipl_get_iplb_secure();
-- 
2.20.1




[PATCH v6 09/18] s390x: protvirt: Move STSI data over SIDAD

2020-03-04 Thread Janosch Frank
For protected guests, we need to put the STSI emulation results into
the SIDA, so SIE will write them into the guest at the next entry.

Signed-off-by: Janosch Frank 
Acked-by: David Hildenbrand 
---
 target/s390x/kvm.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index cdcd538b4f..43fc0c088b 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -1797,11 +1797,16 @@ static int handle_tsch(S390CPU *cpu)
 
 static void insert_stsi_3_2_2(S390CPU *cpu, __u64 addr, uint8_t ar)
 {
+CPUS390XState *env = &cpu->env;
 SysIB_322 sysib;
 int del;
 
-if (s390_cpu_virt_mem_read(cpu, addr, ar, &sysib, sizeof(sysib))) {
-return;
+if (env->pv) {
+s390_cpu_pv_mem_read(cpu, 0, &sysib, sizeof(sysib));
+} else {
+if (s390_cpu_virt_mem_read(cpu, addr, ar, &sysib, sizeof(sysib))) {
+return;
+}
 }
 /* Shift the stack of Extended Names to prepare for our own data */
 memmove(&sysib.ext_names[1], &sysib.ext_names[0],
@@ -1840,7 +1845,11 @@ static void insert_stsi_3_2_2(S390CPU *cpu, __u64 addr, 
uint8_t ar)
 /* Insert UUID */
 memcpy(sysib.vm[0].uuid, &qemu_uuid, sizeof(sysib.vm[0].uuid));
 
-s390_cpu_virt_mem_write(cpu, addr, ar, &sysib, sizeof(sysib));
+if (env->pv) {
+s390_cpu_pv_mem_write(cpu, 0, &sysib, sizeof(sysib));
+} else {
+s390_cpu_virt_mem_write(cpu, addr, ar, &sysib, sizeof(sysib));
+}
 }
 
 static int handle_stsi(S390CPU *cpu)
-- 
2.20.1




[PATCH v6 13/18] s390x: protvirt: Disable address checks for PV guest IO emulation

2020-03-04 Thread Janosch Frank
IO instruction data is routed through SIDAD for protected guests, so
adresses do not need to be checked, as this is kernel memory.

Signed-off-by: Janosch Frank 
Reviewed-by: Thomas Huth 
---
 target/s390x/ioinst.c | 26 +++---
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
index c437a1d8c6..e4102430aa 100644
--- a/target/s390x/ioinst.c
+++ b/target/s390x/ioinst.c
@@ -17,6 +17,16 @@
 #include "trace.h"
 #include "hw/s390x/s390-pci-bus.h"
 
+static uint64_t get_address_from_regs(CPUS390XState *env, uint32_t ipb,
+  uint8_t *ar)
+{
+if (env->pv) {
+*ar = 0;
+return 0;
+}
+return decode_basedisp_s(env, ipb, ar);
+}
+
 int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
  int *schid)
 {
@@ -114,7 +124,7 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, 
uint32_t ipb, uintptr_t ra)
 CPUS390XState *env = &cpu->env;
 uint8_t ar;
 
-addr = decode_basedisp_s(env, ipb, &ar);
+addr = get_address_from_regs(env, ipb, &ar);
 if (addr & 3) {
 s390_program_interrupt(env, PGM_SPECIFICATION, ra);
 return;
@@ -171,7 +181,7 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, 
uint32_t ipb, uintptr_t ra)
 CPUS390XState *env = &cpu->env;
 uint8_t ar;
 
-addr = decode_basedisp_s(env, ipb, &ar);
+addr = get_address_from_regs(env, ipb, &ar);
 if (addr & 3) {
 s390_program_interrupt(env, PGM_SPECIFICATION, ra);
 return;
@@ -203,7 +213,7 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, 
uintptr_t ra)
 CPUS390XState *env = &cpu->env;
 uint8_t ar;
 
-addr = decode_basedisp_s(env, ipb, &ar);
+addr = get_address_from_regs(env, ipb, &ar);
 if (addr & 3) {
 s390_program_interrupt(env, PGM_SPECIFICATION, ra);
 return;
@@ -234,7 +244,7 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, 
uint32_t ipb,
 CPUS390XState *env = &cpu->env;
 uint8_t ar;
 
-addr = decode_basedisp_s(env, ipb, &ar);
+addr = get_address_from_regs(env, ipb, &ar);
 if (addr & 3) {
 s390_program_interrupt(env, PGM_SPECIFICATION, ra);
 return;
@@ -303,7 +313,7 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, 
uint32_t ipb, uintptr_t ra)
 return -EIO;
 }
 trace_ioinst_sch_id("tsch", cssid, ssid, schid);
-addr = decode_basedisp_s(env, ipb, &ar);
+addr = get_address_from_regs(env, ipb, &ar);
 if (addr & 3) {
 s390_program_interrupt(env, PGM_SPECIFICATION, ra);
 return -EIO;
@@ -601,7 +611,7 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, 
uintptr_t ra)
 {
 ChscReq *req;
 ChscResp *res;
-uint64_t addr;
+uint64_t addr = 0;
 int reg;
 uint16_t len;
 uint16_t command;
@@ -610,7 +620,9 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, 
uintptr_t ra)
 
 trace_ioinst("chsc");
 reg = (ipb >> 20) & 0x00f;
-addr = env->regs[reg];
+if (!env->pv) {
+addr = env->regs[reg];
+}
 /* Page boundary? */
 if (addr & 0xfff) {
 s390_program_interrupt(env, PGM_SPECIFICATION, ra);
-- 
2.20.1




[PATCH v6 15/18] s390x: protvirt: Handle SIGP store status correctly

2020-03-04 Thread Janosch Frank
Status storing is not done by QEMU anymore, but is handled by SIE.

Signed-off-by: Janosch Frank 
Reviewed-by: Thomas Huth 
---
 target/s390x/helper.c | 4 
 target/s390x/sigp.c   | 1 +
 2 files changed, 5 insertions(+)

diff --git a/target/s390x/helper.c b/target/s390x/helper.c
index ed72684911..8b91ed68f0 100644
--- a/target/s390x/helper.c
+++ b/target/s390x/helper.c
@@ -246,6 +246,10 @@ int s390_store_status(S390CPU *cpu, hwaddr addr, bool 
store_arch)
 hwaddr len = sizeof(*sa);
 int i;
 
+if (cpu->env.pv) {
+return 0;
+}
+
 sa = cpu_physical_memory_map(addr, &len, true);
 if (!sa) {
 return -EFAULT;
diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
index c604f17710..e1c8071464 100644
--- a/target/s390x/sigp.c
+++ b/target/s390x/sigp.c
@@ -497,6 +497,7 @@ void do_stop_interrupt(CPUS390XState *env)
 if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) {
 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
 }
+/* Storing will occur on next SIE entry for protected VMs */
 if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) {
 s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
 }
-- 
2.20.1




Re: [PATCH v5 16/50] multi-process: Synchronize remote memory

2020-03-04 Thread Dr. David Alan Gilbert
* Jagannathan Raman (jag.ra...@oracle.com) wrote:
> Add memory-listener object which is used to keep the view of the RAM
> in sync between QEMU and remote process.
> A MemoryListener is registered for system-memory AddressSpace. The
> listener sends SYNC_SYSMEM message to the remote process when memory
> listener commits the changes to memory, the remote process receives
> the message and processes it in the handler for SYNC_SYSMEM message.
> 
> TODO: No need to create object for remote memory listener.
> 
> Signed-off-by: Jagannathan Raman 
> Signed-off-by: John G Johnson 
> Signed-off-by: Elena Ufimtseva 
> ---
>  Makefile.target|   3 +
>  hw/proxy/memory-sync.c | 212 
> +
>  hw/proxy/qemu-proxy.c  |   5 +
>  include/hw/proxy/memory-sync.h |  37 +++
>  include/hw/proxy/qemu-proxy.h  |   5 +
>  remote/remote-main.c   |  11 +++
>  6 files changed, 273 insertions(+)
>  create mode 100644 hw/proxy/memory-sync.c
>  create mode 100644 include/hw/proxy/memory-sync.h
> 
> diff --git a/Makefile.target b/Makefile.target
> index cfd36c1..271d883 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -127,6 +127,9 @@ obj-$(CONFIG_TCG) += fpu/softfloat.o
>  obj-y += target/$(TARGET_BASE_ARCH)/
>  obj-y += disas.o
>  obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
> +ifeq ($(TARGET_NAME)-$(CONFIG_MPQEMU)-$(CONFIG_USER_ONLY), x86_64-y-)
> +obj-$(CONFIG_MPQEMU) += hw/proxy/memory-sync.o
> +endif
>  LIBS := $(libs_cpu) $(LIBS)
>  
>  obj-$(CONFIG_PLUGIN) += plugins/
> diff --git a/hw/proxy/memory-sync.c b/hw/proxy/memory-sync.c
> new file mode 100644
> index 000..3edbb19
> --- /dev/null
> +++ b/hw/proxy/memory-sync.c
> @@ -0,0 +1,212 @@
> +/*
> + * Copyright © 2018, 2020 Oracle and/or its affiliates.
> + *
> + * 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 
> +#include 
> +#include 
> +
> +#include "qemu/osdep.h"
> +#include "qemu/compiler.h"
> +#include "qemu/int128.h"
> +#include "qemu/range.h"
> +#include "exec/memory.h"
> +#include "exec/cpu-common.h"
> +#include "cpu.h"
> +#include "exec/ram_addr.h"
> +#include "exec/address-spaces.h"
> +#include "io/mpqemu-link.h"
> +#include "hw/proxy/memory-sync.h"
> +
> +static const TypeInfo remote_mem_sync_type_info = {
> +.name  = TYPE_MEMORY_LISTENER,
> +.parent= TYPE_OBJECT,
> +.instance_size = sizeof(RemoteMemSync),
> +};
> +
> +static void remote_mem_sync_register_types(void)
> +{
> +type_register_static(&remote_mem_sync_type_info);
> +}
> +
> +type_init(remote_mem_sync_register_types)
> +
> +static void proxy_ml_begin(MemoryListener *listener)
> +{
> +RemoteMemSync *sync = container_of(listener, RemoteMemSync, listener);
> +int mrs;
> +
> +for (mrs = 0; mrs < sync->n_mr_sections; mrs++) {
> +memory_region_unref(sync->mr_sections[mrs].mr);
> +}
> +
> +g_free(sync->mr_sections);
> +sync->mr_sections = NULL;
> +sync->n_mr_sections = 0;
> +}
> +
> +static int get_fd_from_hostaddr(uint64_t host, ram_addr_t *offset)
> +{
> +MemoryRegion *mr;
> +ram_addr_t off;
> +
> +mr = memory_region_from_host((void *)(uintptr_t)host, &off);

Do you need to just check we found an 'mr' ?

> +if (offset) {
> +*offset = off;
> +}
> +
> +return memory_region_get_fd(mr);
> +}
> +
> +static bool proxy_mrs_can_merge(uint64_t host, uint64_t prev_host, size_t 
> size)
> +{
> +bool merge;
> +int fd1, fd2;
> +
> +fd1 = get_fd_from_hostaddr(host, NULL);
> +
> +fd2 = get_fd_from_hostaddr(prev_host, NULL);
> +
> +merge = (fd1 == fd2);
> +
> +merge &= ((prev_host + size) == host);

It's interesting; I think the vhost code checks that the two mr's are
the same where you are checking for the same underlying fd - but I think
that's OK.
(I wonder if we need to check offset's within the fd's match up when
they're merged - since you added that offset feature in an earlier
patch?
That would also need checking in vhost_region_add_section)

> +return merge;
> +}
> +
> +static void proxy_ml_region_addnop(MemoryListener *listener,
> +   MemoryRegionSection *section)
> +{
> +RemoteMemSync *sync = container_of(listener, RemoteMemSync, listener);
> +bool need_add = true;
> +uint64_t mrs_size, mrs_gpa, mrs_page;
> +uintptr_t mrs_host;
> +RAMBlock *mrs_rb;
> +MemoryRegionSection *prev_sec;
> +
> +if (!(memory_region_is_ram(section->mr) &&
> +  !memory_region_is_rom(section->mr))) {
> +return;
> +}
> +
> +mrs_rb = section->mr->ram_block;
> +mrs_page = (uint64_t)qemu_ram_pagesize(mrs_rb);
> +mrs_size = int128_get64(section->size);
> +mrs_gpa = section->offset_within_address_space;
> +mrs_host = (uintptr_t)memory_region_get_ram_ptr(section->mr) +
> +   section->offset_within_re

Re: [PATCH v2 00/30] Configurable policy for handling deprecated interfaces

2020-03-04 Thread Peter Krempa
On Tue, Mar 03, 2020 at 17:34:35 +0100, Markus Armbruster wrote:
> Based-on: <20200227144531.24309-1-arm...@redhat.com>
> 
> This series extends QMP introspection to cover deprecation.
> Additionally, new option -compat lets you configure what to do when
> deprecated interfaces get used.  This is intended for testing users of
> the management interfaces.  It is experimental.

I've quickly hacked up support for the 'deprecated' feature in libvirt's
QMP validator. I've found a few uses of deprecated commands but they
might very well be in code paths that are no longer invoked in modern
qemus:

Offenders from qemumonitorjsontest:

44) qemuMonitorJSONSetCPU ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'cpu-add': failed to validate arguments of 'cpu-add' against QAPI schema: 
ERROR: 'cpu-add' is deprecated
FAILED
46) qemuMonitorJSONChangeMedia... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'change': failed to validate arguments of 'change' against QAPI schema: ERROR: 
'change' is deprecated
FAILED
49) qemuMonitorJSONSetMigrationSpeed  ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'migrate_set_speed': failed to validate arguments of 'migrate_set_speed' 
against QAPI schema: ERROR: 'migrate_set_speed' is deprecated
FAILED
50) qemuMonitorJSONSetMigrationDowntime   ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'migrate_set_downtime': failed to validate arguments of 'migrate_set_downtime' 
against QAPI schema: ERROR: 'migrate_set_downtime' is deprecated
FAILED
77) qemuMonitorJSONGetMigrationCacheSize  ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'query-migrate-cache-size': failed to validate arguments of 
'query-migrate-cache-size' against QAPI schema: ERROR: 
'query-migrate-cache-size' is deprecated
FAILED
83) qemuMonitorJSONQueryCPUs  ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'query-cpus': failed to validate arguments of 'query-cpus' against QAPI schema: 
ERROR: 'query-cpus' is deprecated
FAILED
93) GetCPUInfo(x86-basic-pluggable)   ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'query-cpus': failed to validate arguments of 'query-cpus' against QAPI schema: 
ERROR: 'query-cpus' is deprecated
FAILED
94) GetCPUInfo(x86-full)  ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'query-cpus': failed to validate arguments of 'query-cpus' against QAPI schema: 
ERROR: 'query-cpus' is deprecated
FAILED
95) GetCPUInfo(x86-node-full) ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'query-cpus': failed to validate arguments of 'query-cpus' against QAPI schema: 
ERROR: 'query-cpus' is deprecated
FAILED
97) GetCPUInfo(ppc64-basic)   ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'query-cpus': failed to validate arguments of 'query-cpus' against QAPI schema: 
ERROR: 'query-cpus' is deprecated
FAILED
98) GetCPUInfo(ppc64-hotplug-1)   ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'query-cpus': failed to validate arguments of 'query-cpus' against QAPI schema: 
ERROR: 'query-cpus' is deprecated
FAILED
99) GetCPUInfo(ppc64-hotplug-2)   ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'query-cpus': failed to validate arguments of 'query-cpus' against QAPI schema: 
ERROR: 'query-cpus' is deprecated
FAILED
100) GetCPUInfo(ppc64-hotplug-4)   ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'query-cpus': failed to validate arguments of 'query-cpus' against QAPI schema: 
ERROR: 'query-cpus' is deprecated
FAILED
101) GetCPUInfo(ppc64-no-threads)  ... 
libvirt: QEMU Driver error : internal error: unable to execute QEMU command 
'query-cpus': failed to validate arguments of 'query-cpus' against QAPI schema: 
ERROR: 'query-cpus' is deprecated
FAILED

Here all commands are tested just for legacy reasons. query-cpus-fast is
used on any live codebase, cpu-add is no longer used, change is not used
with -blockdev. I'm not sure about the migration parameter APIs but I
didn't check either.

The above shows that we can't enable this without thinking even in our
test-suite.

I'll try to come up with a solution where we can enable the reporting of
use of deprecated commands through /etc/qemu.conf so tha

Re: Wiki user request

2020-03-04 Thread Philippe Mathieu-Daudé
Ping?

Le jeu. 27 févr. 2020 10:29, Joaquin de Andres  a
écrit :

> Hi!
>
> I wonder if I can get write access to the wiki page. I'm working with
> Philippe Mathieu-Daudé in the GSoC Arduino Visualization project ([1])
> and I need to modify and add pages.
>
> Thanks!
> --joa
>
> [1] https://wiki.qemu.org/Internships/ProjectIdeas/ArduinoVisualisation
>
>


Re: [PATCH] optionrom/pvh: scan entire RSDP Area

2020-03-04 Thread Paolo Bonzini
On 04/03/20 09:55, Stefano Garzarella wrote:
> CCing Paolo
> 
> On Tue, Mar 03, 2020 at 02:52:47AM -0800, Joe Richey wrote:
>> From: Joe Richey 
>>
>> Right now the PVH option rom scans for the RSDP from 0xE to
>> 0xE1FFF. This is probobly a typo, it should scan from 0xE to
>> 0xF.
>>
>> This is actually an issue on some QEMU versions/machines. For example,
>> when I run QEMU the RSDP is placed at 0xf5ad0 which will not be picked
>> up by the current implementation.
>>
>> This bug still allows a Linux guest to boot (in most configurations) as
>> the kernel will just scan for the RSDP if one isn't provided.
>>
>> Signed-off-by: Joe Richey 
>> ---
>>  pc-bios/optionrom/pvh_main.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/pc-bios/optionrom/pvh_main.c b/pc-bios/optionrom/pvh_main.c
>> index a015e1bf22..28e79d7fc4 100644
>> --- a/pc-bios/optionrom/pvh_main.c
>> +++ b/pc-bios/optionrom/pvh_main.c
>> @@ -29,7 +29,7 @@ asm (".code32"); /* this code will be executed in 
>> protected mode */
>>  
>>  #define RSDP_SIGNATURE  0x2052545020445352LL /* "RSD PTR " */
>>  #define RSDP_AREA_ADDR  0x000E
>> -#define RSDP_AREA_SIZE  2048
>> +#define RSDP_AREA_SIZE  0x0002
>>  #define EBDA_BASE_ADDR  0x040E
>>  #define EBDA_SIZE   1024
>>  
> 
> The patch LGTM!
> 
> When I wrote this code I followed [1], where it is written that it can
> be found in the "memory region from 0x000E to 0x000F", so it
> should be a typo.
> 
> Thanks for fixing it!
> 
> 
> Fixes: 2785dc7b17 ("optionrom: add new PVH option rom")
> Reviewed-by: Stefano Garzarella 
> 
> 
> [1] https://wiki.osdev.org/RSDP#Detecting_the_RSDP
> 

Queued, thanks for both the fix and the Cc.

Paolo




Re: [PATCH v6 18/18] pc-bios: s390x: Save iplb location in lowcore

2020-03-04 Thread David Hildenbrand
On 04.03.20 12:42, Janosch Frank wrote:
> The POP states that for a list directed IPL the IPLB is stored into
> memory by the machine loader and its address is stored at offset 0x14
> of the lowcore.
> 
> ZIPL currently uses the address in offset 0x14 to access the IPLB and
> acquire flags about secure boot. If the IPLB address points into
> memory which has an unsupported mix of flags set, ZIPL will panic
> instead of booting the OS.
> 
> As the lowcore can have quite a high entropy for a guest that did drop
> out of protected mode (i.e. rebooted) we encountered the ZIPL panic
> quite often.
> 
> Signed-off-by: Janosch Frank 
> Tested-by: Marc Hartmayer 
> ---
>  pc-bios/s390-ccw/jump2ipl.c  |  1 +
>  pc-bios/s390-ccw/main.c  |  8 +++-
>  pc-bios/s390-ccw/netmain.c   |  1 +
>  pc-bios/s390-ccw/s390-arch.h | 10 --
>  pc-bios/s390-ccw/s390-ccw.h  |  1 +
>  5 files changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
> index da13c43cc0..4eba2510b0 100644
> --- a/pc-bios/s390-ccw/jump2ipl.c
> +++ b/pc-bios/s390-ccw/jump2ipl.c
> @@ -35,6 +35,7 @@ void jump_to_IPL_code(uint64_t address)
>  {
>  /* store the subsystem information _after_ the bootmap was loaded */
>  write_subsystem_identification();
> +write_iplb_location();
>  
>  /* prevent unknown IPL types in the guest */
>  if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index a21b386280..4e65b411e1 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -9,6 +9,7 @@
>   */
>  
>  #include "libc.h"
> +#include "helper.h"
>  #include "s390-arch.h"
>  #include "s390-ccw.h"
>  #include "cio.h"
> @@ -22,7 +23,7 @@ QemuIplParameters qipl;
>  IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
>  static bool have_iplb;
>  static uint16_t cutype;
> -LowCore const *lowcore; /* Yes, this *is* a pointer to address 0 */
> +LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
>  
>  #define LOADPARM_PROMPT "PROMPT  "
>  #define LOADPARM_EMPTY  ""
> @@ -42,6 +43,11 @@ void write_subsystem_identification(void)
>  *zeroes = 0;
>  }
>  
> +void write_iplb_location(void)
> +{
> +lowcore->ptr_iplb = ptr2u32(&iplb);
> +}
> +
>  void panic(const char *string)
>  {
>  sclp_print(string);
> diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
> index f2dcc01e27..309ffa30d9 100644
> --- a/pc-bios/s390-ccw/netmain.c
> +++ b/pc-bios/s390-ccw/netmain.c
> @@ -40,6 +40,7 @@
>  #define DEFAULT_TFTP_RETRIES 20
>  
>  extern char _start[];
> +void write_iplb_location(void) {}
>  
>  #define KERNEL_ADDR ((void *)0L)
>  #define KERNEL_MAX_SIZE ((long)_start)
> diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
> index 504fc7c2f0..5f36361c02 100644
> --- a/pc-bios/s390-ccw/s390-arch.h
> +++ b/pc-bios/s390-ccw/s390-arch.h
> @@ -36,7 +36,13 @@ typedef struct LowCore {
>  /* prefix area: defined by architecture */
>  PSWLegacy   ipl_psw;  /* 0x000 */
>  uint32_tccw1[2];  /* 0x008 */
> -uint32_tccw2[2];  /* 0x010 */
> +union {
> +uint32_tccw2[2];  /* 0x010 */
> +struct {
> +uint32_t reserved10;
> +uint32_t ptr_iplb;
> +};
> +};
>  uint8_t pad1[0x80 - 0x18];/* 0x018 */
>  uint32_text_params;   /* 0x080 */
>  uint16_tcpu_addr; /* 0x084 */
> @@ -85,7 +91,7 @@ typedef struct LowCore {
>  PSW io_new_psw;   /* 0x1f0 */
>  } __attribute__((packed, aligned(8192))) LowCore;
>  
> -extern LowCore const *lowcore;
> +extern LowCore *lowcore;
>  
>  static inline void set_prefix(uint32_t address)
>  {
> diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
> index 11bce7d73c..21f27e7990 100644
> --- a/pc-bios/s390-ccw/s390-ccw.h
> +++ b/pc-bios/s390-ccw/s390-ccw.h
> @@ -57,6 +57,7 @@ void consume_io_int(void);
>  /* main.c */
>  void panic(const char *string);
>  void write_subsystem_identification(void);
> +void write_iplb_location(void);
>  extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
>  unsigned int get_loadparm_index(void);
>  
> 

Reviewed-by: David Hildenbrand 

-- 
Thanks,

David / dhildenb




Re: [PATCH v4 4/5] qcow2: add zstd cluster compression

2020-03-04 Thread Denis Plotnikov




On 04.03.2020 10:49, Vladimir Sementsov-Ogievskiy wrote:

03.03.2020 16:34, Denis Plotnikov wrote:

zstd significantly reduces cluster compression time.
It provides better compression performance maintaining
the same level of the compression ratio in comparison with
zlib, which, at the moment, is the only compression
method available.

The performance test results:
Test compresses and decompresses qemu qcow2 image with just
installed rhel-7.6 guest.
Image cluster size: 64K. Image on disk size: 2.2G

The test was conducted with brd disk to reduce the influence
of disk subsystem to the test results.
The results is given in seconds.

compress cmd:
   time ./qemu-img convert -O qcow2 -c -o compression_type=[zlib|zstd]
   src.img [zlib|zstd]_compressed.img
decompress cmd
   time ./qemu-img convert -O qcow2
   [zlib|zstd]_compressed.img uncompressed.img

    compression   decompression
  zlib   zstd   zlib zstd

real 65.5   16.3 (-75 %)    1.9  1.6 (-16 %)
user 65.0   15.8    5.3  2.5
sys   3.3    0.2    2.0  2.0

Both ZLIB and ZSTD gave the same compression ratio: 1.57
compressed image size in both cases: 1.4G

Signed-off-by: Denis Plotnikov 
---


[..]


+static ssize_t qcow2_zstd_compress(void *dest, size_t dest_size,
+   const void *src, size_t src_size)
+{
+    size_t ret;
+
+    /*
+ * steal ZSTD_LEN_BUF bytes in the very beginning of the buffer
+ * to store compressed chunk size
+ */
+    char *d_buf = ((char *) dest) + ZSTD_LEN_BUF;
+
+    /*
+ * sanity check that we can store the compressed data length,
+ * and there is some space left for the compressor buffer
+ */
+    if (dest_size <= ZSTD_LEN_BUF) {
+    return -ENOMEM;
+    }
+
+    dest_size -= ZSTD_LEN_BUF;
+
+    ret = ZSTD_compress(d_buf, dest_size, src, src_size, 5);


You may want to define ZSTD_COMPRESSION_LEVEL constant instead of raw 
number.
I didn't introduce it intentionally. zlib compression has the 
compression level hardcoded as well.
I think it's better to introduce the compression level for both of them 
in the future but not in the scope of this series.

anyway,
Reviewed-by: Vladimir Sementsov-Ogievskiy 









Re: [PATCH v4 5/5] iotests: 287: add qcow2 compression type test

2020-03-04 Thread Denis Plotnikov




On 04.03.2020 14:27, Vladimir Sementsov-Ogievskiy wrote:

03.03.2020 16:34, Denis Plotnikov wrote:

The test checks fulfilling qcow2 requiriements for the compression
type feature and zstd compression type operability.

Signed-off-by: Denis Plotnikov 
---
  tests/qemu-iotests/287 | 127 +
  tests/qemu-iotests/287.out |  43 +
  tests/qemu-iotests/group   |   1 +
  3 files changed, 171 insertions(+)
  create mode 100755 tests/qemu-iotests/287
  create mode 100644 tests/qemu-iotests/287.out

diff --git a/tests/qemu-iotests/287 b/tests/qemu-iotests/287
new file mode 100755
index 00..39cb665c85
--- /dev/null
+++ b/tests/qemu-iotests/287


[..]


+# Test: using zstd compression, write to and read from an image
+echo
+echo "=== Testing reading and writing with zstd ==="
+echo
+
+CLUSTER_SIZE=65536
+IMGOPTS='compression_type=zstd' _make_test_img 64M


As I understand, you should define env variable assignments on the 
same line

with _make_test_img so that they be passed to it, like
CLUSTER_SIZE=65536 IMGOPTS='compression_type=zstd' _make_test_img 64M
It works like a regular env variable and can be defined on another line 
above.
Anyway, I'll move "CLUSTER_SIZE=65536" to the beginning of the test to 
avoid any confusions.


with this:
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Thanks for reviewing the series! l'll send v5 with all modifications 
shortly.


Denis



+$QEMU_IO -c "write -c -P 0xAC 65536 64k " "$TEST_IMG" | _filter_qemu_io


you may s/65536/64k/


+$QEMU_IO -c "read -P 0xAC 65536 65536 " "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -v 131070 8 " "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "read -v 65534 8" "$TEST_IMG" | _filter_qemu_io
+



[..]







[PATCH v2 0/4] Introducing QMP query-netdevs command

2020-03-04 Thread Alexey Kirillov
This patch series introduces a new QMP command "query-netdevs" to get
information about currently attached network devices.
Also, since the "info_str" field of "NetClientState" is now deprecated,
it has been completely removed.
The HMP command "info network" now also uses the new QMP command inside.

Usage example:

-> { "execute": "query-netdevs" }
<- { "return": [
 {
 "peer": "netdev0",
 "netdev": "netdev0",
 "perm-mac": "52:54:00:12:34:56"
 "model": "virtio-net-pci",
 "macaddr": "52:54:00:12:34:56",
 "queues-count": 1,
 "type": "nic",
 "id": "net0"
 },
 {
 "peer": "net0",
 "ipv6": true,
 "ipv4": true,
 "host": "10.0.2.2",
 "queues-count": 1,
 "ipv6-dns": "fec0::3",
 "ipv6-prefix": "fec0::",
 "net": "10.0.2.0/255.255.255.0",
 "ipv6-host": "fec0::2",
 "type": "user",
 "dns": "10.0.2.3",
 "hostfwd": [
 {
 "str": "tcp::20004-:22"
 }
 ],
 "ipv6-prefixlen": 64,
 "id": "netdev0",
 "restrict": false
 }
 ]
   }

v2->v1:
- Rewrite HMP "info network" to get information from results of QMP command.
- Remove obsolete field "info_str" from "NetClientState".

Alexey Kirillov (4):
  qapi: net: Add query-netdevs command
  tests: Add tests for query-netdevs command
  hmp: Use QMP query-netdevs in hmp_info_network
  net: Remove field info_str of NetClientState

 hw/net/allwinner_emac.c  |   2 +-
 hw/net/dp8393x.c |   2 +-
 hw/net/e1000.c   |   4 +-
 hw/net/e1000e.c  |   2 +-
 hw/net/e1000e_core.c |   2 +-
 hw/net/e1000x_common.c   |   2 +-
 hw/net/eepro100.c|   5 +-
 hw/net/etraxfs_eth.c |   2 +-
 hw/net/fsl_etsec/etsec.c |   2 +-
 hw/net/ftgmac100.c   |   2 +-
 hw/net/i82596.c  |   6 +-
 hw/net/imx_fec.c |   2 +-
 hw/net/lan9118.c |   4 +-
 hw/net/mcf_fec.c |   2 +-
 hw/net/milkymist-minimac2.c  |   2 +-
 hw/net/mipsnet.c |   2 +-
 hw/net/ne2000-isa.c  |   2 +-
 hw/net/ne2000-pci.c  |   2 +-
 hw/net/pcnet.c   |   2 +-
 hw/net/rocker/rocker_fp.c|   4 +-
 hw/net/rtl8139.c |   6 +-
 hw/net/smc91c111.c   |   2 +-
 hw/net/spapr_llan.c  |   6 +-
 hw/net/stellaris_enet.c  |   2 +-
 hw/net/sungem.c  |   4 +-
 hw/net/sunhme.c  |   2 +-
 hw/net/tulip.c   |   2 +-
 hw/net/virtio-net.c  |   8 +-
 hw/net/vmxnet3.c |   4 +-
 hw/net/xen_nic.c |   4 -
 hw/net/xgmac.c   |   2 +-
 hw/net/xilinx_axienet.c  |   2 +-
 hw/net/xilinx_ethlite.c  |   2 +-
 hw/usb/dev-network.c |   2 +-
 include/net/net.h|   7 +-
 net/clients.h|   1 +
 net/hub.c|  12 +-
 net/hub.h|   2 +-
 net/l2tpv3.c |  20 ++-
 net/net.c| 272 +--
 net/netmap.c |  13 ++
 net/slirp.c  | 128 ++-
 net/socket.c |  93 ---
 net/tap-win32.c  |   9 +
 net/tap.c| 107 ++--
 net/vde.c|  40 -
 net/vhost-user.c |  20 ++-
 qapi/net.json|  89 ++
 tests/qtest/Makefile.include |   2 +
 tests/qtest/test-query-netdevs.c | 120 ++
 50 files changed, 917 insertions(+), 119 deletions(-)
 create mode 100644 tests/qtest/test-query-netdevs.c

-- 
2.17.1




[PATCH v2 1/4] qapi: net: Add query-netdevs command

2020-03-04 Thread Alexey Kirillov
Add a qmp command that provides information about currently attached
network devices and their configuration.

Signed-off-by: Alexey Kirillov 
---
 include/net/net.h |   1 +
 net/hub.c |   8 +++
 net/l2tpv3.c  |  19 +++
 net/net.c |  91 +
 net/netmap.c  |  13 +
 net/slirp.c   | 126 ++
 net/socket.c  |  71 ++
 net/tap-win32.c   |   9 
 net/tap.c | 103 +++--
 net/vde.c |  26 ++
 net/vhost-user.c  |  18 +--
 qapi/net.json |  89 
 12 files changed, 566 insertions(+), 8 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index e175ba9677..2c8956c0b3 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -92,6 +92,7 @@ struct NetClientState {
 char *model;
 char *name;
 char info_str[256];
+NetdevInfo *stored_config;
 unsigned receive_disabled : 1;
 NetClientDestructor *destructor;
 unsigned int queue_index;
diff --git a/net/hub.c b/net/hub.c
index 5795a678ed..37995b5517 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -148,6 +148,7 @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char 
*name,
 NetHubPort *port;
 int id = hub->num_ports++;
 char default_name[128];
+NetdevHubPortOptions *stored;
 
 if (!name) {
 snprintf(default_name, sizeof(default_name),
@@ -160,6 +161,13 @@ static NetHubPort *net_hub_port_new(NetHub *hub, const 
char *name,
 port->id = id;
 port->hub = hub;
 
+/* Store startup parameters */
+nc->stored_config = g_new0(NetdevInfo, 1);
+nc->stored_config->type = NET_CLIENT_DRIVER_HUBPORT;
+stored = &nc->stored_config->u.hubport;
+
+stored->hubid = hub->id;
+
 QLIST_INSERT_HEAD(&hub->ports, port, next);
 
 return port;
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
index 55fea17c0f..f4e45e7b28 100644
--- a/net/l2tpv3.c
+++ b/net/l2tpv3.c
@@ -535,6 +535,7 @@ int net_init_l2tpv3(const Netdev *netdev,
 struct addrinfo hints;
 struct addrinfo *result = NULL;
 char *srcport, *dstport;
+NetdevL2TPv3Options *stored;
 
 nc = qemu_new_net_client(&net_l2tpv3_info, peer, "l2tpv3", name);
 
@@ -726,6 +727,24 @@ int net_init_l2tpv3(const Netdev *netdev,
 
 l2tpv3_read_poll(s, true);
 
+/* Store startup parameters */
+nc->stored_config = g_new0(NetdevInfo, 1);
+nc->stored_config->type = NET_CLIENT_DRIVER_L2TPV3;
+stored = &nc->stored_config->u.l2tpv3;
+
+memcpy(stored, l2tpv3, sizeof(NetdevL2TPv3Options));
+
+stored->src = g_strdup(l2tpv3->src);
+stored->dst = g_strdup(l2tpv3->dst);
+
+if (l2tpv3->has_srcport) {
+stored->srcport = g_strdup(l2tpv3->srcport);
+}
+
+if (l2tpv3->has_dstport) {
+stored->dstport = g_strdup(l2tpv3->dstport);
+}
+
 snprintf(s->nc.info_str, sizeof(s->nc.info_str),
  "l2tpv3: connected");
 return 0;
diff --git a/net/net.c b/net/net.c
index 9e93c3f8a1..01e0548295 100644
--- a/net/net.c
+++ b/net/net.c
@@ -54,6 +54,7 @@
 #include "sysemu/sysemu.h"
 #include "net/filter.h"
 #include "qapi/string-output-visitor.h"
+#include "qapi/clone-visitor.h"
 
 /* Net bridge is currently not supported for W32. */
 #if !defined(_WIN32)
@@ -128,6 +129,12 @@ char *qemu_mac_strdup_printf(const uint8_t *macaddr)
 
 void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
 {
+g_assert(nc->stored_config);
+
+g_free(nc->stored_config->u.nic.macaddr);
+nc->stored_config->u.nic.macaddr = g_strdup_printf(MAC_FMT,
+   MAC_ARG(macaddr));
+
 snprintf(nc->info_str, sizeof(nc->info_str),
  "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
  nc->model,
@@ -283,6 +290,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
 NetClientState **peers = conf->peers.ncs;
 NICState *nic;
 int i, queues = MAX(1, conf->peers.queues);
+NetLegacyNicOptions *stored;
 
 assert(info->type == NET_CLIENT_DRIVER_NIC);
 assert(info->size >= sizeof(NICState));
@@ -298,6 +306,27 @@ NICState *qemu_new_nic(NetClientInfo *info,
 nic->ncs[i].queue_index = i;
 }
 
+/* Store startup parameters */
+nic->ncs[0].stored_config = g_new0(NetdevInfo, 1);
+nic->ncs[0].stored_config->type = NET_CLIENT_DRIVER_NIC;
+stored = &nic->ncs[0].stored_config->u.nic;
+
+/* Read-only in runtime */
+nic->ncs[0].stored_config->has_perm_mac = true;
+nic->ncs[0].stored_config->perm_mac = g_strdup_printf(MAC_FMT,
+MAC_ARG(conf->macaddr.a));
+
+if (peers[0]) {
+stored->has_netdev = true;
+stored->netdev = g_strdup(peers[0]->name);
+}
+
+stored->has_macaddr = true;
+stored->macaddr = g_strdup_printf(MAC_FMT, MAC_ARG(conf->macaddr.a));
+
+stored->has_model = true;
+stored->model = g_strdup(model);
+
 return nic;
 }
 
@@ -34

[PATCH v2 3/4] hmp: Use QMP query-netdevs in hmp_info_network

2020-03-04 Thread Alexey Kirillov
Replace legacy field info_str of NetClientState with
result of QMP command query-netdevs.

Signed-off-by: Alexey Kirillov 
---
 include/net/net.h |   3 +-
 net/clients.h |   1 +
 net/hub.c |   4 +-
 net/hub.h |   2 +-
 net/net.c | 175 --
 net/vde.c |  10 +++
 6 files changed, 186 insertions(+), 9 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 2c8956c0b3..9df4680937 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -171,7 +171,8 @@ void qemu_check_nic_model(NICInfo *nd, const char *model);
 int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 const char *default_model);
 
-void print_net_client(Monitor *mon, NetClientState *nc);
+void print_net_client(Monitor *mon, NetClientState *nc,
+  NetdevInfoList *ni_list);
 void hmp_info_network(Monitor *mon, const QDict *qdict);
 void net_socket_rs_init(SocketReadState *rs,
 SocketReadStateFinalize *finalize,
diff --git a/net/clients.h b/net/clients.h
index a6ef267e19..f439933522 100644
--- a/net/clients.h
+++ b/net/clients.h
@@ -51,6 +51,7 @@ int net_init_l2tpv3(const Netdev *netdev, const char *name,
 #ifdef CONFIG_VDE
 int net_init_vde(const Netdev *netdev, const char *name,
  NetClientState *peer, Error **errp);
+int net_vde_get_fd(const NetClientState *nc);
 #endif
 
 #ifdef CONFIG_NETMAP
diff --git a/net/hub.c b/net/hub.c
index 37995b5517..cce970b59d 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -252,7 +252,7 @@ NetClientState *net_hub_port_find(int hub_id)
 /**
  * Print hub configuration
  */
-void net_hub_info(Monitor *mon)
+void net_hub_info(Monitor *mon, NetdevInfoList *ni_list)
 {
 NetHub *hub;
 NetHubPort *port;
@@ -263,7 +263,7 @@ void net_hub_info(Monitor *mon)
 monitor_printf(mon, " \\ %s", port->nc.name);
 if (port->nc.peer) {
 monitor_printf(mon, ": ");
-print_net_client(mon, port->nc.peer);
+print_net_client(mon, port->nc.peer, ni_list);
 } else {
 monitor_printf(mon, "\n");
 }
diff --git a/net/hub.h b/net/hub.h
index 66d3322fac..424658a4a2 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -19,7 +19,7 @@
 NetClientState *net_hub_add_port(int hub_id, const char *name,
  NetClientState *hubpeer);
 NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
-void net_hub_info(Monitor *mon);
+void net_hub_info(Monitor *mon, NetdevInfoList *ninfo);
 void net_hub_check_clients(void);
 bool net_hub_flush(NetClientState *nc);
 
diff --git a/net/net.c b/net/net.c
index 01e0548295..1a8153dbf7 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1271,14 +1271,176 @@ static void netfilter_print_info(Monitor *mon, 
NetFilterState *nf)
 monitor_printf(mon, "\n");
 }
 
-void print_net_client(Monitor *mon, NetClientState *nc)
+static NetdevInfo *get_netdev_info(NetdevInfoList *ni_list, char *name)
+{
+NetdevInfo *ni;
+
+while (ni_list) {
+ni = ni_list->value;
+if (g_str_equal(ni->id, name)) {
+return ni;
+}
+ni_list = ni_list->next;
+}
+
+return NULL;
+}
+
+static char *generate_info_str(NetdevInfo *ni, NetClientState *nc)
+{
+char *info_str;
+
+if (!ni) {
+return g_malloc0(1);
+}
+
+switch (ni->type) {
+case NET_CLIENT_DRIVER_NIC: {
+info_str = g_strdup_printf("model=%s,macaddr=%s",
+   ni->u.nic.model,
+   ni->u.nic.macaddr);
+break;
+}
+#ifdef CONFIG_SLIRP
+case NET_CLIENT_DRIVER_USER: {
+size_t len = strchr(ni->u.user.net, '/') - ni->u.user.net;
+char *net = g_strndup(ni->u.user.net, len);
+
+info_str = g_strdup_printf("net=%s,restrict=%s",
+   net,
+   ni->u.user.q_restrict ? "on" : "off");
+g_free(net);
+break;
+}
+#endif /* CONFIG_SLIRP */
+case NET_CLIENT_DRIVER_TAP: {
+#ifndef _WIN32
+if (ni->u.tap.has_fds) {
+char **fds = g_strsplit(ni->u.tap.fds, ":", -1);
+
+info_str = g_strdup_printf("fd=%s", fds[nc->queue_index]);
+g_strfreev(fds);
+} else if (ni->u.tap.has_helper) {
+info_str = g_strdup_printf("helper=%s", ni->u.tap.helper);
+} else {
+info_str = g_strdup_printf("ifname=%s,script=%s,downscript=%s",
+ni->u.tap.ifname,
+nc->queue_index == 0 ? ni->u.tap.script : "no",
+nc->queue_index == 0 ? ni->u.tap.downscript : "no");
+}
+#else
+info_str = g_strdup_printf("tap: ifname=%s", ni->u.tap.ifname);
+#endif /* _WIN32 */
+break;
+}
+#ifdef CONFI

[PATCH v2 2/4] tests: Add tests for query-netdevs command

2020-03-04 Thread Alexey Kirillov
Signed-off-by: Alexey Kirillov 
---
 tests/qtest/Makefile.include |   2 +
 tests/qtest/test-query-netdevs.c | 120 +++
 2 files changed, 122 insertions(+)
 create mode 100644 tests/qtest/test-query-netdevs.c

diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index e769c1ad70..6924843ef9 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -9,6 +9,7 @@ check-qtest-generic-y += qmp-cmd-test
 check-qtest-generic-y += qom-test
 check-qtest-generic-$(CONFIG_MODULES) += modules-test
 check-qtest-generic-y += test-hmp
+check-qtest-generic-$(CONFIG_SLIRP) += test-query-netdevs
 
 check-qtest-pci-$(CONFIG_RTL8139_PCI) += rtl8139-test
 check-qtest-pci-$(CONFIG_VGA) += display-vga-test
@@ -303,6 +304,7 @@ tests/qtest/tpm-crb-test$(EXESUF): 
tests/qtest/tpm-crb-test.o tests/qtest/tpm-em
 tests/qtest/tpm-tis-swtpm-test$(EXESUF): tests/qtest/tpm-tis-swtpm-test.o 
tests/qtest/tpm-emu.o \
tests/qtest/tpm-util.o tests/qtest/tpm-tests.o $(test-io-obj-y)
 tests/qtest/tpm-tis-test$(EXESUF): tests/qtest/tpm-tis-test.o 
tests/qtest/tpm-emu.o $(test-io-obj-y)
+tests/qtest/test-query-netdevs$(EXESUF): tests/qtest/test-query-netdevs.o
 
 # QTest rules
 
diff --git a/tests/qtest/test-query-netdevs.c b/tests/qtest/test-query-netdevs.c
new file mode 100644
index 00..e077358a50
--- /dev/null
+++ b/tests/qtest/test-query-netdevs.c
@@ -0,0 +1,120 @@
+/*
+ * QTest testcase for the query-netdevs
+ *
+ * Copyright Yandex N.V., 2019
+ *
+ * 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 "libqtest.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qlist.h"
+
+/*
+ * Events can get in the way of responses we are actually waiting for.
+ */
+GCC_FMT_ATTR(2, 3)
+static QObject *wait_command(QTestState *who, const char *command, ...)
+{
+va_list ap;
+QDict *response;
+QObject *result;
+
+va_start(ap, command);
+qtest_qmp_vsend(who, command, ap);
+va_end(ap);
+
+response = qtest_qmp_receive(who);
+
+result = qdict_get(response, "return");
+g_assert(result);
+qobject_ref(result);
+qobject_unref(response);
+
+return result;
+}
+
+static void qmp_query_netdevs_no_error(QTestState *qts,
+   size_t netdevs_count)
+{
+QObject *resp;
+QList *netdevs;
+
+resp = wait_command(qts, "{'execute': 'query-netdevs'}");
+
+netdevs = qobject_to(QList, resp);
+g_assert(netdevs);
+g_assert(qlist_size(netdevs) == netdevs_count);
+
+qobject_unref(resp);
+}
+
+static void test_query_netdevs(void)
+{
+const char *arch = qtest_get_arch();
+size_t correction = 0;
+QObject *resp;
+QTestState *state;
+
+/* Archs which still have a netdev despite of -nodefaults */
+if (g_str_equal(arch, "cris") ||
+g_str_equal(arch, "microblaze") ||
+g_str_equal(arch, "microblazeel") ||
+g_str_equal(arch, "sparc")) {
+correction = 1;
+}
+
+if (g_str_equal(arch, "arm") ||
+g_str_equal(arch, "aarch64")) {
+state = qtest_init(
+"-nodefaults "
+"-M virt "
+"-netdev user,id=slirp0");
+} else if (g_str_equal(arch, "tricore")) {
+state = qtest_init(
+"-nodefaults "
+"-M tricore_testboard "
+"-netdev user,id=slirp0");
+} else {
+state = qtest_init(
+"-nodefaults "
+"-netdev user,id=slirp0");
+}
+g_assert(state);
+
+qmp_query_netdevs_no_error(state, 1 + correction);
+
+resp = wait_command(state,
+"{'execute': 'netdev_add', 'arguments': {"
+" 'id': 'slirp1',"
+" 'type': 'user'}}");
+qobject_unref(resp);
+
+qmp_query_netdevs_no_error(state, 2 + correction);
+
+resp = wait_command(state,
+"{'execute': 'netdev_del', 'arguments': {"
+" 'id': 'slirp1'}}");
+qobject_unref(resp);
+
+qmp_query_netdevs_no_error(state, 1 + correction);
+
+qtest_quit(state);
+}
+
+int main(int argc, char **argv)
+{
+int ret = 0;
+g_test_init(&argc, &argv, NULL);
+
+qtest_add_func("/net/qapi/query_netdevs",
+test_query_netdevs);
+
+ret = g_test_run();
+
+return ret;
+}
-- 
2.17.1




[PATCH v2 4/4] net: Remove field info_str of NetClientState

2020-03-04 Thread Alexey Kirillov
Completely remove the info_str field of struct NetClientState because
it is no longer required due to the addition of the QMP query-netdevs command.

Signed-off-by: Alexey Kirillov 
---
 hw/net/allwinner_emac.c |  2 +-
 hw/net/dp8393x.c|  2 +-
 hw/net/e1000.c  |  4 ++--
 hw/net/e1000e.c |  2 +-
 hw/net/e1000e_core.c|  2 +-
 hw/net/e1000x_common.c  |  2 +-
 hw/net/eepro100.c   |  5 +++--
 hw/net/etraxfs_eth.c|  2 +-
 hw/net/fsl_etsec/etsec.c|  2 +-
 hw/net/ftgmac100.c  |  2 +-
 hw/net/i82596.c |  6 +++---
 hw/net/imx_fec.c|  2 +-
 hw/net/lan9118.c|  4 ++--
 hw/net/mcf_fec.c|  2 +-
 hw/net/milkymist-minimac2.c |  2 +-
 hw/net/mipsnet.c|  2 +-
 hw/net/ne2000-isa.c |  2 +-
 hw/net/ne2000-pci.c |  2 +-
 hw/net/pcnet.c  |  2 +-
 hw/net/rocker/rocker_fp.c   |  4 ++--
 hw/net/rtl8139.c|  6 +++---
 hw/net/smc91c111.c  |  2 +-
 hw/net/spapr_llan.c |  6 +++---
 hw/net/stellaris_enet.c |  2 +-
 hw/net/sungem.c |  4 ++--
 hw/net/sunhme.c |  2 +-
 hw/net/tulip.c  |  2 +-
 hw/net/virtio-net.c |  8 
 hw/net/vmxnet3.c|  4 ++--
 hw/net/xen_nic.c|  4 
 hw/net/xgmac.c  |  2 +-
 hw/net/xilinx_axienet.c |  2 +-
 hw/net/xilinx_ethlite.c |  2 +-
 hw/usb/dev-network.c|  2 +-
 include/net/net.h   |  3 +--
 net/l2tpv3.c|  3 ---
 net/net.c   |  8 +---
 net/slirp.c |  4 
 net/socket.c| 24 
 net/tap.c   | 12 
 net/vde.c   |  4 
 net/vhost-user.c|  2 --
 42 files changed, 51 insertions(+), 110 deletions(-)

diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c
index e9bbff8710..6abbdbfd4b 100644
--- a/hw/net/allwinner_emac.c
+++ b/hw/net/allwinner_emac.c
@@ -454,7 +454,7 @@ static void aw_emac_realize(DeviceState *dev, Error **errp)
 qemu_macaddr_default_if_unset(&s->conf.macaddr);
 s->nic = qemu_new_nic(&net_aw_emac_info, &s->conf,
   object_get_typename(OBJECT(dev)), dev->id, s);
-qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 
 fifo8_create(&s->rx_fifo, RX_FIFO_SIZE);
 fifo8_create(&s->tx_fifo[0], TX_FIFO_SIZE);
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 8a3504d962..a6f95b097b 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -982,7 +982,7 @@ static void dp8393x_realize(DeviceState *dev, Error **errp)
 
 s->nic = qemu_new_nic(&net_dp83932_info, &s->conf,
   object_get_typename(OBJECT(dev)), dev->id, s);
-qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+qemu_update_nic_macaddr(qemu_get_queue(s->nic), s->conf.macaddr.a);
 
 s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
 
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 0b833d5a15..5ae52e37ea 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1095,7 +1095,7 @@ mac_writereg(E1000State *s, int index, uint32_t val)
 if (index == RA + 1) {
 macaddr[0] = cpu_to_le32(s->mac_reg[RA]);
 macaddr[1] = cpu_to_le32(s->mac_reg[RA + 1]);
-qemu_format_nic_info_str(qemu_get_queue(s->nic), (uint8_t *)macaddr);
+qemu_update_nic_macaddr(qemu_get_queue(s->nic), (uint8_t *)macaddr);
 }
 }
 
@@ -1711,7 +1711,7 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error 
**errp)
 d->nic = qemu_new_nic(&net_e1000_info, &d->conf,
   object_get_typename(OBJECT(d)), dev->id, d);
 
-qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr);
+qemu_update_nic_macaddr(qemu_get_queue(d->nic), macaddr);
 
 d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, 
d);
 d->mit_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000_mit_timer, d);
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index a91dbdca3c..763661227d 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -333,7 +333,7 @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, 
uint8_t *macaddr)
 trace_e1000e_mac_set_permanent(MAC_ARG(macaddr));
 memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac));
 
-qemu_format_nic_info_str(qemu_get_queue(s->nic), macaddr);
+qemu_update_nic_macaddr(qemu_get_queue(s->nic), macaddr);
 
 /* Setup virtio headers */
 if (s->disable_vnet) {
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index 94ea34dca5..358e90b40d 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -2731,7 +2731,7 @@ e1000e_mac_setmacaddr(E1000ECore *core, int index, 
uint32_t val)
 
 macaddr[0] = cpu_to_le32(core->mac[RA]);
 macaddr[1] = cpu_to_le32(core->mac[RA + 1]);
-qemu_fo

[PULL v1 07/10] docs/specs/tpm: Document TPM_TIS sysbus device for ARM

2020-03-04 Thread Stefan Berger
From: Eric Auger 

Update the documentation with recent changes related to the
sysbus TPM_TIS device addition and add the command line
to be used with arm VIRT.

Signed-off-by: Eric Auger 
Reviewed-by: Stefan Berger 
Message-id: 20200226205942.11424-8-eric.au...@redhat.com
Signed-off-by: Stefan Berger 
---
 docs/specs/tpm.rst | 25 -
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/docs/specs/tpm.rst b/docs/specs/tpm.rst
index 2bdf637f55..da9eb39ca9 100644
--- a/docs/specs/tpm.rst
+++ b/docs/specs/tpm.rst
@@ -18,9 +18,15 @@ The TIS interface makes a memory mapped IO region in the area
 0xfed4-0xfed44fff available to the guest operating system.
 
 QEMU files related to TPM TIS interface:
- - ``hw/tpm/tpm_tis.c``
+ - ``hw/tpm/tpm_tis_common.c``
+ - ``hw/tpm/tpm_tis_isa.c``
+ - ``hw/tpm/tpm_tis_sysbus.c``
  - ``hw/tpm/tpm_tis.h``
 
+Both an ISA device and a sysbus device are available. The former is
+used with pc/q35 machine while the latter can be instantiated in the
+ARM virt machine.
+
 CRB interface
 -
 
@@ -325,6 +331,23 @@ In case a pSeries machine is emulated, use the following 
command line:
 -device 
virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,id=virtio-disk0
 \
 -drive file=test.img,format=raw,if=none,id=drive-virtio-disk0
 
+In case an ARM virt machine is emulated, use the following command line:
+
+.. code-block:: console
+
+  qemu-system-aarch64 -machine virt,gic-version=3,accel=kvm \
+-cpu host -m 4G \
+-nographic -no-acpi \
+-chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
+-tpmdev emulator,id=tpm0,chardev=chrtpm \
+-device tpm-tis-device,tpmdev=tpm0 \
+-device virtio-blk-pci,drive=drv0 \
+-drive format=qcow2,file=hda.qcow2,if=none,id=drv0 \
+-drive if=pflash,format=raw,file=flash0.img,readonly \
+-drive if=pflash,format=raw,file=flash1.img
+
+  On ARM, ACPI boot with TPM is not yet supported.
+
 In case SeaBIOS is used as firmware, it should show the TPM menu item
 after entering the menu with 'ESC'.
 
-- 
2.24.1




[PULL v1 10/10] test: tpm-tis: Add Sysbus TPM-TIS device test

2020-03-04 Thread Stefan Berger
From: Eric Auger 

The tests themselves are the same as the ISA device ones.
Only the main() changes as the "tpm-tis-device" device gets
instantiated. Also the base address of the device is not
0xFED4 anymore but matches the base address of the
ARM virt platform bus.

Signed-off-by: Eric Auger 
Reviewed-by: Stefan Berger 
Message-id: 20200226205942.11424-11-eric.au...@redhat.com
Signed-off-by: Stefan Berger 
---
 tests/qtest/Makefile.include|  5 ++
 tests/qtest/tpm-tis-device-swtpm-test.c | 76 +
 tests/qtest/tpm-tis-device-test.c   | 87 +
 3 files changed, 168 insertions(+)
 create mode 100644 tests/qtest/tpm-tis-device-swtpm-test.c
 create mode 100644 tests/qtest/tpm-tis-device-test.c

diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index 44aac68b25..383b0ab217 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -130,6 +130,8 @@ check-qtest-arm-y += hexloader-test
 check-qtest-arm-$(CONFIG_PFLASH_CFI02) += pflash-cfi02-test
 
 check-qtest-aarch64-y += arm-cpu-features
+check-qtest-aarch64-$(CONFIG_TPM_TIS_SYSBUS) += tpm-tis-device-test
+check-qtest-aarch64-$(CONFIG_TPM_TIS_SYSBUS) += tpm-tis-device-swtpm-test
 check-qtest-aarch64-y += numa-test
 check-qtest-aarch64-y += boot-serial-test
 check-qtest-aarch64-y += migration-test
@@ -302,7 +304,10 @@ tests/qtest/tpm-crb-swtpm-test$(EXESUF): 
tests/qtest/tpm-crb-swtpm-test.o tests/
 tests/qtest/tpm-crb-test$(EXESUF): tests/qtest/tpm-crb-test.o 
tests/qtest/tpm-emu.o $(test-io-obj-y)
 tests/qtest/tpm-tis-swtpm-test$(EXESUF): tests/qtest/tpm-tis-swtpm-test.o 
tests/qtest/tpm-emu.o \
tests/qtest/tpm-util.o tests/qtest/tpm-tests.o $(test-io-obj-y)
+tests/qtest/tpm-tis-device-swtpm-test$(EXESUF): 
tests/qtest/tpm-tis-device-swtpm-test.o tests/qtest/tpm-emu.o \
+   tests/qtest/tpm-util.o tests/qtest/tpm-tests.o $(test-io-obj-y)
 tests/qtest/tpm-tis-test$(EXESUF): tests/qtest/tpm-tis-test.o 
tests/qtest/tpm-tis-util.o tests/qtest/tpm-emu.o $(test-io-obj-y)
+tests/qtest/tpm-tis-device-test$(EXESUF): tests/qtest/tpm-tis-device-test.o 
tests/qtest/tpm-tis-util.o tests/qtest/tpm-emu.o $(test-io-obj-y)
 
 # QTest rules
 
diff --git a/tests/qtest/tpm-tis-device-swtpm-test.c 
b/tests/qtest/tpm-tis-device-swtpm-test.c
new file mode 100644
index 00..7b20035142
--- /dev/null
+++ b/tests/qtest/tpm-tis-device-swtpm-test.c
@@ -0,0 +1,76 @@
+/*
+ * QTest testcase for Sysbus TPM TIS talking to external swtpm and swtpm
+ * migration
+ *
+ * Copyright (c) 2018 IBM Corporation
+ *  with parts borrowed from migration-test.c that is:
+ * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ *   Stefan Berger 
+ *
+ * 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 
+
+#include "libqtest.h"
+#include "qemu/module.h"
+#include "tpm-tests.h"
+#include "hw/acpi/tpm.h"
+
+uint64_t tpm_tis_base_addr = 0xc00;
+#define MACHINE_OPTIONS "-machine virt,gic-version=max -accel tcg"
+
+typedef struct TestState {
+char *src_tpm_path;
+char *dst_tpm_path;
+char *uri;
+} TestState;
+
+static void tpm_tis_swtpm_test(const void *data)
+{
+const TestState *ts = data;
+
+tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer,
+"tpm-tis-device", MACHINE_OPTIONS);
+}
+
+static void tpm_tis_swtpm_migration_test(const void *data)
+{
+const TestState *ts = data;
+
+tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
+  tpm_util_tis_transfer, "tpm-tis-device",
+  MACHINE_OPTIONS);
+}
+
+int main(int argc, char **argv)
+{
+int ret;
+TestState ts = { 0 };
+
+ts.src_tpm_path = g_dir_make_tmp("qemu-tpm-tis-device-swtpm-test.XX",
+ NULL);
+ts.dst_tpm_path = g_dir_make_tmp("qemu-tpm-tis-device-swtpm-test.XX",
+ NULL);
+ts.uri = g_strdup_printf("unix:%s/migsocket", ts.src_tpm_path);
+
+module_call_init(MODULE_INIT_QOM);
+g_test_init(&argc, &argv, NULL);
+
+qtest_add_data_func("/tpm/tis-swtpm/test", &ts, tpm_tis_swtpm_test);
+qtest_add_data_func("/tpm/tis-swtpm-migration/test", &ts,
+tpm_tis_swtpm_migration_test);
+ret = g_test_run();
+
+g_rmdir(ts.dst_tpm_path);
+g_free(ts.dst_tpm_path);
+g_rmdir(ts.src_tpm_path);
+g_free(ts.src_tpm_path);
+g_free(ts.uri);
+
+return ret;
+}
diff --git a/tests/qtest/tpm-tis-device-test.c 
b/tests/qtest/tpm-tis-device-test.c
new file mode 100644
index 00..63ed36440f
--- /dev/null
+++ b/tests/qtest/tpm-tis-device-test.c
@@ -0,0 +1,87 @@
+/*
+ * QTest testcase for SYSBUS TPM TIS
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ * Copyright (c) 2018 IBM Corporation
+ *
+ * Authors:
+ *   Marc-André

[PULL v1 03/10] tpm: Separate tpm_tis common functions from isa code

2020-03-04 Thread Stefan Berger
From: Eric Auger 

Move the device agnostic code into tpm_tis_common.c and
put the ISA device specific code into tpm_tis_isa.c

Signed-off-by: Eric Auger 
Reviewed-by: Stefan Berger 
Tested-by: Ard Biesheuvel 
Acked-by: Ard Biesheuvel 
Message-id: 20200226205942.11424-4-eric.au...@redhat.com
Signed-off-by: Stefan Berger 
---
 hw/tpm/Makefile.objs   |   2 +-
 hw/tpm/tpm_tis.h   |  91 +++
 hw/tpm/{tpm_tis.c => tpm_tis_common.c} | 209 ++---
 hw/tpm/tpm_tis_isa.c   | 170 
 4 files changed, 271 insertions(+), 201 deletions(-)
 create mode 100644 hw/tpm/tpm_tis.h
 rename hw/tpm/{tpm_tis.c => tpm_tis_common.c} (83%)
 create mode 100644 hw/tpm/tpm_tis_isa.c

diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs
index 85eb99ae05..fcc4c2f27c 100644
--- a/hw/tpm/Makefile.objs
+++ b/hw/tpm/Makefile.objs
@@ -1,6 +1,6 @@
 common-obj-$(CONFIG_TPM) += tpm_util.o
 obj-$(call lor,$(CONFIG_TPM_TIS),$(CONFIG_TPM_CRB)) += tpm_ppi.o
-common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o
+common-obj-$(CONFIG_TPM_TIS) += tpm_tis_isa.o tpm_tis_common.o
 common-obj-$(CONFIG_TPM_CRB) += tpm_crb.o
 common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
 common-obj-$(CONFIG_TPM_EMULATOR) += tpm_emulator.o
diff --git a/hw/tpm/tpm_tis.h b/hw/tpm/tpm_tis.h
new file mode 100644
index 00..5554989395
--- /dev/null
+++ b/hw/tpm/tpm_tis.h
@@ -0,0 +1,91 @@
+/*
+ * tpm_tis.h - QEMU's TPM TIS common header
+ *
+ * Copyright (C) 2006,2010-2013 IBM Corporation
+ *
+ * Authors:
+ *  Stefan Berger 
+ *  David Safford 
+ *
+ * Xen 4 support: Andrease Niederl 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * Implementation of the TIS interface according to specs found at
+ * http://www.trustedcomputinggroup.org. This implementation currently
+ * supports version 1.3, 21 March 2013
+ * In the developers menu choose the PC Client section then find the TIS
+ * specification.
+ *
+ * TPM TIS for TPM 2 implementation following TCG PC Client Platform
+ * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43
+ */
+#ifndef TPM_TPM_TIS_H
+#define TPM_TPM_TIS_H
+
+#include "qemu/osdep.h"
+#include "sysemu/tpm_backend.h"
+#include "tpm_ppi.h"
+
+#define TPM_TIS_NUM_LOCALITIES  5 /* per spec */
+#define TPM_TIS_LOCALITY_SHIFT  12
+#define TPM_TIS_NO_LOCALITY 0xff
+
+#define TPM_TIS_IS_VALID_LOCTY(x)   ((x) < TPM_TIS_NUM_LOCALITIES)
+
+#define TPM_TIS_BUFFER_MAX  4096
+
+typedef enum {
+TPM_TIS_STATE_IDLE = 0,
+TPM_TIS_STATE_READY,
+TPM_TIS_STATE_COMPLETION,
+TPM_TIS_STATE_EXECUTION,
+TPM_TIS_STATE_RECEPTION,
+} TPMTISState;
+
+/* locality data  -- all fields are persisted */
+typedef struct TPMLocality {
+TPMTISState state;
+uint8_t access;
+uint32_t sts;
+uint32_t iface_id;
+uint32_t inte;
+uint32_t ints;
+} TPMLocality;
+
+typedef struct TPMState {
+MemoryRegion mmio;
+
+unsigned char buffer[TPM_TIS_BUFFER_MAX];
+uint16_t rw_offset;
+
+uint8_t active_locty;
+uint8_t aborting_locty;
+uint8_t next_locty;
+
+TPMLocality loc[TPM_TIS_NUM_LOCALITIES];
+
+qemu_irq irq;
+uint32_t irq_num;
+
+TPMBackendCmd cmd;
+
+TPMBackend *be_driver;
+TPMVersion be_tpm_version;
+
+size_t be_buffer_size;
+
+bool ppi_enabled;
+TPMPPI ppi;
+} TPMState;
+
+extern const VMStateDescription vmstate_locty;
+extern const MemoryRegionOps tpm_tis_memory_ops;
+
+int tpm_tis_pre_save(TPMState *s);
+void tpm_tis_reset(TPMState *s);
+enum TPMVersion tpm_tis_get_tpm_version(TPMState *s);
+void tpm_tis_request_completed(TPMState *s, int ret);
+
+#endif /* TPM_TPM_TIS_H */
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis_common.c
similarity index 83%
rename from hw/tpm/tpm_tis.c
rename to hw/tpm/tpm_tis_common.c
index fc6d7ca579..9ce64d4836 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis_common.c
@@ -1,5 +1,6 @@
 /*
- * tpm_tis.c - QEMU's TPM TIS interface emulator
+ * tpm_tis_common.c - QEMU's TPM TIS interface emulator
+ * device agnostic functions
  *
  * Copyright (C) 2006,2010-2013 IBM Corporation
  *
@@ -21,7 +22,6 @@
  * TPM TIS for TPM 2 implementation following TCG PC Client Platform
  * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43
  */
-
 #include "qemu/osdep.h"
 #include "hw/irq.h"
 #include "hw/isa/isa.h"
@@ -38,67 +38,7 @@
 #include "tpm_ppi.h"
 #include "trace.h"
 
-#define TPM_TIS_NUM_LOCALITIES  5 /* per spec */
-#define TPM_TIS_LOCALITY_SHIFT  12
-#define TPM_TIS_NO_LOCALITY 0xff
-
-#define TPM_TIS_IS_VALID_LOCTY(x)   ((x) < TPM_TIS_NUM_LOCALITIES)
-
-#define TPM_TIS_BUFFER_MAX  4096
-
-typedef enum {
-TPM_TIS_STATE_IDLE = 0,
-TPM_TIS_STATE_READY,
-TPM_TIS_STATE_COMPLETION,
-TPM_TIS_STATE_EXECUTION,
-TPM_TIS_STATE_RECEPTION,
-} TPMTISState;
-
-/* locality data  -- all fields are persisted */

[PULL v1 08/10] test: tpm: pass optional machine options to swtpm test functions

2020-03-04 Thread Stefan Berger
From: Eric Auger 

We plan to use swtpm test functions on ARM for testing the
sysbus TPM-TIS device. However on ARM there is no default machine
type. So we need to explictly pass some machine options on startup.
Let's allow this by adding a new parameter to both swtpm test
functions and update all call sites.

Signed-off-by: Eric Auger 
Reviewed-by: Stefan Berger 
Message-id: 20200226205942.11424-9-eric.au...@redhat.com
Signed-off-by: Stefan Berger 
---
 tests/qtest/tpm-crb-swtpm-test.c |  5 +++--
 tests/qtest/tpm-tests.c  | 10 ++
 tests/qtest/tpm-tests.h  |  5 +++--
 tests/qtest/tpm-tis-swtpm-test.c |  5 +++--
 tests/qtest/tpm-util.c   |  8 ++--
 tests/qtest/tpm-util.h   |  3 ++-
 6 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/tests/qtest/tpm-crb-swtpm-test.c b/tests/qtest/tpm-crb-swtpm-test.c
index 2c4fb8ae29..5228cb7af4 100644
--- a/tests/qtest/tpm-crb-swtpm-test.c
+++ b/tests/qtest/tpm-crb-swtpm-test.c
@@ -29,7 +29,8 @@ static void tpm_crb_swtpm_test(const void *data)
 {
 const TestState *ts = data;
 
-tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_crb_transfer, "tpm-crb");
+tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_crb_transfer,
+"tpm-crb", NULL);
 }
 
 static void tpm_crb_swtpm_migration_test(const void *data)
@@ -37,7 +38,7 @@ static void tpm_crb_swtpm_migration_test(const void *data)
 const TestState *ts = data;
 
 tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
-  tpm_util_crb_transfer, "tpm-crb");
+  tpm_util_crb_transfer, "tpm-crb", NULL);
 }
 
 int main(int argc, char **argv)
diff --git a/tests/qtest/tpm-tests.c b/tests/qtest/tpm-tests.c
index 6e45a0ba85..a2f2838e15 100644
--- a/tests/qtest/tpm-tests.c
+++ b/tests/qtest/tpm-tests.c
@@ -30,7 +30,7 @@ tpm_test_swtpm_skip(void)
 }
 
 void tpm_test_swtpm_test(const char *src_tpm_path, tx_func *tx,
- const char *ifmodel)
+ const char *ifmodel, const char *machine_options)
 {
 char *args = NULL;
 QTestState *s;
@@ -47,10 +47,11 @@ void tpm_test_swtpm_test(const char *src_tpm_path, tx_func 
*tx,
 g_assert_true(succ);
 
 args = g_strdup_printf(
+"%s "
 "-chardev socket,id=chr,path=%s "
 "-tpmdev emulator,id=dev,chardev=chr "
 "-device %s,tpmdev=dev",
-addr->u.q_unix.path, ifmodel);
+machine_options ? : "", addr->u.q_unix.path, ifmodel);
 
 s = qtest_start(args);
 g_free(args);
@@ -78,7 +79,8 @@ void tpm_test_swtpm_test(const char *src_tpm_path, tx_func 
*tx,
 void tpm_test_swtpm_migration_test(const char *src_tpm_path,
const char *dst_tpm_path,
const char *uri, tx_func *tx,
-   const char *ifmodel)
+   const char *ifmodel,
+   const char *machine_options)
 {
 gboolean succ;
 GPid src_tpm_pid, dst_tpm_pid;
@@ -100,7 +102,7 @@ void tpm_test_swtpm_migration_test(const char *src_tpm_path,
 
 tpm_util_migration_start_qemu(&src_qemu, &dst_qemu,
   src_tpm_addr, dst_tpm_addr, uri,
-  ifmodel);
+  ifmodel, machine_options);
 
 tpm_util_startup(src_qemu, tx);
 tpm_util_pcrextend(src_qemu, tx);
diff --git a/tests/qtest/tpm-tests.h b/tests/qtest/tpm-tests.h
index b97688fe75..a5df35ab5b 100644
--- a/tests/qtest/tpm-tests.h
+++ b/tests/qtest/tpm-tests.h
@@ -16,11 +16,12 @@
 #include "tpm-util.h"
 
 void tpm_test_swtpm_test(const char *src_tpm_path, tx_func *tx,
- const char *ifmodel);
+ const char *ifmodel, const char *machine_options);
 
 void tpm_test_swtpm_migration_test(const char *src_tpm_path,
const char *dst_tpm_path,
const char *uri, tx_func *tx,
-   const char *ifmodel);
+   const char *ifmodel,
+   const char *machine_options);
 
 #endif /* TESTS_TPM_TESTS_H */
diff --git a/tests/qtest/tpm-tis-swtpm-test.c b/tests/qtest/tpm-tis-swtpm-test.c
index 9f58a3a92b..9470f15751 100644
--- a/tests/qtest/tpm-tis-swtpm-test.c
+++ b/tests/qtest/tpm-tis-swtpm-test.c
@@ -29,7 +29,8 @@ static void tpm_tis_swtpm_test(const void *data)
 {
 const TestState *ts = data;
 
-tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer, "tpm-tis");
+tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer,
+"tpm-tis", NULL);
 }
 
 static void tpm_tis_swtpm_migration_test(const void *data)
@@ -37,7 +38,7 @@ static void tpm_tis_swtpm_migration_test(const void *data)
 const TestState *ts = data;
 
 tpm_test_swtpm_migration_test(ts

[PULL v1 05/10] tpm: Add the SysBus TPM TIS device

2020-03-04 Thread Stefan Berger
From: Eric Auger 

Introduce the tpm-tis-device which is a sysbus device
and is bound to be used on ARM.

Signed-off-by: Eric Auger 
Reviewed-by: Stefan Berger 
Tested-by: Ard Biesheuvel 
Acked-by: Ard Biesheuvel 
Message-id: 20200226205942.11424-6-eric.au...@redhat.com
Signed-off-by: Stefan Berger 
---
 hw/tpm/Kconfig  |   5 ++
 hw/tpm/Makefile.objs|   1 +
 hw/tpm/tpm_tis_sysbus.c | 159 
 include/sysemu/tpm.h|   1 +
 4 files changed, 166 insertions(+)
 create mode 100644 hw/tpm/tpm_tis_sysbus.c

diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig
index 686f8206bb..4794e7fe28 100644
--- a/hw/tpm/Kconfig
+++ b/hw/tpm/Kconfig
@@ -7,6 +7,11 @@ config TPM_TIS_ISA
 depends on TPM && ISA_BUS
 select TPM_TIS
 
+config TPM_TIS_SYSBUS
+bool
+depends on TPM
+select TPM_TIS
+
 config TPM_TIS
 bool
 depends on TPM
diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs
index 3ef2036cca..f1ec4beb95 100644
--- a/hw/tpm/Makefile.objs
+++ b/hw/tpm/Makefile.objs
@@ -1,6 +1,7 @@
 common-obj-$(CONFIG_TPM) += tpm_util.o
 obj-$(call lor,$(CONFIG_TPM_TIS),$(CONFIG_TPM_CRB)) += tpm_ppi.o
 common-obj-$(CONFIG_TPM_TIS_ISA) += tpm_tis_isa.o
+common-obj-$(CONFIG_TPM_TIS_SYSBUS) += tpm_tis_sysbus.o
 common-obj-$(CONFIG_TPM_TIS) += tpm_tis_common.o
 common-obj-$(CONFIG_TPM_CRB) += tpm_crb.o
 common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
diff --git a/hw/tpm/tpm_tis_sysbus.c b/hw/tpm/tpm_tis_sysbus.c
new file mode 100644
index 00..18c02aed67
--- /dev/null
+++ b/hw/tpm/tpm_tis_sysbus.c
@@ -0,0 +1,159 @@
+/*
+ * tpm_tis_sysbus.c - QEMU's TPM TIS SYSBUS Device
+ *
+ * Copyright (C) 2006,2010-2013 IBM Corporation
+ *
+ * Authors:
+ *  Stefan Berger 
+ *  David Safford 
+ *
+ * Xen 4 support: Andrease Niederl 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * Implementation of the TIS interface according to specs found at
+ * http://www.trustedcomputinggroup.org. This implementation currently
+ * supports version 1.3, 21 March 2013
+ * In the developers menu choose the PC Client section then find the TIS
+ * specification.
+ *
+ * TPM TIS for TPM 2 implementation following TCG PC Client Platform
+ * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "tpm_util.h"
+#include "hw/sysbus.h"
+#include "tpm_tis.h"
+
+typedef struct TPMStateSysBus {
+/*< private >*/
+SysBusDevice parent_obj;
+
+/*< public >*/
+TPMState state; /* not a QOM object */
+} TPMStateSysBus;
+
+#define TPM_TIS_SYSBUS(obj) OBJECT_CHECK(TPMStateSysBus, (obj), 
TYPE_TPM_TIS_SYSBUS)
+
+static int tpm_tis_pre_save_sysbus(void *opaque)
+{
+TPMStateSysBus *sbdev = opaque;
+
+return tpm_tis_pre_save(&sbdev->state);
+}
+
+static const VMStateDescription vmstate_tpm_tis_sysbus = {
+.name = "tpm-tis",
+.version_id = 0,
+.pre_save  = tpm_tis_pre_save_sysbus,
+.fields = (VMStateField[]) {
+VMSTATE_BUFFER(state.buffer, TPMStateSysBus),
+VMSTATE_UINT16(state.rw_offset, TPMStateSysBus),
+VMSTATE_UINT8(state.active_locty, TPMStateSysBus),
+VMSTATE_UINT8(state.aborting_locty, TPMStateSysBus),
+VMSTATE_UINT8(state.next_locty, TPMStateSysBus),
+
+VMSTATE_STRUCT_ARRAY(state.loc, TPMStateSysBus, TPM_TIS_NUM_LOCALITIES,
+ 0, vmstate_locty, TPMLocality),
+
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void tpm_tis_sysbus_request_completed(TPMIf *ti, int ret)
+{
+TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(ti);
+TPMState *s = &sbdev->state;
+
+tpm_tis_request_completed(s, ret);
+}
+
+static enum TPMVersion tpm_tis_sysbus_get_tpm_version(TPMIf *ti)
+{
+TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(ti);
+TPMState *s = &sbdev->state;
+
+return tpm_tis_get_tpm_version(s);
+}
+
+static void tpm_tis_sysbus_reset(DeviceState *dev)
+{
+TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(dev);
+TPMState *s = &sbdev->state;
+
+return tpm_tis_reset(s);
+}
+
+static Property tpm_tis_sysbus_properties[] = {
+DEFINE_PROP_UINT32("irq", TPMStateSysBus, state.irq_num, TPM_TIS_IRQ),
+DEFINE_PROP_TPMBE("tpmdev", TPMStateSysBus, state.be_driver),
+DEFINE_PROP_BOOL("ppi", TPMStateSysBus, state.ppi_enabled, true),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void tpm_tis_sysbus_initfn(Object *obj)
+{
+TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(obj);
+TPMState *s = &sbdev->state;
+
+memory_region_init_io(&s->mmio, obj, &tpm_tis_memory_ops,
+  s, "tpm-tis-mmio",
+  TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT);
+
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+}
+
+static void tpm_tis_sysbus_realizefn(DeviceState *dev, Error **errp)
+{
+TPMStateSysBus *sbd

[PULL v1 06/10] hw/arm/virt: vTPM support

2020-03-04 Thread Stefan Berger
From: Eric Auger 

Let the TPM TIS SYSBUS device be dynamically instantiable
in ARM virt.  A device tree node is dynamically created
(TPM via MMIO).

The TPM Physical Presence interface (PPI) is not supported.

To run with the swtmp TPM emulator, the qemu command line must
be augmented with:

-chardev socket,id=chrtpm,path=swtpm-sock \
-tpmdev emulator,id=tpm0,chardev=chrtpm \
-device tpm-tis-device,tpmdev=tpm0 \

swtpm/libtpms command line example:

swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm \
--ctrl type=unixio,path=swtpm-sock

Signed-off-by: Eric Auger 
Reviewed-by: Stefan Berger 
Tested-by: Ard Biesheuvel 
Acked-by: Ard Biesheuvel 
Message-id: 20200226205942.11424-7-eric.au...@redhat.com
Signed-off-by: Stefan Berger 
---
 hw/arm/Kconfig  |  1 +
 hw/arm/sysbus-fdt.c | 33 +
 hw/arm/virt.c   |  7 +++
 3 files changed, 41 insertions(+)

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 61635f52c4..bc54fd61f9 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -5,6 +5,7 @@ config ARM_VIRT
 imply VFIO_AMD_XGBE
 imply VFIO_PLATFORM
 imply VFIO_XGMAC
+imply TPM_TIS_SYSBUS
 select A15MPCORE
 select ACPI
 select ARM_SMMUV3
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index 022fc97ecd..f603787b65 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -30,6 +30,7 @@
 #include "hw/arm/sysbus-fdt.h"
 #include "qemu/error-report.h"
 #include "sysemu/device_tree.h"
+#include "sysemu/tpm.h"
 #include "hw/platform-bus.h"
 #include "hw/vfio/vfio-platform.h"
 #include "hw/vfio/vfio-calxeda-xgmac.h"
@@ -434,6 +435,37 @@ static bool vfio_platform_match(SysBusDevice *sbdev,
 #define VFIO_PLATFORM_BINDING(compat, add_fn) \
 {TYPE_VFIO_PLATFORM, (compat), (add_fn), vfio_platform_match}
 
+/*
+ * add_tpm_tis_fdt_node: Create a DT node for TPM TIS
+ *
+ * See kernel documentation:
+ * Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt
+ * Optional interrupt for command completion is not exposed
+ */
+static int add_tpm_tis_fdt_node(SysBusDevice *sbdev, void *opaque)
+{
+PlatformBusFDTData *data = opaque;
+PlatformBusDevice *pbus = data->pbus;
+void *fdt = data->fdt;
+const char *parent_node = data->pbus_node_name;
+char *nodename;
+uint32_t reg_attr[2];
+uint64_t mmio_base;
+
+mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+nodename = g_strdup_printf("%s/tpm_tis@%" PRIx64, parent_node, mmio_base);
+qemu_fdt_add_subnode(fdt, nodename);
+
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "tcg,tpm-tis-mmio");
+
+reg_attr[0] = cpu_to_be32(mmio_base);
+reg_attr[1] = cpu_to_be32(0x5000);
+qemu_fdt_setprop(fdt, nodename, "reg", reg_attr, 2 * sizeof(uint32_t));
+
+g_free(nodename);
+return 0;
+}
+
 #endif /* CONFIG_LINUX */
 
 static int no_fdt_node(SysBusDevice *sbdev, void *opaque)
@@ -455,6 +487,7 @@ static const BindingEntry bindings[] = {
 TYPE_BINDING(TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node),
 TYPE_BINDING(TYPE_VFIO_AMD_XGBE, add_amd_xgbe_fdt_node),
 VFIO_PLATFORM_BINDING("amd,xgbe-seattle-v1a", add_amd_xgbe_fdt_node),
+TYPE_BINDING(TYPE_TPM_TIS_SYSBUS, add_tpm_tis_fdt_node),
 #endif
 TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
 TYPE_BINDING("", NULL), /* last element */
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 856808599d..32d865a488 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -48,6 +48,7 @@
 #include "sysemu/numa.h"
 #include "sysemu/runstate.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/tpm.h"
 #include "sysemu/kvm.h"
 #include "hw/loader.h"
 #include "exec/address-spaces.h"
@@ -2083,6 +2084,7 @@ static void virt_machine_class_init(ObjectClass *oc, void 
*data)
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
+machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
 mc->block_default_type = IF_VIRTIO;
 mc->no_cdrom = 1;
 mc->pci_allow_0_address = true;
@@ -2196,6 +2198,11 @@ type_init(machvirt_machine_init);
 
 static void virt_machine_5_0_options(MachineClass *mc)
 {
+static GlobalProperty compat[] = {
+{ TYPE_TPM_TIS_SYSBUS, "ppi", "false" },
+};
+
+compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
 }
 DEFINE_VIRT_MACHINE_AS_LATEST(5, 0)
 
-- 
2.24.1




[PULL v1 09/10] test: tpm-tis: Get prepared to share tests between ISA and sysbus devices

2020-03-04 Thread Stefan Berger
From: Eric Auger 

ISA and sysbus TPM-TIS devices will share their tests. Only
the main() will change (instantiation option is different).
Also the base address of the TPM-TIS device is going to be
different. on x86 it is located at 0xFED4 while on ARM
it can be located at any location, discovered through the
device tree description.

So we put shared test functions in a new object module.
Each test needs to set tpm_tis_base_addr global variable.

Also take benefit of this move to fix "block comments using
a leading */ on a separate line" checkpatch warnings.

Signed-off-by: Eric Auger 
Reviewed-by: Stefan Berger 
Message-id: 20200226205942.11424-10-eric.au...@redhat.com
Signed-off-by: Stefan Berger 
---
 tests/qtest/Makefile.include |   2 +-
 tests/qtest/tpm-crb-swtpm-test.c |   4 +
 tests/qtest/tpm-crb-test.c   |   3 +
 tests/qtest/tpm-tis-swtpm-test.c |   3 +
 tests/qtest/tpm-tis-test.c   | 414 +---
 tests/qtest/tpm-tis-util.c   | 451 +++
 tests/qtest/tpm-tis-util.h   |  23 ++
 tests/qtest/tpm-util.c   |   3 -
 tests/qtest/tpm-util.h   |   5 +
 9 files changed, 493 insertions(+), 415 deletions(-)
 create mode 100644 tests/qtest/tpm-tis-util.c
 create mode 100644 tests/qtest/tpm-tis-util.h

diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index 028af5b782..44aac68b25 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -302,7 +302,7 @@ tests/qtest/tpm-crb-swtpm-test$(EXESUF): 
tests/qtest/tpm-crb-swtpm-test.o tests/
 tests/qtest/tpm-crb-test$(EXESUF): tests/qtest/tpm-crb-test.o 
tests/qtest/tpm-emu.o $(test-io-obj-y)
 tests/qtest/tpm-tis-swtpm-test$(EXESUF): tests/qtest/tpm-tis-swtpm-test.o 
tests/qtest/tpm-emu.o \
tests/qtest/tpm-util.o tests/qtest/tpm-tests.o $(test-io-obj-y)
-tests/qtest/tpm-tis-test$(EXESUF): tests/qtest/tpm-tis-test.o 
tests/qtest/tpm-emu.o $(test-io-obj-y)
+tests/qtest/tpm-tis-test$(EXESUF): tests/qtest/tpm-tis-test.o 
tests/qtest/tpm-tis-util.o tests/qtest/tpm-emu.o $(test-io-obj-y)
 
 # QTest rules
 
diff --git a/tests/qtest/tpm-crb-swtpm-test.c b/tests/qtest/tpm-crb-swtpm-test.c
index 5228cb7af4..55fdb5657d 100644
--- a/tests/qtest/tpm-crb-swtpm-test.c
+++ b/tests/qtest/tpm-crb-swtpm-test.c
@@ -18,6 +18,10 @@
 #include "libqtest.h"
 #include "qemu/module.h"
 #include "tpm-tests.h"
+#include "hw/acpi/tpm.h"
+
+/* Not used but needed for linking */
+uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
 
 typedef struct TestState {
 char *src_tpm_path;
diff --git a/tests/qtest/tpm-crb-test.c b/tests/qtest/tpm-crb-test.c
index 632fb7fbd8..ed533900d1 100644
--- a/tests/qtest/tpm-crb-test.c
+++ b/tests/qtest/tpm-crb-test.c
@@ -19,6 +19,9 @@
 #include "qemu/module.h"
 #include "tpm-emu.h"
 
+/* Not used but needed for linking */
+uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
+
 #define TPM_CMD "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00"
 
 static void tpm_crb_test(const void *data)
diff --git a/tests/qtest/tpm-tis-swtpm-test.c b/tests/qtest/tpm-tis-swtpm-test.c
index 9470f15751..90131cb3c4 100644
--- a/tests/qtest/tpm-tis-swtpm-test.c
+++ b/tests/qtest/tpm-tis-swtpm-test.c
@@ -18,6 +18,9 @@
 #include "libqtest.h"
 #include "qemu/module.h"
 #include "tpm-tests.h"
+#include "hw/acpi/tpm.h"
+
+uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
 
 typedef struct TestState {
 char *src_tpm_path;
diff --git a/tests/qtest/tpm-tis-test.c b/tests/qtest/tpm-tis-test.c
index dcf30e05b7..79ffbc943e 100644
--- a/tests/qtest/tpm-tis-test.c
+++ b/tests/qtest/tpm-tis-test.c
@@ -1,5 +1,5 @@
 /*
- * QTest testcase for TPM TIS
+ * QTest testcase for ISA TPM TIS
  *
  * Copyright (c) 2018 Red Hat, Inc.
  * Copyright (c) 2018 IBM Corporation
@@ -20,417 +20,9 @@
 #include "libqtest-single.h"
 #include "qemu/module.h"
 #include "tpm-emu.h"
+#include "tpm-tis-util.h"
 
-#define TIS_REG(LOCTY, REG) \
-(TPM_TIS_ADDR_BASE + ((LOCTY) << 12) + REG)
-
-#define DEBUG_TIS_TEST 0
-
-#define DPRINTF(fmt, ...) do { \
-if (DEBUG_TIS_TEST) { \
-printf(fmt, ## __VA_ARGS__); \
-} \
-} while (0)
-
-#define DPRINTF_ACCESS \
-DPRINTF("%s: %d: locty=%d l=%d access=0x%02x pending_request_flag=0x%x\n", 
\
-__func__, __LINE__, locty, l, access, pending_request_flag)
-
-#define DPRINTF_STS \
-DPRINTF("%s: %d: sts = 0x%08x\n", __func__, __LINE__, sts)
-
-static const uint8_t TPM_CMD[12] =
-"\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00";
-
-static void tpm_tis_test_check_localities(const void *data)
-{
-uint8_t locty;
-uint8_t access;
-uint32_t ifaceid;
-uint32_t capability;
-uint32_t didvid;
-uint32_t rid;
-
-for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES; locty++) {
-access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
-g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
-TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
-
-capability = readl(TIS_REG

[PULL v1 00/10] Merge TPM 2020/03/04

2020-03-04 Thread Stefan Berger
This series of patches adds support for TPM on ARM.

Regards,
Stefan

The following changes since commit 2ac031d171ccd18c973014d9978b4a63f0ad5fb0:

  Merge remote-tracking branch 'remotes/palmer/tags/riscv-for-master-5.0-sf3' 
into staging (2020-03-03 11:06:39 +)

are available in the Git repository at:

  git://github.com/stefanberger/qemu-tpm.git tags/pull-tpm-2020-03-04-1

for you to fetch changes up to cf5b8ff14b38eb93363364635df3a0e6aa8c74e5:

  test: tpm-tis: Add Sysbus TPM-TIS device test (2020-03-03 07:29:09 -0500)


Eric Auger (10):
  tpm: rename TPM_TIS into TPM_TIS_ISA
  tpm: Use TPMState as a common struct
  tpm: Separate tpm_tis common functions from isa code
  tpm: Separate TPM_TIS and TPM_TIS_ISA configs
  tpm: Add the SysBus TPM TIS device
  hw/arm/virt: vTPM support
  docs/specs/tpm: Document TPM_TIS sysbus device for ARM
  test: tpm: pass optional machine options to swtpm test functions
  test: tpm-tis: Get prepared to share tests between ISA and sysbus
devices
  test: tpm-tis: Add Sysbus TPM-TIS device test

 default-configs/i386-softmmu.mak|   2 +-
 docs/specs/tpm.rst  |  25 +-
 hw/arm/Kconfig  |   1 +
 hw/arm/sysbus-fdt.c |  33 ++
 hw/arm/virt.c   |   7 +
 hw/i386/Kconfig |   2 +-
 hw/i386/acpi-build.c|   6 +-
 hw/tpm/Kconfig  |  12 +-
 hw/tpm/Makefile.objs|   4 +-
 hw/tpm/tpm_tis.h|  91 +
 hw/tpm/{tpm_tis.c => tpm_tis_common.c}  | 181 +-
 hw/tpm/tpm_tis_isa.c| 170 +
 hw/tpm/tpm_tis_sysbus.c | 159 +
 include/sysemu/tpm.h|   7 +-
 tests/qtest/Makefile.include|  11 +-
 tests/qtest/tpm-crb-swtpm-test.c|   9 +-
 tests/qtest/tpm-crb-test.c  |   3 +
 tests/qtest/tpm-tests.c |  10 +-
 tests/qtest/tpm-tests.h |   5 +-
 tests/qtest/tpm-tis-device-swtpm-test.c |  76 
 tests/qtest/tpm-tis-device-test.c   |  87 +
 tests/qtest/tpm-tis-swtpm-test.c|   8 +-
 tests/qtest/tpm-tis-test.c  | 414 +-
 tests/qtest/tpm-tis-util.c  | 451 
 tests/qtest/tpm-tis-util.h  |  23 ++
 tests/qtest/tpm-util.c  |  11 +-
 tests/qtest/tpm-util.h  |   8 +-
 27 files changed, 1207 insertions(+), 609 deletions(-)
 create mode 100644 hw/tpm/tpm_tis.h
 rename hw/tpm/{tpm_tis.c => tpm_tis_common.c} (85%)
 create mode 100644 hw/tpm/tpm_tis_isa.c
 create mode 100644 hw/tpm/tpm_tis_sysbus.c
 create mode 100644 tests/qtest/tpm-tis-device-swtpm-test.c
 create mode 100644 tests/qtest/tpm-tis-device-test.c
 create mode 100644 tests/qtest/tpm-tis-util.c
 create mode 100644 tests/qtest/tpm-tis-util.h

-- 
2.24.1




[PULL v1 04/10] tpm: Separate TPM_TIS and TPM_TIS_ISA configs

2020-03-04 Thread Stefan Berger
From: Eric Auger 

Let's separate the compilation of tpm_tis_common.c from
the compilation of tpm_tis_isa.c

The common part will be also compiled along with the
tpm_tis_sysbus device.

Signed-off-by: Eric Auger 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Ard Biesheuvel 
Acked-by: Ard Biesheuvel 
Message-id: 20200226205942.11424-5-eric.au...@redhat.com
Signed-off-by: Stefan Berger 
---
 default-configs/i386-softmmu.mak | 2 +-
 hw/i386/Kconfig  | 2 +-
 hw/tpm/Kconfig   | 7 ++-
 hw/tpm/Makefile.objs | 3 ++-
 tests/qtest/Makefile.include | 4 ++--
 5 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 4cc64dafa2..84d1a2487c 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -20,7 +20,7 @@
 #CONFIG_SGA=n
 #CONFIG_TEST_DEVICES=n
 #CONFIG_TPM_CRB=n
-#CONFIG_TPM_TIS=n
+#CONFIG_TPM_TIS_ISA=n
 #CONFIG_VTD=n
 
 # Boards:
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index cdc851598c..c93f32f657 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -20,7 +20,7 @@ config PC
 imply SGA
 imply TEST_DEVICES
 imply TPM_CRB
-imply TPM_TIS
+imply TPM_TIS_ISA
 imply VGA_PCI
 imply VIRTIO_VGA
 select FDC
diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig
index 9e67d990e8..686f8206bb 100644
--- a/hw/tpm/Kconfig
+++ b/hw/tpm/Kconfig
@@ -2,9 +2,14 @@ config TPMDEV
 bool
 depends on TPM
 
-config TPM_TIS
+config TPM_TIS_ISA
 bool
 depends on TPM && ISA_BUS
+select TPM_TIS
+
+config TPM_TIS
+bool
+depends on TPM
 select TPMDEV
 
 config TPM_CRB
diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs
index fcc4c2f27c..3ef2036cca 100644
--- a/hw/tpm/Makefile.objs
+++ b/hw/tpm/Makefile.objs
@@ -1,6 +1,7 @@
 common-obj-$(CONFIG_TPM) += tpm_util.o
 obj-$(call lor,$(CONFIG_TPM_TIS),$(CONFIG_TPM_CRB)) += tpm_ppi.o
-common-obj-$(CONFIG_TPM_TIS) += tpm_tis_isa.o tpm_tis_common.o
+common-obj-$(CONFIG_TPM_TIS_ISA) += tpm_tis_isa.o
+common-obj-$(CONFIG_TPM_TIS) += tpm_tis_common.o
 common-obj-$(CONFIG_TPM_CRB) += tpm_crb.o
 common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
 common-obj-$(CONFIG_TPM_EMULATOR) += tpm_emulator.o
diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index e769c1ad70..028af5b782 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -54,8 +54,8 @@ check-qtest-i386-y += q35-test
 check-qtest-i386-y += vmgenid-test
 check-qtest-i386-$(CONFIG_TPM_CRB) += tpm-crb-swtpm-test
 check-qtest-i386-$(CONFIG_TPM_CRB) += tpm-crb-test
-check-qtest-i386-$(CONFIG_TPM_TIS) += tpm-tis-swtpm-test
-check-qtest-i386-$(CONFIG_TPM_TIS) += tpm-tis-test
+check-qtest-i386-$(CONFIG_TPM_TIS_ISA) += tpm-tis-swtpm-test
+check-qtest-i386-$(CONFIG_TPM_TIS_ISA) += tpm-tis-test
 check-qtest-i386-$(CONFIG_SLIRP) += test-netfilter
 check-qtest-i386-$(CONFIG_POSIX) += test-filter-mirror
 check-qtest-i386-$(CONFIG_RTL8139_PCI) += test-filter-redirector
-- 
2.24.1




Re: [PATCH 1/2] misc: Replace zero-length arrays with flexible array member (automatic)

2020-03-04 Thread Philippe Mathieu-Daudé

On 3/4/20 1:51 AM, Philippe Mathieu-Daudé wrote:

Description copied from Linux kernel commit from Gustavo A. R. Silva
(see [3]):

--v-- description start --v--

   The current codebase makes use of the zero-length array language
   extension to the C90 standard, but the preferred mechanism to
   declare variable-length types such as these ones is a flexible
   array member [1], introduced in C99:

   struct foo {
   int stuff;
   struct boo array[];
   };

   By making use of the mechanism above, we will get a compiler
   warning in case the flexible array does not occur last in the
   structure, which will help us prevent some kind of undefined
   behavior bugs from being unadvertenly introduced [2] to the
   Linux codebase from now on.

--^-- description end --^--

Do the similar housekeeping in the QEMU codebase (which uses
C99 since commit 7be41675f7cb).

All these instances of code were found with the help of the
following Coccinelle script:

   @@
   identifier s, a;
   type T;
   @@
struct s {
   ...
   -   T a[0];
   +   T a[];
   };
   @@
   identifier s, a;
   type T;
   @@
struct s {
   ...
   -   T a[0];
   +   T a[];
} QEMU_PACKED;

[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76497732932f
[3] 
https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/commit/?id=17642a2fbd2c1

Inspired-by: Gustavo A. R. Silva 
Signed-off-by: Philippe Mathieu-Daudé 
---
  bsd-user/qemu.h   |  2 +-
  contrib/libvhost-user/libvhost-user.h |  2 +-
  hw/m68k/bootinfo.h|  2 +-
  hw/scsi/srp.h |  6 +++---
  hw/xen/xen_pt.h   |  2 +-
  include/hw/acpi/acpi-defs.h   | 12 ++--
  include/hw/arm/smmu-common.h  |  2 +-
  include/hw/i386/intel_iommu.h |  3 ++-
  include/hw/virtio/virtio-iommu.h  |  2 +-
  include/sysemu/cryptodev.h|  2 +-
  include/tcg/tcg.h |  2 +-
  pc-bios/s390-ccw/bootmap.h|  2 +-
  pc-bios/s390-ccw/sclp.h   |  2 +-
  tests/qtest/libqos/ahci.h |  2 +-
  block/linux-aio.c |  2 +-
  hw/acpi/nvdimm.c  |  6 +++---
  hw/dma/soc_dma.c  |  2 +-
  hw/i386/x86.c |  2 +-
  hw/misc/omap_l4.c |  2 +-
  hw/nvram/eeprom93xx.c |  2 +-
  hw/rdma/vmw/pvrdma_qp_ops.c   |  4 ++--
  hw/usb/dev-network.c  |  2 +-
  hw/usb/dev-smartcard-reader.c |  4 ++--
  hw/virtio/virtio.c|  4 ++--
  net/queue.c   |  2 +-
  25 files changed, 38 insertions(+), 37 deletions(-)


[...]

diff --git a/hw/scsi/srp.h b/hw/scsi/srp.h
index d27f31d2d5..54c954badd 100644
--- a/hw/scsi/srp.h
+++ b/hw/scsi/srp.h
@@ -112,7 +112,7 @@ struct srp_direct_buf {
  struct srp_indirect_buf {
  struct srp_direct_buftable_desc;
  uint32_t len;
-struct srp_direct_bufdesc_list[0];
+struct srp_direct_bufdesc_list[];
  } QEMU_PACKED;
  
  enum {

@@ -211,7 +211,7 @@ struct srp_cmd {
  uint8_treserved4;
  uint8_tadd_cdb_len;
  uint8_tcdb[16];
-uint8_tadd_data[0];
+uint8_tadd_data[];
  } QEMU_PACKED;
  
  enum {

@@ -241,7 +241,7 @@ struct srp_rsp {
  uint32_t   data_in_res_cnt;
  uint32_t   sense_data_len;
  uint32_t   resp_data_len;
-uint8_tdata[0];
+uint8_tdata[];
  } QEMU_PACKED;


hw/scsi/spapr_vscsi.c:69:29: error: field 'iu' with variable sized type 
'union viosrp_iu' not at the end of a struct or class is a GNU extension 
[-Werror,-Wgnu-variable-sized-type-not-at-end]

union viosrp_iu iu;
^

Yay we found a bug! Thanks Gustavo :)

union srp_iu {
struct srp_login_req login_req;
struct srp_login_rsp login_rsp;
struct srp_login_rej login_rej;
struct srp_i_logout i_logout;
struct srp_t_logout t_logout;
struct srp_tsk_mgmt tsk_mgmt;
struct srp_cmd cmd;
struct srp_rsp rsp;
uint8_t reserved[SRP_MAX_IU_LEN];
};

union viosrp_iu {
union srp_iu srp;
union mad_iu mad;
};

typedef struct vscsi_req {
vscsi_crq   crq;
union viosrp_iu iu;

/* SCSI request tracking */
SCSIRequest *sreq;
uint32_tqtag; /* qemu tag != srp tag */
boolactive;
boolwriting;
booldma_error;
uint32_tdata_len;
uint32_tsenselen;
uint8_t sense[SCSI_SENSE_BUF_SIZE];

/* RDMA related bits */
uint8_t dma_fmt;
uint16_tlocal_desc;
uint16_ttotal_desc;
uint16_tcdb_offset;
uint16_tcur_desc_num;
uint16_t   

[PULL v1 01/10] tpm: rename TPM_TIS into TPM_TIS_ISA

2020-03-04 Thread Stefan Berger
From: Eric Auger 

As we plan to introduce a sysbus TPM_TIS, let's rename
TPM_TIS into TPM_TIS_ISA.

Signed-off-by: Eric Auger 
Reviewed-by: Stefan Berger 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Ard Biesheuvel 
Acked-by: Ard Biesheuvel 
Message-id: 20200226205942.11424-2-eric.au...@redhat.com
Signed-off-by: Stefan Berger 
---
 hw/i386/acpi-build.c | 6 +++---
 hw/tpm/tpm_tis.c | 4 ++--
 include/sysemu/tpm.h | 6 +++---
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 9c4e46fa74..26777f8828 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2026,7 +2026,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 }
 }
 
-if (TPM_IS_TIS(tpm_find())) {
+if (TPM_IS_TIS_ISA(tpm_find())) {
 aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE,
TPM_TIS_ADDR_SIZE, AML_READ_WRITE));
 }
@@ -2197,7 +2197,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 /* Scan all PCI buses. Generate tables to support hotplug. */
 build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en);
 
-if (TPM_IS_TIS(tpm)) {
+if (TPM_IS_TIS_ISA(tpm)) {
 if (misc->tpm_version == TPM_VERSION_2_0) {
 dev = aml_device("TPM");
 aml_append(dev, aml_name_decl("_HID",
@@ -2304,7 +2304,7 @@ build_tpm2(GArray *table_data, BIOSLinker *linker, GArray 
*tcpalog)
 (char *)&tpm2_ptr->log_area_start_address - table_data->data;
 
 tpm2_ptr->platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT);
-if (TPM_IS_TIS(tpm_find())) {
+if (TPM_IS_TIS_ISA(tpm_find())) {
 tpm2_ptr->control_area_address = cpu_to_le64(0);
 tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
 } else if (TPM_IS_CRB(tpm_find())) {
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 31facb896d..c609737272 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -91,7 +91,7 @@ typedef struct TPMState {
 TPMPPI ppi;
 } TPMState;
 
-#define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS)
+#define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS_ISA)
 
 #define DEBUG_TIS 0
 
@@ -1008,7 +1008,7 @@ static void tpm_tis_class_init(ObjectClass *klass, void 
*data)
 }
 
 static const TypeInfo tpm_tis_info = {
-.name = TYPE_TPM_TIS,
+.name = TYPE_TPM_TIS_ISA,
 .parent = TYPE_ISA_DEVICE,
 .instance_size = sizeof(TPMState),
 .instance_init = tpm_tis_initfn,
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index 15979a3647..1691b92c28 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -43,12 +43,12 @@ typedef struct TPMIfClass {
 enum TPMVersion (*get_version)(TPMIf *obj);
 } TPMIfClass;
 
-#define TYPE_TPM_TIS"tpm-tis"
+#define TYPE_TPM_TIS_ISA"tpm-tis"
 #define TYPE_TPM_CRB"tpm-crb"
 #define TYPE_TPM_SPAPR  "tpm-spapr"
 
-#define TPM_IS_TIS(chr) \
-object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS)
+#define TPM_IS_TIS_ISA(chr) \
+object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS_ISA)
 #define TPM_IS_CRB(chr) \
 object_dynamic_cast(OBJECT(chr), TYPE_TPM_CRB)
 #define TPM_IS_SPAPR(chr)   \
-- 
2.24.1




[PULL v1 02/10] tpm: Use TPMState as a common struct

2020-03-04 Thread Stefan Berger
From: Eric Auger 

As we plan to introduce a SysBus TPM TIS device, let's
make the TPMState a common struct usable by both the
ISADevice and the SysBusDevice. TPMStateISA embeds the
struct and inherits from the ISADevice.

The prototype of functions bound to be used by both
the ISA and SysBus devices is changed to take TPMState
handle.

A bunch of structs also are renamed to be specialized
for the ISA device. Besides those transformations, no
functional change is expected.

Signed-off-by: Eric Auger 
Reviewed-by: Stefan Berger 
Tested-by: Ard Biesheuvel 
Acked-by: Ard Biesheuvel 
Message-id: 20200226205942.11424-3-eric.au...@redhat.com
Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_tis.c | 146 +--
 1 file changed, 91 insertions(+), 55 deletions(-)

diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index c609737272..fc6d7ca579 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -65,7 +65,6 @@ typedef struct TPMLocality {
 } TPMLocality;
 
 typedef struct TPMState {
-ISADevice busdev;
 MemoryRegion mmio;
 
 unsigned char buffer[TPM_TIS_BUFFER_MAX];
@@ -91,7 +90,15 @@ typedef struct TPMState {
 TPMPPI ppi;
 } TPMState;
 
-#define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS_ISA)
+typedef struct TPMStateISA {
+/*< private >*/
+ISADevice parent_obj;
+
+/*< public >*/
+TPMState state; /* not a QOM object */
+} TPMStateISA;
+
+#define TPM_TIS_ISA(obj) OBJECT_CHECK(TPMStateISA, (obj), TYPE_TPM_TIS_ISA)
 
 #define DEBUG_TIS 0
 
@@ -281,9 +288,8 @@ static void tpm_tis_prep_abort(TPMState *s, uint8_t locty, 
uint8_t newlocty)
 /*
  * Callback from the TPM to indicate that the response was received.
  */
-static void tpm_tis_request_completed(TPMIf *ti, int ret)
+static void tpm_tis_request_completed(TPMState *s, int ret)
 {
-TPMState *s = TPM(ti);
 uint8_t locty = s->cmd.locty;
 uint8_t l;
 
@@ -338,7 +344,7 @@ static uint32_t tpm_tis_data_read(TPMState *s, uint8_t 
locty)
 }
 
 #ifdef DEBUG_TIS
-static void tpm_tis_dump_state(void *opaque, hwaddr addr)
+static void tpm_tis_dump_state(TPMState *s, hwaddr addr)
 {
 static const unsigned regs[] = {
 TPM_TIS_REG_ACCESS,
@@ -353,7 +359,6 @@ static void tpm_tis_dump_state(void *opaque, hwaddr addr)
 int idx;
 uint8_t locty = tpm_tis_locality_from_addr(addr);
 hwaddr base = addr & ~0xfff;
-TPMState *s = opaque;
 
 printf("tpm_tis: active locality  : %d\n"
"tpm_tis: state of locality %d : %d\n"
@@ -363,7 +368,7 @@ static void tpm_tis_dump_state(void *opaque, hwaddr addr)
 
 for (idx = 0; regs[idx] != 0xfff; idx++) {
 printf("tpm_tis: 0x%04x : 0x%08x\n", regs[idx],
-   (int)tpm_tis_mmio_read(opaque, base + regs[idx], 4));
+   (int)tpm_tis_mmio_read(s, base + regs[idx], 4));
 }
 
 printf("tpm_tis: r/w offset: %d\n"
@@ -488,7 +493,7 @@ static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr,
 break;
 #ifdef DEBUG_TIS
 case TPM_TIS_REG_DEBUG:
-tpm_tis_dump_state(opaque, addr);
+tpm_tis_dump_state(s, addr);
 break;
 #endif
 }
@@ -835,10 +840,8 @@ static const MemoryRegionOps tpm_tis_memory_ops = {
 /*
  * Get the TPMVersion of the backend device being used
  */
-static enum TPMVersion tpm_tis_get_tpm_version(TPMIf *ti)
+static enum TPMVersion tpm_tis_get_tpm_version(TPMState *s)
 {
-TPMState *s = TPM(ti);
-
 if (tpm_backend_had_startup_error(s->be_driver)) {
 return TPM_VERSION_UNSPEC;
 }
@@ -850,9 +853,8 @@ static enum TPMVersion tpm_tis_get_tpm_version(TPMIf *ti)
  * This function is called when the machine starts, resets or due to
  * S3 resume.
  */
-static void tpm_tis_reset(DeviceState *dev)
+static void tpm_tis_reset(TPMState *s)
 {
-TPMState *s = TPM(dev);
 int c;
 
 s->be_tpm_version = tpm_backend_get_tpm_version(s->be_driver);
@@ -896,15 +898,14 @@ static void tpm_tis_reset(DeviceState *dev)
 
 /* persistent state handling */
 
-static int tpm_tis_pre_save(void *opaque)
+static int tpm_tis_pre_save(TPMState *s)
 {
-TPMState *s = opaque;
 uint8_t locty = s->active_locty;
 
 trace_tpm_tis_pre_save(locty, s->rw_offset);
 
 if (DEBUG_TIS) {
-tpm_tis_dump_state(opaque, 0);
+tpm_tis_dump_state(s, 0);
 }
 
 /*
@@ -929,34 +930,78 @@ static const VMStateDescription vmstate_locty = {
 }
 };
 
-static const VMStateDescription vmstate_tpm_tis = {
+/* ISA */
+
+static int tpm_tis_pre_save_isa(void *opaque)
+{
+TPMStateISA *isadev = opaque;
+
+return tpm_tis_pre_save(&isadev->state);
+}
+
+static const VMStateDescription vmstate_tpm_tis_isa = {
 .name = "tpm-tis",
 .version_id = 0,
-.pre_save  = tpm_tis_pre_save,
+.pre_save  = tpm_tis_pre_save_isa,
 .fields = (VMStateField[]) {
-VMSTATE_BUFFER(buffer, TPMState),
-VMSTATE_UINT16(rw_offset, TPMState),
-VMSTATE_UINT8(active_locty, TPMState),
-VMSTATE_UINT8(aborting_loct

Re: [PATCH v6 18/18] pc-bios: s390x: Save iplb location in lowcore

2020-03-04 Thread Christian Borntraeger
On 04.03.20 12:42, Janosch Frank wrote:
> The POP states that for a list directed IPL the IPLB is stored into
> memory by the machine loader and its address is stored at offset 0x14
> of the lowcore.
> 
> ZIPL currently uses the address in offset 0x14 to access the IPLB and
> acquire flags about secure boot. If the IPLB address points into
> memory which has an unsupported mix of flags set, ZIPL will panic
> instead of booting the OS.
> 
> As the lowcore can have quite a high entropy for a guest that did drop
> out of protected mode (i.e. rebooted) we encountered the ZIPL panic
> quite often.
> 
> Signed-off-by: Janosch Frank 
> Tested-by: Marc Hartmayer 

I think this makes sense even without protected virtualization, no?
Unless somebody complains, I think I will pick this up while Conny is
on vacation.



> ---
>  pc-bios/s390-ccw/jump2ipl.c  |  1 +
>  pc-bios/s390-ccw/main.c  |  8 +++-
>  pc-bios/s390-ccw/netmain.c   |  1 +
>  pc-bios/s390-ccw/s390-arch.h | 10 --
>  pc-bios/s390-ccw/s390-ccw.h  |  1 +
>  5 files changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
> index da13c43cc0..4eba2510b0 100644
> --- a/pc-bios/s390-ccw/jump2ipl.c
> +++ b/pc-bios/s390-ccw/jump2ipl.c
> @@ -35,6 +35,7 @@ void jump_to_IPL_code(uint64_t address)
>  {
>  /* store the subsystem information _after_ the bootmap was loaded */
>  write_subsystem_identification();
> +write_iplb_location();
>  
>  /* prevent unknown IPL types in the guest */
>  if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index a21b386280..4e65b411e1 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -9,6 +9,7 @@
>   */
>  
>  #include "libc.h"
> +#include "helper.h"
>  #include "s390-arch.h"
>  #include "s390-ccw.h"
>  #include "cio.h"
> @@ -22,7 +23,7 @@ QemuIplParameters qipl;
>  IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
>  static bool have_iplb;
>  static uint16_t cutype;
> -LowCore const *lowcore; /* Yes, this *is* a pointer to address 0 */
> +LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
>  
>  #define LOADPARM_PROMPT "PROMPT  "
>  #define LOADPARM_EMPTY  ""
> @@ -42,6 +43,11 @@ void write_subsystem_identification(void)
>  *zeroes = 0;
>  }
>  
> +void write_iplb_location(void)
> +{
> +lowcore->ptr_iplb = ptr2u32(&iplb);
> +}
> +
>  void panic(const char *string)
>  {
>  sclp_print(string);
> diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
> index f2dcc01e27..309ffa30d9 100644
> --- a/pc-bios/s390-ccw/netmain.c
> +++ b/pc-bios/s390-ccw/netmain.c
> @@ -40,6 +40,7 @@
>  #define DEFAULT_TFTP_RETRIES 20
>  
>  extern char _start[];
> +void write_iplb_location(void) {}
>  
>  #define KERNEL_ADDR ((void *)0L)
>  #define KERNEL_MAX_SIZE ((long)_start)
> diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
> index 504fc7c2f0..5f36361c02 100644
> --- a/pc-bios/s390-ccw/s390-arch.h
> +++ b/pc-bios/s390-ccw/s390-arch.h
> @@ -36,7 +36,13 @@ typedef struct LowCore {
>  /* prefix area: defined by architecture */
>  PSWLegacy   ipl_psw;  /* 0x000 */
>  uint32_tccw1[2];  /* 0x008 */
> -uint32_tccw2[2];  /* 0x010 */
> +union {
> +uint32_tccw2[2];  /* 0x010 */
> +struct {
> +uint32_t reserved10;
> +uint32_t ptr_iplb;
> +};
> +};
>  uint8_t pad1[0x80 - 0x18];/* 0x018 */
>  uint32_text_params;   /* 0x080 */
>  uint16_tcpu_addr; /* 0x084 */
> @@ -85,7 +91,7 @@ typedef struct LowCore {
>  PSW io_new_psw;   /* 0x1f0 */
>  } __attribute__((packed, aligned(8192))) LowCore;
>  
> -extern LowCore const *lowcore;
> +extern LowCore *lowcore;
>  
>  static inline void set_prefix(uint32_t address)
>  {
> diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
> index 11bce7d73c..21f27e7990 100644
> --- a/pc-bios/s390-ccw/s390-ccw.h
> +++ b/pc-bios/s390-ccw/s390-ccw.h
> @@ -57,6 +57,7 @@ void consume_io_int(void);
>  /* main.c */
>  void panic(const char *string);
>  void write_subsystem_identification(void);
> +void write_iplb_location(void);
>  extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
>  unsigned int get_loadparm_index(void);
>  
> 




Re: [PATCH] dp8393x: Mask EOL bit from descriptor addresses, take 2

2020-03-04 Thread Philippe Mathieu-Daudé

On 3/4/20 4:23 AM, Finn Thain wrote:

A portion of a recent patch got lost due to a merge snafu. That patch is
now commit 88f632fbb1 ("dp8393x: Mask EOL bit from descriptor addresses").
This patch restores the portion that got lost.

Signed-off-by: Finn Thain 
---
  hw/net/dp8393x.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 8a3504d962..81fc13ee9f 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -525,8 +525,8 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
   * (4 + 3 * s->regs[SONIC_TFC]),
 MEMTXATTRS_UNSPECIFIED, s->data,
 size);
-s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0) & ~0x1;
-if (dp8393x_get(s, width, 0) & SONIC_DESC_EOL) {
+s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0);
+if (s->regs[SONIC_CTDA] & SONIC_DESC_EOL) {
  /* EOL detected */
  break;
  }



Reviewed-by: Philippe Mathieu-Daudé 




[PATCH v5 1/5] block/qcow2-threads: fix qcow2_decompress

2020-03-04 Thread Denis Plotnikov
From: Vladimir Sementsov-Ogievskiy 

On success path we return what inflate() returns instead of 0. And it
most probably works for Z_STREAM_END as it is positive, but is
definitely broken for Z_BUF_ERROR.

While being here, switch to errno return code, to be closer to
qcow2_compress API (and usual expectations).

Revert condition in if to be more positive. Drop dead initialization of
ret.

Cc: qemu-sta...@nongnu.org # v4.0
Fixes: 341926ab83e2b
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Alberto Garcia 
---
 block/qcow2-threads.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
index 77bb578cdf..a68126f291 100644
--- a/block/qcow2-threads.c
+++ b/block/qcow2-threads.c
@@ -128,12 +128,12 @@ static ssize_t qcow2_compress(void *dest, size_t 
dest_size,
  * @src - source buffer, @src_size bytes
  *
  * Returns: 0 on success
- *  -1 on fail
+ *  -EIO on fail
  */
 static ssize_t qcow2_decompress(void *dest, size_t dest_size,
 const void *src, size_t src_size)
 {
-int ret = 0;
+int ret;
 z_stream strm;
 
 memset(&strm, 0, sizeof(strm));
@@ -144,17 +144,19 @@ static ssize_t qcow2_decompress(void *dest, size_t 
dest_size,
 
 ret = inflateInit2(&strm, -12);
 if (ret != Z_OK) {
-return -1;
+return -EIO;
 }
 
 ret = inflate(&strm, Z_FINISH);
-if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) || strm.avail_out != 0) {
+if ((ret == Z_STREAM_END || ret == Z_BUF_ERROR) && strm.avail_out == 0) {
 /*
  * We approve Z_BUF_ERROR because we need @dest buffer to be filled, 
but
  * @src buffer may be processed partly (because in qcow2 we know size 
of
  * compressed data with precision of one sector)
  */
-ret = -1;
+ret = 0;
+} else {
+ret = -EIO;
 }
 
 inflateEnd(&strm);
-- 
2.17.0




[PATCH v5 0/5] qcow2: Implement zstd cluster compression method

2020-03-04 Thread Denis Plotnikov
v5:
   * replace -ENOTSUP with abort in qcow2_co_decompress [Vladimir]
   * set cluster size for all test cases in the beginning of the 287 test

v4:
   * the series is rebased on top of 01 "block/qcow2-threads: fix 
qcow2_decompress"
   * 01 is just a no-change resend to avoid extra dependencies. Still, it may 
be merged in separate

v3:
   * remove redundant max compression type value check [Vladimir, Eric]
 (the switch below checks everything)
   * prevent compression type changing on "qemu-img amend" [Vladimir]
   * remove zstd config setting, since it has been added already by
 "migration" patches [Vladimir]
   * change the compression type error message [Vladimir] 
   * fix alignment and 80-chars exceeding [Vladimir]

v2:
   * rework compression type setting [Vladimir]
   * squash iotest changes to the compression type introduction patch 
[Vladimir, Eric]
   * fix zstd availability checking in zstd iotest [Vladimir]
   * remove unnecessry casting [Eric]
   * remove rudundant checks [Eric]
   * fix compressed cluster layout in qcow2 spec [Vladimir]
   * fix wording [Eric, Vladimir]
   * fix compression type filtering in iotests [Eric]

v1:
   the initial series

Denis Plotnikov (4):
  qcow2: introduce compression type feature
  qcow2: rework the cluster compression routine
  qcow2: add zstd cluster compression
  iotests: 287: add qcow2 compression type test

Vladimir Sementsov-Ogievskiy (1):
  block/qcow2-threads: fix qcow2_decompress

 docs/interop/qcow2.txt   |  20 +++
 configure|   2 +-
 qapi/block-core.json |  23 +++-
 block/qcow2.h|  18 ++-
 include/block/block_int.h|   1 +
 block/qcow2-threads.c| 206 ---
 block/qcow2.c| 108 
 tests/qemu-iotests/031.out   |  14 +--
 tests/qemu-iotests/036.out   |   4 +-
 tests/qemu-iotests/049.out   | 102 +++
 tests/qemu-iotests/060.out   |   1 +
 tests/qemu-iotests/061.out   |  34 ++---
 tests/qemu-iotests/065   |  28 +++--
 tests/qemu-iotests/080   |   2 +-
 tests/qemu-iotests/144.out   |   4 +-
 tests/qemu-iotests/182.out   |   2 +-
 tests/qemu-iotests/242.out   |   5 +
 tests/qemu-iotests/255.out   |   8 +-
 tests/qemu-iotests/287   | 128 +++
 tests/qemu-iotests/287.out   |  43 +++
 tests/qemu-iotests/common.filter |   3 +-
 tests/qemu-iotests/group |   1 +
 22 files changed, 644 insertions(+), 113 deletions(-)
 create mode 100755 tests/qemu-iotests/287
 create mode 100644 tests/qemu-iotests/287.out

-- 
2.17.0




[PATCH v5 3/5] qcow2: rework the cluster compression routine

2020-03-04 Thread Denis Plotnikov
The patch enables processing the image compression type defined
for the image and chooses an appropriate method for image clusters
(de)compression.

Signed-off-by: Denis Plotnikov 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 block/qcow2-threads.c | 71 ---
 1 file changed, 60 insertions(+), 11 deletions(-)

diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
index a68126f291..7dbaf53489 100644
--- a/block/qcow2-threads.c
+++ b/block/qcow2-threads.c
@@ -74,7 +74,9 @@ typedef struct Qcow2CompressData {
 } Qcow2CompressData;
 
 /*
- * qcow2_compress()
+ * qcow2_zlib_compress()
+ *
+ * Compress @src_size bytes of data using zlib compression method
  *
  * @dest - destination buffer, @dest_size bytes
  * @src - source buffer, @src_size bytes
@@ -83,8 +85,8 @@ typedef struct Qcow2CompressData {
  *  -ENOMEM destination buffer is not enough to store compressed data
  *  -EIOon any other error
  */
-static ssize_t qcow2_compress(void *dest, size_t dest_size,
-  const void *src, size_t src_size)
+static ssize_t qcow2_zlib_compress(void *dest, size_t dest_size,
+   const void *src, size_t src_size)
 {
 ssize_t ret;
 z_stream strm;
@@ -119,10 +121,10 @@ static ssize_t qcow2_compress(void *dest, size_t 
dest_size,
 }
 
 /*
- * qcow2_decompress()
+ * qcow2_zlib_decompress()
  *
  * Decompress some data (not more than @src_size bytes) to produce exactly
- * @dest_size bytes.
+ * @dest_size bytes using zlib compression method
  *
  * @dest - destination buffer, @dest_size bytes
  * @src - source buffer, @src_size bytes
@@ -130,8 +132,8 @@ static ssize_t qcow2_compress(void *dest, size_t dest_size,
  * Returns: 0 on success
  *  -EIO on fail
  */
-static ssize_t qcow2_decompress(void *dest, size_t dest_size,
-const void *src, size_t src_size)
+static ssize_t qcow2_zlib_decompress(void *dest, size_t dest_size,
+ const void *src, size_t src_size)
 {
 int ret;
 z_stream strm;
@@ -191,20 +193,67 @@ qcow2_co_do_compress(BlockDriverState *bs, void *dest, 
size_t dest_size,
 return arg.ret;
 }
 
+/*
+ * qcow2_co_compress()
+ *
+ * Compress @src_size bytes of data using the compression
+ * method defined by the image compression type
+ *
+ * @dest - destination buffer, @dest_size bytes
+ * @src - source buffer, @src_size bytes
+ *
+ * Returns: compressed size on success
+ *  a negative error code on failure
+ */
 ssize_t coroutine_fn
 qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
   const void *src, size_t src_size)
 {
-return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
-qcow2_compress);
+BDRVQcow2State *s = bs->opaque;
+Qcow2CompressFunc fn;
+
+switch (s->compression_type) {
+case QCOW2_COMPRESSION_TYPE_ZLIB:
+fn = qcow2_zlib_compress;
+break;
+
+default:
+abort();
+}
+
+return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, fn);
 }
 
+/*
+ * qcow2_co_decompress()
+ *
+ * Decompress some data (not more than @src_size bytes) to produce exactly
+ * @dest_size bytes using the compression method defined by the image
+ * compression type
+ *
+ * @dest - destination buffer, @dest_size bytes
+ * @src - source buffer, @src_size bytes
+ *
+ * Returns: 0 on success
+ *  a negative error code on failure
+ */
 ssize_t coroutine_fn
 qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size,
 const void *src, size_t src_size)
 {
-return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
-qcow2_decompress);
+BDRVQcow2State *s = bs->opaque;
+Qcow2CompressFunc fn;
+
+switch (s->compression_type) {
+case QCOW2_COMPRESSION_TYPE_ZLIB:
+fn = qcow2_zlib_decompress;
+break;
+
+default:
+abort();
+}
+
+return qcow2_co_do_compress(bs, dest, dest_size, src, src_size, fn);
 }
 
 
-- 
2.17.0




[PATCH v5 4/5] qcow2: add zstd cluster compression

2020-03-04 Thread Denis Plotnikov
zstd significantly reduces cluster compression time.
It provides better compression performance maintaining
the same level of the compression ratio in comparison with
zlib, which, at the moment, is the only compression
method available.

The performance test results:
Test compresses and decompresses qemu qcow2 image with just
installed rhel-7.6 guest.
Image cluster size: 64K. Image on disk size: 2.2G

The test was conducted with brd disk to reduce the influence
of disk subsystem to the test results.
The results is given in seconds.

compress cmd:
  time ./qemu-img convert -O qcow2 -c -o compression_type=[zlib|zstd]
  src.img [zlib|zstd]_compressed.img
decompress cmd
  time ./qemu-img convert -O qcow2
  [zlib|zstd]_compressed.img uncompressed.img

   compression   decompression
 zlib   zstd   zlib zstd

real 65.5   16.3 (-75 %)1.9  1.6 (-16 %)
user 65.0   15.85.3  2.5
sys   3.30.22.0  2.0

Both ZLIB and ZSTD gave the same compression ratio: 1.57
compressed image size in both cases: 1.4G

Signed-off-by: Denis Plotnikov 
QAPI part:
Acked-by: Markus Armbruster 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 docs/interop/qcow2.txt |  20 +++
 configure  |   2 +-
 qapi/block-core.json   |   3 +-
 block/qcow2-threads.c  | 123 +
 block/qcow2.c  |   7 +++
 5 files changed, 153 insertions(+), 2 deletions(-)

diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
index 5597e24474..9048114445 100644
--- a/docs/interop/qcow2.txt
+++ b/docs/interop/qcow2.txt
@@ -208,6 +208,7 @@ version 2.
 
 Available compression type values:
 0: zlib 
+1: zstd 
 
 
 === Header padding ===
@@ -575,11 +576,30 @@ Compressed Clusters Descriptor (x = 62 - (cluster_bits - 
8)):
 Another compressed cluster may map to the tail of the final
 sector used by this compressed cluster.
 
+The layout of the compressed data depends on the 
compression
+type used for the image (see compressed cluster layout).
+
 If a cluster is unallocated, read requests shall read the data from the backing
 file (except if bit 0 in the Standard Cluster Descriptor is set). If there is
 no backing file or the backing file is smaller than the image, they shall read
 zeros for all parts that are not covered by the backing file.
 
+=== Compressed Cluster Layout ===
+
+The compressed cluster data has a layout depending on the compression
+type used for the image, as follows:
+
+Compressed data layout for the available compression types:
+data_space_lenght - data chunk length available to store a compressed cluster.
+(for more details see "Compressed Clusters Descriptor")
+x = data_space_length - 1
+
+0:  (default)  zlib :
+Byte  0 -  x: the compressed data content
+  all the space provided used for compressed data
+1:  zstd :
+Byte  0 -  3: the length of compressed data in bytes
+  4 -  x: the compressed data content
 
 == Snapshots ==
 
diff --git a/configure b/configure
index caa65f5883..b2a0aa241a 100755
--- a/configure
+++ b/configure
@@ -1835,7 +1835,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   lzfse   support of lzfse compression library
   (for reading lzfse-compressed dmg images)
   zstdsupport for zstd compression library
-  (for migration compression)
+  (for migration compression and qcow2 cluster compression)
   seccomp seccomp support
   coroutine-pool  coroutine freelist (better performance)
   glusterfs   GlusterFS backend
diff --git a/qapi/block-core.json b/qapi/block-core.json
index a67eb8bff4..84889fb741 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4401,11 +4401,12 @@
 # Compression type used in qcow2 image file
 #
 # @zlib:  zlib compression, see 
+# @zstd:  zstd compression, see 
 #
 # Since: 5.0
 ##
 { 'enum': 'Qcow2CompressionType',
-  'data': [ 'zlib' ] }
+  'data': [ 'zlib', { 'name': 'zstd', 'if': 'defined(CONFIG_ZSTD)' } ] }
 
 ##
 # @BlockdevCreateOptionsQcow2:
diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
index 7dbaf53489..eeae68e88e 100644
--- a/block/qcow2-threads.c
+++ b/block/qcow2-threads.c
@@ -28,6 +28,11 @@
 #define ZLIB_CONST
 #include 
 
+#ifdef CONFIG_ZSTD
+#include 
+#include 
+#endif
+
 #include "qcow2.h"
 #include "block/thread-pool.h"
 #include "crypto.h"
@@ -166,6 +171,114 @@ static ssize_t qcow2_zlib_decompress(void *de

Re: [PATCH v6 18/18] pc-bios: s390x: Save iplb location in lowcore

2020-03-04 Thread David Hildenbrand
On 04.03.20 14:25, Christian Borntraeger wrote:
> On 04.03.20 12:42, Janosch Frank wrote:
>> The POP states that for a list directed IPL the IPLB is stored into
>> memory by the machine loader and its address is stored at offset 0x14
>> of the lowcore.
>>
>> ZIPL currently uses the address in offset 0x14 to access the IPLB and
>> acquire flags about secure boot. If the IPLB address points into
>> memory which has an unsupported mix of flags set, ZIPL will panic
>> instead of booting the OS.
>>
>> As the lowcore can have quite a high entropy for a guest that did drop
>> out of protected mode (i.e. rebooted) we encountered the ZIPL panic
>> quite often.
>>
>> Signed-off-by: Janosch Frank 
>> Tested-by: Marc Hartmayer 
> 
> I think this makes sense even without protected virtualization, no?
> Unless somebody complains, I think I will pick this up while Conny is
> on vacation.

Yes, makes sense!


-- 
Thanks,

David / dhildenb




  1   2   3   >