Re: [PATCH] qemu-img: add support for rate limit in qemu-img convert

2020-10-17 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/1602999390-21324-1-git-send-email-lizhen...@huawei.com/



Hi,

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

Type: series
Message-id: 1602999390-21324-1-git-send-email-lizhen...@huawei.com
Subject: [PATCH] qemu-img: add support for rate limit in qemu-img convert

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/1602999390-21324-1-git-send-email-lizhen...@huawei.com -> 
patchew/1602999390-21324-1-git-send-email-lizhen...@huawei.com
Switched to a new branch 'test'
c39672c qemu-img: add support for rate limit in qemu-img convert

=== OUTPUT BEGIN ===
ERROR: consider using qemu_strtoull in preference to strtoull
#94: FILE: qemu-img.c:2336:
+unsigned long long sval = strtoull(optarg, , 10);

total: 1 errors, 0 warnings, 94 lines checked

Commit c39672c23e5d (qemu-img: add support for rate limit in qemu-img convert) 
has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


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

Re: [PATCH] qemu-img: add support for offline rate limit in qemu-img commit

2020-10-17 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/1602999097-24744-1-git-send-email-lizhen...@huawei.com/



Hi,

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

Type: series
Message-id: 1602999097-24744-1-git-send-email-lizhen...@huawei.com
Subject: [PATCH] qemu-img: add support for offline rate limit in qemu-img commit

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/1602999097-24744-1-git-send-email-lizhen...@huawei.com -> 
patchew/1602999097-24744-1-git-send-email-lizhen...@huawei.com
Switched to a new branch 'test'
ffdac92 qemu-img: add support for offline rate limit in qemu-img commit

=== OUTPUT BEGIN ===
ERROR: consider using qemu_strtoull in preference to strtoull
#59: FILE: qemu-img.c:1032:
+unsigned long long sval = strtoull(optarg, , 10);

total: 1 errors, 0 warnings, 49 lines checked

Commit ffdac92f0f39 (qemu-img: add support for offline rate limit in qemu-img 
commit) has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


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

[PATCH] qemu-img: add support for rate limit in qemu-img convert

2020-10-17 Thread Zhengui li
From: Zhengui 

Currently, there is no rate limit for qemu-img convert. This may
cause the task of qemu-img convert to consume all the bandwidth
of the storage. This will affect the IO performance of other processes
and virtual machines under shared storage. So we add support for
offline rate limit in qemu-img convert to get better quality of sevice.

Signed-off-by: Zhengui 
---
 qemu-img-cmds.hx |  4 ++--
 qemu-img.c   | 35 ++-
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index ed55b76..70c0bf7 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ SRST
 ERST
 
 DEF("convert", img_convert,
-"convert [--object objectdef] [--image-opts] [--target-image-opts] 
[--target-is-zero] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t 
cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l 
snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] [--salvage] filename 
[filename2 [...]] output_filename")
+"convert [--object objectdef] [--image-opts] [--target-image-opts] 
[--target-is-zero] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t 
cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l 
snapshot_param] [-S sparse_size] [-r rate_limit] [-m num_coroutines] [-W] 
[--salvage] filename [filename2 [...]] output_filename")
 SRST
-.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] 
[--target-is-zero] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t 
CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l 
SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-m NUM_COROUTINES] [-W] [--salvage] FILENAME 
[FILENAME2 [...]] OUTPUT_FILENAME
+.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] 
[--target-is-zero] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t 
CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l 
SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-r RATE_LIMIT] [-m NUM_COROUTINES] [-W] 
[--salvage] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
 ERST
 
 DEF("create", img_create,
diff --git a/qemu-img.c b/qemu-img.c
index 67c83b47..d27d8a6 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -50,6 +50,8 @@
 #include "block/qapi.h"
 #include "crypto/init.h"
 #include "trace/control.h"
+#include "qemu/throttle.h"
+#include "block/throttle-groups.h"
 
 #define QEMU_IMG_VERSION "qemu-img version " QEMU_FULL_VERSION \
   "\n" QEMU_COPYRIGHT "\n"
@@ -1672,6 +1674,7 @@ enum ImgConvertBlockStatus {
 };
 
 #define MAX_COROUTINES 16
+#define CONVERT_THROTTLE_GROUP "img_convert"
 
 typedef struct ImgConvertState {
 BlockBackend **src;
@@ -2187,6 +2190,17 @@ static int convert_copy_bitmaps(BlockDriverState *src, 
BlockDriverState *dst)
 
 #define MAX_BUF_SECTORS 32768
 
+static void set_rate_limit(BlockBackend *blk, int64_t rate_limit)
+{
+ThrottleConfig cfg;
+
+throttle_config_init();
+cfg.buckets[THROTTLE_BPS_WRITE].avg = rate_limit;
+
+blk_io_limits_enable(blk, CONVERT_THROTTLE_GROUP);
+blk_set_io_limits(blk, );
+}
+
 static int img_convert(int argc, char **argv)
 {
 int c, bs_i, flags, src_flags = 0;
@@ -2207,6 +2221,7 @@ static int img_convert(int argc, char **argv)
 bool force_share = false;
 bool explict_min_sparse = false;
 bool bitmaps = false;
+int64_t rate_limit = 0;
 
 ImgConvertState s = (ImgConvertState) {
 /* Need at least 4k of zeros for sparse detection */
@@ -2229,7 +2244,7 @@ static int img_convert(int argc, char **argv)
 {"bitmaps", no_argument, 0, OPTION_BITMAPS},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WU",
+c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WUr:",
 long_options, NULL);
 if (c == -1) {
 break;
@@ -2326,6 +2341,16 @@ static int img_convert(int argc, char **argv)
 case 'U':
 force_share = true;
 break;
+case 'r': {
+char *end;
+unsigned long long sval = strtoull(optarg, , 10);
+if (*end != '\0' || sval > UINT_MAX) {
+error_report("rate limit parse failed");
+ret = -1;
+goto fail_getopt;
+}
+rate_limit = (int64_t)sval * 1024 * 1024;
+}   break;
 case OPTION_OBJECT: {
 QemuOpts *object_opts;
 object_opts = qemu_opts_parse_noisily(_object_opts,
@@ -2715,6 +2740,10 @@ static int img_convert(int argc, char **argv)
 s.cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE;
 }
 
+if (rate_limit) {
+set_rate_limit(s.target, rate_limit);
+}
+
 ret = convert_do_copy();
 
 /* Now copy the bitmaps */
@@ -2730,6 +2759,10 @@ out:
 qemu_opts_del(opts);
 qemu_opts_free(create_opts);
 qemu_opts_del(sn_opts);
+if (s.target && rate_limit &&
+ 

[PATCH] qemu-img: add support for offline rate limit in qemu-img commit

2020-10-17 Thread Zhengui li
From: Zhengui 

Currently, there is no rate limit for qemu-img commit. This may
cause the task of qemu-img commit to consume all the bandwidth
of the storage. This will affect the IO performance of other processes
and virtual machines under shared storage. So we add support for
offline rate limit in qemu-img commit to get better quality of sevice.

Signed-off-by: Zhengui 
---
 qemu-img-cmds.hx |  4 ++--
 qemu-img.c   | 14 --
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index b89c019..ed55b76 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -34,9 +34,9 @@ SRST
 ERST
 
 DEF("commit", img_commit,
-"commit [--object objectdef] [--image-opts] [-q] [-f fmt] [-t cache] [-b 
base] [-d] [-p] filename")
+"commit [--object objectdef] [--image-opts] [-q] [-f fmt] [-t cache] [-b 
base] [-s speed] [-d] [-p] filename")
 SRST
-.. option:: commit [--object OBJECTDEF] [--image-opts] [-q] [-f FMT] [-t 
CACHE] [-b BASE] [-d] [-p] FILENAME
+.. option:: commit [--object OBJECTDEF] [--image-opts] [-q] [-f FMT] [-t 
CACHE] [-b BASE] [-s SPEED] [-d] [-p] FILENAME
 ERST
 
 DEF("compare", img_compare,
diff --git a/qemu-img.c b/qemu-img.c
index 2103507..67c83b47 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -980,6 +980,7 @@ static int img_commit(int argc, char **argv)
 CommonBlockJobCBInfo cbi;
 bool image_opts = false;
 AioContext *aio_context;
+int64_t rate_limit = 0;
 
 fmt = NULL;
 cache = BDRV_DEFAULT_CACHE;
@@ -991,7 +992,7 @@ static int img_commit(int argc, char **argv)
 {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
 {0, 0, 0, 0}
 };
-c = getopt_long(argc, argv, ":f:ht:b:dpq",
+c = getopt_long(argc, argv, ":f:ht:b:dpqs:",
 long_options, NULL);
 if (c == -1) {
 break;
@@ -1026,6 +1027,15 @@ static int img_commit(int argc, char **argv)
 case 'q':
 quiet = true;
 break;
+case 's': {
+char *end;
+unsigned long long sval = strtoull(optarg, , 10);
+if (*end != '\0' || sval > UINT_MAX) {
+error_report("rate limit parse failed");
+return 1;
+}
+rate_limit = (int64_t)sval * 1024 * 1024;
+}   break;
 case OPTION_OBJECT: {
 QemuOpts *opts;
 opts = qemu_opts_parse_noisily(_object_opts,
@@ -1099,7 +1109,7 @@ static int img_commit(int argc, char **argv)
 
 aio_context = bdrv_get_aio_context(bs);
 aio_context_acquire(aio_context);
-commit_active_start("commit", bs, base_bs, JOB_DEFAULT, 0,
+commit_active_start("commit", bs, base_bs, JOB_DEFAULT, rate_limit,
 BLOCKDEV_ON_ERROR_REPORT, NULL, common_block_job_cb,
 , false, _err);
 aio_context_release(aio_context);
-- 
1.8.3.1




Re: [PATCH] drivers/virt: vmgenid: add vm generation id driver

2020-10-17 Thread Colm MacCarthaigh




On 17 Oct 2020, at 6:24, Jason A. Donenfeld wrote:


There are a few design goals of notifying userspace: it should be
fast, because people who are using userspace RNGs are usually doing so
in the first place to completely avoid syscall overhead for whatever
high performance application they have - e.g. I recall conversations
with Colm about his TLS implementation needing to make random IVs
_really_ fast.


That’s our old friend TLS1.1 in CBC mode, which needs a random 
explicit IV for every record sent. Speed is still a reason at the 
margins in cases like that, but getrandom() is really fast. A stickier 
problem is that getrandom() is not certified for use with every 
compliance standard, and those often dictate precise use of some NIST 
DRBG or NRBG construction. That keeps people proliferating user-space 
RNGs even when speed isn’t as important.



It should also happen as early as possible, with no
race or as minimal as possible race window, so that userspace doesn't
begin using old randomness and then switch over after the damage is
already done.


+1 to this, and I’d add that anyone making VM snapshots that they plan 
to restore from multiple times really needs to think this through top to 
bottom. The system would likely need to be put in to some kind of 
quiescent state when the snapshot is taken.



So, anyway, here are a few options with some pros and cons for the
kernel notifying userspace that its RNG should reseed.

1. SIGRND - a new signal. Lol.

2. Userspace opens a file descriptor that it can epoll on. Pros are
that many notification mechanisms already use this. Cons is that this
requires syscall and might be more racy than we want. Another con is
that this a new thing for userspace programs to do.


A library like OpenSSL or BoringSSL also has to account for running 
inside a chroot, which also makes this hard.



Any thoughts on 4c? Is that utterly insane, or does that actually get
us somewhere close to what we want?


I still like 4c, and as a user-space crypto-person, and a VM person, 
they have a lot of appeal. Alex and Adrian’s replies get into some of 
the sufficiency challenge. But for user-space libraries like the *SSLs, 
the JVMs, and other runtimes where RNGs show up, it could plug in easily 
enough.


-
Colm



Re: [PATCH] drivers/virt: vmgenid: add vm generation id driver

2020-10-17 Thread Jann Horn
On Sat, Oct 17, 2020 at 8:09 PM Alexander Graf  wrote:
> There are applications way beyond that though. What do you do with
> applications that already consumed randomness? For example a cached pool
> of SSL keys. Or a higher level language primitive that consumes
> randomness and caches its seed somewhere in an internal data structure.

For deterministic protection, those would also have to poll some
memory location that tells them whether the VmGenID changed:

1. between reading entropy from their RNG pool and using it
2. between collecting data from external sources (user input, clock,
...) and encrypting it

and synchronously shoot down the connection if a change happened. If
e.g. an application inside the VM has an AES-GCM-encrypted TLS
connection and, directly after the VM is restored, triggers an
application-level timeout that sends some fixed message across the
connection, then the TLS library must guarantee that either the VM was
already committed to sending exactly that message before the VM was
forked or the message will be blocked. If we don't do that, an
attacker who captures both a single packet from the forked VM and
traffic from the old VM can decrypt the next message from the old VM
after the fork (because AES-GCM is like AES-CTR plus an authenticator,
and CTR means that when keystream reuse occurs and one of the
plaintexts is known, the attacker can simply recover the other
plaintext using XOR).

(Or maybe, in disaster failover environments, TLS 1.3 servers could
get away with rekeying the connection instead of shooting it down? Ask
your resident friendly cryptographer whether that would be secure, I
am not one.)

I don't think a mechanism based around asynchronously telling the
application and waiting for it to confirm the rotation at a later
point is going to cut it; we should have some hard semantics on when
an application needs to poll this value.

> Or even worse: your system's host ssh key.

Mmmh... I think I normally would not want a VM to reset its host ssh
key after merely restoring a snapshot though? And more importantly,
Microsoft's docs say that they also change the VmGenID on disaster
failover. I think you very much wouldn't want your server to lose its
host key every time disaster failover happens. On the other hand,
after importing a public VM image, it might be a good idea.

I guess you could push that responsibility on the user, by adding an
option to the sshd_config that tells OpenSSH whether the host key
should be rotated on an ID change or not... but that still would not
be particularly pretty.

Ideally we would have the host tell us what type of events happened to
the VM, or something like that... or maybe even get the host VM
management software to ask the user whether they're importing a public
image... I really feel like with Microsoft's current protocol, we
don't get enough information to figure out what we should do about
private long-term authentication keys.



Re: [PATCH v26 05/17] vfio: Add VM state change handler to know state of VM

2020-10-17 Thread Alex Williamson
On Sun, 18 Oct 2020 02:00:44 +0530
Kirti Wankhede  wrote:

> On 9/26/2020 1:50 AM, Alex Williamson wrote:
> > On Wed, 23 Sep 2020 04:54:07 +0530
> > Kirti Wankhede  wrote:
> >   
> >> VM state change handler gets called on change in VM's state. This is used 
> >> to set
> >> VFIO device state to _RUNNING.
> >>
> >> Signed-off-by: Kirti Wankhede 
> >> Reviewed-by: Neo Jia 
> >> Reviewed-by: Dr. David Alan Gilbert 
> >> ---
> >>   hw/vfio/migration.c   | 136 
> >> ++
> >>   hw/vfio/trace-events  |   3 +-
> >>   include/hw/vfio/vfio-common.h |   4 ++
> >>   3 files changed, 142 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
> >> index 2f760f1f9c47..a30d628ba963 100644
> >> --- a/hw/vfio/migration.c
> >> +++ b/hw/vfio/migration.c
> >> @@ -10,6 +10,7 @@
> >>   #include "qemu/osdep.h"
> >>   #include 
> >>   
> >> +#include "sysemu/runstate.h"
> >>   #include "hw/vfio/vfio-common.h"
> >>   #include "cpu.h"
> >>   #include "migration/migration.h"
> >> @@ -22,6 +23,58 @@
> >>   #include "exec/ram_addr.h"
> >>   #include "pci.h"
> >>   #include "trace.h"
> >> +#include "hw/hw.h"
> >> +
> >> +static inline int vfio_mig_access(VFIODevice *vbasedev, void *val, int 
> >> count,
> >> +  off_t off, bool iswrite)
> >> +{
> >> +int ret;
> >> +
> >> +ret = iswrite ? pwrite(vbasedev->fd, val, count, off) :
> >> +pread(vbasedev->fd, val, count, off);
> >> +if (ret < count) {
> >> +error_report("vfio_mig_%s%d %s: failed at offset 0x%lx, err: %s",
> >> + iswrite ? "write" : "read", count * 8,
> >> + vbasedev->name, off, strerror(errno));  
> > 
> > This would suggest from the log that there's, for example, a
> > vfio_mig_read8 function, which doesn't exist.
> >   
> 
> Changing to:
> error_report("vfio_mig_%s %d byte %s: failed at offset 0x%lx, err: %s",
>   iswrite ? "write" : "read", count,
>   vbasedev->name, off, strerror(errno));
> Hope this address your concern.
> 
> >> +return (ret < 0) ? ret : -EINVAL;
> >> +}
> >> +return 0;
> >> +}
> >> +
> >> +static int vfio_mig_rw(VFIODevice *vbasedev, __u8 *buf, size_t count,
> >> +   off_t off, bool iswrite)
> >> +{
> >> +int ret, done = 0;
> >> +__u8 *tbuf = buf;
> >> +
> >> +while (count) {
> >> +int bytes = 0;
> >> +
> >> +if (count >= 8 && !(off % 8)) {
> >> +bytes = 8;
> >> +} else if (count >= 4 && !(off % 4)) {
> >> +bytes = 4;
> >> +} else if (count >= 2 && !(off % 2)) {
> >> +bytes = 2;
> >> +} else {
> >> +bytes = 1;
> >> +}
> >> +
> >> +ret = vfio_mig_access(vbasedev, tbuf, bytes, off, iswrite);
> >> +if (ret) {
> >> +return ret;
> >> +}
> >> +
> >> +count -= bytes;
> >> +done += bytes;
> >> +off += bytes;
> >> +tbuf += bytes;
> >> +}
> >> +return done;
> >> +}
> >> +
> >> +#define vfio_mig_read(f, v, c, o)   vfio_mig_rw(f, (__u8 *)v, c, o, 
> >> false)
> >> +#define vfio_mig_write(f, v, c, o)  vfio_mig_rw(f, (__u8 *)v, c, o, 
> >> true)
> >>   
> >>   static void vfio_migration_region_exit(VFIODevice *vbasedev)
> >>   {
> >> @@ -70,6 +123,82 @@ err:
> >>   return ret;
> >>   }
> >>   
> >> +static int vfio_migration_set_state(VFIODevice *vbasedev, uint32_t mask,
> >> +uint32_t value)
> >> +{
> >> +VFIOMigration *migration = vbasedev->migration;
> >> +VFIORegion *region = >region;
> >> +off_t dev_state_off = region->fd_offset +
> >> +  offsetof(struct vfio_device_migration_info, 
> >> device_state);
> >> +uint32_t device_state;
> >> +int ret;
> >> +
> >> +ret = vfio_mig_read(vbasedev, _state, sizeof(device_state),
> >> +dev_state_off);
> >> +if (ret < 0) {
> >> +return ret;
> >> +}
> >> +
> >> +device_state = (device_state & mask) | value;  
> > 
> > Agree with Connie that mask and value args are not immediately obvious
> > how they're used.  I don't have a naming convention that would be more
> > clear and the names do make some sense once they're understood, but a
> > comment to indicate mask bits are preserved, value bits are set,
> > remaining bits are cleared would probably help the reader.
> >   
> 
> Added comment.
> 
> >> +
> >> +if (!VFIO_DEVICE_STATE_VALID(device_state)) {
> >> +return -EINVAL;
> >> +}
> >> +
> >> +ret = vfio_mig_write(vbasedev, _state, sizeof(device_state),
> >> + dev_state_off);
> >> +if (ret < 0) {
> >> +ret = vfio_mig_read(vbasedev, _state, sizeof(device_state),
> >> +  dev_state_off);
> >> +if (ret < 0) {
> >> +return ret;  
> > 
> > Seems like we're in 

Re: [PATCH v9] mac_oldworld: Allow loading binary ROM image

2020-10-17 Thread BALATON Zoltan via

On Sat, 17 Oct 2020, Philippe Mathieu-Daudé wrote:

On 10/17/20 6:31 PM, BALATON Zoltan via wrote:

On Sat, 17 Oct 2020, Philippe Mathieu-Daudé wrote:

+Alistair for loader

On 10/17/20 5:47 PM, BALATON Zoltan via wrote:

The beige G3 Power Macintosh has a 4MB firmware ROM. Fix the size of
the rom region and fall back to loading a binary image with -bios if
loading ELF image failed. This allows testing emulation with a ROM
image from real hardware as well as using an ELF OpenBIOS image.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Mark Cave-Ayland 
---
v9: Revert change from v8, back to the same as v7 rebased on latest

  hw/ppc/mac_oldworld.c | 29 -
  1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 05e46ee6fe..0117ae17f5 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -59,6 +59,8 @@
  #define NDRV_VGA_FILENAME "qemu_vga.ndrv"
    #define GRACKLE_BASE 0xfec0
+#define PROM_BASE 0xffc0
+#define PROM_SIZE (4 * MiB)
    static void fw_cfg_boot_set(void *opaque, const char *boot_device,
  Error **errp)
@@ -100,6 +102,7 @@ static void ppc_heathrow_init(MachineState *machine)
  SysBusDevice *s;
  DeviceState *dev, *pic_dev;
  BusState *adb_bus;
+    uint64_t bios_addr;
  int bios_size;
  unsigned int smp_cpus = machine->smp.cpus;
  uint16_t ppc_boot_device;
@@ -128,24 +131,32 @@ static void ppc_heathrow_init(MachineState 
*machine)

    memory_region_add_subregion(sysmem, 0, machine->ram);
  -    /* allocate and load BIOS */
-    memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE,
+    /* allocate and load firmware ROM */
+    memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", PROM_SIZE,
 _fatal);
+    memory_region_add_subregion(sysmem, PROM_BASE, bios);
  -    if (bios_name == NULL)
+    if (!bios_name) {
  bios_name = PROM_FILENAME;
+    }
  filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-    memory_region_add_subregion(sysmem, PROM_ADDR, bios);
-
-    /* Load OpenBIOS (ELF) */
  if (filename) {
-    bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL, 
NULL,

- 1, PPC_ELF_MACHINE, 0, 0);
+    /* Load OpenBIOS (ELF) */
+    bios_size = load_elf(filename, NULL, NULL, NULL, NULL, 
_addr,

+ NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
+    /* Unfortunately, load_elf sign-extends reading elf32 */


Maybe this is what translate_fn() is for?

uint64_t oldworld_phys(void *opaque, uint64_t addr)
{
   return addr & UINT32_MAX;
}

Using as (untested):

   bios_size = load_elf(filename, NULL, oldworld_phys, NULL,
    NULL, _addr, NULL,
    NULL, 1, PPC_ELF_MACHINE, 0, 0);


Please don't come up with any more great ideas for this patch unless you 
also propose a replacement and test it. This one works and we could just 
get this in as it is until the real problem with load_elf is fixed at which 
point all this can be removed so no need to be more sophisticated as the 
simple cast I have.


Zoltan, I'm not trying to block your patch to get merged,


I didn't say you're trying to do that but based on my past experience any 
slightest doubt could result in that so I did not want it to miss another 
freeze now that it's almost got in.



I'm asking because I'm trying to understand how this API
is expected to be used.


Likely nobody knows, this seems to have been evolved into this mess which 
could be cleaned up but unrelated to this series. Probably nobody dared to 
touch it so far as it's used by almost every board so breling something is 
easy and testing it is difficult.


Regards,
BALATON Zoltan


As you can see in the original discussion:

http://patchwork.ozlabs.org/project/qemu-devel/patch/c69a791c7cad1246f3f34b3993dee4f549b75aa2.1593456926.git.bala...@eik.bme.hu/ 

problem is really in include/hw/elf_ops.h this is just a work around for 
that as I did not want to break anything I can't test so I'd rather fix it 
up here and let you fix load_elf then drop this cast. But unless you can do 
that before the freeze please don't hold up this patch any more.


Regards,
BALATON Zoltan


+    bios_addr = (uint32_t)bios_addr;
+
+    if (bios_size <= 0) {
+    /* or load binary ROM image */
+    bios_size = load_image_targphys(filename, PROM_BASE, 
PROM_SIZE);

+    bios_addr = PROM_BASE;
+    }
  g_free(filename);
  } else {
  bios_size = -1;
  }
-    if (bios_size < 0 || bios_size > BIOS_SIZE) {
+    if (bios_size < 0 || bios_addr - PROM_BASE + bios_size > PROM_SIZE) 
{

  error_report("could not load PowerPC bios '%s'", bios_name);
  exit(1);
  }









[PATCH] accel/kvm: add PIO ioeventfds only in case kvm_eventfds_allowed is true

2020-10-17 Thread Elena Afanasova
Signed-off-by: Stefan Hajnoczi 
Signed-off-by: Elena Afanasova 
---
 accel/kvm/kvm-all.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 9ef5daf4c5..baaa54249d 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2239,8 +2239,10 @@ static int kvm_init(MachineState *ms)
 
 kvm_memory_listener_register(s, >memory_listener,
  _space_memory, 0);
-memory_listener_register(_io_listener,
- _space_io);
+if (kvm_eventfds_allowed) {
+memory_listener_register(_io_listener,
+ _space_io);
+}
 memory_listener_register(_coalesced_pio_listener,
  _space_io);
 
-- 
2.25.1




[PATCH] softmmu/memory: fix memory_region_ioeventfd_equal()

2020-10-17 Thread Elena Afanasova
Eventfd can be registered with a zero length when fast_mmio is true.
Handle this case properly when dispatching through QEMU.

Signed-off-by: Elena Afanasova 
---
 softmmu/memory.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/softmmu/memory.c b/softmmu/memory.c
index 403ff3abc9..3ca2154a64 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -203,10 +203,17 @@ static bool 
memory_region_ioeventfd_before(MemoryRegionIoeventfd *a,
 }
 
 static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd *a,
-  MemoryRegionIoeventfd *b)
-{
-return !memory_region_ioeventfd_before(a, b)
-&& !memory_region_ioeventfd_before(b, a);
+  MemoryRegionIoeventfd *mrb)
+{
+if (int128_eq(a->addr.start, mrb->addr.start) &&
+(!int128_nz(mrb->addr.size) ||
+ int128_eq(a->addr.size, mrb->addr.size)) &&
+(a->match_data == mrb->match_data) &&
+((mrb->match_data && (a->data == mrb->data)) || !mrb->match_data) 
&&
+(a->e == mrb->e))
+return true;
+
+return false;
 }
 
 /* Range of memory in the global map.  Addresses are absolute. */
-- 
2.25.1




[PATCH 3/6] sun4m: use qdev instead of legacy m48t59_init() function

2020-10-17 Thread BALATON Zoltan via
Also declare nvram variable with the correct type.

Signed-off-by: BALATON Zoltan 
---
 hw/sparc/sun4m.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 54a2b2f9ef..7f1a48440c 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -837,7 +837,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 {
 DeviceState *slavio_intctl;
 unsigned int i;
-void *nvram;
+Nvram *nvram;
 qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
 qemu_irq fdc_tc;
 unsigned long kernel_size;
@@ -966,7 +966,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
 create_unimplemented_device("SUNW,sx", hwdef->sx_base, 0x2000);
 }
 
-nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x2000, 1968, 8);
+nvram = NVRAM(sysbus_create_simple("sysbus-m48t08", hwdef->nvram_base,
+   slavio_irq[0]));
 
 slavio_timer_init_all(hwdef->counter_base, slavio_irq[19], slavio_cpu_irq, 
smp_cpus);
 
-- 
2.21.3




[PATCH 6/6] m48t59: remove legacy m48t59_init() function

2020-10-17 Thread BALATON Zoltan via
From: Mark Cave-Ayland 

Now that all of the callers of this function have been switched to use qdev
properties, this legacy init function can now be removed.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Hervé Poussineau 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/rtc/m48t59.c | 35 ---
 include/hw/rtc/m48t59.h |  4 
 2 files changed, 39 deletions(-)

diff --git a/hw/rtc/m48t59.c b/hw/rtc/m48t59.c
index 3108cf3d3f..e74716c491 100644
--- a/hw/rtc/m48t59.c
+++ b/hw/rtc/m48t59.c
@@ -564,41 +564,6 @@ const MemoryRegionOps m48t59_io_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-/* Initialisation routine */
-Nvram *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
-   uint32_t io_base, uint16_t size, int base_year,
-   int model)
-{
-DeviceState *dev;
-SysBusDevice *s;
-int i;
-
-for (i = 0; i < ARRAY_SIZE(m48txx_sysbus_info); i++) {
-if (m48txx_sysbus_info[i].size != size ||
-m48txx_sysbus_info[i].model != model) {
-continue;
-}
-
-dev = qdev_new(m48txx_sysbus_info[i].bus_name);
-qdev_prop_set_int32(dev, "base-year", base_year);
-s = SYS_BUS_DEVICE(dev);
-sysbus_realize_and_unref(s, _fatal);
-sysbus_connect_irq(s, 0, IRQ);
-if (io_base != 0) {
-memory_region_add_subregion(get_system_io(), io_base,
-sysbus_mmio_get_region(s, 1));
-}
-if (mem_base != 0) {
-sysbus_mmio_map(s, 0, mem_base);
-}
-
-return NVRAM(s);
-}
-
-assert(false);
-return NULL;
-}
-
 void m48t59_realize_common(M48t59State *s, Error **errp)
 {
 s->buffer = g_malloc0(s->size);
diff --git a/include/hw/rtc/m48t59.h b/include/hw/rtc/m48t59.h
index 9defe578d1..d9b45eb161 100644
--- a/include/hw/rtc/m48t59.h
+++ b/include/hw/rtc/m48t59.h
@@ -47,8 +47,4 @@ struct NvramClass {
 void (*toggle_lock)(Nvram *obj, int lock);
 };
 
-Nvram *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
-   uint32_t io_base, uint16_t size, int base_year,
-   int type);
-
 #endif /* HW_M48T59_H */
-- 
2.21.3




[PATCH 0/6] m48t59: remove legacy init functions

2020-10-17 Thread BALATON Zoltan via
This is inspired by Mark's series:

https://lists.nongnu.org/archive/html/qemu-ppc/2020-10/msg00251.html

and implements what I've suggested in review of that series to
simplify it and avoid code churn if implementing my suggestion later.

Regards,
BALATON Zoltan

BALATON Zoltan (4):
  mt48t59: Set default value of base-year property to 1968
  sun4m: use qdev instead of legacy m48t59_init() function
  sun4u: use qdev instead of legacy m48t59_init() function
  ppc405_boards: use qdev instead of legacy m48t59_init() function

Mark Cave-Ayland (2):
  m48t59-isa: remove legacy m48t59_init_isa() function
  m48t59: remove legacy m48t59_init() function

 hw/ppc/ppc405_boards.c  |  3 ++-
 hw/rtc/m48t59-isa.c | 25 -
 hw/rtc/m48t59.c | 37 +
 hw/sparc/sun4m.c|  5 +++--
 hw/sparc64/sun4u.c  |  6 --
 include/hw/rtc/m48t59.h |  6 --
 6 files changed, 10 insertions(+), 72 deletions(-)

-- 
2.21.3




[PATCH 1/6] m48t59-isa: remove legacy m48t59_init_isa() function

2020-10-17 Thread BALATON Zoltan via
From: Mark Cave-Ayland 

This function is no longer used within the codebase.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Hervé Poussineau 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
---
 hw/rtc/m48t59-isa.c | 25 -
 include/hw/rtc/m48t59.h |  2 --
 2 files changed, 27 deletions(-)

diff --git a/hw/rtc/m48t59-isa.c b/hw/rtc/m48t59-isa.c
index cae315e488..dc21fb10a5 100644
--- a/hw/rtc/m48t59-isa.c
+++ b/hw/rtc/m48t59-isa.c
@@ -58,31 +58,6 @@ static M48txxInfo m48txx_isa_info[] = {
 }
 };
 
-Nvram *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
-   int base_year, int model)
-{
-ISADevice *isa_dev;
-DeviceState *dev;
-int i;
-
-for (i = 0; i < ARRAY_SIZE(m48txx_isa_info); i++) {
-if (m48txx_isa_info[i].size != size ||
-m48txx_isa_info[i].model != model) {
-continue;
-}
-
-isa_dev = isa_new(m48txx_isa_info[i].bus_name);
-dev = DEVICE(isa_dev);
-qdev_prop_set_uint32(dev, "iobase", io_base);
-qdev_prop_set_int32(dev, "base-year", base_year);
-isa_realize_and_unref(isa_dev, bus, _fatal);
-return NVRAM(dev);
-}
-
-assert(false);
-return NULL;
-}
-
 static uint32_t m48txx_isa_read(Nvram *obj, uint32_t addr)
 {
 M48txxISAState *d = M48TXX_ISA(obj);
diff --git a/include/hw/rtc/m48t59.h b/include/hw/rtc/m48t59.h
index 04abedf3b2..9defe578d1 100644
--- a/include/hw/rtc/m48t59.h
+++ b/include/hw/rtc/m48t59.h
@@ -47,8 +47,6 @@ struct NvramClass {
 void (*toggle_lock)(Nvram *obj, int lock);
 };
 
-Nvram *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
-   int base_year, int type);
 Nvram *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
uint32_t io_base, uint16_t size, int base_year,
int type);
-- 
2.21.3




Re: [PATCH v26 07/17] vfio: Register SaveVMHandlers for VFIO device

2020-10-17 Thread Kirti Wankhede




On 9/29/2020 3:49 PM, Dr. David Alan Gilbert wrote:

* Philippe Mathieu-Daudé (phi...@redhat.com) wrote:

On 9/23/20 1:24 AM, Kirti Wankhede wrote:

Define flags to be used as delimeter in migration file stream.


Typo "delimiter".


Added .save_setup and .save_cleanup functions. Mapped & unmapped migration
region from these functions at source during saving or pre-copy phase.
Set VFIO device state depending on VM's state. During live migration, VM is
running when .save_setup is called, _SAVING | _RUNNING state is set for VFIO
device. During save-restore, VM is paused, _SAVING state is set for VFIO device.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
---
  hw/vfio/migration.c  | 91 
  hw/vfio/trace-events |  2 ++
  2 files changed, 93 insertions(+)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index f650fe9fc3c8..8e8adaa25779 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -8,12 +8,15 @@
   */
  
  #include "qemu/osdep.h"

+#include "qemu/main-loop.h"
+#include "qemu/cutils.h"
  #include 
  
  #include "sysemu/runstate.h"

  #include "hw/vfio/vfio-common.h"
  #include "cpu.h"
  #include "migration/migration.h"
+#include "migration/vmstate.h"
  #include "migration/qemu-file.h"
  #include "migration/register.h"
  #include "migration/blocker.h"
@@ -25,6 +28,17 @@
  #include "trace.h"
  #include "hw/hw.h"
  
+/*

+ * Flags used as delimiter:
+ * 0x => MSB 32-bit all 1s
+ * 0xef10 => emulated (virtual) function IO
+ * 0x => 16-bits reserved for flags
+ */
+#define VFIO_MIG_FLAG_END_OF_STATE  (0xef11ULL)
+#define VFIO_MIG_FLAG_DEV_CONFIG_STATE  (0xef12ULL)
+#define VFIO_MIG_FLAG_DEV_SETUP_STATE   (0xef13ULL)
+#define VFIO_MIG_FLAG_DEV_DATA_STATE(0xef14ULL)
+
  static inline int vfio_mig_access(VFIODevice *vbasedev, void *val, int count,
off_t off, bool iswrite)
  {
@@ -166,6 +180,65 @@ static int vfio_migration_set_state(VFIODevice *vbasedev, 
uint32_t mask,
  return 0;
  }
  
+/* -- */

+
+static int vfio_save_setup(QEMUFile *f, void *opaque)
+{
+VFIODevice *vbasedev = opaque;
+VFIOMigration *migration = vbasedev->migration;
+int ret;
+
+trace_vfio_save_setup(vbasedev->name);
+
+qemu_put_be64(f, VFIO_MIG_FLAG_DEV_SETUP_STATE);
+
+if (migration->region.mmaps) {
+qemu_mutex_lock_iothread();
+ret = vfio_region_mmap(>region);
+qemu_mutex_unlock_iothread();
+if (ret) {
+error_report("%s: Failed to mmap VFIO migration region %d: %s",
+ vbasedev->name, migration->region.nr,
+ strerror(-ret));
+error_report("%s: Falling back to slow path", vbasedev->name);
+}
+}
+
+ret = vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_MASK,
+   VFIO_DEVICE_STATE_SAVING);
+if (ret) {
+error_report("%s: Failed to set state SAVING", vbasedev->name);
+return ret;
+}
+
+qemu_put_be64(f, VFIO_MIG_FLAG_END_OF_STATE);
+
+ret = qemu_file_get_error(f);
+if (ret) {
+return ret;
+}
+
+return 0;
+}
+
+static void vfio_save_cleanup(void *opaque)
+{
+VFIODevice *vbasedev = opaque;
+VFIOMigration *migration = vbasedev->migration;
+
+if (migration->region.mmaps) {
+vfio_region_unmap(>region);
+}
+trace_vfio_save_cleanup(vbasedev->name);
+}
+
+static SaveVMHandlers savevm_vfio_handlers = {
+.save_setup = vfio_save_setup,
+.save_cleanup = vfio_save_cleanup,
+};
+
+/* -- */
+
  static void vfio_vmstate_change(void *opaque, int running, RunState state)
  {
  VFIODevice *vbasedev = opaque;
@@ -225,6 +298,8 @@ static int vfio_migration_init(VFIODevice *vbasedev,
 struct vfio_region_info *info)
  {
  int ret = -EINVAL;
+char id[256] = "";
+Object *obj;
  
  if (!vbasedev->ops->vfio_get_object) {

  return ret;
@@ -241,6 +316,22 @@ static int vfio_migration_init(VFIODevice *vbasedev,
  return ret;
  }
  
+obj = vbasedev->ops->vfio_get_object(vbasedev);

+
+if (obj) {
+DeviceState *dev = DEVICE(obj);
+char *oid = vmstate_if_get_id(VMSTATE_IF(dev));
+
+if (oid) {
+pstrcpy(id, sizeof(id), oid);
+pstrcat(id, sizeof(id), "/");
+g_free(oid);
+}
+}
+pstrcat(id, sizeof(id), "vfio");


Alternatively (easier to review, matter of taste):

  g_autofree char *path = NULL;

  if (oid) {
path = g_strdup_printf("%s/vfio",
   vmstate_if_get_id(VMSTATE_IF(obj)););
  } else {
path = g_strdup("vfio");
  }
  strpadcpy(id, sizeof(id), path, '\0');


Maybe, although it's a straight copy of the 

[PATCH 4/6] sun4u: use qdev instead of legacy m48t59_init() function

2020-10-17 Thread BALATON Zoltan via
Signed-off-by: BALATON Zoltan 
---
 hw/sparc64/sun4u.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index ad5ca2472a..a89ebed6f0 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -671,10 +671,12 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
 pci_ide_create_devs(pci_dev);
 
 /* Map NVRAM into I/O (ebus) space */
-nvram = m48t59_init(NULL, 0, 0, NVRAM_SIZE, 1968, 59);
-s = SYS_BUS_DEVICE(nvram);
+dev = qdev_new("sysbus-m48t59");
+s = SYS_BUS_DEVICE(dev);
+sysbus_realize_and_unref(s, _fatal);
 memory_region_add_subregion(pci_address_space_io(ebus), 0x2000,
 sysbus_mmio_get_region(s, 0));
+nvram = NVRAM(dev);
  
 initrd_size = 0;
 initrd_addr = 0;
-- 
2.21.3




[PATCH 5/6] ppc405_boards: use qdev instead of legacy m48t59_init() function

2020-10-17 Thread BALATON Zoltan via
Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc405_boards.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 6198ec1035..7a11a38831 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -28,6 +28,7 @@
 #include "qemu-common.h"
 #include "cpu.h"
 #include "hw/ppc/ppc.h"
+#include "hw/sysbus.h"
 #include "ppc405.h"
 #include "hw/rtc/m48t59.h"
 #include "hw/block/flash.h"
@@ -227,7 +228,7 @@ static void ref405ep_init(MachineState *machine)
 /* Register FPGA */
 ref405ep_fpga_init(sysmem, 0xF030);
 /* Register NVRAM */
-m48t59_init(NULL, 0xF000, 0, 8192, 1968, 8);
+sysbus_create_simple("sysbus-m48t08", 0xF000, NULL);
 /* Load kernel */
 linux_boot = (kernel_filename != NULL);
 if (linux_boot) {
-- 
2.21.3




[PATCH 2/6] mt48t59: Set default value of base-year property to 1968

2020-10-17 Thread BALATON Zoltan via
All instances set this value explicitely so make it the default to
make it simpler to create instances without setting property.

Signed-off-by: BALATON Zoltan 
---
 hw/rtc/m48t59.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/rtc/m48t59.c b/hw/rtc/m48t59.c
index 6525206976..3108cf3d3f 100644
--- a/hw/rtc/m48t59.c
+++ b/hw/rtc/m48t59.c
@@ -655,7 +655,7 @@ static void m48txx_sysbus_toggle_lock(Nvram *obj, int lock)
 }
 
 static Property m48t59_sysbus_properties[] = {
-DEFINE_PROP_INT32("base-year", M48txxSysBusState, state.base_year, 0),
+DEFINE_PROP_INT32("base-year", M48txxSysBusState, state.base_year, 1968),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.21.3




Re: [PATCH v26 06/17] vfio: Add migration state change notifier

2020-10-17 Thread Kirti Wankhede




On 9/26/2020 1:50 AM, Alex Williamson wrote:

On Wed, 23 Sep 2020 04:54:08 +0530
Kirti Wankhede  wrote:


Added migration state change notifier to get notification on migration state
change. These states are translated to VFIO device state and conveyed to vendor
driver.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
Reviewed-by: Dr. David Alan Gilbert 
---
  hw/vfio/migration.c   | 29 +
  hw/vfio/trace-events  |  5 +++--
  include/hw/vfio/vfio-common.h |  1 +
  3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index a30d628ba963..f650fe9fc3c8 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -199,6 +199,28 @@ static void vfio_vmstate_change(void *opaque, int running, 
RunState state)
  }
  }
  
+static void vfio_migration_state_notifier(Notifier *notifier, void *data)

+{
+MigrationState *s = data;
+VFIODevice *vbasedev = container_of(notifier, VFIODevice, migration_state);
+int ret;
+
+trace_vfio_migration_state_notifier(vbasedev->name,
+MigrationStatus_str(s->state));
+
+switch (s->state) {
+case MIGRATION_STATUS_CANCELLING:
+case MIGRATION_STATUS_CANCELLED:
+case MIGRATION_STATUS_FAILED:
+ret = vfio_migration_set_state(vbasedev,
+  ~(VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RESUMING),
+  VFIO_DEVICE_STATE_RUNNING);
+if (ret) {
+error_report("%s: Failed to set state RUNNING", vbasedev->name);
+}


Here again the caller assumes success means the device has entered the
desired state, but as implemented it only means the device is in some
non-error state.


+}
+}
+
  static int vfio_migration_init(VFIODevice *vbasedev,
 struct vfio_region_info *info)
  {
@@ -221,6 +243,8 @@ static int vfio_migration_init(VFIODevice *vbasedev,
  
  vbasedev->vm_state = qemu_add_vm_change_state_handler(vfio_vmstate_change,

vbasedev);
+vbasedev->migration_state.notify = vfio_migration_state_notifier;
+add_migration_state_change_notifier(>migration_state);
  return ret;
  }
  
@@ -263,6 +287,11 @@ add_blocker:
  
  void vfio_migration_finalize(VFIODevice *vbasedev)

  {
+
+if (vbasedev->migration_state.notify) {
+remove_migration_state_change_notifier(>migration_state);
+}
+
  if (vbasedev->vm_state) {
  qemu_del_vm_change_state_handler(vbasedev->vm_state);
  }
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 6524734bf7b4..bcb3fa7314d7 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -149,5 +149,6 @@ vfio_display_edid_write_error(void) ""
  
  # migration.c

  vfio_migration_probe(const char *name, uint32_t index) " (%s) Region %d"
-vfio_migration_set_state(char *name, uint32_t state) " (%s) state %d"
-vfio_vmstate_change(char *name, int running, const char *reason, uint32_t dev_state) 
" (%s) running %d reason %s device state %d"
+vfio_migration_set_state(const char *name, uint32_t state) " (%s) state %d"
+vfio_vmstate_change(const char *name, int running, const char *reason, uint32_t 
dev_state) " (%s) running %d reason %s device state %d"
+vfio_migration_state_notifier(const char *name, const char *state) " (%s) state 
%s"
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 25e3b1a3b90a..49c7c7a0e29a 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -123,6 +123,7 @@ typedef struct VFIODevice {
  VMChangeStateEntry *vm_state;
  uint32_t device_state;
  int vm_running;
+Notifier migration_state;


Can this live in VFIOMigration?  Thanks,



No, callback vfio_migration_state_notifier() has notifier argument and 
to reach its corresponding device structure as below, its should be in 
VFIODevice.


VFIODevice *vbasedev = container_of(notifier, VFIODevice, migration_state);

Thanks,
Kirti


Alex


  } VFIODevice;
  
  struct VFIODeviceOps {






Re: [PATCH v26 05/17] vfio: Add VM state change handler to know state of VM

2020-10-17 Thread Kirti Wankhede




On 9/26/2020 1:50 AM, Alex Williamson wrote:

On Wed, 23 Sep 2020 04:54:07 +0530
Kirti Wankhede  wrote:


VM state change handler gets called on change in VM's state. This is used to set
VFIO device state to _RUNNING.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
Reviewed-by: Dr. David Alan Gilbert 
---
  hw/vfio/migration.c   | 136 ++
  hw/vfio/trace-events  |   3 +-
  include/hw/vfio/vfio-common.h |   4 ++
  3 files changed, 142 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 2f760f1f9c47..a30d628ba963 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -10,6 +10,7 @@
  #include "qemu/osdep.h"
  #include 
  
+#include "sysemu/runstate.h"

  #include "hw/vfio/vfio-common.h"
  #include "cpu.h"
  #include "migration/migration.h"
@@ -22,6 +23,58 @@
  #include "exec/ram_addr.h"
  #include "pci.h"
  #include "trace.h"
+#include "hw/hw.h"
+
+static inline int vfio_mig_access(VFIODevice *vbasedev, void *val, int count,
+  off_t off, bool iswrite)
+{
+int ret;
+
+ret = iswrite ? pwrite(vbasedev->fd, val, count, off) :
+pread(vbasedev->fd, val, count, off);
+if (ret < count) {
+error_report("vfio_mig_%s%d %s: failed at offset 0x%lx, err: %s",
+ iswrite ? "write" : "read", count * 8,
+ vbasedev->name, off, strerror(errno));


This would suggest from the log that there's, for example, a
vfio_mig_read8 function, which doesn't exist.



Changing to:
error_report("vfio_mig_%s %d byte %s: failed at offset 0x%lx, err: %s",
 iswrite ? "write" : "read", count,
 vbasedev->name, off, strerror(errno));
Hope this address your concern.


+return (ret < 0) ? ret : -EINVAL;
+}
+return 0;
+}
+
+static int vfio_mig_rw(VFIODevice *vbasedev, __u8 *buf, size_t count,
+   off_t off, bool iswrite)
+{
+int ret, done = 0;
+__u8 *tbuf = buf;
+
+while (count) {
+int bytes = 0;
+
+if (count >= 8 && !(off % 8)) {
+bytes = 8;
+} else if (count >= 4 && !(off % 4)) {
+bytes = 4;
+} else if (count >= 2 && !(off % 2)) {
+bytes = 2;
+} else {
+bytes = 1;
+}
+
+ret = vfio_mig_access(vbasedev, tbuf, bytes, off, iswrite);
+if (ret) {
+return ret;
+}
+
+count -= bytes;
+done += bytes;
+off += bytes;
+tbuf += bytes;
+}
+return done;
+}
+
+#define vfio_mig_read(f, v, c, o)   vfio_mig_rw(f, (__u8 *)v, c, o, false)
+#define vfio_mig_write(f, v, c, o)  vfio_mig_rw(f, (__u8 *)v, c, o, true)
  
  static void vfio_migration_region_exit(VFIODevice *vbasedev)

  {
@@ -70,6 +123,82 @@ err:
  return ret;
  }
  
+static int vfio_migration_set_state(VFIODevice *vbasedev, uint32_t mask,

+uint32_t value)
+{
+VFIOMigration *migration = vbasedev->migration;
+VFIORegion *region = >region;
+off_t dev_state_off = region->fd_offset +
+  offsetof(struct vfio_device_migration_info, 
device_state);
+uint32_t device_state;
+int ret;
+
+ret = vfio_mig_read(vbasedev, _state, sizeof(device_state),
+dev_state_off);
+if (ret < 0) {
+return ret;
+}
+
+device_state = (device_state & mask) | value;


Agree with Connie that mask and value args are not immediately obvious
how they're used.  I don't have a naming convention that would be more
clear and the names do make some sense once they're understood, but a
comment to indicate mask bits are preserved, value bits are set,
remaining bits are cleared would probably help the reader.



Added comment.


+
+if (!VFIO_DEVICE_STATE_VALID(device_state)) {
+return -EINVAL;
+}
+
+ret = vfio_mig_write(vbasedev, _state, sizeof(device_state),
+ dev_state_off);
+if (ret < 0) {
+ret = vfio_mig_read(vbasedev, _state, sizeof(device_state),
+  dev_state_off);
+if (ret < 0) {
+return ret;


Seems like we're in pretty bad shape here, should this be combined with
below to trigger a hw_error?



Ok.


+}
+
+if (VFIO_DEVICE_STATE_IS_ERROR(device_state)) {
+hw_error("%s: Device is in error state 0x%x",
+ vbasedev->name, device_state);
+return -EFAULT;
+}
+}
+
+vbasedev->device_state = device_state;
+trace_vfio_migration_set_state(vbasedev->name, device_state);
+return 0;


So we return success even if we failed to write the desired state as
long as we were able to read back any non-error state?
vbasedev->device_state remains correct, but it seems confusing form a
caller perspective that a set-state can succeed but it's then necessary
to check the state.



Correcting here. If 

Re: [PATCH v26 05/17] vfio: Add VM state change handler to know state of VM

2020-10-17 Thread Kirti Wankhede




On 9/29/2020 4:33 PM, Dr. David Alan Gilbert wrote:

* Cornelia Huck (coh...@redhat.com) wrote:

On Wed, 23 Sep 2020 04:54:07 +0530
Kirti Wankhede  wrote:


VM state change handler gets called on change in VM's state. This is used to set
VFIO device state to _RUNNING.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
Reviewed-by: Dr. David Alan Gilbert 
---
  hw/vfio/migration.c   | 136 ++
  hw/vfio/trace-events  |   3 +-
  include/hw/vfio/vfio-common.h |   4 ++
  3 files changed, 142 insertions(+), 1 deletion(-)



(...)


+static int vfio_migration_set_state(VFIODevice *vbasedev, uint32_t mask,
+uint32_t value)


I think I've mentioned that before, but this function could really
benefit from a comment what mask and value mean.



Adding a comment as:

/*
 *  Write device_state field to inform the vendor driver about the 
device state

 *  to be transitioned to.
 *  vbasedev: VFIO device
 *  mask : bits set in the mask are preserved in device_state
 *  value: bits set in the value are set in device_state
 *  Remaining bits in device_state are cleared.
 */



+{
+VFIOMigration *migration = vbasedev->migration;
+VFIORegion *region = >region;
+off_t dev_state_off = region->fd_offset +
+  offsetof(struct vfio_device_migration_info, 
device_state);
+uint32_t device_state;
+int ret;
+
+ret = vfio_mig_read(vbasedev, _state, sizeof(device_state),
+dev_state_off);
+if (ret < 0) {
+return ret;
+}
+
+device_state = (device_state & mask) | value;
+
+if (!VFIO_DEVICE_STATE_VALID(device_state)) {
+return -EINVAL;
+}
+
+ret = vfio_mig_write(vbasedev, _state, sizeof(device_state),
+ dev_state_off);
+if (ret < 0) {
+ret = vfio_mig_read(vbasedev, _state, sizeof(device_state),
+  dev_state_off);
+if (ret < 0) {
+return ret;
+}
+
+if (VFIO_DEVICE_STATE_IS_ERROR(device_state)) {
+hw_error("%s: Device is in error state 0x%x",
+ vbasedev->name, device_state);
+return -EFAULT;


Is -EFAULT a good return value here? Maybe -EIO?



Ok. Changing to -EIO.


+}
+}
+
+vbasedev->device_state = device_state;
+trace_vfio_migration_set_state(vbasedev->name, device_state);
+return 0;
+}
+
+static void vfio_vmstate_change(void *opaque, int running, RunState state)
+{
+VFIODevice *vbasedev = opaque;
+
+if ((vbasedev->vm_running != running)) {
+int ret;
+uint32_t value = 0, mask = 0;
+
+if (running) {
+value = VFIO_DEVICE_STATE_RUNNING;
+if (vbasedev->device_state & VFIO_DEVICE_STATE_RESUMING) {
+mask = ~VFIO_DEVICE_STATE_RESUMING;


I've been staring at this for some time and I think that the desired
result is
- set _RUNNING
- if _RESUMING was set, clear it, but leave the other bits intact


Upto here, you're correct.


- if _RESUMING was not set, clear everything previously set
This would really benefit from a comment (or am I the only one
struggling here?)



Here mask should be ~0. Correcting it.



+}
+} else {
+mask = ~VFIO_DEVICE_STATE_RUNNING;
+}
+
+ret = vfio_migration_set_state(vbasedev, mask, value);
+if (ret) {
+/*
+ * vm_state_notify() doesn't support reporting failure. If such
+ * error reporting support added in furure, migration should be
+ * aborted.



"We should abort the migration in this case, but vm_state_notify()
currently does not support reporting failures."

?



Ok. Updating comment as suggested here.


Can/should we mark the failing device in some way?


I think you can call qemu_file_set_error on the migration stream to
force an error.



It should be as below, right?
qemu_file_set_error(migrate_get_current()->to_dst_file, ret);


Thanks,
Kirti


Dave


+ */
+error_report("%s: Failed to set device state 0x%x",
+ vbasedev->name, value & mask);
+}
+vbasedev->vm_running = running;
+trace_vfio_vmstate_change(vbasedev->name, running, RunState_str(state),
+  value & mask);
+}
+}
+
  static int vfio_migration_init(VFIODevice *vbasedev,
 struct vfio_region_info *info)
  {


(...)




Re: [PATCH v26 04/17] vfio: Add migration region initialization and finalize function

2020-10-17 Thread Kirti Wankhede




On 9/26/2020 1:50 AM, Alex Williamson wrote:

On Wed, 23 Sep 2020 04:54:06 +0530
Kirti Wankhede  wrote:


Whether the VFIO device supports migration or not is decided based of
migration region query. If migration region query is successful and migration
region initialization is successful then migration is supported else
migration is blocked.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
Acked-by: Dr. David Alan Gilbert 
---
  hw/vfio/meson.build   |   1 +
  hw/vfio/migration.c   | 142 ++
  hw/vfio/trace-events  |   5 ++
  include/hw/vfio/vfio-common.h |   9 +++
  4 files changed, 157 insertions(+)
  create mode 100644 hw/vfio/migration.c

diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
index 37efa74018bc..da9af297a0c5 100644
--- a/hw/vfio/meson.build
+++ b/hw/vfio/meson.build
@@ -2,6 +2,7 @@ vfio_ss = ss.source_set()
  vfio_ss.add(files(
'common.c',
'spapr.c',
+  'migration.c',
  ))
  vfio_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
'display.c',
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
new file mode 100644
index ..2f760f1f9c47
--- /dev/null
+++ b/hw/vfio/migration.c
@@ -0,0 +1,142 @@
+/*
+ * Migration support for VFIO devices
+ *
+ * Copyright NVIDIA, Inc. 2020
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include 
+
+#include "hw/vfio/vfio-common.h"
+#include "cpu.h"
+#include "migration/migration.h"
+#include "migration/qemu-file.h"
+#include "migration/register.h"
+#include "migration/blocker.h"
+#include "migration/misc.h"
+#include "qapi/error.h"
+#include "exec/ramlist.h"
+#include "exec/ram_addr.h"
+#include "pci.h"
+#include "trace.h"
+
+static void vfio_migration_region_exit(VFIODevice *vbasedev)
+{
+VFIOMigration *migration = vbasedev->migration;
+
+if (!migration) {
+return;
+}
+
+if (migration->region.size) {
+vfio_region_exit(>region);
+vfio_region_finalize(>region);
+}
+}
+
+static int vfio_migration_region_init(VFIODevice *vbasedev, int index)
+{
+VFIOMigration *migration = vbasedev->migration;
+Object *obj = NULL;


Unnecessary initialization.


+int ret = -EINVAL;


return -EINVAL below, this doesn't need to be initialized, use it for
storing actual return values.


+
+obj = vbasedev->ops->vfio_get_object(vbasedev);
+if (!obj) {
+return ret;
+}


vfio_migration_init() tests whether the vbasedev->ops supports
vfio_get_object, then calls this, then calls vfio_get_object itself
(added in a later patch, with a strange inconsistency in failure modes).
Wouldn't it make more sense for vfio_migration_init() to pass the
Object since that function also needs it (eventually) and actually does
the existence test?


+
+ret = vfio_region_setup(obj, vbasedev, >region, index,
+"migration");
+if (ret) {
+error_report("%s: Failed to setup VFIO migration region %d: %s",
+ vbasedev->name, index, strerror(-ret));
+goto err;
+}
+
+if (!migration->region.size) {
+ret = -EINVAL;
+error_report("%s: Invalid region size of VFIO migration region %d: %s",
+ vbasedev->name, index, strerror(-ret));
+goto err;
+}


If the caller were to pass obj, this is nothing more than a wrapper for
calling vfio_region_setup(), which suggests to me we might not even
need this as a separate function outside of vfio_migration_init().



Removed vfio_migration_region_init(), moving vfio_region_setup() to
vfio_migration_init()

Thanks,
Kirti


+
+return 0;
+
+err:
+vfio_migration_region_exit(vbasedev);
+return ret;
+}
+
+static int vfio_migration_init(VFIODevice *vbasedev,
+   struct vfio_region_info *info)
+{
+int ret = -EINVAL;
+
+if (!vbasedev->ops->vfio_get_object) {
+return ret;
+}
+
+vbasedev->migration = g_new0(VFIOMigration, 1);
+
+ret = vfio_migration_region_init(vbasedev, info->index);
+if (ret) {
+error_report("%s: Failed to initialise migration region",
+ vbasedev->name);
+g_free(vbasedev->migration);
+vbasedev->migration = NULL;
+}
+
+return ret;
+}
+
+/* -- */
+
+int vfio_migration_probe(VFIODevice *vbasedev, Error **errp)
+{
+struct vfio_region_info *info = NULL;


Not sure this initialization is strictly necessary either, but it also
seems to be a common convention for this function, so either way.

Connie, does vfio_ccw_get_region() leak this?  It appears to call
vfio_get_dev_region_info() and vfio_get_region_info() several times with
the same pointer without freeing it between uses.

Thanks,
Alex


+Error *local_err = NULL;
+int ret;
+
+ret = vfio_get_dev_region_info(vbasedev, 

Re: [PATCH v26 04/17] vfio: Add migration region initialization and finalize function

2020-10-17 Thread Kirti Wankhede




On 9/24/2020 7:38 PM, Cornelia Huck wrote:

On Wed, 23 Sep 2020 04:54:06 +0530
Kirti Wankhede  wrote:


Whether the VFIO device supports migration or not is decided based of
migration region query. If migration region query is successful and migration
region initialization is successful then migration is supported else
migration is blocked.

Signed-off-by: Kirti Wankhede 
Reviewed-by: Neo Jia 
Acked-by: Dr. David Alan Gilbert 
---
  hw/vfio/meson.build   |   1 +
  hw/vfio/migration.c   | 142 ++
  hw/vfio/trace-events  |   5 ++
  include/hw/vfio/vfio-common.h |   9 +++
  4 files changed, 157 insertions(+)
  create mode 100644 hw/vfio/migration.c


(...)


+static int vfio_migration_region_init(VFIODevice *vbasedev, int index)
+{
+VFIOMigration *migration = vbasedev->migration;
+Object *obj = NULL;
+int ret = -EINVAL;
+
+obj = vbasedev->ops->vfio_get_object(vbasedev);
+if (!obj) {
+return ret;
+}
+
+ret = vfio_region_setup(obj, vbasedev, >region, index,
+"migration");
+if (ret) {
+error_report("%s: Failed to setup VFIO migration region %d: %s",
+ vbasedev->name, index, strerror(-ret));
+goto err;
+}
+
+if (!migration->region.size) {
+ret = -EINVAL;
+error_report("%s: Invalid region size of VFIO migration region %d: %s",
+ vbasedev->name, index, strerror(-ret));


Using strerror on a hardcoded error value is probably not terribly
helpful. I think printing either region.size (if you plan to extend
this check later) or something like "Invalid zero-sized VFIO migration
region" would make more sense.



Updating the error string as you suggested.



+goto err;
+}
+
+return 0;
+
+err:
+vfio_migration_region_exit(vbasedev);
+return ret;
+}


(...)

Apart from that, looks good to me.



Thanks.

Kirti



Re: [PULL v2 00/22] Build system + misc changes for 2020-10-16

2020-10-17 Thread Peter Maydell
On Sat, 17 Oct 2020 at 17:37, Paolo Bonzini  wrote:
> Ok, so the warning remains when everything is fixed, though the text is
> slightly different (and better):
>
>   Library iconv found: NO
>   Run-time dependency ncursesw found: NO (tried pkgconfig)
>   Library ncursesw found: YES
>   Library cursesw found: NO
>   ../src/meson.build:540: WARNING: curses library not usable, disabling
>
> In this case, meson.build warns because curses doesn't always have a .pc
> file; therefore when meson.build doesn't find the headers it can't but
> proceed without curses suport.

> The "library found"/"curses support disabled" situation is a bit
> confusing, which is why I've been adding some kind of message for those
> few cases in which we cannot just use pkg-config.  (The multipath test
> is already warning, but those libraries are a bit niche so you probably
> don't even have the libraries installed).
>
> Peter, I would like your input on these two things:
>
> 1) are you going to pull v3 and I can fix up everything later?  Or would
> you prefer me to send v4 once the new curses test is reviewed?

If the only issue with v3 is that stray warning message I'm
OK with applying it and improving the test later.

> 2) would you prefer the "library was found but headers weren't" to warn,
> issue an informative message, or be completely silent?

I think the build system should just say whether it found a
working curses setup or not, and do our usual "this is fatal
if --enable-whatever, otherwise just disable feature". If we
happen to have convenient information to put in whatever
the new build system's equivalent of config.log is [ie the
saved-for-debug-purposes log], we might as well put it in,
but we don't need to put that in the stdout. (We shouldn't
say "ncurses found: YES" unless we actually found a working
version, ideally.)

thanks
-- PMM



Re: [PATCH] drivers/virt: vmgenid: add vm generation id driver

2020-10-17 Thread Alexander Graf

Hi Jason,

On 17.10.20 15:24, Jason A. Donenfeld wrote:


After discussing this offline with Jann a bit, I have a few general
comments on the design of this.

First, the UUID communicated by the hypervisor should be consumed by
the kernel -- added as another input to the rng -- and then userspace


We definitely want a kernel internal notifier as well, yes :).


should be notified that it should reseed any userspace RNGs that it
may have, without actually communicating that UUID to userspace. IOW,


I also tend to agree that it makes sense to disconnect the actual UUID 
we receive from the notification to user space. This would allow us to 
create a generic mechanism for VM save/restore cycles across different 
hypervisors. Let me add PPC and s390x people to the CC list to see 
whether they have anything remotely similar to the VmGenID mechanism. 
For x86 and aarch64, the ACPI and memory based VmGenID implemented here 
is the most obvious option to implement IMHO. It's also already 
implemented in all major hypervisors.



I agree with Jann there. Then, it's the functioning of this
notification mechanism to userspace that is interesting to me.


Absolutely! Please have a look at the previous discussion here:


https://lore.kernel.org/linux-pm/b7793b7a-3660-4769-9b9a-ffcf25072...@amazon.com/

The user space interface is absolutely what this is about.


There are a few design goals of notifying userspace: it should be
fast, because people who are using userspace RNGs are usually doing so
in the first place to completely avoid syscall overhead for whatever
high performance application they have - e.g. I recall conversations
with Colm about his TLS implementation needing to make random IVs
_really_ fast. It should also happen as early as possible, with no
race or as minimal as possible race window, so that userspace doesn't
begin using old randomness and then switch over after the damage is
already done.


There are multiple facets and different types of consumers here. For a 
user space RNG, I agree that fast and as race free as possible is key. 
That's what the mmap interface is there for.


There are applications way beyond that though. What do you do with 
applications that already consumed randomness? For example a cached pool 
of SSL keys. Or a higher level language primitive that consumes 
randomness and caches its seed somewhere in an internal data structure. 
Or even worse: your system's host ssh key.


For those types of events, an mmap (or vDSO) interface does not work. We 
need to actively allow user space applications to readjust to the new 
environment - either internally (the language primitive case) or through 
a system event, maybe even as systemd trigger (the ssh host key case).


To give everyone enough time before we consider a system as "updated to 
the new environment", we have the callback logic with the "Orchestrator" 
that can check whether all listeners to system wide updates confirms 
they adjusted themselves.


That's what the rest of the logic is there for: A read+poll interface 
and all of the orchestration logic. It's not for the user space RNG 
case, it's for all of its downstream users.



I'm also not wedded to using Microsoft's proprietary hypervisor design
for this. If we come up with a better interface, I don't think it's
asking too much to implement that and reasonably expect for Microsoft
to catch up. Maybe someone here will find that controversial, but
whatever -- discussing ideal designs does not seem out of place or
inappropriate for how we usually approach things in the kernel, and a
closed source hypervisor coming along shouldn't disrupt that.


The main bonus point on this interface is that Hyper-V, VMware and QEMU 
implement it already. It would be a very natural for into the ecosystem. 
I agree though that we shouldn't have our user space interface 
necessarily dictated by it: Other hypervisors may implement different 
ways such as a simple edge IRQ that gets triggered whenever the VM gets 
resumed.



So, anyway, here are a few options with some pros and cons for the
kernel notifying userspace that its RNG should reseed.


I can only stress again that we should not be laser focused on the RNG 
case. In a lot of cases, data has already been generated by the RNG 
before the snapshot and needs to be reinitialized after the snapshot. In 
other cases such as system UUIDs, it's completely orthogonal to the RNG.




1. SIGRND - a new signal. Lol.


Doable, but a lot of plumbing in user space. It's also not necessarily a 
good for for event notification in most user space applications.




2. Userspace opens a file descriptor that it can epoll on. Pros are
that many notification mechanisms already use this. Cons is that this
requires syscall and might be more racy than we want. Another con is
that this a new thing for userspace programs to do.


That's part of what this patch does, right? This patch implements 
read+poll as well as mmap() for high speed reads.



3. We 

Re: [PATCH v2 0/6] hw/sd/sdcard: Do not attempt to erase out of range addresses

2020-10-17 Thread Alexander Bulekov
On 201015 0838, Philippe Mathieu-Daudé wrote:
> Yet another bug in the sdcard model found by libfuzzer:
> https://bugs.launchpad.net/bugs/1895310
> 
> Since RFC: Settled migration issue
> 
> Philippe Mathieu-Daudé (6):
>   hw/sd/sdcard: Add trace event for ERASE command (CMD38)
>   hw/sd/sdcard: Introduce the INVALID_ADDRESS definition
>   hw/sd/sdcard: Do not use legal address '0' for INVALID_ADDRESS
>   hw/sd/sdcard: Reset both start/end addresses on error
>   hw/sd/sdcard: Do not attempt to erase out of range addresses
>   hw/sd/sdcard: Assert if accessing an illegal group
> 
>  hw/sd/sd.c | 30 ++
>  hw/sd/trace-events |  2 +-
>  2 files changed, 23 insertions(+), 9 deletions(-)
> 
> -- 
> 2.26.2
> 

Hi Phil,
For this series:
Tested-by: Alexander Bulekov 

Thanks
-Alex



Re: [PATCH] drivers/virt: vmgenid: add vm generation id driver

2020-10-17 Thread Andy Lutomirski
On Fri, Oct 16, 2020 at 6:40 PM Jann Horn  wrote:
>
> [adding some more people who are interested in RNG stuff: Andy, Jason,
> Theodore, Willy Tarreau, Eric Biggers. also linux-api@, because this
> concerns some pretty fundamental API stuff related to RNG usage]
>
> On Fri, Oct 16, 2020 at 4:33 PM Catangiu, Adrian Costin
>  wrote:
> > - Background
> >
> > The VM Generation ID is a feature defined by Microsoft (paper:
> > http://go.microsoft.com/fwlink/?LinkId=260709) and supported by
> > multiple hypervisor vendors.
> >
> > The feature is required in virtualized environments by apps that work
> > with local copies/caches of world-unique data such as random values,
> > uuids, monotonically increasing counters, etc.
> > Such apps can be negatively affected by VM snapshotting when the VM
> > is either cloned or returned to an earlier point in time.
> >
> > The VM Generation ID is a simple concept meant to alleviate the issue
> > by providing a unique ID that changes each time the VM is restored
> > from a snapshot. The hw provided UUID value can be used to
> > differentiate between VMs or different generations of the same VM.
> >
> > - Problem
> >
> > The VM Generation ID is exposed through an ACPI device by multiple
> > hypervisor vendors but neither the vendors or upstream Linux have no
> > default driver for it leaving users to fend for themselves.
> >
> > Furthermore, simply finding out about a VM generation change is only
> > the starting point of a process to renew internal states of possibly
> > multiple applications across the system. This process could benefit
> > from a driver that provides an interface through which orchestration
> > can be easily done.
> >
> > - Solution
> >
> > This patch is a driver which exposes the Virtual Machine Generation ID
> > via a char-dev FS interface that provides ID update sync and async
> > notification, retrieval and confirmation mechanisms:
> >
> > When the device is 'open()'ed a copy of the current vm UUID is
> > associated with the file handle. 'read()' operations block until the
> > associated UUID is no longer up to date - until HW vm gen id changes -
> > at which point the new UUID is provided/returned. Nonblocking 'read()'
> > uses EWOULDBLOCK to signal that there is no _new_ UUID available.
> >
> > 'poll()' is implemented to allow polling for UUID updates. Such
> > updates result in 'EPOLLIN' events.
> >
> > Subsequent read()s following a UUID update no longer block, but return
> > the updated UUID. The application needs to acknowledge the UUID update
> > by confirming it through a 'write()'.
> > Only on writing back to the driver the right/latest UUID, will the
> > driver mark this "watcher" as up to date and remove EPOLLIN status.
> >
> > 'mmap()' support allows mapping a single read-only shared page which
> > will always contain the latest UUID value at offset 0.
>
> It would be nicer if that page just contained an incrementing counter,
> instead of a UUID. It's not like the application cares *what* the UUID
> changed to, just that it *did* change and all RNGs state now needs to
> be reseeded from the kernel, right? And an application can't reliably
> read the entire UUID from the memory mapping anyway, because the VM
> might be forked in the middle.
>
> So I think your kernel driver should detect UUID changes and then turn
> those into a monotonically incrementing counter. (Probably 64 bits
> wide?) (That's probably also a little bit faster than comparing an
> entire UUID.)
>
> An option might be to put that counter into the vDSO, instead of a
> separate VMA; but I don't know how the other folks feel about that.
> Andy, do you have opinions on this? That way, normal userspace code
> that uses this infrastructure wouldn't have to mess around with a
> special device at all. And it'd be usable in seccomp sandboxes and so
> on without needing special plumbing. And libraries wouldn't have to
> call open() and mess with file descriptor numbers.

The vDSO might be annoyingly slow for this.  Something like the rseq
page might make sense.  It could be a generic indication of "system
went through some form of suspend".



[PATCH 2/2] hw/intc/bcm2836_control: Use IRQ definitions instead of magic numbers

2020-10-17 Thread Philippe Mathieu-Daudé
The IRQ values are defined few lines earlier, use them instead of
the magic numbers.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/intc/bcm2836_control.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/intc/bcm2836_control.c b/hw/intc/bcm2836_control.c
index 53dba0080ca..2ead76ffdce 100644
--- a/hw/intc/bcm2836_control.c
+++ b/hw/intc/bcm2836_control.c
@@ -157,22 +157,22 @@ static void bcm2836_control_set_local_irq(void *opaque, 
int core, int local_irq,
 
 static void bcm2836_control_set_local_irq0(void *opaque, int core, int level)
 {
-bcm2836_control_set_local_irq(opaque, core, 0, level);
+bcm2836_control_set_local_irq(opaque, core, IRQ_CNTPSIRQ, level);
 }
 
 static void bcm2836_control_set_local_irq1(void *opaque, int core, int level)
 {
-bcm2836_control_set_local_irq(opaque, core, 1, level);
+bcm2836_control_set_local_irq(opaque, core, IRQ_CNTPNSIRQ, level);
 }
 
 static void bcm2836_control_set_local_irq2(void *opaque, int core, int level)
 {
-bcm2836_control_set_local_irq(opaque, core, 2, level);
+bcm2836_control_set_local_irq(opaque, core, IRQ_CNTHPIRQ, level);
 }
 
 static void bcm2836_control_set_local_irq3(void *opaque, int core, int level)
 {
-bcm2836_control_set_local_irq(opaque, core, 3, level);
+bcm2836_control_set_local_irq(opaque, core, IRQ_CNTVIRQ, level);
 }
 
 static void bcm2836_control_set_gpu_irq(void *opaque, int irq, int level)
-- 
2.26.2




Re: [PATCH] drivers/virt: vmgenid: add vm generation id driver

2020-10-17 Thread Catangiu, Adrian Costin
After discussing this offline with Jann a bit, I have a few general
comments on the design of this. 
First, the UUID communicated by the hypervisor should be consumed by
the kernel -- added as another input to the rng -- and then userspace
should be notified that it should reseed any userspace RNGs that it
may have, without actually communicating that UUID to userspace. IOW,
I agree with Jann there. Then, it's the functioning of this
notification mechanism to userspace that is interesting to me.

Agreed! The UUID/vmgenid is the glue to the hypervisor to be able to find 
out about VM snapshots/forks. The really interesting (and important) topic
here is finding the right notification mechanism to userspace.

...In retrospect, I should have posted this as RFC instead of PATCH.

So, anyway, here are a few options with some pros and cons for the
kernel notifying userspace that its RNG should reseed.
1. SIGRND - a new signal. Lol.
2. Userspace opens a file descriptor that it can epoll on. Pros are
that many notification mechanisms already use this. Cons is that this
requires syscall and might be more racy than we want. Another con is
that this a new thing for userspace programs to do.
3. We stick an atomic counter in the vDSO, Jann's suggestion. Pros are
that this is extremely fast, and also simple to use and implement.
There are enough sequence points in typical crypto programs that
checking to see whether this counter has changed before doing whatever
operation seems easy enough. Cons are that typically we've been
conservative about adding things to the vDSO, and this is also a new
thing for userspace programs to do.

For each 1, 2, and 3 options, userspace programs _have to do smth new_
anyway, so I wouldn't weigh that as a con.

An atomic counter in the vDSO looks like the most bang for the buck to me.
I'm really curious to hear more opinions on why we shouldn't do it.

4. We already have a mechanism for this kind of thing, because the
same issue comes up when fork()ing. The solution was MADV_WIPEONFORK,
where userspace marks a page to be zeroed when forking, for the
purposes of the RNG being notified when its world gets split in two.
This is basically the same thing as we're discussing here with guest
snapshots, except it's on the system level rather than the process
level, and a system has many processes. But the problem space is still
almost the same, and we could simply reuse that same mechanism. There
are a few implementation strategies for that:

I don't think we can piggy back on MADV_WIPEONFORK. That madvise flag
has a clear contract of only wiping _on fork_. Overloading it with wiping
on VM-fork - while process doesn't fork - might break some of its users.

4a. We mess with the PTEs of all processes' pages that are
MADV_WIPEONFORK, like fork does now, when the hypervisor notifies us
to do so. Then we wind up reusing the already existing logic for
userspace RNGs. Cons might be that this usually requires semaphores,
and we're in irq context, so we'd have to hoist to a workqueue, which
means either more wake up latency, or a larger race window.
4b. We just memzero all processes' pages that are MADV_WIPEONFORK,
when the hypervisor notifies us to do so. Then we wind up reusing the
already existing logic for userspace RNGs.
4c. The guest kernel maintains an array of physical addresses that are
MADV_WIPEONFORK. The hypervisor knows about this array and its
location through whatever protocol, and before resuming a
moved/snapshotted/duplicated VM, it takes the responsibility for
memzeroing this memory. The huge pro here would be that this
eliminates all races, and reduces complexity quite a bit, because the
hypervisor can perfectly synchronize its bringup (and SMP bringup)
with this, and it can even optimize things like on-disk memory
snapshots to simply not write out those pages to disk.

I've previously proposed a path similar (in concept at least) with a combination
of 4 a,b and c - 
https://lwn.net/ml/linux-mm/b7793b7a-3660-4769-9b9a-ffcf25072...@amazon.com/
without reusing MADV_WIPEONFORK, but by adding a dedicated
MADV_WIPEONSUSPEND.

That proposal was clunky however with many people raising concerns around
how the interface is too subtle and hard to work with.

A vmgenid driver offering a clean FS interface seemed cleaner, although, like
some of you observed, it still allows a window of time between actual VM fork
and userspace handling of the event.

One other direction that I would like to explore and I feel it’s similar to 
your 4c
proposal is to do smth like:
"mm: extend memfd with ability to create 'secret' memory"
https://patchwork.kernel.org/project/linux-mm/patch/20200130162340.GA14232@rapoport-lnx/

Maybe we can combine ideas from the two patches in smth like: instead of libs
using anon 

[PATCH 0/2] hw/intc/bcm283x: Trivial tracing cleanup

2020-10-17 Thread Philippe Mathieu-Daudé
Add trace event for IRQ from CPU/GPU,
use definitions for IRQ numbers.

Philippe Mathieu-Daudé (2):
  hw/intc/bcm2835_ic: Trace GPU/CPU IRQ handlers
  hw/intc/bcm2836_control: Use IRQ definitions instead of magic numbers

 hw/intc/bcm2835_ic.c  | 4 +++-
 hw/intc/bcm2836_control.c | 8 
 hw/intc/trace-events  | 4 
 3 files changed, 11 insertions(+), 5 deletions(-)

-- 
2.26.2




[PATCH 1/2] hw/intc/bcm2835_ic: Trace GPU/CPU IRQ handlers

2020-10-17 Thread Philippe Mathieu-Daudé
Add trace events for GPU and CPU IRQs.

Reviewed-by: Luc Michel 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/intc/bcm2835_ic.c | 4 +++-
 hw/intc/trace-events | 4 
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/intc/bcm2835_ic.c b/hw/intc/bcm2835_ic.c
index 53ab8f58810..9000d995e81 100644
--- a/hw/intc/bcm2835_ic.c
+++ b/hw/intc/bcm2835_ic.c
@@ -18,6 +18,7 @@
 #include "migration/vmstate.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
+#include "trace.h"
 
 #define GPU_IRQS 64
 #define ARM_IRQS 8
@@ -51,7 +52,6 @@ static void bcm2835_ic_update(BCM2835ICState *s)
 set = (s->gpu_irq_level & s->gpu_irq_enable)
 || (s->arm_irq_level & s->arm_irq_enable);
 qemu_set_irq(s->irq, set);
-
 }
 
 static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level)
@@ -59,6 +59,7 @@ static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int 
level)
 BCM2835ICState *s = opaque;
 
 assert(irq >= 0 && irq < 64);
+trace_bcm2835_ic_set_gpu_irq(irq, level);
 s->gpu_irq_level = deposit64(s->gpu_irq_level, irq, 1, level != 0);
 bcm2835_ic_update(s);
 }
@@ -68,6 +69,7 @@ static void bcm2835_ic_set_arm_irq(void *opaque, int irq, int 
level)
 BCM2835ICState *s = opaque;
 
 assert(irq >= 0 && irq < 8);
+trace_bcm2835_ic_set_cpu_irq(irq, level);
 s->arm_irq_level = deposit32(s->arm_irq_level, irq, 1, level != 0);
 bcm2835_ic_update(s);
 }
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 527c3f76cae..22782b3f089 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -199,3 +199,7 @@ nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned 
size) "NVIC sysreg wri
 heathrow_write(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 
0x%"PRIx64
 heathrow_read(uint64_t addr, unsigned int n, uint64_t value) "0x%"PRIx64" %u: 
0x%"PRIx64
 heathrow_set_irq(int num, int level) "set_irq: num=0x%02x level=%d"
+
+# bcm2835_ic.c
+bcm2835_ic_set_gpu_irq(int irq, int level) "GPU irq #%d level %d"
+bcm2835_ic_set_cpu_irq(int irq, int level) "CPU irq #%d level %d"
-- 
2.26.2




[Bug 1874504] Re: VFIO passthrough spits out thousands of messages

2020-10-17 Thread Artyom Tarasenko
Is this a regression? Can you please bisect to the first commit where it
happened?

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

Title:
  VFIO passthrough spits out thousands of messages

Status in QEMU:
  New

Bug description:
  started qemu as:
  sudo qemu-system-sparc64 -device vfio-pci,host=0b:05.0,x-no-mmap=on,bus=pciB

  messages received thousands of times:

  qemu-system-sparc64: -device vfio-pci,host=0b:05.0,x-no-mmap=on,bus=pciB: 
iommu has granularity incompatible with target AS
  qemu-system-sparc64: -device vfio-pci,host=0b:05.0,x-no-mmap=on,bus=pciB: 
iommu map to non memory area 4079c000

  qemu version (think telling a lie as sure its 5.0)
  QEMU emulator version 4.2.92
  Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers

  pci device being passed through:

  0b:05.0 Display controller [0380]: 3DLabs Permedia II 2D+3D [3d3d:0009] (rev 
01)
Subsystem: Tech-Source Permedia II 2D+3D [1227:0006]
Flags: medium devsel, IRQ 11
Memory at 8300 (32-bit, non-prefetchable) [disabled] [size=128K]
Memory at 8280 (32-bit, non-prefetchable) [disabled] [size=8M]
Memory at 8200 (32-bit, non-prefetchable) [disabled] [size=8M]
Expansion ROM at 8302 [disabled] [size=64K]
Capabilities: 
Kernel driver in use: vfio-pci

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



Re: [PULL 25/33] tests/acceptance: Add a test for the N800 and N810 arm machines

2020-10-17 Thread Philippe Mathieu-Daudé

Hi Peter, Igor, Thomas,

On 2/28/20 5:38 PM, Peter Maydell wrote:

From: Thomas Huth 

Old kernels from the Meego project can be used to check that Linux
is at least starting on these machines.

Signed-off-by: Thomas Huth 
Reviewed-by: Wainer dos Santos Moschetta 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Philippe Mathieu-Daudé 
Message-id: 20200225172501.29609-2-phi...@redhat.com
Message-Id: <20200129131920.22302-1-th...@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Peter Maydell 
---
  MAINTAINERS  |  1 +
  tests/acceptance/machine_arm_n8x0.py | 49 
  2 files changed, 50 insertions(+)
  create mode 100644 tests/acceptance/machine_arm_n8x0.py

diff --git a/MAINTAINERS b/MAINTAINERS
index b66c46dcb9f..264374adbe8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -686,6 +686,7 @@ F: hw/rtc/twl92230.c
  F: include/hw/display/blizzard.h
  F: include/hw/input/tsc2xxx.h
  F: include/hw/misc/cbus.h
+F: tests/acceptance/machine_arm_n8x0.py
  
  Palm

  M: Andrzej Zaborowski 
diff --git a/tests/acceptance/machine_arm_n8x0.py 
b/tests/acceptance/machine_arm_n8x0.py
new file mode 100644
index 000..e5741f2d8d1
--- /dev/null
+++ b/tests/acceptance/machine_arm_n8x0.py
@@ -0,0 +1,49 @@
+# Functional test that boots a Linux kernel and checks the console
+#
+# Copyright (c) 2020 Red Hat, Inc.
+#
+# Author:
+#  Thomas Huth 
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+import os
+
+from avocado import skipUnless
+from avocado_qemu import Test
+from avocado_qemu import wait_for_console_pattern
+
+class N8x0Machine(Test):
+"""Boots the Linux kernel and checks that the console is operational"""
+
+timeout = 90
+
+def __do_test_n8x0(self):
+kernel_url = ('http://stskeeps.subnetmask.net/meego-n8x0/'
+  'meego-arm-n8x0-1.0.80.20100712.1431-'
+  'vmlinuz-2.6.35~rc4-129.1-n8x0')
+kernel_hash = 'e9d5ab8d7548923a0061b6fbf601465e479ed269'
+kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
+
+self.vm.set_console(console_index=1)
+self.vm.add_args('-kernel', kernel_path,
+ '-append', 'printk.time=0 console=ttyS1')
+self.vm.launch()
+wait_for_console_pattern(self, 'TSC2005 driver initializing')
+
+@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
+def test_n800(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:n800
+"""
+self.__do_test_n8x0()
+
+@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
+def test_n810(self):
+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:n810
+"""
+self.__do_test_n8x0()



FYI this test is failing:

qemu-system-arm: kernel 'meego-arm-n8x0-1.0.80.20100712.1431-vml
inuz-2.6.35~rc4-129.1-n8x0' is too large to fit in RAM (kernel size 
1964608, RAM size 0)


Alex, Thomas, can we enable AVOCADO_ALLOW_UNTRUSTED_CODE on GitLab
to avoid such regressions?

Regards,

Phil.



Re: [PATCH v8 0/5] Mac Old World ROM experiment (ppc/mac_* clean ups and loading binary ROM)

2020-10-17 Thread Philippe Mathieu-Daudé

On 10/17/20 6:39 PM, BALATON Zoltan via wrote:

On Fri, 16 Oct 2020, Philippe Mathieu-Daudé wrote:

On 10/16/20 11:58 AM, Mark Cave-Ayland wrote:

On 16/10/2020 00:47, BALATON Zoltan via wrote:


This is the cut down version of the earlier series omitting unfinished
patches that I plan to rework later and rebased to Mark's qemu-macppc
branch. Compared to v7 the only change is the cast to (target_ulong)
from (uint32_t) as requested by Mark in patch 1.


FWIW the reason for suggesting the cast to target_ulong is so that 
the same code works for both qemu-system-ppc and qemu-system-ppc64. 
For qemu-system-ppc that should correctly drop the sign extension 
from 32-bit, whilst still allowing someone to load a 64-bit ELF into 
qemu-system-ppc64 if requested.


IMO this is part of a bigger design problem. Not all
machines main bus is 64-bit. I did some experiments
but changing that involves a lot of work.


Did not want to reply to this to not bring it to your attention before 
patch gets in finally but it's too late...


Not sure what you refer to


I refer to having machines with a N-bit main bus using a N-bit main bus
(currently all main busses are 64-bit wide).

Some 32-bit machines have access to 64-bit busses, some don't.

I have been wondering about it because of the AVR CPU which
uses a pair of busses, each less than 32-bit.

If one day I can finish my work there, the Old World mac might
benefit from it.

but in this particular case the problem only 
seems to be load_elf loading 32 bit ELF files returning sign extended 64 
bit address which looks bogus but since this function is widely used I 
did not feel confident enough to propose a patch to load_elf.


By the way, also the parameters of load_elf could take a clean up to 
remove all the mostly NULL values as I've pointed out before:


https://lists.nongnu.org/archive/html/qemu-devel/2019-01/msg03427.html

but all this could wait until later, these don't seem to be urgent 
problems to prevent moving mac machines forward now and could all be 
addressen in separate elf loading series. So just note the problem and 
move on for now please.


Reagards.
BALATON Zoltan




Re: [PATCH v9] mac_oldworld: Allow loading binary ROM image

2020-10-17 Thread Philippe Mathieu-Daudé

On 10/17/20 6:31 PM, BALATON Zoltan via wrote:

On Sat, 17 Oct 2020, Philippe Mathieu-Daudé wrote:

+Alistair for loader

On 10/17/20 5:47 PM, BALATON Zoltan via wrote:

The beige G3 Power Macintosh has a 4MB firmware ROM. Fix the size of
the rom region and fall back to loading a binary image with -bios if
loading ELF image failed. This allows testing emulation with a ROM
image from real hardware as well as using an ELF OpenBIOS image.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Mark Cave-Ayland 
---
v9: Revert change from v8, back to the same as v7 rebased on latest

  hw/ppc/mac_oldworld.c | 29 -
  1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 05e46ee6fe..0117ae17f5 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -59,6 +59,8 @@
  #define NDRV_VGA_FILENAME "qemu_vga.ndrv"
    #define GRACKLE_BASE 0xfec0
+#define PROM_BASE 0xffc0
+#define PROM_SIZE (4 * MiB)
    static void fw_cfg_boot_set(void *opaque, const char *boot_device,
  Error **errp)
@@ -100,6 +102,7 @@ static void ppc_heathrow_init(MachineState *machine)
  SysBusDevice *s;
  DeviceState *dev, *pic_dev;
  BusState *adb_bus;
+    uint64_t bios_addr;
  int bios_size;
  unsigned int smp_cpus = machine->smp.cpus;
  uint16_t ppc_boot_device;
@@ -128,24 +131,32 @@ static void ppc_heathrow_init(MachineState 
*machine)

    memory_region_add_subregion(sysmem, 0, machine->ram);
  -    /* allocate and load BIOS */
-    memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE,
+    /* allocate and load firmware ROM */
+    memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", PROM_SIZE,
 _fatal);
+    memory_region_add_subregion(sysmem, PROM_BASE, bios);
  -    if (bios_name == NULL)
+    if (!bios_name) {
  bios_name = PROM_FILENAME;
+    }
  filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-    memory_region_add_subregion(sysmem, PROM_ADDR, bios);
-
-    /* Load OpenBIOS (ELF) */
  if (filename) {
-    bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, 
NULL, NULL,

- 1, PPC_ELF_MACHINE, 0, 0);
+    /* Load OpenBIOS (ELF) */
+    bios_size = load_elf(filename, NULL, NULL, NULL, NULL, 
_addr,

+ NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
+    /* Unfortunately, load_elf sign-extends reading elf32 */


Maybe this is what translate_fn() is for?

uint64_t oldworld_phys(void *opaque, uint64_t addr)
{
   return addr & UINT32_MAX;
}

Using as (untested):

   bios_size = load_elf(filename, NULL, oldworld_phys, NULL,
    NULL, _addr, NULL,
    NULL, 1, PPC_ELF_MACHINE, 0, 0);


Please don't come up with any more great ideas for this patch unless you 
also propose a replacement and test it. This one works and we could just 
get this in as it is until the real problem with load_elf is fixed at 
which point all this can be removed so no need to be more sophisticated 
as the simple cast I have.


Zoltan, I'm not trying to block your patch to get merged,
I'm asking because I'm trying to understand how this API
is expected to be used.


As you can see in the original discussion:

http://patchwork.ozlabs.org/project/qemu-devel/patch/c69a791c7cad1246f3f34b3993dee4f549b75aa2.1593456926.git.bala...@eik.bme.hu/ 



problem is really in include/hw/elf_ops.h this is just a work around for 
that as I did not want to break anything I can't test so I'd rather fix 
it up here and let you fix load_elf then drop this cast. But unless you 
can do that before the freeze please don't hold up this patch any more.


Regards,
BALATON Zoltan


+    bios_addr = (uint32_t)bios_addr;
+
+    if (bios_size <= 0) {
+    /* or load binary ROM image */
+    bios_size = load_image_targphys(filename, PROM_BASE, 
PROM_SIZE);

+    bios_addr = PROM_BASE;
+    }
  g_free(filename);
  } else {
  bios_size = -1;
  }
-    if (bios_size < 0 || bios_size > BIOS_SIZE) {
+    if (bios_size < 0 || bios_addr - PROM_BASE + bios_size > 
PROM_SIZE) {

  error_report("could not load PowerPC bios '%s'", bios_name);
  exit(1);
  }









Re: [PATCH v11] scripts: Convert qemu-version.sh to qemu-version.py

2020-10-17 Thread Paolo Bonzini
Il sab 17 ott 2020, 18:43 Yonggang Luo  ha scritto:

> The sh script are harder to maintain for compatible different
> xsh environment so convert it to python script
> Also incorporate the fixes in
>
> https://patchew.org/QEMU/20200929143654.518157-1-marcandre.lur...@redhat.com/
>
> According to https://github.com/msys2/MSYS2-packages/issues/2176
> We need use CYGWIN=noglob and MSYS=noglob in the environment variable
> for disable wildcard expanding in msys or cygwin git, and setting the
> shell=False
>

Honestly, I don't see the point in doing this change. Python is the wrong
tool for this job, and it's not like the configure script is disappearing
any time soon---so getting rid of shell scripts at this point is of limited
utility, especially for something like qemu-version.sh.

IMO the msys build is already much more robust in 5.2 than in 5.1 once the
pending pull request for ninja is in). Any other change has to provide a
clear improvement.

Paolo


> Signed-off-by: Yonggang Luo 
> Message-Id: <20201006112139.700-1-luoyongg...@gmail.com>
> Signed-off-by: Paolo Bonzini 
> ---
>  meson.build |  2 +-
>  scripts/qemu-version.py | 37 +
>  scripts/qemu-version.sh | 25 -
>  3 files changed, 38 insertions(+), 26 deletions(-)
>  create mode 100644 scripts/qemu-version.py
>  delete mode 100755 scripts/qemu-version.sh
>
> diff --git a/meson.build b/meson.build
> index 05fb59a00b..b100b6d7be 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1240,7 +1240,7 @@ tracetool = [
> '--backend=' + config_host['TRACE_BACKENDS']
>  ]
>
> -qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
> +qemu_version_cmd = [find_program('scripts/qemu-version.py'),
>  meson.current_source_dir(),
>  config_host['PKGVERSION'], meson.project_version()]
>  qemu_version = custom_target('qemu-version.h',
> diff --git a/scripts/qemu-version.py b/scripts/qemu-version.py
> new file mode 100644
> index 00..cf97b2bbb5
> --- /dev/null
> +++ b/scripts/qemu-version.py
> @@ -0,0 +1,37 @@
> +#!/usr/bin/env python3
> +
> +#
> +# Script for retrieve qemu git version information
> +#
> +# Authors:
> +#  Yonggang Luo 
> +#
> +# 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.
> +
> +import sys
> +import subprocess
> +import os
> +import os.path
> +
> +def main(_program, dir, pkgversion, version, *unused):
> +os.chdir(dir)
> +if not pkgversion and os.path.exists('.git'):
> +pc = subprocess.run(
> +['git', 'describe', '--match', 'v*', '--dirty', '--always'],
> +env=dict(os.environ, CYGWIN="noglob", MSYS='noglob'),
> +stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
> +encoding='utf8', shell=False)
> +if pc.returncode == 0:
> +pkgversion = pc.stdout.strip()
> +
> +fullversion = version
> +if pkgversion:
> +fullversion = "{} ({})".format(version, pkgversion)
> +
> +print('#define QEMU_PKGVERSION "%s"' % pkgversion)
> +print('#define QEMU_FULL_VERSION "%s"' % fullversion)
> +
> +if __name__ == "__main__":
> +main(*sys.argv)
> diff --git a/scripts/qemu-version.sh b/scripts/qemu-version.sh
> deleted file mode 100755
> index 3f6e7e6d41..00
> --- a/scripts/qemu-version.sh
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -#!/bin/sh
> -
> -set -eu
> -
> -dir="$1"
> -pkgversion="$2"
> -version="$3"
> -
> -if [ -z "$pkgversion" ]; then
> -cd "$dir"
> -if [ -e .git ]; then
> -pkgversion=$(git describe --match 'v*' --dirty) || :
> -fi
> -fi
> -
> -if [ -n "$pkgversion" ]; then
> -fullversion="$version ($pkgversion)"
> -else
> -fullversion="$version"
> -fi
> -
> -cat < -#define QEMU_PKGVERSION "$pkgversion"
> -#define QEMU_FULL_VERSION "$fullversion"
> -EOF
> --
> 2.28.0.windows.1
>
>


Re: [PATCH v11] scripts: Convert qemu-version.sh to qemu-version.py

2020-10-17 Thread Yonggang Luo
On Sun, Oct 18, 2020 at 12:43 AM Yonggang Luo  wrote:
>
> The sh script are harder to maintain for compatible different
> xsh environment so convert it to python script
> Also incorporate the fixes in
>
https://patchew.org/QEMU/20200929143654.518157-1-marcandre.lur...@redhat.com/
>
> According to https://github.com/msys2/MSYS2-packages/issues/2176
> We need use CYGWIN=noglob and MSYS=noglob in the environment variable
> for disable wildcard expanding in msys or cygwin git, and setting the
shell=False
>
> Signed-off-by: Yonggang Luo 
> Message-Id: <20201006112139.700-1-luoyongg...@gmail.com>
> Signed-off-by: Paolo Bonzini 
> ---
>  meson.build |  2 +-
>  scripts/qemu-version.py | 37 +
>  scripts/qemu-version.sh | 25 -
>  3 files changed, 38 insertions(+), 26 deletions(-)
>  create mode 100644 scripts/qemu-version.py
>  delete mode 100755 scripts/qemu-version.sh
>
> diff --git a/meson.build b/meson.build
> index 05fb59a00b..b100b6d7be 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1240,7 +1240,7 @@ tracetool = [
> '--backend=' + config_host['TRACE_BACKENDS']
>  ]
>
> -qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
> +qemu_version_cmd = [find_program('scripts/qemu-version.py'),
>  meson.current_source_dir(),
>  config_host['PKGVERSION'], meson.project_version()]
>  qemu_version = custom_target('qemu-version.h',
> diff --git a/scripts/qemu-version.py b/scripts/qemu-version.py
> new file mode 100644
> index 00..cf97b2bbb5
> --- /dev/null
> +++ b/scripts/qemu-version.py
> @@ -0,0 +1,37 @@
> +#!/usr/bin/env python3
> +
> +#
> +# Script for retrieve qemu git version information
> +#
> +# Authors:
> +#  Yonggang Luo 
> +#
> +# 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.
> +
> +import sys
> +import subprocess
> +import os
> +import os.path
> +
> +def main(_program, dir, pkgversion, version, *unused):
> +os.chdir(dir)
> +if not pkgversion and os.path.exists('.git'):
> +pc = subprocess.run(
> +['git', 'describe', '--match', 'v*', '--dirty', '--always'],
> +env=dict(os.environ, CYGWIN="noglob", MSYS='noglob'),
Sorry for disturb, under msys2,  use   env=dict(os.environ,
CYGWIN="noglob", MSYS='noglob') we make sure
'v*‘ are passed into git without wildcard. So I send this patch again for
fixes this issue
> +stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
> +encoding='utf8', shell=False)
> +if pc.returncode == 0:
> +pkgversion = pc.stdout.strip()
> +
> +fullversion = version
> +if pkgversion:
> +fullversion = "{} ({})".format(version, pkgversion)
> +
> +print('#define QEMU_PKGVERSION "%s"' % pkgversion)
> +print('#define QEMU_FULL_VERSION "%s"' % fullversion)
> +
> +if __name__ == "__main__":
> +main(*sys.argv)
> diff --git a/scripts/qemu-version.sh b/scripts/qemu-version.sh
> deleted file mode 100755
> index 3f6e7e6d41..00
> --- a/scripts/qemu-version.sh
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -#!/bin/sh
> -
> -set -eu
> -
> -dir="$1"
> -pkgversion="$2"
> -version="$3"
> -
> -if [ -z "$pkgversion" ]; then
> -cd "$dir"
> -if [ -e .git ]; then
> -pkgversion=$(git describe --match 'v*' --dirty) || :
> -fi
> -fi
> -
> -if [ -n "$pkgversion" ]; then
> -fullversion="$version ($pkgversion)"
> -else
> -fullversion="$version"
> -fi
> -
> -cat < -#define QEMU_PKGVERSION "$pkgversion"
> -#define QEMU_FULL_VERSION "$fullversion"
> -EOF
> --
> 2.28.0.windows.1
>


--
 此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo


[PATCH v11] scripts: Convert qemu-version.sh to qemu-version.py

2020-10-17 Thread Yonggang Luo
The sh script are harder to maintain for compatible different
xsh environment so convert it to python script
Also incorporate the fixes in
https://patchew.org/QEMU/20200929143654.518157-1-marcandre.lur...@redhat.com/

According to https://github.com/msys2/MSYS2-packages/issues/2176
We need use CYGWIN=noglob and MSYS=noglob in the environment variable
for disable wildcard expanding in msys or cygwin git, and setting the 
shell=False

Signed-off-by: Yonggang Luo 
Message-Id: <20201006112139.700-1-luoyongg...@gmail.com>
Signed-off-by: Paolo Bonzini 
---
 meson.build |  2 +-
 scripts/qemu-version.py | 37 +
 scripts/qemu-version.sh | 25 -
 3 files changed, 38 insertions(+), 26 deletions(-)
 create mode 100644 scripts/qemu-version.py
 delete mode 100755 scripts/qemu-version.sh

diff --git a/meson.build b/meson.build
index 05fb59a00b..b100b6d7be 100644
--- a/meson.build
+++ b/meson.build
@@ -1240,7 +1240,7 @@ tracetool = [
'--backend=' + config_host['TRACE_BACKENDS']
 ]
 
-qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
+qemu_version_cmd = [find_program('scripts/qemu-version.py'),
 meson.current_source_dir(),
 config_host['PKGVERSION'], meson.project_version()]
 qemu_version = custom_target('qemu-version.h',
diff --git a/scripts/qemu-version.py b/scripts/qemu-version.py
new file mode 100644
index 00..cf97b2bbb5
--- /dev/null
+++ b/scripts/qemu-version.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python3
+
+#
+# Script for retrieve qemu git version information
+#
+# Authors:
+#  Yonggang Luo 
+#
+# 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.
+
+import sys
+import subprocess
+import os
+import os.path
+
+def main(_program, dir, pkgversion, version, *unused):
+os.chdir(dir)
+if not pkgversion and os.path.exists('.git'):
+pc = subprocess.run(
+['git', 'describe', '--match', 'v*', '--dirty', '--always'],
+env=dict(os.environ, CYGWIN="noglob", MSYS='noglob'),
+stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
+encoding='utf8', shell=False)
+if pc.returncode == 0:
+pkgversion = pc.stdout.strip()
+
+fullversion = version
+if pkgversion:
+fullversion = "{} ({})".format(version, pkgversion)
+
+print('#define QEMU_PKGVERSION "%s"' % pkgversion)
+print('#define QEMU_FULL_VERSION "%s"' % fullversion)
+
+if __name__ == "__main__":
+main(*sys.argv)
diff --git a/scripts/qemu-version.sh b/scripts/qemu-version.sh
deleted file mode 100755
index 3f6e7e6d41..00
--- a/scripts/qemu-version.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-
-set -eu
-
-dir="$1"
-pkgversion="$2"
-version="$3"
-
-if [ -z "$pkgversion" ]; then
-cd "$dir"
-if [ -e .git ]; then
-pkgversion=$(git describe --match 'v*' --dirty) || :
-fi
-fi
-
-if [ -n "$pkgversion" ]; then
-fullversion="$version ($pkgversion)"
-else
-fullversion="$version"
-fi
-
-cat <

Re: [PATCH v8 0/5] Mac Old World ROM experiment (ppc/mac_* clean ups and loading binary ROM)

2020-10-17 Thread BALATON Zoltan via

On Fri, 16 Oct 2020, Philippe Mathieu-Daudé wrote:

On 10/16/20 11:58 AM, Mark Cave-Ayland wrote:

On 16/10/2020 00:47, BALATON Zoltan via wrote:


This is the cut down version of the earlier series omitting unfinished
patches that I plan to rework later and rebased to Mark's qemu-macppc
branch. Compared to v7 the only change is the cast to (target_ulong)
from (uint32_t) as requested by Mark in patch 1.


FWIW the reason for suggesting the cast to target_ulong is so that the same 
code works for both qemu-system-ppc and qemu-system-ppc64. For 
qemu-system-ppc that should correctly drop the sign extension from 32-bit, 
whilst still allowing someone to load a 64-bit ELF into qemu-system-ppc64 
if requested.


IMO this is part of a bigger design problem. Not all
machines main bus is 64-bit. I did some experiments
but changing that involves a lot of work.


Did not want to reply to this to not bring it to your attention before 
patch gets in finally but it's too late...


Not sure what you refer to but in this particular case the problem only 
seems to be load_elf loading 32 bit ELF files returning sign extended 64 
bit address which looks bogus but since this function is widely used I did 
not feel confident enough to propose a patch to load_elf.


By the way, also the parameters of load_elf could take a clean up to 
remove all the mostly NULL values as I've pointed out before:


https://lists.nongnu.org/archive/html/qemu-devel/2019-01/msg03427.html

but all this could wait until later, these don't seem to be urgent 
problems to prevent moving mac machines forward now and could all be 
addressen in separate elf loading series. So just note the problem and 
move on for now please.


Reagards.
BALATON Zoltan

Re: [PULL v2 00/22] Build system + misc changes for 2020-10-16

2020-10-17 Thread Paolo Bonzini
On 17/10/20 17:37, Paolo Bonzini wrote:
> On 17/10/20 16:39, Peter Maydell wrote:
>> Library iconv found: NO
>> ../src/meson.build:531: WARNING: iconv required for curses UI but not
>> available, disabling
> 
> I'm not sure if that will remove the warning or not, but I'll check (and
> if it does remain, it'll be of the "useful" kind which documents some
> unexpected dependency between options).

Ok, so the warning remains when everything is fixed, though the text is
slightly different (and better):

  Library iconv found: NO
  Run-time dependency ncursesw found: NO (tried pkgconfig)
  Library ncursesw found: YES
  Library cursesw found: NO
  ../src/meson.build:540: WARNING: curses library not usable, disabling

In this case, meson.build warns because curses doesn't always have a .pc
file; therefore when meson.build doesn't find the headers it can't but
proceed without curses suport.

The "library found"/"curses support disabled" situation is a bit
confusing, which is why I've been adding some kind of message for those
few cases in which we cannot just use pkg-config.  (The multipath test
is already warning, but those libraries are a bit niche so you probably
don't even have the libraries installed).

Peter, I would like your input on these two things:

1) are you going to pull v3 and I can fix up everything later?  Or would
you prefer me to send v4 once the new curses test is reviewed?

2) would you prefer the "library was found but headers weren't" to warn,
issue an informative message, or be completely silent?

Paolo



Re: [PATCH v9] mac_oldworld: Allow loading binary ROM image

2020-10-17 Thread BALATON Zoltan via

On Sat, 17 Oct 2020, Philippe Mathieu-Daudé wrote:

+Alistair for loader

On 10/17/20 5:47 PM, BALATON Zoltan via wrote:

The beige G3 Power Macintosh has a 4MB firmware ROM. Fix the size of
the rom region and fall back to loading a binary image with -bios if
loading ELF image failed. This allows testing emulation with a ROM
image from real hardware as well as using an ELF OpenBIOS image.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Mark Cave-Ayland 
---
v9: Revert change from v8, back to the same as v7 rebased on latest

  hw/ppc/mac_oldworld.c | 29 -
  1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 05e46ee6fe..0117ae17f5 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -59,6 +59,8 @@
  #define NDRV_VGA_FILENAME "qemu_vga.ndrv"
#define GRACKLE_BASE 0xfec0
+#define PROM_BASE 0xffc0
+#define PROM_SIZE (4 * MiB)
static void fw_cfg_boot_set(void *opaque, const char *boot_device,
  Error **errp)
@@ -100,6 +102,7 @@ static void ppc_heathrow_init(MachineState *machine)
  SysBusDevice *s;
  DeviceState *dev, *pic_dev;
  BusState *adb_bus;
+uint64_t bios_addr;
  int bios_size;
  unsigned int smp_cpus = machine->smp.cpus;
  uint16_t ppc_boot_device;
@@ -128,24 +131,32 @@ static void ppc_heathrow_init(MachineState *machine)
memory_region_add_subregion(sysmem, 0, machine->ram);
  -/* allocate and load BIOS */
-memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE,
+/* allocate and load firmware ROM */
+memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", PROM_SIZE,
 _fatal);
+memory_region_add_subregion(sysmem, PROM_BASE, bios);
  -if (bios_name == NULL)
+if (!bios_name) {
  bios_name = PROM_FILENAME;
+}
  filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-memory_region_add_subregion(sysmem, PROM_ADDR, bios);
-
-/* Load OpenBIOS (ELF) */
  if (filename) {
-bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL, 
NULL,

- 1, PPC_ELF_MACHINE, 0, 0);
+/* Load OpenBIOS (ELF) */
+bios_size = load_elf(filename, NULL, NULL, NULL, NULL, _addr,
+ NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
+/* Unfortunately, load_elf sign-extends reading elf32 */


Maybe this is what translate_fn() is for?

uint64_t oldworld_phys(void *opaque, uint64_t addr)
{
   return addr & UINT32_MAX;
}

Using as (untested):

   bios_size = load_elf(filename, NULL, oldworld_phys, NULL,
NULL, _addr, NULL,
NULL, 1, PPC_ELF_MACHINE, 0, 0);


Please don't come up with any more great ideas for this patch unless you 
also propose a replacement and test it. This one works and we could just 
get this in as it is until the real problem with load_elf is fixed at 
which point all this can be removed so no need to be more sophisticated as 
the simple cast I have. As you can see in the original discussion:


http://patchwork.ozlabs.org/project/qemu-devel/patch/c69a791c7cad1246f3f34b3993dee4f549b75aa2.1593456926.git.bala...@eik.bme.hu/

problem is really in include/hw/elf_ops.h this is just a work around for 
that as I did not want to break anything I can't test so I'd rather fix it 
up here and let you fix load_elf then drop this cast. But unless you can 
do that before the freeze please don't hold up this patch any more.


Regards,
BALATON Zoltan


+bios_addr = (uint32_t)bios_addr;
+
+if (bios_size <= 0) {
+/* or load binary ROM image */
+bios_size = load_image_targphys(filename, PROM_BASE, 
PROM_SIZE);

+bios_addr = PROM_BASE;
+}
  g_free(filename);
  } else {
  bios_size = -1;
  }
-if (bios_size < 0 || bios_size > BIOS_SIZE) {
+if (bios_size < 0 || bios_addr - PROM_BASE + bios_size > PROM_SIZE) {
  error_report("could not load PowerPC bios '%s'", bios_name);
  exit(1);
  }






Re: [PULL v2 00/22] Build system + misc changes for 2020-10-16

2020-10-17 Thread Yonggang Luo
On Sat, Oct 17, 2020 at 11:37 PM Paolo Bonzini  wrote:
>
> On 17/10/20 16:39, Peter Maydell wrote:
> > On Sat, 17 Oct 2020 at 14:38, Paolo Bonzini  wrote:
> >> OpenBSD and NetBSD call the ninja package "ninja-build" unlike FreeBSD.
> >>  I'm sure I had used the right name but well I didn't.  I'll send a v3.
> >
> > OpenBSD built OK but meson produces this new warning:
> >
> > Library iconv found: NO
> > ../src/meson.build:531: WARNING: iconv required for curses UI but not
> > available, disabling
>
> Hrm, the curses test was not plainly converted from shell to meson (guys
> please do *one* thing per patch, things are already complex enough!);
Oh, sorry for that,
> and it is messed up in more ways than I had first noticed (of which the
> most blatant is using /usr/include/ncursesw as a library path).  I'll
> fix everything up and resend this pull request when I'm done.
>
> I'm not sure if that will remove the warning or not, but I'll check (and
> if it does remain, it'll be of the "useful" kind which documents some
> unexpected dependency between options).
>
> Paolo
>


--
 此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo


Re: [PATCH v9] mac_oldworld: Allow loading binary ROM image

2020-10-17 Thread Philippe Mathieu-Daudé

+Alistair for loader

On 10/17/20 5:47 PM, BALATON Zoltan via wrote:

The beige G3 Power Macintosh has a 4MB firmware ROM. Fix the size of
the rom region and fall back to loading a binary image with -bios if
loading ELF image failed. This allows testing emulation with a ROM
image from real hardware as well as using an ELF OpenBIOS image.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Mark Cave-Ayland 
---
v9: Revert change from v8, back to the same as v7 rebased on latest

  hw/ppc/mac_oldworld.c | 29 -
  1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 05e46ee6fe..0117ae17f5 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -59,6 +59,8 @@
  #define NDRV_VGA_FILENAME "qemu_vga.ndrv"
  
  #define GRACKLE_BASE 0xfec0

+#define PROM_BASE 0xffc0
+#define PROM_SIZE (4 * MiB)
  
  static void fw_cfg_boot_set(void *opaque, const char *boot_device,

  Error **errp)
@@ -100,6 +102,7 @@ static void ppc_heathrow_init(MachineState *machine)
  SysBusDevice *s;
  DeviceState *dev, *pic_dev;
  BusState *adb_bus;
+uint64_t bios_addr;
  int bios_size;
  unsigned int smp_cpus = machine->smp.cpus;
  uint16_t ppc_boot_device;
@@ -128,24 +131,32 @@ static void ppc_heathrow_init(MachineState *machine)
  
  memory_region_add_subregion(sysmem, 0, machine->ram);
  
-/* allocate and load BIOS */

-memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE,
+/* allocate and load firmware ROM */
+memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", PROM_SIZE,
 _fatal);
+memory_region_add_subregion(sysmem, PROM_BASE, bios);
  
-if (bios_name == NULL)

+if (!bios_name) {
  bios_name = PROM_FILENAME;
+}
  filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-memory_region_add_subregion(sysmem, PROM_ADDR, bios);
-
-/* Load OpenBIOS (ELF) */
  if (filename) {
-bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL, NULL,
- 1, PPC_ELF_MACHINE, 0, 0);
+/* Load OpenBIOS (ELF) */
+bios_size = load_elf(filename, NULL, NULL, NULL, NULL, _addr,
+ NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
+/* Unfortunately, load_elf sign-extends reading elf32 */


Maybe this is what translate_fn() is for?

uint64_t oldworld_phys(void *opaque, uint64_t addr)
{
return addr & UINT32_MAX;
}

Using as (untested):

bios_size = load_elf(filename, NULL, oldworld_phys, NULL,
 NULL, _addr, NULL,
 NULL, 1, PPC_ELF_MACHINE, 0, 0);


+bios_addr = (uint32_t)bios_addr;
+
+if (bios_size <= 0) {
+/* or load binary ROM image */
+bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE);
+bios_addr = PROM_BASE;
+}
  g_free(filename);
  } else {
  bios_size = -1;
  }
-if (bios_size < 0 || bios_size > BIOS_SIZE) {
+if (bios_size < 0 || bios_addr - PROM_BASE + bios_size > PROM_SIZE) {
  error_report("could not load PowerPC bios '%s'", bios_name);
  exit(1);
  }






Re: [PATCH V14 7/8] hw/mips: Add Loongson-3 machine support

2020-10-17 Thread Philippe Mathieu-Daudé

On 10/16/20 8:51 AM, Huacai Chen wrote:

Add Loongson-3 based machine support, it use liointc as the interrupt
controler and use GPEX as the pci controller. Currently it can work with
both TCG and KVM.

As the machine model is not based on any exiting physical hardware, the
name of the machine is "loongson3-virt". It may be superseded in future
by a real machine model. If this happens, then a regular deprecation
procedure shall occur for "loongson3-virt" machine.

We now already have a full functional Linux kernel (based on Linux-5.4.x
LTS, the kvm host side and guest side have both been upstream for Linux-
5.9, but Linux-5.9 has not been released yet) here:

https://github.com/chenhuacai/linux

Of course the upstream kernel is also usable (though it is "unstable"
now):

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

How to use QEMU/Loongson-3?
1, Download kernel source from the above URL;
2, Build a kernel with arch/mips/configs/loongson3_defconfig;
3, Boot a Loongson-3A4000 host with this kernel (for KVM mode);
4, Build QEMU-master with this patchset;
5, modprobe kvm (only necessary for KVM mode);
6, Use QEMU with TCG:
qemu-system-mips64el -M loongson3-virt,accel=tcg -cpu Loongson-3A1000 -kernel 
 -append ...
Use QEMU with KVM:
qemu-system-mips64el -M loongson3-virt,accel=kvm -cpu Loongson-3A4000 -kernel 
 -append ...

The "-cpu" parameter is optional here and QEMU will use the correct type 
for TCG/KVM automatically.

Signed-off-by: Huacai Chen 
Co-developed-by: Jiaxun Yang 
---
  default-configs/devices/mips64el-softmmu.mak |   1 +
  hw/mips/Kconfig  |  12 +
  hw/mips/loongson3_virt.c | 615 +++
  hw/mips/meson.build  |   2 +-
  4 files changed, 629 insertions(+), 1 deletion(-)
  create mode 100644 hw/mips/loongson3_virt.c

diff --git a/default-configs/devices/mips64el-softmmu.mak 
b/default-configs/devices/mips64el-softmmu.mak
index 9f8a3ef156..26c660a05c 100644
--- a/default-configs/devices/mips64el-softmmu.mak
+++ b/default-configs/devices/mips64el-softmmu.mak
@@ -3,6 +3,7 @@
  include mips-softmmu-common.mak
  CONFIG_IDE_VIA=y
  CONFIG_FULOONG=y
+CONFIG_LOONGSON3V=y
  CONFIG_ATI_VGA=y
  CONFIG_RTL8139_PCI=y
  CONFIG_JAZZ=y
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index 67d39c56a4..6562b346ab 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -45,6 +45,18 @@ config FULOONG
  bool
  select PCI_BONITO
  
+config LOONGSON3V

+bool
+select PCKBD
+select SERIAL
+select GOLDFISH_RTC
+select LOONGSON_LIOINTC
+select PCI_DEVICES
+select PCI_EXPRESS_GENERIC_BRIDGE
+select VIRTIO_VGA
+select QXL if SPICE
+select MSI_NONBROKEN
+
  config MIPS_CPS
  bool
  select PTIMER
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
new file mode 100644
index 00..c298a16793
--- /dev/null
+++ b/hw/mips/loongson3_virt.c
@@ -0,0 +1,627 @@
+/*
+ * Generic Loongson-3 Platform support
+ *
+ * Copyright (c) 2017-2020 Huacai Chen (che...@lemote.com)
+ * Copyright (c) 2017-2020 Jiaxun Yang 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/*
+ * Generic virtualized PC Platform based on Loongson-3 CPU (MIPS64R2 with
+ * extensions, 800~2000MHz)
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/units.h"
+#include "qemu/cutils.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "elf.h"
+#include "kvm_mips.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/mips/mips.h"
+#include "hw/mips/cpudevs.h"
+#include "hw/mips/fw_cfg.h"
+#include "hw/mips/loongson3_bootp.h"
+#include "hw/misc/unimp.h"
+#include "hw/intc/i8259.h"
+#include "hw/loader.h"
+#include "hw/isa/superio.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/rtc/mc146818rtc.h"
+#include "hw/usb.h"
+#include "net/net.h"
+#include "exec/address-spaces.h"
+#include "sysemu/kvm.h"
+#include "sysemu/qtest.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+
+#define PM_CNTL_MODE  0x10
+
+#define LOONGSON_MAX_VCPUS  16
+
+/*
+ * Loongson-3's virtual machine BIOS can be obtained here:
+ * 1, https://github.com/loongson-community/firmware-nonfree
+ * 2, 

Re: [PATCH v8 0/5] Mac Old World ROM experiment (ppc/mac_* clean ups and loading binary ROM)

2020-10-17 Thread BALATON Zoltan via

On Sat, 17 Oct 2020, Mark Cave-Ayland wrote:

On 16/10/2020 13:19, BALATON Zoltan via wrote:

On Fri, 16 Oct 2020, Mark Cave-Ayland wrote:

On 16/10/2020 00:47, BALATON Zoltan via wrote:

This is the cut down version of the earlier series omitting unfinished
patches that I plan to rework later and rebased to Mark's qemu-macppc
branch. Compared to v7 the only change is the cast to (target_ulong)
from (uint32_t) as requested by Mark in patch 1.


FWIW the reason for suggesting the cast to target_ulong is so that the 
same code works for both qemu-system-ppc and qemu-system-ppc64. For 
qemu-system-ppc that should correctly drop the sign extension from 32-bit, 
whilst still allowing someone to load a 64-bit ELF into qemu-system-ppc64 
if requested.


Can you confirm that the sign extension behaviour is still correct for 
both qemu-system-ppc and qemu-system-ppc64? If so I'm happy to give it a 
R-B tag.


I've tried it now again with both ppc and ppc64: both OpenBIOS and a G3 
beige ROM can be loaded with qemu-system-ppc but qemu-system-ppc64 fails 
with OpenBIOS when casting to target_ulong (i think because target_ulong is 
64 bit there but g3beige is still 32 bit but I haven't throughly debugged 
it). But everything works with my original uint32_t cast, so ditch it and 
use my original version. Should I resubmit or you can fix up? (I think I 
wait until it's clear if this will be taken by David or you and send a 
fixed version cc-ing David if this is decided to go through the PPC queue.)


Hmmm yes I see that qemu-system-ppc64 fails because target_ulong will always 
represent a 64-bit quantity, even if you request a 32-bit CPU. Rather than 
add some CPU-specific code let's keep the uint32_t cast for now as I would 
hope it is unlikely someone would load an ELF in high memory, and perhaps the 
sign-extended address bug will get fixed later.


With the cast reverted to uint32_t then for patches 1 and 2:
Reviewed-by: Mark Cave-Ayland 

If you can send a v9 with the cast fixed I'll apply this to my qemu-macppc 
branch right away.


You could've really just edit the single cast in patch 1 before applying 
to change the it back but I've resent the changed patch 1 as v9 also 
adding your R-b for your convenience. Other patches are unchanged so you 
can take the v8 for those, I haven't resent those, let me know if you want 
the whole series but this is really getting much more work that it should 
be for such a simple change. (There is no cast in patch 2 as I've already 
stated several times.)


Regards,
BALATON Zoltan



[PATCH v9] mac_oldworld: Allow loading binary ROM image

2020-10-17 Thread BALATON Zoltan via
The beige G3 Power Macintosh has a 4MB firmware ROM. Fix the size of
the rom region and fall back to loading a binary image with -bios if
loading ELF image failed. This allows testing emulation with a ROM
image from real hardware as well as using an ELF OpenBIOS image.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Mark Cave-Ayland 
---
v9: Revert change from v8, back to the same as v7 rebased on latest

 hw/ppc/mac_oldworld.c | 29 -
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 05e46ee6fe..0117ae17f5 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -59,6 +59,8 @@
 #define NDRV_VGA_FILENAME "qemu_vga.ndrv"
 
 #define GRACKLE_BASE 0xfec0
+#define PROM_BASE 0xffc0
+#define PROM_SIZE (4 * MiB)
 
 static void fw_cfg_boot_set(void *opaque, const char *boot_device,
 Error **errp)
@@ -100,6 +102,7 @@ static void ppc_heathrow_init(MachineState *machine)
 SysBusDevice *s;
 DeviceState *dev, *pic_dev;
 BusState *adb_bus;
+uint64_t bios_addr;
 int bios_size;
 unsigned int smp_cpus = machine->smp.cpus;
 uint16_t ppc_boot_device;
@@ -128,24 +131,32 @@ static void ppc_heathrow_init(MachineState *machine)
 
 memory_region_add_subregion(sysmem, 0, machine->ram);
 
-/* allocate and load BIOS */
-memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE,
+/* allocate and load firmware ROM */
+memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", PROM_SIZE,
_fatal);
+memory_region_add_subregion(sysmem, PROM_BASE, bios);
 
-if (bios_name == NULL)
+if (!bios_name) {
 bios_name = PROM_FILENAME;
+}
 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-memory_region_add_subregion(sysmem, PROM_ADDR, bios);
-
-/* Load OpenBIOS (ELF) */
 if (filename) {
-bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL, NULL,
- 1, PPC_ELF_MACHINE, 0, 0);
+/* Load OpenBIOS (ELF) */
+bios_size = load_elf(filename, NULL, NULL, NULL, NULL, _addr,
+ NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
+/* Unfortunately, load_elf sign-extends reading elf32 */
+bios_addr = (uint32_t)bios_addr;
+
+if (bios_size <= 0) {
+/* or load binary ROM image */
+bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE);
+bios_addr = PROM_BASE;
+}
 g_free(filename);
 } else {
 bios_size = -1;
 }
-if (bios_size < 0 || bios_size > BIOS_SIZE) {
+if (bios_size < 0 || bios_addr - PROM_BASE + bios_size > PROM_SIZE) {
 error_report("could not load PowerPC bios '%s'", bios_name);
 exit(1);
 }
-- 
2.21.3




Re: [PULL v2 00/22] Build system + misc changes for 2020-10-16

2020-10-17 Thread Paolo Bonzini
On 17/10/20 16:39, Peter Maydell wrote:
> On Sat, 17 Oct 2020 at 14:38, Paolo Bonzini  wrote:
>> OpenBSD and NetBSD call the ninja package "ninja-build" unlike FreeBSD.
>>  I'm sure I had used the right name but well I didn't.  I'll send a v3.
> 
> OpenBSD built OK but meson produces this new warning:
> 
> Library iconv found: NO
> ../src/meson.build:531: WARNING: iconv required for curses UI but not
> available, disabling

Hrm, the curses test was not plainly converted from shell to meson (guys
please do *one* thing per patch, things are already complex enough!);
and it is messed up in more ways than I had first noticed (of which the
most blatant is using /usr/include/ncursesw as a library path).  I'll
fix everything up and resend this pull request when I'm done.

I'm not sure if that will remove the warning or not, but I'll check (and
if it does remain, it'll be of the "useful" kind which documents some
unexpected dependency between options).

Paolo




Re: io_uring possibly the culprit for qemu hang (linux-5.4.y)

2020-10-17 Thread Jens Axboe
On 10/17/20 8:29 AM, Ju Hyung Park wrote:
> Hi Jens.
> 
> On Sat, Oct 17, 2020 at 3:07 AM Jens Axboe  wrote:
>>
>> Would be great if you could try 5.4.71 and see if that helps for your
>> issue.
>>
> 
> Oh wow, yeah it did fix the issue.
> 
> I'm able to reliably turn off and start the VM multiple times in a row.
> Double checked by confirming QEMU is dynamically linked to liburing.so.1.
> 
> Looks like those 4 io_uring fixes helped.

Awesome, thanks for testing!

-- 
Jens Axboe




[PULL 10/22] build: replace ninjatool with ninja

2020-10-17 Thread Paolo Bonzini
Now that the build is done entirely by Meson, there is no need
to keep the Makefile conversion.  Instead, we can ask Ninja about
the targets it exposes and forward them.

The main advantages are, from smallest to largest:

- reducing the possible namespace pollution within the Makefile

- removal of a relatively large Python program

- faster build because parsing Makefile.ninja is slower than
parsing build.ninja; and faster build after Meson runs because
we do not have to generate Makefile.ninja.

- tracking of command lines, which provides more accurate rebuilds

In addition the change removes the requirement for GNU make 3.82, which
was annoying on Mac, and avoids bugs on Windows due to ninjatool not
knowing how to convert Windows escapes to POSIX escapes.

Signed-off-by: Paolo Bonzini 
---
 Makefile|   80 +--
 configure   |9 +-
 docs/devel/build-system.rst |6 +-
 meson.build |4 -
 scripts/mtest2make.py   |3 +-
 scripts/ninjatool.py| 1008 ---
 tests/Makefile.include  |2 +-
 7 files changed, 59 insertions(+), 1053 deletions(-)
 delete mode 100755 scripts/ninjatool.py

diff --git a/Makefile b/Makefile
index 53d624a0be..18f026eac3 100644
--- a/Makefile
+++ b/Makefile
@@ -72,27 +72,8 @@ git-submodule-update:
 endif
 endif
 
-export NINJA=./ninjatool
+# 0. ensure the build tree is okay
 
-# Running meson regenerates both build.ninja and ninjatool, and that is
-# enough to prime the rest of the build.
-ninjatool: build.ninja
-
-Makefile.ninja: build.ninja ninjatool
-   ./ninjatool -t ninja2make --omit clean dist uninstall cscope TAGS ctags 
< $< > $@
--include Makefile.ninja
-
-${ninja-targets-c_COMPILER} ${ninja-targets-cpp_COMPILER}: .var.command += -MP
-
-# If MESON is empty, the rule will be re-evaluated after Makefiles are
-# reread (and MESON won't be empty anymore).
-ifneq ($(MESON),)
-Makefile.mtest: build.ninja scripts/mtest2make.py
-   $(MESON) introspect --targets --tests --benchmarks | $(PYTHON) 
scripts/mtest2make.py > $@
--include Makefile.mtest
-endif
-
-# Ensure the build tree is okay.
 # Check that we're not trying to do an out-of-tree build from
 # a tree that's been used for an in-tree build.
 ifneq ($(realpath $(SRC_PATH)),$(realpath .))
@@ -117,6 +98,7 @@ ifeq ($(wildcard build.ninja),)
 x := $(shell rm -rf meson-private meson-info meson-logs)
 endif
 
+# 1. ensure config-host.mak is up-to-date
 config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/pc-bios $(SRC_PATH)/VERSION
@echo $@ is out-of-date, running configure
@if test -f meson-private/coredata.dat; then \
@@ -125,6 +107,46 @@ config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/pc-bios 
$(SRC_PATH)/VERSION
  ./config.status; \
fi
 
+# 2. ensure generated build files are up-to-date
+
+ifneq ($(NINJA),)
+# A separate rule is needed for Makefile dependencies to avoid -n
+export NINJA
+Makefile.ninja: build.ninja
+   $(quiet-@){ echo 'ninja-targets = \'; $(NINJA) -t targets all | sed 
's/:.*//; $$!s/$$/ \\/'; } > $@
+-include Makefile.ninja
+endif
+
+ifneq ($(MESON),)
+# The dependency on config-host.mak ensures that meson has run
+Makefile.mtest: build.ninja scripts/mtest2make.py config-host.mak
+   $(MESON) introspect --targets --tests --benchmarks | $(PYTHON) 
scripts/mtest2make.py > $@
+-include Makefile.mtest
+endif
+
+# 3. Rules to bridge to other makefiles
+
+ifneq ($(NINJA),)
+NINJAFLAGS = $(if $V,-v,) \
+$(filter-out -j, $(lastword -j1 $(filter -l% -j%, $(MAKEFLAGS \
+$(subst -k, -k0, $(filter -n -k,$(MAKEFLAGS)))
+
+ninja-cmd-goals = $(or $(MAKECMDGOALS), all)
+ninja-cmd-goals += $(foreach t, $(.tests), $(.test.deps.$t))
+
+makefile-targets := build.ninja ctags TAGS cscope dist clean uninstall
+ninja-targets := $(filter-out $(makefile-targets), $(ninja-targets))
+.PHONY: $(ninja-targets) run-ninja
+$(ninja-targets): run-ninja
+
+# Use "| cat" to give Ninja a more "make-y" output.  Use "+" to bypass the
+# --output-sync line.
+run-ninja: config-host.mak
+ifneq ($(filter $(ninja-targets), $(ninja-cmd-goals)),)
+   +@$(NINJA) $(NINJAFLAGS) $(sort $(filter $(ninja-targets), 
$(ninja-cmd-goals))) | cat
+endif
+endif
+
 # Force configure to re-run if the API symbols are updated
 ifeq ($(CONFIG_PLUGIN),y)
 config-host.mak: $(SRC_PATH)/plugins/qemu-plugins.symbols
@@ -144,13 +166,6 @@ ifneq ($(filter-out 
$(UNCHECKED_GOALS),$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),,fa
 endif
 endif # config-host.mak does not exist
 
-# Only needed in case Makefile.ninja does not exist.
-.PHONY: ninja-clean ninja-distclean clean-ctlist
-clean-ctlist:
-ninja-clean::
-ninja-distclean::
-build.ninja: config-host.mak
-
 SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory --quiet)
 
 include $(SRC_PATH)/tests/Makefile.include
@@ -170,8 +185,9 @@ recurse-clean: $(addsuffix /clean, $(ROM_DIRS))
 
 ##
 
-clean: 

[PULL v3 00/22] Build system + misc changes for 2020-10-16

2020-10-17 Thread Paolo Bonzini
The following changes since commit 3e40748834923798aa57e3751db13a069e2c617b:

  Merge remote-tracking branch 'remotes/rth/tags/pull-mb-20201014' into staging 
(2020-10-15 20:30:24 +0100)

are available in the Git repository at:

  https://gitlab.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to c47110d90fa5401bcc42c17f8ae0724a1c96599a:

  ci: include configure and meson logs in all jobs if configure fails 
(2020-10-17 10:45:53 -0400)


* Drop ninjatool and just require ninja (Paolo)
* Fix docs build under msys2 (Yonggang)
* HAX snafu fix (Claudio)
* Disable signal handlers during fuzzing (Alex)
* Miscellaneous fixes (Bruce, Greg)


Alexander Bulekov (1):
  fuzz: Disable QEMU's SIG{INT,HUP,TERM} handlers

Bruce Rogers (3):
  meson.build: don't condition iconv detection on library detection
  configure: fix handling of --docdir parameter
  meson: Only install icons and qemu.desktop if have_system

Claudio Fontana (1):
  hax: unbreak accelerator cpu code after cpus.c split

Greg Kurz (1):
  Makefile: Ensure cscope.out/tags/TAGS are generated in the source tree

Paolo Bonzini (13):
  submodules: bump meson to 0.55.3
  tests/Makefile.include: unbreak non-tcg builds
  make: run shell with pipefail
  tests: add missing generated sources to testqapi
  configure: move QEMU_INCLUDES to meson
  dockerfiles: enable Centos 8 PowerTools
  add ninja to dockerfiles, CI configurations and test VMs
  build: cleanups to Makefile
  build: replace ninjatool with ninja
  build: add --enable/--disable-libudev
  meson: cleanup curses/iconv test
  meson: move SPHINX_ARGS references within "if build_docs"
  ci: include configure and meson logs in all jobs if configure fails

Yonggang Luo (3):
  docs: Fix Sphinx configuration for msys2/mingw
  meson: Move the detection logic for sphinx to meson
  cirrus: Enable doc build on msys2/mingw

 .cirrus.yml|   21 +-
 .gitlab-ci.yml |6 +-
 .travis.yml|   21 +-
 Makefile   |  135 ++--
 configure  |  101 +--
 docs/conf.py   |2 +-
 docs/devel/build-system.rst|6 +-
 docs/meson.build   |   46 ++
 docs/sphinx/kerneldoc.py   |2 +-
 meson  |2 +-
 meson.build|  185 ++---
 meson_options.txt  |6 +
 scripts/mtest2make.py  |3 +-
 scripts/ninjatool.py   | 1008 
 target/i386/hax-cpus.c |1 +
 tests/Makefile.include |2 +-
 tests/docker/dockerfiles/centos7.docker|1 +
 tests/docker/dockerfiles/centos8.docker|5 +-
 tests/docker/dockerfiles/debian10.docker   |1 +
 tests/docker/dockerfiles/fedora.docker |1 +
 tests/docker/dockerfiles/travis.docker |2 +-
 tests/docker/dockerfiles/ubuntu.docker |1 +
 tests/docker/dockerfiles/ubuntu1804.docker |1 +
 tests/docker/dockerfiles/ubuntu2004.docker |1 +
 tests/include/meson.build  |8 +-
 tests/meson.build  |   14 +-
 tests/qapi-schema/meson.build  |   88 +--
 tests/qtest/fuzz/fuzz.c|8 +
 tests/vm/centos|2 +-
 tests/vm/centos.aarch64|2 +-
 tests/vm/fedora|2 +-
 tests/vm/freebsd   |1 +
 tests/vm/netbsd|1 +
 tests/vm/openbsd   |1 +
 tests/vm/ubuntu.aarch64|2 +-
 tests/vm/ubuntu.i386   |2 +-
 ui/meson.build |7 +-
 37 files changed, 389 insertions(+), 1309 deletions(-)
 delete mode 100755 scripts/ninjatool.py
-- 
2.26.2




[PULL 08/22] add ninja to dockerfiles, CI configurations and test VMs

2020-10-17 Thread Paolo Bonzini
Reviewed-by: Daniel P. Berrangé 
Acked-by: Alex Bennée 
Signed-off-by: Paolo Bonzini 
---
 .cirrus.yml|  6 +++---
 .travis.yml| 13 +
 tests/docker/dockerfiles/centos7.docker|  1 +
 tests/docker/dockerfiles/centos8.docker|  1 +
 tests/docker/dockerfiles/debian10.docker   |  1 +
 tests/docker/dockerfiles/fedora.docker |  1 +
 tests/docker/dockerfiles/travis.docker |  2 +-
 tests/docker/dockerfiles/ubuntu.docker |  1 +
 tests/docker/dockerfiles/ubuntu1804.docker |  1 +
 tests/docker/dockerfiles/ubuntu2004.docker |  1 +
 tests/vm/centos|  2 +-
 tests/vm/centos.aarch64|  2 +-
 tests/vm/fedora|  2 +-
 tests/vm/freebsd   |  1 +
 tests/vm/netbsd|  1 +
 tests/vm/openbsd   |  1 +
 tests/vm/ubuntu.aarch64|  2 +-
 tests/vm/ubuntu.i386   |  2 +-
 18 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/.cirrus.yml b/.cirrus.yml
index 0f46cb5eaf..396888fbd3 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -9,7 +9,7 @@ freebsd_12_task:
   install_script:
 - ASSUME_ALWAYS_YES=yes pkg bootstrap -f ;
 - pkg install -y bash curl cyrus-sasl git glib gmake gnutls gsed
-  nettle perl5 pixman pkgconf png usbredir
+  nettle perl5 pixman pkgconf png usbredir ninja
   script:
 - mkdir build
 - cd build
@@ -21,7 +21,7 @@ macos_task:
   osx_instance:
 image: catalina-base
   install_script:
-- brew install pkg-config python gnu-sed glib pixman make sdl2 bash
+- brew install pkg-config python gnu-sed glib pixman make sdl2 bash ninja
   script:
 - mkdir build
 - cd build
@@ -36,7 +36,7 @@ macos_xcode_task:
 # this is an alias for the latest Xcode
 image: catalina-xcode
   install_script:
-- brew install pkg-config gnu-sed glib pixman make sdl2 bash
+- brew install pkg-config gnu-sed glib pixman make sdl2 bash ninja
   script:
 - mkdir build
 - cd build
diff --git a/.travis.yml b/.travis.yml
index 1054ec5d29..d7bfbb8bfe 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -49,6 +49,7 @@ addons:
   - libvdeplug-dev
   - libvte-2.91-dev
   - libzstd-dev
+  - ninja-build
   - sparse
   - uuid-dev
   - gcovr
@@ -177,6 +178,7 @@ jobs:
   addons:
 apt:
   packages:
+- ninja-build
 - python3-sphinx
 - perl
 
@@ -211,6 +213,10 @@ jobs:
 # gprof/gcov are GCC features
 - name: "GCC gprof/gcov"
   dist: bionic
+  addons:
+apt:
+  packages:
+- ninja-build
   env:
 - CONFIG="--enable-gprof --enable-gcov --disable-libssh
   --target-list=${MAIN_SOFTMMU_TARGETS}"
@@ -281,6 +287,7 @@ jobs:
 - liburcu-dev
 - libusb-1.0-0-dev
 - libvte-2.91-dev
+- ninja-build
 - sparse
 - uuid-dev
   language: generic
@@ -346,6 +353,7 @@ jobs:
   - libusb-1.0-0-dev
   - libvdeplug-dev
   - libvte-2.91-dev
+  - ninja-build
   # Tests dependencies
   - genisoimage
   env:
@@ -379,6 +387,7 @@ jobs:
   - libusb-1.0-0-dev
   - libvdeplug-dev
   - libvte-2.91-dev
+  - ninja-build
   # Tests dependencies
   - genisoimage
   env:
@@ -411,6 +420,7 @@ jobs:
   - libusb-1.0-0-dev
   - libvdeplug-dev
   - libvte-2.91-dev
+  - ninja-build
   # Tests dependencies
   - genisoimage
   env:
@@ -450,6 +460,7 @@ jobs:
   - libzstd-dev
   - nettle-dev
   - xfslibs-dev
+  - ninja-build
   # Tests dependencies
   - genisoimage
   env:
@@ -463,6 +474,7 @@ jobs:
 apt_packages:
   - libgcrypt20-dev
   - libgnutls28-dev
+  - ninja-build
   env:
 - CONFIG="--disable-containers --disable-system"
 
@@ -493,6 +505,7 @@ jobs:
   - libusb-1.0-0-dev
   - libvdeplug-dev
   - libvte-2.91-dev
+  - ninja-build
   env:
 - TEST_CMD="make check-unit"
 - CONFIG="--disable-containers --disable-tcg --enable-kvm
diff --git a/tests/docker/dockerfiles/centos7.docker 
b/tests/docker/dockerfiles/centos7.docker
index 4623bf..8b273725ee 100644
--- a/tests/docker/dockerfiles/centos7.docker
+++ b/tests/docker/dockerfiles/centos7.docker
@@ -27,6 +27,7 @@ ENV PACKAGES \
 mesa-libEGL-devel \
 mesa-libgbm-devel \
 nettle-devel \
+ninja-build \
 perl-Test-Harness \
 pixman-devel \
 python3 \
diff --git a/tests/docker/dockerfiles/centos8.docker 
b/tests/docker/dockerfiles/centos8.docker
index e29e9657fb..585dfad9be 100644
--- a/tests/docker/dockerfiles/centos8.docker
+++ b/tests/docker/dockerfiles/centos8.docker
@@ 

Re: [PATCH 4/5] ppc405_boards: use qdev properties instead of legacy m48t59_init() function

2020-10-17 Thread Artyom Tarasenko
On Fri, Oct 16, 2020 at 10:38 PM BALATON Zoltan  wrote:
>
> On Fri, 16 Oct 2020, Mark Cave-Ayland wrote:
> > Signed-off-by: Mark Cave-Ayland 
> > ---
> > hw/ppc/ppc405_boards.c | 10 +-
> > 1 file changed, 9 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
> > index 6198ec1035..4687715b15 100644
> > --- a/hw/ppc/ppc405_boards.c
> > +++ b/hw/ppc/ppc405_boards.c
> > @@ -28,6 +28,8 @@
> > #include "qemu-common.h"
> > #include "cpu.h"
> > #include "hw/ppc/ppc.h"
> > +#include "hw/qdev-properties.h"
> > +#include "hw/sysbus.h"
> > #include "ppc405.h"
> > #include "hw/rtc/m48t59.h"
> > #include "hw/block/flash.h"
> > @@ -145,6 +147,8 @@ static void ref405ep_init(MachineState *machine)
> > char *filename;
> > ppc4xx_bd_info_t bd;
> > CPUPPCState *env;
> > +DeviceState *dev;
> > +SysBusDevice *s;
> > qemu_irq *pic;
> > MemoryRegion *bios;
> > MemoryRegion *sram = g_new(MemoryRegion, 1);
> > @@ -227,7 +231,11 @@ static void ref405ep_init(MachineState *machine)
> > /* Register FPGA */
> > ref405ep_fpga_init(sysmem, 0xF030);
> > /* Register NVRAM */
> > -m48t59_init(NULL, 0xF000, 0, 8192, 1968, 8);
> > +dev = qdev_new("sysbus-m48t08");
> > +qdev_prop_set_int32(dev, "base-year", 1968);
>
> Is there anything that uses other than 1968 as base year?

I think 40p uses 1900 as the base year.

> If not this
> could be the default in the device so you don't need these set prop calls
> here and in sun machines.
>
> The only other place this device is used seems to be ppc/prep machine that
> uses the isa version but does not set a base year. Is that a bug? The
> original prep machine removed in b2ce76a0730 used 2000 but that's unlikely
> as well as these machines predate that. Anyway, the sysbus and isa
> versions are different so their default base-year could be set
> independently and then boards won't need to set this propery and may be
> could use qdev_create_simple instead or whatever that was renamed to.
>
> Regards,
> BALATON Zoltan
>
> > +s = SYS_BUS_DEVICE(dev);
> > +sysbus_realize_and_unref(s, _fatal);
> > +sysbus_mmio_map(s, 0, 0xF000);
> > /* Load kernel */
> > linux_boot = (kernel_filename != NULL);
> > if (linux_boot) {
> >



[PULL v2 5/5] tests/9pfs: add local Tmkdir test

2020-10-17 Thread Christian Schoenebeck
This test case uses the 9pfs 'local' driver to create a directory
and then checks if the expected directory was actually created
(as real directory) on host side.

This patch introduces a custom split() implementation, because
the test code requires non empty array elements as result. For
that reason g_strsplit() would not be a good alternative, as
it would require additional filter code for reshuffling the
array, and the resulting code would be even more complex than
this split() function.

Signed-off-by: Christian Schoenebeck 
Message-Id: 

Signed-off-by: Christian Schoenebeck 
---
 tests/qtest/virtio-9p-test.c | 139 +++
 1 file changed, 139 insertions(+)

diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c
index af7e169d3a..c15908f27b 100644
--- a/tests/qtest/virtio-9p-test.c
+++ b/tests/qtest/virtio-9p-test.c
@@ -18,6 +18,62 @@
 #define QVIRTIO_9P_TIMEOUT_US (10 * 1000 * 1000)
 static QGuestAllocator *alloc;
 
+/*
+ * Used to auto generate new fids. Start with arbitrary high value to avoid
+ * collision with hard coded fids in basic test code.
+ */
+static uint32_t fid_generator = 1000;
+
+static uint32_t genfid(void)
+{
+return fid_generator++;
+}
+
+/**
+ * Splits the @a in string by @a delim into individual (non empty) strings
+ * and outputs them to @a out. The output array @a out is NULL terminated.
+ *
+ * Output array @a out must be freed by calling split_free().
+ *
+ * @returns number of individual elements in output array @a out (without the
+ *  final NULL terminating element)
+ */
+static int split(const char *in, const char *delim, char ***out)
+{
+int n = 0, i = 0;
+char *tmp, *p;
+
+tmp = g_strdup(in);
+for (p = strtok(tmp, delim); p != NULL; p = strtok(NULL, delim)) {
+if (strlen(p) > 0) {
+++n;
+}
+}
+g_free(tmp);
+
+*out = g_new0(char *, n + 1); /* last element NULL delimiter */
+
+tmp = g_strdup(in);
+for (p = strtok(tmp, delim); p != NULL; p = strtok(NULL, delim)) {
+if (strlen(p) > 0) {
+(*out)[i++] = g_strdup(p);
+}
+}
+g_free(tmp);
+
+return n;
+}
+
+static void split_free(char ***out)
+{
+int i;
+for (i = 0; (*out)[i]; ++i) {
+g_free((*out)[i]);
+}
+g_free(*out);
+*out = NULL;
+}
+
 static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc)
 {
 QVirtio9P *v9p = obj;
@@ -201,6 +257,7 @@ static const char *rmessage_name(uint8_t id)
 id == P9_RWALK ? "RWALK" :
 id == P9_RLOPEN ? "RLOPEN" :
 id == P9_RWRITE ? "RWRITE" :
+id == P9_RMKDIR ? "RMKDIR" :
 id == P9_RFLUSH ? "RFLUSH" :
 id == P9_RREADDIR ? "READDIR" :
 "";
@@ -578,6 +635,39 @@ static bool fs_dirents_contain_name(struct V9fsDirent *e, 
const char* name)
 return false;
 }
 
+/* size[4] Tmkdir tag[2] dfid[4] name[s] mode[4] gid[4] */
+static P9Req *v9fs_tmkdir(QVirtio9P *v9p, uint32_t dfid, const char *name,
+  uint32_t mode, uint32_t gid, uint16_t tag)
+{
+P9Req *req;
+
+uint32_t body_size = 4 + 4 + 4;
+uint16_t string_size = v9fs_string_size(name);
+
+g_assert_cmpint(body_size, <=, UINT32_MAX - string_size);
+body_size += string_size;
+
+req = v9fs_req_init(v9p, body_size, P9_TMKDIR, tag);
+v9fs_uint32_write(req, dfid);
+v9fs_string_write(req, name);
+v9fs_uint32_write(req, mode);
+v9fs_uint32_write(req, gid);
+v9fs_req_send(req);
+return req;
+}
+
+/* size[4] Rmkdir tag[2] qid[13] */
+static void v9fs_rmkdir(P9Req *req, v9fs_qid *qid)
+{
+v9fs_req_recv(req, P9_RMKDIR);
+if (qid) {
+v9fs_memread(req, qid, 13);
+} else {
+v9fs_memskip(req, 13);
+}
+v9fs_req_free(req);
+}
+
 /* basic readdir test where reply fits into a single response message */
 static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc)
 {
@@ -877,6 +967,30 @@ static void fs_flush_ignored(void *obj, void *data, 
QGuestAllocator *t_alloc)
 g_free(wnames[0]);
 }
 
+static void fs_mkdir(void *obj, void *data, QGuestAllocator *t_alloc,
+ const char *path, const char *cname)
+{
+QVirtio9P *v9p = obj;
+alloc = t_alloc;
+char **wnames;
+char *const name = g_strdup(cname);
+P9Req *req;
+const uint32_t fid = genfid();
+
+int nwnames = split(path, "/", );
+
+req = v9fs_twalk(v9p, 0, fid, nwnames, wnames, 0);
+v9fs_req_wait_for_reply(req, NULL);
+v9fs_rwalk(req, NULL, NULL);
+
+req = v9fs_tmkdir(v9p, fid, name, 0750, 0, 0);
+v9fs_req_wait_for_reply(req, NULL);
+v9fs_rmkdir(req, NULL);
+
+g_free(name);
+split_free();
+}
+
 static void fs_readdir_split_128(void *obj, void *data,
  QGuestAllocator *t_alloc)
 {
@@ -895,6 +1009,30 @@ static void fs_readdir_split_512(void *obj, void *data,
 fs_readdir_split(obj, data, t_alloc, 512);
 }
 
+
+/* tests using the 9pfs 

Re: [PULL v2 00/22] Build system + misc changes for 2020-10-16

2020-10-17 Thread Peter Maydell
On Sat, 17 Oct 2020 at 14:38, Paolo Bonzini  wrote:
> OpenBSD and NetBSD call the ninja package "ninja-build" unlike FreeBSD.
>  I'm sure I had used the right name but well I didn't.  I'll send a v3.

OpenBSD built OK but meson produces this new warning:

Library iconv found: NO
../src/meson.build:531: WARNING: iconv required for curses UI but not
available, disabling

thanks
-- PMM



[PULL 44/44] target/mips: Increase number of TLB entries on the 34Kf core (16 -> 64)

2020-10-17 Thread Philippe Mathieu-Daudé
Per "MIPS32 34K Processor Core Family Software User's Manual,
Revision 01.13" page 8 in "Joint TLB (JTLB)" section:

  "The JTLB is a fully associative TLB cache containing 16, 32,
   or 64-dual-entries mapping up to 128 virtual pages to their
   corresponding physical addresses."

There is no particular reason to restrict the 34Kf core model to
16 TLB entries, so raise its config to 64.

This is helpful for other projects, in particular the Yocto Project:

  Yocto Project uses qemu-system-mips 34Kf cpu model, to run 32bit
  MIPS CI loop. It was observed that in this case CI test execution
  time was almost twice longer than 64bit MIPS variant that runs
  under MIPS64R2-generic model. It was investigated and concluded
  that the difference in number of TLBs 16 in 34Kf case vs 64 in
  MIPS64R2-generic is responsible for most of CI real time execution
  difference. Because with 16 TLBs linux user-land trashes TLB more
  and it needs to execute more instructions in TLB refill handler
  calls, as result it runs much longer.

(https://lists.gnu.org/archive/html/qemu-devel/2020-10/msg03428.html)

Buglink: https://bugzilla.yoctoproject.org/show_bug.cgi?id=13992
Reported-by: Victor Kamensky 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20201016133317.553068-1-f4...@amsat.org>
---
 target/mips/translate_init.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/translate_init.c.inc b/target/mips/translate_init.c.inc
index c735b2bf667..fb5a9b38e5d 100644
--- a/target/mips/translate_init.c.inc
+++ b/target/mips/translate_init.c.inc
@@ -254,7 +254,7 @@ const mips_def_t mips_defs[] =
 .CP0_PRid = 0x00019500,
 .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
(MMU_TYPE_R4000 << CP0C0_MT),
-.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) |
+.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) |
(0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
(0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
(1 << CP0C1_CA),
-- 
2.26.2




[PULL 43/44] MAINTAINERS: Remove duplicated Malta test entries

2020-10-17 Thread Philippe Mathieu-Daudé
The Malta tests are already covered in the Malta section.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Thomas Huth 
Message-Id: <20201013101659.3557154-3-f4...@amsat.org>
---
 MAINTAINERS | 2 --
 1 file changed, 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8770cd6d05a..a7f0acf8663 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -237,8 +237,6 @@ F: include/hw/intc/mips_gic.h
 F: include/hw/mips/
 F: include/hw/misc/mips_*
 F: include/hw/timer/mips_gictimer.h
-F: tests/acceptance/linux_ssh_mips_malta.py
-F: tests/acceptance/machine_mips_malta.py
 F: tests/tcg/mips/
 K: ^Subject:.*(?i)mips
 
-- 
2.26.2




Re: io_uring possibly the culprit for qemu hang (linux-5.4.y)

2020-10-17 Thread Ju Hyung Park
Hi Jens.

On Sat, Oct 17, 2020 at 3:07 AM Jens Axboe  wrote:
>
> Would be great if you could try 5.4.71 and see if that helps for your
> issue.
>

Oh wow, yeah it did fix the issue.

I'm able to reliably turn off and start the VM multiple times in a row.
Double checked by confirming QEMU is dynamically linked to liburing.so.1.

Looks like those 4 io_uring fixes helped.

Thanks!



[PULL 36/44] hw/mips: Rename TYPE_MIPS_BOSTON to TYPE_BOSTON

2020-10-17 Thread Philippe Mathieu-Daudé
From: Eduardo Habkost 

This will make the type name constant consistent with the name of
the type checking macro.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20200902224311.1321159-19-ehabk...@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/mips/boston.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index cf2296f4488..74c18edbb34 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -44,10 +44,10 @@
 #include 
 #include "qom/object.h"
 
-#define TYPE_MIPS_BOSTON "mips-boston"
+#define TYPE_BOSTON "mips-boston"
 typedef struct BostonState BostonState;
 DECLARE_INSTANCE_CHECKER(BostonState, BOSTON,
- TYPE_MIPS_BOSTON)
+ TYPE_BOSTON)
 
 struct BostonState {
 SysBusDevice parent_obj;
@@ -262,7 +262,7 @@ static void mips_boston_instance_init(Object *obj)
 }
 
 static const TypeInfo boston_device = {
-.name  = TYPE_MIPS_BOSTON,
+.name  = TYPE_BOSTON,
 .parent= TYPE_SYS_BUS_DEVICE,
 .instance_size = sizeof(BostonState),
 .instance_init = mips_boston_instance_init,
@@ -455,7 +455,7 @@ static void boston_mach_init(MachineState *machine)
 exit(1);
 }
 
-dev = qdev_new(TYPE_MIPS_BOSTON);
+dev = qdev_new(TYPE_BOSTON);
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
 
 s = BOSTON(dev);
-- 
2.26.2




[PULL v2 0/5] 9p queue (previous 2020-10-15)

2020-10-17 Thread Christian Schoenebeck
The following changes since commit e12ce85b2c79d83a340953291912875c30b3af06:

  Merge remote-tracking branch 'remotes/ehabkost/tags/x86-next-pull-request' 
into staging (2020-10-16 22:46:28 +0100)

are available in the Git repository at:

  https://github.com/cschoenebeck/qemu.git tags/pull-9p-20201017

for you to fetch changes up to fa4551e3f4416cc8c62086ac430b1ceb4f03eb6b:

  tests/9pfs: add local Tmkdir test (2020-10-17 15:58:39 +0200)


9pfs: add tests using local fs driver

The currently existing 9pfs test cases are all solely using the 9pfs 'synth'
fileystem driver, which is a very simple and purely simulated (in RAM only)
filesystem. There are issues though where the 'synth' fs driver is not
sufficient. For example the following two bugs need test cases running the
9pfs 'local' fs driver:

https://bugs.launchpad.net/qemu/+bug/1336794
https://bugs.launchpad.net/qemu/+bug/1877384

This patch set for that reason introduces 9pfs test cases using the 9pfs
'local' filesystem driver along to the already existing tests on 'synth'.


Christian Schoenebeck (5):
  tests/9pfs: change qtest name prefix to synth
  tests/9pfs: introduce local tests
  tests/9pfs: wipe local 9pfs test directory
  tests/9pfs: add virtio_9p_test_path()
  tests/9pfs: add local Tmkdir test

 tests/qtest/libqos/virtio-9p.c | 100 +
 tests/qtest/libqos/virtio-9p.h |  10 +++
 tests/qtest/virtio-9p-test.c   | 197 -
 3 files changed, 286 insertions(+), 21 deletions(-)



[PULL 38/44] tests/acceptance: Add MIPS record/replay tests

2020-10-17 Thread Philippe Mathieu-Daudé
From: Pavel Dovgalyuk 

This patch adds MIPS-targeted acceptance tests for
record/replay functions.

Signed-off-by: Pavel Dovgalyuk 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <160276110297.2705.10918105269658307206.stgit@pasha-ThinkPad-X280>
[PMD: Moved 'override timeout' comment from instance to class,
  moved nanomips tests to ReplayKernelSlow class,
  tagged ReplayKernelSlow class with AVOCADO_TIMEOUT_EXPECTED]
Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/acceptance/replay_kernel.py | 167 +-
 1 file changed, 166 insertions(+), 1 deletion(-)

diff --git a/tests/acceptance/replay_kernel.py 
b/tests/acceptance/replay_kernel.py
index 952f429cace..00c228382bd 100644
--- a/tests/acceptance/replay_kernel.py
+++ b/tests/acceptance/replay_kernel.py
@@ -9,6 +9,8 @@
 # later.  See the COPYING file in the top-level directory.
 
 import os
+import lzma
+import shutil
 import logging
 import time
 
@@ -19,7 +21,7 @@
 from avocado.utils import process
 from boot_linux_console import LinuxKernelTest
 
-class ReplayKernel(LinuxKernelTest):
+class ReplayKernelBase(LinuxKernelTest):
 """
 Boots a Linux kernel in record mode and checks that the console
 is operational and the kernel command line is properly passed
@@ -74,6 +76,7 @@ def run_rr(self, kernel_path, kernel_command_line, 
console_pattern,
 logger = logging.getLogger('replay')
 logger.info('replay overhead {:.2%}'.format(t2 / t1 - 1))
 
+class ReplayKernelNormal(ReplayKernelBase):
 @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
 def test_x86_64_pc(self):
 """
@@ -91,6 +94,51 @@ def test_x86_64_pc(self):
 
 self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
 
+def test_mips_malta(self):
+"""
+:avocado: tags=arch:mips
+:avocado: tags=machine:malta
+:avocado: tags=endian:big
+"""
+deb_url = ('http://snapshot.debian.org/archive/debian/'
+   '20130217T032700Z/pool/main/l/linux-2.6/'
+   'linux-image-2.6.32-5-4kc-malta_2.6.32-48_mips.deb')
+deb_hash = 'a8cfc28ad8f45f54811fc6cf74fc43ffcfe0ba04'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+kernel_path = self.extract_from_deb(deb_path,
+'/boot/vmlinux-2.6.32-5-4kc-malta')
+kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
+console_pattern = 'Kernel command line: %s' % kernel_command_line
+
+self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
+
+def test_mips64el_malta(self):
+"""
+This test requires the ar tool to extract "data.tar.gz" from
+the Debian package.
+
+The kernel can be rebuilt using this Debian kernel source [1] and
+following the instructions on [2].
+
+[1] http://snapshot.debian.org/package/linux-2.6/2.6.32-48/
+#linux-source-2.6.32_2.6.32-48
+[2] https://kernel-team.pages.debian.net/kernel-handbook/
+ch-common-tasks.html#s-common-official
+
+:avocado: tags=arch:mips64el
+:avocado: tags=machine:malta
+"""
+deb_url = ('http://snapshot.debian.org/archive/debian/'
+   '20130217T032700Z/pool/main/l/linux-2.6/'
+   'linux-image-2.6.32-5-5kc-malta_2.6.32-48_mipsel.deb')
+deb_hash = '1aaec92083bf22fda31e0d27fa8d9a388e5fc3d5'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+kernel_path = self.extract_from_deb(deb_path,
+'/boot/vmlinux-2.6.32-5-5kc-malta')
+kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
+console_pattern = 'Kernel command line: %s' % kernel_command_line
+self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
+
 def test_aarch64_virt(self):
 """
 :avocado: tags=arch:aarch64
@@ -302,3 +350,120 @@ def test_xtensa_lx60(self):
 file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
 self.do_test_advcal_2018(file_path, 'santas-sleigh-ride.elf',
  args=('-cpu', 'dc233c'))
+
+@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
+class ReplayKernelSlow(ReplayKernelBase):
+# Override the timeout, because this kernel includes an inner
+# loop which is executed with TB recompilings during replay,
+# making it very slow.
+timeout = 180
+
+def test_mips_malta_cpio(self):
+"""
+:avocado: tags=arch:mips
+:avocado: tags=machine:malta
+:avocado: tags=endian:big
+:avocado: tags=slowness:high
+"""
+deb_url = ('http://snapshot.debian.org/archive/debian/'
+   '20160601T041800Z/pool/main/l/linux/'
+   'linux-image-4.5.0-2-4kc-malta_4.5.5-1_mips.deb')

[PULL 31/44] hw/mips/malta: Fix FPGA I/O region size

2020-10-17 Thread Philippe Mathieu-Daudé
The FPGA present on the CoreCard has an I/O region 1MiB wide.

Refs:
- Atlas User’s Manual (Document Number: MD5)
- Malta User’s Manual (Document Number: MD00048)

Fixes: ea85df72b60 ("mips_malta: convert to memory API")
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20200905213049.761949-1-f4...@amsat.org>
---
 hw/mips/malta.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 1e2b750719e..a4a4c386268 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -578,7 +578,7 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion 
*address_space,
 memory_region_init_alias(>iomem_lo, NULL, "malta-fpga",
  >iomem, 0, 0x900);
 memory_region_init_alias(>iomem_hi, NULL, "malta-fpga",
- >iomem, 0xa00, 0x1 - 0xa00);
+ >iomem, 0xa00, 0x10 - 0xa00);
 
 memory_region_add_subregion(address_space, base, >iomem_lo);
 memory_region_add_subregion(address_space, base + 0xa00, >iomem_hi);
-- 
2.26.2




[PULL 37/44] hw/mips: Remove exit(1) in case of missing ROM

2020-10-17 Thread Philippe Mathieu-Daudé
From: Pavel Dovgalyuk 

This patch updates MIPS-based machines to allow starting them without ROM.
In this case CPU starts to execute instructions from the empty memory,
but QEMU allows introspecting the machine configuration.

Signed-off-by: Pavel Dovgalyuk 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <159531210571.24117.231100997794891819.stgit@pasha-ThinkPad-X280>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/mips/fuloong2e.c |  8 +++-
 hw/mips/jazz.c  |  8 +++-
 hw/mips/malta.c | 11 ---
 hw/mips/mipssim.c   | 10 +++---
 4 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index de66215f95f..a9e0c2f8d30 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -337,10 +337,8 @@ static void mips_fuloong2e_init(MachineState *machine)
 kernel_entry = load_kernel(env);
 write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
 } else {
-if (bios_name == NULL) {
-bios_name = FULOONG_BIOSNAME;
-}
-filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
+  bios_name ?: FULOONG_BIOSNAME);
 if (filename) {
 bios_size = load_image_targphys(filename, 0x1fc0LL,
 BIOS_SIZE);
@@ -350,7 +348,7 @@ static void mips_fuloong2e_init(MachineState *machine)
 }
 
 if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
-!kernel_filename && !qtest_enabled()) {
+bios_name && !qtest_enabled()) {
 error_report("Could not load MIPS bios '%s'", bios_name);
 exit(1);
 }
diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
index 8f1ad55ba34..71448f72ac9 100644
--- a/hw/mips/jazz.c
+++ b/hw/mips/jazz.c
@@ -218,10 +218,7 @@ static void mips_jazz_init(MachineState *machine,
 memory_region_add_subregion(address_space, 0xfff0LL, bios2);
 
 /* load the BIOS image. */
-if (bios_name == NULL) {
-bios_name = BIOS_FILENAME;
-}
-filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name ?: BIOS_FILENAME);
 if (filename) {
 bios_size = load_image_targphys(filename, 0xfff0LL,
 MAGNUM_BIOS_SIZE);
@@ -229,7 +226,8 @@ static void mips_jazz_init(MachineState *machine,
 } else {
 bios_size = -1;
 }
-if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) && !qtest_enabled()) {
+if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE)
+&& bios_name && !qtest_enabled()) {
 error_report("Could not load MIPS bios '%s'", bios_name);
 exit(1);
 }
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index beb0f43941a..9d1a3b50b7a 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -1332,10 +1332,8 @@ void mips_malta_init(MachineState *machine)
 /* Load firmware from flash. */
 if (!dinfo) {
 /* Load a BIOS image. */
-if (bios_name == NULL) {
-bios_name = BIOS_FILENAME;
-}
-filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
+  bios_name ?: BIOS_FILENAME);
 if (filename) {
 bios_size = load_image_targphys(filename, FLASH_ADDRESS,
 BIOS_SIZE);
@@ -1344,9 +1342,8 @@ void mips_malta_init(MachineState *machine)
 bios_size = -1;
 }
 if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
-!kernel_filename && !qtest_enabled()) {
-error_report("Could not load MIPS bios '%s', and no "
- "-kernel argument was specified", bios_name);
+bios_name && !qtest_enabled()) {
+error_report("Could not load MIPS bios '%s'", bios_name);
 exit(1);
 }
 }
diff --git a/hw/mips/mipssim.c b/hw/mips/mipssim.c
index 97dcc232476..aaa62a0f4b7 100644
--- a/hw/mips/mipssim.c
+++ b/hw/mips/mipssim.c
@@ -177,10 +177,7 @@ mips_mipssim_init(MachineState *machine)
 /* Map the BIOS / boot exception handler. */
 memory_region_add_subregion(address_space_mem, 0x1fc0LL, bios);
 /* Load a BIOS / boot exception handler image. */
-if (bios_name == NULL) {
-bios_name = BIOS_FILENAME;
-}
-filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name ?: BIOS_FILENAME);
 if (filename) {
 bios_size = load_image_targphys(filename, 0x1fc0LL, BIOS_SIZE);
 g_free(filename);
@@ -188,10 +185,9 @@ mips_mipssim_init(MachineState *machine)
 bios_size = -1;
 }
 if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
-

[PULL 30/44] target/mips/cpu: Display warning when CPU is used without input clock

2020-10-17 Thread Philippe Mathieu-Daudé
All our QOM users provides an input clock. In order to avoid
avoid future machines added without clock, display a warning.

User-mode emulation use the CP0 timer with the RDHWR instruction
(see commit cdfcad788394) so keep using the fixed 200 MHz clock
without diplaying any warning. Only display it in system-mode
emulation.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-22-f4...@amsat.org>
---
 target/mips/cpu.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 33a9ed5c24b..76d50b00b42 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -19,12 +19,14 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "qapi/error.h"
 #include "cpu.h"
 #include "internal.h"
 #include "kvm_mips.h"
 #include "qemu/module.h"
 #include "sysemu/kvm.h"
+#include "sysemu/qtest.h"
 #include "exec/exec-all.h"
 #include "hw/qdev-properties.h"
 #include "hw/qdev-clock.h"
@@ -158,6 +160,14 @@ static void mips_cpu_realizefn(DeviceState *dev, Error 
**errp)
 Error *local_err = NULL;
 
 if (!clock_get(cpu->clock)) {
+#ifndef CONFIG_USER_ONLY
+if (!qtest_enabled()) {
+g_autofree char *cpu_freq_str = freq_to_str(CPU_FREQ_HZ_DEFAULT);
+
+warn_report("CPU input clock is not connected to any output clock, 
"
+"using default frequency of %s.", cpu_freq_str);
+}
+#endif
 /* Initialize the frequency in case the clock remains unconnected. */
 clock_set_hz(cpu->clock, CPU_FREQ_HZ_DEFAULT);
 }
-- 
2.26.2




[PULL v2 4/5] tests/9pfs: add virtio_9p_test_path()

2020-10-17 Thread Christian Schoenebeck
This new public function virtio_9p_test_path() allows 9pfs
'local' tests to translate a path from guest scope to host
scope. For instance by passing an empty string it would
return the root path on host of the exported 9pfs tree.

Signed-off-by: Christian Schoenebeck 
Message-Id: 

Signed-off-by: Christian Schoenebeck 
---
 tests/qtest/libqos/virtio-9p.c | 6 ++
 tests/qtest/libqos/virtio-9p.h | 5 +
 2 files changed, 11 insertions(+)

diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c
index 8ee2a134bc..d43647b3b7 100644
--- a/tests/qtest/libqos/virtio-9p.c
+++ b/tests/qtest/libqos/virtio-9p.c
@@ -65,6 +65,12 @@ static void remove_local_test_dir(void)
 g_free(cmd);
 }
 
+char *virtio_9p_test_path(const char *path)
+{
+g_assert(local_test_path);
+return concat_path(local_test_path, path);
+}
+
 static void virtio_9p_cleanup(QVirtio9P *interface)
 {
 qvirtqueue_cleanup(interface->vdev->bus, interface->vq, alloc);
diff --git a/tests/qtest/libqos/virtio-9p.h b/tests/qtest/libqos/virtio-9p.h
index 326a603f72..19a4d97454 100644
--- a/tests/qtest/libqos/virtio-9p.h
+++ b/tests/qtest/libqos/virtio-9p.h
@@ -49,4 +49,9 @@ struct QVirtio9PDevice {
  */
 void virtio_9p_assign_local_driver(GString *cmd_line, const char *args);
 
+/**
+ * Returns path on host to the passed guest path. Result must be freed.
+ */
+char *virtio_9p_test_path(const char *path);
+
 #endif
-- 
2.20.1




[PULL 35/44] hw/mips: Simplify code using ROUND_UP(INITRD_PAGE_SIZE)

2020-10-17 Thread Philippe Mathieu-Daudé
Instead of using a INITRD_PAGE_MASK definition, use the
simpler INITRD_PAGE_SIZE one which allows us to simplify
the code by using directly the self-explicit ROUND_UP()
macro.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20200927163943.614604-3-f4...@amsat.org>
---
 include/hw/mips/mips.h | 4 +++-
 hw/mips/fuloong2e.c| 3 +--
 hw/mips/malta.c| 6 +++---
 hw/mips/mipssim.c  | 3 +--
 hw/mips/r4k.c  | 3 +--
 5 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h
index 0af4c3d5d74..6c9c8805f3f 100644
--- a/include/hw/mips/mips.h
+++ b/include/hw/mips/mips.h
@@ -2,8 +2,10 @@
 #define HW_MIPS_H
 /* Definitions for mips board emulation.  */
 
+#include "qemu/units.h"
+
 /* Kernels can be configured with 64KB pages */
-#define INITRD_PAGE_MASK (~((1 << 16) - 1))
+#define INITRD_PAGE_SIZE (64 * KiB)
 
 #include "exec/memory.h"
 
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index b8234f61083..de66215f95f 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -133,8 +133,7 @@ static int64_t load_kernel(CPUMIPSState *env)
 if (loaderparams.initrd_filename) {
 initrd_size = get_image_size(loaderparams.initrd_filename);
 if (initrd_size > 0) {
-initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) &
-INITRD_PAGE_MASK;
+initrd_offset = ROUND_UP(kernel_high, INITRD_PAGE_SIZE);
 if (initrd_offset + initrd_size > ram_size) {
 error_report("memory too small for initial ram disk '%s'",
  loaderparams.initrd_filename);
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index ff3225bb8e3..beb0f43941a 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -1077,9 +1077,9 @@ static int64_t load_kernel(void)
  * the initrd.  It takes at most 128kiB for 2GB RAM and 4kiB
  * pages.
  */
-initrd_offset = (loaderparams.ram_low_size - initrd_size
- - (128 * KiB)
- - ~INITRD_PAGE_MASK) & INITRD_PAGE_MASK;
+initrd_offset = ROUND_UP(loaderparams.ram_low_size
+ - (initrd_size + 128 * KiB),
+ INITRD_PAGE_SIZE);
 if (kernel_high >= initrd_offset) {
 error_report("memory too small for initial ram disk '%s'",
  loaderparams.initrd_filename);
diff --git a/hw/mips/mipssim.c b/hw/mips/mipssim.c
index afef4f2e77a..97dcc232476 100644
--- a/hw/mips/mipssim.c
+++ b/hw/mips/mipssim.c
@@ -90,8 +90,7 @@ static int64_t load_kernel(void)
 if (loaderparams.initrd_filename) {
 initrd_size = get_image_size(loaderparams.initrd_filename);
 if (initrd_size > 0) {
-initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) &
-INITRD_PAGE_MASK;
+initrd_offset = ROUND_UP(kernel_high, INITRD_PAGE_SIZE);
 if (initrd_offset + initrd_size > loaderparams.ram_size) {
 error_report("memory too small for initial ram disk '%s'",
  loaderparams.initrd_filename);
diff --git a/hw/mips/r4k.c b/hw/mips/r4k.c
index 7ee37c49689..38308543421 100644
--- a/hw/mips/r4k.c
+++ b/hw/mips/r4k.c
@@ -115,8 +115,7 @@ static int64_t load_kernel(void)
 if (loaderparams.initrd_filename) {
 initrd_size = get_image_size(loaderparams.initrd_filename);
 if (initrd_size > 0) {
-initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) &
- INITRD_PAGE_MASK;
+initrd_offset = ROUND_UP(kernel_high, INITRD_PAGE_SIZE);
 if (initrd_offset + initrd_size > ram_size) {
 error_report("memory too small for initial ram disk '%s'",
  loaderparams.initrd_filename);
-- 
2.26.2




[PULL 29/44] hw/mips/cps: Do not allow use without input clock

2020-10-17 Thread Philippe Mathieu-Daudé
Now than all QOM users provides the input clock, do not allow
using a CPS without input clock connected.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-21-f4...@amsat.org>
---
 hw/mips/cps.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index af7b58c4bdd..c624821315a 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -74,6 +74,11 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 bool itu_present = false;
 bool saar_present = false;
 
+if (!clock_get(s->clock)) {
+error_setg(errp, "CPS input clock is not connected to an output 
clock");
+return;
+}
+
 for (i = 0; i < s->num_vp; i++) {
 cpu = MIPS_CPU(object_new(s->cpu_type));
 
-- 
2.26.2




[PULL v2 3/5] tests/9pfs: wipe local 9pfs test directory

2020-10-17 Thread Christian Schoenebeck
Before running the first 9pfs test case, make sure the test directory
for running the 9pfs 'local' tests on is entirely empty. For that
reason simply delete the test directory (if any) before (re)creating
it on test suite startup.

Note: The preferable precise behaviour would be the test directory
only being wiped once *before* a test suite run. Right now the test
directory is also wiped at the *end* of a test suite run because
libqos is calling the virtio_9p_register_nodes() callback for some
reason also when a test suite completed. This is suboptimal as
developers cannot immediately see what files and directories the
9pfs local tests created precisely after the test suite completed.
But fortunately the test directory is not wiped if some test failed.
So it is probably not worth it drilling another hole into libqos
for this issue.

Signed-off-by: Christian Schoenebeck 
Message-Id: 

Signed-off-by: Christian Schoenebeck 
---
 tests/qtest/libqos/virtio-9p.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c
index ee331166de..8ee2a134bc 100644
--- a/tests/qtest/libqos/virtio-9p.c
+++ b/tests/qtest/libqos/virtio-9p.c
@@ -53,6 +53,18 @@ static void create_local_test_dir(void)
 g_assert((st.st_mode & S_IFMT) == S_IFDIR);
 }
 
+/* Deletes directory previously created by create_local_test_dir(). */
+static void remove_local_test_dir(void)
+{
+g_assert(local_test_path != NULL);
+char *cmd = g_strdup_printf("rm -r '%s'\n", local_test_path);
+int res = system(cmd);
+if (res < 0) {
+/* ignore error, dummy check to prevent compiler error */
+}
+g_free(cmd);
+}
+
 static void virtio_9p_cleanup(QVirtio9P *interface)
 {
 qvirtqueue_cleanup(interface->vdev->bus, interface->vq, alloc);
@@ -230,6 +242,7 @@ static void virtio_9p_register_nodes(void)
 
 /* make sure test dir for the 'local' tests exists and is clean */
 init_local_test_path();
+remove_local_test_dir();
 create_local_test_dir();
 
 QPCIAddress addr = {
-- 
2.20.1




[PULL 33/44] hw/mips/malta: Use clearer qdev style

2020-10-17 Thread Philippe Mathieu-Daudé
In order to be consistent with the other code base uses,
rewrite slightly how the MIPS_MALTA object is created.
No logical change.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20201012160503.3472140-3-f4...@amsat.org>
---
 hw/mips/malta.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 944045d7701..ff3225bb8e3 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -1235,11 +1235,11 @@ void mips_malta_init(MachineState *machine)
 DriveInfo *dinfo;
 int fl_idx = 0;
 int be;
+MaltaState *s;
+DeviceState *dev;
 
-DeviceState *dev = qdev_new(TYPE_MIPS_MALTA);
-MaltaState *s = MIPS_MALTA(dev);
-
-sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
+s = MIPS_MALTA(qdev_new(TYPE_MIPS_MALTA));
+sysbus_realize_and_unref(SYS_BUS_DEVICE(s), _fatal);
 
 /* create CPU */
 mips_create_cpu(machine, s, _irq, _irq);
-- 
2.26.2




[PULL 28/44] hw/mips/malta: Set CPU frequency to 320 MHz

2020-10-17 Thread Philippe Mathieu-Daudé
The CoreLV card with ID 0x420's CPU clocked at 320 MHz. Create
a 'cpuclk' output clock and connect it to the CPU input clock.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-20-f4...@amsat.org>
---
 hw/mips/malta.c | 19 ---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 4019c9dc1a8..1e2b750719e 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -26,6 +26,7 @@
 #include "qemu/units.h"
 #include "qemu-common.h"
 #include "cpu.h"
+#include "hw/clock.h"
 #include "hw/southbridge/piix.h"
 #include "hw/isa/superio.h"
 #include "hw/char/serial.h"
@@ -57,6 +58,7 @@
 #include "sysemu/kvm.h"
 #include "hw/semihosting/semihost.h"
 #include "hw/mips/cps.h"
+#include "hw/qdev-clock.h"
 
 #define ENVP_ADDR   0x80002000l
 #define ENVP_NB_ENTRIES 16
@@ -94,6 +96,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(MaltaState, MIPS_MALTA)
 struct MaltaState {
 SysBusDevice parent_obj;
 
+Clock *cpuclk;
 MIPSCPSState cps;
 qemu_irq i8259[ISA_NUM_IRQS];
 };
@@ -1159,7 +1162,7 @@ static void main_cpu_reset(void *opaque)
 }
 }
 
-static void create_cpu_without_cps(MachineState *ms,
+static void create_cpu_without_cps(MachineState *ms, MaltaState *s,
qemu_irq *cbus_irq, qemu_irq *i8259_irq)
 {
 CPUMIPSState *env;
@@ -1167,7 +1170,7 @@ static void create_cpu_without_cps(MachineState *ms,
 int i;
 
 for (i = 0; i < ms->smp.cpus; i++) {
-cpu = MIPS_CPU(cpu_create(ms->cpu_type));
+cpu = mips_cpu_create_with_clock(ms->cpu_type, s->cpuclk);
 
 /* Init internal devices */
 cpu_mips_irq_init_cpu(cpu);
@@ -1189,6 +1192,7 @@ static void create_cps(MachineState *ms, MaltaState *s,
 _fatal);
 object_property_set_int(OBJECT(>cps), "num-vp", ms->smp.cpus,
 _fatal);
+qdev_connect_clock_in(DEVICE(>cps), "clk-in", s->cpuclk);
 sysbus_realize(SYS_BUS_DEVICE(>cps), _fatal);
 
 sysbus_mmio_map_overlap(SYS_BUS_DEVICE(>cps), 0, 0, 1);
@@ -1203,7 +1207,7 @@ static void mips_create_cpu(MachineState *ms, MaltaState 
*s,
 if ((ms->smp.cpus > 1) && cpu_supports_cps_smp(ms->cpu_type)) {
 create_cps(ms, s, cbus_irq, i8259_irq);
 } else {
-create_cpu_without_cps(ms, cbus_irq, i8259_irq);
+create_cpu_without_cps(ms, s, cbus_irq, i8259_irq);
 }
 }
 
@@ -1421,10 +1425,19 @@ void mips_malta_init(MachineState *machine)
 pci_vga_init(pci_bus);
 }
 
+static void mips_malta_instance_init(Object *obj)
+{
+MaltaState *s = MIPS_MALTA(obj);
+
+s->cpuclk = qdev_init_clock_out(DEVICE(obj), "cpu-refclk");
+clock_set_hz(s->cpuclk, 32000); /* 320 MHz */
+}
+
 static const TypeInfo mips_malta_device = {
 .name  = TYPE_MIPS_MALTA,
 .parent= TYPE_SYS_BUS_DEVICE,
 .instance_size = sizeof(MaltaState),
+.instance_init = mips_malta_instance_init,
 };
 
 static void mips_malta_machine_init(MachineClass *mc)
-- 
2.26.2




[PULL v2 2/5] tests/9pfs: introduce local tests

2020-10-17 Thread Christian Schoenebeck
This patch introduces 9pfs test cases using the 9pfs 'local'
filesystem driver which reads/writes/creates/deletes real files
and directories.

In this initial version, there is only one local test which actually
only checks if the 9pfs 'local' device was created successfully.

Before the 9pfs 'local' tests are run, a test directory 'qtest-9p-local'
is created (with world rwx permissions) under the current working
directory. At this point that test directory is not auto deleted yet.

Signed-off-by: Christian Schoenebeck 
Message-Id: 
<81fc4b3b6b6c9bf7999e79f5e7cbc364a5f09ddb.1602182956.git.qemu_...@crudebyte.com>
Signed-off-by: Christian Schoenebeck 
---
 tests/qtest/libqos/virtio-9p.c | 81 ++
 tests/qtest/libqos/virtio-9p.h |  5 +++
 tests/qtest/virtio-9p-test.c   | 44 --
 3 files changed, 116 insertions(+), 14 deletions(-)

diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c
index 2e300063e3..ee331166de 100644
--- a/tests/qtest/libqos/virtio-9p.c
+++ b/tests/qtest/libqos/virtio-9p.c
@@ -24,6 +24,34 @@
 #include "qgraph.h"
 
 static QGuestAllocator *alloc;
+static char *local_test_path;
+
+/* Concatenates the passed 2 pathes. Returned result must be freed. */
+static char *concat_path(const char* a, const char* b)
+{
+return g_build_filename(a, b, NULL);
+}
+
+static void init_local_test_path(void)
+{
+char *pwd = g_get_current_dir();
+local_test_path = concat_path(pwd, "qtest-9p-local");
+g_free(pwd);
+}
+
+/* Creates the directory for the 9pfs 'local' filesystem driver to access. */
+static void create_local_test_dir(void)
+{
+struct stat st;
+
+g_assert(local_test_path != NULL);
+mkdir(local_test_path, 0777);
+
+/* ensure test directory exists now ... */
+g_assert(stat(local_test_path, ) == 0);
+/* ... and is actually a directory */
+g_assert((st.st_mode & S_IFMT) == S_IFDIR);
+}
 
 static void virtio_9p_cleanup(QVirtio9P *interface)
 {
@@ -146,11 +174,64 @@ static void *virtio_9p_pci_create(void *pci_bus, 
QGuestAllocator *t_alloc,
 return obj;
 }
 
+/**
+ * Performs regular expression based search and replace on @a haystack.
+ *
+ * @param haystack - input string to be parsed, result of replacement is
+ *   stored back to @a haystack
+ * @param pattern - the regular expression pattern for scanning @a haystack
+ * @param replace_fmt - matches of supplied @a pattern are replaced by this,
+ *  if necessary glib printf format can be used to add
+ *  variable arguments of this function to this
+ *  replacement string
+ */
+static void regex_replace(GString *haystack, const char *pattern,
+  const char *replace_fmt, ...)
+{
+GRegex *regex;
+char *replace, *s;
+va_list argp;
+
+va_start(argp, replace_fmt);
+replace = g_strdup_vprintf(replace_fmt, argp);
+va_end(argp);
+
+regex = g_regex_new(pattern, 0, 0, NULL);
+s = g_regex_replace(regex, haystack->str, -1, 0, replace, 0, NULL);
+g_string_assign(haystack, s);
+g_free(s);
+g_regex_unref(regex);
+g_free(replace);
+}
+
+void virtio_9p_assign_local_driver(GString *cmd_line, const char *args)
+{
+g_assert_nonnull(local_test_path);
+
+/* replace 'synth' driver by 'local' driver */
+regex_replace(cmd_line, "-fsdev synth,", "-fsdev local,");
+
+/* append 'path=...' to '-fsdev ...' group */
+regex_replace(cmd_line, "(-fsdev \\w[^ ]*)", "\\1,path='%s'",
+  local_test_path);
+
+if (!args) {
+return;
+}
+
+/* append passed args to '-fsdev ...' group */
+regex_replace(cmd_line, "(-fsdev \\w[^ ]*)", "\\1,%s", args);
+}
+
 static void virtio_9p_register_nodes(void)
 {
 const char *str_simple = "fsdev=fsdev0,mount_tag=" MOUNT_TAG;
 const char *str_addr = "fsdev=fsdev0,addr=04.0,mount_tag=" MOUNT_TAG;
 
+/* make sure test dir for the 'local' tests exists and is clean */
+init_local_test_path();
+create_local_test_dir();
+
 QPCIAddress addr = {
 .devfn = QPCI_DEVFN(4, 0),
 };
diff --git a/tests/qtest/libqos/virtio-9p.h b/tests/qtest/libqos/virtio-9p.h
index b1e6badc4a..326a603f72 100644
--- a/tests/qtest/libqos/virtio-9p.h
+++ b/tests/qtest/libqos/virtio-9p.h
@@ -44,4 +44,9 @@ struct QVirtio9PDevice {
 QVirtio9P v9p;
 };
 
+/**
+ * Prepares QEMU command line for 9pfs tests using the 'local' fs driver.
+ */
+void virtio_9p_assign_local_driver(GString *cmd_line, const char *args);
+
 #endif
diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c
index 3281153b9c..af7e169d3a 100644
--- a/tests/qtest/virtio-9p-test.c
+++ b/tests/qtest/virtio-9p-test.c
@@ -895,29 +895,45 @@ static void fs_readdir_split_512(void *obj, void *data,
 fs_readdir_split(obj, data, t_alloc, 512);
 }
 
+static void *assign_9p_local_driver(GString *cmd_line, void *arg)
+{
+virtio_9p_assign_local_driver(cmd_line, 

[PULL 26/44] hw/mips/cps: Expose input clock and connect it to CPU cores

2020-10-17 Thread Philippe Mathieu-Daudé
Expose a qdev input clock named 'clk-in', and connect it to each
core to forward-propagate the clock.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-18-f4...@amsat.org>
---
 include/hw/mips/cps.h | 2 ++
 hw/mips/cps.c | 4 
 2 files changed, 6 insertions(+)

diff --git a/include/hw/mips/cps.h b/include/hw/mips/cps.h
index 9e35a881366..859a8d4a674 100644
--- a/include/hw/mips/cps.h
+++ b/include/hw/mips/cps.h
@@ -21,6 +21,7 @@
 #define MIPS_CPS_H
 
 #include "hw/sysbus.h"
+#include "hw/clock.h"
 #include "hw/misc/mips_cmgcr.h"
 #include "hw/intc/mips_gic.h"
 #include "hw/misc/mips_cpc.h"
@@ -43,6 +44,7 @@ struct MIPSCPSState {
 MIPSGICState gic;
 MIPSCPCState cpc;
 MIPSITUState itu;
+Clock *clock;
 };
 
 qemu_irq get_cps_irq(MIPSCPSState *cps, int pin_number);
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 23c0f87e41a..af7b58c4bdd 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -22,6 +22,7 @@
 #include "qemu/module.h"
 #include "hw/mips/cps.h"
 #include "hw/mips/mips.h"
+#include "hw/qdev-clock.h"
 #include "hw/qdev-properties.h"
 #include "hw/mips/cpudevs.h"
 #include "sysemu/kvm.h"
@@ -38,6 +39,7 @@ static void mips_cps_init(Object *obj)
 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 MIPSCPSState *s = MIPS_CPS(obj);
 
+s->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, NULL);
 /*
  * Cover entire address space as there do not seem to be any
  * constraints for the base address of CPC and GIC.
@@ -80,6 +82,8 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
   errp)) {
 return;
 }
+/* All cores use the same clock tree */
+qdev_connect_clock_in(DEVICE(cpu), "clk-in", s->clock);
 
 if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
 return;
-- 
2.26.2




[PULL 32/44] hw/mips/malta: Move gt64120 related code together

2020-10-17 Thread Philippe Mathieu-Daudé
The 'empty_slot' region created is related to the gt64120.
Move its creation close to the gt64120 instance creation.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20201012160503.3472140-2-f4...@amsat.org>
---
 hw/mips/malta.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index a4a4c386268..944045d7701 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -1239,13 +1239,6 @@ void mips_malta_init(MachineState *machine)
 DeviceState *dev = qdev_new(TYPE_MIPS_MALTA);
 MaltaState *s = MIPS_MALTA(dev);
 
-/*
- * The whole address space decoded by the GT-64120A doesn't generate
- * exception when accessing invalid memory. Create an empty slot to
- * emulate this feature.
- */
-empty_slot_init("GT64120", 0, 0x2000);
-
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
 
 /* create CPU */
@@ -1399,6 +1392,12 @@ void mips_malta_init(MachineState *machine)
 
 /* Northbridge */
 pci_bus = gt64120_register(s->i8259);
+/*
+ * The whole address space decoded by the GT-64120A doesn't generate
+ * exception when accessing invalid memory. Create an empty slot to
+ * emulate this feature.
+ */
+empty_slot_init("GT64120", 0, 0x2000);
 
 /* Southbridge */
 dev = piix4_create(pci_bus, _bus, );
-- 
2.26.2




[PULL 24/44] hw/mips/mipssim: Correct CPU frequency

2020-10-17 Thread Philippe Mathieu-Daudé
The MIPSsim machine CPU frequency is too fast running at 200 MHz,
while it should be 12 MHz for the 24K and 6 MHz for the 5K core.

Ref: Linux commit c78cbf49c4ed
("Support for MIPSsim, the cycle accurate MIPS simulator.")

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-16-f4...@amsat.org>
---
 hw/mips/mipssim.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/mips/mipssim.c b/hw/mips/mipssim.c
index 5d4ad74828d..f0042f7f436 100644
--- a/hw/mips/mipssim.c
+++ b/hw/mips/mipssim.c
@@ -29,6 +29,7 @@
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "cpu.h"
+#include "hw/clock.h"
 #include "hw/mips/mips.h"
 #include "hw/mips/cpudevs.h"
 #include "hw/char/serial.h"
@@ -150,13 +151,21 @@ mips_mipssim_init(MachineState *machine)
 MemoryRegion *address_space_mem = get_system_memory();
 MemoryRegion *isa = g_new(MemoryRegion, 1);
 MemoryRegion *bios = g_new(MemoryRegion, 1);
+Clock *cpuclk;
 MIPSCPU *cpu;
 CPUMIPSState *env;
 ResetData *reset_info;
 int bios_size;
 
+cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
+#ifdef TARGET_MIPS64
+clock_set_hz(cpuclk, 600); /* 6 MHz */
+#else
+clock_set_hz(cpuclk, 1200); /* 12 MHz */
+#endif
+
 /* Init CPUs. */
-cpu = MIPS_CPU(cpu_create(machine->cpu_type));
+cpu = mips_cpu_create_with_clock(machine->cpu_type, cpuclk);
 env = >env;
 
 reset_info = g_malloc0(sizeof(ResetData));
-- 
2.26.2




[PULL v2 1/5] tests/9pfs: change qtest name prefix to synth

2020-10-17 Thread Christian Schoenebeck
All existing 9pfs test cases are using the 'synth' fs driver so far, which
means they are not accessing real files, but a purely simulated (in RAM
only) file system.

Let's make this clear by changing the prefix of the individual qtest case
names from 'fs/' to 'synth/'. That way they'll be easily distinguishable
from upcoming new 9pfs test cases supposed to be using a different fs
driver.

Signed-off-by: Christian Schoenebeck 
Message-Id: 

Signed-off-by: Christian Schoenebeck 
---
 tests/qtest/virtio-9p-test.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c
index de30b717b6..3281153b9c 100644
--- a/tests/qtest/virtio-9p-test.c
+++ b/tests/qtest/virtio-9p-test.c
@@ -897,26 +897,26 @@ static void fs_readdir_split_512(void *obj, void *data,
 
 static void register_virtio_9p_test(void)
 {
-qos_add_test("config", "virtio-9p", pci_config, NULL);
-qos_add_test("fs/version/basic", "virtio-9p", fs_version, NULL);
-qos_add_test("fs/attach/basic", "virtio-9p", fs_attach, NULL);
-qos_add_test("fs/walk/basic", "virtio-9p", fs_walk, NULL);
-qos_add_test("fs/walk/no_slash", "virtio-9p", fs_walk_no_slash,
+qos_add_test("synth/config", "virtio-9p", pci_config, NULL);
+qos_add_test("synth/version/basic", "virtio-9p", fs_version, NULL);
+qos_add_test("synth/attach/basic", "virtio-9p", fs_attach, NULL);
+qos_add_test("synth/walk/basic", "virtio-9p", fs_walk, NULL);
+qos_add_test("synth/walk/no_slash", "virtio-9p", fs_walk_no_slash,
  NULL);
-qos_add_test("fs/walk/dotdot_from_root", "virtio-9p",
+qos_add_test("synth/walk/dotdot_from_root", "virtio-9p",
  fs_walk_dotdot, NULL);
-qos_add_test("fs/lopen/basic", "virtio-9p", fs_lopen, NULL);
-qos_add_test("fs/write/basic", "virtio-9p", fs_write, NULL);
-qos_add_test("fs/flush/success", "virtio-9p", fs_flush_success,
+qos_add_test("synth/lopen/basic", "virtio-9p", fs_lopen, NULL);
+qos_add_test("synth/write/basic", "virtio-9p", fs_write, NULL);
+qos_add_test("synth/flush/success", "virtio-9p", fs_flush_success,
  NULL);
-qos_add_test("fs/flush/ignored", "virtio-9p", fs_flush_ignored,
+qos_add_test("synth/flush/ignored", "virtio-9p", fs_flush_ignored,
  NULL);
-qos_add_test("fs/readdir/basic", "virtio-9p", fs_readdir, NULL);
-qos_add_test("fs/readdir/split_512", "virtio-9p",
+qos_add_test("synth/readdir/basic", "virtio-9p", fs_readdir, NULL);
+qos_add_test("synth/readdir/split_512", "virtio-9p",
  fs_readdir_split_512, NULL);
-qos_add_test("fs/readdir/split_256", "virtio-9p",
+qos_add_test("synth/readdir/split_256", "virtio-9p",
  fs_readdir_split_256, NULL);
-qos_add_test("fs/readdir/split_128", "virtio-9p",
+qos_add_test("synth/readdir/split_128", "virtio-9p",
  fs_readdir_split_128, NULL);
 }
 
-- 
2.20.1




[PULL 27/44] hw/mips/boston: Set CPU frequency to 1 GHz

2020-10-17 Thread Philippe Mathieu-Daudé
The I6400 can run at 1 GHz or more. Create a 'cpuclk'
output clock and connect it to the CPU input clock.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-19-f4...@amsat.org>
---
 hw/mips/boston.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index 1b3f69e949c..cf2296f4488 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -30,6 +30,7 @@
 #include "hw/mips/cps.h"
 #include "hw/mips/cpudevs.h"
 #include "hw/pci-host/xilinx-pcie.h"
+#include "hw/qdev-clock.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
@@ -54,6 +55,7 @@ struct BostonState {
 MachineState *mach;
 MIPSCPSState cps;
 SerialMM *uart;
+Clock *cpuclk;
 
 CharBackend lcd_display;
 char lcd_content[8];
@@ -251,10 +253,19 @@ static const MemoryRegionOps boston_platreg_ops = {
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+static void mips_boston_instance_init(Object *obj)
+{
+BostonState *s = BOSTON(obj);
+
+s->cpuclk = qdev_init_clock_out(DEVICE(obj), "cpu-refclk");
+clock_set_hz(s->cpuclk, 10); /* 1 GHz */
+}
+
 static const TypeInfo boston_device = {
 .name  = TYPE_MIPS_BOSTON,
 .parent= TYPE_SYS_BUS_DEVICE,
 .instance_size = sizeof(BostonState),
+.instance_init = mips_boston_instance_init,
 };
 
 static void boston_register_types(void)
@@ -462,6 +473,8 @@ static void boston_mach_init(MachineState *machine)
 _fatal);
 object_property_set_int(OBJECT(>cps), "num-vp", machine->smp.cpus,
 _fatal);
+qdev_connect_clock_in(DEVICE(>cps), "clk-in",
+  qdev_get_clock_out(dev, "cpu-refclk"));
 sysbus_realize(SYS_BUS_DEVICE(>cps), _fatal);
 
 sysbus_mmio_map_overlap(SYS_BUS_DEVICE(>cps), 0, 0, 1);
-- 
2.26.2




[PULL 21/44] target/mips/cpu: Introduce mips_cpu_create_with_clock() helper

2020-10-17 Thread Philippe Mathieu-Daudé
Introduce an helper to create a MIPS CPU and connect it to
a reference clock. This helper is not MIPS specific, but so
far only MIPS CPUs need it.

Suggested-by: Huacai Chen 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-13-f4...@amsat.org>
---
 target/mips/cpu.h | 12 
 target/mips/cpu.c | 12 
 2 files changed, 24 insertions(+)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 062a4ba6225..d41579d44ae 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1307,4 +1307,16 @@ static inline void cpu_get_tb_cpu_state(CPUMIPSState 
*env, target_ulong *pc,
 MIPS_HFLAG_HWRENA_ULR);
 }
 
+/**
+ * mips_cpu_create_with_clock:
+ * @typename: a MIPS CPU type.
+ * @cpu_refclk: this cpu input clock (an output clock of another device)
+ *
+ * Instantiates a MIPS CPU, set the input clock of the CPU to @cpu_refclk,
+ * then realizes the CPU.
+ *
+ * Returns: A #CPUState or %NULL if an error occurred.
+ */
+MIPSCPU *mips_cpu_create_with_clock(const char *cpu_type, Clock *cpu_refclk);
+
 #endif /* MIPS_CPU_H */
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 2a6f4840e20..33a9ed5c24b 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -288,3 +288,15 @@ static void mips_cpu_register_types(void)
 }
 
 type_init(mips_cpu_register_types)
+
+/* Could be used by generic CPU object */
+MIPSCPU *mips_cpu_create_with_clock(const char *cpu_type, Clock *cpu_refclk)
+{
+DeviceState *cpu;
+
+cpu = DEVICE(object_new(cpu_type));
+qdev_connect_clock_in(cpu, "clk-in", cpu_refclk);
+qdev_realize(cpu, NULL, _abort);
+
+return MIPS_CPU(cpu);
+}
-- 
2.26.2




[PULL 23/44] hw/mips/fuloong2e: Set CPU frequency to 533 MHz

2020-10-17 Thread Philippe Mathieu-Daudé
The CPU frequency is normally provided by the firmware in the
"cpuclock" environment variable. The 2E board can handles up
to 660MHz, but be conservative and take the same value used
by the Linux kernel: 533 MHz.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Jiaxun Yang 
Message-Id: <20201012095804.3335117-15-f4...@amsat.org>
---
 hw/mips/fuloong2e.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index b000ed1d7f7..b8234f61083 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -23,6 +23,7 @@
 #include "qemu/units.h"
 #include "qapi/error.h"
 #include "cpu.h"
+#include "hw/clock.h"
 #include "hw/intc/i8259.h"
 #include "hw/dma/i8257.h"
 #include "hw/isa/superio.h"
@@ -298,12 +299,16 @@ static void mips_fuloong2e_init(MachineState *machine)
 PCIBus *pci_bus;
 ISABus *isa_bus;
 I2CBus *smbus;
+Clock *cpuclk;
 MIPSCPU *cpu;
 CPUMIPSState *env;
 DeviceState *dev;
 
+cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
+clock_set_hz(cpuclk, 53308); /* ~533 MHz */
+
 /* init CPUs */
-cpu = MIPS_CPU(cpu_create(machine->cpu_type));
+cpu = mips_cpu_create_with_clock(machine->cpu_type, cpuclk);
 env = >env;
 
 qemu_register_reset(main_cpu_reset, cpu);
-- 
2.26.2




[PULL 22/44] hw/mips/r4k: Explicit CPU frequency is 200 MHz

2020-10-17 Thread Philippe Mathieu-Daudé
Since its introduction in commit 6af0bf9c7c3,
the 'r4k' machine runs at 200 MHz.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-14-f4...@amsat.org>
---
 hw/mips/r4k.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/mips/r4k.c b/hw/mips/r4k.c
index 3487013a4a1..39bc626e7c5 100644
--- a/hw/mips/r4k.c
+++ b/hw/mips/r4k.c
@@ -13,6 +13,7 @@
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "cpu.h"
+#include "hw/clock.h"
 #include "hw/mips/mips.h"
 #include "hw/mips/cpudevs.h"
 #include "hw/intc/i8259.h"
@@ -182,6 +183,7 @@ void mips_r4k_init(MachineState *machine)
 MemoryRegion *isa_io = g_new(MemoryRegion, 1);
 MemoryRegion *isa_mem = g_new(MemoryRegion, 1);
 int bios_size;
+Clock *cpuclk;
 MIPSCPU *cpu;
 CPUMIPSState *env;
 ResetData *reset_info;
@@ -192,8 +194,11 @@ void mips_r4k_init(MachineState *machine)
 DriveInfo *dinfo;
 int be;
 
+cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
+clock_set_hz(cpuclk, 2); /* 200 MHz */
+
 /* init CPUs */
-cpu = MIPS_CPU(cpu_create(machine->cpu_type));
+cpu = mips_cpu_create_with_clock(machine->cpu_type, cpuclk);
 env = >env;
 
 reset_info = g_malloc0(sizeof(ResetData));
-- 
2.26.2




[PULL 20/44] target/mips/cpu: Allow the CPU to use dynamic frequencies

2020-10-17 Thread Philippe Mathieu-Daudé
Use the Clock API and let the CPU object have an input clock.

If no clock is connected, keep using the default frequency of
200 MHz used since the introduction of the 'r4k' machine in
commit 6af0bf9c7c3.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-12-f4...@amsat.org>
---
 target/mips/cpu.h |  4 
 target/mips/cpu.c | 11 +--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index baeceb892ef..062a4ba6225 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -4,6 +4,7 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat-types.h"
+#include "hw/clock.h"
 #include "mips-defs.h"
 
 #define TCG_GUEST_DEFAULT_MO (0)
@@ -1151,6 +1152,8 @@ struct CPUMIPSState {
 /**
  * MIPSCPU:
  * @env: #CPUMIPSState
+ * @clock: this CPU input clock (may be connected
+ * to an output clock from another device).
  * @cp0_count_rate: rate at which the coprocessor 0 counter increments
  *
  * A MIPS CPU.
@@ -1160,6 +1163,7 @@ struct MIPSCPU {
 CPUState parent_obj;
 /*< public >*/
 
+Clock *clock;
 CPUNegativeOffsetState neg;
 CPUMIPSState env;
 /*
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 461edfe22b7..2a6f4840e20 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -27,6 +27,7 @@
 #include "sysemu/kvm.h"
 #include "exec/exec-all.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-clock.h"
 
 static void mips_cpu_set_pc(CPUState *cs, vaddr value)
 {
@@ -144,8 +145,9 @@ static void mips_cp0_period_set(MIPSCPU *cpu)
 {
 CPUMIPSState *env = >env;
 
-env->cp0_count_ns = muldiv64(NANOSECONDS_PER_SECOND, cpu->cp0_count_rate,
- CPU_FREQ_HZ_DEFAULT);
+env->cp0_count_ns = cpu->cp0_count_rate
+* clock_get_ns(MIPS_CPU(cpu)->clock);
+assert(env->cp0_count_ns);
 }
 
 static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
@@ -155,6 +157,10 @@ static void mips_cpu_realizefn(DeviceState *dev, Error 
**errp)
 MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(dev);
 Error *local_err = NULL;
 
+if (!clock_get(cpu->clock)) {
+/* Initialize the frequency in case the clock remains unconnected. */
+clock_set_hz(cpu->clock, CPU_FREQ_HZ_DEFAULT);
+}
 mips_cp0_period_set(cpu);
 
 cpu_exec_realizefn(cs, _err);
@@ -178,6 +184,7 @@ static void mips_cpu_initfn(Object *obj)
 MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(obj);
 
 cpu_set_cpustate_pointers(cpu);
+cpu->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, cpu);
 env->cpu_model = mcc->cpu_def;
 }
 
-- 
2.26.2




[PULL 40/44] MAINTAINERS: Remove myself

2020-10-17 Thread Philippe Mathieu-Daudé
From: Aleksandar Markovic 

I have been working on project other than QEMU for some time, and would
like to devote myself to that project. It is impossible for me to find
enough time to perform maintainer's duties with needed meticulousness
and patience.

I wish prosperous future to QEMU and all colleagues in QEMU community.

Signed-off-by: Aleksandar Markovic 
Message-Id: <1602103041-32017-6-git-send-email-aleksandar.qemu.de...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS | 17 +
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 99ab02bbab3..b91bd754d16 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -220,11 +220,10 @@ F: hw/microblaze/
 F: disas/microblaze.c
 
 MIPS TCG CPUs
-M: Aleksandar Markovic 
 R: Aurelien Jarno 
 R: Jiaxun Yang 
 R: Aleksandar Rikalo 
-S: Maintained
+S: Orphaned
 F: target/mips/
 F: default-configs/*mips*
 F: disas/*mips*
@@ -386,7 +385,6 @@ F: target/arm/kvm.c
 
 MIPS KVM CPUs
 M: Huacai Chen 
-M: Aleksandar Markovic 
 S: Odd Fixes
 F: target/mips/kvm.c
 
@@ -1123,10 +1121,9 @@ F: hw/display/jazz_led.c
 F: hw/dma/rc4030.c
 
 Malta
-M: Aleksandar Markovic 
 M: Philippe Mathieu-Daudé 
 R: Aurelien Jarno 
-S: Maintained
+S: Odd Fixes
 F: hw/isa/piix4.c
 F: hw/acpi/piix4.c
 F: hw/mips/malta.c
@@ -1136,14 +1133,12 @@ F: tests/acceptance/linux_ssh_mips_malta.py
 F: tests/acceptance/machine_mips_malta.py
 
 Mipssim
-M: Aleksandar Markovic 
 R: Aleksandar Rikalo 
-S: Odd Fixes
+S: Orphaned
 F: hw/mips/mipssim.c
 F: hw/net/mipsnet.c
 
 R4000
-M: Aleksandar Markovic 
 R: Aurelien Jarno 
 R: Aleksandar Rikalo 
 S: Obsolete
@@ -1152,7 +1147,6 @@ F: hw/mips/r4k.c
 Fuloong 2E
 M: Huacai Chen 
 M: Philippe Mathieu-Daudé 
-M: Aleksandar Markovic 
 R: Jiaxun Yang 
 S: Odd Fixes
 F: hw/mips/fuloong2e.c
@@ -2823,12 +2817,11 @@ F: tcg/i386/
 F: disas/i386.c
 
 MIPS TCG target
-M: Aleksandar Markovic 
 R: Aurelien Jarno 
 R: Huacai Chen 
 R: Jiaxun Yang 
 R: Aleksandar Rikalo 
-S: Maintained
+S: Orphaned
 F: tcg/mips/
 
 PPC TCG target
@@ -3169,7 +3162,7 @@ S: Odd Fixes
 F: scripts/git-submodule.sh
 
 UI translations
-M: Aleksandar Markovic 
+S: Orphaned
 F: po/*.po
 
 Sphinx documentation configuration and build machinery
-- 
2.26.2




[PULL 17/44] target/mips: Move cp0_count_ns to CPUMIPSState

2020-10-17 Thread Philippe Mathieu-Daudé
Currently the CP0 timer period is fixed at 10 ns, corresponding
to a fixed CPU frequency of 200 MHz (using half the speed of the
CPU).

In few commits we will be able to use a different CPU frequency.
In preparation, move the cp0_count_ns variable to CPUMIPSState
so we can modify it.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Jiaxun Yang 
Message-Id: <20201012095804.3335117-9-f4...@amsat.org>
---
 target/mips/cpu.h   |  1 +
 target/mips/cp0_timer.c | 23 ++-
 target/mips/cpu.c   | 21 +
 3 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 7cf7f5239f7..085a88e9550 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1145,6 +1145,7 @@ struct CPUMIPSState {
 struct MIPSITUState *itu;
 MemoryRegion *itc_tag; /* ITC Configuration Tags */
 target_ulong exception_base; /* ExceptionBase input to the core */
+uint64_t cp0_count_ns; /* CP0_Count clock period (in nanoseconds) */
 };
 
 /**
diff --git a/target/mips/cp0_timer.c b/target/mips/cp0_timer.c
index 6fec5fe0ff7..5ec0d6249e9 100644
--- a/target/mips/cp0_timer.c
+++ b/target/mips/cp0_timer.c
@@ -27,18 +27,6 @@
 #include "sysemu/kvm.h"
 #include "internal.h"
 
-/*
- * Since commit 6af0bf9c7c3 this model assumes a CPU clocked at 200MHz
- * and a CP0 timer running at half the clock of the CPU (cp0_count_rate = 2).
- *
- * TIMER_FREQ_HZ = CPU_FREQ_HZ / CP0_COUNT_RATE = 200 MHz / 2 = 100 MHz
- *
- * TIMER_PERIOD_NS = 1 / TIMER_FREQ_HZ = 10 ns
- */
-#define CPU_FREQ_HZ_DEFAULT 2
-#define CP0_COUNT_RATE_DEFAULT  2
-#define TIMER_PERIOD10  /* 1 / (CPU_FREQ_HZ / CP0_COUNT_RATE) */
-
 /* MIPS R4K timer */
 static void cpu_mips_timer_update(CPUMIPSState *env)
 {
@@ -47,8 +35,8 @@ static void cpu_mips_timer_update(CPUMIPSState *env)
 
 now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 wait = env->CP0_Compare - env->CP0_Count -
-   (uint32_t)(now_ns / TIMER_PERIOD);
-next_ns = now_ns + (uint64_t)wait * TIMER_PERIOD;
+   (uint32_t)(now_ns / env->cp0_count_ns);
+next_ns = now_ns + (uint64_t)wait * env->cp0_count_ns;
 timer_mod(env->timer, next_ns);
 }
 
@@ -76,7 +64,7 @@ uint32_t cpu_mips_get_count(CPUMIPSState *env)
 cpu_mips_timer_expire(env);
 }
 
-return env->CP0_Count + (uint32_t)(now_ns / TIMER_PERIOD);
+return env->CP0_Count + (uint32_t)(now_ns / env->cp0_count_ns);
 }
 }
 
@@ -92,7 +80,8 @@ void cpu_mips_store_count(CPUMIPSState *env, uint32_t count)
 } else {
 /* Store new count register */
 env->CP0_Count = count -
-   (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 
TIMER_PERIOD);
+   (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
+  env->cp0_count_ns);
 /* Update timer timer */
 cpu_mips_timer_update(env);
 }
@@ -119,7 +108,7 @@ void cpu_mips_stop_count(CPUMIPSState *env)
 {
 /* Store the current value */
 env->CP0_Count += (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
- TIMER_PERIOD);
+ env->cp0_count_ns);
 }
 
 static void mips_timer_cb(void *opaque)
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index e86cd065483..84b727fefa8 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -134,6 +134,25 @@ static void mips_cpu_disas_set_info(CPUState *s, 
disassemble_info *info)
 }
 }
 
+/*
+ * Since commit 6af0bf9c7c3 this model assumes a CPU clocked at 200MHz
+ * and a CP0 timer running at half the clock of the CPU (cp0_count_rate = 2).
+ *
+ * TIMER_FREQ_HZ = CPU_FREQ_HZ / CP0_COUNT_RATE = 200 MHz / 2 = 100 MHz
+ *
+ * TIMER_PERIOD_NS = 1 / TIMER_FREQ_HZ = 10 ns
+ */
+#define CPU_FREQ_HZ_DEFAULT 2
+#define CP0_COUNT_RATE_DEFAULT  2
+#define TIMER_PERIOD_DEFAULT10  /* 1 / (CPU_FREQ_HZ / CP0_COUNT_RATE) */
+
+static void mips_cp0_period_set(MIPSCPU *cpu)
+{
+CPUMIPSState *env = >env;
+
+env->cp0_count_ns = TIMER_PERIOD_DEFAULT;
+}
+
 static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
 {
 CPUState *cs = CPU(dev);
@@ -141,6 +160,8 @@ static void mips_cpu_realizefn(DeviceState *dev, Error 
**errp)
 MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(dev);
 Error *local_err = NULL;
 
+mips_cp0_period_set(cpu);
+
 cpu_exec_realizefn(cs, _err);
 if (local_err != NULL) {
 error_propagate(errp, local_err);
-- 
2.26.2




[PULL 16/44] target/mips/cp0_timer: Document TIMER_PERIOD origin

2020-10-17 Thread Philippe Mathieu-Daudé
TIMER_PERIOD value of '10 ns' can be explained looking at
commit 6af0bf9c7c3doc, where the CPU frequency is 200 MHz
and CP0 default count rate is half the frequency of the
CPU. Document that.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-8-f4...@amsat.org>
---
 target/mips/cp0_timer.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/target/mips/cp0_timer.c b/target/mips/cp0_timer.c
index 5194c967ae3..6fec5fe0ff7 100644
--- a/target/mips/cp0_timer.c
+++ b/target/mips/cp0_timer.c
@@ -27,7 +27,17 @@
 #include "sysemu/kvm.h"
 #include "internal.h"
 
-#define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */
+/*
+ * Since commit 6af0bf9c7c3 this model assumes a CPU clocked at 200MHz
+ * and a CP0 timer running at half the clock of the CPU (cp0_count_rate = 2).
+ *
+ * TIMER_FREQ_HZ = CPU_FREQ_HZ / CP0_COUNT_RATE = 200 MHz / 2 = 100 MHz
+ *
+ * TIMER_PERIOD_NS = 1 / TIMER_FREQ_HZ = 10 ns
+ */
+#define CPU_FREQ_HZ_DEFAULT 2
+#define CP0_COUNT_RATE_DEFAULT  2
+#define TIMER_PERIOD10  /* 1 / (CPU_FREQ_HZ / CP0_COUNT_RATE) */
 
 /* MIPS R4K timer */
 static void cpu_mips_timer_update(CPUMIPSState *env)
-- 
2.26.2




[PULL 39/44] docs/system: Update MIPS CPU documentation

2020-10-17 Thread Philippe Mathieu-Daudé
From: Huacai Chen 

Add Loongson-3A CPU models description.

Signed-off-by: Huacai Chen 
Message-Id: <1602059975-10115-10-git-send-email-che...@lemote.com>
[PMD: Split patch in 2: CPU / machine]
Signed-off-by: Philippe Mathieu-Daudé 
---
 docs/system/cpu-models-mips.rst.inc | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/docs/system/cpu-models-mips.rst.inc 
b/docs/system/cpu-models-mips.rst.inc
index 499b5b6fedb..02cc4bb884c 100644
--- a/docs/system/cpu-models-mips.rst.inc
+++ b/docs/system/cpu-models-mips.rst.inc
@@ -48,11 +48,17 @@ across all desired hosts.
 ``I6400``
 MIPS64 Processor (Release 6, 2014)
 
+``Loongson-2E``
+MIPS64 Processor (Loongson 2, 2006)
+
 ``Loongson-2F``
 MIPS64 Processor (Loongson 2, 2008)
 
-``Loongson-2E``
-MIPS64 Processor (Loongson 2, 2006)
+``Loongson-3A1000``
+MIPS64 Processor (Loongson 3, 2010)
+
+``Loongson-3A4000``
+MIPS64 Processor (Loongson 3, 2018)
 
 ``mips64dspr2``
 MIPS64 Processor (Release 2, 2006)
-- 
2.26.2




[PULL 42/44] MAINTAINERS: Downgrade MIPS Boston to 'Odd Fixes', fix Paul Burton mail

2020-10-17 Thread Philippe Mathieu-Daudé
Paul's Wavecomp email has been bouncing for months. He told us
he "no longer has access to modern MIPS CPUs or Boston hardware,
and wouldn't currently have time to spend on them if he did." [1]
but "perhaps that might change in the future." [2].
Be fair and downgrade the status of the Boston board to "Odd Fixes"
(has a maintainer but they don't have time to do much other).
Similarly to commit 2b107c2c1c (".mailmap: Update Paul Burton email
address"), update his email address here too.

[1] https://www.mail-archive.com/qemu-devel@nongnu.org/msg718739.html
[2] https://www.mail-archive.com/qemu-devel@nongnu.org/msg728605.html

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Thomas Huth 
Message-Id: <20201013101659.3557154-4-f4...@amsat.org>
---
 MAINTAINERS | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 50fb9fda34d..8770cd6d05a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1162,9 +1162,9 @@ S: Maintained
 F: hw/intc/loongson_liointc.c
 
 Boston
-M: Paul Burton 
+M: Paul Burton 
 R: Aleksandar Rikalo 
-S: Maintained
+S: Odd Fixes
 F: hw/core/loader-fit.c
 F: hw/mips/boston.c
 F: hw/pci-host/xilinx-pcie.c
-- 
2.26.2




[PULL 15/44] target/mips/cp0_timer: Explicit unit in variable name

2020-10-17 Thread Philippe Mathieu-Daudé
Name variables holding nanoseconds with the '_ns' suffix.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Message-Id: <20201012095804.3335117-7-f4...@amsat.org>
---
 target/mips/cp0_timer.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/target/mips/cp0_timer.c b/target/mips/cp0_timer.c
index 9c38e9da1c8..5194c967ae3 100644
--- a/target/mips/cp0_timer.c
+++ b/target/mips/cp0_timer.c
@@ -32,13 +32,14 @@
 /* MIPS R4K timer */
 static void cpu_mips_timer_update(CPUMIPSState *env)
 {
-uint64_t now, next;
+uint64_t now_ns, next_ns;
 uint32_t wait;
 
-now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-wait = env->CP0_Compare - env->CP0_Count - (uint32_t)(now / TIMER_PERIOD);
-next = now + (uint64_t)wait * TIMER_PERIOD;
-timer_mod(env->timer, next);
+now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+wait = env->CP0_Compare - env->CP0_Count -
+   (uint32_t)(now_ns / TIMER_PERIOD);
+next_ns = now_ns + (uint64_t)wait * TIMER_PERIOD;
+timer_mod(env->timer, next_ns);
 }
 
 /* Expire the timer.  */
@@ -56,16 +57,16 @@ uint32_t cpu_mips_get_count(CPUMIPSState *env)
 if (env->CP0_Cause & (1 << CP0Ca_DC)) {
 return env->CP0_Count;
 } else {
-uint64_t now;
+uint64_t now_ns;
 
-now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 if (timer_pending(env->timer)
-&& timer_expired(env->timer, now)) {
+&& timer_expired(env->timer, now_ns)) {
 /* The timer has already expired.  */
 cpu_mips_timer_expire(env);
 }
 
-return env->CP0_Count + (uint32_t)(now / TIMER_PERIOD);
+return env->CP0_Count + (uint32_t)(now_ns / TIMER_PERIOD);
 }
 }
 
-- 
2.26.2




[PULL 11/44] target/mips/op_helper: Convert multiple if() to switch case

2020-10-17 Thread Philippe Mathieu-Daudé
The cache operation is encoded in bits [20:18] of the instruction.
The 'op' argument of helper_cache() contains the bits [20:16].
Extract the 3 bits and parse them using a switch case. This allow
us to handle multiple cache types (the cache type is encoded in
bits [17:16]).

Previously the if() block was only checking the D-Cache (Primary
Data or Unified Primary). Now we also handle the I-Cache (Primary
Instruction), S-Cache (Secondary) and T-Cache (Terciary).

Reported-by: Jiaxun Yang 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Jiaxun Yang 
Message-Id: <20200813181527.22551-2-f4...@amsat.org>
---
 target/mips/op_helper.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 9552b280e07..c15f5c07761 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -1574,15 +1574,20 @@ void helper_msa_st_d(CPUMIPSState *env, uint32_t wd,
 void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op)
 {
 #ifndef CONFIG_USER_ONLY
+uint32_t cache_operation = extract32(op, 2, 3);
 target_ulong index = addr & 0x1fff;
-if (op == 9) {
-/* Index Store Tag */
+
+switch (cache_operation) {
+case 0b010: /* Index Store Tag */
 memory_region_dispatch_write(env->itc_tag, index, env->CP0_TagLo,
  MO_64, MEMTXATTRS_UNSPECIFIED);
-} else if (op == 5) {
-/* Index Load Tag */
+break;
+case 0b001: /* Index Load Tag */
 memory_region_dispatch_read(env->itc_tag, index, >CP0_TagLo,
 MO_64, MEMTXATTRS_UNSPECIFIED);
+break;
+default:
+break;
 }
 #endif
 }
-- 
2.26.2




[PULL 34/44] hw/mips: Simplify loading 64-bit ELF kernels

2020-10-17 Thread Philippe Mathieu-Daudé
Since 82790064116 ("Cast ELF datatypes properly to host 64bit types")
we don't need to sign-extend the entry_point address. Remove this
unnecessary code.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20200927163943.614604-2-f4...@amsat.org>
---
 hw/mips/mipssim.c | 6 +-
 hw/mips/r4k.c | 6 +-
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/hw/mips/mipssim.c b/hw/mips/mipssim.c
index f0042f7f436..afef4f2e77a 100644
--- a/hw/mips/mipssim.c
+++ b/hw/mips/mipssim.c
@@ -77,11 +77,7 @@ static int64_t load_kernel(void)
(uint64_t *), NULL,
(uint64_t *)_high, NULL, big_endian,
EM_MIPS, 1, 0);
-if (kernel_size >= 0) {
-if ((entry & ~0x7fffULL) == 0x8000) {
-entry = (int32_t)entry;
-}
-} else {
+if (kernel_size < 0) {
 error_report("could not load kernel '%s': %s",
  loaderparams.kernel_filename,
  load_elf_strerror(kernel_size));
diff --git a/hw/mips/r4k.c b/hw/mips/r4k.c
index 39bc626e7c5..7ee37c49689 100644
--- a/hw/mips/r4k.c
+++ b/hw/mips/r4k.c
@@ -102,11 +102,7 @@ static int64_t load_kernel(void)
(uint64_t *), NULL,
(uint64_t *)_high, NULL, big_endian,
EM_MIPS, 1, 0);
-if (kernel_size >= 0) {
-if ((entry & ~0x7fffULL) == 0x8000) {
-entry = (int32_t)entry;
-}
-} else {
+if (kernel_size < 0) {
 error_report("could not load kernel '%s': %s",
  loaderparams.kernel_filename,
  load_elf_strerror(kernel_size));
-- 
2.26.2




[PULL 08/44] target/mips: Add loongson-ext lswc2 group of instructions (Part 1)

2020-10-17 Thread Philippe Mathieu-Daudé
From: Jiaxun Yang 

LWC2 & SWC2 have been rewritten by Loongson EXT vendor ASE
as "load/store quad word" and "shifted load/store" groups of
instructions.

This patch add implementation of these instructions:

  gslq: load 16 bytes to GPR
  gssq: store 16 bytes from GPR
  gslqc1: load 16 bytes to FPR
  gssqc1: store 16 bytes from FPR

Details of Loongson-EXT is here:
https://github.com/FlyGoat/loongson-insn/blob/master/loongson-ext.md

Signed-off-by: Jiaxun Yang 
Signed-off-by: Huacai Chen 
Message-Id: <1602831120-3377-3-git-send-email-che...@lemote.com>
[PMD: Restrict t1 variable to TARGET_MIPS64, remove unused t2/fp0]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c | 86 +
 1 file changed, 86 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index b4d009078e0..e83954d782f 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -460,6 +460,17 @@ enum {
 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
 };
 
+/* Loongson EXT load/store quad word opcodes */
+#define MASK_LOONGSON_GSLSQ(op)   (MASK_OP_MAJOR(op) | (op & 0x8020))
+enum {
+OPC_GSLQ= 0x0020 | OPC_LWC2,
+OPC_GSLQC1  = 0x8020 | OPC_LWC2,
+OPC_GSSHFL  = OPC_LWC2,
+OPC_GSSQ= 0x0020 | OPC_SWC2,
+OPC_GSSQC1  = 0x8020 | OPC_SWC2,
+OPC_GSSHFS  = OPC_SWC2,
+};
+
 /* BSHFL opcodes */
 #define MASK_BSHFL(op)  (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 
@@ -5910,6 +5921,79 @@ no_rd:
 tcg_temp_free_i64(t1);
 }
 
+static void gen_loongson_lswc2(DisasContext *ctx, int rt,
+   int rs, int rd)
+{
+TCGv t0;
+#if defined(TARGET_MIPS64)
+TCGv t1;
+int lsq_rt1 = ctx->opcode & 0x1f;
+int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
+#endif
+
+t0 = tcg_temp_new();
+
+switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
+#if defined(TARGET_MIPS64)
+case OPC_GSLQ:
+t1 = tcg_temp_new();
+gen_base_offset_addr(ctx, t0, rs, lsq_offset);
+tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
+   ctx->default_tcg_memop_mask);
+gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
+tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
+   ctx->default_tcg_memop_mask);
+gen_store_gpr(t1, rt);
+gen_store_gpr(t0, lsq_rt1);
+tcg_temp_free(t1);
+break;
+case OPC_GSLQC1:
+check_cp1_enabled(ctx);
+t1 = tcg_temp_new();
+gen_base_offset_addr(ctx, t0, rs, lsq_offset);
+tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
+   ctx->default_tcg_memop_mask);
+gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
+tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
+   ctx->default_tcg_memop_mask);
+gen_store_fpr64(ctx, t1, rt);
+gen_store_fpr64(ctx, t0, lsq_rt1);
+tcg_temp_free(t1);
+break;
+case OPC_GSSQ:
+t1 = tcg_temp_new();
+gen_base_offset_addr(ctx, t0, rs, lsq_offset);
+gen_load_gpr(t1, rt);
+tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
+   ctx->default_tcg_memop_mask);
+gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
+gen_load_gpr(t1, lsq_rt1);
+tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
+   ctx->default_tcg_memop_mask);
+tcg_temp_free(t1);
+break;
+case OPC_GSSQC1:
+check_cp1_enabled(ctx);
+t1 = tcg_temp_new();
+gen_base_offset_addr(ctx, t0, rs, lsq_offset);
+gen_load_fpr64(ctx, t1, rt);
+tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
+   ctx->default_tcg_memop_mask);
+gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
+gen_load_fpr64(ctx, t1, lsq_rt1);
+tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
+   ctx->default_tcg_memop_mask);
+tcg_temp_free(t1);
+break;
+#endif
+default:
+MIPS_INVAL("loongson_gslsq");
+generate_exception_end(ctx, EXCP_RI);
+break;
+}
+tcg_temp_free(t0);
+}
+
 /* Traps */
 static void gen_trap(DisasContext *ctx, uint32_t opc,
  int rs, int rt, int16_t imm)
@@ -30774,6 +30858,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext 
*ctx)
 /* OPC_BC, OPC_BALC */
 gen_compute_compact_branch(ctx, op, 0, 0,
sextract32(ctx->opcode << 2, 0, 28));
+} else if (ctx->insn_flags & ASE_LEXT) {
+gen_loongson_lswc2(ctx, rt, rs, rd);
 } else {
 /* OPC_LWC2, OPC_SWC2 */
 /* COP2: Not implemented. */
-- 
2.26.2




[PULL 14/44] target/mips: Move cpu_mips_get_random() with CP0 helpers

2020-10-17 Thread Philippe Mathieu-Daudé
The get_random() helper uses the CP0_Wired register, which is
unrelated to the CP0_Count register used as timer.
Commit e16fe40c872 ("Move the MIPS CPU timer in a separate file")
incorrectly moved this get_random() helper with timer specific
code. Move it back to generic CP0 helpers.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Reviewed-by: Luc Michel 
Message-Id: <20201012095804.3335117-6-f4...@amsat.org>
---
 target/mips/internal.h   |  2 +-
 target/mips/cp0_helper.c | 25 +
 target/mips/cp0_timer.c  | 25 -
 3 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/target/mips/internal.h b/target/mips/internal.h
index b811f547f38..dd8a7809b64 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -144,6 +144,7 @@ void r4k_helper_tlbr(CPUMIPSState *env);
 void r4k_helper_tlbinv(CPUMIPSState *env);
 void r4k_helper_tlbinvf(CPUMIPSState *env);
 void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra);
+uint32_t cpu_mips_get_random(CPUMIPSState *env);
 
 void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
 vaddr addr, unsigned size,
@@ -209,7 +210,6 @@ void cpu_state_reset(CPUMIPSState *s);
 void cpu_mips_realize_env(CPUMIPSState *env);
 
 /* cp0_timer.c */
-uint32_t cpu_mips_get_random(CPUMIPSState *env);
 uint32_t cpu_mips_get_count(CPUMIPSState *env);
 void cpu_mips_store_count(CPUMIPSState *env, uint32_t value);
 void cpu_mips_store_compare(CPUMIPSState *env, uint32_t value);
diff --git a/target/mips/cp0_helper.c b/target/mips/cp0_helper.c
index de64add038b..12143ac55b9 100644
--- a/target/mips/cp0_helper.c
+++ b/target/mips/cp0_helper.c
@@ -203,6 +203,31 @@ static void sync_c0_entryhi(CPUMIPSState *cpu, int tc)
 *tcst |= asid;
 }
 
+/* XXX: do not use a global */
+uint32_t cpu_mips_get_random(CPUMIPSState *env)
+{
+static uint32_t seed = 1;
+static uint32_t prev_idx;
+uint32_t idx;
+uint32_t nb_rand_tlb = env->tlb->nb_tlb - env->CP0_Wired;
+
+if (nb_rand_tlb == 1) {
+return env->tlb->nb_tlb - 1;
+}
+
+/* Don't return same value twice, so get another value */
+do {
+/*
+ * Use a simple algorithm of Linear Congruential Generator
+ * from ISO/IEC 9899 standard.
+ */
+seed = 1103515245 * seed + 12345;
+idx = (seed >> 16) % nb_rand_tlb + env->CP0_Wired;
+} while (idx == prev_idx);
+prev_idx = idx;
+return idx;
+}
+
 /* CP0 helpers */
 target_ulong helper_mfc0_mvpcontrol(CPUMIPSState *env)
 {
diff --git a/target/mips/cp0_timer.c b/target/mips/cp0_timer.c
index bd7efb152dd..9c38e9da1c8 100644
--- a/target/mips/cp0_timer.c
+++ b/target/mips/cp0_timer.c
@@ -29,31 +29,6 @@
 
 #define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */
 
-/* XXX: do not use a global */
-uint32_t cpu_mips_get_random(CPUMIPSState *env)
-{
-static uint32_t seed = 1;
-static uint32_t prev_idx = 0;
-uint32_t idx;
-uint32_t nb_rand_tlb = env->tlb->nb_tlb - env->CP0_Wired;
-
-if (nb_rand_tlb == 1) {
-return env->tlb->nb_tlb - 1;
-}
-
-/* Don't return same value twice, so get another value */
-do {
-/*
- * Use a simple algorithm of Linear Congruential Generator
- * from ISO/IEC 9899 standard.
- */
-seed = 1103515245 * seed + 12345;
-idx = (seed >> 16) % nb_rand_tlb + env->CP0_Wired;
-} while (idx == prev_idx);
-prev_idx = idx;
-return idx;
-}
-
 /* MIPS R4K timer */
 static void cpu_mips_timer_update(CPUMIPSState *env)
 {
-- 
2.26.2




[PULL 41/44] MAINTAINERS: Put myself forward for MIPS target

2020-10-17 Thread Philippe Mathieu-Daudé
To avoid the MIPS target being orphan, volunteer to keep an eye
on it and put together pull requests.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Jiaxun Yang 
Reviewed-by: Thomas Huth 
Message-Id: <20201013101659.3557154-2-f4...@amsat.org>
---
 MAINTAINERS | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index b91bd754d16..50fb9fda34d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -220,10 +220,11 @@ F: hw/microblaze/
 F: disas/microblaze.c
 
 MIPS TCG CPUs
+M: Philippe Mathieu-Daudé 
 R: Aurelien Jarno 
 R: Jiaxun Yang 
 R: Aleksandar Rikalo 
-S: Orphaned
+S: Odd Fixes
 F: target/mips/
 F: default-configs/*mips*
 F: disas/*mips*
@@ -2817,11 +2818,12 @@ F: tcg/i386/
 F: disas/i386.c
 
 MIPS TCG target
+M: Philippe Mathieu-Daudé 
 R: Aurelien Jarno 
 R: Huacai Chen 
 R: Jiaxun Yang 
 R: Aleksandar Rikalo 
-S: Orphaned
+S: Odd Fixes
 F: tcg/mips/
 
 PPC TCG target
-- 
2.26.2




[PULL 25/44] hw/mips/jazz: Correct CPU frequencies

2020-10-17 Thread Philippe Mathieu-Daudé
The Magnum 4000PC CPU runs at 100 MHz, and the Acer PICA-61
CPU at ~134 MHz.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-17-f4...@amsat.org>
---
 hw/mips/jazz.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
index 47723093b63..8f1ad55ba34 100644
--- a/hw/mips/jazz.c
+++ b/hw/mips/jazz.c
@@ -24,6 +24,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu-common.h"
+#include "hw/clock.h"
 #include "hw/mips/mips.h"
 #include "hw/mips/cpudevs.h"
 #include "hw/intc/i8259.h"
@@ -142,6 +143,7 @@ static void mips_jazz_init(MachineState *machine,
 MemoryRegion *address_space = get_system_memory();
 char *filename;
 int bios_size, n;
+Clock *cpuclk;
 MIPSCPU *cpu;
 CPUClass *cc;
 CPUMIPSState *env;
@@ -163,14 +165,25 @@ static void mips_jazz_init(MachineState *machine,
 MemoryRegion *bios2 = g_new(MemoryRegion, 1);
 SysBusESPState *sysbus_esp;
 ESPState *esp;
+static const struct {
+unsigned freq_hz;
+unsigned pll_mult;
+} ext_clk[] = {
+[JAZZ_MAGNUM] = {5000, 2},
+[JAZZ_PICA61] = {, 4},
+};
 
 if (machine->ram_size > 256 * MiB) {
 error_report("RAM size more than 256Mb is not supported");
 exit(EXIT_FAILURE);
 }
 
+cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
+clock_set_hz(cpuclk, ext_clk[jazz_model].freq_hz
+ * ext_clk[jazz_model].pll_mult);
+
 /* init CPUs */
-cpu = MIPS_CPU(cpu_create(machine->cpu_type));
+cpu = mips_cpu_create_with_clock(machine->cpu_type, cpuclk);
 env = >env;
 qemu_register_reset(main_cpu_reset, cpu);
 
-- 
2.26.2




[PULL 13/44] target/mips/op_helper: Log unimplemented cache opcode

2020-10-17 Thread Philippe Mathieu-Daudé
In case the guest uses a cache opcode we are not expecting,
log it to give us a chance to notice it, in case we should
actually do something.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Jiaxun Yang 
Message-Id: <20200813181527.22551-4-f4...@amsat.org>
---
 target/mips/op_helper.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 2496d1dd718..0050d0616b6 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -1574,6 +1574,13 @@ void helper_msa_st_d(CPUMIPSState *env, uint32_t wd,
 void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op)
 {
 #ifndef CONFIG_USER_ONLY
+static const char *const type_name[] = {
+"Primary Instruction",
+"Primary Data or Unified Primary",
+"Tertiary",
+"Secondary"
+};
+uint32_t cache_type = extract32(op, 0, 2);
 uint32_t cache_operation = extract32(op, 2, 3);
 target_ulong index = addr & 0x1fff;
 
@@ -1592,6 +1599,8 @@ void helper_cache(CPUMIPSState *env, target_ulong addr, 
uint32_t op)
 /* no-op */
 break;
 default:
+qemu_log_mask(LOG_UNIMP, "cache operation:%u (type: %s cache)\n",
+  cache_operation, type_name[cache_type]);
 break;
 }
 #endif
-- 
2.26.2




[PULL 12/44] target/mips/op_helper: Document Invalidate/Writeback opcodes as no-op

2020-10-17 Thread Philippe Mathieu-Daudé
QEMU does not model caches, so there is not much to do with the
Invalidate/Writeback opcodes. Make it explicit adding a comment.

Suggested-by: Jiaxun Yang 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Jiaxun Yang 
Message-Id: <20200813181527.22551-3-f4...@amsat.org>
---
 target/mips/op_helper.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index c15f5c07761..2496d1dd718 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -1586,6 +1586,11 @@ void helper_cache(CPUMIPSState *env, target_ulong addr, 
uint32_t op)
 memory_region_dispatch_read(env->itc_tag, index, >CP0_TagLo,
 MO_64, MEMTXATTRS_UNSPECIFIED);
 break;
+case 0b000: /* Index Invalidate */
+case 0b100: /* Hit Invalidate */
+case 0b110: /* Hit Writeback */
+/* no-op */
+break;
 default:
 break;
 }
-- 
2.26.2




[PULL 06/44] target/mips: Demacro helpers for MF.

2020-10-17 Thread Philippe Mathieu-Daudé
From: Aleksandar Markovic 

Remove function definitions via macros to achieve better code clarity.

Signed-off-by: Aleksandar Markovic 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <1602103041-32017-3-git-send-email-aleksandar.qemu.de...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/fpu_helper.c | 63 +---
 1 file changed, 46 insertions(+), 17 deletions(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index f851723f22d..b3c715494a9 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -1666,25 +1666,54 @@ uint64_t helper_float_nmsub_ps(CPUMIPSState *env, 
uint64_t fdt0,
 }
 
 
-#define FLOAT_FMADDSUB(name, bits, muladd_arg)  \
-uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \
- uint ## bits ## _t fs, \
- uint ## bits ## _t ft, \
- uint ## bits ## _t fd) \
-{   \
-uint ## bits ## _t fdret;   \
-\
-fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg,\
- >active_fpu.fp_status);   \
-update_fcr31(env, GETPC()); \
-return fdret;   \
+uint32_t helper_float_maddf_s(CPUMIPSState *env, uint32_t fs,
+  uint32_t ft, uint32_t fd)
+{
+uint32_t fdret;
+
+fdret = float32_muladd(fs, ft, fd, 0,
+   >active_fpu.fp_status);
+
+update_fcr31(env, GETPC());
+return fdret;
+}
+
+uint64_t helper_float_maddf_d(CPUMIPSState *env, uint64_t fs,
+  uint64_t ft, uint64_t fd)
+{
+uint64_t fdret;
+
+fdret = float64_muladd(fs, ft, fd, 0,
+   >active_fpu.fp_status);
+
+update_fcr31(env, GETPC());
+return fdret;
+}
+
+uint32_t helper_float_msubf_s(CPUMIPSState *env, uint32_t fs,
+  uint32_t ft, uint32_t fd)
+{
+uint32_t fdret;
+
+fdret = float32_muladd(fs, ft, fd, float_muladd_negate_product,
+   >active_fpu.fp_status);
+
+update_fcr31(env, GETPC());
+return fdret;
+}
+
+uint64_t helper_float_msubf_d(CPUMIPSState *env, uint64_t fs,
+  uint64_t ft, uint64_t fd)
+{
+uint64_t fdret;
+
+fdret = float64_muladd(fs, ft, fd, float_muladd_negate_product,
+   >active_fpu.fp_status);
+
+update_fcr31(env, GETPC());
+return fdret;
 }
 
-FLOAT_FMADDSUB(maddf_s, 32, 0)
-FLOAT_FMADDSUB(maddf_d, 64, 0)
-FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_product)
-FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_product)
-#undef FLOAT_FMADDSUB
 
 /* compare operations */
 #define FOP_COND_D(op, cond)   \
-- 
2.26.2




[PULL 19/44] target/mips/cpu: Make cp0_count_rate a property

2020-10-17 Thread Philippe Mathieu-Daudé
Since not all CPU implementations use a cores use a CP0 timer
at half the frequency of the CPU, make this variable a property.

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201012095804.3335117-11-f4...@amsat.org>
---
 target/mips/cpu.h |  9 +
 target/mips/cpu.c | 19 +++
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 085a88e9550..baeceb892ef 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1151,6 +1151,7 @@ struct CPUMIPSState {
 /**
  * MIPSCPU:
  * @env: #CPUMIPSState
+ * @cp0_count_rate: rate at which the coprocessor 0 counter increments
  *
  * A MIPS CPU.
  */
@@ -1161,6 +1162,14 @@ struct MIPSCPU {
 
 CPUNegativeOffsetState neg;
 CPUMIPSState env;
+/*
+ * The Count register acts as a timer, incrementing at a constant rate,
+ * whether or not an instruction is executed, retired, or any forward
+ * progress is made through the pipeline. The rate at which the counter
+ * increments is implementation dependent, and is a function of the
+ * pipeline clock of the processor, not the issue width of the processor.
+ */
+unsigned cp0_count_rate;
 };
 
 
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 46188139b7b..461edfe22b7 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -26,7 +26,7 @@
 #include "qemu/module.h"
 #include "sysemu/kvm.h"
 #include "exec/exec-all.h"
-
+#include "hw/qdev-properties.h"
 
 static void mips_cpu_set_pc(CPUState *cs, vaddr value)
 {
@@ -135,12 +135,7 @@ static void mips_cpu_disas_set_info(CPUState *s, 
disassemble_info *info)
 }
 
 /*
- * Since commit 6af0bf9c7c3 this model assumes a CPU clocked at 200MHz
- * and a CP0 timer running at half the clock of the CPU (cp0_count_rate = 2).
- *
- * TIMER_FREQ_HZ = CPU_FREQ_HZ / CP0_COUNT_RATE = 200 MHz / 2 = 100 MHz
- *
- * TIMER_PERIOD_NS = 1 / TIMER_FREQ_HZ = 10 ns
+ * Since commit 6af0bf9c7c3 this model assumes a CPU clocked at 200MHz.
  */
 #define CPU_FREQ_HZ_DEFAULT 2
 #define CP0_COUNT_RATE_DEFAULT  2
@@ -149,7 +144,7 @@ static void mips_cp0_period_set(MIPSCPU *cpu)
 {
 CPUMIPSState *env = >env;
 
-env->cp0_count_ns = muldiv64(NANOSECONDS_PER_SECOND, 
CP0_COUNT_RATE_DEFAULT,
+env->cp0_count_ns = muldiv64(NANOSECONDS_PER_SECOND, cpu->cp0_count_rate,
  CPU_FREQ_HZ_DEFAULT);
 }
 
@@ -202,6 +197,13 @@ static ObjectClass *mips_cpu_class_by_name(const char 
*cpu_model)
 return oc;
 }
 
+static Property mips_cpu_properties[] = {
+/* CP0 timer running at half the clock of the CPU */
+DEFINE_PROP_UINT32("cp0-count-rate", MIPSCPU, cp0_count_rate,
+   CP0_COUNT_RATE_DEFAULT),
+DEFINE_PROP_END_OF_LIST()
+};
+
 static void mips_cpu_class_init(ObjectClass *c, void *data)
 {
 MIPSCPUClass *mcc = MIPS_CPU_CLASS(c);
@@ -211,6 +213,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 device_class_set_parent_realize(dc, mips_cpu_realizefn,
 >parent_realize);
 device_class_set_parent_reset(dc, mips_cpu_reset, >parent_reset);
+device_class_set_props(dc, mips_cpu_properties);
 
 cc->class_by_name = mips_cpu_class_by_name;
 cc->has_work = mips_cpu_has_work;
-- 
2.26.2




[PULL 03/44] hw/core/clock: Add the clock_new helper function

2020-10-17 Thread Philippe Mathieu-Daudé
From: Luc Michel 

This function creates a clock and parents it to another object with a
given name. It calls clock_setup_canonical_path before returning the
new clock.

This function is useful to create clocks in devices when one doesn't
want to expose it at the qdev level (as an input or an output).

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Luc Michel 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20201010135759.437903-4-...@lmichel.fr>
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/clock.h | 13 +
 hw/core/clock.c| 15 +++
 2 files changed, 28 insertions(+)

diff --git a/include/hw/clock.h b/include/hw/clock.h
index d357594df99..cbc5e6ced1e 100644
--- a/include/hw/clock.h
+++ b/include/hw/clock.h
@@ -90,6 +90,19 @@ extern const VMStateDescription vmstate_clock;
  */
 void clock_setup_canonical_path(Clock *clk);
 
+/**
+ * clock_new:
+ * @parent: the clock parent
+ * @name: the clock object name
+ *
+ * Helper function to create a new clock and parent it to @parent. There is no
+ * need to call clock_setup_canonical_path on the returned clock as it is done
+ * by this function.
+ *
+ * @return the newly created clock
+ */
+Clock *clock_new(Object *parent, const char *name);
+
 /**
  * clock_set_callback:
  * @clk: the clock to register the callback into
diff --git a/hw/core/clock.c b/hw/core/clock.c
index 7066282f7b9..f866717a835 100644
--- a/hw/core/clock.c
+++ b/hw/core/clock.c
@@ -23,6 +23,21 @@ void clock_setup_canonical_path(Clock *clk)
 clk->canonical_path = object_get_canonical_path(OBJECT(clk));
 }
 
+Clock *clock_new(Object *parent, const char *name)
+{
+Object *obj;
+Clock *clk;
+
+obj = object_new(TYPE_CLOCK);
+object_property_add_child(parent, name, obj);
+object_unref(obj);
+
+clk = CLOCK(obj);
+clock_setup_canonical_path(clk);
+
+return clk;
+}
+
 void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque)
 {
 clk->callback = cb;
-- 
2.26.2




[PULL 05/44] target/mips: Demacro helpers for .

2020-10-17 Thread Philippe Mathieu-Daudé
From: Aleksandar Markovic 

Remove function definitions via macros to achieve better code clarity.

Signed-off-by: Aleksandar Markovic 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <1602103041-32017-2-git-send-email-aleksandar.qemu.de...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/fpu_helper.c | 59 ++--
 1 file changed, 39 insertions(+), 20 deletions(-)

diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index 56beda49d82..f851723f22d 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -983,27 +983,46 @@ uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, 
uint32_t fst0)
 }
 
 /* unary operations, not modifying fp status  */
-#define FLOAT_UNOP(name)   \
-uint64_t helper_float_ ## name ## _d(uint64_t fdt0)\
-{  \
-return float64_ ## name(fdt0); \
-}  \
-uint32_t helper_float_ ## name ## _s(uint32_t fst0)\
-{  \
-return float32_ ## name(fst0); \
-}  \
-uint64_t helper_float_ ## name ## _ps(uint64_t fdt0)   \
-{  \
-uint32_t wt0;  \
-uint32_t wth0; \
-   \
-wt0 = float32_ ## name(fdt0 & 0X); \
-wth0 = float32_ ## name(fdt0 >> 32);   \
-return ((uint64_t)wth0 << 32) | wt0;   \
+
+uint64_t helper_float_abs_d(uint64_t fdt0)
+{
+   return float64_abs(fdt0);
+}
+
+uint32_t helper_float_abs_s(uint32_t fst0)
+{
+return float32_abs(fst0);
+}
+
+uint64_t helper_float_abs_ps(uint64_t fdt0)
+{
+uint32_t wt0;
+uint32_t wth0;
+
+wt0 = float32_abs(fdt0 & 0X);
+wth0 = float32_abs(fdt0 >> 32);
+return ((uint64_t)wth0 << 32) | wt0;
+}
+
+uint64_t helper_float_chs_d(uint64_t fdt0)
+{
+   return float64_chs(fdt0);
+}
+
+uint32_t helper_float_chs_s(uint32_t fst0)
+{
+return float32_chs(fst0);
+}
+
+uint64_t helper_float_chs_ps(uint64_t fdt0)
+{
+uint32_t wt0;
+uint32_t wth0;
+
+wt0 = float32_chs(fdt0 & 0X);
+wth0 = float32_chs(fdt0 >> 32);
+return ((uint64_t)wth0 << 32) | wt0;
 }
-FLOAT_UNOP(abs)
-FLOAT_UNOP(chs)
-#undef FLOAT_UNOP
 
 /* MIPS specific unary operations */
 uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
-- 
2.26.2




[PULL 18/44] target/mips/cpu: Calculate the CP0 timer period using the CPU frequency

2020-10-17 Thread Philippe Mathieu-Daudé
The CP0 timer period is a function of the CPU frequency.
Start using the default values, which will be replaced by
properties in the next commits.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Jiaxun Yang 
Message-Id: <20201012095804.3335117-10-f4...@amsat.org>
---
 target/mips/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 84b727fefa8..46188139b7b 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -144,13 +144,13 @@ static void mips_cpu_disas_set_info(CPUState *s, 
disassemble_info *info)
  */
 #define CPU_FREQ_HZ_DEFAULT 2
 #define CP0_COUNT_RATE_DEFAULT  2
-#define TIMER_PERIOD_DEFAULT10  /* 1 / (CPU_FREQ_HZ / CP0_COUNT_RATE) */
 
 static void mips_cp0_period_set(MIPSCPU *cpu)
 {
 CPUMIPSState *env = >env;
 
-env->cp0_count_ns = TIMER_PERIOD_DEFAULT;
+env->cp0_count_ns = muldiv64(NANOSECONDS_PER_SECOND, 
CP0_COUNT_RATE_DEFAULT,
+ CPU_FREQ_HZ_DEFAULT);
 }
 
 static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
-- 
2.26.2




[PULL 09/44] target/mips: Add loongson-ext lswc2 group of instructions (Part 2)

2020-10-17 Thread Philippe Mathieu-Daudé
From: Jiaxun Yang 

LWC2 & SWC2 have been rewritten by Loongson EXT vendor ASE
as "load/store quad word" and "shifted load/store" groups of
instructions.

This patch add implementation of these instructions:

  gslwlc1: similar to lwl but RT is FPR instead of GPR
  gslwrc1: similar to lwr but RT is FPR instead of GPR
  gsldlc1: similar to ldl but RT is FPR instead of GPR
  gsldrc1: similar to ldr but RT is FPR instead of GPR
  gsswlc1: similar to swl but RT is FPR instead of GPR
  gsswrc1: similar to swr but RT is FPR instead of GPR
  gssdlc1: similar to sdl but RT is FPR instead of GPR
  gssdrc1: similar to sdr but RT is FPR instead of GPR

Details of Loongson-EXT is here:
https://github.com/FlyGoat/loongson-insn/blob/master/loongson-ext.md

Signed-off-by: Jiaxun Yang 
Signed-off-by: Huacai Chen 
Message-Id: <1602831120-3377-4-git-send-email-che...@lemote.com>
[PMD: Reuse t1 on MIPS32, reintroduce t2/fp0]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c | 182 +++-
 1 file changed, 180 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index e83954d782f..b335645e03b 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -471,6 +471,19 @@ enum {
 OPC_GSSHFS  = OPC_SWC2,
 };
 
+/* Loongson EXT shifted load/store opcodes */
+#define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
+enum {
+OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
+OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
+OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
+OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
+OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
+OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
+OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
+OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
+};
+
 /* BSHFL opcodes */
 #define MASK_BSHFL(op)  (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 
@@ -5924,12 +5937,13 @@ no_rd:
 static void gen_loongson_lswc2(DisasContext *ctx, int rt,
int rs, int rd)
 {
-TCGv t0;
+TCGv t0, t1, t2;
+TCGv_i32 fp0;
 #if defined(TARGET_MIPS64)
-TCGv t1;
 int lsq_rt1 = ctx->opcode & 0x1f;
 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
 #endif
+int shf_offset = sextract32(ctx->opcode, 6, 8);
 
 t0 = tcg_temp_new();
 
@@ -5986,6 +6000,170 @@ static void gen_loongson_lswc2(DisasContext *ctx, int 
rt,
 tcg_temp_free(t1);
 break;
 #endif
+case OPC_GSSHFL:
+switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
+case OPC_GSLWLC1:
+check_cp1_enabled(ctx);
+gen_base_offset_addr(ctx, t0, rs, shf_offset);
+t1 = tcg_temp_new();
+tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+tcg_gen_andi_tl(t1, t0, 3);
+#ifndef TARGET_WORDS_BIGENDIAN
+tcg_gen_xori_tl(t1, t1, 3);
+#endif
+tcg_gen_shli_tl(t1, t1, 3);
+tcg_gen_andi_tl(t0, t0, ~3);
+tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
+tcg_gen_shl_tl(t0, t0, t1);
+t2 = tcg_const_tl(-1);
+tcg_gen_shl_tl(t2, t2, t1);
+fp0 = tcg_temp_new_i32();
+gen_load_fpr32(ctx, fp0, rt);
+tcg_gen_ext_i32_tl(t1, fp0);
+tcg_gen_andc_tl(t1, t1, t2);
+tcg_temp_free(t2);
+tcg_gen_or_tl(t0, t0, t1);
+tcg_temp_free(t1);
+#if defined(TARGET_MIPS64)
+tcg_gen_extrl_i64_i32(fp0, t0);
+#else
+tcg_gen_ext32s_tl(fp0, t0);
+#endif
+gen_store_fpr32(ctx, fp0, rt);
+tcg_temp_free_i32(fp0);
+break;
+case OPC_GSLWRC1:
+check_cp1_enabled(ctx);
+gen_base_offset_addr(ctx, t0, rs, shf_offset);
+t1 = tcg_temp_new();
+tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+tcg_gen_andi_tl(t1, t0, 3);
+#ifdef TARGET_WORDS_BIGENDIAN
+tcg_gen_xori_tl(t1, t1, 3);
+#endif
+tcg_gen_shli_tl(t1, t1, 3);
+tcg_gen_andi_tl(t0, t0, ~3);
+tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
+tcg_gen_shr_tl(t0, t0, t1);
+tcg_gen_xori_tl(t1, t1, 31);
+t2 = tcg_const_tl(0xfffeull);
+tcg_gen_shl_tl(t2, t2, t1);
+fp0 = tcg_temp_new_i32();
+gen_load_fpr32(ctx, fp0, rt);
+tcg_gen_ext_i32_tl(t1, fp0);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_temp_free(t2);
+tcg_gen_or_tl(t0, t0, t1);
+tcg_temp_free(t1);
+#if defined(TARGET_MIPS64)
+tcg_gen_extrl_i64_i32(fp0, t0);
+#else
+tcg_gen_ext32s_tl(fp0, t0);
+#endif
+gen_store_fpr32(ctx, fp0, rt);
+tcg_temp_free_i32(fp0);
+break;
+#if defined(TARGET_MIPS64)
+case OPC_GSLDLC1:
+check_cp1_enabled(ctx);
+gen_base_offset_addr(ctx, t0, rs, shf_offset);
+t1 = tcg_temp_new();
+

[PULL 01/44] util/cutils: Introduce freq_to_str() to display Hertz units

2020-10-17 Thread Philippe Mathieu-Daudé
Introduce freq_to_str() to convert frequency values in human
friendly units using the SI units for Hertz.

Suggested-by: Luc Michel 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Reviewed-by: Luc Michel 
Message-Id: <20201012095804.3335117-2-f4...@amsat.org>
---
 include/qemu/cutils.h | 12 
 util/cutils.c | 14 ++
 2 files changed, 26 insertions(+)

diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index 3a86ec0321e..4bbf4834ea5 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -158,6 +158,18 @@ int qemu_strtosz_metric(const char *nptr, const char 
**end, uint64_t *result);
 
 char *size_to_str(uint64_t val);
 
+/**
+ * freq_to_str:
+ * @freq_hz: frequency to stringify
+ *
+ * Return human readable string for frequency @freq_hz.
+ * Use SI units like KHz, MHz, and so forth.
+ *
+ * The caller is responsible for releasing the value returned
+ * with g_free() after use.
+ */
+char *freq_to_str(uint64_t freq_hz);
+
 /* used to print char* safely */
 #define STR_OR_NULL(str) ((str) ? (str) : "null")
 
diff --git a/util/cutils.c b/util/cutils.c
index 8da34e04b0b..be4e43a9eff 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -885,6 +885,20 @@ char *size_to_str(uint64_t val)
 return g_strdup_printf("%0.3g %sB", (double)val / div, suffixes[i]);
 }
 
+char *freq_to_str(uint64_t freq_hz)
+{
+static const char *const suffixes[] = { "", "K", "M", "G", "T", "P", "E" };
+double freq = freq_hz;
+size_t idx = 0;
+
+while (freq >= 1000.0 && idx < ARRAY_SIZE(suffixes)) {
+freq /= 1000.0;
+idx++;
+}
+
+return g_strdup_printf("%0.3g %sHz", freq, suffixes[idx]);
+}
+
 int qemu_pstrcmp0(const char **str1, const char **str2)
 {
 return g_strcmp0(*str1, *str2);
-- 
2.26.2




  1   2   >