Re: [PATCH] riscv: Add semihosting support [v8]

2020-10-23 Thread Keith Packard
Alistair Francis  writes:

Thanks much for taking time to review this patch in detail. I've left
the indicated changes in a new version of my riscv-semihost branch here:

https://github.com/keith-packard/qemu/tree/riscv-semihost

I'll post a new version once we've wound up discussion on the remaining
issues.

>> +M: Keith Packard 
>
> I don't think you should be a maintainer just yet. In general people
> have to be actively reviewing patches to be listed as a maintainer.

Cool, I'm glad to not be listed. checkpatch.pl suggested that I might
need to add something here, so I went ahead and included it in case it
was necessary. (I probably should do some patch review though; SiFive is
rather dependent on QEMU continuing to be a great RISC-V emulator)

>> +#include "exec/cpu-all.h"
>
> This isn't used in the header so it shouldn't be here.

Worse than that -- it's already included in this file. I suspect
this is left over from a previous version and have removed it.

>> +#define RISCV_EXCP_SEMIHOST  0x10
>
> I don't see this in the RISC-V spec, it seems to just be reserved, not
> for semihosting.

Hrm. It's entirely an internal implementation detail in QEMU and matches
how semihosting works in the ARM implementation -- the presence of the
semihosting breakpoint raises this exception which is then handled in
the usual exception processing path.

If there is ever a real exception that uses this number, we can
re-define this to something else. Or if you have a favorite number you'd
like to use instead, that'd be great.

>> + *  ARM Semihosting is documented in:
>> + * Semihosting for AArch32 and AArch64 Release 2.0
>> + * https://static.docs.arm.com/100863/0200/semihosting.pdf
>
> Maybe just point to the RISC-V doc instead.

Good suggestion. Fixed.

> Could we split all of the shared code out somewhere?

Yes, that seems like a reasonable suggestion. I haven't done so because
that brings a lot of additional obligations on the patch to not impact
the ARM implementation, and means that future changes to either the
RISC-V or ARM specifications would need to be careful to not impact the
other architecture as the code is modified.

Benjamin Herrenschmidt started a thread back in January about creating a
common semihosting implementation to be shared across ARM, RISC-V and
PPC. I'm not sure he ever published the resulting code, but we can
probably get whatever he's done and see if we want to go that way. I
suspect the biggest impact will be to the ARM maintainers who will end
up on the hook for reviewing the code to make sure it doesn't break
anything for them.

I can expand the semihost testing which picolibc currently performs
under QEMU on ARM, AARCH64 and RISC-V; that might help catch regressions
caused by this rework.

>> --- a/target/riscv/translate.c
>> +++ b/target/riscv/translate.c
>> @@ -63,6 +63,7 @@ typedef struct DisasContext {
>>  uint16_t vlen;
>>  uint16_t mlen;
>>  bool vl_eq_vlmax;
>> +CPUState *cs;
>
> I'm not sure we should do this.

Yeah, the RISC-V semihosting requirement that three instructions be
compared to determine a valid 'sequence' is the least pleasing part of
the specification. This is the second version of this particular piece
of code.

We also changed the semihosting specification to require that all three
instructions lie on the same page to make sure they are all available if
any are available. In the application implementation, all that was
required to meet that was to put the sequence in a function and align
that to a 16-byte boundary as the function consists of four 32-bit
instructions:

.global sys_semihost
.balign 16
.option push
.option norvc
sys_semihost:
slli zero, zero, 0x1f
ebreak
srai zero, zero, 0x7
ret
.option pop

>> +static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
>> +{
>> +DisasContext *ctx = container_of(dcbase, DisasContext, base);
>> +CPUState *cpu = ctx->cs;
>> +CPURISCVState *env = cpu->env_ptr;
>> +
>> +return cpu_ldl_code(env, pc);
>
> @Richard Henderson is this ok?

Let me know if you've got a better plan, or even some suggestions on how
it might be improved as it seems like it a layering violation to me.

-- 
-keith


signature.asc
Description: PGP signature


Re: [PATCH v4 06/12] tests/qtest/qos-test: dump environment variables if verbose

2020-10-23 Thread Thomas Huth
On 08/10/2020 20.34, Christian Schoenebeck wrote:
> If qtests are run in verbose mode (i.e. if --verbose CL argument
> was provided) then print all environment variables to stdout
> before running the individual tests.

Why? ... you should provide some rationale in the patch description here, at
least to me this is not obvious why it is needed / desired.

 Thomas




Re: [PATCH 3/4] libqtest: fix memory leak in the qtest_qmp_event_ref

2020-10-23 Thread Thomas Huth
On 19/10/2020 18.37, Maxim Levitsky wrote:
> The g_list_remove_link doesn't free the link element,
> opposed to what I thought.
> Switch to g_list_delete_link that does free it.
> 
> Also refactor the code a bit.
> Thanks for Max Reitz for helping me with this.
> 
> Signed-off-by: Maxim Levitsky 
> ---
>  tests/qtest/libqtest.c | 11 ---
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
> index bd96cb6fdd..9ae052d566 100644
> --- a/tests/qtest/libqtest.c
> +++ b/tests/qtest/libqtest.c
> @@ -795,15 +795,12 @@ void qtest_qmp_send_raw(QTestState *s, const char *fmt, 
> ...)
>  
>  QDict *qtest_qmp_event_ref(QTestState *s, const char *event)
>  {
> -GList *next = NULL;
> -QDict *response;
> -
> -for (GList *it = s->pending_events; it != NULL; it = next) {
> +while (s->pending_events) {
>  
> -next = it->next;
> -response = (QDict *)it->data;
> +GList *first = s->pending_events;
> +QDict *response = (QDict *)first->data;
>  
> -s->pending_events = g_list_remove_link(s->pending_events, it);
> +s->pending_events = g_list_delete_link(s->pending_events, first);
>  
>  if (!strcmp(qdict_get_str(response, "event"), event)) {
>  return response;
> 

Thanks, queued (together with patch 2) to qtest-next:

 https://gitlab.com/huth/qemu/-/commits/qtest-next/

 Thomas




Re: [PATCH 1/4] qdev: Fix two typos

2020-10-23 Thread Thomas Huth
On 19/10/2020 18.36, Maxim Levitsky wrote:
> Signed-off-by: Maxim Levitsky 
> ---
>  include/hw/qdev-core.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index 868973319e..3761186804 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -163,8 +163,8 @@ struct NamedClockList {
>  /**
>   * DeviceState:
>   * @realized: Indicates whether the device has been fully constructed.
> - *When accessed outsize big qemu lock, must be accessed with
> - *atomic_load_acquire()
> + *When accessed outside big qemu lock, must be accessed with
> + *qatomic_load_acquire()
>   * @reset: ResettableState for the device; handled by Resettable interface.
>   *
>   * This structure should not be accessed directly.  We declare it here
> 

Reviewed-by: Thomas Huth 




Re: [PATCH v3 1/6] tests/qtest: Make npcm7xx_timer-test conditional on CONFIG_NPCM7XX

2020-10-23 Thread Thomas Huth
On 23/10/2020 23.06, Havard Skinnemoen wrote:
> This test won't work if qemu was compiled without CONFIG_NPCM7XX, as
> pointed out by Thomas Huth on a different patch.
> 
> Signed-off-by: Havard Skinnemoen 
> ---
>  tests/qtest/meson.build | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 28d4068718..7e0ecaa2c5 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -133,12 +133,13 @@ qtests_sparc64 = \
>(config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : 
> []) +\
>['prom-env-test', 'boot-serial-test']
>  
> +qtests_npcm7xx = ['npcm7xx_timer-test']
>  qtests_arm = \
>(config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] 
> : []) + \
> +  (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
>['arm-cpu-features',
> 'microbit-test',
> 'm25p80-test',
> -   'npcm7xx_timer-test',
> 'test-arm-mptimer',
> 'boot-serial-test',
> 'hexloader-test']
> 

Reviewed-by: Thomas Huth 




Re: [PATCH v2 2/6] configure: avoid new clang 11+ warnings

2020-10-23 Thread Thomas Huth
On 23/10/2020 22.06, Daniele Buono wrote:
> Clang 11 finds a couple of spots in the code that trigger new warnings:
> 
> ../qemu-base/hw/usb/dev-uas.c:157:31: error: field 'status' with variable 
> sized type 'uas_iu' not at the end of a struct or class is a GNU extension 
> [-Werror,-Wgnu-variable-sized-type-not-at-end]
> uas_iustatus;
>   ^
> 1 error generated.
> 
> The data structure is UASStatus, which must end with a QTAILQ_ENTRY, so
> I believe we cannot have uas_iu at the end. Since this is a gnu
> extension but CLANG supports it, just add
> -Wno-gnu-variable-sized-type-not-at-end
> to remove the warning.
> 
> ../qemu-base/target/s390x/cpu_models.c:985:21: error: cast to smaller integer 
> type 'S390Feat' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
> S390Feat feat = (S390Feat) opaque;
> ^
> ../qemu-base/target/s390x/cpu_models.c:1002:21: error: cast to smaller 
> integer type 'S390Feat' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
> S390Feat feat = (S390Feat) opaque;
> ^
> ../qemu-base/target/s390x/cpu_models.c:1036:27: error: cast to smaller 
> integer type 'S390FeatGroup' from 'void *' 
> [-Werror,-Wvoid-pointer-to-enum-cast]
> S390FeatGroup group = (S390FeatGroup) opaque;
>   ^~
> ../qemu-base/target/s390x/cpu_models.c:1057:27: error: cast to smaller 
> integer type 'S390FeatGroup' from 'void *' 
> [-Werror,-Wvoid-pointer-to-enum-cast]
> S390FeatGroup group = (S390FeatGroup) opaque;
>   ^~
> 4 errors generated.
> 
> These are void * that get casted to enums, which are (or can be)
> smaller than a 64bit pointer.
> A code reorg may be better on the long term, but for now will
> fix this adding
> -Wno-void-pointer-to-enum-cast

Compiling all code with -Wno-void-pointer-to-enum-cast sounds like the wrong
approach to me, since this might hide some real bugs in other spots instead.

Could you please try to cast the value through (uintptr_t) first, e.g. :

S390Feat feat = (S390Feat)(uintptr_t) opaque;

It's a little bit ugly, but still better than to disable the warning
globally, I think.

 Thomas


> Signed-off-by: Daniele Buono 
> ---
>  configure | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/configure b/configure
> index e6754c1e87..9dc05cfb8a 100755
> --- a/configure
> +++ b/configure
> @@ -2000,6 +2000,8 @@ add_to nowarn_flags -Wno-shift-negative-value
>  add_to nowarn_flags -Wno-string-plus-int
>  add_to nowarn_flags -Wno-typedef-redefinition
>  add_to nowarn_flags -Wno-tautological-type-limit-compare
> +add_to nowarn_flags -Wno-gnu-variable-sized-type-not-at-end
> +add_to nowarn_flags -Wno-void-pointer-to-enum-cast
>  add_to nowarn_flags -Wno-psabi
>  
>  gcc_flags="$warn_flags $nowarn_flags"
> 




Re: Ramping up Continuous Fuzzing of Virtual Devices in QEMU

2020-10-23 Thread Li Qiang
Alexander Bulekov  于2020年10月23日周五 上午12:20写道:
>
> Hello,
> QEMU was accepted into Google's oss-fuzz continuous-fuzzing platform [1]
> earlier this year. The fuzzers currently running on oss-fuzz are based on my
> 2019 Google Summer of Code Project, which leveraged libfuzzer, qtest and 
> libqos
> to provide a framework for writing virtual-device fuzzers. At the moment, 
> there
> are a handful of fuzzers upstream and running on oss-fuzz(located in
> tests/qtest/fuzz/). They fuzz only a few devices and serve mostly as
> examples.
>
> If everything goes well, soon a generic fuzzer [2] will land upstream, which
> allows us to fuzz many configurations of QEMU, without any device-specific
> code. To date this fuzzer has led to ~50 bug reports on launchpad. Once the
> generic-fuzzer lands upstream, OSS-Fuzz will automatically start fuzzing a
> bunch [3] of fuzzer configurations, and it is likely to find bugs.  Others 
> will
> also be able to send simple patches to add additional device configurations 
> for
> fuzzing.
>
> The oss-fuzz process looks roughly like this:
> 1. oss-fuzz fuzzes QEMU
> 2. When oss-fuzz finds a bug, it reports it to a few [4] people that have
> access to reports and reproducers.
> 3. If a fix is merged upstream, oss-fuzz will figure this out and mark the
> bug as fixed and make the report public 30 days later.
> 3. After 90 days the bug(fixed or not) becomes public, so anyone can view
> it here https://bugs.chromium.org/p/oss-fuzz/issues/list
>
> The oss-fuzz reports look like this:
> https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=23701=qemu=2
>
> This means that when oss-fuzz find new bugs, the relevant developers do not
> know about them unless someone with access files a separate report to the
> list/launchpad. So far this hasn't been a problem, since oss-fuzz has only 
> been
> running some small example fuzzers. Once [2] lands upstream, we should
> see a significant uptick in oss-fuzz reports, and I hope that we can develop a
> process to ensure these bugs are properly dealt with. One option we have is to
> make the reports public immediately and send notifications to
> qemu-devel. This is the approach taken by some other projects on
> oss-fuzz, such as LLVM. Though its not on oss-fuzz, bugs found by
> syzkaller in the kernel, are also automatically sent to a public list.
> The question is:
>
> What approach should we take for dealing with bugs found on oss-fuzz?
>

Hi Alex,

I prefer to send these bugs to public list such as qemu-devel.

There are lots of low impact bugs so no need to prepare a private
bugtracker for the little important issues.
Also the maintainer's decision may take a long time.

For the public issues, the security engineer, maintainer and volunteer
can both see them and point out its
impact more quickly.



> [1] https://github.com/google/oss-fuzz
> [2] https://lists.gnu.org/archive/html/qemu-devel/2020-10/msg06331.html
> [3] https://lists.gnu.org/archive/html/qemu-devel/2020-10/msg06345.html
> [4] 
> https://github.com/google/oss-fuzz/blob/fbf916ce14952ba192e58fe8550096b868fcf62d/projects/qemu/project.yaml#L4

BTW, is there any condition to join this lists?
I'm quite interested to fix the qemu issues.

Thanks,
Li Qiang

>
> For further reference, the vast majority of these bugs, were found with the
> generic-fuzzer:
> https://bugs.launchpad.net/~a1xndr/+bugs
>
> There are more that I haven't yet had time to write reports for.
> Thank you
> -Alex



[PATCH] hw/sd: Zero out function selection fields before being populated

2020-10-23 Thread Bin Meng
From: Bin Meng 

The function selection fields (399:376) should be zeroed out to
prevent leftover from being or'ed into the switch function status
data structure.

This fixes the boot failure as seen in the acceptance testing on
the orangepi target.

Fixes: b638627c723a ("hw/sd: Fix incorrect populated function switch status 
data structure")
Reported-by: Michael Roth 
Signed-off-by: Bin Meng 
---

 hw/sd/sd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index c3febed243..bd10ec8fc4 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -824,6 +824,7 @@ static void sd_function_switch(SDState *sd, uint32_t arg)
 sd->data[12] = 0x80;   /* Supported group 1 functions */
 sd->data[13] = 0x03;
 
+memset(>data[14], 0, 3);
 for (i = 0; i < 6; i ++) {
 new_func = (arg >> (i * 4)) & 0x0f;
 if (mode && new_func != 0x0f)
-- 
2.25.1




Re: [RFC PATCH 0/4] tests/acceptance: Test U-Boot/Linux from Armbian 20.08 on Orange Pi PC

2020-10-23 Thread Bin Meng
Hi Philippe,

On Sat, Oct 24, 2020 at 1:56 AM Philippe Mathieu-Daudé  wrote:
>
> On 10/23/20 7:42 PM, Bin Meng wrote:
> > Hi Philippe,
> >
> > On Fri, Oct 23, 2020 at 9:18 PM Philippe Mathieu-Daudé  
> > wrote:
> >>
> >> Series meant to help Bin Meng to debug the SD card issue
> >> reported by Michael Roth.
> >
> > Thank you for the patches.
> >
> >>
> >> Philippe Mathieu-Daudé (4):
> >>Revert "hw/sd: Fix incorrect populated function switch status data
> >>  structure"
> >>tests/acceptance: Allow running Orange Pi test using cached artifacts
> >>tests/acceptance: Extract do_test_arm_orangepi_armbian_uboot() method
> >>tests/acceptance: Test U-Boot/Linux from Armbian 20.08 on Orange Pi PC
> >>
> >>   hw/sd/sd.c |  3 +-
> >>   tests/acceptance/boot_linux_console.py | 68 +++---
> >>   2 files changed, 50 insertions(+), 21 deletions(-)
> >
> > With this series, I used:
> >
> > $ ARMBIAN_ARTIFACTS_CACHED=1 AVOCADO_ALLOW_LARGE_STORAGE=1 make 
> > check-acceptance
> >
> > It looks that the failure still exists? Log below:
> >
> > 13-tests_acceptance_boot_linux_console.py_BootLinuxConsole.test_arm_orangepi_bionic_20_08/debug.log:
> >
> > 01:11:27 DEBUG| => boot
> > 01:11:27 DEBUG| unable to select a mode
> > 01:11:27 DEBUG| Device 0: unknown device
> > 01:11:27 DEBUG| BOOTP broadcast 1
> > 01:11:27 DEBUG| DHCP client bound to address 10.0.2.15 (1 ms)
> > 01:11:27 DEBUG| *** Warning: no boot file name; using '0A00020F.img'
> > 01:11:27 DEBUG| Using ethernet@1c3 device
> > 01:11:27 DEBUG| TFTP from server 10.0.2.2; our IP address is 10.0.2.15
> > 01:11:27 DEBUG| Filename '0A00020F.img'.
> > 01:11:27 DEBUG| Load address: 0x4200
> > 01:11:27 DEBUG| Loading: *^H
> > 01:11:27 DEBUG| TFTP error: 'Access violation' (2)
> > 01:11:27 DEBUG| Not retrying...
>
> Have you rebuilt qemu-system-arm with the reverted patch included?

Oops, I took it for granted that the `make check-acceptance` will
automatically rebuild the QEMU binary, which is not the case. Should
we enforce the rebuild before testing in Makefiles?

Regards,
Bin



Re: [PATCH v1 4/4] hw/core: implement a guest-loader to support static hypervisor guests

2020-10-23 Thread Alistair Francis
On Wed, Oct 21, 2020 at 10:09 AM Alex Bennée  wrote:
>
> Hypervisors, especially type-1 ones, need the firmware/bootcode to put
> their initial guest somewhere in memory and pass the information to it
> via platform data. The guest-loader is modelled after the generic
> loader for exactly this sort of purpose:

guest as in Hypervisor guest and QEMU guest is a little confusing, but
I can't think of a better name

>
>   $QEMU $ARGS  -kernel ~/xen.git/xen/xen \
> -append "dom0_mem=1G,max:1G loglvl=all guest_loglvl=all" \
> -device 
> guest-loader,addr=0x4200,kernel=Image,bootargs="root=/dev/sda2 ro 
> console=hvc0 earlyprintk=xen" \
> -device guest-loader,addr=0x4700,initrd=rootfs.cpio

This seems fine to me.

Do you mind writing some documentation though? The generic-loader
documentation should be a good place to start.

>
> Signed-off-by: Alex Bennée 
> ---
>  hw/core/guest-loader.h |  34 ++
>  hw/core/guest-loader.c | 140 +
>  hw/core/meson.build|   2 +
>  3 files changed, 176 insertions(+)
>  create mode 100644 hw/core/guest-loader.h
>  create mode 100644 hw/core/guest-loader.c
>
> diff --git a/hw/core/guest-loader.h b/hw/core/guest-loader.h
> new file mode 100644
> index 00..07f4b4884b
> --- /dev/null
> +++ b/hw/core/guest-loader.h
> @@ -0,0 +1,34 @@
> +/*
> + * Guest Loader
> + *
> + * Copyright (C) 2020 Linaro
> + * Written by Alex Bennée 
> + * (based on the generic-loader by Li Guang )
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#ifndef GUEST_LOADER_H
> +#define GUEST_LOADER_H
> +
> +#include "hw/qdev-core.h"
> +#include "qom/object.h"
> +
> +struct GuestLoaderState {
> +/*  */
> +DeviceState parent_obj;
> +
> +/*  */
> +uint64_t addr;
> +char *kernel;
> +char *args;
> +char *initrd;
> +};
> +
> +#define TYPE_GUEST_LOADER "guest-loader"
> +OBJECT_DECLARE_SIMPLE_TYPE(GuestLoaderState, GUEST_LOADER)
> +
> +#endif
> diff --git a/hw/core/guest-loader.c b/hw/core/guest-loader.c
> new file mode 100644
> index 00..1ce39842be
> --- /dev/null
> +++ b/hw/core/guest-loader.c
> @@ -0,0 +1,140 @@
> +/*
> + * Guest Loader
> + *
> + * Copyright (C) 2020 Linaro
> + * Written by Alex Bennée 
> + * (based on the generic-loader by Li Guang )
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +/*
> + * Much like the generic-loader this is treated as a special device
> + * inside QEMU. However unlike the generic-loader this device is used
> + * to load guest images for hypervisors. As part of that process the
> + * hypervisor needs to have platform information passed to it by the
> + * lower levels of the stack (e.g. firmware/bootloader). If you boot
> + * the hypervisor directly you use the guest-loader to load the Dom0
> + * or equivalent guest images in the right place in the same way a
> + * boot loader would.
> + *
> + * This is only relevant for full system emulation.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/core/cpu.h"
> +#include "hw/sysbus.h"
> +#include "sysemu/dma.h"
> +#include "hw/loader.h"
> +#include "hw/qdev-properties.h"
> +#include "qapi/error.h"
> +#include "qemu/module.h"
> +#include "guest-loader.h"
> +#include "sysemu/device_tree.h"
> +#include "hw/boards.h"
> +
> +/*
> + * Insert some FDT nodes for the loaded blob.
> + */
> +static void loader_insert_platform_data(GuestLoaderState *s, int size, Error 
> **errp)
> +{
> +MachineState *machine = MACHINE(qdev_get_machine());
> +void *fdt = machine->fdt;
> +g_autofree char *node = g_strdup_printf("/chosen/module@%#08lx", 
> s->addr);
> +uint64_t reg_attr[2] = {cpu_to_be64(s->addr), cpu_to_be64(size)};
> +
> +if (!fdt) {
> +error_setg(errp, "Cannot modify FDT fields if the machine has none");
> +return;
> +}
> +
> +qemu_fdt_add_subnode(fdt, node);
> +qemu_fdt_setprop(fdt, node, "reg", _attr, sizeof(reg_attr));
> +
> +if (s->kernel) {
> +const char *compat[2] = { "multiboot,module", "multiboot,kernel" };
> +if (qemu_fdt_setprop_string_array
> +(fdt, node, "compatible", (char **) , ARRAY_SIZE(compat)) 
> < 0) {
> +error_setg(errp, "couldn't set %s/compatible", node);
> +return;
> +}
> +if (s->args) {
> +if (qemu_fdt_setprop_string(fdt, node, "bootargs", s->args) < 0) 
> {
> +error_setg(errp, "couldn't set %s/bootargs", node);
> +}
> +}
> +} else if (s->initrd) {
> +const char * compat[2] = { "multiboot,module", "multiboot,ramdisk" };
> +if (qemu_fdt_setprop_string_array
> +(fdt, node, "compatible", (char **) , 

Re: [PATCH v1 3/4] device_tree: add qemu_fdt_setprop_string_array helper

2020-10-23 Thread Alistair Francis
On Wed, Oct 21, 2020 at 10:11 AM Alex Bennée  wrote:
>
> A string array in device tree is simply a series of \0 terminated
> strings next to each other. As libfdt doesn't support that directly
> we need to build it ourselves.
>
> Signed-off-by: Alex Bennée 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  include/sysemu/device_tree.h | 17 +
>  softmmu/device_tree.c| 26 ++
>  2 files changed, 43 insertions(+)
>
> diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
> index 982c89345f..8a2fe55622 100644
> --- a/include/sysemu/device_tree.h
> +++ b/include/sysemu/device_tree.h
> @@ -70,6 +70,23 @@ int qemu_fdt_setprop_u64(void *fdt, const char *node_path,
>   const char *property, uint64_t val);
>  int qemu_fdt_setprop_string(void *fdt, const char *node_path,
>  const char *property, const char *string);
> +
> +/**
> + * qemu_fdt_setprop_string_array: set a string array property
> + *
> + * @fdt: pointer to the dt blob
> + * @name: node name
> + * @prop: property array
> + * @array: pointer to an array of string pointers
> + * @len: length of array
> + *
> + * assigns a string array to a property. This function converts and
> + * array of strings to a sequential string with \0 separators before
> + * setting the property.
> + */
> +int qemu_fdt_setprop_string_array(void *fdt, const char *node_path,
> +  const char *prop, char **array, int len);
> +
>  int qemu_fdt_setprop_phandle(void *fdt, const char *node_path,
>   const char *property,
>   const char *target_node_path);
> diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
> index b335dae707..a19873316a 100644
> --- a/softmmu/device_tree.c
> +++ b/softmmu/device_tree.c
> @@ -21,6 +21,7 @@
>  #include "qemu/error-report.h"
>  #include "qemu/option.h"
>  #include "qemu/bswap.h"
> +#include "qemu/cutils.h"
>  #include "sysemu/device_tree.h"
>  #include "sysemu/sysemu.h"
>  #include "hw/loader.h"
> @@ -397,6 +398,31 @@ int qemu_fdt_setprop_string(void *fdt, const char 
> *node_path,
>  return r;
>  }
>
> +/*
> + * libfdt doesn't allow us to add string arrays directly but they are
> + * test a series of null terminated strings with a length. We build
> + * the string up here so we can calculate the final length.
> + */
> +int qemu_fdt_setprop_string_array(void *fdt, const char *node_path, const 
> char *prop,
> +  char **array, int len)
> +{
> +int ret, i, total_len = 0;
> +char *str, *p;
> +for (i = 0; i < len; i++) {
> +total_len += strlen(array[i]) + 1;
> +}
> +p = str = g_malloc0(total_len);
> +for (i = 0; i < len; i++) {
> +int len = strlen(array[i]) + 1;
> +pstrcpy(p, len, array[i]);
> +p += len;
> +}
> +
> +ret = qemu_fdt_setprop(fdt, node_path, prop, str, total_len);
> +g_free(str);
> +return ret;
> +}
> +
>  const void *qemu_fdt_getprop(void *fdt, const char *node_path,
>   const char *property, int *lenp, Error **errp)
>  {
> --
> 2.20.1
>
>



Re: [PATCH v6 0/6] RISC-V Pointer Masking implementation

2020-10-23 Thread Alistair Francis
On Thu, Oct 22, 2020 at 1:04 AM Alexey Baturo  wrote:
>
> Hi,
>
> Added missing sign-off on the first patch.
>
> Thanks
>
> Alexey Baturo (5):
>   [RISCV_PM] Add J-extension into RISC-V
>   [RISCV_PM] Support CSRs required for RISC-V PM extension except for
> ones in hypervisor mode
>   [RISCV_PM] Print new PM CSRs in QEMU logs
>   [RISCV_PM] Support pointer masking for RISC-V for i/c/f/d/a types of
> instructions
>   [RISCV_PM] Allow experimental J-ext to be turned on
>
> Anatoly Parshintsev (1):
>   [RISCV_PM] Implement address masking functions required for RISC-V
> Pointer Masking extension

Thanks for the patches!

I don't know a lot about the J-extension, so it will take me some time
to read into it before I can review this.

Maybe you can convince Richard to review it for you :P

Alistair

>
>  target/riscv/cpu.c  |  30 +++
>  target/riscv/cpu.h  |  33 +++
>  target/riscv/cpu_bits.h |  66 ++
>  target/riscv/csr.c  | 271 
>  target/riscv/insn_trans/trans_rva.c.inc |   3 +
>  target/riscv/insn_trans/trans_rvd.c.inc |   2 +
>  target/riscv/insn_trans/trans_rvf.c.inc |   2 +
>  target/riscv/insn_trans/trans_rvi.c.inc |   2 +
>  target/riscv/translate.c|  44 
>  9 files changed, 453 insertions(+)
>
> --
> 2.20.1
>
>



Re: [PATCH v6 1/6] [RISCV_PM] Add J-extension into RISC-V

2020-10-23 Thread Alistair Francis
On Thu, Oct 22, 2020 at 1:05 AM Alexey Baturo  wrote:
>
> Signed-off-by: Alexey Baturo 
> ---
>  target/riscv/cpu.c | 1 +
>  target/riscv/cpu.h | 2 ++
>  2 files changed, 3 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0bbfd7f457..4e305249b3 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -516,6 +516,7 @@ static Property riscv_cpu_properties[] = {
>  DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
>  /* This is experimental so mark with 'x-' */
>  DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
> +DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),

This line should be in the last commit. It shouldn't be exposed to
users until the very end.

Alistair

>  DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
>  DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
>  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index de275782e6..eca611a367 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -66,6 +66,7 @@
>  #define RVS RV('S')
>  #define RVU RV('U')
>  #define RVH RV('H')
> +#define RVJ RV('J')
>
>  /* S extension denotes that Supervisor mode exists, however it is possible
> to have a core that support S mode but does not have an MMU and there
> @@ -277,6 +278,7 @@ struct RISCVCPU {
>  bool ext_s;
>  bool ext_u;
>  bool ext_h;
> +bool ext_j;
>  bool ext_v;
>  bool ext_counters;
>  bool ext_ifencei;
> --
> 2.20.1
>
>



Re: [PATCH] riscv: Add semihosting support [v8]

2020-10-23 Thread Alistair Francis
On Fri, Oct 23, 2020 at 2:51 PM Keith Packard via  wrote:
>
> Adapt the arm semihosting support code for RISCV. This implementation
> is based on the standard for RISC-V semihosting version 0.2 as
> documented in
>
>https://github.com/riscv/riscv-semihosting-spec/releases/tag/0.2
>
> Signed-off-by: Keith Packard 

Hey Keith,

>
> ---
>
> v2:
> Update PC after exception is handled to follow
> change in the ARM version for SYS_READC
>
> v3:
> Disallow semihosting in user mode; report a regular
> breakpoint in that case.
>
> v4:
> Fix errors reported by checkpatch
>
> v5:
> Reference current RISC-V semihosting specification
>
> v6:
> Add support for semihosting in riscv64-linux-user and
> riscv32-linux-user
>
> v7:
> Add meson build support
>
> v8:
> Fix errors reported by checkpatch that crept in.
> ---
>  MAINTAINERS   |1 +
>  default-configs/devices/riscv32-softmmu.mak   |1 +
>  default-configs/devices/riscv64-softmmu.mak   |1 +
>  linux-user/meson.build|1 +
>  linux-user/qemu.h |4 +-
>  linux-user/riscv/meson.build  |2 +
>  linux-user/riscv/semihost.c   |   76 ++
>  qemu-options.hx   |   10 +-
>  target/riscv/cpu.h|7 +
>  target/riscv/cpu_bits.h   |1 +
>  target/riscv/cpu_helper.c |9 +
>  .../riscv/insn_trans/trans_privileged.c.inc   |   24 +-
>  target/riscv/meson.build  |1 +
>  target/riscv/riscv-semi.c | 1086 +
>  target/riscv/translate.c  |   11 +
>  15 files changed, 1229 insertions(+), 6 deletions(-)
>  create mode 100644 linux-user/riscv/meson.build
>  create mode 100644 linux-user/riscv/semihost.c
>  create mode 100644 target/riscv/riscv-semi.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 6a197bd358..8cf5b1e448 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -279,6 +279,7 @@ M: Palmer Dabbelt 
>  M: Alistair Francis 
>  M: Sagar Karandikar 
>  M: Bastian Koppelmann 
> +M: Keith Packard 

I don't think you should be a maintainer just yet. In general people
have to be actively reviewing patches to be listed as a maintainer.

>  L: qemu-ri...@nongnu.org
>  S: Supported
>  F: target/riscv/
> diff --git a/default-configs/devices/riscv32-softmmu.mak 
> b/default-configs/devices/riscv32-softmmu.mak
> index 94a236c9c2..e8a4eeebec 100644
> --- a/default-configs/devices/riscv32-softmmu.mak
> +++ b/default-configs/devices/riscv32-softmmu.mak
> @@ -3,6 +3,7 @@
>  # Uncomment the following lines to disable these optional devices:
>  #
>  #CONFIG_PCI_DEVICES=n
> +CONFIG_SEMIHOSTING=y
>
>  # Boards:
>  #
> diff --git a/default-configs/devices/riscv64-softmmu.mak 
> b/default-configs/devices/riscv64-softmmu.mak
> index 76b6195648..d8a87b7671 100644
> --- a/default-configs/devices/riscv64-softmmu.mak
> +++ b/default-configs/devices/riscv64-softmmu.mak
> @@ -3,6 +3,7 @@
>  # Uncomment the following lines to disable these optional devices:
>  #
>  #CONFIG_PCI_DEVICES=n
> +CONFIG_SEMIHOSTING=y
>
>  # Boards:
>  #
> diff --git a/linux-user/meson.build b/linux-user/meson.build
> index 2b94e4ba24..31b5ed99b5 100644
> --- a/linux-user/meson.build
> +++ b/linux-user/meson.build
> @@ -29,6 +29,7 @@ subdir('microblaze')
>  subdir('mips64')
>  subdir('mips')
>  subdir('ppc')
> +subdir('riscv')
>  subdir('s390x')
>  subdir('sh4')
>  subdir('sparc64')
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index 941ca99722..faeaab9614 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -105,6 +105,8 @@ typedef struct TaskState {
>  /* FPA state */
>  FPA11 fpa;
>  # endif
> +#endif
> +#if defined(TARGET_ARM) || defined(TARGET_RISCV)
>  int swi_errno;
>  #endif
>  #if defined(TARGET_I386) && !defined(TARGET_X86_64)
> @@ -118,7 +120,7 @@ typedef struct TaskState {
>  #ifdef TARGET_M68K
>  abi_ulong tp_value;
>  #endif
> -#if defined(TARGET_ARM) || defined(TARGET_M68K)
> +#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_RISCV)
>  /* Extra fields for semihosted binaries.  */
>  abi_ulong heap_base;
>  abi_ulong heap_limit;
> diff --git a/linux-user/riscv/meson.build b/linux-user/riscv/meson.build
> new file mode 100644
> index 00..aee3179cdb
> --- /dev/null
> +++ b/linux-user/riscv/meson.build
> @@ -0,0 +1,2 @@
> +linux_user_ss.add(when: 'TARGET_RISCV64', if_true: files('semihost.c'))
> +linux_user_ss.add(when: 'TARGET_RISCV32', if_true: files('semihost.c'))
> diff --git a/linux-user/riscv/semihost.c b/linux-user/riscv/semihost.c
> new file mode 100644
> index 00..2d35ebab68
> --- /dev/null
> +++ b/linux-user/riscv/semihost.c
> @@ -0,0 +1,76 @@
> +/*
> + * RISC-V Semihosting Console Support
> + *
> + * Copyright (c) 2019 Linaro Ltd
> + *
> + * 

Re: [PATCH 2/2] riscv: Add sifive test device to sifive_u target

2020-10-23 Thread Keith Packard
Alistair Francis  writes:

> I also don't see this in the FU540 memory map.

Same as for the FE310 -- this is a QEMU-only device. In addition,
OpenSBI expects to use this when built for QEMU.

-- 
-keith


signature.asc
Description: PGP signature


Re: [PATCH 1/2] riscv: Add sifive test device to sifive_e target

2020-10-23 Thread Alistair Francis
On Fri, Oct 23, 2020 at 5:13 PM Keith Packard  wrote:
>
> Alistair Francis  writes:
>
> > I don't see this mentioned in the FE310 data sheet. Is it included in
> > the hardware?
>
> This is strictly a virtual device used to support 'power off' when
> running under QEMU. We need either this or semihosting support for doing

The sifive_u and sifive_e model real hardware (the names are confusing
I agree) so I would rather not add a virtual device.

> automated testing. Our tests currently use this device, but I'd be happy
> to switch them over to using semihosting instead, if you'd be interested
> in getting that merged...

Looking at it now.

Alistair

>
> --
> -keith



Re: [PATCH 1/2] riscv: Add sifive test device to sifive_e target

2020-10-23 Thread Keith Packard
Alistair Francis  writes:

> I don't see this mentioned in the FE310 data sheet. Is it included in
> the hardware?

This is strictly a virtual device used to support 'power off' when
running under QEMU. We need either this or semihosting support for doing
automated testing. Our tests currently use this device, but I'd be happy
to switch them over to using semihosting instead, if you'd be interested
in getting that merged...

-- 
-keith


signature.asc
Description: PGP signature


Re: [PATCH V3 6/6] target/riscv: Add sifive_plic vmstate

2020-10-23 Thread Alistair Francis
On Fri, Oct 23, 2020 at 2:13 AM Yifei Jiang  wrote:
>
> Add sifive_plic vmstate for supporting sifive_plic migration.
> Current vmstate framework only supports one structure parameter
> as num field to describe variable length arrays, so introduce
> num_enables.
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Yipeng Yin 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/intc/sifive_plic.c | 26 +-
>  hw/intc/sifive_plic.h |  1 +
>  2 files changed, 26 insertions(+), 1 deletion(-)
>
> diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> index f42fd695d8..97a1a27a9a 100644
> --- a/hw/intc/sifive_plic.c
> +++ b/hw/intc/sifive_plic.c
> @@ -30,6 +30,7 @@
>  #include "hw/intc/sifive_plic.h"
>  #include "target/riscv/cpu.h"
>  #include "sysemu/sysemu.h"
> +#include "migration/vmstate.h"
>
>  #define RISCV_DEBUG_PLIC 0
>
> @@ -448,11 +449,12 @@ static void sifive_plic_realize(DeviceState *dev, Error 
> **errp)
>TYPE_SIFIVE_PLIC, plic->aperture_size);
>  parse_hart_config(plic);
>  plic->bitfield_words = (plic->num_sources + 31) >> 5;
> +plic->num_enables = plic->bitfield_words * plic->num_addrs;
>  plic->source_priority = g_new0(uint32_t, plic->num_sources);
>  plic->target_priority = g_new(uint32_t, plic->num_addrs);
>  plic->pending = g_new0(uint32_t, plic->bitfield_words);
>  plic->claimed = g_new0(uint32_t, plic->bitfield_words);
> -plic->enable = g_new0(uint32_t, plic->bitfield_words * plic->num_addrs);
> +plic->enable = g_new0(uint32_t, plic->num_enables);
>  sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mmio);
>  qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
>
> @@ -472,12 +474,34 @@ static void sifive_plic_realize(DeviceState *dev, Error 
> **errp)
>  msi_nonbroken = true;
>  }
>
> +static const VMStateDescription vmstate_sifive_plic = {
> +.name = "riscv_sifive_plic",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.fields = (VMStateField[]) {
> +VMSTATE_VARRAY_UINT32(source_priority, SiFivePLICState,
> +  num_sources, 0,
> +  vmstate_info_uint32, uint32_t),
> +VMSTATE_VARRAY_UINT32(target_priority, SiFivePLICState,
> +  num_addrs, 0,
> +  vmstate_info_uint32, uint32_t),
> +VMSTATE_VARRAY_UINT32(pending, SiFivePLICState, bitfield_words, 
> 0,
> +  vmstate_info_uint32, uint32_t),
> +VMSTATE_VARRAY_UINT32(claimed, SiFivePLICState, bitfield_words, 
> 0,
> +  vmstate_info_uint32, uint32_t),
> +VMSTATE_VARRAY_UINT32(enable, SiFivePLICState, num_enables, 0,
> +  vmstate_info_uint32, uint32_t),
> +VMSTATE_END_OF_LIST()
> +}
> +};
> +
>  static void sifive_plic_class_init(ObjectClass *klass, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(klass);
>
>  device_class_set_props(dc, sifive_plic_properties);
>  dc->realize = sifive_plic_realize;
> +dc->vmsd = _sifive_plic;
>  }
>
>  static const TypeInfo sifive_plic_info = {
> diff --git a/hw/intc/sifive_plic.h b/hw/intc/sifive_plic.h
> index b75b1f145d..1e451a270c 100644
> --- a/hw/intc/sifive_plic.h
> +++ b/hw/intc/sifive_plic.h
> @@ -52,6 +52,7 @@ struct SiFivePLICState {
>  uint32_t num_addrs;
>  uint32_t num_harts;
>  uint32_t bitfield_words;
> +uint32_t num_enables;
>  PLICAddr *addr_config;
>  uint32_t *source_priority;
>  uint32_t *target_priority;
> --
> 2.19.1
>
>



Re: [PATCH V3 5/6] target/riscv: Add V extension state description

2020-10-23 Thread Alistair Francis
On Fri, Oct 23, 2020 at 2:18 AM Yifei Jiang  wrote:
>
> In the case of supporting V extension, add V extension description
> to vmstate_riscv_cpu.
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Yipeng Yin 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/machine.c | 25 +
>  1 file changed, 25 insertions(+)
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index ae60050898..44d4015bd6 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -76,6 +76,30 @@ static bool hyper_needed(void *opaque)
>  return riscv_has_ext(env, RVH);
>  }
>
> +static bool vector_needed(void *opaque)
> +{
> +RISCVCPU *cpu = opaque;
> +CPURISCVState *env = >env;
> +
> +return riscv_has_ext(env, RVV);
> +}
> +
> +static const VMStateDescription vmstate_vector = {
> +.name = "cpu/vector",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.needed = vector_needed,
> +.fields = (VMStateField[]) {
> +VMSTATE_UINT64_ARRAY(env.vreg, RISCVCPU, 32 * RV_VLEN_MAX / 64),
> +VMSTATE_UINTTL(env.vxrm, RISCVCPU),
> +VMSTATE_UINTTL(env.vxsat, RISCVCPU),
> +VMSTATE_UINTTL(env.vl, RISCVCPU),
> +VMSTATE_UINTTL(env.vstart, RISCVCPU),
> +VMSTATE_UINTTL(env.vtype, RISCVCPU),
> +VMSTATE_END_OF_LIST()
> +}
> +};
> +
>  static const VMStateDescription vmstate_hyper = {
>  .name = "cpu/hyper",
>  .version_id = 1,
> @@ -166,6 +190,7 @@ const VMStateDescription vmstate_riscv_cpu = {
>  .subsections = (const VMStateDescription * []) {
>  _pmp,
>  _hyper,
> +_vector,
>  NULL
>  }
>  };
> --
> 2.19.1
>
>



Re: [PATCH V3 4/6] target/riscv: Add H extension state description

2020-10-23 Thread Alistair Francis
On Fri, Oct 23, 2020 at 2:16 AM Yifei Jiang  wrote:
>
> In the case of supporting H extension, add H extension description
> to vmstate_riscv_cpu.
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Yipeng Yin 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/machine.c | 47 ++
>  1 file changed, 47 insertions(+)
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index fc1461d88e..ae60050898 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -68,6 +68,52 @@ static const VMStateDescription vmstate_pmp = {
>  }
>  };
>
> +static bool hyper_needed(void *opaque)
> +{
> +RISCVCPU *cpu = opaque;
> +CPURISCVState *env = >env;
> +
> +return riscv_has_ext(env, RVH);
> +}
> +
> +static const VMStateDescription vmstate_hyper = {
> +.name = "cpu/hyper",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.needed = hyper_needed,
> +.fields = (VMStateField[]) {
> +VMSTATE_UINTTL(env.hstatus, RISCVCPU),
> +VMSTATE_UINTTL(env.hedeleg, RISCVCPU),
> +VMSTATE_UINTTL(env.hideleg, RISCVCPU),
> +VMSTATE_UINTTL(env.hcounteren, RISCVCPU),
> +VMSTATE_UINTTL(env.htval, RISCVCPU),
> +VMSTATE_UINTTL(env.htinst, RISCVCPU),
> +VMSTATE_UINTTL(env.hgatp, RISCVCPU),
> +VMSTATE_UINT64(env.htimedelta, RISCVCPU),
> +
> +VMSTATE_UINT64(env.vsstatus, RISCVCPU),
> +VMSTATE_UINTTL(env.vstvec, RISCVCPU),
> +VMSTATE_UINTTL(env.vsscratch, RISCVCPU),
> +VMSTATE_UINTTL(env.vsepc, RISCVCPU),
> +VMSTATE_UINTTL(env.vscause, RISCVCPU),
> +VMSTATE_UINTTL(env.vstval, RISCVCPU),
> +VMSTATE_UINTTL(env.vsatp, RISCVCPU),
> +
> +VMSTATE_UINTTL(env.mtval2, RISCVCPU),
> +VMSTATE_UINTTL(env.mtinst, RISCVCPU),
> +
> +VMSTATE_UINTTL(env.stvec_hs, RISCVCPU),
> +VMSTATE_UINTTL(env.sscratch_hs, RISCVCPU),
> +VMSTATE_UINTTL(env.sepc_hs, RISCVCPU),
> +VMSTATE_UINTTL(env.scause_hs, RISCVCPU),
> +VMSTATE_UINTTL(env.stval_hs, RISCVCPU),
> +VMSTATE_UINTTL(env.satp_hs, RISCVCPU),
> +VMSTATE_UINT64(env.mstatus_hs, RISCVCPU),
> +
> +VMSTATE_END_OF_LIST()
> +}
> +};
> +
>  const VMStateDescription vmstate_riscv_cpu = {
>  .name = "cpu",
>  .version_id = 1,
> @@ -119,6 +165,7 @@ const VMStateDescription vmstate_riscv_cpu = {
>  },
>  .subsections = (const VMStateDescription * []) {
>  _pmp,
> +_hyper,
>  NULL
>  }
>  };
> --
> 2.19.1
>
>



Re: [PATCH V3 3/6] target/riscv: Add PMP state description

2020-10-23 Thread Alistair Francis
On Fri, Oct 23, 2020 at 2:16 AM Yifei Jiang  wrote:
>
> In the case of supporting PMP feature, add PMP state description
> to vmstate_riscv_cpu.
>
> 'vmstate_pmp_addr' and 'num_rules' could be regenerated by
> pmp_update_rule(). But there exists the problem of updating
> num_rules repeatedly in pmp_update_rule(). So here extracts
> pmp_update_rule_addr() and pmp_update_rule_nums() to update
> 'vmstate_pmp_addr' and 'num_rules' respectively.
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Yipeng Yin 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/machine.c | 50 ++
>  target/riscv/pmp.c | 29 ++--
>  target/riscv/pmp.h |  2 ++
>  3 files changed, 70 insertions(+), 11 deletions(-)
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 32edbcba7c..fc1461d88e 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -22,6 +22,52 @@
>  #include "sysemu/kvm.h"
>  #include "migration/cpu.h"
>
> +static bool pmp_needed(void *opaque)
> +{
> +RISCVCPU *cpu = opaque;
> +CPURISCVState *env = >env;
> +
> +return riscv_feature(env, RISCV_FEATURE_PMP);
> +}
> +
> +static int pmp_post_load(void *opaque, int version_id)
> +{
> +RISCVCPU *cpu = opaque;
> +CPURISCVState *env = >env;
> +int i;
> +
> +for (i = 0; i < MAX_RISCV_PMPS; i++) {
> +pmp_update_rule_addr(env, i);
> +}
> +pmp_update_rule_nums(env);
> +
> +return 0;
> +}
> +
> +static const VMStateDescription vmstate_pmp_entry = {
> +.name = "cpu/pmp/entry",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.fields = (VMStateField[]) {
> +VMSTATE_UINTTL(addr_reg, pmp_entry_t),
> +VMSTATE_UINT8(cfg_reg, pmp_entry_t),
> +VMSTATE_END_OF_LIST()
> +}
> +};
> +
> +static const VMStateDescription vmstate_pmp = {
> +.name = "cpu/pmp",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.needed = pmp_needed,
> +.post_load = pmp_post_load,
> +.fields = (VMStateField[]) {
> +VMSTATE_STRUCT_ARRAY(env.pmp_state.pmp, RISCVCPU, MAX_RISCV_PMPS,
> + 0, vmstate_pmp_entry, pmp_entry_t),
> +VMSTATE_END_OF_LIST()
> +}
> +};
> +
>  const VMStateDescription vmstate_riscv_cpu = {
>  .name = "cpu",
>  .version_id = 1,
> @@ -70,5 +116,9 @@ const VMStateDescription vmstate_riscv_cpu = {
>  VMSTATE_UINT64(env.timecmp, RISCVCPU),
>
>  VMSTATE_END_OF_LIST()
> +},
> +.subsections = (const VMStateDescription * []) {
> +_pmp,
> +NULL
>  }
>  };
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index c394e867f8..2eda8e1e2f 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -136,18 +136,8 @@ static void pmp_decode_napot(target_ulong a, 
> target_ulong *sa, target_ulong *ea)
>  }
>  }
>
> -
> -/* Convert cfg/addr reg values here into simple 'sa' --> start address and 
> 'ea'
> - *   end address values.
> - *   This function is called relatively infrequently whereas the check that
> - *   an address is within a pmp rule is called often, so optimise that one
> - */
> -static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
> +void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
>  {
> -int i;
> -
> -env->pmp_state.num_rules = 0;
> -
>  uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg;
>  target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg;
>  target_ulong prev_addr = 0u;
> @@ -186,7 +176,13 @@ static void pmp_update_rule(CPURISCVState *env, uint32_t 
> pmp_index)
>
>  env->pmp_state.addr[pmp_index].sa = sa;
>  env->pmp_state.addr[pmp_index].ea = ea;
> +}
>
> +void pmp_update_rule_nums(CPURISCVState *env)
> +{
> +int i;
> +
> +env->pmp_state.num_rules = 0;
>  for (i = 0; i < MAX_RISCV_PMPS; i++) {
>  const uint8_t a_field =
>  pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
> @@ -196,6 +192,17 @@ static void pmp_update_rule(CPURISCVState *env, uint32_t 
> pmp_index)
>  }
>  }
>
> +/* Convert cfg/addr reg values here into simple 'sa' --> start address and 
> 'ea'
> + *   end address values.
> + *   This function is called relatively infrequently whereas the check that
> + *   an address is within a pmp rule is called often, so optimise that one
> + */
> +static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
> +{
> +pmp_update_rule_addr(env, pmp_index);
> +pmp_update_rule_nums(env);
> +}
> +
>  static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong 
> addr)
>  {
>  int result = 0;
> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
> index 6a8f072871..6c6b4c9bef 100644
> --- a/target/riscv/pmp.h
> +++ b/target/riscv/pmp.h
> @@ -62,5 +62,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
> addr,
>  target_ulong size, pmp_priv_t priv, target_ulong mode);
>  bool 

Re: [PATCH V3 2/6] target/riscv: Add basic vmstate description of CPU

2020-10-23 Thread Alistair Francis
On Fri, Oct 23, 2020 at 2:13 AM Yifei Jiang  wrote:
>
> Add basic CPU state description to the newly created machine.c
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Yipeng Yin 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c   |  8 +
>  target/riscv/internals.h |  4 +++
>  target/riscv/machine.c   | 74 
>  target/riscv/meson.build |  3 +-
>  4 files changed, 81 insertions(+), 8 deletions(-)
>  create mode 100644 target/riscv/machine.c
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index dd05a220c7..6a0264fc6b 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -22,6 +22,7 @@
>  #include "qemu/ctype.h"
>  #include "qemu/log.h"
>  #include "cpu.h"
> +#include "internals.h"
>  #include "exec/exec-all.h"
>  #include "qapi/error.h"
>  #include "qemu/error-report.h"
> @@ -498,13 +499,6 @@ static void riscv_cpu_init(Object *obj)
>  cpu_set_cpustate_pointers(cpu);
>  }
>
> -#ifndef CONFIG_USER_ONLY
> -static const VMStateDescription vmstate_riscv_cpu = {
> -.name = "cpu",
> -.unmigratable = 1,
> -};
> -#endif
> -
>  static Property riscv_cpu_properties[] = {
>  DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true),
>  DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
> index f1a546dba6..b15ad394bb 100644
> --- a/target/riscv/internals.h
> +++ b/target/riscv/internals.h
> @@ -38,6 +38,10 @@ target_ulong fclass_d(uint64_t frs1);
>  #define SEW32 2
>  #define SEW64 3
>
> +#ifndef CONFIG_USER_ONLY
> +extern const VMStateDescription vmstate_riscv_cpu;
> +#endif
> +
>  static inline uint64_t nanbox_s(float32 f)
>  {
>  return f | MAKE_64BIT_MASK(32, 32);
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> new file mode 100644
> index 00..32edbcba7c
> --- /dev/null
> +++ b/target/riscv/machine.c
> @@ -0,0 +1,74 @@
> +/*
> + * RISC-V VMState Description
> + *
> + * Copyright (c) 2020 Huawei Technologies Co., Ltd
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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 .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "cpu.h"
> +#include "qemu/error-report.h"
> +#include "sysemu/kvm.h"
> +#include "migration/cpu.h"
> +
> +const VMStateDescription vmstate_riscv_cpu = {
> +.name = "cpu",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.fields = (VMStateField[]) {
> +VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
> +VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
> +VMSTATE_UINTTL(env.pc, RISCVCPU),
> +VMSTATE_UINTTL(env.load_res, RISCVCPU),
> +VMSTATE_UINTTL(env.load_val, RISCVCPU),
> +VMSTATE_UINTTL(env.frm, RISCVCPU),
> +VMSTATE_UINTTL(env.badaddr, RISCVCPU),
> +VMSTATE_UINTTL(env.guest_phys_fault_addr, RISCVCPU),
> +VMSTATE_UINTTL(env.priv_ver, RISCVCPU),
> +VMSTATE_UINTTL(env.vext_ver, RISCVCPU),
> +VMSTATE_UINTTL(env.misa, RISCVCPU),
> +VMSTATE_UINTTL(env.misa_mask, RISCVCPU),
> +VMSTATE_UINT32(env.features, RISCVCPU),
> +VMSTATE_UINTTL(env.priv, RISCVCPU),
> +VMSTATE_UINTTL(env.virt, RISCVCPU),
> +VMSTATE_UINTTL(env.resetvec, RISCVCPU),
> +VMSTATE_UINTTL(env.mhartid, RISCVCPU),
> +VMSTATE_UINT64(env.mstatus, RISCVCPU),
> +VMSTATE_UINTTL(env.mip, RISCVCPU),
> +VMSTATE_UINT32(env.miclaim, RISCVCPU),
> +VMSTATE_UINTTL(env.mie, RISCVCPU),
> +VMSTATE_UINTTL(env.mideleg, RISCVCPU),
> +VMSTATE_UINTTL(env.sptbr, RISCVCPU),
> +VMSTATE_UINTTL(env.satp, RISCVCPU),
> +VMSTATE_UINTTL(env.sbadaddr, RISCVCPU),
> +VMSTATE_UINTTL(env.mbadaddr, RISCVCPU),
> +VMSTATE_UINTTL(env.medeleg, RISCVCPU),
> +VMSTATE_UINTTL(env.stvec, RISCVCPU),
> +VMSTATE_UINTTL(env.sepc, RISCVCPU),
> +VMSTATE_UINTTL(env.scause, RISCVCPU),
> +VMSTATE_UINTTL(env.mtvec, RISCVCPU),
> +VMSTATE_UINTTL(env.mepc, RISCVCPU),
> +VMSTATE_UINTTL(env.mcause, RISCVCPU),
> +VMSTATE_UINTTL(env.mtval, RISCVCPU),
> +VMSTATE_UINTTL(env.scounteren, RISCVCPU),
> +VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
> +VMSTATE_UINTTL(env.sscratch, RISCVCPU),
> +VMSTATE_UINTTL(env.mscratch, RISCVCPU),
> +VMSTATE_UINT64(env.mfromhost, RISCVCPU),
> +VMSTATE_UINT64(env.mtohost, RISCVCPU),

Re: [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit

2020-10-23 Thread Alistair Francis
On Fri, Oct 23, 2020 at 2:17 AM Yifei Jiang  wrote:
>
> mstatus/mstatush and vsstatus/vsstatush are two halved for RISCV32.
> This patch expands mstatus and vsstatus to uint64_t instead of
> target_ulong so that it can be saved as one unit and reduce some
> ifdefs in the code.
>
> Signed-off-by: Yifei Jiang 
> Signed-off-by: Yipeng Yin 

Argh. I just sent a similar patch. I was hoping to save you having to do this.

Sorry about that.

I'm happy to apply yours as it was first.

> ---
>  target/riscv/cpu.c|  8 +++--
>  target/riscv/cpu.h| 16 ++---
>  target/riscv/cpu_bits.h   | 16 -
>  target/riscv/cpu_helper.c | 72 ---
>  target/riscv/csr.c| 28 ---
>  target/riscv/op_helper.c  | 49 +-
>  6 files changed, 82 insertions(+), 107 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0bbfd7f457..dd05a220c7 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -216,13 +216,15 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
> int flags)
>  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc  ", env->pc);
>  #ifndef CONFIG_USER_ONLY
>  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
> -qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
> +qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", 
> (target_ulong)env->mstatus);
>  #ifdef TARGET_RISCV32
> -qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ", env->mstatush);
> +qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
> + (target_ulong)(env->mstatus >> 32));
>  #endif
>  if (riscv_has_ext(env, RVH)) {
>  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
> -qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ", 
> env->vsstatus);
> +qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ",
> + (target_ulong)env->vsstatus);
>  }
>  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip ", env->mip);
>  qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", env->mie);
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index de275782e6..57050f2268 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -140,14 +140,10 @@ struct CPURISCVState {
>  target_ulong resetvec;
>
>  target_ulong mhartid;
> -target_ulong mstatus;
> +uint64_t mstatus;
>
>  target_ulong mip;
>
> -#ifdef TARGET_RISCV32
> -target_ulong mstatush;
> -#endif
> -
>  uint32_t miclaim;
>
>  target_ulong mie;
> @@ -179,16 +175,13 @@ struct CPURISCVState {
>  uint64_t htimedelta;
>
>  /* Virtual CSRs */
> -target_ulong vsstatus;
> +uint64_t vsstatus;
>  target_ulong vstvec;
>  target_ulong vsscratch;
>  target_ulong vsepc;
>  target_ulong vscause;
>  target_ulong vstval;
>  target_ulong vsatp;
> -#ifdef TARGET_RISCV32
> -target_ulong vsstatush;
> -#endif
>
>  target_ulong mtval2;
>  target_ulong mtinst;
> @@ -200,10 +193,7 @@ struct CPURISCVState {
>  target_ulong scause_hs;
>  target_ulong stval_hs;
>  target_ulong satp_hs;
> -target_ulong mstatus_hs;
> -#ifdef TARGET_RISCV32
> -target_ulong mstatush_hs;
> -#endif
> +uint64_t mstatus_hs;
>
>  target_ulong scounteren;
>  target_ulong mcounteren;
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index bd36062877..62ca6b6f89 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -5,9 +5,14 @@
>
>  #define get_field(reg, mask) (((reg) & \
>   (target_ulong)(mask)) / ((mask) & ~((mask) << 1)))
> +#define get_field64(reg, mask) (((reg) & \
> +   (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
>  #define set_field(reg, mask, val) (((reg) & ~(target_ulong)(mask)) | \
>   (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
>   (target_ulong)(mask)))
> +#define set_field64(reg, mask, val) (((reg) & ~(uint64_t)(mask)) | \
> +   (((uint64_t)(val) * ((mask) & ~((mask) << 1))) & \
> +   (uint64_t)(mask)))

We should just be able to change the existing ones to use uint64_t.

>
>  /* Floating point round mode */
>  #define FSR_RD_SHIFT5
> @@ -381,19 +386,10 @@
>  #define MSTATUS_TVM 0x0010 /* since: priv-1.10 */
>  #define MSTATUS_TW  0x2000 /* since: priv-1.10 */
>  #define MSTATUS_TSR 0x4000 /* since: priv-1.10 */
> -#if defined(TARGET_RISCV64)
>  #define MSTATUS_GVA 0x40ULL
>  #define MSTATUS_MPV 0x80ULL
> -#elif defined(TARGET_RISCV32)
> -#define MSTATUS_GVA 0x0040
> -#define MSTATUS_MPV 0x0080
> -#endif
>
> -#ifdef TARGET_RISCV32
> -# define MSTATUS_MPV_ISSET(env)  get_field(env->mstatush, MSTATUS_MPV)
> -#else
> -# define MSTATUS_MPV_ISSET(env)  get_field(env->mstatus, MSTATUS_MPV)
> 

Re: [PATCH 2/2] riscv: Add sifive test device to sifive_u target

2020-10-23 Thread Alistair Francis
On Fri, Oct 23, 2020 at 2:48 PM Keith Packard via  wrote:
>
> The SiFive test device provides a mechanism for terminating the qemu
> instance from the emulated system. This patch adds that device to the
> sifive_u target, including constructing a suitable FDT node.
>
> Signed-off-by: Keith Packard 
> ---
>  hw/riscv/sifive_u.c | 15 +++
>  include/hw/riscv/sifive_u.h |  1 +
>  2 files changed, 16 insertions(+)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 6ad975d692..8d803fe7c0 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -15,6 +15,7 @@
>   * 5) OTP (One-Time Programmable) memory with stored serial number
>   * 6) GEM (Gigabit Ethernet Controller) and management block
>   * 7) DMA (Direct Memory Access Controller)
> + * 8) TEST (Test device)
>   *
>   * This board currently generates devicetree dynamically that indicates at 
> least
>   * two harts and up to five harts.
> @@ -44,6 +45,7 @@
>  #include "hw/char/serial.h"
>  #include "hw/cpu/cluster.h"
>  #include "hw/misc/unimp.h"
> +#include "hw/misc/sifive_test.h"
>  #include "target/riscv/cpu.h"
>  #include "hw/riscv/riscv_hart.h"
>  #include "hw/riscv/sifive_u.h"
> @@ -72,6 +74,7 @@ static const struct MemmapEntry {
>  } sifive_u_memmap[] = {
>  [SIFIVE_U_DEV_DEBUG] ={0x0,  0x100 },
>  [SIFIVE_U_DEV_MROM] = { 0x1000, 0xf000 },
> +[SIFIVE_U_DEV_TEST] = {   0x10, 0x1000 },

I also don't see this in the FU540 memory map.

Alistair

>  [SIFIVE_U_DEV_CLINT] ={  0x200,0x1 },
>  [SIFIVE_U_DEV_L2CC] = {  0x201, 0x1000 },
>  [SIFIVE_U_DEV_PDMA] = {  0x300,   0x10 },
> @@ -397,6 +400,16 @@ static void create_fdt(SiFiveUState *s, const struct 
> MemmapEntry *memmap,
>  qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
>
>  g_free(nodename);
> +
> +nodename = g_strdup_printf("/soc/test@%lx",
> +   (long)memmap[SIFIVE_U_DEV_TEST].base);
> +qemu_fdt_add_subnode(fdt, nodename);
> +qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,test0");
> +qemu_fdt_setprop_cells(fdt, nodename, "reg",
> +   0x0, memmap[SIFIVE_U_DEV_TEST].base,
> +   0x0, memmap[SIFIVE_U_DEV_TEST].size);
> +
> +g_free(nodename);
>  }
>
>  static void sifive_u_machine_reset(void *opaque, int n, int level)
> @@ -780,6 +793,8 @@ static void sifive_u_soc_realize(DeviceState *dev, Error 
> **errp)
>  sysbus_connect_irq(SYS_BUS_DEVICE(>gem), 0,
> qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_GEM_IRQ));
>
> +sifive_test_create(memmap[SIFIVE_U_DEV_TEST].base);
> +
>  create_unimplemented_device("riscv.sifive.u.gem-mgmt",
>  memmap[SIFIVE_U_DEV_GEM_MGMT].base, 
> memmap[SIFIVE_U_DEV_GEM_MGMT].size);
>
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index 22e7e6efa1..4b3ebc3fc6 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -72,6 +72,7 @@ typedef struct SiFiveUState {
>  enum {
>  SIFIVE_U_DEV_DEBUG,
>  SIFIVE_U_DEV_MROM,
> +SIFIVE_U_DEV_TEST,
>  SIFIVE_U_DEV_CLINT,
>  SIFIVE_U_DEV_L2CC,
>  SIFIVE_U_DEV_PDMA,
> --
> 2.28.0
>
>



Re: [PATCH 1/2] riscv: Add sifive test device to sifive_e target

2020-10-23 Thread Alistair Francis
On Fri, Oct 23, 2020 at 2:45 PM Keith Packard via  wrote:
>
> The SiFive test device provides a mechanism for terminating the qemu
> instance from the emulated system. This patch adds that device to the
> sifive_e target.
>
> Signed-off-by: Keith Packard 
> ---
>  hw/riscv/sifive_e.c | 4 
>  include/hw/riscv/sifive_e.h | 1 +
>  2 files changed, 5 insertions(+)
>
> diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> index fcfac16816..417e3a5409 100644
> --- a/hw/riscv/sifive_e.c
> +++ b/hw/riscv/sifive_e.c
> @@ -11,6 +11,7 @@
>   * 3) PRCI (Power, Reset, Clock, Interrupt)
>   * 4) Registers emulated as RAM: AON, GPIO, QSPI, PWM
>   * 5) Flash memory emulated as RAM
> + * 6) TEST (Test device)
>   *
>   * The Mask ROM reset vector jumps to the flash payload at 0x2040_.
>   * The OTP ROM and Flash boot code will be emulated in a future version.
> @@ -45,6 +46,7 @@
>  #include "hw/intc/sifive_clint.h"
>  #include "hw/intc/sifive_plic.h"
>  #include "hw/misc/sifive_e_prci.h"
> +#include "hw/misc/sifive_test.h"
>  #include "chardev/char.h"
>  #include "sysemu/arch_init.h"
>  #include "sysemu/sysemu.h"
> @@ -57,6 +59,7 @@ static const struct MemmapEntry {
>  [SIFIVE_E_DEV_DEBUG] ={0x0, 0x1000 },
>  [SIFIVE_E_DEV_MROM] = { 0x1000, 0x2000 },
>  [SIFIVE_E_DEV_OTP] =  {0x2, 0x2000 },
> +[SIFIVE_E_DEV_TEST] = {   0x10, 0x1000 },

I don't see this mentioned in the FE310 data sheet. Is it included in
the hardware?

Alistair

>  [SIFIVE_E_DEV_CLINT] ={  0x200,0x1 },
>  [SIFIVE_E_DEV_PLIC] = {  0xc00,  0x400 },
>  [SIFIVE_E_DEV_AON] =  { 0x1000, 0x8000 },
> @@ -216,6 +219,7 @@ static void sifive_e_soc_realize(DeviceState *dev, Error 
> **errp)
>  memmap[SIFIVE_E_DEV_CLINT].size, 0, ms->smp.cpus,
>  SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
>  SIFIVE_CLINT_TIMEBASE_FREQ, false);
> +sifive_test_create(memmap[SIFIVE_E_DEV_TEST].base);
>  create_unimplemented_device("riscv.sifive.e.aon",
>  memmap[SIFIVE_E_DEV_AON].base, memmap[SIFIVE_E_DEV_AON].size);
>  sifive_e_prci_create(memmap[SIFIVE_E_DEV_PRCI].base);
> diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
> index 83604da805..92bab6d0d4 100644
> --- a/include/hw/riscv/sifive_e.h
> +++ b/include/hw/riscv/sifive_e.h
> @@ -56,6 +56,7 @@ enum {
>  SIFIVE_E_DEV_DEBUG,
>  SIFIVE_E_DEV_MROM,
>  SIFIVE_E_DEV_OTP,
> +SIFIVE_E_DEV_TEST,
>  SIFIVE_E_DEV_CLINT,
>  SIFIVE_E_DEV_PLIC,
>  SIFIVE_E_DEV_AON,
> --
> 2.28.0
>
>



Re: [PATCH 2/2] hw/riscv: virt: Allow passing custom DTB

2020-10-23 Thread Alistair Francis
On Wed, Oct 21, 2020 at 10:34 PM Anup Patel  wrote:
>
> Extend virt machine to allow passing custom DTB using "-dtb"
> command-line parameter. This will help users pass modified DTB
> to virt machine.
>
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/virt.c | 27 ---
>  1 file changed, 20 insertions(+), 7 deletions(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 41bd2f38ba..d535119e37 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -181,6 +181,7 @@ static void create_fdt(RISCVVirtState *s, const struct 
> MemmapEntry *memmap,
>  {
>  void *fdt;
>  int i, cpu, socket;
> +const char *dtb_filename;
>  MachineState *mc = MACHINE(s);
>  uint64_t addr, size;
>  uint32_t *clint_cells, *plic_cells;
> @@ -194,10 +195,20 @@ static void create_fdt(RISCVVirtState *s, const struct 
> MemmapEntry *memmap,
>  hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
>  hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
>
> -fdt = s->fdt = create_device_tree(>fdt_size);
> -if (!fdt) {
> -error_report("create_device_tree() failed");
> -exit(1);
> +dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
> +if (dtb_filename) {
> +fdt = s->fdt = load_device_tree(dtb_filename, >fdt_size);
> +if (!fdt) {
> +error_report("load_device_tree() failed");
> +exit(1);
> +}
> +goto update_bootargs;
> +} else {
> +fdt = s->fdt = create_device_tree(>fdt_size);
> +if (!fdt) {
> +error_report("create_device_tree() failed");
> +exit(1);
> +}
>  }
>
>  qemu_fdt_setprop_string(fdt, "/", "model", "riscv-virtio,qemu");
> @@ -418,9 +429,6 @@ static void create_fdt(RISCVVirtState *s, const struct 
> MemmapEntry *memmap,
>
>  qemu_fdt_add_subnode(fdt, "/chosen");
>  qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", name);
> -if (cmdline) {
> -qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
> -}
>  g_free(name);
>
>  name = g_strdup_printf("/soc/rtc@%lx", (long)memmap[VIRT_RTC].base);
> @@ -441,6 +449,11 @@ static void create_fdt(RISCVVirtState *s, const struct 
> MemmapEntry *memmap,
>   2, flashbase + flashsize, 2, flashsize);
>  qemu_fdt_setprop_cell(s->fdt, name, "bank-width", 4);
>  g_free(name);
> +
> +update_bootargs:
> +if (cmdline) {
> +qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
> +}
>  }
>
>  static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
> --
> 2.25.1
>
>



Re: [PATCH 1/2] hw/riscv: sifive_u: Allow passing custom DTB

2020-10-23 Thread Alistair Francis
On Wed, Oct 21, 2020 at 10:33 PM Anup Patel  wrote:
>
> Extend sifive_u machine to allow passing custom DTB using "-dtb"
> command-line parameter. This will help users pass modified DTB
> or Linux SiFive DTB to sifive_u machine.
>
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/sifive_u.c | 28 
>  1 file changed, 20 insertions(+), 8 deletions(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 6ad975d692..554e38abf0 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -100,14 +100,25 @@ static void create_fdt(SiFiveUState *s, const struct 
> MemmapEntry *memmap,
>  int cpu;
>  uint32_t *cells;
>  char *nodename;
> +const char *dtb_filename;
>  char ethclk_names[] = "pclk\0hclk";
>  uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
>  uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
>
> -fdt = s->fdt = create_device_tree(>fdt_size);
> -if (!fdt) {
> -error_report("create_device_tree() failed");
> -exit(1);
> +dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
> +if (dtb_filename) {
> +fdt = s->fdt = load_device_tree(dtb_filename, >fdt_size);
> +if (!fdt) {
> +error_report("load_device_tree() failed");
> +exit(1);
> +}
> +goto update_bootargs;
> +} else {
> +fdt = s->fdt = create_device_tree(>fdt_size);
> +if (!fdt) {
> +error_report("create_device_tree() failed");
> +exit(1);
> +}
>  }
>
>  qemu_fdt_setprop_string(fdt, "/", "model", "SiFive HiFive Unleashed 
> A00");
> @@ -390,13 +401,14 @@ static void create_fdt(SiFiveUState *s, const struct 
> MemmapEntry *memmap,
>
>  qemu_fdt_add_subnode(fdt, "/chosen");
>  qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
> -if (cmdline) {
> -qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
> -}
> -
>  qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
>
>  g_free(nodename);
> +
> +update_bootargs:
> +if (cmdline) {
> +qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
> +}
>  }
>
>  static void sifive_u_machine_reset(void *opaque, int n, int level)
> --
> 2.25.1
>
>



Re: [PATCH v1 1/5] target/riscv: Add a virtualised MMU Mode

2020-10-23 Thread Alistair Francis
On Fri, Oct 23, 2020 at 12:13 PM Richard Henderson
 wrote:
>
> On 10/23/20 8:26 AM, Alistair Francis wrote:
> > +++ b/target/riscv/cpu-param.h
> > @@ -18,6 +18,6 @@
> >  # define TARGET_VIRT_ADDR_SPACE_BITS 32 /* sv32 */
> >  #endif
> >  #define TARGET_PAGE_BITS 12 /* 4 KiB Pages */
> > -#define NB_MMU_MODES 4
> > +#define NB_MMU_MODES 8
>
> Is there really a PRV_M + virt enabled state?

No, there isn't.

>
> > +#define TB_FLAGS_PRIV_MMU_MASK3
> ...
> > -int mode = mmu_idx;
> > +int mode = mmu_idx & 0x3;
>
> Use that MASK here?

Good idea.

Alistair

>
>
> r~



[PATCH] riscv: Add semihosting support [v8]

2020-10-23 Thread Keith Packard via
Adapt the arm semihosting support code for RISCV. This implementation
is based on the standard for RISC-V semihosting version 0.2 as
documented in

   https://github.com/riscv/riscv-semihosting-spec/releases/tag/0.2

Signed-off-by: Keith Packard 

---

v2:
Update PC after exception is handled to follow
change in the ARM version for SYS_READC

v3:
Disallow semihosting in user mode; report a regular
breakpoint in that case.

v4:
Fix errors reported by checkpatch

v5:
Reference current RISC-V semihosting specification

v6:
Add support for semihosting in riscv64-linux-user and
riscv32-linux-user

v7:
Add meson build support

v8:
Fix errors reported by checkpatch that crept in.
---
 MAINTAINERS   |1 +
 default-configs/devices/riscv32-softmmu.mak   |1 +
 default-configs/devices/riscv64-softmmu.mak   |1 +
 linux-user/meson.build|1 +
 linux-user/qemu.h |4 +-
 linux-user/riscv/meson.build  |2 +
 linux-user/riscv/semihost.c   |   76 ++
 qemu-options.hx   |   10 +-
 target/riscv/cpu.h|7 +
 target/riscv/cpu_bits.h   |1 +
 target/riscv/cpu_helper.c |9 +
 .../riscv/insn_trans/trans_privileged.c.inc   |   24 +-
 target/riscv/meson.build  |1 +
 target/riscv/riscv-semi.c | 1086 +
 target/riscv/translate.c  |   11 +
 15 files changed, 1229 insertions(+), 6 deletions(-)
 create mode 100644 linux-user/riscv/meson.build
 create mode 100644 linux-user/riscv/semihost.c
 create mode 100644 target/riscv/riscv-semi.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6a197bd358..8cf5b1e448 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -279,6 +279,7 @@ M: Palmer Dabbelt 
 M: Alistair Francis 
 M: Sagar Karandikar 
 M: Bastian Koppelmann 
+M: Keith Packard 
 L: qemu-ri...@nongnu.org
 S: Supported
 F: target/riscv/
diff --git a/default-configs/devices/riscv32-softmmu.mak 
b/default-configs/devices/riscv32-softmmu.mak
index 94a236c9c2..e8a4eeebec 100644
--- a/default-configs/devices/riscv32-softmmu.mak
+++ b/default-configs/devices/riscv32-softmmu.mak
@@ -3,6 +3,7 @@
 # Uncomment the following lines to disable these optional devices:
 #
 #CONFIG_PCI_DEVICES=n
+CONFIG_SEMIHOSTING=y
 
 # Boards:
 #
diff --git a/default-configs/devices/riscv64-softmmu.mak 
b/default-configs/devices/riscv64-softmmu.mak
index 76b6195648..d8a87b7671 100644
--- a/default-configs/devices/riscv64-softmmu.mak
+++ b/default-configs/devices/riscv64-softmmu.mak
@@ -3,6 +3,7 @@
 # Uncomment the following lines to disable these optional devices:
 #
 #CONFIG_PCI_DEVICES=n
+CONFIG_SEMIHOSTING=y
 
 # Boards:
 #
diff --git a/linux-user/meson.build b/linux-user/meson.build
index 2b94e4ba24..31b5ed99b5 100644
--- a/linux-user/meson.build
+++ b/linux-user/meson.build
@@ -29,6 +29,7 @@ subdir('microblaze')
 subdir('mips64')
 subdir('mips')
 subdir('ppc')
+subdir('riscv')
 subdir('s390x')
 subdir('sh4')
 subdir('sparc64')
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 941ca99722..faeaab9614 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -105,6 +105,8 @@ typedef struct TaskState {
 /* FPA state */
 FPA11 fpa;
 # endif
+#endif
+#if defined(TARGET_ARM) || defined(TARGET_RISCV)
 int swi_errno;
 #endif
 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
@@ -118,7 +120,7 @@ typedef struct TaskState {
 #ifdef TARGET_M68K
 abi_ulong tp_value;
 #endif
-#if defined(TARGET_ARM) || defined(TARGET_M68K)
+#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_RISCV)
 /* Extra fields for semihosted binaries.  */
 abi_ulong heap_base;
 abi_ulong heap_limit;
diff --git a/linux-user/riscv/meson.build b/linux-user/riscv/meson.build
new file mode 100644
index 00..aee3179cdb
--- /dev/null
+++ b/linux-user/riscv/meson.build
@@ -0,0 +1,2 @@
+linux_user_ss.add(when: 'TARGET_RISCV64', if_true: files('semihost.c'))
+linux_user_ss.add(when: 'TARGET_RISCV32', if_true: files('semihost.c'))
diff --git a/linux-user/riscv/semihost.c b/linux-user/riscv/semihost.c
new file mode 100644
index 00..2d35ebab68
--- /dev/null
+++ b/linux-user/riscv/semihost.c
@@ -0,0 +1,76 @@
+/*
+ * RISC-V Semihosting Console Support
+ *
+ * Copyright (c) 2019 Linaro Ltd
+ *
+ * Currently RISC-V and ARM are unique in having support for semihosting 
support
+ * in linux-user. So for now we implement the common console API but
+ * just for risc-v and arm linux-user.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "hw/semihosting/console.h"
+#include "qemu.h"
+#include 
+
+int qemu_semihosting_console_outs(CPUArchState *env, target_ulong addr)
+{
+int len = target_strlen(addr);
+void *s;
+

[PATCH 2/2] riscv: Add sifive test device to sifive_u target

2020-10-23 Thread Keith Packard via
The SiFive test device provides a mechanism for terminating the qemu
instance from the emulated system. This patch adds that device to the
sifive_u target, including constructing a suitable FDT node.

Signed-off-by: Keith Packard 
---
 hw/riscv/sifive_u.c | 15 +++
 include/hw/riscv/sifive_u.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 6ad975d692..8d803fe7c0 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -15,6 +15,7 @@
  * 5) OTP (One-Time Programmable) memory with stored serial number
  * 6) GEM (Gigabit Ethernet Controller) and management block
  * 7) DMA (Direct Memory Access Controller)
+ * 8) TEST (Test device)
  *
  * This board currently generates devicetree dynamically that indicates at 
least
  * two harts and up to five harts.
@@ -44,6 +45,7 @@
 #include "hw/char/serial.h"
 #include "hw/cpu/cluster.h"
 #include "hw/misc/unimp.h"
+#include "hw/misc/sifive_test.h"
 #include "target/riscv/cpu.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_u.h"
@@ -72,6 +74,7 @@ static const struct MemmapEntry {
 } sifive_u_memmap[] = {
 [SIFIVE_U_DEV_DEBUG] ={0x0,  0x100 },
 [SIFIVE_U_DEV_MROM] = { 0x1000, 0xf000 },
+[SIFIVE_U_DEV_TEST] = {   0x10, 0x1000 },
 [SIFIVE_U_DEV_CLINT] ={  0x200,0x1 },
 [SIFIVE_U_DEV_L2CC] = {  0x201, 0x1000 },
 [SIFIVE_U_DEV_PDMA] = {  0x300,   0x10 },
@@ -397,6 +400,16 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
 
 g_free(nodename);
+
+nodename = g_strdup_printf("/soc/test@%lx",
+   (long)memmap[SIFIVE_U_DEV_TEST].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,test0");
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+   0x0, memmap[SIFIVE_U_DEV_TEST].base,
+   0x0, memmap[SIFIVE_U_DEV_TEST].size);
+
+g_free(nodename);
 }
 
 static void sifive_u_machine_reset(void *opaque, int n, int level)
@@ -780,6 +793,8 @@ static void sifive_u_soc_realize(DeviceState *dev, Error 
**errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>gem), 0,
qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_GEM_IRQ));
 
+sifive_test_create(memmap[SIFIVE_U_DEV_TEST].base);
+
 create_unimplemented_device("riscv.sifive.u.gem-mgmt",
 memmap[SIFIVE_U_DEV_GEM_MGMT].base, 
memmap[SIFIVE_U_DEV_GEM_MGMT].size);
 
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 22e7e6efa1..4b3ebc3fc6 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -72,6 +72,7 @@ typedef struct SiFiveUState {
 enum {
 SIFIVE_U_DEV_DEBUG,
 SIFIVE_U_DEV_MROM,
+SIFIVE_U_DEV_TEST,
 SIFIVE_U_DEV_CLINT,
 SIFIVE_U_DEV_L2CC,
 SIFIVE_U_DEV_PDMA,
-- 
2.28.0




[PATCH 1/2] riscv: Add sifive test device to sifive_e target

2020-10-23 Thread Keith Packard via
The SiFive test device provides a mechanism for terminating the qemu
instance from the emulated system. This patch adds that device to the
sifive_e target.

Signed-off-by: Keith Packard 
---
 hw/riscv/sifive_e.c | 4 
 include/hw/riscv/sifive_e.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index fcfac16816..417e3a5409 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -11,6 +11,7 @@
  * 3) PRCI (Power, Reset, Clock, Interrupt)
  * 4) Registers emulated as RAM: AON, GPIO, QSPI, PWM
  * 5) Flash memory emulated as RAM
+ * 6) TEST (Test device)
  *
  * The Mask ROM reset vector jumps to the flash payload at 0x2040_.
  * The OTP ROM and Flash boot code will be emulated in a future version.
@@ -45,6 +46,7 @@
 #include "hw/intc/sifive_clint.h"
 #include "hw/intc/sifive_plic.h"
 #include "hw/misc/sifive_e_prci.h"
+#include "hw/misc/sifive_test.h"
 #include "chardev/char.h"
 #include "sysemu/arch_init.h"
 #include "sysemu/sysemu.h"
@@ -57,6 +59,7 @@ static const struct MemmapEntry {
 [SIFIVE_E_DEV_DEBUG] ={0x0, 0x1000 },
 [SIFIVE_E_DEV_MROM] = { 0x1000, 0x2000 },
 [SIFIVE_E_DEV_OTP] =  {0x2, 0x2000 },
+[SIFIVE_E_DEV_TEST] = {   0x10, 0x1000 },
 [SIFIVE_E_DEV_CLINT] ={  0x200,0x1 },
 [SIFIVE_E_DEV_PLIC] = {  0xc00,  0x400 },
 [SIFIVE_E_DEV_AON] =  { 0x1000, 0x8000 },
@@ -216,6 +219,7 @@ static void sifive_e_soc_realize(DeviceState *dev, Error 
**errp)
 memmap[SIFIVE_E_DEV_CLINT].size, 0, ms->smp.cpus,
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
 SIFIVE_CLINT_TIMEBASE_FREQ, false);
+sifive_test_create(memmap[SIFIVE_E_DEV_TEST].base);
 create_unimplemented_device("riscv.sifive.e.aon",
 memmap[SIFIVE_E_DEV_AON].base, memmap[SIFIVE_E_DEV_AON].size);
 sifive_e_prci_create(memmap[SIFIVE_E_DEV_PRCI].base);
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index 83604da805..92bab6d0d4 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -56,6 +56,7 @@ enum {
 SIFIVE_E_DEV_DEBUG,
 SIFIVE_E_DEV_MROM,
 SIFIVE_E_DEV_OTP,
+SIFIVE_E_DEV_TEST,
 SIFIVE_E_DEV_CLINT,
 SIFIVE_E_DEV_PLIC,
 SIFIVE_E_DEV_AON,
-- 
2.28.0




[PATCH 0/2] riscv: Add SiFive test device to sifive targets

2020-10-23 Thread Keith Packard via
The SiFive test device, which is already available in the qemu tree,
allows the system under emulation to shut down qemu. This is currently
used by OpenSBI to terminate QEMU at powerdown time. These two patches
add this device to the two sifive models.





[PATCH v3 6/6] hw/gpio: Add GPIO model for Nuvoton NPCM7xx

2020-10-23 Thread Havard Skinnemoen via
The NPCM7xx chips have multiple GPIO controllers that are mostly
identical except for some minor differences like the reset values of
some registers. Each controller controls up to 32 pins.

Each individual pin is modeled as a pair of unnamed GPIOs -- one for
emitting the actual pin state, and one for driving the pin externally.
Like the nRF51 GPIO controller, a gpio level may be negative, which
means the pin is not driven, or floating.

Reviewed-by: Tyrone Ting 
Signed-off-by: Havard Skinnemoen 
---
 docs/system/arm/nuvoton.rst |   2 +-
 include/hw/arm/npcm7xx.h|   2 +
 include/hw/gpio/npcm7xx_gpio.h  |  55 +
 hw/arm/npcm7xx.c|  80 ++
 hw/gpio/npcm7xx_gpio.c  | 424 
 tests/qtest/npcm7xx_gpio-test.c | 385 +
 hw/gpio/meson.build |   1 +
 hw/gpio/trace-events|   7 +
 tests/qtest/meson.build |   3 +-
 9 files changed, 957 insertions(+), 2 deletions(-)
 create mode 100644 include/hw/gpio/npcm7xx_gpio.h
 create mode 100644 hw/gpio/npcm7xx_gpio.c
 create mode 100644 tests/qtest/npcm7xx_gpio-test.c

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index 99fc61c740..b00d405d52 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -40,11 +40,11 @@ Supported devices
  * Flash Interface Unit (FIU; no protection features)
  * Random Number Generator (RNG)
  * USB host (USBH)
+ * GPIO controller
 
 Missing devices
 ---
 
- * GPIO controller
  * LPC/eSPI host-to-BMC interface, including
 
* Keyboard and mouse controller interface (KBCI)
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index aeee1beaaa..5469247e38 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -18,6 +18,7 @@
 
 #include "hw/boards.h"
 #include "hw/cpu/a9mpcore.h"
+#include "hw/gpio/npcm7xx_gpio.h"
 #include "hw/mem/npcm7xx_mc.h"
 #include "hw/misc/npcm7xx_clk.h"
 #include "hw/misc/npcm7xx_gcr.h"
@@ -79,6 +80,7 @@ typedef struct NPCM7xxState {
 NPCM7xxOTPState fuse_array;
 NPCM7xxMCState  mc;
 NPCM7xxRNGState rng;
+NPCM7xxGPIOStategpio[8];
 EHCISysBusState ehci;
 OHCISysBusState ohci;
 NPCM7xxFIUState fiu[2];
diff --git a/include/hw/gpio/npcm7xx_gpio.h b/include/hw/gpio/npcm7xx_gpio.h
new file mode 100644
index 00..b1d771bd77
--- /dev/null
+++ b/include/hw/gpio/npcm7xx_gpio.h
@@ -0,0 +1,55 @@
+/*
+ * Nuvoton NPCM7xx General Purpose Input / Output (GPIO)
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef NPCM7XX_GPIO_H
+#define NPCM7XX_GPIO_H
+
+#include "exec/memory.h"
+#include "hw/sysbus.h"
+
+/* Number of pins managed by each controller. */
+#define NPCM7XX_GPIO_NR_PINS (32)
+
+/*
+ * Number of registers in our device state structure. Don't change this without
+ * incrementing the version_id in the vmstate.
+ */
+#define NPCM7XX_GPIO_NR_REGS (0x80 / sizeof(uint32_t))
+
+typedef struct NPCM7xxGPIOState {
+SysBusDevice parent;
+
+/* Properties to be defined by the SoC */
+uint32_t reset_pu;
+uint32_t reset_pd;
+uint32_t reset_osrc;
+uint32_t reset_odsc;
+
+MemoryRegion mmio;
+
+qemu_irq irq;
+qemu_irq output[NPCM7XX_GPIO_NR_PINS];
+
+uint32_t pin_level;
+uint32_t ext_level;
+uint32_t ext_driven;
+
+uint32_t regs[NPCM7XX_GPIO_NR_REGS];
+} NPCM7xxGPIOState;
+
+#define TYPE_NPCM7XX_GPIO "npcm7xx-gpio"
+#define NPCM7XX_GPIO(obj) \
+OBJECT_CHECK(NPCM7xxGPIOState, (obj), TYPE_NPCM7XX_GPIO)
+
+#endif /* NPCM7XX_GPIO_H */
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index c1d122576b..47e2b6fc40 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -96,6 +96,14 @@ enum NPCM7xxInterrupt {
 NPCM7XX_WDG2_IRQ,   /* Timer Module 2 Watchdog */
 NPCM7XX_EHCI_IRQ= 61,
 NPCM7XX_OHCI_IRQ= 62,
+NPCM7XX_GPIO0_IRQ   = 116,
+NPCM7XX_GPIO1_IRQ,
+NPCM7XX_GPIO2_IRQ,
+NPCM7XX_GPIO3_IRQ,
+NPCM7XX_GPIO4_IRQ,
+NPCM7XX_GPIO5_IRQ,
+NPCM7XX_GPIO6_IRQ,
+NPCM7XX_GPIO7_IRQ,
 };
 
 /* Total number of GIC interrupts, including internal Cortex-A9 interrupts. */
@@ -130,6 +138,55 @@ static const hwaddr npcm7xx_fiu3_flash_addr[] = {
 0xb800, /* CS3 */
 };
 
+static const struct {
+hwaddr regs_addr;
+uint32_t unconnected_pins;
+uint32_t reset_pu;
+uint32_t reset_pd;
+uint32_t reset_osrc;
+uint32_t reset_odsc;
+} npcm7xx_gpio[] = {
+{
+.regs_addr = 0xf001,
+

[PATCH v3 3/6] hw/timer: Adding watchdog for NPCM7XX Timer.

2020-10-23 Thread Havard Skinnemoen via
From: Hao Wu 

The watchdog is part of NPCM7XX's timer module. Its behavior is
controlled by the WTCR register in the timer.

When enabled, the watchdog issues an interrupt signal after a pre-set
amount of cycles, and issues a reset signal shortly after that.

Reviewed-by: Tyrone Ting 
Signed-off-by: Hao Wu 
Signed-off-by: Havard Skinnemoen 
---
 include/hw/misc/npcm7xx_clk.h |   2 +
 include/hw/timer/npcm7xx_timer.h  |  48 +++-
 hw/arm/npcm7xx.c  |  12 +
 hw/misc/npcm7xx_clk.c |  28 ++
 hw/timer/npcm7xx_timer.c  | 266 ++
 tests/qtest/npcm7xx_watchdog_timer-test.c | 320 ++
 MAINTAINERS   |   1 +
 tests/qtest/meson.build   |   2 +-
 8 files changed, 625 insertions(+), 54 deletions(-)
 create mode 100644 tests/qtest/npcm7xx_watchdog_timer-test.c

diff --git a/include/hw/misc/npcm7xx_clk.h b/include/hw/misc/npcm7xx_clk.h
index cdcc9e8534..2338fbbdb5 100644
--- a/include/hw/misc/npcm7xx_clk.h
+++ b/include/hw/misc/npcm7xx_clk.h
@@ -31,6 +31,8 @@
  */
 #define NPCM7XX_CLK_NR_REGS (0x70 / sizeof(uint32_t))
 
+#define NPCM7XX_WATCHDOG_RESET_GPIO_IN "npcm7xx-clk-watchdog-reset-gpio-in"
+
 typedef struct NPCM7xxCLKState {
 SysBusDevice parent;
 
diff --git a/include/hw/timer/npcm7xx_timer.h b/include/hw/timer/npcm7xx_timer.h
index 878a365a79..6993fd723a 100644
--- a/include/hw/timer/npcm7xx_timer.h
+++ b/include/hw/timer/npcm7xx_timer.h
@@ -29,14 +29,31 @@
  */
 #define NPCM7XX_TIMER_NR_REGS (0x54 / sizeof(uint32_t))
 
+/* The basic watchdog timer period is 2^14 clock cycles. */
+#define NPCM7XX_WATCHDOG_BASETIME_SHIFT 14
+
+#define NPCM7XX_WATCHDOG_RESET_GPIO_OUT "npcm7xx-clk-watchdog-reset-gpio-out"
+
 typedef struct NPCM7xxTimerCtrlState NPCM7xxTimerCtrlState;
 
 /**
- * struct NPCM7xxTimer - Individual timer state.
- * @irq: GIC interrupt line to fire on expiration (if enabled).
+ * struct NPCM7xxBaseTimer - Basic functionality that both regular timer and
+ * watchdog timer use.
  * @qtimer: QEMU timer that notifies us on expiration.
  * @expires_ns: Absolute virtual expiration time.
  * @remaining_ns: Remaining time until expiration if timer is paused.
+ */
+typedef struct NPCM7xxBaseTimer {
+QEMUTimer   qtimer;
+int64_t expires_ns;
+int64_t remaining_ns;
+} NPCM7xxBaseTimer;
+
+/**
+ * struct NPCM7xxTimer - Individual timer state.
+ * @ctrl: The timer module that owns this timer.
+ * @irq: GIC interrupt line to fire on expiration (if enabled).
+ * @base_timer: The basic timer functionality for this timer.
  * @tcsr: The Timer Control and Status Register.
  * @ticr: The Timer Initial Count Register.
  */
@@ -44,21 +61,38 @@ typedef struct NPCM7xxTimer {
 NPCM7xxTimerCtrlState *ctrl;
 
 qemu_irqirq;
-QEMUTimer   qtimer;
-int64_t expires_ns;
-int64_t remaining_ns;
+NPCM7xxBaseTimer base_timer;
 
 uint32_ttcsr;
 uint32_tticr;
 } NPCM7xxTimer;
 
+/**
+ * struct NPCM7xxWatchdogTimer - The watchdog timer state.
+ * @ctrl: The timer module that owns this timer.
+ * @irq: GIC interrupt line to fire on expiration (if enabled).
+ * @reset_signal: The GPIO used to send a reset signal.
+ * @base_timer: The basic timer functionality for this timer.
+ * @wtcr: The Watchdog Timer Control Register.
+ */
+typedef struct NPCM7xxWatchdogTimer {
+NPCM7xxTimerCtrlState *ctrl;
+
+qemu_irqirq;
+qemu_irqreset_signal;
+NPCM7xxBaseTimer base_timer;
+
+uint32_twtcr;
+} NPCM7xxWatchdogTimer;
+
 /**
  * struct NPCM7xxTimerCtrlState - Timer Module device state.
  * @parent: System bus device.
  * @iomem: Memory region through which registers are accessed.
+ * @index: The index of this timer module.
  * @tisr: The Timer Interrupt Status Register.
- * @wtcr: The Watchdog Timer Control Register.
  * @timer: The five individual timers managed by this module.
+ * @watchdog_timer: The watchdog timer managed by this module.
  */
 struct NPCM7xxTimerCtrlState {
 SysBusDevice parent;
@@ -66,9 +100,9 @@ struct NPCM7xxTimerCtrlState {
 MemoryRegion iomem;
 
 uint32_ttisr;
-uint32_twtcr;
 
 NPCM7xxTimer timer[NPCM7XX_TIMERS_PER_CTRL];
+NPCM7xxWatchdogTimer watchdog_timer;
 };
 
 #define TYPE_NPCM7XX_TIMER "npcm7xx-timer"
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 037f3a26f2..c341dcab8b 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -86,6 +86,9 @@ enum NPCM7xxInterrupt {
 NPCM7XX_TIMER12_IRQ,
 NPCM7XX_TIMER13_IRQ,
 NPCM7XX_TIMER14_IRQ,
+NPCM7XX_WDG0_IRQ= 47,   /* Timer Module 0 Watchdog */
+NPCM7XX_WDG1_IRQ,   /* Timer Module 1 Watchdog */
+NPCM7XX_WDG2_IRQ,   /* Timer Module 2 Watchdog */
 };
 
 /* Total number of GIC interrupts, including internal Cortex-A9 interrupts. */
@@ -353,6 +356,15 @@ static void npcm7xx_realize(DeviceState 

[PATCH v3 5/6] hw/arm/npcm7xx: Add EHCI and OHCI controllers

2020-10-23 Thread Havard Skinnemoen via
The NPCM730 and NPCM750 chips have a single USB host port shared between
a USB 2.0 EHCI host controller and a USB 1.1 OHCI host controller. This
adds support for both of them.

Testing notes:
  * With -device usb-kbd, qemu will automatically insert a full-speed
hub, and the keyboard becomes controlled by the OHCI controller.
  * With -device usb-kbd,bus=usb-bus.0,port=1, the keyboard is directly
attached to the port without any hubs, and the device becomes
controlled by the EHCI controller since it's high speed capable.
  * With -device usb-kbd,bus=usb-bus.0,port=1,usb_version=1, the
keyboard is directly attached to the port, but it only advertises
itself as full-speed capable, so it becomes controlled by the OHCI
controller.

In all cases, the keyboard device enumerates correctly.

Reviewed-by: Tyrone Ting 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Havard Skinnemoen 
---
 docs/system/arm/nuvoton.rst |  2 +-
 hw/usb/hcd-ehci.h   |  1 +
 include/hw/arm/npcm7xx.h|  4 
 hw/arm/npcm7xx.c| 27 +--
 hw/usb/hcd-ehci-sysbus.c| 19 +++
 5 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index 4342434df4..99fc61c740 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -39,6 +39,7 @@ Supported devices
  * OTP controllers (no protection features)
  * Flash Interface Unit (FIU; no protection features)
  * Random Number Generator (RNG)
+ * USB host (USBH)
 
 Missing devices
 ---
@@ -54,7 +55,6 @@ Missing devices
* eSPI slave interface
 
  * Ethernet controllers (GMAC and EMC)
- * USB host (USBH)
  * USB device (USBD)
  * SMBus controller (SMBF)
  * Peripheral SPI controller (PSPI)
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index fd122dd4cd..a173707d9b 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -344,6 +344,7 @@ struct EHCIPCIState {
 #define TYPE_PLATFORM_EHCI "platform-ehci-usb"
 #define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb"
 #define TYPE_AW_H3_EHCI "aw-h3-ehci-usb"
+#define TYPE_NPCM7XX_EHCI "npcm7xx-ehci-usb"
 #define TYPE_TEGRA2_EHCI "tegra2-ehci-usb"
 #define TYPE_PPC4xx_EHCI "ppc4xx-ehci-usb"
 #define TYPE_FUSBH200_EHCI "fusbh200-ehci-usb"
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 761f9b987e..aeee1beaaa 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -25,6 +25,8 @@
 #include "hw/nvram/npcm7xx_otp.h"
 #include "hw/timer/npcm7xx_timer.h"
 #include "hw/ssi/npcm7xx_fiu.h"
+#include "hw/usb/hcd-ehci.h"
+#include "hw/usb/hcd-ohci.h"
 #include "target/arm/cpu.h"
 
 #define NPCM7XX_MAX_NUM_CPUS(2)
@@ -77,6 +79,8 @@ typedef struct NPCM7xxState {
 NPCM7xxOTPState fuse_array;
 NPCM7xxMCState  mc;
 NPCM7xxRNGState rng;
+EHCISysBusState ehci;
+OHCISysBusState ohci;
 NPCM7xxFIUState fiu[2];
 } NPCM7xxState;
 
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index cb4db41c54..c1d122576b 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -46,6 +46,10 @@
 #define NPCM7XX_MC_BA   (0xf0824000)
 #define NPCM7XX_RNG_BA  (0xf000b000)
 
+/* USB Host modules */
+#define NPCM7XX_EHCI_BA (0xf0806000)
+#define NPCM7XX_OHCI_BA (0xf0807000)
+
 /* Internal AHB SRAM */
 #define NPCM7XX_RAM3_BA (0xc0008000)
 #define NPCM7XX_RAM3_SZ (4 * KiB)
@@ -90,6 +94,8 @@ enum NPCM7xxInterrupt {
 NPCM7XX_WDG0_IRQ= 47,   /* Timer Module 0 Watchdog */
 NPCM7XX_WDG1_IRQ,   /* Timer Module 1 Watchdog */
 NPCM7XX_WDG2_IRQ,   /* Timer Module 2 Watchdog */
+NPCM7XX_EHCI_IRQ= 61,
+NPCM7XX_OHCI_IRQ= 62,
 };
 
 /* Total number of GIC interrupts, including internal Cortex-A9 interrupts. */
@@ -263,6 +269,9 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, "tim[*]", >tim[i], TYPE_NPCM7XX_TIMER);
 }
 
+object_initialize_child(obj, "ehci", >ehci, TYPE_NPCM7XX_EHCI);
+object_initialize_child(obj, "ohci", >ohci, TYPE_SYSBUS_OHCI);
+
 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
 for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
 object_initialize_child(obj, npcm7xx_fiu[i].name, >fiu[i],
@@ -380,6 +389,22 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 sysbus_realize(SYS_BUS_DEVICE(>rng), _abort);
 sysbus_mmio_map(SYS_BUS_DEVICE(>rng), 0, NPCM7XX_RNG_BA);
 
+/* USB Host */
+object_property_set_bool(OBJECT(>ehci), "companion-enable", true,
+ _abort);
+sysbus_realize(SYS_BUS_DEVICE(>ehci), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(>ehci), 0, NPCM7XX_EHCI_BA);
+sysbus_connect_irq(SYS_BUS_DEVICE(>ehci), 0,
+   npcm7xx_irq(s, NPCM7XX_EHCI_IRQ));
+
+object_property_set_str(OBJECT(>ohci), "masterbus", "usb-bus.0",
+

[PATCH v3 0/6] Additional NPCM7xx features, devices and tests

2020-10-23 Thread Havard Skinnemoen via
This is an update to the initial NPCM7xx patch series adding

  - Watchdog timer support. This makes the reboot command work.
  - Random Number Generator device.
  - USB Host Controllers.
  - GPIO Controllers.

The watchdog was implemented by my new teammate Hao Wu. Expect to see more
patches from him in the near future.

This series has also been pushed to the npcm7xx-5.2-update branch of my github
repository at

  https://github.com/hskinnemoen/qemu

Changes since v2:

  - Watchdog timer test now uses libqos/libqtest.h API consistently instead of
a mix of that and libqtest-single.h.
  - Made all npcm7xx-related tests conditional on CONFIG_NPCM7XX. An extra
patch was added for the previously submitted timer test.

Changes since v1:

  - Dropped the timer test since it's already applied (thanks Peter).
  - Watchdog reset signaling is now using GPIOs instead of a custom API
(thanks Peter for suggesting, and Hao for implementing it).
  - Various comment updates for the timer.
  - VMState added to GPIO device.
  - Missing VMstate terminator added to RNG device.
  - Include order in RNG test fixed.

Again, thanks a lot for reviewing!

Havard

Hao Wu (1):
  hw/timer: Adding watchdog for NPCM7XX Timer.

Havard Skinnemoen (5):
  tests/qtest: Make npcm7xx_timer-test conditional on CONFIG_NPCM7XX
  Move npcm7xx_timer_reached_zero call out of npcm7xx_timer_pause
  hw/misc: Add npcm7xx random number generator
  hw/arm/npcm7xx: Add EHCI and OHCI controllers
  hw/gpio: Add GPIO model for Nuvoton NPCM7xx

 docs/system/arm/nuvoton.rst   |   6 +-
 hw/usb/hcd-ehci.h |   1 +
 include/hw/arm/npcm7xx.h  |   8 +
 include/hw/gpio/npcm7xx_gpio.h|  55 +++
 include/hw/misc/npcm7xx_clk.h |   2 +
 include/hw/misc/npcm7xx_rng.h |  34 ++
 include/hw/timer/npcm7xx_timer.h  |  48 ++-
 hw/arm/npcm7xx.c  | 126 ++-
 hw/gpio/npcm7xx_gpio.c| 424 ++
 hw/misc/npcm7xx_clk.c |  28 ++
 hw/misc/npcm7xx_rng.c | 180 +
 hw/timer/npcm7xx_timer.c  | 270 +++---
 hw/usb/hcd-ehci-sysbus.c  |  19 +
 tests/qtest/npcm7xx_gpio-test.c   | 385 
 tests/qtest/npcm7xx_rng-test.c| 278 ++
 tests/qtest/npcm7xx_watchdog_timer-test.c | 320 
 MAINTAINERS   |   1 +
 hw/gpio/meson.build   |   1 +
 hw/gpio/trace-events  |   7 +
 hw/misc/meson.build   |   1 +
 hw/misc/trace-events  |   4 +
 tests/qtest/meson.build   |   7 +-
 22 files changed, 2143 insertions(+), 62 deletions(-)
 create mode 100644 include/hw/gpio/npcm7xx_gpio.h
 create mode 100644 include/hw/misc/npcm7xx_rng.h
 create mode 100644 hw/gpio/npcm7xx_gpio.c
 create mode 100644 hw/misc/npcm7xx_rng.c
 create mode 100644 tests/qtest/npcm7xx_gpio-test.c
 create mode 100644 tests/qtest/npcm7xx_rng-test.c
 create mode 100644 tests/qtest/npcm7xx_watchdog_timer-test.c

-- 
2.29.0.rc1.297.gfa9743e501-goog




[PATCH v3 4/6] hw/misc: Add npcm7xx random number generator

2020-10-23 Thread Havard Skinnemoen via
The RNG module returns a byte of randomness when the Data Valid bit is
set.

This implementation ignores the prescaler setting, and loads a new value
into RNGD every time RNGCS is read while the RNG is enabled and random
data is available.

A qtest featuring some simple randomness tests is included.

Reviewed-by: Tyrone Ting 
Reviewed-by: Peter Maydell 
Signed-off-by: Havard Skinnemoen 
---
 docs/system/arm/nuvoton.rst|   2 +-
 include/hw/arm/npcm7xx.h   |   2 +
 include/hw/misc/npcm7xx_rng.h  |  34 
 hw/arm/npcm7xx.c   |   7 +-
 hw/misc/npcm7xx_rng.c  | 180 +
 tests/qtest/npcm7xx_rng-test.c | 278 +
 hw/misc/meson.build|   1 +
 hw/misc/trace-events   |   4 +
 tests/qtest/meson.build|   5 +-
 9 files changed, 510 insertions(+), 3 deletions(-)
 create mode 100644 include/hw/misc/npcm7xx_rng.h
 create mode 100644 hw/misc/npcm7xx_rng.c
 create mode 100644 tests/qtest/npcm7xx_rng-test.c

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index e3e1a3a3a7..4342434df4 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -38,6 +38,7 @@ Supported devices
  * DDR4 memory controller (dummy interface indicating memory training is done)
  * OTP controllers (no protection features)
  * Flash Interface Unit (FIU; no protection features)
+ * Random Number Generator (RNG)
 
 Missing devices
 ---
@@ -59,7 +60,6 @@ Missing devices
  * Peripheral SPI controller (PSPI)
  * Analog to Digital Converter (ADC)
  * SD/MMC host
- * Random Number Generator (RNG)
  * PECI interface
  * Pulse Width Modulation (PWM)
  * Tachometer
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 13106af215..761f9b987e 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -21,6 +21,7 @@
 #include "hw/mem/npcm7xx_mc.h"
 #include "hw/misc/npcm7xx_clk.h"
 #include "hw/misc/npcm7xx_gcr.h"
+#include "hw/misc/npcm7xx_rng.h"
 #include "hw/nvram/npcm7xx_otp.h"
 #include "hw/timer/npcm7xx_timer.h"
 #include "hw/ssi/npcm7xx_fiu.h"
@@ -75,6 +76,7 @@ typedef struct NPCM7xxState {
 NPCM7xxOTPState key_storage;
 NPCM7xxOTPState fuse_array;
 NPCM7xxMCState  mc;
+NPCM7xxRNGState rng;
 NPCM7xxFIUState fiu[2];
 } NPCM7xxState;
 
diff --git a/include/hw/misc/npcm7xx_rng.h b/include/hw/misc/npcm7xx_rng.h
new file mode 100644
index 00..5e85fd439d
--- /dev/null
+++ b/include/hw/misc/npcm7xx_rng.h
@@ -0,0 +1,34 @@
+/*
+ * Nuvoton NPCM7xx Random Number Generator.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License 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.
+ */
+#ifndef NPCM7XX_RNG_H
+#define NPCM7XX_RNG_H
+
+#include "hw/sysbus.h"
+
+typedef struct NPCM7xxRNGState {
+SysBusDevice parent;
+
+MemoryRegion iomem;
+
+uint8_t rngcs;
+uint8_t rngd;
+uint8_t rngmode;
+} NPCM7xxRNGState;
+
+#define TYPE_NPCM7XX_RNG "npcm7xx-rng"
+#define NPCM7XX_RNG(obj) OBJECT_CHECK(NPCM7xxRNGState, (obj), TYPE_NPCM7XX_RNG)
+
+#endif /* NPCM7XX_RNG_H */
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index c341dcab8b..cb4db41c54 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -44,6 +44,7 @@
 #define NPCM7XX_GCR_BA  (0xf080)
 #define NPCM7XX_CLK_BA  (0xf0801000)
 #define NPCM7XX_MC_BA   (0xf0824000)
+#define NPCM7XX_RNG_BA  (0xf000b000)
 
 /* Internal AHB SRAM */
 #define NPCM7XX_RAM3_BA (0xc0008000)
@@ -256,6 +257,7 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, "otp2", >fuse_array,
 TYPE_NPCM7XX_FUSE_ARRAY);
 object_initialize_child(obj, "mc", >mc, TYPE_NPCM7XX_MC);
+object_initialize_child(obj, "rng", >rng, TYPE_NPCM7XX_RNG);
 
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
 object_initialize_child(obj, "tim[*]", >tim[i], TYPE_NPCM7XX_TIMER);
@@ -374,6 +376,10 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
serial_hd(i), DEVICE_LITTLE_ENDIAN);
 }
 
+/* Random Number Generator. Cannot fail. */
+sysbus_realize(SYS_BUS_DEVICE(>rng), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(>rng), 0, NPCM7XX_RNG_BA);
+
 /*
  * Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
  * specified, but this is a programming error.
@@ -412,7 +418,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.vdmx", 0xe080,   4 * KiB);
 

[PATCH v3 1/6] tests/qtest: Make npcm7xx_timer-test conditional on CONFIG_NPCM7XX

2020-10-23 Thread Havard Skinnemoen via
This test won't work if qemu was compiled without CONFIG_NPCM7XX, as
pointed out by Thomas Huth on a different patch.

Signed-off-by: Havard Skinnemoen 
---
 tests/qtest/meson.build | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 28d4068718..7e0ecaa2c5 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -133,12 +133,13 @@ qtests_sparc64 = \
   (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : 
[]) +\
   ['prom-env-test', 'boot-serial-test']
 
+qtests_npcm7xx = ['npcm7xx_timer-test']
 qtests_arm = \
   (config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : 
[]) + \
+  (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
   ['arm-cpu-features',
'microbit-test',
'm25p80-test',
-   'npcm7xx_timer-test',
'test-arm-mptimer',
'boot-serial-test',
'hexloader-test']
-- 
2.29.0.rc1.297.gfa9743e501-goog




[PATCH v3 2/6] Move npcm7xx_timer_reached_zero call out of npcm7xx_timer_pause

2020-10-23 Thread Havard Skinnemoen via
This allows us to reuse npcm7xx_timer_pause for the watchdog timer.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Havard Skinnemoen 
---
 hw/timer/npcm7xx_timer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
index 5703e43d40..2df9e3e496 100644
--- a/hw/timer/npcm7xx_timer.c
+++ b/hw/timer/npcm7xx_timer.c
@@ -157,9 +157,6 @@ static void npcm7xx_timer_pause(NPCM7xxTimer *t)
 timer_del(>qtimer);
 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 t->remaining_ns = t->expires_ns - now;
-if (t->remaining_ns <= 0) {
-npcm7xx_timer_reached_zero(t);
-}
 }
 
 /*
@@ -239,6 +236,9 @@ static void npcm7xx_timer_write_tcsr(NPCM7xxTimer *t, 
uint32_t new_tcsr)
 } else {
 t->tcsr &= ~NPCM7XX_TCSR_CACT;
 npcm7xx_timer_pause(t);
+if (t->remaining_ns <= 0) {
+npcm7xx_timer_reached_zero(t);
+}
 }
 }
 }
-- 
2.29.0.rc1.297.gfa9743e501-goog




Re: [PATCH v2 0/6] Add support for Control-Flow Integrity

2020-10-23 Thread Eric Blake
On 10/23/20 3:06 PM, Daniele Buono wrote:
> v2: Several months (and structural changes in QEMU) have passed since v1.
> While the spirit of the patch is similar, the implementation is changed
> in multiple points, and should address most if not all the comments
> received in v1.

> 5) Most of the logic to enable CFI goes in the configure, since it's
> just a matter of checking for dependencies and incompatible options.
> However, I had to disable CFI checks for a few TCG functions.
> This can only be done through a blacklist file. I added a file in the
> root of QEMU, called cfi-blacklist.txt for such purpose. I am open to
> suggestions on where the file should go, and I am willing to become the
> maintainer of it, if deemed necessary.

In the meantime, we have commits like:

commit b199c682f1f0aaee22b2170a5fb885250057eec2
Author: Philippe Mathieu-Daudé 
Date:   Thu Sep 10 09:01:31 2020 +0200

target/i386/kvm: Rename host_tsx_blacklisted() as host_tsx_broken()

In order to use inclusive terminology, rename host_tsx_blacklisted()
as host_tsx_broken().

which may help you in coming up with a more appropriate name for the new
file.

> 
>  MAINTAINERS   |   5 +
>  accel/tcg/cpu-exec.c  |   9 ++
>  configure | 214 ++
>  include/qemu/sanitizers.h |  22 
>  meson.build   |   3 +
>  plugins/core.c|  25 
>  plugins/loader.c  |   5 +
>  tcg/tci.c |   5 +
>  tests/check-block.sh  |  18 +--
>  tests/qtest/fuzz/fork_fuzz.ld |  12 +-
>  util/main-loop.c  |   9 ++
>  util/oslib-posix.c|   9 ++
>  12 files changed, 328 insertions(+), 8 deletions(-)
>  create mode 100644 include/qemu/sanitizers.h

although I don't see a new file by that name here, so perhaps the v1
overview is now stale?

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




Re: [PATCH v5 12/12] qapi: Use QAPI_LIST_ADD() where possible

2020-10-23 Thread Eric Blake
On 10/23/20 1:36 PM, Eric Blake wrote:
> Anywhere we create a list of just one item or by prepending items
> (typically because order doesn't matter), we can use the now-public
> macro.  But places where we must keep the list in order by appending
> remain open-coded.
> 
> Signed-off-by: Eric Blake 
> ---
>  docs/devel/writing-qmp-commands.txt | 13 +++--

> +++ b/docs/devel/writing-qmp-commands.txt
> @@ -531,15 +531,10 @@ TimerAlarmMethodList *qmp_query_alarm_methods(Error 
> **errp)
>  bool current = true;
> 
>  for (p = alarm_timers; p->name; p++) {
> -TimerAlarmMethodList *info = g_malloc0(sizeof(*info));
> -info->value = g_malloc0(sizeof(*info->value));
> -info->value->method_name = g_strdup(p->name);
> -info->value->current = current;
> -
> -current = false;
> -
> -info->next = method_list;
> -method_list = info;
> + TimerAlarmMethod *value = g_new0(TimerAlarmMethod, 1);
> +value->method_name = g_strdup(p->name);

Oops, tab damage.

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




[PATCH v2 5/6] check-block: enable iotests with cfi-icall

2020-10-23 Thread Daniele Buono
cfi-icall is a form of Control-Flow Integrity for indirect function
calls implemented by llvm. It is enabled with a -fsanitize flag.

iotests are currently disabled when -fsanitize options is used, with the
exception of SafeStack.

This patch implements a generic filtering mechanism to allow iotests
with a set of known-to-be-safe -fsanitize option. Then marks SafeStack
and the new options used for cfi-icall safe for iotests

Signed-off-by: Daniele Buono 
---
 tests/check-block.sh | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/tests/check-block.sh b/tests/check-block.sh
index f6b1bda7b9..fb4c1baae9 100755
--- a/tests/check-block.sh
+++ b/tests/check-block.sh
@@ -21,14 +21,18 @@ if grep -q "CONFIG_GPROF=y" config-host.mak 2>/dev/null ; 
then
 exit 0
 fi
 
-# Disable tests with any sanitizer except for SafeStack
-CFLAGS=$( grep "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null )
-SANITIZE_FLAGS=""
-#Remove all occurrencies of -fsanitize=safe-stack
-for i in ${CFLAGS}; do
-if [ "${i}" != "-fsanitize=safe-stack" ]; then
-SANITIZE_FLAGS="${SANITIZE_FLAGS} ${i}"
+# Disable tests with any sanitizer except for specific ones
+SANITIZE_FLAGS=$( grep "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null )
+ALLOWED_SANITIZE_FLAGS="safe-stack cfi-icall"
+#Remove all occurrencies of allowed Sanitize flags
+for j in ${ALLOWED_SANITIZE_FLAGS}; do
+TMP_FLAGS=${SANITIZE_FLAGS}
+SANITIZE_FLAGS=""
+for i in ${TMP_FLAGS}; do
+if ! echo ${i} | grep -q "${j}" 2>/dev/null; then
+SANITIZE_FLAGS="${SANITIZE_FLAGS} ${i}"
 fi
+done
 done
 if echo ${SANITIZE_FLAGS} | grep -q "\-fsanitize" 2>/dev/null; then
 # Have a sanitize flag that is not allowed, stop
-- 
2.17.1




[PATCH v2 4/6] cfi: Initial support for cfi-icall in QEMU

2020-10-23 Thread Daniele Buono
LLVM/Clang, supports runtime checks for forward-edge Control-Flow
Integrity (CFI).

CFI on indirect function calls (cfi-icall) ensures that, in indirect
function calls, the function called is of the right signature for the
pointer type defined at compile time.

For this check to work, the code must always respect the function
signature when using function pointer, the function must be defined
at compile time, and be compiled with link-time optimization.

This rules out, for example, shared libraries that are dynamically loaded
(given that functions are not known at compile time), and code that is
dynamically generated at run-time.

This patch:

1) Introduces the CONFIG_CFI flag to support cfi in QEMU

2) Introduces a decorator to allow the definition of "sensitive"
functions, where a non-instrumented function may be called at runtime
through a pointer. The decorator will take care of disabling cfi-icall
checks on such functions, when cfi is enabled.

3) Marks functions currently in QEMU that exhibit such behavior,
in particular:
- The function in TCG that calls pre-compiled TBs
- The function in TCI that interprets instructions
- Functions in the plugin infrastructures that jump to callbacks
- Functions in util that directly call a signal handler

4) Add a new section in MAINTAINERS with me as a maintainer for
include/qemu/sanitizers.h, in case a maintainer is deemed
necessary for this feature

Signed-off-by: Daniele Buono 
---
 MAINTAINERS   |  5 +
 accel/tcg/cpu-exec.c  |  9 +
 include/qemu/sanitizers.h | 22 ++
 plugins/core.c| 25 +
 plugins/loader.c  |  5 +
 tcg/tci.c |  5 +
 util/main-loop.c  |  9 +
 util/oslib-posix.c|  9 +
 8 files changed, 89 insertions(+)
 create mode 100644 include/qemu/sanitizers.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6a197bd358..93b2b52b88 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3094,6 +3094,11 @@ S: Maintained
 F: hw/semihosting/
 F: include/hw/semihosting/
 
+Control Flow Integrity
+M: Daniele Buono 
+S: Maintained
+F: include/qemu/sanitizers.h
+
 Build and test automation
 -
 Build and test automation
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 58aea605d8..efa01c51db 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -26,6 +26,7 @@
 #include "exec/exec-all.h"
 #include "tcg/tcg.h"
 #include "qemu/atomic.h"
+#include "qemu/sanitizers.h"
 #include "sysemu/qtest.h"
 #include "qemu/timer.h"
 #include "qemu/rcu.h"
@@ -144,6 +145,14 @@ static void init_delay_params(SyncClocks *sc, const 
CPUState *cpu)
 #endif /* CONFIG USER ONLY */
 
 /* Execute a TB, and fix up the CPU state afterwards if necessary */
+/* Disable CFI checks.
+ * TCG creates binary blobs at runtime, with the transformed code.
+ * A TB is a blob of binary code, created at runtime and called with an
+ * indirect function call. Since such function did not exist at compile time,
+ * the CFI runtime has no way to verify its signature and would fail.
+ * TCG is not considered a security-sensitive part of QEMU so this does not
+ * affect the impact of CFI in environment with high security requirements */
+__disable_cfi__
 static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock 
*itb)
 {
 CPUArchState *env = cpu->env_ptr;
diff --git a/include/qemu/sanitizers.h b/include/qemu/sanitizers.h
new file mode 100644
index 00..31e404d58d
--- /dev/null
+++ b/include/qemu/sanitizers.h
@@ -0,0 +1,22 @@
+/*
+ * Decorators to disable sanitizers on specific functions
+ *
+ * Copyright IBM Corp., 2020
+ *
+ * Author:
+ *  Daniele Buono 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifdef CONFIG_CFI
+/* If CFI is enabled, use an attribute to disable cfi-icall on the following
+ * function */
+#define __disable_cfi__ __attribute__((no_sanitize("cfi-icall")))
+#else
+/* If CFI is not enabled, use an empty define to not change the behavior */
+#define __disable_cfi__
+#endif
+
diff --git a/plugins/core.c b/plugins/core.c
index 51bfc94787..9b712ca4ac 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -31,6 +31,7 @@
 #include "tcg/tcg-op.h"
 #include "trace/mem-internal.h" /* mem_info macros */
 #include "plugin.h"
+#include "qemu/sanitizers.h"
 
 struct qemu_plugin_cb {
 struct qemu_plugin_ctx *ctx;
@@ -90,6 +91,10 @@ void plugin_unregister_cb__locked(struct qemu_plugin_ctx 
*ctx,
 }
 }
 
+/* Disable CFI checks.
+ * The callback function has been loaded from an external library so we do not
+ * have type information */
+__disable_cfi__
 static void plugin_vcpu_cb__simple(CPUState *cpu, enum qemu_plugin_event ev)
 {
 struct qemu_plugin_cb *cb, *next;
@@ -111,6 +116,10 @@ static void plugin_vcpu_cb__simple(CPUState *cpu, enum 
qemu_plugin_event ev)
 }
 }
 
+/* Disable CFI checks.

[PATCH v2 6/6] configure: add support for Control-Flow Integrity

2020-10-23 Thread Daniele Buono
This patch adds a flag to enable/disable control flow integrity checks
on indirect function calls.
This feature only allows indirect function calls at runtime to functions
with compatible signatures.

This feature is only provided by LLVM/Clang, and depends on link-time
optimization which is currently supported only with LLVM/Clang >= 6.0

We also add an option to enable a debugging version of cfi, with verbose
output in case of a CFI violation.

CFI on indirect function calls does not support calls to functions in
shared libraries (since they were not known at compile time), and such
calls are forbidden. QEMU relies on dlopen/dlsym when using modules,
so we make modules incompatible with CFI.

Signed-off-by: Daniele Buono 
---
 configure   | 84 +
 meson.build |  2 ++
 2 files changed, 86 insertions(+)

diff --git a/configure b/configure
index e964040522..f996c4462e 100755
--- a/configure
+++ b/configure
@@ -272,6 +272,8 @@ debug_info="yes"
 lto="false"
 stack_protector=""
 safe_stack=""
+cfi="no"
+cfi_debug="no"
 use_containers="yes"
 gdb_bin=$(command -v "gdb-multiarch" || command -v "gdb")
 
@@ -1199,6 +1201,16 @@ for opt do
   ;;
   --disable-safe-stack) safe_stack="no"
   ;;
+  --enable-cfi)
+  cfi="yes" ;
+  lto="true" ;
+  ;;
+  --disable-cfi) cfi="no"
+  ;;
+  --enable-cfi-debug) cfi_debug="yes"
+  ;;
+  --disable-cfi-debug) cfi_debug="no"
+  ;;
   --disable-curses) curses="disabled"
   ;;
   --enable-curses) curses="enabled"
@@ -1772,6 +1784,13 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   sparse  sparse checker
   safe-stack  SafeStack Stack Smash Protection. Depends on
   clang/llvm >= 3.7 and requires coroutine backend ucontext.
+  cfi Enable Control-Flow Integrity for indirect function calls.
+  In case of a cfi violation, QEMU is terminated with SIGILL
+  Depends on lto and is incompatible with modules
+  Automatically enables Link-Time Optimization (lto)
+  cfi-debug   In case of a cfi violation, a message containing the line 
that
+  triggered the error is written to stderr. After the error,
+  QEMU is still terminated with SIGILL
 
   gnutls  GNUTLS cryptography support
   nettle  nettle cryptography support
@@ -5312,6 +5331,64 @@ EOF
   CONFIGURE_CFLAGS="$QEMU_CFLAGS -flto"
   CONFIGURE_LDFLAGS="$QEMU_LDFLAGS -flto"
 fi
+
+
+# cfi (Control Flow Integrity)
+
+if test "$cfi" = "yes"; then
+  # Compiler/Linker Flags that needs to be added for cfi:
+  # -fsanitize=cfi-icall to enable control-flow integrity checks on
+  #indirect function calls.
+  # -fsanitize-cfi-icall-generalize-pointers to allow indirect function calls
+  #with pointers of a different type (i.e. pass a void* to a
+  #function that expects a char*). Used in some spots in QEMU,
+  #with compile-time type checks done by macros
+  # -fno-sanitize-trap=cfi-icall, when debug is enabled, to display the
+  #position in the code that triggered a CFI violation
+
+  # Make sure that LTO is enabled
+  if test "$lto" != "true"; then
+error_exit "Control Flow Integrity requires Link-Time Optimization (LTO)"
+  fi
+
+  test_cflag="-fsanitize=cfi-icall -fsanitize-cfi-icall-generalize-pointers"
+  test_ldflag="-fsanitize=cfi-icall"
+
+  if test "$cfi_debug" = "yes"; then
+# Disable the default trap mechanism so that a error message is displayed
+# when a CFI violation happens. The code is still terminated after the
+# message
+test_cflag="${test_cflag} -fno-sanitize-trap=cfi-icall"
+test_ldflag="${test_ldflag} -fno-sanitize-trap=cfi-icall"
+  fi
+
+  # Check that cfi is supported.
+  cat > $TMPC << EOF
+int main(int argc, char *argv[]) {
+  return 0;
+}
+EOF
+  # Manually add -flto because even if is enabled, flags for it will be
+  # set up later by meson
+  if ! compile_prog "-Werror $test_cflag" "$test_ldflag"; then
+error_exit "Control Flow Integrity is not supported by your compiler"
+  fi
+
+  # Check for incompatible options
+  if test "$modules" = "yes"; then
+error_exit "Control Flow Integrity is not compatible with modules"
+  fi
+
+   All good, add the flags for CFI to our CFLAGS and LDFLAGS
+  # Flag needed both at compilation and at linking
+  QEMU_CFLAGS="$QEMU_CFLAGS $test_cflag"
+  QEMU_LDFLAGS="$QEMU_LDFLAGS $test_ldflag"
+else
+  if test "$cfi_debug" = "yes"; then
+error_exit "Cannot enable Control Flow Integrity debugging since CFI is 
not enabled"
+  fi
+fi
+
 # See if __attribute__((alias)) is supported.
 # This false for Xcode 9, but has been remedied for Xcode 10.
 # Unfortunately, travis uses Xcode 9 by default.
@@ -6972,6 +7049,13 @@ if test "$safe_stack" = "yes"; then
   echo "CONFIG_SAFESTACK=y" >> $config_host_mak
 fi
 
+if test "$cfi" = "yes"; then
+ 

[PATCH v2 2/6] configure: avoid new clang 11+ warnings

2020-10-23 Thread Daniele Buono
Clang 11 finds a couple of spots in the code that trigger new warnings:

../qemu-base/hw/usb/dev-uas.c:157:31: error: field 'status' with variable sized 
type 'uas_iu' not at the end of a struct or class is a GNU extension 
[-Werror,-Wgnu-variable-sized-type-not-at-end]
uas_iustatus;
  ^
1 error generated.

The data structure is UASStatus, which must end with a QTAILQ_ENTRY, so
I believe we cannot have uas_iu at the end. Since this is a gnu
extension but CLANG supports it, just add
-Wno-gnu-variable-sized-type-not-at-end
to remove the warning.

../qemu-base/target/s390x/cpu_models.c:985:21: error: cast to smaller integer 
type 'S390Feat' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
S390Feat feat = (S390Feat) opaque;
^
../qemu-base/target/s390x/cpu_models.c:1002:21: error: cast to smaller integer 
type 'S390Feat' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
S390Feat feat = (S390Feat) opaque;
^
../qemu-base/target/s390x/cpu_models.c:1036:27: error: cast to smaller integer 
type 'S390FeatGroup' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
S390FeatGroup group = (S390FeatGroup) opaque;
  ^~
../qemu-base/target/s390x/cpu_models.c:1057:27: error: cast to smaller integer 
type 'S390FeatGroup' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
S390FeatGroup group = (S390FeatGroup) opaque;
  ^~
4 errors generated.

These are void * that get casted to enums, which are (or can be)
smaller than a 64bit pointer.
A code reorg may be better on the long term, but for now will
fix this adding
-Wno-void-pointer-to-enum-cast

Signed-off-by: Daniele Buono 
---
 configure | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configure b/configure
index e6754c1e87..9dc05cfb8a 100755
--- a/configure
+++ b/configure
@@ -2000,6 +2000,8 @@ add_to nowarn_flags -Wno-shift-negative-value
 add_to nowarn_flags -Wno-string-plus-int
 add_to nowarn_flags -Wno-typedef-redefinition
 add_to nowarn_flags -Wno-tautological-type-limit-compare
+add_to nowarn_flags -Wno-gnu-variable-sized-type-not-at-end
+add_to nowarn_flags -Wno-void-pointer-to-enum-cast
 add_to nowarn_flags -Wno-psabi
 
 gcc_flags="$warn_flags $nowarn_flags"
-- 
2.17.1




[PATCH v2 3/6] configure: add option to enable LTO

2020-10-23 Thread Daniele Buono
This patch allows to compile QEMU with link-time optimization (LTO).
Compilation with LTO is handled directly by meson. This patch adds checks
in configure to make sure the toolchain supports LTO.

Currently, allow LTO only with clang, since I have found a couple of issues
with gcc-based LTO.

In case fuzzing is enabled, automatically switch to llvm's linker (lld).
The standard bfd linker has a bug where function wrapping (used by the fuzz*
targets) is used in conjunction with LTO.

Tested with all major versions of clang from 6 to 12

Signed-off-by: Daniele Buono 
---
 configure   | 128 
 meson.build |   1 +
 2 files changed, 129 insertions(+)

diff --git a/configure b/configure
index 9dc05cfb8a..e964040522 100755
--- a/configure
+++ b/configure
@@ -76,6 +76,7 @@ fi
 TMPB="qemu-conf"
 TMPC="${TMPDIR1}/${TMPB}.c"
 TMPO="${TMPDIR1}/${TMPB}.o"
+TMPA="${TMPDIR1}/lib${TMPB}.a"
 TMPCXX="${TMPDIR1}/${TMPB}.cxx"
 TMPE="${TMPDIR1}/${TMPB}.exe"
 TMPTXT="${TMPDIR1}/${TMPB}.txt"
@@ -180,6 +181,32 @@ compile_prog() {
   $LDFLAGS $CONFIGURE_LDFLAGS $QEMU_LDFLAGS $local_ldflags
 }
 
+do_run_filter() {
+# Run a generic program, capturing its output to the log,
+# but also filtering the output with grep.
+# Returns the return value of grep.
+# First argument is the filter string.
+# Second argument is binary to execute.
+local filter="$1"
+local filter_pattern=""
+if test "$filter" = "yes"; then
+  shift
+  filter_pattern="$1"
+fi
+shift
+local program="$1"
+shift
+echo $program $@ >> config.log
+$program $@ >> config.log 2>&1 || return $?
+if test "$filter" = "yes"; then
+  $program $@ 2>&1 | grep "${filter_pattern}" >> /dev/null || return $?
+fi
+}
+
+create_library() {
+  do_run_filter "no" "$ar" -rc${1} $TMPA $TMPO
+}
+
 # symbolically link $1 to $2.  Portable version of "ln -sf".
 symlink() {
   rm -rf "$2"
@@ -242,6 +269,7 @@ host_cc="cc"
 audio_win_int=""
 libs_qga=""
 debug_info="yes"
+lto="false"
 stack_protector=""
 safe_stack=""
 use_containers="yes"
@@ -1159,6 +1187,10 @@ for opt do
   ;;
   --disable-werror) werror="no"
   ;;
+  --enable-lto) lto="true"
+  ;;
+  --disable-lto) lto="false"
+  ;;
   --enable-stack-protector) stack_protector="yes"
   ;;
   --disable-stack-protector) stack_protector="no"
@@ -1735,6 +1767,8 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   module-upgrades try to load modules from alternate paths for upgrades
   debug-tcg   TCG debugging (default is disabled)
   debug-info  debugging information
+  lto Enable Link-Time Optimization.
+  Depends on clang/llvm >=6.0
   sparse  sparse checker
   safe-stack  SafeStack Stack Smash Protection. Depends on
   clang/llvm >= 3.7 and requires coroutine backend ucontext.
@@ -5222,6 +5256,62 @@ if  test "$plugins" = "yes" &&
 fi
 
 
+# lto (Link-Time Optimization)
+
+if test "$lto" = "true"; then
+  # Test compiler/ar/linker support for lto.
+  # compilation with lto is handled by meson. Just make sure that compiler
+  # support is fully functional, and add additional compatibility flags
+  # if necessary.
+
+  if ! echo | $cc -dM -E - | grep __clang__ > /dev/null 2>&1 ; then
+# LTO with GCC and other compilers is not tested, and possibly broken
+error_exit "QEMU only supports LTO with CLANG"
+  fi
+
+  # Check that lto is supported.
+  # Need to check for:
+  # - Valid compiler, that supports lto flags
+  # - Valid ar, able to support intermediate code
+  # - Valid linker, able to support intermediate code
+
+   Check for a valid *ar* for link-time optimization.
+  # Test it by creating a static library and linking it
+  # Compile an object first
+  cat > $TMPC << EOF
+int fun(int val);
+
+int fun(int val) {
+return val;
+}
+EOF
+  if ! compile_object "-Werror -flto"; then
+error_exit "LTO is not supported by your compiler"
+  fi
+  # Create a library out of it
+  if ! create_library "s" ; then
+error_exit "LTO is not supported by ar. This usually happens when mixing 
GNU and LLVM toolchain."
+  fi
+  # Now create a binary using the library
+  cat > $TMPC << EOF
+int fun(int val);
+
+int main(int argc, char *argv[]) {
+  return fun(0);
+}
+EOF
+  if ! compile_prog "-Werror" "$test_ldflag -flto ${TMPA}"; then
+error_exit "LTO is not supported by ar or the linker. This usually happens 
when mixing GNU and LLVM toolchain."
+  fi
+
+   All good, add the flags for CFI to our CFLAGS and LDFLAGS
+  # Flag needed both at compilation and at linking
+  QEMU_LDFLAGS="$QEMU_LDFLAGS $test_ldflag"
+  # Add -flto to CONFIGURE_*FLAGS since we need it in configure,
+  # but will be added by meson later
+  CONFIGURE_CFLAGS="$QEMU_CFLAGS -flto"
+  CONFIGURE_LDFLAGS="$QEMU_LDFLAGS -flto"
+fi
 # See if __attribute__((alias)) is supported.
 # This false for Xcode 9, but has been 

[PATCH v2 0/6] Add support for Control-Flow Integrity

2020-10-23 Thread Daniele Buono
v2: Several months (and structural changes in QEMU) have passed since v1.
While the spirit of the patch is similar, the implementation is changed
in multiple points, and should address most if not all the comments
received in v1.
* Instead of disabling CFI in specific functions by using a filter file,
  disable cfi by using a new decorator to be prefixed to the function
  definition. The decorator is automatically expanded to an attribute
  asking clang to disable cfi-icall on the function.
  This should simplify tracking of sensitive function, compared to
  keeping the list in a separate file
  I tentatively added myself as maintainer of a new include file defined for
  that purpose, in case a maintainer is considered needed.
* Updated patch to work with the new build system based on meson
* Split LTO and CFI options. Now LTO can be used independently of CFI.
  LTO uses the meson option to build and can now work, in general, with
  any linker (ld, gold, lld). LTO with meson works fine with clang >=6
  and requires the use of LLVM's ar to handle shared libraries with
  intermediate code (selectable by setting the environment variable
  AR to llvm-ar-xx).
* Introduce a small patch for the linker script used by fuzzing targets,
  so that it works properly with both bfd and lld >=12
* Disable a couple of warning check that trigger errors with clang >= 11 
* Add additional checks for fuzzing and LTO. At the moment, only LLVM's
  lld linker v12 is able to support fuzzing and LTO, because of a bug in the
  bfd linker when handling --wrap with LTO. Therefore, automatically
  select lld if fuzzing and LTO are both enabled.
* Made sure that fuzzing works with LTO and CFI enabled.

-
v1's cover letter starts here
-

LLVM/Clang supports multiple types of forward-edge Control-Flow Integrity
(CFI), including runtime checks on indirect function calls.

CFI on indirect function calls can have a huge impact in enhancing QEMU
security, by significantly limiting one of the most used attack vectors
for VM Escape. Attacks demonstrated in [1],[2] and [3] will, at some
point, change a function pointer in a QEMU data structure.

At high level, LLVM's implementation relies on compile-time information
to create a range of consecutive trampolines for "compatible functions".
At runtime, if the pointer is not in the valid range, it is assumed that
the control flow was hijacked, and the process is terminated with an
"Illegal Instruction" exception.

CAVEATS:

1) For this CFI check to work, the code must always respect the function
signature when using function pointer. While this is generally true
in QEMU, there are a few instances where pointers are handled as
generic void* from the caller. Since this is a common approach, Clang
offer a flag to relax pointer checks and consider all pointer types
to be compatible.

2) Since CFI relies on compile-time information, it requires using
link-time optimization (LTO) to support CFI across compilation units.
This adds a requirement for the gold linker, and LLVM's versions of
static libraries tools (ar, ranlib, nm).

3) CFI checks cannot be performed on shared libraries (given that functions
are not known at compile time). This means that indirect function calls
will fail if the function pointer belong to a shared library.
This does not seem to be a big issue for a standard QEMU deployment today,
but QEMU modules won't be able to work when CFI is enabled.
There is a way to allow shared library pointers, but it is experimental
in LLVM, requires some work and reduces performance and security. For
these reasons, I think it's best to start with this version, and discuss
an extension for modules later.

4) CFI cannot be fully applied to TCG. The purpose of TCG is to transform
code on-the-fly from one ISA to another. In doing so, binary blobs of
executable code are created and called with function pointers.
Since the code did not exist at compile time, runtime CFI checks find such
functions illegal. To allow the code to keep running, CFI checks are not
performed in the core function of TCG/TCI, and in the code that
implements TCG plugins.
This does not affect QEMU when executed with KVM, and all the device
emulation code is always protected, even when using TCG.

5) Most of the logic to enable CFI goes in the configure, since it's
just a matter of checking for dependencies and incompatible options.
However, I had to disable CFI checks for a few TCG functions.
This can only be done through a blacklist file. I added a file in the
root of QEMU, called cfi-blacklist.txt for such purpose. I am open to
suggestions on where the file should go, and I am willing to become the
maintainer of it, if deemed necessary.

PERFORMANCE:

Enabling CFI creates a larger binary, which may be an issue in some use
cases. However, the increase is not exceptionally large. On my Ubuntu
system, with default options, I see an increase of stripped size from
14MiB to 15.3MiB when enabling CFI with Clang v9.

There is also 

[PATCH v2 1/6] fuzz: Make fork_fuzz.ld compatible with LLVM's LLD

2020-10-23 Thread Daniele Buono
LLVM's linker, LLD, supports the keyword "INSERT AFTER", starting with
version 11.
However, when multiple sections are defined in the same "INSERT AFTER",
they are added in a reversed order, compared to BFD's LD.

This patch makes fork_fuzz.ld generic enough to work with both linkers.
Each section now has its own "INSERT AFTER" keyword, so proper ordering is
defined between the sections added.

Signed-off-by: Daniele Buono 
---
 tests/qtest/fuzz/fork_fuzz.ld | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/fuzz/fork_fuzz.ld b/tests/qtest/fuzz/fork_fuzz.ld
index bfb667ed06..cfb88b7fdb 100644
--- a/tests/qtest/fuzz/fork_fuzz.ld
+++ b/tests/qtest/fuzz/fork_fuzz.ld
@@ -16,6 +16,11 @@ SECTIONS
   /* Lowest stack counter */
   *(__sancov_lowest_stack);
   }
+}
+INSERT AFTER .data;
+
+SECTIONS
+{
   .data.fuzz_ordered :
   {
   /*
@@ -34,6 +39,11 @@ SECTIONS
*/
*(.bss._ZN6fuzzer3TPCE);
   }
+}
+INSERT AFTER .data.fuzz_start;
+
+SECTIONS
+{
   .data.fuzz_end : ALIGN(4K)
   {
   __FUZZ_COUNTERS_END = .;
@@ -43,4 +53,4 @@ SECTIONS
  * Don't overwrite the SECTIONS in the default linker script. Instead insert 
the
  * above into the default script
  */
-INSERT AFTER .data;
+INSERT AFTER .data.fuzz_ordered;
-- 
2.17.1




Re: [PATCH] ACPI: Avoid infinite recursion when dump-vmstate

2020-10-23 Thread Igor Mammedov
On Fri, 23 Oct 2020 19:54:41 +0100
"Dr. David Alan Gilbert"  wrote:

> * Igor Mammedov (imamm...@redhat.com) wrote:
> > On Mon, 19 Oct 2020 17:31:56 +0800
> > Peng Liang  wrote:
> >   
> > > There is a field with vmstate_ghes_state as vmsd in vmstate_ghes_state,
> > > which will lead to infinite recursion in dump_vmstate_vmsd.
> > > 
> > > Fixes: a08a64627b ("ACPI: Record the Generic Error Status Block address")
> > > Reported-by: Euler Robot 
> > > Signed-off-by: Peng Liang 
> > > ---
> > >  hw/acpi/generic_event_device.c | 3 +--
> > >  1 file changed, 1 insertion(+), 2 deletions(-)
> > > 
> > > diff --git a/hw/acpi/generic_event_device.c 
> > > b/hw/acpi/generic_event_device.c
> > > index 6df400e1ee16..4b6867300a55 100644
> > > --- a/hw/acpi/generic_event_device.c
> > > +++ b/hw/acpi/generic_event_device.c
> > > @@ -334,8 +334,7 @@ static const VMStateDescription vmstate_ghes_state = {
> > >  .minimum_version_id = 1,
> > >  .needed = ghes_needed,
> > >  .fields  = (VMStateField[]) {
> > > -VMSTATE_STRUCT(ghes_state, AcpiGedState, 1,
> > > -   vmstate_ghes_state, AcpiGhesState),
> > > +VMSTATE_UINT64(ghes_state.ghes_addr_le, AcpiGedState),  
> > 
> > not sure its' ok handle it this way,
> > 
> > see how it is done with another structure:
> > 
> > static const VMStateDescription vmstate_ged_state = {   
> >  
> > .name = "acpi-ged-state",   
> >  
> > .version_id = 1,
> >  
> > .minimum_version_id = 1,
> >  
> > .fields  = (VMStateField[]) {   
> >  
> > VMSTATE_UINT32(sel, GEDState),  
> >  
> > VMSTATE_END_OF_LIST()   
> >  
> > }   
> >  
> > }; 
> > 
> > ...
> > 
> > VMSTATE_STRUCT(ged_state, AcpiGedState, 1, vmstate_ged_state, GEDState),
> > 
> > i.e. it looks like we are missing structure definition for AcpiGhesState
> > 
> > CCing David,
> >  to help with migration magic in case I'm wrong or missed something  
> 
> Yeh that's confusing :-)
> 
> Given a:
> 
>   VMSTATE_STRUCT(a, B, 1, vmstate_c, C)
> 
> We're saying there's a field 'a' in type B, and field 'a'
> should be of type C and be serialised using vmstate_c.
> 
> That also means that in any vmstate_c, we're expecting it
> to be passed a type C generally.
> 
> Having said that; you don't need a struct - you can get away
> with that VMSTATE_UINT64, there's two problems:
> 
>   a) That assumes that your ghes always stays that simple.
>   b) If you wanted to store a Ghes from a number of different
> parent structures then you're stuck because your vmstate_ghes_state
> is bound to being a strict field of AcpiGedState.
> 
> So yes, it's neatest to do it using a VMSD for AcpiGhesState
> 
> And congratulations on finding a loop; I don't think we've ever had one
> before :-)

can we make compilation fail in case VMSTATE_STRUCT is used but
is not actually provided like it was in this case?

> 
> Dave
> 
> > >  VMSTATE_END_OF_LIST()
> > >  }
> > >  };  
> >   




Re: [PATCH 1/5] pc-dimm: Drop @errp argument of pc_dimm_plug()

2020-10-23 Thread Igor Mammedov
On Mon, 19 Oct 2020 10:48:04 +0200
Greg Kurz  wrote:

> pc_dimm_plug() doesn't use it. It only aborts on error.
> 
> Drop @errp and adapt the callers accordingly.
> 
> Signed-off-by: Greg Kurz 
Reviewed-by: Igor Mammedov 

arguably the same should be done in spapr.

> ---
>  hw/arm/virt.c|9 +
>  hw/i386/pc.c |8 +---
>  hw/mem/pc-dimm.c |2 +-
>  hw/ppc/spapr.c   |5 +
>  include/hw/mem/pc-dimm.h |2 +-
>  5 files changed, 5 insertions(+), 21 deletions(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index e465a988d683..27dbeb549ef1 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -2261,12 +2261,8 @@ static void virt_memory_plug(HotplugHandler 
> *hotplug_dev,
>  VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
>  MachineState *ms = MACHINE(hotplug_dev);
>  bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
> -Error *local_err = NULL;
>  
> -pc_dimm_plug(PC_DIMM(dev), MACHINE(vms), _err);
> -if (local_err) {
> -goto out;
> -}
> +pc_dimm_plug(PC_DIMM(dev), MACHINE(vms));
>  
>  if (is_nvdimm) {
>  nvdimm_plug(ms->nvdimms_state);
> @@ -2274,9 +2270,6 @@ static void virt_memory_plug(HotplugHandler 
> *hotplug_dev,
>  
>  hotplug_handler_plug(HOTPLUG_HANDLER(vms->acpi_dev),
>   dev, _abort);
> -
> -out:
> -error_propagate(errp, local_err);
>  }
>  
>  static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index e87be5d29a01..38b1be78e707 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1265,24 +1265,18 @@ static void pc_memory_pre_plug(HotplugHandler 
> *hotplug_dev, DeviceState *dev,
>  static void pc_memory_plug(HotplugHandler *hotplug_dev,
> DeviceState *dev, Error **errp)
>  {
> -Error *local_err = NULL;
>  PCMachineState *pcms = PC_MACHINE(hotplug_dev);
>  X86MachineState *x86ms = X86_MACHINE(hotplug_dev);
>  MachineState *ms = MACHINE(hotplug_dev);
>  bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
>  
> -pc_dimm_plug(PC_DIMM(dev), MACHINE(pcms), _err);
> -if (local_err) {
> -goto out;
> -}
> +pc_dimm_plug(PC_DIMM(dev), MACHINE(pcms));
>  
>  if (is_nvdimm) {
>  nvdimm_plug(ms->nvdimms_state);
>  }
>  
>  hotplug_handler_plug(x86ms->acpi_dev, dev, _abort);
> -out:
> -error_propagate(errp, local_err);
>  }
>  
>  static void pc_memory_unplug_request(HotplugHandler *hotplug_dev,
> diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
> index c30351070bb8..2ffc986734df 100644
> --- a/hw/mem/pc-dimm.c
> +++ b/hw/mem/pc-dimm.c
> @@ -64,7 +64,7 @@ void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState 
> *machine,
> errp);
>  }
>  
> -void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine, Error **errp)
> +void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine)
>  {
>  PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
>  MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm,
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index ee716a12af73..4edd31b86915 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -3438,10 +3438,7 @@ static void spapr_memory_plug(HotplugHandler 
> *hotplug_dev, DeviceState *dev,
>  
>  size = memory_device_get_region_size(MEMORY_DEVICE(dev), _abort);
>  
> -pc_dimm_plug(dimm, MACHINE(ms), _err);
> -if (local_err) {
> -goto out;
> -}
> +pc_dimm_plug(dimm, MACHINE(ms));
>  
>  if (!is_nvdimm) {
>  addr = object_property_get_uint(OBJECT(dimm),
> diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
> index aec9527fdd96..3d3db82641f8 100644
> --- a/include/hw/mem/pc-dimm.h
> +++ b/include/hw/mem/pc-dimm.h
> @@ -72,6 +72,6 @@ struct PCDIMMDeviceClass {
>  
>  void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine,
>const uint64_t *legacy_align, Error **errp);
> -void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine, Error **errp);
> +void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine);
>  void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine);
>  #endif
> 
> 
> 




Re: [PATCH 5/5] spapr: Simplify error handling in spapr_memory_plug()

2020-10-23 Thread Igor Mammedov
On Mon, 19 Oct 2020 10:49:01 +0200
Greg Kurz  wrote:

> As recommended in "qapi/error.h", add a bool return value to
> spapr_add_lmbs() and spapr_add_nvdimm(), and use them instead
> of local_err in spapr_memory_plug().
> 
> This allows to get rid of the error propagation overhead.
> 
> Signed-off-by: Greg Kurz 
you won't need this patch if check from spapr_drc_attach() were
moved to _pre_plug() time.

> ---
>  hw/ppc/spapr.c|   23 ++-
>  hw/ppc/spapr_nvdimm.c |5 +++--
>  include/hw/ppc/spapr_nvdimm.h |2 +-
>  3 files changed, 14 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 62f217a6b914..0cc19b5863a4 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -3382,7 +3382,7 @@ int spapr_lmb_dt_populate(SpaprDrc *drc, 
> SpaprMachineState *spapr,
>  return 0;
>  }
>  
> -static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t 
> size,
> +static bool spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t 
> size,
> bool dedicated_hp_event_source, Error **errp)
>  {
>  SpaprDrc *drc;
> @@ -3403,7 +3403,7 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t 
> addr_start, uint64_t size,
>addr / SPAPR_MEMORY_BLOCK_SIZE);
>  spapr_drc_detach(drc);
>  }
> -return;
> +return false;
>  }
>  if (!hotplugged) {
>  spapr_drc_reset(drc);
> @@ -3425,12 +3425,12 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t 
> addr_start, uint64_t size,
> nr_lmbs);
>  }
>  }
> +return true;
>  }
>  
>  static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
>Error **errp)
>  {
> -Error *local_err = NULL;
>  SpaprMachineState *ms = SPAPR_MACHINE(hotplug_dev);
>  PCDIMMDevice *dimm = PC_DIMM(dev);
>  uint64_t size, addr;
> @@ -3444,27 +3444,24 @@ static void spapr_memory_plug(HotplugHandler 
> *hotplug_dev, DeviceState *dev,
>  if (!is_nvdimm) {
>  addr = object_property_get_uint(OBJECT(dimm),
>  PC_DIMM_ADDR_PROP, _abort);
> -spapr_add_lmbs(dev, addr, size,
> -   spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT),
> -   _err);
> +if (!spapr_add_lmbs(dev, addr, size,
> +spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT), errp)) 
> {
> +goto out_unplug;
> +}
>  } else {
>  slot = object_property_get_int(OBJECT(dimm),
> PC_DIMM_SLOT_PROP, _abort);
>  /* We should have valid slot number at this point */
>  g_assert(slot >= 0);
> -spapr_add_nvdimm(dev, slot, _err);
> -}
> -
> -if (local_err) {
> -goto out_unplug;
> +if (!spapr_add_nvdimm(dev, slot, errp)) {
> +goto out_unplug;
> +}
>  }
>  
>  return;
>  
>  out_unplug:
>  pc_dimm_unplug(dimm, MACHINE(ms));
> -out:
> -error_propagate(errp, local_err);
>  }
>  
>  static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState 
> *dev,
> diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
> index 9e3d94071fe1..a833a63b5ed3 100644
> --- a/hw/ppc/spapr_nvdimm.c
> +++ b/hw/ppc/spapr_nvdimm.c
> @@ -89,7 +89,7 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, 
> NVDIMMDevice *nvdimm,
>  }
>  
>  
> -void spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp)
> +bool spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp)
>  {
>  SpaprDrc *drc;
>  bool hotplugged = spapr_drc_hotplugged(dev);
> @@ -98,12 +98,13 @@ void spapr_add_nvdimm(DeviceState *dev, uint64_t slot, 
> Error **errp)
>  g_assert(drc);
>  
>  if (!spapr_drc_attach(drc, dev, errp)) {
> -return;
> +return false;
>  }
>  
>  if (hotplugged) {
>  spapr_hotplug_req_add_by_index(drc);
>  }
> +return true;
>  }
>  
>  static int spapr_dt_nvdimm(SpaprMachineState *spapr, void *fdt,
> diff --git a/include/hw/ppc/spapr_nvdimm.h b/include/hw/ppc/spapr_nvdimm.h
> index 490b19a009f4..344582d2f5f7 100644
> --- a/include/hw/ppc/spapr_nvdimm.h
> +++ b/include/hw/ppc/spapr_nvdimm.h
> @@ -30,6 +30,6 @@ int spapr_pmem_dt_populate(SpaprDrc *drc, SpaprMachineState 
> *spapr,
>  void spapr_dt_persistent_memory(SpaprMachineState *spapr, void *fdt);
>  bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
> uint64_t size, Error **errp);
> -void spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp);
> +bool spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp);
>  
>  #endif
> 
> 




Re: [PATCH 4/5] spapr: Pass _abort when getting some PC DIMM properties

2020-10-23 Thread Igor Mammedov
On Mon, 19 Oct 2020 10:48:41 +0200
Greg Kurz  wrote:

> Both PC_DIMM_SLOT_PROP and PC_DIMM_ADDR_PROP are defined in the
> default property list of the PC DIMM device class:
> 
> DEFINE_PROP_UINT64(PC_DIMM_ADDR_PROP, PCDIMMDevice, addr, 0),
> 
> DEFINE_PROP_INT32(PC_DIMM_SLOT_PROP, PCDIMMDevice, slot,
>   PC_DIMM_UNASSIGNED_SLOT),
> 
> They should thus be always gettable for both PC DIMMs and NVDIMMs.
> An error in getting them can only be the result of a programming
> error. It doesn't make much sense to propagate the error in this
> case. Abort instead.
> 
> Signed-off-by: Greg Kurz 

Reviewed-by: Igor Mammedov 

TODO for future,
get rid of local_err in spapr_memory_plug() altogether, it should not fail.
it needs moving check from spapr_drc_attach() to spapr_memory_pre_plug() time.

that will clear up (a bit) road for dropping errp in spapr_memory_plug()
> ---
>  hw/ppc/spapr.c |   17 +++--
>  1 file changed, 3 insertions(+), 14 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 1b173861152f..62f217a6b914 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -3443,19 +3443,13 @@ static void spapr_memory_plug(HotplugHandler 
> *hotplug_dev, DeviceState *dev,
>  
>  if (!is_nvdimm) {
>  addr = object_property_get_uint(OBJECT(dimm),
> -PC_DIMM_ADDR_PROP, _err);
> -if (local_err) {
> -goto out_unplug;
> -}
> +PC_DIMM_ADDR_PROP, _abort);
>  spapr_add_lmbs(dev, addr, size,
> spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT),
> _err);
>  } else {
>  slot = object_property_get_int(OBJECT(dimm),
> -   PC_DIMM_SLOT_PROP, _err);
> -if (local_err) {
> -goto out_unplug;
> -}
> +   PC_DIMM_SLOT_PROP, _abort);
>  /* We should have valid slot number at this point */
>  g_assert(slot >= 0);
>  spapr_add_nvdimm(dev, slot, _err);
> @@ -3634,7 +3628,6 @@ static void spapr_memory_unplug_request(HotplugHandler 
> *hotplug_dev,
>  DeviceState *dev, Error **errp)
>  {
>  SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
> -Error *local_err = NULL;
>  PCDIMMDevice *dimm = PC_DIMM(dev);
>  uint32_t nr_lmbs;
>  uint64_t size, addr_start, addr;
> @@ -3650,11 +3643,7 @@ static void spapr_memory_unplug_request(HotplugHandler 
> *hotplug_dev,
>  nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
>  
>  addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP,
> - _err);
> -if (local_err) {
> -error_propagate(errp, local_err);
> -return;
> -}
> +  _abort);
>  
>  /*
>   * An existing pending dimm state for this DIMM means that there is an
> 
> 
> 




Re: [PATCH v1 1/5] target/riscv: Add a virtualised MMU Mode

2020-10-23 Thread Richard Henderson
On 10/23/20 8:26 AM, Alistair Francis wrote:
> +++ b/target/riscv/cpu-param.h
> @@ -18,6 +18,6 @@
>  # define TARGET_VIRT_ADDR_SPACE_BITS 32 /* sv32 */
>  #endif
>  #define TARGET_PAGE_BITS 12 /* 4 KiB Pages */
> -#define NB_MMU_MODES 4
> +#define NB_MMU_MODES 8

Is there really a PRV_M + virt enabled state?

> +#define TB_FLAGS_PRIV_MMU_MASK3
...
> -int mode = mmu_idx;
> +int mode = mmu_idx & 0x3;

Use that MASK here?


r~



Re: [PATCH 19/30] parallel nor flas...: Fix Lesser GPL version number

2020-10-23 Thread Thomas Huth


The subject looks a little bit odd - should be "flash" instead of "flas..."
... with that fixed:

Reviewed-by: Thomas Huth 


On 23/10/2020 14.30, Chetan Pant wrote:
> There is no "version 2" of the "Lesser" General Public License.
> It is either "GPL version 2.0" or "Lesser GPL version 2.1".
> This patch replaces all occurrences of "Lesser GPL version 2" with
> "Lesser GPL version 2.1" in comment section.
> 
> Signed-off-by: Chetan Pant 
> ---
>  hw/block/pflash_cfi01.c | 2 +-
>  hw/block/pflash_cfi02.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
> index f0fcd63..daae965 100644
> --- a/hw/block/pflash_cfi01.c
> +++ b/hw/block/pflash_cfi01.c
> @@ -7,7 +7,7 @@
>   * This library is free software; you can redistribute it and/or
>   * modify it under the terms of the GNU Lesser General Public
>   * License as published by the Free Software Foundation; either
> - * version 2 of the License, or (at your option) any later version.
> + * version 2.1 of the License, or (at your option) any later version.
>   *
>   * This library is distributed in the hope that it will be useful,
>   * but WITHOUT ANY WARRANTY; without even the implied warranty of
> diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
> index eb02fcc..1b3d94e 100644
> --- a/hw/block/pflash_cfi02.c
> +++ b/hw/block/pflash_cfi02.c
> @@ -6,7 +6,7 @@
>   * This library is free software; you can redistribute it and/or
>   * modify it under the terms of the GNU Lesser General Public
>   * License as published by the Free Software Foundation; either
> - * version 2 of the License, or (at your option) any later version.
> + * version 2.1 of the License, or (at your option) any later version.
>   *
>   * This library is distributed in the hope that it will be useful,
>   * but WITHOUT ANY WARRANTY; without even the implied warranty of
> 




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

2020-10-23 Thread Igor Mammedov
On Fri, 23 Oct 2020 19:39:16 +0200
Philippe Mathieu-Daudé  wrote:

> On 10/23/20 5:43 PM, Igor Mammedov wrote:
> > On Mon, 19 Oct 2020 11:43:13 +0200
> > Philippe Mathieu-Daudé  wrote:  
> > 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)  
> >>>
> >>> FWIW:
> >>>
> >>> 7998beb9c2e280f0b7424223747941f106e2e854 is the first bad commit
> >>> commit 7998beb9c2e280f0b7424223747941f106e2e854
> >>> Author: Igor Mammedov 
> >>> Date:   Wed Feb 19 11:08:59 2020 -0500
> >>>
> >>>       arm/nseries: use memdev for RAM
> >>>
> >>>       memory_region_allocate_system_memory() API is going away, so
> >>>       replace it with memdev allocated MemoryRegion. The later is
> >>>       initialized by generic code, so board only needs to opt in
> >>>       to memdev scheme by providing
> >>>     MachineClass::default_ram_id
> >>>       and using MachineState::ram instead of manually initializing
> >>>       RAM memory region.
> >>>
> >>>       PS:
> >>>    while at it add check for user supplied RAM size and error
> >>>    out if it mismatches board expected value.
> >>>
> >>>       Signed-off-by: Igor Mammedov 
> >>>       Reviewed-by: Andrew Jones 
> >>>       Reviewed-by: Richard Henderson 
> >>>       Message-Id: <20200219160953.13771-26-imamm...@redhat.com>  
> >>
> >> This fixes the issue:
> >>  
> >> -- >8 --  
> >> diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
> >> index e48092ca047..76fd7fe9854 100644
> >> --- a/hw/arm/nseries.c
> >> +++ b/hw/arm/nseries.c
> >> @@ -1318,6 +1318,7 @@ static void n8x0_init(MachineState *machine,
> >>g_free(sz);
> >>exit(EXIT_FAILURE);
> >>}
> >> +binfo->ram_size = machine->ram_size;
> >>
> >>memory_region_add_subregion(get_system_memory(), OMAP2_Q2_BASE,
> >>machine->ram);  
> > 
> > we really should replace binfo->ram_size with machine->ram_size to avoid
> > duplicating the same data, but as a quick fix this should fix issue.  
> 
> Hmm this is the 'ARM kernel loader' API in "arm/boot.h":
> 
> struct arm_boot_info {
>  uint64_t ram_size;
>  const char *kernel_filename;
>  const char *kernel_cmdline;
>  const char *initrd_filename;
>  const char *dtb_filename;
> 
> and:
> 
>void (*write_secondary_boot)(ARMCPU *cpu,
> const struct arm_boot_info *info);
>void (*secondary_cpu_reset_hook)(ARMCPU *cpu,
> const struct arm_boot_info *info);
> 
> Are you saying arm_boot_info should hold a pointer to MachineState*
> instead of duplicating?

yep, some parts of it (fdt related) already use MachineState* so it's
complete rewrite. The same probably applies to the fields you've just
quoted.

> 




Re: [PATCH 21/30] overall usermode...: Fix Lesser GPL version number

2020-10-23 Thread Thomas Huth
On 23/10/2020 14.32, Chetan Pant wrote:
> There is no "version 2" of the "Lesser" General Public License.
> It is either "GPL version 2.0" or "Lesser GPL version 2.1".
> This patch replaces all occurrences of "Lesser GPL version 2" with
> "Lesser GPL version 2.1" in comment section.
> 
> Signed-off-by: Chetan Pant 
> ---
>  thunk.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/thunk.c b/thunk.c
> index 0718325..fc5be1a 100644
> --- a/thunk.c
> +++ b/thunk.c
> @@ -6,7 +6,7 @@
>   * This library is free software; you can redistribute it and/or
>   * modify it under the terms of the GNU Lesser General Public
>   * License as published by the Free Software Foundation; either
> - * version 2 of the License, or (at your option) any later version.
> + * version 2.1 of the License, or (at your option) any later version.
>   *
>   * This library is distributed in the hope that it will be useful,
>   * but WITHOUT ANY WARRANTY; without even the implied warranty of
> 

Reviewed-by: Thomas Huth 




Re: [PATCH 18/30] arm tcg cpus: Fix Lesser GPL version number

2020-10-23 Thread Thomas Huth
On 23/10/2020 14.29, Chetan Pant wrote:
> There is no "version 2" of the "Lesser" General Public License.
> It is either "GPL version 2.0" or "Lesser GPL version 2.1".
> This patch replaces all occurrences of "Lesser GPL version 2" with
> "Lesser GPL version 2.1" in comment section.
> 
> Signed-off-by: Chetan Pant 
> ---
>  hw/intc/arm_gicv2m.c| 2 +-
>  hw/intc/arm_gicv3_its_kvm.c | 2 +-
>  target/arm/a32-uncond.decode| 2 +-
>  target/arm/a32.decode   | 2 +-
>  target/arm/arm_ldst.h   | 2 +-
>  target/arm/cpu.h| 2 +-
>  target/arm/crypto_helper.c  | 2 +-
>  target/arm/gdbstub.c| 2 +-
>  target/arm/gdbstub64.c  | 2 +-
>  target/arm/helper-a64.c | 2 +-
>  target/arm/helper-a64.h | 2 +-
>  target/arm/helper-sve.h | 2 +-
>  target/arm/iwmmxt_helper.c  | 2 +-
>  target/arm/neon-dp.decode   | 2 +-
>  target/arm/neon-ls.decode   | 2 +-
>  target/arm/neon-shared.decode   | 2 +-
>  target/arm/op_helper.c  | 2 +-
>  target/arm/pauth_helper.c   | 2 +-
>  target/arm/sve.decode   | 2 +-
>  target/arm/sve_helper.c | 2 +-
>  target/arm/t16.decode   | 2 +-
>  target/arm/t32.decode   | 2 +-
>  target/arm/translate-a64.c  | 2 +-
>  target/arm/translate-a64.h  | 2 +-
>  target/arm/translate-neon.c.inc | 2 +-
>  target/arm/translate-sve.c  | 2 +-
>  target/arm/translate-vfp.c.inc  | 2 +-
>  target/arm/translate.c  | 2 +-
>  target/arm/vec_helper.c | 2 +-
>  target/arm/vec_internal.h   | 2 +-
>  target/arm/vfp-uncond.decode| 2 +-
>  target/arm/vfp.decode   | 2 +-
>  32 files changed, 32 insertions(+), 32 deletions(-)

Reviewed-by: Thomas Huth 





Re: [PATCH v3 00/18] Support Multifd for RDMA migration

2020-10-23 Thread Dr. David Alan Gilbert
* Zheng Chuan (zhengch...@huawei.com) wrote:
> 
> 
> On 2020/10/21 17:25, Zhanghailiang wrote:
> > Hi zhengchuan,
> > 
> >> -Original Message-
> >> From: zhengchuan
> >> Sent: Saturday, October 17, 2020 12:26 PM
> >> To: quint...@redhat.com; dgilb...@redhat.com
> >> Cc: Zhanghailiang ; Chenzhendong (alex)
> >> ; Xiexiangyou ; wanghao
> >> (O) ; yubihong ;
> >> fengzhim...@huawei.com; qemu-devel@nongnu.org
> >> Subject: [PATCH v3 00/18] Support Multifd for RDMA migration
> >>
> >> Now I continue to support multifd for RDMA migration based on my colleague
> >> zhiming's work:)
> >>
> >> The previous RFC patches is listed below:
> >> v1:
> >> https://www.mail-archive.com/qemu-devel@nongnu.org/msg669455.html
> >> v2:
> >> https://www.mail-archive.com/qemu-devel@nongnu.org/msg679188.html
> >>
> >> As descried in previous RFC, the RDMA bandwidth is not fully utilized for 
> >> over
> >> 25Gigabit NIC because of single channel for RDMA migration.
> >> This patch series is going to support multifd for RDMA migration based on 
> >> multifd
> >> framework.
> >>
> >> Comparsion is between origion and multifd RDMA migration is re-tested for 
> >> v3.
> >> The VM specifications for migration are as follows:
> >> - VM use 4k page;
> >> - the number of VCPU is 4;
> >> - the total memory is 16Gigabit;
> >> - use 'mempress' tool to pressurize VM(mempress 8000 500);
> >> - use 25Gigabit network card to migrate;
> >>
> >> For origin RDMA and MultiRDMA migration, the total migration times of VM 
> >> are
> >> as follows:
> >> +
> >> | | NOT rdma-pin-all | rdma-pin-all |
> >> +
> >> | origin RDMA |   26 s   | 29 s |
> >> -
> >> |  MultiRDMA  |   16 s   | 17 s |
> >> +
> >>
> >> Test the multifd RDMA migration like this:
> >> virsh migrate --live --multiFd --migrateuri
> > 
> > There is no option '--multiFd' for virsh commands, It seems that, we added 
> > this private option for internal usage.
> > It's better to provide testing method by using qemu commands.
> > 
> > 
> Hi, Hailiang
> Yes, it should be, will update in V4.
> 
> Also, Ping.
> 
> Dave, Juan.
> 
> Any suggestion and comment about this series? Hope this feature could catch 
> up with qemu 5.2.

It's a bit close; I'm not sure if I'll have time to review it on Monday
before the pull.

Dave

> > Thanks.
> > 
> >> rdma://192.168.1.100 [VM] --listen-address 0.0.0.0
> >> qemu+tcp://192.168.1.100/system --verbose
> >>
> >> v2 -> v3:
> >> create multifd ops for both tcp and rdma
> >> do not export rdma to avoid multifd code in mess
> >> fix build issue for non-rdma
> >> fix some codestyle and buggy code
> >>
> >> Chuan Zheng (18):
> >>   migration/rdma: add the 'migrate_use_rdma_pin_all' function
> >>   migration/rdma: judge whether or not the RDMA is used for migration
> >>   migration/rdma: create multifd_setup_ops for Tx/Rx thread
> >>   migration/rdma: add multifd_setup_ops for rdma
> >>   migration/rdma: do not need sync main for rdma
> >>   migration/rdma: export MultiFDSendParams/MultiFDRecvParams
> >>   migration/rdma: add rdma field into multifd send/recv param
> >>   migration/rdma: export getQIOChannel to get QIOchannel in rdma
> >>   migration/rdma: add multifd_rdma_load_setup() to setup multifd rdma
> >>   migration/rdma: Create the multifd recv channels for RDMA
> >>   migration/rdma: record host_port for multifd RDMA
> >>   migration/rdma: Create the multifd send channels for RDMA
> >>   migration/rdma: Add the function for dynamic page registration
> >>   migration/rdma: register memory for multifd RDMA channels
> >>   migration/rdma: only register the memory for multifd channels
> >>   migration/rdma: add rdma_channel into Migrationstate field
> >>   migration/rdma: send data for both rdma-pin-all and NOT rdma-pin-all
> >> mode
> >>   migration/rdma: RDMA cleanup for multifd migration
> >>
> >>  migration/migration.c |  24 +++
> >>  migration/migration.h |  11 ++
> >>  migration/multifd.c   |  97 +-
> >>  migration/multifd.h   |  24 +++
> >>  migration/qemu-file.c |   5 +
> >>  migration/qemu-file.h |   1 +
> >>  migration/rdma.c  | 503
> >> +-
> >>  7 files changed, 653 insertions(+), 12 deletions(-)
> >>
> >> --
> >> 1.8.3.1
> > 
> > .
> > 
> 
> -- 
> Regards.
> Chuan
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH 1/4] microvm: make number of virtio transports runtime configurable

2020-10-23 Thread Igor Mammedov
On Fri, 16 Oct 2020 13:43:25 +0200
Gerd Hoffmann  wrote:

> Signed-off-by: Gerd Hoffmann 
> ---
>  include/hw/i386/microvm.h | 2 +-
>  hw/i386/microvm.c | 9 +++--
>  2 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
> index 91b064575d55..0154ad5bd707 100644
> --- a/include/hw/i386/microvm.h
> +++ b/include/hw/i386/microvm.h
> @@ -52,7 +52,6 @@
>  
>  /* Platform virtio definitions */
>  #define VIRTIO_MMIO_BASE  0xfeb0
> -#define VIRTIO_NUM_TRANSPORTS 8
>  #define VIRTIO_CMDLINE_MAXLEN 64
>  
>  #define GED_MMIO_BASE 0xfea0
> @@ -95,6 +94,7 @@ struct MicrovmMachineState {
>  
>  /* Machine state */
>  uint32_t virtio_irq_base;
> +uint32_t virtio_num_transports;
>  bool kernel_cmdline_fixed;
>  Notifier machine_done;
>  Notifier powerdown_req;
> diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
> index 9dd74458aca4..eaf5da31f7e1 100644
> --- a/hw/i386/microvm.c
> +++ b/hw/i386/microvm.c
> @@ -177,8 +177,13 @@ static void microvm_devices_init(MicrovmMachineState 
> *mms)
>  
>  kvmclock_create(true);
>  
> -mms->virtio_irq_base = x86_machine_is_acpi_enabled(x86ms) ? 16 : 5;
> -for (i = 0; i < VIRTIO_NUM_TRANSPORTS; i++) {
> +mms->virtio_irq_base = 5;
> +mms->virtio_num_transports = 8;
> +if (x86_machine_is_acpi_enabled(x86ms)) {
> +mms->virtio_irq_base = 16;
> +}

can we unify and use the same base in both cases?

> +
> +for (i = 0; i < mms->virtio_num_transports; i++) {
>  sysbus_create_simple("virtio-mmio",
>   VIRTIO_MMIO_BASE + i * 512,
>   x86ms->gsi[mms->virtio_irq_base + i]);




Re: [PATCH 17/30] x86 tcg cpus: Fix Lesser GPL version number

2020-10-23 Thread Thomas Huth
On 23/10/2020 14.28, Chetan Pant wrote:
> There is no "version 2" of the "Lesser" General Public License.
> It is either "GPL version 2.0" or "Lesser GPL version 2.1".
> This patch replaces all occurrences of "Lesser GPL version 2" with
> "Lesser GPL version 2.1" in comment section.
> 
> Signed-off-by: Chetan Pant 
> ---
>  target/i386/bpt_helper.c| 2 +-
>  target/i386/cc_helper.c | 2 +-
>  target/i386/cc_helper_template.h| 2 +-
>  target/i386/cpu.c   | 2 +-
>  target/i386/cpu.h   | 2 +-
>  target/i386/excp_helper.c   | 2 +-
>  target/i386/fpu_helper.c| 2 +-
>  target/i386/gdbstub.c   | 2 +-
>  target/i386/helper.c| 2 +-
>  target/i386/int_helper.c| 2 +-
>  target/i386/mem_helper.c| 2 +-
>  target/i386/misc_helper.c   | 2 +-
>  target/i386/mpx_helper.c| 2 +-
>  target/i386/ops_sse.h   | 2 +-
>  target/i386/ops_sse_header.h| 2 +-
>  target/i386/seg_helper.c| 2 +-
>  target/i386/shift_helper_template.h | 2 +-
>  target/i386/smm_helper.c| 2 +-
>  target/i386/svm_helper.c| 2 +-
>  target/i386/tcg-stub.c  | 2 +-
>  target/i386/translate.c | 2 +-
>  21 files changed, 21 insertions(+), 21 deletions(-)

Reviewed-by: Thomas Huth 




Re: [PATCH 2/4] microvm: make pcie irq base runtime configurable

2020-10-23 Thread Igor Mammedov
On Fri, 16 Oct 2020 13:43:26 +0200
Gerd Hoffmann  wrote:

> Signed-off-by: Gerd Hoffmann 

Reviewed-by: Igor Mammedov 

> ---
>  include/hw/i386/microvm.h |  2 +-
>  hw/i386/microvm.c | 11 ++-
>  2 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
> index 0154ad5bd707..ede9625756b8 100644
> --- a/include/hw/i386/microvm.h
> +++ b/include/hw/i386/microvm.h
> @@ -63,7 +63,6 @@
>  #define PCIE_MMIO_SIZE0x2000
>  #define PCIE_ECAM_BASE0xe000
>  #define PCIE_ECAM_SIZE0x1000
> -#define PCIE_IRQ_BASE 12
>  
>  /* Machine type options */
>  #define MICROVM_MACHINE_PIT "pit"
> @@ -93,6 +92,7 @@ struct MicrovmMachineState {
>  bool auto_kernel_cmdline;
>  
>  /* Machine state */
> +uint32_t pcie_irq_base;
>  uint32_t virtio_irq_base;
>  uint32_t virtio_num_transports;
>  bool kernel_cmdline_fixed;
> diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
> index eaf5da31f7e1..638e95c39e8c 100644
> --- a/hw/i386/microvm.c
> +++ b/hw/i386/microvm.c
> @@ -180,6 +180,7 @@ static void microvm_devices_init(MicrovmMachineState *mms)
>  mms->virtio_irq_base = 5;
>  mms->virtio_num_transports = 8;
>  if (x86_machine_is_acpi_enabled(x86ms)) {
> +mms->pcie_irq_base = 12;
>  mms->virtio_irq_base = 16;
>  }
>  
> @@ -213,12 +214,12 @@ static void microvm_devices_init(MicrovmMachineState 
> *mms)
>  mms->gpex.mmio32.size = PCIE_MMIO_SIZE;
>  mms->gpex.ecam.base   = PCIE_ECAM_BASE;
>  mms->gpex.ecam.size   = PCIE_ECAM_SIZE;
> -mms->gpex.irq = PCIE_IRQ_BASE;
> +mms->gpex.irq = mms->pcie_irq_base;
>  create_gpex(mms);
> -x86ms->pci_irq_mask = ((1 << (PCIE_IRQ_BASE + 0)) |
> -   (1 << (PCIE_IRQ_BASE + 1)) |
> -   (1 << (PCIE_IRQ_BASE + 2)) |
> -   (1 << (PCIE_IRQ_BASE + 3)));
> +x86ms->pci_irq_mask = ((1 << (mms->pcie_irq_base + 0)) |
> +   (1 << (mms->pcie_irq_base + 1)) |
> +   (1 << (mms->pcie_irq_base + 2)) |
> +   (1 << (mms->pcie_irq_base + 3)));
>  } else {
>  x86ms->pci_irq_mask = 0;
>  }




Re: [PATCH 3/4] microvm: add second ioapic

2020-10-23 Thread Igor Mammedov
On Fri, 16 Oct 2020 13:43:27 +0200
Gerd Hoffmann  wrote:

> Add more IRQ lines.  Depends on ACPI.
> Also enable this only with userspace ioapic,
> not sure whenever the kernel can handle two ioapics.
> 
> Signed-off-by: Gerd Hoffmann 

For ACPI part:
Reviewed-by: Igor Mammedov 

> ---
>  include/hw/i386/ioapic_internal.h |  2 +-
>  include/hw/i386/x86.h |  1 +
>  hw/i386/acpi-common.c | 10 ++
>  hw/i386/microvm.c | 30 --
>  4 files changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/include/hw/i386/ioapic_internal.h 
> b/include/hw/i386/ioapic_internal.h
> index 0ac9e2400d6b..4cebd2e32c9f 100644
> --- a/include/hw/i386/ioapic_internal.h
> +++ b/include/hw/i386/ioapic_internal.h
> @@ -27,7 +27,7 @@
>  #include "qemu/notify.h"
>  #include "qom/object.h"
>  
> -#define MAX_IOAPICS 1
> +#define MAX_IOAPICS 2
>  
>  #define IOAPIC_LVT_DEST_SHIFT   56
>  #define IOAPIC_LVT_DEST_IDX_SHIFT   48
> diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
> index bfa9cb2a258b..6da57033a875 100644
> --- a/include/hw/i386/x86.h
> +++ b/include/hw/i386/x86.h
> @@ -120,6 +120,7 @@ bool x86_machine_is_acpi_enabled(const X86MachineState 
> *x86ms);
>  typedef struct GSIState {
>  qemu_irq i8259_irq[ISA_NUM_IRQS];
>  qemu_irq ioapic_irq[IOAPIC_NUM_PINS];
> +qemu_irq ioapic2_irq[IOAPIC_NUM_PINS];
>  } GSIState;
>  
>  qemu_irq x86_allocate_cpu_irq(void);
> diff --git a/hw/i386/acpi-common.c b/hw/i386/acpi-common.c
> index 8a769654060e..f0689392a39f 100644
> --- a/hw/i386/acpi-common.c
> +++ b/hw/i386/acpi-common.c
> @@ -103,6 +103,16 @@ void acpi_build_madt(GArray *table_data, BIOSLinker 
> *linker,
>  io_apic->address = cpu_to_le32(IO_APIC_DEFAULT_ADDRESS);
>  io_apic->interrupt = cpu_to_le32(0);
>  
> +if (object_property_find(OBJECT(x86ms), "ioapic2")) {
> +AcpiMadtIoApic *io_apic2;
> +io_apic2 = acpi_data_push(table_data, sizeof *io_apic);
> +io_apic2->type = ACPI_APIC_IO;
> +io_apic2->length = sizeof(*io_apic);
> +io_apic2->io_apic_id = ACPI_BUILD_IOAPIC_ID + 1;
> +io_apic2->address = cpu_to_le32(IO_APIC_DEFAULT_ADDRESS + 0x1);
> +io_apic2->interrupt = cpu_to_le32(24);
> +}
> +
>  if (x86ms->apic_xrupt_override) {
>  intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);
>  intsrcovr->type   = ACPI_APIC_XRUPT_OVERRIDE;
> diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
> index 638e95c39e8c..15c3e078a4aa 100644
> --- a/hw/i386/microvm.c
> +++ b/hw/i386/microvm.c
> @@ -99,7 +99,11 @@ static void microvm_gsi_handler(void *opaque, int n, int 
> level)
>  {
>  GSIState *s = opaque;
>  
> -qemu_set_irq(s->ioapic_irq[n], level);
> +if (n >= 24) {
> +qemu_set_irq(s->ioapic2_irq[n - 24], level);
> +} else {
> +qemu_set_irq(s->ioapic_irq[n], level);
> +}
>  }
>  
>  static void create_gpex(MicrovmMachineState *mms)
> @@ -157,6 +161,7 @@ static void microvm_devices_init(MicrovmMachineState *mms)
>  ISABus *isa_bus;
>  ISADevice *rtc_state;
>  GSIState *gsi_state;
> +bool ioapic2 = false;
>  int i;
>  
>  /* Core components */
> @@ -165,8 +170,13 @@ static void microvm_devices_init(MicrovmMachineState 
> *mms)
>  if (mms->pic == ON_OFF_AUTO_ON || mms->pic == ON_OFF_AUTO_AUTO) {
>  x86ms->gsi = qemu_allocate_irqs(gsi_handler, gsi_state, 
> GSI_NUM_PINS);
>  } else {
> +int pins = GSI_NUM_PINS;
> +if (!kvm_ioapic_in_kernel() && x86_machine_is_acpi_enabled(x86ms)) {
> +ioapic2 = true;
> +pins += 24;
> +}
>  x86ms->gsi = qemu_allocate_irqs(microvm_gsi_handler,
> -gsi_state, GSI_NUM_PINS);
> +gsi_state, pins);
>  }
>  
>  isa_bus = isa_bus_new(NULL, get_system_memory(), get_system_io(),
> @@ -175,6 +185,22 @@ static void microvm_devices_init(MicrovmMachineState 
> *mms)
>  
>  ioapic_init_gsi(gsi_state, "machine");
>  
> +if (ioapic2) {
> +DeviceState *dev;
> +SysBusDevice *d;
> +unsigned int i;
> +
> +dev = qdev_new(TYPE_IOAPIC);
> +object_property_add_child(OBJECT(mms), "ioapic2", OBJECT(dev));
> +d = SYS_BUS_DEVICE(dev);
> +sysbus_realize_and_unref(d, _fatal);
> +sysbus_mmio_map(d, 0, IO_APIC_DEFAULT_ADDRESS + 0x1);
> +
> +for (i = 0; i < IOAPIC_NUM_PINS; i++) {
> +gsi_state->ioapic2_irq[i] = qdev_get_gpio_in(dev, i);
> +}
> +}
> +
>  kvmclock_create(true);
>  
>  mms->virtio_irq_base = 5;




Re: [PATCH] ACPI: Avoid infinite recursion when dump-vmstate

2020-10-23 Thread Dr. David Alan Gilbert
* Igor Mammedov (imamm...@redhat.com) wrote:
> On Mon, 19 Oct 2020 17:31:56 +0800
> Peng Liang  wrote:
> 
> > There is a field with vmstate_ghes_state as vmsd in vmstate_ghes_state,
> > which will lead to infinite recursion in dump_vmstate_vmsd.
> > 
> > Fixes: a08a64627b ("ACPI: Record the Generic Error Status Block address")
> > Reported-by: Euler Robot 
> > Signed-off-by: Peng Liang 
> > ---
> >  hw/acpi/generic_event_device.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> > 
> > diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
> > index 6df400e1ee16..4b6867300a55 100644
> > --- a/hw/acpi/generic_event_device.c
> > +++ b/hw/acpi/generic_event_device.c
> > @@ -334,8 +334,7 @@ static const VMStateDescription vmstate_ghes_state = {
> >  .minimum_version_id = 1,
> >  .needed = ghes_needed,
> >  .fields  = (VMStateField[]) {
> > -VMSTATE_STRUCT(ghes_state, AcpiGedState, 1,
> > -   vmstate_ghes_state, AcpiGhesState),
> > +VMSTATE_UINT64(ghes_state.ghes_addr_le, AcpiGedState),
> 
> not sure its' ok handle it this way,
> 
> see how it is done with another structure:
> 
> static const VMStateDescription vmstate_ged_state = { 
>
> .name = "acpi-ged-state", 
>
> .version_id = 1,  
>
> .minimum_version_id = 1,  
>
> .fields  = (VMStateField[]) { 
>
> VMSTATE_UINT32(sel, GEDState),
>
> VMSTATE_END_OF_LIST() 
>
> } 
>
> }; 
> 
> ...
> 
> VMSTATE_STRUCT(ged_state, AcpiGedState, 1, vmstate_ged_state, GEDState),
> 
> i.e. it looks like we are missing structure definition for AcpiGhesState
> 
> CCing David,
>  to help with migration magic in case I'm wrong or missed something

Yeh that's confusing :-)

Given a:

  VMSTATE_STRUCT(a, B, 1, vmstate_c, C)

We're saying there's a field 'a' in type B, and field 'a'
should be of type C and be serialised using vmstate_c.

That also means that in any vmstate_c, we're expecting it
to be passed a type C generally.

Having said that; you don't need a struct - you can get away
with that VMSTATE_UINT64, there's two problems:

  a) That assumes that your ghes always stays that simple.
  b) If you wanted to store a Ghes from a number of different
parent structures then you're stuck because your vmstate_ghes_state
is bound to being a strict field of AcpiGedState.

So yes, it's neatest to do it using a VMSD for AcpiGhesState

And congratulations on finding a loop; I don't think we've ever had one
before :-)

Dave

> >  VMSTATE_END_OF_LIST()
> >  }
> >  };
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH 4/4] microvm: reconfigure irqs if second ioapic is available

2020-10-23 Thread Igor Mammedov
On Fri, 16 Oct 2020 13:43:28 +0200
Gerd Hoffmann  wrote:

> Use GSI 16+ for PCIe (needs acpi_build_madt() tweak).
> Use GSI 24+ (second ioapic) for virtio-mmio.
> Use all irq lines of the second ioapic
> and allow up to 24 virtio-mmio devices.

description is  missing answer to question why it's done.


> 
> Signed-off-by: Gerd Hoffmann 
> ---
>  hw/i386/acpi-common.c | 2 +-
>  hw/i386/microvm.c | 6 +-
>  2 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/i386/acpi-common.c b/hw/i386/acpi-common.c
> index f0689392a39f..1653a8315248 100644
> --- a/hw/i386/acpi-common.c
> +++ b/hw/i386/acpi-common.c
> @@ -122,7 +122,7 @@ void acpi_build_madt(GArray *table_data, BIOSLinker 
> *linker,
>  intsrcovr->flags  = cpu_to_le16(0); /* conforms to bus 
> specifications */
>  }
>  
> -for (i = 1; i < 16; i++) {
> +for (i = 1; i < 24; i++) {
>  if (!(x86ms->pci_irq_mask & (1 << i))) {
>  /* No need for a INT source override structure. */
>  continue;
> diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
> index 15c3e078a4aa..70bb8a4e3954 100644
> --- a/hw/i386/microvm.c
> +++ b/hw/i386/microvm.c
> @@ -205,7 +205,11 @@ static void microvm_devices_init(MicrovmMachineState 
> *mms)
>  
>  mms->virtio_irq_base = 5;
>  mms->virtio_num_transports = 8;
> -if (x86_machine_is_acpi_enabled(x86ms)) {
> +if (ioapic2) {
> +mms->pcie_irq_base = 16;
> +mms->virtio_irq_base = 24;
> +mms->virtio_num_transports = 24;
> +} else if (x86_machine_is_acpi_enabled(x86ms)) {
>  mms->pcie_irq_base = 12;
>  mms->virtio_irq_base = 16;
>  }




Re: [PATCH v5 00/12] Exposing backing-chain allocation over NBD

2020-10-23 Thread Eric Blake
On 10/23/20 1:36 PM, Eric Blake wrote:
> v4 was here:
> https://lists.gnu.org/archive/html/qemu-devel/2020-10/msg02708.html
> 
> Since then:
> - rebase to master
> - patches 1, 2, and 12 are new based on Vladimir's observation of 
> QAPI_LIST_ADD
> - patches 10-11 are new based on prior discussion on exposing actual
> depth in addition to a tri-state encoding
> - patch 3 has a nasty bug fixed that was causing iotest failures
> - patch 6 updated to take advantage of patch 2
> - other minor tweaks based on review comments
> 
> 001/12:[down] 'qapi: Move GenericList to qapi/util.h'
> 002/12:[down] 'qapi: Make QAPI_LIST_ADD() public'
> 003/12:[0002] [FC] 'nbd: Utilize QAPI_CLONE for type conversion'
> 004/12:[0010] [FC] 'nbd: Add new qemu:allocation-depth metadata context'
> 005/12:[] [--] 'nbd: Add 'qemu-nbd -A' to expose allocation depth'
> 006/12:[0014] [FC] 'nbd: Update qapi to support exporting multiple bitmaps'
> 007/12:[] [--] 'nbd: Simplify qemu bitmap context name'
> 008/12:[] [--] 'nbd: Refactor counting of metadata contexts'
> 009/12:[0017] [FC] 'nbd: Allow export of multiple bitmaps for one device'
> 010/12:[down] 'block: Return depth level during bdrv_is_allocated_above'
> 011/12:[down] 'nbd: Expose actual depth in qemu:allocation-depth'
> 012/12:[down] 'qapi: Use QAPI_LIST_ADD() where possible'

and I meant to add:

Also available at:
https://repo.or.cz/qemu/ericb.git/shortlog/refs/tags/nbd-alloc-depth-v5

patch 12 is the largest; it may be worth splitting that by maintainer,
or even pushing it off post-5.2.  Logically, it can go in anywhere after
patch 2, but by putting it last, I'm hoping to send a pull request for
soft freeze next week for patches 1-11 for sure, and only include 12 if
we get enough positive review in time.  I did not try to see if
Coccinelle could make the work done in patch 12 more automatable.

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




Re: [PATCH] CHANGELOG: remove disused file

2020-10-23 Thread Thomas Huth
On 23/10/2020 18.34, John Snow wrote:
> On 10/23/20 1:43 AM, Thomas Huth wrote:
>> On 22/10/2020 18.28, John Snow wrote:
>>> There's no reason to keep this here; the versions described are
>>> ancient. Everything here is still mirrored on
>>> https://wiki.qemu.org/ChangeLog/old if anyone is curious; otherwise, use
>>> the git history.
>>>
>>> Signed-off-by: John Snow 
>>> ---
>>>   Changelog | 580 --
>>>   1 file changed, 580 deletions(-)
>>>   delete mode 100644 Changelog
>>>
>>> diff --git a/Changelog b/Changelog
>>> deleted file mode 100644
>>> index f7e178ccc01..000
>>> --- a/Changelog
>>> +++ /dev/null
>>> @@ -1,580 +0,0 @@
>>> -This file documents changes for QEMU releases 0.12 and earlier.
>>> -For changelog information for later releases, see
>>> -https://wiki.qemu.org/ChangeLog or look at the git history for
>>> -more detailed information.
>>
>> I agree with removing the old log. But should we maybe leave a pointer to
>> https://wiki.qemu.org/ChangeLog / the git history here to let people know
>> how to see the changelogs?
>>
>>   Thomas
>>
> 
> Maybe in README.rst, just below "Bug Reporting" and above "Contact" ?
> 
> 
> Changelog
> =
> 
> For version history and release notes, please visit
> ``_ or look at the git history for more
> detailed information.

Ok, but IIRC the "ChangeLog" file is a standard file in GNU coding
conventions, so it might be worth to keep the information in this file ...
of course we are not bound to the GNU conventions in QEMU, but users still
might expect to find the information in here...

 Thomas




[PATCH v5 12/12] qapi: Use QAPI_LIST_ADD() where possible

2020-10-23 Thread Eric Blake
Anywhere we create a list of just one item or by prepending items
(typically because order doesn't matter), we can use the now-public
macro.  But places where we must keep the list in order by appending
remain open-coded.

Signed-off-by: Eric Blake 
---
 docs/devel/writing-qmp-commands.txt | 13 +++--
 hw/net/rocker/rocker_fp.h   |  2 +-
 block/gluster.c | 19 +
 chardev/char.c  | 21 +++
 hw/core/machine.c   |  6 +
 hw/net/rocker/rocker.c  |  8 +++---
 hw/net/rocker/rocker_fp.c   | 14 +-
 hw/net/virtio-net.c | 21 +--
 migration/migration.c   |  7 ++---
 migration/postcopy-ram.c|  7 ++---
 monitor/hmp-cmds.c  | 11 
 qemu-img.c  |  5 ++--
 qga/commands-posix.c| 13 +++--
 qga/commands-win32.c| 17 +++-
 qga/commands.c  |  6 +
 qom/qom-qmp-cmds.c  | 29 ++--
 target/arm/helper.c |  6 +
 target/arm/monitor.c| 13 ++---
 target/i386/cpu.c   |  6 +
 target/mips/helper.c|  6 +
 target/s390x/cpu_models.c   | 12 ++---
 tests/test-clone-visitor.c  |  7 ++---
 tests/test-qobject-output-visitor.c | 42 ++---
 tests/test-visitor-serialization.c  |  5 +---
 trace/qmp.c | 22 +++
 ui/vnc.c| 21 +--
 util/qemu-config.c  | 14 +++---
 target/ppc/translate_init.c.inc | 12 ++---
 28 files changed, 119 insertions(+), 246 deletions(-)

diff --git a/docs/devel/writing-qmp-commands.txt 
b/docs/devel/writing-qmp-commands.txt
index 46a6c48683f5..3e11eeaa1893 100644
--- a/docs/devel/writing-qmp-commands.txt
+++ b/docs/devel/writing-qmp-commands.txt
@@ -531,15 +531,10 @@ TimerAlarmMethodList *qmp_query_alarm_methods(Error 
**errp)
 bool current = true;

 for (p = alarm_timers; p->name; p++) {
-TimerAlarmMethodList *info = g_malloc0(sizeof(*info));
-info->value = g_malloc0(sizeof(*info->value));
-info->value->method_name = g_strdup(p->name);
-info->value->current = current;
-
-current = false;
-
-info->next = method_list;
-method_list = info;
+   TimerAlarmMethod *value = g_new0(TimerAlarmMethod, 1);
+value->method_name = g_strdup(p->name);
+value->current = current;
+QAPI_LIST_ADD(method_list, value);
 }

 return method_list;
diff --git a/hw/net/rocker/rocker_fp.h b/hw/net/rocker/rocker_fp.h
index dbe1dd329a4b..4cb0bb9ccf81 100644
--- a/hw/net/rocker/rocker_fp.h
+++ b/hw/net/rocker/rocker_fp.h
@@ -28,7 +28,7 @@ int fp_port_eg(FpPort *port, const struct iovec *iov, int 
iovcnt);

 char *fp_port_get_name(FpPort *port);
 bool fp_port_get_link_up(FpPort *port);
-void fp_port_get_info(FpPort *port, RockerPortList *info);
+void fp_port_get_info(FpPort *port, RockerPort *info);
 void fp_port_get_macaddr(FpPort *port, MACAddr *macaddr);
 void fp_port_set_macaddr(FpPort *port, MACAddr *macaddr);
 uint8_t fp_port_get_learning(FpPort *port);
diff --git a/block/gluster.c b/block/gluster.c
index 4f1448e2bc88..cf446c23f85d 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -359,8 +359,8 @@ static int qemu_gluster_parse_uri(BlockdevOptionsGluster 
*gconf,
 return -EINVAL;
 }

-gconf->server = g_new0(SocketAddressList, 1);
-gconf->server->value = gsconf = g_new0(SocketAddress, 1);
+gsconf = g_new0(SocketAddress, 1);
+QAPI_LIST_ADD(gconf->server, gsconf);

 /* transport */
 if (!uri->scheme || !strcmp(uri->scheme, "gluster")) {
@@ -514,7 +514,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 {
 QemuOpts *opts;
 SocketAddress *gsconf = NULL;
-SocketAddressList *curr = NULL;
+SocketAddressList **curr;
 QDict *backing_options = NULL;
 Error *local_err = NULL;
 char *str = NULL;
@@ -547,6 +547,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 }
 gconf->path = g_strdup(ptr);
 qemu_opts_del(opts);
+curr = >server;

 for (i = 0; i < num_servers; i++) {
 str = g_strdup_printf(GLUSTER_OPT_SERVER_PATTERN"%d.", i);
@@ -655,15 +656,9 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster 
*gconf,
 qemu_opts_del(opts);
 }

-if (gconf->server == NULL) {
-gconf->server = g_new0(SocketAddressList, 1);
-gconf->server->value = gsconf;
-curr = gconf->server;
-} else {
-curr->next = g_new0(SocketAddressList, 1);
-curr->next->value = gsconf;
-curr = curr->next;
-}
+*curr = g_new0(SocketAddressList, 1);
+(*curr)->value = gsconf;
+curr = &(*curr)->next;
   

Re: [PATCH 0/7] microvm: fix PCIe IRQs in APIC table.

2020-10-23 Thread Igor Mammedov
On Fri, 16 Oct 2020 13:38:28 +0200
Gerd Hoffmann  wrote:

> Gerd Hoffmann (7):
>   tests/acpi: allow changes for microvm/APIC.pcie
>   tests/acpi: add empty microvm/APIC.pcie
>   x86: make pci irqs runtime configurable
>   microvm: set pci_irq_mask
>   apci: drop has_pci arg for acpi_build_madt
>   tests/acpi: update expected data files
>   tests/acpi: disallow changes for microvm/APIC.pcie
> 
>  hw/i386/acpi-common.h |   3 +--
>  include/hw/i386/x86.h |   2 ++
>  hw/i386/acpi-build.c  |   2 +-
>  hw/i386/acpi-common.c |  26 +++---
>  hw/i386/acpi-microvm.c|   2 +-
>  hw/i386/microvm.c |   6 ++
>  hw/i386/x86.c |   1 +
>  tests/data/acpi/microvm/APIC.pcie | Bin 0 -> 110 bytes
>  8 files changed, 23 insertions(+), 19 deletions(-)
>  create mode 100644 tests/data/acpi/microvm/APIC.pcie
> 

for series:

Reviewed-by: Igor Mammedov 




[PATCH v5 11/12] nbd: Expose actual depth in qemu:allocation-depth

2020-10-23 Thread Eric Blake
Preserve the tri-state encoding in the low bits, as that still remains
a valuable way to utilize qemu-img map with x-dirty-bitmap for
accessing quick information without needing a third-party NBD client.
But now that the block layer gives us an actual depth, we can easily
expose it in the remaining bits of our metadata context (leaving two
bits reserved, to make it easier to read depth out of a raw hex
number).  This assumes no one runs a backing chain larger than 256M
elements.

iotest 309 remains unchanged (an example of the above-mentioned
x-dirty-bitmap hack); actually testing the new bits requires libnbd or
a similar client, and I didn't want to make iotests depend on libnbd
at this point in time; rather, see the libnbd project for interop
tests that exercise this new feature.

Signed-off-by: Eric Blake 
---
 docs/interop/nbd.txt |  6 +-
 include/block/nbd.h  |  2 ++
 nbd/server.c | 27 +++
 3 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/docs/interop/nbd.txt b/docs/interop/nbd.txt
index 7e948bd42218..d90723ffe991 100644
--- a/docs/interop/nbd.txt
+++ b/docs/interop/nbd.txt
@@ -34,7 +34,8 @@ the image, with a single metadata context named:

 qemu:allocation-depth

-In the allocation depth context, bits 0 and 1 form a tri-state value:
+In the allocation depth context, bits 0 and 1 form a tri-state value,
+along with 28 bits giving an actual depth:

 bits 0-1: 00: NBD_STATE_DEPTH_UNALLOC, the extent is unallocated
   01: NBD_STATE_DEPTH_LOCAL, the extent is allocated in the
@@ -42,6 +43,9 @@ In the allocation depth context, bits 0 and 1 form a 
tri-state value:
   10: NBD_STATE_DEPTH_BACKING, the extent is inherited from a
   backing layer
   11: invalid, never returned
+bits 2-3: reserved, always 0
+bits 4-31: NBD_STATE_DEPTH_RAW, the backing layer depth (0 if
+   UNALLOC, 1 for LOCAL, 2 or more for BACKING)

 For NBD_OPT_LIST_META_CONTEXT the following queries are supported
 in addition to the specific "qemu:allocation-depth" and
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 956687f5c368..3c0692aec642 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -264,6 +264,8 @@ enum {
 #define NBD_STATE_DEPTH_UNALLOC  0x0
 #define NBD_STATE_DEPTH_LOCAL0x1
 #define NBD_STATE_DEPTH_BACKING  0x2
+#define NBD_STATE_DEPTH_RAW_MASK 0xfff0
+#define NBD_STATE_DEPTH_RAW_SHIFT4

 static inline bool nbd_reply_type_is_error(int type)
 {
diff --git a/nbd/server.c b/nbd/server.c
index 53526090b0a2..afa79e63a7a6 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -2037,22 +2037,25 @@ static int blockalloc_to_extents(BlockDriverState *bs, 
uint64_t offset,
 while (bytes) {
 uint32_t flags;
 int64_t num;
-int ret = bdrv_is_allocated(bs, offset, bytes, );
+int depth = bdrv_is_allocated_above(bs, NULL, false, offset, bytes,
+);

-if (ret < 0) {
-return ret;
-}
-
-if (ret == 1) {
+switch (depth) {
+case 0:
+flags = NBD_STATE_DEPTH_UNALLOC;
+break;
+case 1:
 flags = NBD_STATE_DEPTH_LOCAL;
-} else {
-ret = bdrv_is_allocated_above(bs, NULL, false, offset, num,
-  );
-if (ret < 0) {
-return ret;
+break;
+default:
+if (depth < 0) {
+return depth;
 }
-flags = ret ? NBD_STATE_DEPTH_BACKING : NBD_STATE_DEPTH_UNALLOC;
+flags = NBD_STATE_DEPTH_BACKING;
+break;
 }
+assert(depth <= UINT32_MAX >> NBD_STATE_DEPTH_RAW_SHIFT);
+flags |= depth << NBD_STATE_DEPTH_RAW_SHIFT;

 if (nbd_extent_array_add(ea, num, flags) < 0) {
 return 0;
-- 
2.29.0




[PATCH v5 10/12] block: Return depth level during bdrv_is_allocated_above

2020-10-23 Thread Eric Blake
When checking for allocation across a chain, it's already easy to
count the depth within the chain at which the allocation is found.
Instead of throwing that information away, return it to the caller.
Existing callers only cared about allocated/non-allocated, but having
a depth available will be used by NBD in the next patch.

Note that the previous code (since commit 188a7bbf94 in 2012) was
lazy: for each layer deeper in the backing chain, it was issuing a
bdrv_is_allocated request on the original 'bytes' amount, rather than
on any smaller amount 'n' learned from an upper layer.  These
semantics happened to work, since if you have:

Base <- Active
XX---XX-

the consecutive results are offset 0: '11' with *pnum 2, followed by
offset 2: '1' with *pnum 1, followed by offset 3: '0' with *pnum 1;
the resulting sequence 1110 matches reality (the first three clusters
are indeed allocated somewhere in the given range).  But post-patch,
we correctly give the results offset 0: '2' with *pnum 1, followed by
offset 1: '11' with *pnum 2, followed by offset 3: '0' with *pnum 1
(2110), without over-reporting the length of contributions from the
backing layers.

Signed-off-by: Eric Blake 
---
 block/io.c | 11 +++
 block/commit.c |  2 +-
 block/mirror.c |  2 +-
 block/stream.c |  2 +-
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/block/io.c b/block/io.c
index 54f0968aee27..4a4fa1c9ab1b 100644
--- a/block/io.c
+++ b/block/io.c
@@ -2414,8 +2414,9 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, 
int64_t offset,
 /*
  * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP]
  *
- * Return 1 if (a prefix of) the given range is allocated in any image
- * between BASE and TOP (BASE is only included if include_base is set).
+ * Return a positive depth if (a prefix of) the given range is allocated
+ * in any image between BASE and TOP (BASE is only included if include_base
+ * is set).  Depth 1 is TOP, 2 is the first backing layer, and so forth.
  * BASE can be NULL to check if the given offset is allocated in any
  * image of the chain.  Return 0 otherwise, or negative errno on
  * failure.
@@ -2435,6 +2436,7 @@ int bdrv_is_allocated_above(BlockDriverState *top,
 {
 BlockDriverState *intermediate;
 int ret;
+int depth = 0;
 int64_t n = bytes;

 assert(base || !include_base);
@@ -2444,14 +2446,15 @@ int bdrv_is_allocated_above(BlockDriverState *top,
 int64_t pnum_inter;
 int64_t size_inter;

+depth++;
 assert(intermediate);
-ret = bdrv_is_allocated(intermediate, offset, bytes, _inter);
+ret = bdrv_is_allocated(intermediate, offset, n, _inter);
 if (ret < 0) {
 return ret;
 }
 if (ret) {
 *pnum = pnum_inter;
-return 1;
+return depth;
 }

 size_inter = bdrv_getlength(intermediate);
diff --git a/block/commit.c b/block/commit.c
index 1e85c306cc41..71db7ba7472e 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -156,7 +156,7 @@ static int coroutine_fn commit_run(Job *job, Error **errp)
 /* Copy if allocated above the base */
 ret = bdrv_is_allocated_above(blk_bs(s->top), s->base_overlay, true,
   offset, COMMIT_BUFFER_SIZE, );
-copy = (ret == 1);
+copy = (ret > 0);
 trace_commit_one_iteration(s, offset, n, ret);
 if (copy) {
 assert(n < SIZE_MAX);
diff --git a/block/mirror.c b/block/mirror.c
index 26acf4af6fb7..8e1ad6eceb57 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -846,7 +846,7 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
 }

 assert(count);
-if (ret == 1) {
+if (ret > 0) {
 bdrv_set_dirty_bitmap(s->dirty_bitmap, offset, count);
 }
 offset += count;
diff --git a/block/stream.c b/block/stream.c
index 8ce6729a33da..236384f2f739 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -167,7 +167,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 n = len - offset;
 }

-copy = (ret == 1);
+copy = (ret > 0);
 }
 trace_stream_one_iteration(s, offset, n, ret);
 if (copy) {
-- 
2.29.0




[PATCH v5 09/12] nbd: Allow export of multiple bitmaps for one device

2020-10-23 Thread Eric Blake
With this, 'qemu-nbd -B b0 -B b1 -f qcow2 img.qcow2' can let you sniff
out multiple bitmaps from one server.  qemu-img as client can still
only read one bitmap per client connection, but other NBD clients
(hello libnbd) can now read multiple bitmaps in a single pass.

Signed-off-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 nbd/server.c   | 100 -
 tests/qemu-iotests/291 |   6 +--
 2 files changed, 72 insertions(+), 34 deletions(-)

diff --git a/nbd/server.c b/nbd/server.c
index 27d943529409..53526090b0a2 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -28,6 +28,7 @@

 #define NBD_META_ID_BASE_ALLOCATION 0
 #define NBD_META_ID_ALLOCATION_DEPTH 1
+/* Dirty bitmaps use 'NBD_META_ID_DIRTY_BITMAP + i', so keep this id last. */
 #define NBD_META_ID_DIRTY_BITMAP 2

 /*
@@ -96,7 +97,8 @@ struct NBDExport {
 Notifier eject_notifier;

 bool allocation_depth;
-BdrvDirtyBitmap *export_bitmap;
+BdrvDirtyBitmap **export_bitmaps;
+size_t nr_export_bitmaps;
 };

 static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
@@ -109,7 +111,10 @@ typedef struct NBDExportMetaContexts {
 size_t count; /* number of negotiated contexts */
 bool base_allocation; /* export base:allocation context (block status) */
 bool allocation_depth; /* export qemu:allocation-depth */
-bool bitmap; /* export qemu:dirty-bitmap: */
+bool *bitmaps; /*
+* export qemu:dirty-bitmap:,
+* sized by exp->nr_export_bitmaps
+*/
 } NBDExportMetaContexts;

 struct NBDClient {
@@ -861,6 +866,8 @@ static bool nbd_meta_base_query(NBDClient *client, 
NBDExportMetaContexts *meta,
 static bool nbd_meta_qemu_query(NBDClient *client, NBDExportMetaContexts *meta,
 const char *query)
 {
+size_t i;
+
 if (!nbd_strshift(, "qemu:")) {
 return false;
 }
@@ -869,7 +876,7 @@ static bool nbd_meta_qemu_query(NBDClient *client, 
NBDExportMetaContexts *meta,
 if (!*query) {
 if (client->opt == NBD_OPT_LIST_META_CONTEXT) {
 meta->allocation_depth = meta->exp->allocation_depth;
-meta->bitmap = !!meta->exp->export_bitmap;
+memset(meta->bitmaps, 1, meta->exp->nr_export_bitmaps);
 }
 trace_nbd_negotiate_meta_query_parse("empty");
 return true;
@@ -882,17 +889,26 @@ static bool nbd_meta_qemu_query(NBDClient *client, 
NBDExportMetaContexts *meta,
 }

 if (nbd_strshift(, "dirty-bitmap:")) {
-const char *bm_name;
-
 trace_nbd_negotiate_meta_query_parse("dirty-bitmap:");
-if (!meta->exp->export_bitmap) {
-trace_nbd_negotiate_meta_query_skip("no dirty-bitmap exported");
+if (!*query) {
+if (client->opt == NBD_OPT_LIST_META_CONTEXT) {
+memset(meta->bitmaps, 1, meta->exp->nr_export_bitmaps);
+}
+trace_nbd_negotiate_meta_query_parse("empty");
 return true;
 }
-bm_name = bdrv_dirty_bitmap_name(meta->exp->export_bitmap);
-if (nbd_meta_empty_or_pattern(client, bm_name, query)) {
-meta->bitmap = true;
+
+for (i = 0; i < meta->exp->nr_export_bitmaps; i++) {
+const char *bm_name;
+
+bm_name = bdrv_dirty_bitmap_name(meta->exp->export_bitmaps[i]);
+if (strcmp(bm_name, query) == 0) {
+meta->bitmaps[i] = true;
+trace_nbd_negotiate_meta_query_parse(query);
+return true;
+}
 }
+trace_nbd_negotiate_meta_query_skip("no dirty-bitmap match");
 return true;
 }

@@ -954,9 +970,10 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
 {
 int ret;
 g_autofree char *export_name = NULL;
-NBDExportMetaContexts local_meta;
+g_autofree bool *bitmaps = NULL;
+NBDExportMetaContexts local_meta = {0};
 uint32_t nb_queries;
-int i;
+size_t i;
 size_t count = 0;

 if (!client->structured_reply) {
@@ -971,6 +988,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
 meta = _meta;
 }

+g_free(meta->bitmaps);
 memset(meta, 0, sizeof(*meta));

 ret = nbd_opt_read_name(client, _name, NULL, errp);
@@ -985,6 +1003,10 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
 return nbd_opt_drop(client, NBD_REP_ERR_UNKNOWN, errp,
 "export '%s' not present", sane_name);
 }
+meta->bitmaps = g_new0(bool, meta->exp->nr_export_bitmaps);
+if (client->opt == NBD_OPT_LIST_META_CONTEXT) {
+bitmaps = meta->bitmaps;
+}

 ret = nbd_opt_read(client, _queries, sizeof(nb_queries), false, errp);
 if (ret <= 0) {
@@ -998,7 +1020,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
 /* enable all known contexts */
 meta->base_allocation = true;
 meta->allocation_depth = 

[PATCH v5 07/12] nbd: Simplify qemu bitmap context name

2020-10-23 Thread Eric Blake
Each dirty bitmap already knows its name; by reducing the scope of the
places where we construct "qemu:dirty-bitmap:NAME" strings, tracking
the name is more localized, and there are fewer per-export fields to
worry about.  This in turn will make it easier for an upcoming patch
to export more than one bitmap at once.

Signed-off-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 nbd/server.c | 19 +--
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/nbd/server.c b/nbd/server.c
index 884ffa00f1bd..05a8154975a1 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -97,7 +97,6 @@ struct NBDExport {

 bool allocation_depth;
 BdrvDirtyBitmap *export_bitmap;
-char *export_bitmap_context;
 };

 static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
@@ -882,14 +881,15 @@ static bool nbd_meta_qemu_query(NBDClient *client, 
NBDExportMetaContexts *meta,
 }

 if (nbd_strshift(, "dirty-bitmap:")) {
+const char *bm_name;
+
 trace_nbd_negotiate_meta_query_parse("dirty-bitmap:");
 if (!meta->exp->export_bitmap) {
 trace_nbd_negotiate_meta_query_skip("no dirty-bitmap exported");
 return true;
 }
-if (nbd_meta_empty_or_pattern(client,
-  meta->exp->export_bitmap_context +
-  strlen("qemu:dirty-bitmap:"), query)) {
+bm_name = bdrv_dirty_bitmap_name(meta->exp->export_bitmap);
+if (nbd_meta_empty_or_pattern(client, bm_name, query)) {
 meta->bitmap = true;
 }
 return true;
@@ -1025,8 +1025,11 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
 }

 if (meta->bitmap) {
-ret = nbd_negotiate_send_meta_context(client,
-  meta->exp->export_bitmap_context,
+const char *bm_name = bdrv_dirty_bitmap_name(meta->exp->export_bitmap);
+g_autofree char *context = g_strdup_printf("qemu:dirty-bitmap:%s",
+   bm_name);
+
+ret = nbd_negotiate_send_meta_context(client, context,
   NBD_META_ID_DIRTY_BITMAP,
   errp);
 if (ret < 0) {
@@ -1599,9 +1602,6 @@ static int nbd_export_create(BlockExport *blk_exp, 
BlockExportOptions *exp_args,
 bdrv_dirty_bitmap_set_busy(bm, true);
 exp->export_bitmap = bm;
 assert(strlen(bitmap) <= BDRV_BITMAP_MAX_NAME_SIZE);
-exp->export_bitmap_context = g_strdup_printf("qemu:dirty-bitmap:%s",
- bitmap);
-assert(strlen(exp->export_bitmap_context) < NBD_MAX_STRING_SIZE);
 }

 exp->allocation_depth = arg->allocation_depth;
@@ -1681,7 +1681,6 @@ static void nbd_export_delete(BlockExport *blk_exp)

 if (exp->export_bitmap) {
 bdrv_dirty_bitmap_set_busy(exp->export_bitmap, false);
-g_free(exp->export_bitmap_context);
 }
 }

-- 
2.29.0




[PATCH v5 08/12] nbd: Refactor counting of metadata contexts

2020-10-23 Thread Eric Blake
Rather than open-code the count of negotiated contexts at several
sites, embed it directly into the struct.

Signed-off-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 nbd/server.c | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/nbd/server.c b/nbd/server.c
index 05a8154975a1..27d943529409 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -106,8 +106,7 @@ static QTAILQ_HEAD(, NBDExport) exports = 
QTAILQ_HEAD_INITIALIZER(exports);
  * NBD_OPT_LIST_META_CONTEXT. */
 typedef struct NBDExportMetaContexts {
 NBDExport *exp;
-bool valid; /* means that negotiation of the option finished without
-   errors */
+size_t count; /* number of negotiated contexts */
 bool base_allocation; /* export base:allocation context (block status) */
 bool allocation_depth; /* export qemu:allocation-depth */
 bool bitmap; /* export qemu:dirty-bitmap: */
@@ -448,7 +447,9 @@ static int nbd_negotiate_handle_list(NBDClient *client, 
Error **errp)

 static void nbd_check_meta_export(NBDClient *client)
 {
-client->export_meta.valid &= client->exp == client->export_meta.exp;
+if (client->exp != client->export_meta.exp) {
+client->export_meta.count = 0;
+}
 }

 /* Send a reply to NBD_OPT_EXPORT_NAME.
@@ -956,6 +957,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
 NBDExportMetaContexts local_meta;
 uint32_t nb_queries;
 int i;
+size_t count = 0;

 if (!client->structured_reply) {
 return nbd_opt_invalid(client, errp,
@@ -1013,6 +1015,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
 if (ret < 0) {
 return ret;
 }
+count++;
 }

 if (meta->allocation_depth) {
@@ -1022,6 +1025,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
 if (ret < 0) {
 return ret;
 }
+count++;
 }

 if (meta->bitmap) {
@@ -1035,11 +1039,12 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
 if (ret < 0) {
 return ret;
 }
+count++;
 }

 ret = nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
 if (ret == 0) {
-meta->valid = true;
+meta->count = count;
 }

 return ret;
@@ -2400,15 +2405,9 @@ static coroutine_fn int nbd_handle_request(NBDClient 
*client,
 return nbd_send_generic_reply(client, request->handle, -EINVAL,
   "need non-zero length", errp);
 }
-if (client->export_meta.valid &&
-(client->export_meta.base_allocation ||
- client->export_meta.allocation_depth ||
- client->export_meta.bitmap))
-{
+if (client->export_meta.count) {
 bool dont_fragment = request->flags & NBD_CMD_FLAG_REQ_ONE;
-int contexts_remaining = client->export_meta.base_allocation +
-client->export_meta.allocation_depth +
-client->export_meta.bitmap;
+int contexts_remaining = client->export_meta.count;

 if (client->export_meta.base_allocation) {
 ret = nbd_co_send_block_status(client, request->handle,
-- 
2.29.0




[PATCH v5 04/12] nbd: Add new qemu:allocation-depth metadata context

2020-10-23 Thread Eric Blake
'qemu-img map' provides a way to determine which extents of an image
come from the top layer vs. inherited from a backing chain.  This is
useful information worth exposing over NBD.  There is a proposal to
add a QMP command block-dirty-bitmap-populate which can create a dirty
bitmap that reflects allocation information, at which point the
qemu:dirty-bitmap:NAME metadata context can expose that information
via the creation of a temporary bitmap, but we can shorten the effort
by adding a new qemu:allocation-depth metadata context that does the
same thing without an intermediate bitmap (this patch does not
eliminate the need for that proposal, as it will have other uses as
well).

For this patch, I just encoded a tri-state value (DEPTH_CODE_MASK:
unallocated, from this layer, from any of the backing layers); an
obvious extension would be to provide the actual depth in bits 31-4 (a
new DEPTH_RAW_MASK 0xfff0) while keeping bits 1-0 as a tri-state
(leaving bits 3-2 unused, for ease of reading depth from a hex
number).  But adding this extension would require
bdrv_is_allocated_above to return a depth number.

While documenting things, remember that although the NBD protocol has
NBD_OPT_SET_META_CONTEXT, the rest of its documentation refers to
'metadata context', which is a more apt description of what is
actually being used by NBD_CMD_BLOCK_STATUS: the user is requesting
metadata by passing one or more context names.  So I also touched up
some existing wording to prefer the term 'metadata context' where it
makes sense.

Note that this patch does not actually enable any way to request a
server to enable this context; that will come in the next patch.

Signed-off-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 docs/interop/nbd.txt | 27 ++---
 include/block/nbd.h  | 12 --
 nbd/server.c | 92 
 3 files changed, 116 insertions(+), 15 deletions(-)

diff --git a/docs/interop/nbd.txt b/docs/interop/nbd.txt
index f3b3cacc9621..7e948bd42218 100644
--- a/docs/interop/nbd.txt
+++ b/docs/interop/nbd.txt
@@ -17,19 +17,35 @@ namespace "qemu".

 == "qemu" namespace ==

-The "qemu" namespace currently contains only one type of context,
-related to exposing the contents of a dirty bitmap alongside the
-associated disk contents.  That context has the following form:
+The "qemu" namespace currently contains two available metadata context
+types.  The first is related to exposing the contents of a dirty
+bitmap alongside the associated disk contents.  That metadata context
+is named with the following form:

 qemu:dirty-bitmap:

 Each dirty-bitmap metadata context defines only one flag for extents
 in reply for NBD_CMD_BLOCK_STATUS:

-bit 0: NBD_STATE_DIRTY, means that the extent is "dirty"
+bit 0: NBD_STATE_DIRTY, set when the extent is "dirty"
+
+The second is related to exposing the source of various extents within
+the image, with a single metadata context named:
+
+qemu:allocation-depth
+
+In the allocation depth context, bits 0 and 1 form a tri-state value:
+
+bits 0-1: 00: NBD_STATE_DEPTH_UNALLOC, the extent is unallocated
+  01: NBD_STATE_DEPTH_LOCAL, the extent is allocated in the
+  top layer of the image
+  10: NBD_STATE_DEPTH_BACKING, the extent is inherited from a
+  backing layer
+  11: invalid, never returned

 For NBD_OPT_LIST_META_CONTEXT the following queries are supported
-in addition to "qemu:dirty-bitmap:":
+in addition to the specific "qemu:allocation-depth" and
+"qemu:dirty-bitmap:":

 * "qemu:" - returns list of all available metadata contexts in the
 namespace.
@@ -55,3 +71,4 @@ the operation of that feature.
 NBD_CMD_BLOCK_STATUS for "qemu:dirty-bitmap:", NBD_CMD_CACHE
 * 4.2: NBD_FLAG_CAN_MULTI_CONN for shareable read-only exports,
 NBD_CMD_FLAG_FAST_ZERO
+* 5.2: NBD_CMD_BLOCK_STATUS for "qemu:allocation-depth"
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 3dd9a04546ec..956687f5c368 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2016-2019 Red Hat, Inc.
+ *  Copyright (C) 2016-2020 Red Hat, Inc.
  *  Copyright (C) 2005  Anthony Liguori 
  *
  *  Network Block Device
@@ -47,7 +47,7 @@ typedef struct NBDOptionReply NBDOptionReply;
 typedef struct NBDOptionReplyMetaContext {
 NBDOptionReply h; /* h.type = NBD_REP_META_CONTEXT, h.length > 4 */
 uint32_t context_id;
-/* meta context name follows */
+/* metadata context name follows */
 } QEMU_PACKED NBDOptionReplyMetaContext;

 /* Transmission phase structs
@@ -229,7 +229,7 @@ enum {
 #define NBD_MAX_BUFFER_SIZE (32 * 1024 * 1024)

 /*
- * Maximum size of a protocol string (export name, meta context name,
+ * Maximum size of a protocol string (export name, metadata context name,
  * etc.).  Use malloc rather than stack allocation for storage of a
  * string.
  */
@@ -259,6 +259,12 @@ enum {
 /* Extent 

[PATCH v5 05/12] nbd: Add 'qemu-nbd -A' to expose allocation depth

2020-10-23 Thread Eric Blake
Allow the server to expose an additional metacontext to be requested
by savvy clients.  qemu-nbd adds a new option -A to expose the
qemu:allocation-depth metacontext through NBD_CMD_BLOCK_STATUS; this
can also be set via QMP when using block-export-add.

qemu as client can be hacked into viewing this new context by using
the now-misnamed x-dirty-bitmap option when creating an NBD blockdev
(even though our x- naming means we could rename it, I did not think
it worth breaking back-compat of tools that have been using it while
waiting for a better solution).  It is worth noting the decoding of
how such context information will appear in 'qemu-img map
--output=json':

NBD_STATE_DEPTH_UNALLOC => "zero":false, "data":true
NBD_STATE_DEPTH_LOCAL   => "zero":false, "data":false
NBD_STATE_DEPTH_BACKING => "zero":true,  "data":true

libnbd as client is probably a nicer way to get at the information
without having to decipher such hacks in qemu as client. ;)

Signed-off-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 docs/tools/qemu-nbd.rst|  8 -
 qapi/block-core.json   |  7 ++--
 qapi/block-export.json | 12 +--
 nbd/server.c   |  2 ++
 qemu-nbd.c | 26 +-
 tests/qemu-iotests/309 | 73 ++
 tests/qemu-iotests/309.out | 22 
 tests/qemu-iotests/group   |  1 +
 8 files changed, 136 insertions(+), 15 deletions(-)
 create mode 100755 tests/qemu-iotests/309
 create mode 100644 tests/qemu-iotests/309.out

diff --git a/docs/tools/qemu-nbd.rst b/docs/tools/qemu-nbd.rst
index 667861cb22e9..fe41336dc550 100644
--- a/docs/tools/qemu-nbd.rst
+++ b/docs/tools/qemu-nbd.rst
@@ -72,10 +72,16 @@ driver options if ``--image-opts`` is specified.

   Export the disk as read-only.

+.. option:: -A, --allocation-depth
+
+  Expose allocation depth information via the
+  ``qemu:allocation-depth`` metadata context accessible through
+  NBD_OPT_SET_META_CONTEXT.
+
 .. option:: -B, --bitmap=NAME

   If *filename* has a qcow2 persistent bitmap *NAME*, expose
-  that bitmap via the ``qemu:dirty-bitmap:NAME`` context
+  that bitmap via the ``qemu:dirty-bitmap:NAME`` metadata context
   accessible through NBD_OPT_SET_META_CONTEXT.

 .. option:: -s, --snapshot
diff --git a/qapi/block-core.json b/qapi/block-core.json
index ee5ebef7f2ce..b6368f5fd9a1 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3883,9 +3883,12 @@
 #
 # @tls-creds: TLS credentials ID
 #
-# @x-dirty-bitmap: A "qemu:dirty-bitmap:NAME" string to query in place of
+# @x-dirty-bitmap: A metadata context name such as "qemu:dirty-bitmap:NAME"
+#  or "qemu:allocation-depth" to query in place of the
 #  traditional "base:allocation" block status (see
-#  NBD_OPT_LIST_META_CONTEXT in the NBD protocol) (since 3.0)
+#  NBD_OPT_LIST_META_CONTEXT in the NBD protocol; and
+#  yes, naming this option x-context would have made
+#  more sense) (since 3.0)
 #
 # @reconnect-delay: On an unexpected disconnect, the nbd client tries to
 #   connect again until succeeding or encountering a serious
diff --git a/qapi/block-export.json b/qapi/block-export.json
index 65804834d905..893d5cde5dfe 100644
--- a/qapi/block-export.json
+++ b/qapi/block-export.json
@@ -75,14 +75,20 @@
 #   (Since 5.0)
 #
 # @bitmap: Also export the dirty bitmap reachable from @device, so the
-#  NBD client can use NBD_OPT_SET_META_CONTEXT with
-#  "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0)
+#  NBD client can use NBD_OPT_SET_META_CONTEXT with the
+#  metadata context name "qemu:dirty-bitmap:NAME" to inspect the
+#  bitmap. (since 4.0)
+#
+# @allocation-depth: Also export the allocation depth map for @device, so
+#the NBD client can use NBD_OPT_SET_META_CONTEXT with
+#the metadata context name "qemu:allocation-depth" to
+#inspect allocation details. (since 5.2)
 #
 # Since: 5.0
 ##
 { 'struct': 'BlockExportOptionsNbd',
   'data': { '*name': 'str', '*description': 'str',
-'*bitmap': 'str' } }
+'*bitmap': 'str', '*allocation-depth': 'bool' } }

 ##
 # @NbdServerAddOptions:
diff --git a/nbd/server.c b/nbd/server.c
index ae6f8a8e5429..30cfe0eee467 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1597,6 +1597,8 @@ static int nbd_export_create(BlockExport *blk_exp, 
BlockExportOptions *exp_args,
 assert(strlen(exp->export_bitmap_context) < NBD_MAX_STRING_SIZE);
 }

+exp->allocation_depth = arg->allocation_depth;
+
 blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp);

 QTAILQ_INSERT_TAIL(, exp, next);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index bc644a0670b6..847fde435a7f 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -99,6 +99,7 @@ static void usage(const char *name)
 "\n"
 "Exposing part of the 

[PATCH v5 03/12] nbd: Utilize QAPI_CLONE for type conversion

2020-10-23 Thread Eric Blake
Rather than open-coding the translation from the deprecated
NbdServerAddOptions type to the preferred BlockExportOptionsNbd, it's
better to utilize QAPI_CLONE_MEMBERS.  This solves a couple of issues:
first, if we do any more refactoring of the base type (which an
upcoming patch plans to do), we don't have to revisit the open-coding.
Second, our assignment to arg->name is fishy: the generated QAPI code
currently does not visit it if arg->has_name is false, but if it DID
visit it, we would have introduced a double-free situation when arg is
finally freed.

Signed-off-by: Eric Blake 
---
 blockdev-nbd.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 8174023e5c47..cee9134b12eb 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -14,6 +14,8 @@
 #include "sysemu/block-backend.h"
 #include "hw/block/block.h"
 #include "qapi/error.h"
+#include "qapi/clone-visitor.h"
+#include "qapi/qapi-visit-block-export.h"
 #include "qapi/qapi-commands-block-export.h"
 #include "block/nbd.h"
 #include "io/channel-socket.h"
@@ -195,7 +197,8 @@ void qmp_nbd_server_add(NbdServerAddOptions *arg, Error 
**errp)
  * the device name as a default here for compatibility.
  */
 if (!arg->has_name) {
-arg->name = arg->device;
+arg->has_name = true;
+arg->name = g_strdup(arg->device);
 }

 export_opts = g_new(BlockExportOptions, 1);
@@ -205,15 +208,9 @@ void qmp_nbd_server_add(NbdServerAddOptions *arg, Error 
**errp)
 .node_name  = g_strdup(bdrv_get_node_name(bs)),
 .has_writable   = arg->has_writable,
 .writable   = arg->writable,
-.u.nbd = {
-.has_name   = true,
-.name   = g_strdup(arg->name),
-.has_description= arg->has_description,
-.description= g_strdup(arg->description),
-.has_bitmap = arg->has_bitmap,
-.bitmap = g_strdup(arg->bitmap),
-},
 };
+QAPI_CLONE_MEMBERS(BlockExportOptionsNbd, _opts->u.nbd,
+   qapi_NbdServerAddOptions_base(arg));

 /*
  * nbd-server-add doesn't complain when a read-only device should be
-- 
2.29.0




[PATCH v5 06/12] nbd: Update qapi to support exporting multiple bitmaps

2020-10-23 Thread Eric Blake
Since 'nbd-server-add' is deprecated, and 'block-export-add' is new to
5.2, we can still tweak the interface.  Allowing 'bitmaps':['str'] is
nicer than 'bitmap':'str'.  This wires up the qapi and qemu-nbd
changes to permit passing multiple bitmaps as distinct metadata
contexts that the NBD client may request, but the actual support for
more than one will require a further patch to the server.

Signed-off-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 docs/system/deprecated.rst |  4 +++-
 qapi/block-export.json | 18 --
 blockdev-nbd.c | 13 +
 nbd/server.c   | 19 +--
 qemu-nbd.c | 10 +-
 5 files changed, 46 insertions(+), 18 deletions(-)

diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index 905628f3a0cb..d6cd027ac740 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -268,7 +268,9 @@ the 'wait' field, which is only applicable to sockets in 
server mode
 

 Use the more generic commands ``block-export-add`` and ``block-export-del``
-instead.
+instead.  As part of this deprecation, it is now preferred to export a
+list of dirty bitmaps via ``bitmaps``, rather than a single bitmap via
+``bitmap``.

 Human Monitor Protocol (HMP) commands
 -
diff --git a/qapi/block-export.json b/qapi/block-export.json
index 893d5cde5dfe..c7c749d61097 100644
--- a/qapi/block-export.json
+++ b/qapi/block-export.json
@@ -74,10 +74,10 @@
 # @description: Free-form description of the export, up to 4096 bytes.
 #   (Since 5.0)
 #
-# @bitmap: Also export the dirty bitmap reachable from @device, so the
-#  NBD client can use NBD_OPT_SET_META_CONTEXT with the
-#  metadata context name "qemu:dirty-bitmap:NAME" to inspect the
-#  bitmap. (since 4.0)
+# @bitmaps: Also export each of the named dirty bitmaps reachable from
+#   @device, so the NBD client can use NBD_OPT_SET_META_CONTEXT with
+#   the metadata context name "qemu:dirty-bitmap:BITMAP" to inspect
+#   each bitmap. (since 5.2)
 #
 # @allocation-depth: Also export the allocation depth map for @device, so
 #the NBD client can use NBD_OPT_SET_META_CONTEXT with
@@ -88,7 +88,7 @@
 ##
 { 'struct': 'BlockExportOptionsNbd',
   'data': { '*name': 'str', '*description': 'str',
-'*bitmap': 'str', '*allocation-depth': 'bool' } }
+'*bitmaps': ['str'], '*allocation-depth': 'bool' } }

 ##
 # @NbdServerAddOptions:
@@ -100,12 +100,18 @@
 # @writable: Whether clients should be able to write to the device via the
 #NBD connection (default false).
 #
+# @bitmap: Also export a single dirty bitmap reachable from @device, so the
+#  NBD client can use NBD_OPT_SET_META_CONTEXT with the metadata
+#  context name "qemu:dirty-bitmap:BITMAP" to inspect the bitmap
+#  (since 4.0).  Mutually exclusive with @bitmaps, and newer
+#  clients should use that instead.
+#
 # Since: 5.0
 ##
 { 'struct': 'NbdServerAddOptions',
   'base': 'BlockExportOptionsNbd',
   'data': { 'device': 'str',
-'*writable': 'bool' } }
+'*writable': 'bool', '*bitmap': 'str' } }

 ##
 # @nbd-server-add:
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index cee9134b12eb..cfd46223bf4d 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -192,6 +192,19 @@ void qmp_nbd_server_add(NbdServerAddOptions *arg, Error 
**errp)
 return;
 }

+/*
+ * New code should use the list 'bitmaps'; but until this code is
+ * gone, we must support the older single 'bitmap'.  Use only one.
+ */
+if (arg->has_bitmap) {
+if (arg->has_bitmaps) {
+error_setg(errp, "Can't mix 'bitmap' and 'bitmaps'");
+return;
+}
+arg->has_bitmaps = true;
+QAPI_LIST_ADD(arg->bitmaps, g_strdup(arg->bitmap));
+}
+
 /*
  * block-export-add would default to the node-name, but we may have to use
  * the device name as a default here for compatibility.
diff --git a/nbd/server.c b/nbd/server.c
index 30cfe0eee467..884ffa00f1bd 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1495,6 +1495,7 @@ static int nbd_export_create(BlockExport *blk_exp, 
BlockExportOptions *exp_args,
 uint64_t perm, shared_perm;
 bool readonly = !exp_args->writable;
 bool shared = !exp_args->writable;
+strList *bitmaps;
 int ret;

 assert(exp_args->type == BLOCK_EXPORT_TYPE_NBD);
@@ -1556,12 +1557,18 @@ static int nbd_export_create(BlockExport *blk_exp, 
BlockExportOptions *exp_args,
 }
 exp->size = QEMU_ALIGN_DOWN(size, BDRV_SECTOR_SIZE);

-if (arg->bitmap) {
+/* XXX Allow more than one bitmap */
+if (arg->bitmaps && arg->bitmaps->next) {
+error_setg(errp, "multiple bitmaps per export not supported yet");
+return -EOPNOTSUPP;
+}
+for 

[PATCH v5 02/12] qapi: Make QAPI_LIST_ADD() public

2020-10-23 Thread Eric Blake
We have a useful macro for inserting at the front of any
QAPI-generated list; move it from block.c to qapi/util.h so more
places can use it, including one earlier place in block.c.

Suggested-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Eric Blake 
---
 include/qapi/util.h |  8 
 block.c | 15 +++
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/include/qapi/util.h b/include/qapi/util.h
index 50201896c7a4..b6083055ce69 100644
--- a/include/qapi/util.h
+++ b/include/qapi/util.h
@@ -30,4 +30,12 @@ int qapi_enum_parse(const QEnumLookup *lookup, const char 
*buf,

 int parse_qapi_name(const char *name, bool complete);

+/* For any GenericList @list, insert @element at the front. */
+#define QAPI_LIST_ADD(list, element) do { \
+typeof(list) _tmp = g_new(typeof(*(list)), 1); \
+_tmp->value = (element); \
+_tmp->next = (list); \
+(list) = _tmp; \
+} while (0)
+
 #endif
diff --git a/block.c b/block.c
index 430edf79bb10..45bd79299611 100644
--- a/block.c
+++ b/block.c
@@ -39,6 +39,7 @@
 #include "qapi/qmp/qstring.h"
 #include "qapi/qobject-output-visitor.h"
 #include "qapi/qapi-visit-block-core.h"
+#include "qapi/util.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/sysemu.h"
 #include "qemu/notify.h"
@@ -5211,7 +5212,7 @@ BlockDriverState *bdrv_find_node(const char *node_name)
 BlockDeviceInfoList *bdrv_named_nodes_list(bool flat,
Error **errp)
 {
-BlockDeviceInfoList *list, *entry;
+BlockDeviceInfoList *list;
 BlockDriverState *bs;

 list = NULL;
@@ -5221,22 +5222,12 @@ BlockDeviceInfoList *bdrv_named_nodes_list(bool flat,
 qapi_free_BlockDeviceInfoList(list);
 return NULL;
 }
-entry = g_malloc0(sizeof(*entry));
-entry->value = info;
-entry->next = list;
-list = entry;
+QAPI_LIST_ADD(list, info);
 }

 return list;
 }

-#define QAPI_LIST_ADD(list, element) do { \
-typeof(list) _tmp = g_new(typeof(*(list)), 1); \
-_tmp->value = (element); \
-_tmp->next = (list); \
-(list) = _tmp; \
-} while (0)
-
 typedef struct XDbgBlockGraphConstructor {
 XDbgBlockGraph *graph;
 GHashTable *graph_nodes;
-- 
2.29.0




[PATCH v5 00/12] Exposing backing-chain allocation over NBD

2020-10-23 Thread Eric Blake
v4 was here:
https://lists.gnu.org/archive/html/qemu-devel/2020-10/msg02708.html

Since then:
- rebase to master
- patches 1, 2, and 12 are new based on Vladimir's observation of QAPI_LIST_ADD
- patches 10-11 are new based on prior discussion on exposing actual
depth in addition to a tri-state encoding
- patch 3 has a nasty bug fixed that was causing iotest failures
- patch 6 updated to take advantage of patch 2
- other minor tweaks based on review comments

001/12:[down] 'qapi: Move GenericList to qapi/util.h'
002/12:[down] 'qapi: Make QAPI_LIST_ADD() public'
003/12:[0002] [FC] 'nbd: Utilize QAPI_CLONE for type conversion'
004/12:[0010] [FC] 'nbd: Add new qemu:allocation-depth metadata context'
005/12:[] [--] 'nbd: Add 'qemu-nbd -A' to expose allocation depth'
006/12:[0014] [FC] 'nbd: Update qapi to support exporting multiple bitmaps'
007/12:[] [--] 'nbd: Simplify qemu bitmap context name'
008/12:[] [--] 'nbd: Refactor counting of metadata contexts'
009/12:[0017] [FC] 'nbd: Allow export of multiple bitmaps for one device'
010/12:[down] 'block: Return depth level during bdrv_is_allocated_above'
011/12:[down] 'nbd: Expose actual depth in qemu:allocation-depth'
012/12:[down] 'qapi: Use QAPI_LIST_ADD() where possible'

Eric Blake (12):
  qapi: Move GenericList to qapi/util.h
  qapi: Make QAPI_LIST_ADD() public
  nbd: Utilize QAPI_CLONE for type conversion
  nbd: Add new qemu:allocation-depth metadata context
  nbd: Add 'qemu-nbd -A' to expose allocation depth
  nbd: Update qapi to support exporting multiple bitmaps
  nbd: Simplify qemu bitmap context name
  nbd: Refactor counting of metadata contexts
  nbd: Allow export of multiple bitmaps for one device
  block: Return depth level during bdrv_is_allocated_above
  nbd: Expose actual depth in qemu:allocation-depth
  qapi: Use QAPI_LIST_ADD() where possible

 docs/devel/writing-qmp-commands.txt |  13 +-
 docs/interop/nbd.txt|  31 +++-
 docs/system/deprecated.rst  |   4 +-
 docs/tools/qemu-nbd.rst |   8 +-
 qapi/block-core.json|   7 +-
 qapi/block-export.json  |  22 ++-
 include/qapi/visitor.h  |   9 +-
 hw/net/rocker/rocker_fp.h   |   2 +-
 include/block/nbd.h |  14 +-
 include/qapi/util.h |  16 ++
 block/io.c  |  11 +-
 block.c |  15 +-
 block/commit.c  |   2 +-
 block/gluster.c |  19 +--
 block/mirror.c  |   2 +-
 block/stream.c  |   2 +-
 blockdev-nbd.c  |  28 ++--
 chardev/char.c  |  21 ++-
 hw/core/machine.c   |   6 +-
 hw/net/rocker/rocker.c  |   8 +-
 hw/net/rocker/rocker_fp.c   |  14 +-
 hw/net/virtio-net.c |  21 +--
 migration/migration.c   |   7 +-
 migration/postcopy-ram.c|   7 +-
 monitor/hmp-cmds.c  |  11 +-
 nbd/server.c| 222 ++--
 qemu-img.c  |   5 +-
 qemu-nbd.c  |  30 ++--
 qga/commands-posix.c|  13 +-
 qga/commands-win32.c|  17 +--
 qga/commands.c  |   6 +-
 qom/qom-qmp-cmds.c  |  29 +---
 target/arm/helper.c |   6 +-
 target/arm/monitor.c|  13 +-
 target/i386/cpu.c   |   6 +-
 target/mips/helper.c|   6 +-
 target/s390x/cpu_models.c   |  12 +-
 tests/test-clone-visitor.c  |   7 +-
 tests/test-qobject-output-visitor.c |  42 +++---
 tests/test-visitor-serialization.c  |   5 +-
 trace/qmp.c |  22 ++-
 ui/vnc.c|  21 +--
 util/qemu-config.c  |  14 +-
 target/ppc/translate_init.c.inc |  12 +-
 tests/qemu-iotests/291  |   6 +-
 tests/qemu-iotests/309  |  73 +
 tests/qemu-iotests/309.out  |  22 +++
 tests/qemu-iotests/group|   1 +
 48 files changed, 529 insertions(+), 361 deletions(-)
 create mode 100755 tests/qemu-iotests/309
 create mode 100644 tests/qemu-iotests/309.out

-- 
2.29.0




Re: [PATCH 16/24] virt: Register "its" as class property

2020-10-23 Thread Igor Mammedov
On Mon, 21 Sep 2020 18:10:37 -0400
Eduardo Habkost  wrote:

> Class properties make QOM introspection simpler and easier, as
> they don't require an object to be instantiated.
> 
> Note: "its" is currently registered conditionally, but this makes
> the feature be registered unconditionally.  The only side effect
> is that it will be now possible to set its=on on virt-2.7 and
> older.
> 
> Signed-off-by: Eduardo Habkost 

Reviewed-by: Igor Mammedov 

> ---
> Cc: Peter Maydell 
> Cc: qemu-...@nongnu.org
> Cc: qemu-devel@nongnu.org
> ---
>  hw/arm/virt.c | 12 +++-
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index d1ab660fa60..986b75a6b89 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -2484,6 +2484,13 @@ static void virt_machine_class_init(ObjectClass *oc, 
> void *data)
>"Set on/off to enable/disable 
> emulating a "
>"guest CPU which implements the 
> ARM "
>"Memory Tagging Extension");
> +
> +object_class_property_add_bool(oc, "its", virt_get_its,
> +   virt_set_its);
> +object_class_property_set_description(oc, "its",
> +  "Set on/off to enable/disable "
> +  "ITS instantiation");
> +
>  }
>  
>  static void virt_instance_init(Object *obj)
> @@ -2511,11 +2518,6 @@ static void virt_instance_init(Object *obj)
>  } else {
>  /* Default allows ITS instantiation */
>  vms->its = true;
> -object_property_add_bool(obj, "its", virt_get_its,
> - virt_set_its);
> -object_property_set_description(obj, "its",
> -"Set on/off to enable/disable "
> -"ITS instantiation");
>  }
>  
>  /* Default disallows iommu instantiation */




[PATCH v5 01/12] qapi: Move GenericList to qapi/util.h

2020-10-23 Thread Eric Blake
Placing GenericList in util.h will make it easier for the next patch
to promote QAPI_LIST_ADD() into a public macro without requiring more
files to include the unrelated visitor.h.

However, we can't also move GenericAlternate; this is because it would
introduce a circular dependency: qapi-builtin-types.h needs a complete
definition of QEnumLookup (so it includes qapi/util.h), and
GenericAlternate needs a complete definition of QType (declared in
qapi-builtin-types.h).  Leaving GenericAlternate in visitor.h breaks
the cycle, and doesn't matter since we don't have any further planned
uses for that type outside of visitors.

Suggested-by: Markus Armbruster 
Signed-off-by: Eric Blake 
---
 include/qapi/visitor.h | 9 +
 include/qapi/util.h| 8 
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index ebc19ede7fff..8c2e1c29ad8b 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -16,6 +16,7 @@
 #define QAPI_VISITOR_H

 #include "qapi/qapi-builtin-types.h"
+#include "qapi/util.h"

 /*
  * The QAPI schema defines both a set of C data types, and a QMP wire
@@ -228,14 +229,6 @@

 /*** Useful types ***/

-/* This struct is layout-compatible with all other *List structs
- * created by the QAPI generator.  It is used as a typical
- * singly-linked list. */
-typedef struct GenericList {
-struct GenericList *next;
-char padding[];
-} GenericList;
-
 /* This struct is layout-compatible with all Alternate types
  * created by the QAPI generator. */
 typedef struct GenericAlternate {
diff --git a/include/qapi/util.h b/include/qapi/util.h
index a7c3c6414874..50201896c7a4 100644
--- a/include/qapi/util.h
+++ b/include/qapi/util.h
@@ -11,6 +11,14 @@
 #ifndef QAPI_UTIL_H
 #define QAPI_UTIL_H

+/* This struct is layout-compatible with all other *List structs
+ * created by the QAPI generator.  It is used as a typical
+ * singly-linked list. */
+typedef struct GenericList {
+struct GenericList *next;
+char padding[];
+} GenericList;
+
 typedef struct QEnumLookup {
 const char *const *array;
 int size;
-- 
2.29.0




Re: [PATCH 18/24] arm/cpu64: Register "aarch64" as class property

2020-10-23 Thread Igor Mammedov
On Mon, 21 Sep 2020 18:10:39 -0400
Eduardo Habkost  wrote:

> Class properties make QOM introspection simpler and easier, as
> they don't require an object to be instantiated.
> 
> Signed-off-by: Eduardo Habkost 

Reviewed-by: Igor Mammedov 

> ---
> Cc: Peter Maydell 
> Cc: qemu-...@nongnu.org
> Cc: qemu-devel@nongnu.org
> ---
>  target/arm/cpu64.c | 16 ++--
>  1 file changed, 6 insertions(+), 10 deletions(-)
> 
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 3c2b3d95993..349c9fa3a3a 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -758,15 +758,6 @@ static void aarch64_cpu_set_aarch64(Object *obj, bool 
> value, Error **errp)
>  }
>  }
>  
> -static void aarch64_cpu_initfn(Object *obj)
> -{
> -object_property_add_bool(obj, "aarch64", aarch64_cpu_get_aarch64,
> - aarch64_cpu_set_aarch64);
> -object_property_set_description(obj, "aarch64",
> -"Set on/off to enable/disable aarch64 "
> -"execution state ");
> -}
> -
>  static void aarch64_cpu_finalizefn(Object *obj)
>  {
>  }
> @@ -786,6 +777,12 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void 
> *data)
>  cc->gdb_num_core_regs = 34;
>  cc->gdb_core_xml_file = "aarch64-core.xml";
>  cc->gdb_arch_name = aarch64_gdb_arch_name;
> +
> +object_class_property_add_bool(oc, "aarch64", aarch64_cpu_get_aarch64,
> +   aarch64_cpu_set_aarch64);
> +object_class_property_set_description(oc, "aarch64",
> +  "Set on/off to enable/disable 
> aarch64 "
> +  "execution state ");
>  }
>  
>  static void aarch64_cpu_instance_init(Object *obj)
> @@ -823,7 +820,6 @@ static const TypeInfo aarch64_cpu_type_info = {
>  .name = TYPE_AARCH64_CPU,
>  .parent = TYPE_ARM_CPU,
>  .instance_size = sizeof(ARMCPU),
> -.instance_init = aarch64_cpu_initfn,
>  .instance_finalize = aarch64_cpu_finalizefn,
>  .abstract = true,
>  .class_size = sizeof(AArch64CPUClass),




Re: [PATCH 15/24] arm/virt: Register most properties as class properties

2020-10-23 Thread Igor Mammedov
On Mon, 21 Sep 2020 18:10:36 -0400
Eduardo Habkost  wrote:

> Class properties make QOM introspection simpler and easier, as
> they don't require an object to be instantiated.
> 
> Signed-off-by: Eduardo Habkost 

Reviewed-by: Igor Mammedov 

> ---
> Cc: Peter Maydell 
> Cc: qemu-...@nongnu.org
> Cc: qemu-devel@nongnu.org
> ---
>  hw/arm/virt.c | 76 +++
>  1 file changed, 41 insertions(+), 35 deletions(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index acf9bfbecea..d1ab660fa60 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -2443,6 +2443,47 @@ static void virt_machine_class_init(ObjectClass *oc, 
> void *data)
>  NULL, NULL);
>  object_class_property_set_description(oc, "acpi",
>  "Enable ACPI");
> +object_class_property_add_bool(oc, "secure", virt_get_secure,
> +   virt_set_secure);
> +object_class_property_set_description(oc, "secure",
> +"Set on/off to 
> enable/disable the ARM "
> +"Security Extensions 
> (TrustZone)");
> +
> +object_class_property_add_bool(oc, "virtualization", virt_get_virt,
> +   virt_set_virt);
> +object_class_property_set_description(oc, "virtualization",
> +  "Set on/off to enable/disable 
> emulating a "
> +  "guest CPU which implements the 
> ARM "
> +  "Virtualization Extensions");
> +
> +object_class_property_add_bool(oc, "highmem", virt_get_highmem,
> +   virt_set_highmem);
> +object_class_property_set_description(oc, "highmem",
> +  "Set on/off to enable/disable 
> using "
> +  "physical address space above 32 
> bits");
> +
> +object_class_property_add_str(oc, "gic-version", virt_get_gic_version,
> +  virt_set_gic_version);
> +object_class_property_set_description(oc, "gic-version",
> +  "Set GIC version. "
> +  "Valid values are 2, 3, host and 
> max");
> +
> +object_class_property_add_str(oc, "iommu", virt_get_iommu, 
> virt_set_iommu);
> +object_class_property_set_description(oc, "iommu",
> +  "Set the IOMMU type. "
> +  "Valid values are none and 
> smmuv3");
> +
> +object_class_property_add_bool(oc, "ras", virt_get_ras,
> +   virt_set_ras);
> +object_class_property_set_description(oc, "ras",
> +  "Set on/off to enable/disable 
> reporting host memory errors "
> +  "to a KVM guest using ACPI and 
> guest external abort exceptions");
> +
> +object_class_property_add_bool(oc, "mte", virt_get_mte, virt_set_mte);
> +object_class_property_set_description(oc, "mte",
> +  "Set on/off to enable/disable 
> emulating a "
> +  "guest CPU which implements the 
> ARM "
> +  "Memory Tagging Extension");
>  }
>  
>  static void virt_instance_init(Object *obj)
> @@ -2455,34 +2496,13 @@ static void virt_instance_init(Object *obj)
>   * boot UEFI blobs which assume no TrustZone support.
>   */
>  vms->secure = false;
> -object_property_add_bool(obj, "secure", virt_get_secure,
> - virt_set_secure);
> -object_property_set_description(obj, "secure",
> -"Set on/off to enable/disable the ARM "
> -"Security Extensions (TrustZone)");
>  
>  /* EL2 is also disabled by default, for similar reasons */
>  vms->virt = false;
> -object_property_add_bool(obj, "virtualization", virt_get_virt,
> - virt_set_virt);
> -object_property_set_description(obj, "virtualization",
> -"Set on/off to enable/disable emulating 
> a "
> -"guest CPU which implements the ARM "
> -"Virtualization Extensions");
>  
>  /* High memory is enabled by default */
>  vms->highmem = true;
> -object_property_add_bool(obj, "highmem", virt_get_highmem,
> - virt_set_highmem);
> -object_property_set_description(obj, "highmem",
> -"Set on/off to enable/disable using "
> -"physical address space above 32 bits");
>  vms->gic_version = VIRT_GIC_VERSION_NOSEL;
> -object_property_add_str(obj, "gic-version", 

Re: [PATCH v3] virtiofsd: add container-friendly -o sandbox=chroot option

2020-10-23 Thread Dr. David Alan Gilbert
* Stefan Hajnoczi (stefa...@redhat.com) wrote:
> virtiofsd cannot run in a container because CAP_SYS_ADMIN is required to
> create namespaces.
> 
> Introduce a weaker sandbox mode that is sufficient in container
> environments because the container runtime already sets up namespaces.
> Use chroot to restrict path traversal to the shared directory.
> 
> virtiofsd loses the following:
> 
> 1. Mount namespace. The process chroots to the shared directory but
>leaves the mounts in place. Seccomp rejects mount(2)/umount(2)
>syscalls.
> 
> 2. Pid namespace. This should be fine because virtiofsd is the only
>process running in the container.
> 
> 3. Network namespace. This should be fine because seccomp already
>rejects the connect(2) syscall, but an additional layer of security
>is lost. Container runtime-specific network security policies can be
>used drop network traffic (except for the vhost-user UNIX domain
>socket).
> 
> Signed-off-by: Stefan Hajnoczi 

Reviewed-by: Dr. David Alan Gilbert 

> ---
> v3:
>  * Rebased onto David Gilbert's latest migration & virtiofsd pull
>request
> 
>  tools/virtiofsd/helper.c |  8 +
>  tools/virtiofsd/passthrough_ll.c | 57 ++--
>  docs/tools/virtiofsd.rst | 32 ++
>  3 files changed, 88 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c
> index 85770d63f1..2e181a49b5 100644
> --- a/tools/virtiofsd/helper.c
> +++ b/tools/virtiofsd/helper.c
> @@ -166,6 +166,14 @@ void fuse_cmdline_help(void)
> "   enable/disable readirplus\n"
> "   default: readdirplus except with "
> "cache=none\n"
> +   "-o sandbox=namespace|chroot\n"
> +   "   sandboxing mode:\n"
> +   "   - namespace: mount, pid, and 
> net\n"
> +   " namespaces with pivot_root(2)\n"
> +   " into shared directory\n"
> +   "   - chroot: chroot(2) into shared\n"
> +   " directory (use in containers)\n"
> +   "   default: namespace\n"
> "-o timeout=I/O timeout (seconds)\n"
> "   default: depends on cache= 
> option.\n"
> "-o writeback|no_writeback  enable/disable writeback cache\n"
> diff --git a/tools/virtiofsd/passthrough_ll.c 
> b/tools/virtiofsd/passthrough_ll.c
> index ff53df4451..5b9064278a 100644
> --- a/tools/virtiofsd/passthrough_ll.c
> +++ b/tools/virtiofsd/passthrough_ll.c
> @@ -137,8 +137,14 @@ enum {
>  CACHE_ALWAYS,
>  };
>  
> +enum {
> +SANDBOX_NAMESPACE,
> +SANDBOX_CHROOT,
> +};
> +
>  struct lo_data {
>  pthread_mutex_t mutex;
> +int sandbox;
>  int debug;
>  int writeback;
>  int flock;
> @@ -163,6 +169,12 @@ struct lo_data {
>  };
>  
>  static const struct fuse_opt lo_opts[] = {
> +{ "sandbox=namespace",
> +  offsetof(struct lo_data, sandbox),
> +  SANDBOX_NAMESPACE },
> +{ "sandbox=chroot",
> +  offsetof(struct lo_data, sandbox),
> +  SANDBOX_CHROOT },
>  { "writeback", offsetof(struct lo_data, writeback), 1 },
>  { "no_writeback", offsetof(struct lo_data, writeback), 0 },
>  { "source=%s", offsetof(struct lo_data, source), 0 },
> @@ -2660,6 +2672,41 @@ static void setup_capabilities(char *modcaps_in)
>  pthread_mutex_unlock();
>  }
>  
> +/*
> + * Use chroot as a weaker sandbox for environments where the process is
> + * launched without CAP_SYS_ADMIN.
> + */
> +static void setup_chroot(struct lo_data *lo)
> +{
> +lo->proc_self_fd = open("/proc/self/fd", O_PATH);
> +if (lo->proc_self_fd == -1) {
> +fuse_log(FUSE_LOG_ERR, "open(\"/proc/self/fd\", O_PATH): %m\n");
> +exit(1);
> +}
> +
> +/*
> + * Make the shared directory the file system root so that FUSE_OPEN
> + * (lo_open()) cannot escape the shared directory by opening a symlink.
> + *
> + * The chroot(2) syscall is later disabled by seccomp and the
> + * CAP_SYS_CHROOT capability is dropped so that tampering with the chroot
> + * is not possible.
> + *
> + * However, it's still possible to escape the chroot via lo->proc_self_fd
> + * but that requires first gaining control of the process.
> + */
> +if (chroot(lo->source) != 0) {
> +fuse_log(FUSE_LOG_ERR, "chroot(\"%s\"): %m\n", lo->source);
> +exit(1);
> +}
> +
> +/* Move into the chroot */
> +if (chdir("/") != 0) {
> +fuse_log(FUSE_LOG_ERR, "chdir(\"/\"): %m\n");
> +exit(1);
> +}
> +}
> +
>  /*
>   * Lock down this process to prevent access to other processes or files 
> outside
>   * source directory.  This reduces the impact 

Re: [PATCH 11/24] tmp421: Register properties as class properties

2020-10-23 Thread Igor Mammedov
On Mon, 21 Sep 2020 18:10:32 -0400
Eduardo Habkost  wrote:

> Class properties make QOM introspection simpler and easier, as
> they don't require an object to be instantiated.
> 
> Signed-off-by: Eduardo Habkost 

Reviewed-by: Igor Mammedov 

> ---
> Cc: qemu-devel@nongnu.org
> ---
>  hw/misc/tmp421.c | 30 +-
>  1 file changed, 13 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/misc/tmp421.c b/hw/misc/tmp421.c
> index 212d6e0e831..1c19a3a9713 100644
> --- a/hw/misc/tmp421.c
> +++ b/hw/misc/tmp421.c
> @@ -340,22 +340,6 @@ static void tmp421_realize(DeviceState *dev, Error 
> **errp)
>  tmp421_reset(>i2c);
>  }
>  
> -static void tmp421_initfn(Object *obj)
> -{
> -object_property_add(obj, "temperature0", "int",
> -tmp421_get_temperature,
> -tmp421_set_temperature, NULL, NULL);
> -object_property_add(obj, "temperature1", "int",
> -tmp421_get_temperature,
> -tmp421_set_temperature, NULL, NULL);
> -object_property_add(obj, "temperature2", "int",
> -tmp421_get_temperature,
> -tmp421_set_temperature, NULL, NULL);
> -object_property_add(obj, "temperature3", "int",
> -tmp421_get_temperature,
> -tmp421_set_temperature, NULL, NULL);
> -}
> -
>  static void tmp421_class_init(ObjectClass *klass, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -368,6 +352,19 @@ static void tmp421_class_init(ObjectClass *klass, void 
> *data)
>  k->send = tmp421_tx;
>  dc->vmsd = _tmp421;
>  sc->dev = (DeviceInfo *) data;
> +
> +object_class_property_add(klass, "temperature0", "int",
> +  tmp421_get_temperature,
> +  tmp421_set_temperature, NULL, NULL);
> +object_class_property_add(klass, "temperature1", "int",
> +  tmp421_get_temperature,
> +  tmp421_set_temperature, NULL, NULL);
> +object_class_property_add(klass, "temperature2", "int",
> +  tmp421_get_temperature,
> +  tmp421_set_temperature, NULL, NULL);
> +object_class_property_add(klass, "temperature3", "int",
> +  tmp421_get_temperature,
> +  tmp421_set_temperature, NULL, NULL);
>  }
>  
>  static const TypeInfo tmp421_info = {
> @@ -375,7 +372,6 @@ static const TypeInfo tmp421_info = {
>  .parent= TYPE_I2C_SLAVE,
>  .instance_size = sizeof(TMP421State),
>  .class_size= sizeof(TMP421Class),
> -.instance_init = tmp421_initfn,
>  .abstract  = true,
>  };
>  




Re: [PATCH 08/24] vexpress-a15: Register "virtualization" as class property

2020-10-23 Thread Igor Mammedov
On Mon, 21 Sep 2020 18:10:29 -0400
Eduardo Habkost  wrote:

> Class properties make QOM introspection simpler and easier, as
> they don't require an object to be instantiated.
> 
> Signed-off-by: Eduardo Habkost 

Reviewed-by: Igor Mammedov 

> ---
> Cc: Peter Maydell 
> Cc: qemu-...@nongnu.org
> Cc: qemu-devel@nongnu.org
> ---
>  hw/arm/vexpress.c | 14 --
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
> index 0cc35749d7d..13339302af5 100644
> --- a/hw/arm/vexpress.c
> +++ b/hw/arm/vexpress.c
> @@ -769,12 +769,6 @@ static void vexpress_a15_instance_init(Object *obj)
>   * but can also be specifically set to on or off.
>   */
>  vms->virt = true;
> -object_property_add_bool(obj, "virtualization", vexpress_get_virt,
> - vexpress_set_virt);
> -object_property_set_description(obj, "virtualization",
> -"Set on/off to enable/disable the ARM "
> -"Virtualization Extensions "
> -"(defaults to same as 'secure')");
>  }
>  
>  static void vexpress_a9_instance_init(Object *obj)
> @@ -822,6 +816,14 @@ static void vexpress_a15_class_init(ObjectClass *oc, 
> void *data)
>  mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
>  
>  vmc->daughterboard = _daughterboard;
> +
> +object_class_property_add_bool(oc, "virtualization", vexpress_get_virt,
> +   vexpress_set_virt);
> +object_class_property_set_description(oc, "virtualization",
> +  "Set on/off to enable/disable the 
> ARM "
> +  "Virtualization Extensions "
> +  "(defaults to same as 'secure')");
> +
>  }
>  
>  static const TypeInfo vexpress_info = {




Re: [PATCH 05/24] vhost-user: Register "chardev" as class property

2020-10-23 Thread Igor Mammedov
On Mon, 21 Sep 2020 18:10:26 -0400
Eduardo Habkost  wrote:

> Class properties make QOM introspection simpler and easier, as
> they don't require an object to be instantiated.
> 
> Signed-off-by: Eduardo Habkost 

Reviewed-by: Igor Mammedov 

> ---
> Cc: "Michael S. Tsirkin" 
> Cc: qemu-devel@nongnu.org
> ---
>  backends/vhost-user.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/backends/vhost-user.c b/backends/vhost-user.c
> index 9e6e1985465..858fdeae26c 100644
> --- a/backends/vhost-user.c
> +++ b/backends/vhost-user.c
> @@ -175,9 +175,9 @@ static char *get_chardev(Object *obj, Error **errp)
>  return NULL;
>  }
>  
> -static void vhost_user_backend_init(Object *obj)
> +static void vhost_user_backend_class_init(ObjectClass *oc, void *data)
>  {
> -object_property_add_str(obj, "chardev", get_chardev, set_chardev);
> +object_class_property_add_str(oc, "chardev", get_chardev, set_chardev);
>  }
>  
>  static void vhost_user_backend_finalize(Object *obj)
> @@ -195,7 +195,7 @@ static const TypeInfo vhost_user_backend_info = {
>  .name = TYPE_VHOST_USER_BACKEND,
>  .parent = TYPE_OBJECT,
>  .instance_size = sizeof(VhostUserBackend),
> -.instance_init = vhost_user_backend_init,
> +.class_init = vhost_user_backend_class_init,
>  .instance_finalize = vhost_user_backend_finalize,
>  .class_size = sizeof(VhostUserBackendClass),
>  };




Re: [RFC PATCH 0/4] tests/acceptance: Test U-Boot/Linux from Armbian 20.08 on Orange Pi PC

2020-10-23 Thread Philippe Mathieu-Daudé

On 10/23/20 7:42 PM, Bin Meng wrote:

Hi Philippe,

On Fri, Oct 23, 2020 at 9:18 PM Philippe Mathieu-Daudé  wrote:


Series meant to help Bin Meng to debug the SD card issue
reported by Michael Roth.


Thank you for the patches.



Philippe Mathieu-Daudé (4):
   Revert "hw/sd: Fix incorrect populated function switch status data
 structure"
   tests/acceptance: Allow running Orange Pi test using cached artifacts
   tests/acceptance: Extract do_test_arm_orangepi_armbian_uboot() method
   tests/acceptance: Test U-Boot/Linux from Armbian 20.08 on Orange Pi PC

  hw/sd/sd.c |  3 +-
  tests/acceptance/boot_linux_console.py | 68 +++---
  2 files changed, 50 insertions(+), 21 deletions(-)


With this series, I used:

$ ARMBIAN_ARTIFACTS_CACHED=1 AVOCADO_ALLOW_LARGE_STORAGE=1 make check-acceptance

It looks that the failure still exists? Log below:

13-tests_acceptance_boot_linux_console.py_BootLinuxConsole.test_arm_orangepi_bionic_20_08/debug.log:

01:11:27 DEBUG| => boot
01:11:27 DEBUG| unable to select a mode
01:11:27 DEBUG| Device 0: unknown device
01:11:27 DEBUG| BOOTP broadcast 1
01:11:27 DEBUG| DHCP client bound to address 10.0.2.15 (1 ms)
01:11:27 DEBUG| *** Warning: no boot file name; using '0A00020F.img'
01:11:27 DEBUG| Using ethernet@1c3 device
01:11:27 DEBUG| TFTP from server 10.0.2.2; our IP address is 10.0.2.15
01:11:27 DEBUG| Filename '0A00020F.img'.
01:11:27 DEBUG| Load address: 0x4200
01:11:27 DEBUG| Loading: *^H
01:11:27 DEBUG| TFTP error: 'Access violation' (2)
01:11:27 DEBUG| Not retrying...


Have you rebuilt qemu-system-arm with the reverted patch included?



Regards,
Bin





Re: [agl-dev-community] Tips for debugging GPU acceleration.

2020-10-23 Thread Marius Vlad
On Fri, Oct 23, 2020 at 05:28:22PM +0100, Alex Bennée wrote:
> Thanks - that seems to do the trick.
> I can't find where in the agl repo that is set. The recipe seems to be in:
> 
>   
> meta-agl-cluster-demo/recipie-graphics/wayland/weston-ini-conf/virtual-landscape.cfg
> 
> but I can't see where the "transform=270" got added.
I assume from
meta-agl/meta-agl-bsp/meta-aglprofilegraphical/recipes-graphics/wayland/weston-ini-conf/virtual.cfg
> 
> Visually it looks a lot nicer now although I could still do with
> getting rid of the quite large AGL lower banner which is cropping out
> the main display.
Yes, like I've said, but apparently I've substituted landscape w/
portrait, applications are designed to accommodate portrait orientation.
The panels, are added dynamically by homescreen.
> 
> On Fri, 23 Oct 2020 at 13:32, Marius Vlad  wrote:
> >
> > On Fri, Oct 23, 2020 at 12:52:17PM +0100, Alex Bennée wrote:
> > >
> > > Gerd Hoffmann  writes:
> > >
> > > >   Hi,
> > > >
> > > >>   [2.930300] [drm] virgl 3d acceleration not supported by host
> > > >
> > > > Nope, not active.
> > > >
> > > >> -display gtk,show-cursor=on \
> > > >
> > > > Needs -display gtk,gl=on for opengl support.
> > >
> > > Awesome - even on TCG the display is now nice and snappy.
> > >
> > > For bonus points:
> > >
> > > The AGL panel display is rotated 90 degrees which is putting a bit of a
> > > crink in my neck. Is their anyway to rotate the view port. I tried
> > > inverting xres and yres but that didn't do anything.
> > Hi,
> >
> > The output is rotated, edit /etc/xdg/weston/weston.ini and comment out
> > transform ini entry from the Virtual-1 output section. Reboot, or
> > restart weston@display service. Note that the apps are optimized for
> > landscape.
> >
> > Enabling 3D with qemu might be something worth adding in the docs.
> > >
> > > >> -device virtio-gpu-pci,virgl=true
> > > >
> > > > virgl is silently turned off in case opengl support is not available.
> > > > Ideally virgl should be OnOffAuto not bool, but I fear changing that
> > > > now (and start throwing errors on virgl=on if opengl is not available)
> > > > will break stuff ...
> > >
> > > At least a warn_report maybe?
> > >
> > > >
> > > > take care,
> > > >   Gerd
> > >
> > >
> > > --
> > > Alex Bennée
> > >
> > >
> > >
> > >
> > >
> >
> >
> > 
> >
> >
> 
> 
> -- 
> Alex Bennée
> KVM/QEMU Hacker for Linaro
> 
> 
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#8773): 
> https://lists.automotivelinux.org/g/agl-dev-community/message/8773
> Mute This Topic: https://lists.automotivelinux.org/mt/77748325/4043866
> Group Owner: agl-dev-community+ow...@lists.automotivelinux.org
> Unsubscribe: 
> https://lists.automotivelinux.org/g/agl-dev-community/leave/7327001/516878461/xyzzy
>  [marius.v...@collabora.com]
> -=-=-=-=-=-=-=-=-=-=-=-
> 
> 


signature.asc
Description: PGP signature


Re: [PATCH] Makefile: separate meson rerun from the rest of the ninja invocation

2020-10-23 Thread Håvard Skinnemoen
On Fri, Oct 23, 2020 at 8:05 AM Paolo Bonzini  wrote:

> The rules to build Makefile.mtest are suffering from the "tunnel vision"
> problem that is common with recursive makefiles.  Makefile.mtest depends
> on build.ninja, but Make does not know when build.ninja needs to be
> rebuilt before creating Makefile.mtest.
>
> To fix this, separate the ninja invocation into the "regenerate build
> files" phase and the QEMU build phase.  Sentinel files such as
> meson-private/coredata.dat or build.ninja are used to figure out the
> phases that haven't run yet; however, because those files' timestamps
> are not guaranteed to be touched, the usual makefile stamp-file trick
> is used on top.
>

Thanks for the quick response. Unfortunately, it doesn't seem to work quite
right for me.

I think it should be possible to reproduce on unmodified upstream sources
like this:

$ cd bin/opt/arm
$ ../../../configure --target-list=arm-softmmu
$ make check-qtest  # Feel free to interrupt after verifying that
npcm7xx_timer-test is run
$ cd -
$ git revert 19d50149c857e50ccb1ee35dd4277f9d4954877f
Removing tests/qtest/npcm7xx_timer-test.c
[meson-test 3ce2b719aa] Revert "tests/qtest: Add npcm7xx timer test"
 2 files changed, 563 deletions(-)
 delete mode 100644 tests/qtest/npcm7xx_timer-test.c
$ cd -
$ make check-qtest

After the revert, check-qtest still runs npcm7xx_timer-test. Note that it
doesn't fail because the patch I reverted only adds a new test, it doesn't
touch the device being tested.

If you run 'make check-qtest' again, npcm7xx_timer-test does not run.
Interestingly, it looks like Makefile.mtest gets regenerated here -- I
didn't notice that happening in the first run, nor does it happen if I run
make check-qtest a third time.

I pasted the output from the last two runs of make check-qtest here:
https://gist.github.com/hskinnemoen/1773edafeb190773661076e00fdc14de

Reported-by: Havard Skinnemoen 
> Signed-off-by: Paolo Bonzini 
> ---
>  Makefile | 42 +++---
>  1 file changed, 31 insertions(+), 11 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 18f026eac3..007ad4d863 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -92,6 +92,8 @@ endif
>  ifeq ($(NINJA),)
>  .PHONY: config-host.mak
>  x := $(shell rm -rf meson-private meson-info meson-logs)
> +else
> +export NINJA
>  endif
>  ifeq ($(wildcard build.ninja),)
>  .PHONY: config-host.mak
> @@ -100,31 +102,46 @@ 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
> +   @echo config-host.mak is out-of-date, running configure
> @if test -f meson-private/coredata.dat; then \
>   ./config.status --skip-meson; \
> else \
> - ./config.status; \
> + ./config.status && touch build.ninja.stamp; \
> fi
>
> -# 2. ensure generated build files are up-to-date
> +# 2. meson.stamp exists if meson has run at least once (so ninja
> reconfigure
> +# works), but otherwise never needs to be updated
> +meson-private/coredata.dat: meson.stamp
> +meson.stamp: config-host.mak
> +   @touch meson.stamp
> +
> +# 3. ensure generated build files are up-to-date
>
> -ifneq ($(NINJA),)
>  # A separate rule is needed for Makefile dependencies to avoid -n
> -export NINJA
> +ifneq ($(MESON),)
> +build.ninja: build.ninja.stamp
> +build.ninja.stamp: meson.stamp
> +   $(NINJA) $(if $V,-v,) reconfigure && touch $@
> +endif
> +
> +ifneq ($(NINJA),)
>  Makefile.ninja: build.ninja
> -   $(quiet-@){ echo 'ninja-targets = \'; $(NINJA) -t targets all |
> sed 's/:.*//; $$!s/$$/ \\/'; } > $@
> +   $(quiet-@){ \
> + echo 'ninja-targets = \'; \
> + $(NINJA) -t targets all | sed 's/:.*//; $$!s/$$/ \\/'; \
> + echo 'build-files = \'; \
> + $(NINJA) -t query build.ninja | sed -n '1,/^  input:/d; /^
> outputs:/q; s/$$/ \\/p'; \
> +   } > $@.tmp && mv $@.tmp $@
>  -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
> +Makefile.mtest: build.ninja scripts/mtest2make.py
> $(MESON) introspect --targets --tests --benchmarks | $(PYTHON)
> scripts/mtest2make.py > $@
>  -include Makefile.mtest
>  endif
>
> -# 3. Rules to bridge to other makefiles
> +# 4. Rules to bridge to other makefiles
>
>  ifneq ($(NINJA),)
>  NINJAFLAGS = $(if $V,-v,) \
> @@ -135,7 +152,10 @@ 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))
> +# "ninja -t targets" also lists all prerequisites.  If build system
> +# files are marked as PHONY, however, Make will always try to execute
> +# "ninja reconfigure" to rebuild build.ninja.
> 

Re: [RFC PATCH 0/4] tests/acceptance: Test U-Boot/Linux from Armbian 20.08 on Orange Pi PC

2020-10-23 Thread Bin Meng
Hi Philippe,

On Fri, Oct 23, 2020 at 9:18 PM Philippe Mathieu-Daudé  wrote:
>
> Series meant to help Bin Meng to debug the SD card issue
> reported by Michael Roth.

Thank you for the patches.

>
> Philippe Mathieu-Daudé (4):
>   Revert "hw/sd: Fix incorrect populated function switch status data
> structure"
>   tests/acceptance: Allow running Orange Pi test using cached artifacts
>   tests/acceptance: Extract do_test_arm_orangepi_armbian_uboot() method
>   tests/acceptance: Test U-Boot/Linux from Armbian 20.08 on Orange Pi PC
>
>  hw/sd/sd.c |  3 +-
>  tests/acceptance/boot_linux_console.py | 68 +++---
>  2 files changed, 50 insertions(+), 21 deletions(-)

With this series, I used:

$ ARMBIAN_ARTIFACTS_CACHED=1 AVOCADO_ALLOW_LARGE_STORAGE=1 make check-acceptance

It looks that the failure still exists? Log below:

13-tests_acceptance_boot_linux_console.py_BootLinuxConsole.test_arm_orangepi_bionic_20_08/debug.log:

01:11:27 DEBUG| => boot
01:11:27 DEBUG| unable to select a mode
01:11:27 DEBUG| Device 0: unknown device
01:11:27 DEBUG| BOOTP broadcast 1
01:11:27 DEBUG| DHCP client bound to address 10.0.2.15 (1 ms)
01:11:27 DEBUG| *** Warning: no boot file name; using '0A00020F.img'
01:11:27 DEBUG| Using ethernet@1c3 device
01:11:27 DEBUG| TFTP from server 10.0.2.2; our IP address is 10.0.2.15
01:11:27 DEBUG| Filename '0A00020F.img'.
01:11:27 DEBUG| Load address: 0x4200
01:11:27 DEBUG| Loading: *^H
01:11:27 DEBUG| TFTP error: 'Access violation' (2)
01:11:27 DEBUG| Not retrying...

Regards,
Bin



Re: [PATCH v3 8/9] hw/arm/raspi: Add the Raspberry Pi Zero machine

2020-10-23 Thread Igor Mammedov
On Fri, 23 Oct 2020 19:35:19 +0200
Philippe Mathieu-Daudé  wrote:

> Hi Igor,
> 
> On 10/23/20 5:51 PM, Igor Mammedov wrote:
> > On Sun, 18 Oct 2020 22:33:57 +0200
> > Philippe Mathieu-Daudé  wrote:
> >   
> >> Similarly to the Pi A, the Pi Zero uses a BCM2835 SoC (ARMv6Z core).
> >>
> >> Example booting the machine using content from [*]:
> >>
> >>$ qemu-system-arm -M raspi0 -serial stdio \
> >>-kernel raspberrypi/firmware/boot/kernel.img \
> >>-dtb raspberrypi/firmware/boot/bcm2708-rpi-zero.dtb \
> >>-append 'printk.time=0 earlycon=pl011,0x20201000 console=ttyAMA0'
> >>[0.00] Booting Linux on physical CPU 0x0
> >>[0.00] Linux version 4.19.118+ (dom@buildbot) (gcc version 
> >> 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1311 Mon Apr 27 
> >> 14:16:15 BST 2020
> >>[0.00] CPU: ARMv6-compatible processor [410fb767] revision 7 
> >> (ARMv7), cr=00c5387d
> >>[0.00] CPU: VIPT aliasing data cache, unknown instruction cache
> >>[0.00] OF: fdt: Machine model: Raspberry Pi Zero
> >>...
> >>
> >> [*] 
> >> http://archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20200512-2_armhf.deb
> >>
> >> Reviewed-by: Luc Michel 
> >> Signed-off-by: Philippe Mathieu-Daudé 
> >> ---
> >>   hw/arm/raspi.c | 13 +
> >>   1 file changed, 13 insertions(+)
> >>
> >> diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
> >> index 91a59d1d489..1510ca01afe 100644
> >> --- a/hw/arm/raspi.c
> >> +++ b/hw/arm/raspi.c
> >> @@ -319,6 +319,15 @@ static void 
> >> raspi_machine_class_common_init(MachineClass *mc,
> >>   mc->default_ram_id = "ram";
> >>   };
> >>   
> >> +static void raspi0_machine_class_init(ObjectClass *oc, void *data)
> >> +{
> >> +MachineClass *mc = MACHINE_CLASS(oc);
> >> +RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc);
> >> +
> >> +rmc->board_rev = 0x900092;  
> > 
> > shouldn't it be
> > 920092  Zero1.2 512MB   Embest
> > or
> > 920093  Zero1.3 512MB   Embest  
> 
> I took the value from the "New-style revision codes"
> table listed in hw/arm/raspi.c before the REV_CODE
> register definitions:
> 
> https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
> 
> 90009x's manufacturer is "Sony UK", 92009x is "Embest".
> I guess we don't care much the manufacturer :)
> 
> The Revision 1.3 exposed the MIPI camera interface.
> As we don't model it, I prefer to use the 1.2 revision
> which matches better.
> 
> I'll add this information in the commit description.

With that
Reviewed-by: Igor Mammedov 

> 
> Thanks for reviewing!
> 
> >   
> >> +raspi_machine_class_common_init(mc, rmc->board_rev);
> >> +};
> >> +
> >>   static void raspi1ap_machine_class_init(ObjectClass *oc, void *data)
> >>   {
> >>   MachineClass *mc = MACHINE_CLASS(oc);
> >> @@ -352,6 +361,10 @@ static void raspi3b_machine_class_init(ObjectClass 
> >> *oc, void *data)
> >>   
> >>   static const TypeInfo raspi_machine_types[] = {
> >>   {
> >> +.name   = MACHINE_TYPE_NAME("raspi0"),
> >> +.parent = TYPE_RASPI_MACHINE,
> >> +.class_init = raspi0_machine_class_init,
> >> +}, {
> >>   .name   = MACHINE_TYPE_NAME("raspi1ap"),
> >>   .parent = TYPE_RASPI_MACHINE,
> >>   .class_init = raspi1ap_machine_class_init,  
> > 
> >   
> 




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

2020-10-23 Thread Philippe Mathieu-Daudé

On 10/23/20 5:43 PM, Igor Mammedov wrote:

On Mon, 19 Oct 2020 11:43:13 +0200
Philippe Mathieu-Daudé  wrote:

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)


FWIW:

7998beb9c2e280f0b7424223747941f106e2e854 is the first bad commit
commit 7998beb9c2e280f0b7424223747941f106e2e854
Author: Igor Mammedov 
Date:   Wed Feb 19 11:08:59 2020 -0500

      arm/nseries: use memdev for RAM

      memory_region_allocate_system_memory() API is going away, so
      replace it with memdev allocated MemoryRegion. The later is
      initialized by generic code, so board only needs to opt in
      to memdev scheme by providing
    MachineClass::default_ram_id
      and using MachineState::ram instead of manually initializing
      RAM memory region.

      PS:
   while at it add check for user supplied RAM size and error
   out if it mismatches board expected value.

      Signed-off-by: Igor Mammedov 
      Reviewed-by: Andrew Jones 
      Reviewed-by: Richard Henderson 
      Message-Id: <20200219160953.13771-26-imamm...@redhat.com>


This fixes the issue:

-- >8 --
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index e48092ca047..76fd7fe9854 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -1318,6 +1318,7 @@ static void n8x0_init(MachineState *machine,
   g_free(sz);
   exit(EXIT_FAILURE);
   }
+binfo->ram_size = machine->ram_size;

   memory_region_add_subregion(get_system_memory(), OMAP2_Q2_BASE,
   machine->ram);


we really should replace binfo->ram_size with machine->ram_size to avoid
duplicating the same data, but as a quick fix this should fix issue.


Hmm this is the 'ARM kernel loader' API in "arm/boot.h":

struct arm_boot_info {
uint64_t ram_size;
const char *kernel_filename;
const char *kernel_cmdline;
const char *initrd_filename;
const char *dtb_filename;

and:

  void (*write_secondary_boot)(ARMCPU *cpu,
   const struct arm_boot_info *info);
  void (*secondary_cpu_reset_hook)(ARMCPU *cpu,
   const struct arm_boot_info *info);

Are you saying arm_boot_info should hold a pointer to MachineState*
instead of duplicating?



Re: [PATCH v3 8/9] hw/arm/raspi: Add the Raspberry Pi Zero machine

2020-10-23 Thread Philippe Mathieu-Daudé

Hi Igor,

On 10/23/20 5:51 PM, Igor Mammedov wrote:

On Sun, 18 Oct 2020 22:33:57 +0200
Philippe Mathieu-Daudé  wrote:


Similarly to the Pi A, the Pi Zero uses a BCM2835 SoC (ARMv6Z core).

Example booting the machine using content from [*]:

   $ qemu-system-arm -M raspi0 -serial stdio \
   -kernel raspberrypi/firmware/boot/kernel.img \
   -dtb raspberrypi/firmware/boot/bcm2708-rpi-zero.dtb \
   -append 'printk.time=0 earlycon=pl011,0x20201000 console=ttyAMA0'
   [0.00] Booting Linux on physical CPU 0x0
   [0.00] Linux version 4.19.118+ (dom@buildbot) (gcc version 4.9.3 
(crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1311 Mon Apr 27 14:16:15 BST 
2020
   [0.00] CPU: ARMv6-compatible processor [410fb767] revision 7 
(ARMv7), cr=00c5387d
   [0.00] CPU: VIPT aliasing data cache, unknown instruction cache
   [0.00] OF: fdt: Machine model: Raspberry Pi Zero
   ...

[*] 
http://archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20200512-2_armhf.deb

Reviewed-by: Luc Michel 
Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/arm/raspi.c | 13 +
  1 file changed, 13 insertions(+)

diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 91a59d1d489..1510ca01afe 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -319,6 +319,15 @@ static void raspi_machine_class_common_init(MachineClass 
*mc,
  mc->default_ram_id = "ram";
  };
  
+static void raspi0_machine_class_init(ObjectClass *oc, void *data)

+{
+MachineClass *mc = MACHINE_CLASS(oc);
+RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc);
+
+rmc->board_rev = 0x900092;


shouldn't it be
920092  Zero1.2 512MB   Embest
or
920093  Zero1.3 512MB   Embest


I took the value from the "New-style revision codes"
table listed in hw/arm/raspi.c before the REV_CODE
register definitions:

https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md

90009x's manufacturer is "Sony UK", 92009x is "Embest".
I guess we don't care much the manufacturer :)

The Revision 1.3 exposed the MIPI camera interface.
As we don't model it, I prefer to use the 1.2 revision
which matches better.

I'll add this information in the commit description.

Thanks for reviewing!




+raspi_machine_class_common_init(mc, rmc->board_rev);
+};
+
  static void raspi1ap_machine_class_init(ObjectClass *oc, void *data)
  {
  MachineClass *mc = MACHINE_CLASS(oc);
@@ -352,6 +361,10 @@ static void raspi3b_machine_class_init(ObjectClass *oc, 
void *data)
  
  static const TypeInfo raspi_machine_types[] = {

  {
+.name   = MACHINE_TYPE_NAME("raspi0"),
+.parent = TYPE_RASPI_MACHINE,
+.class_init = raspi0_machine_class_init,
+}, {
  .name   = MACHINE_TYPE_NAME("raspi1ap"),
  .parent = TYPE_RASPI_MACHINE,
  .class_init = raspi1ap_machine_class_init,







Re: [PATCH] pci: Refuse to hotplug PCI Devices when the Guest OS is not ready

2020-10-23 Thread Igor Mammedov
On Fri, 23 Oct 2020 11:54:40 -0400
"Michael S. Tsirkin"  wrote:

> On Fri, Oct 23, 2020 at 09:47:14AM +0300, Marcel Apfelbaum wrote:
> > Hi David,
> > 
> > On Fri, Oct 23, 2020 at 6:49 AM David Gibson  wrote:
> > 
> > On Thu, 22 Oct 2020 11:01:04 -0400
> > "Michael S. Tsirkin"  wrote:
> >   
> > > On Thu, Oct 22, 2020 at 05:50:51PM +0300, Marcel Apfelbaum wrote:
> > >  [...] 
> > >
> > > Right. After detecting just failing unconditionally it a bit too
> > > simplistic IMHO.  
> > 
> > There's also another factor here, which I thought I'd mentioned
> > already, but looks like I didn't: I think we're still missing some
> > details in what's going on.
> > 
> > The premise for this patch is that plugging while the indicator is in
> > transition state is allowed to fail in any way on the guest side.  I
> > don't think that's a reasonable interpretation, because it's unworkable
> > for physical hotplug.  If the indicator starts blinking while you're 
> > in
> > the middle of shoving a card in, you'd be in trouble.
> > 
> > So, what I'm assuming here is that while "don't plug while blinking" is
> > the instruction for the operator to obey as best they can, on the guest
> > side the rule has to be "start blinking, wait a while and by the time
> > you leave blinking state again, you can be confident any plugs or
> > unplugs have completed".  Obviously still racy in the strict computer
> > science sense, but about the best you can do with slow humans in the
> > mix.
> > 
> > So, qemu should of course endeavour to follow that rule as though it
> > was a human operator on a physical machine and not plug when the
> > indicator is blinking.  *But* the qemu plug will in practice be fast
> > enough that if we're hitting real problems here, it suggests the guest
> > is still doing something wrong.
> > 
> > 
> > I personally think there is a little bit of over-engineering here.
> > Let's start with the spec:
> > 
> >     Power Indicator Blinking
> >     A blinking Power Indicator indicates that the slot is powering up 
> > or
> > powering down and that
> >     insertion or removal of the adapter is not permitted.
> > 
> > What exactly is an interpretation here?
> > As you stated, the races are theoretical, the whole point of the indicator
> > is to let the operator know he can't plug the device just yet.
> > 
> > I understand it would be more user friendly if the QEMU would wait 
> > internally
> > for the
> > blinking to end, but the whole point of the indicator is to let the 
> > operator 
> > (human or machine)
> > know they can't plug the device at a specific time.
> > Should QEMU take the responsibility of the operator? Is it even correct?
> > 
> > Even if we would want such a feature, how is it related to this patch?
> > The patch simply refuses to start a hotplug operation when it knows it will 
> > not
> > succeed. 
> >  
> > Another way that would make sense to me would be  is a new QEMU 
> > interface other
> > than
> > "add_device", let's say "adding_device_allowed", that would return true if 
> > the
> > hotplug is allowed
> > at this point of time. (I am aware of the theoretical races)   
> 
> Rather than adding_device_allowed, something like "query slot"
> might be helpful for debugging. That would help user figure out
> e.g. why isn't device visible without any races.

Would be new command useful tough? What we end up is broken guest
(if I read commit message right) and a user who has no idea if 
device_add was successful or not.
So what user should do in this case
  - wait till it explodes?
  - can user remove it or it would be stuck there forever?
  - poll slot before hotplug, manually?

(if this is the case then failing device_add cleanly doesn't sound bad,
it looks similar to another error we have "/* Check if hot-plug is disabled on 
the slot */"
in pcie_cap_slot_pre_plug_cb)

CCing libvirt, as it concerns not only QEMU.

> 
> > The above will at least mimic the mechanics of the pyhs world.  The 
> > operator
> > looks at the indicator,
> > the management software checks if adding the device is allowed.
> > Since it is a corner case I would prefer the device_add to fail rather than
> > introducing a new interface,
> > but that's just me.
> > 
> > Thanks,
> > Marcel
> >   
> 
> I think we want QEMU management interface to be reasonably
> abstract and agnostic if possible. Pushing knowledge of hardware
> detail to management will just lead to pain IMHO.
> We supported device_add which practically never fails for years,

For CPUs and RAM, device_add can fail so maybe management is also
prepared to handle errors on PCI hotplug path.

> at this point it's easier to keep supporting it than
> change all users ...
> 
> 
> > 
> > --
> > David Gibson 
> > Principal Software Engineer, Virtualization, Red Hat
> >   
> 
> 




Re: [PATCH v11 12/19] multi-process: Forward PCI config space acceses to the remote process

2020-10-23 Thread Philippe Mathieu-Daudé

On 10/15/20 8:05 PM, Jagannathan Raman wrote:

From: Elena Ufimtseva 

The Proxy Object sends the PCI config space accesses as messages
to the remote process over the communication channel

TODO:
Investigate if the local PCI config writes can be dropped.
Without the proxy local PCI config space writes for the device,
the driver in the guest times out on the probing.
We have tried to only refer to the remote for the PCI config writes,
but the driver timeout in the guest forced as to left this
as it is (removing local PCI config only).


I expect this TODO to be lost in git history. Better to
commit it in the code and remove it once resolved IMHO.



Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
Reviewed-by: Stefan Hajnoczi 
---
  hw/i386/remote-msg.c | 62 
  hw/pci/proxy.c   | 50 ++
  include/io/mpqemu-link.h |  9 +++
  io/mpqemu-link.c |  6 +
  4 files changed, 127 insertions(+)


Please have a look at scripts/git.orderfile, it helps
reviewers to avoid scrolling down/up the patches.



diff --git a/hw/i386/remote-msg.c b/hw/i386/remote-msg.c
index 6451b77..94937db 100644
--- a/hw/i386/remote-msg.c
+++ b/hw/i386/remote-msg.c
@@ -15,6 +15,12 @@
  #include "io/mpqemu-link.h"
  #include "qapi/error.h"
  #include "sysemu/runstate.h"
+#include "hw/pci/pci.h"
+
+static void process_config_write(QIOChannel *ioc, PCIDevice *dev,
+ MPQemuMsg *msg);
+static void process_config_read(QIOChannel *ioc, PCIDevice *dev,
+MPQemuMsg *msg);
  
  void coroutine_fn mpqemu_remote_msg_loop_co(void *data)

  {
@@ -43,6 +49,12 @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
  }
  
  switch (msg.cmd) {

+case PCI_CONFIG_WRITE:
+process_config_write(com->ioc, pci_dev, );
+break;
+case PCI_CONFIG_READ:
+process_config_read(com->ioc, pci_dev, );
+break;
  default:
  error_setg(_err,
 "Unknown command (%d) received for device %s (pid=%d)",
@@ -60,3 +72,53 @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
  
  return;

  }
+
+static void process_config_write(QIOChannel *ioc, PCIDevice *dev,
+ MPQemuMsg *msg)
+{
+ConfDataMsg *conf = (ConfDataMsg *)>data.conf_data;
+MPQemuMsg ret = { 0 };
+Error *local_err = NULL;
+
+if ((conf->addr + sizeof(conf->val)) > pci_config_size(dev)) {
+error_report("Bad address received when writing PCI config, pid %d",
+ getpid());
+ret.data.u64 = UINT64_MAX;
+} else {
+pci_default_write_config(dev, conf->addr, conf->val, conf->l);
+}
+
+ret.cmd = RET_MSG;
+ret.size = sizeof(ret.data.u64);
+
+mpqemu_msg_send(, ioc, _err);
+if (local_err) {
+error_report("Could not send message to proxy from pid %d",
+ getpid());
+}
+}
+
+static void process_config_read(QIOChannel *ioc, PCIDevice *dev,
+MPQemuMsg *msg)
+{
+ConfDataMsg *conf = (ConfDataMsg *)>data.conf_data;
+MPQemuMsg ret = { 0 };
+Error *local_err = NULL;
+
+if ((conf->addr + sizeof(conf->val)) > pci_config_size(dev)) {
+error_report("Bad address received when reading PCI config, pid %d",
+ getpid());
+ret.data.u64 = UINT64_MAX;
+} else {
+ret.data.u64 = pci_default_read_config(dev, conf->addr, conf->l);


Isn't it endianess issue here? It might makes sense to
declare ConfDataMsg and PCI_CONFIG_READ/PCI_CONFIG_WRITE
packets in little endian.


+}
+
+ret.cmd = RET_MSG;
+ret.size = sizeof(ret.data.u64);
+
+mpqemu_msg_send(, ioc, _err);
+if (local_err) {
+error_report("Could not send message to proxy from pid %d",
+ getpid());
+}
+}
diff --git a/hw/pci/proxy.c b/hw/pci/proxy.c
index 7a12f23..27714fe 100644
--- a/hw/pci/proxy.c
+++ b/hw/pci/proxy.c
@@ -16,6 +16,8 @@
  #include "hw/qdev-properties.h"
  #include "monitor/monitor.h"
  #include "migration/blocker.h"
+#include "io/mpqemu-link.h"
+#include "qemu/error-report.h"
  
  static void proxy_set_socket(PCIProxyDev *pdev, int fd, Error **errp)

  {
@@ -69,6 +71,51 @@ static void pci_proxy_dev_exit(PCIDevice *pdev)
  error_free(dev->migration_blocker);
  }
  
+static int config_op_send(PCIProxyDev *pdev, uint32_t addr, uint32_t *val,

+  int l, unsigned int op)
+{
+MPQemuMsg msg = { 0 };
+uint64_t ret = -EINVAL;
+Error *local_err = NULL;
+
+msg.cmd = op;
+msg.data.conf_data.addr = addr;
+msg.data.conf_data.val = (op == PCI_CONFIG_WRITE) ? *val : 0;
+msg.data.conf_data.l = l;
+msg.size = sizeof(ConfDataMsg);
+
+ret = mpqemu_msg_send_and_await_reply(, pdev, _err);
+if (local_err) {
+   

[PATCH v4 4/5] tools/virtiofsd: xattr name mapping examples

2020-10-23 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

Add a few examples of xattrmaps to the documentation.

Signed-off-by: Dr. David Alan Gilbert 
Reviewed-by: Stefan Hajnoczi 
---
 docs/tools/virtiofsd.rst | 50 
 1 file changed, 50 insertions(+)

diff --git a/docs/tools/virtiofsd.rst b/docs/tools/virtiofsd.rst
index 868fa0e97b..4e74690eca 100644
--- a/docs/tools/virtiofsd.rst
+++ b/docs/tools/virtiofsd.rst
@@ -201,6 +201,56 @@ e.g.:
 
   would hide 'security.' xattr's in listxattr from the server.
 
+xattr-mapping Examples
+--
+
+1) Prefix all attributes with 'user.virtiofs.'
+
+::
+
+-o xattrmap=":prefix:all::user.virtiofs.::bad:all:::"
+
+
+This uses two rules, using : as the field separator;
+the first rule prefixes and strips 'user.virtiofs.',
+the second rule hides any non-prefixed attributes that
+the host set.
+
+2) Prefix 'trusted.' attributes, allow others through
+
+::
+
+   "/prefix/all/trusted./user.virtiofs./
+/bad/server//trusted./
+/bad/client/user.virtiofs.//
+/ok/all///"
+
+
+Here there are four rules, using / as the field
+separator, and also demonstrating that new lines can
+be included between rules.
+The first rule is the prefixing of 'trusted.' and
+stripping of 'user.virtiofs.'.
+The second rule hides unprefixed 'trusted.' attributes
+on the host.
+The third rule stops a guest from explicitly setting
+the 'user.viritofs.' path directly.
+Finally, the fourth rule lets all remaining attributes
+through.
+
+3) Hide 'security.' attributes, and allow everything else
+
+::
+
+"/bad/all/security./security./
+ /ok/all///'
+
+The first rule combines what could be separate client and server
+rules into a single 'all' rule, matching 'security.' in either
+client arguments or lists returned from the host.  This stops
+the client seeing any 'security.' attributes on the server and
+stops it setting any.
+
 Examples
 
 
-- 
2.28.0




Re: [PATCH v11 12/19] multi-process: Forward PCI config space acceses to the remote process

2020-10-23 Thread Philippe Mathieu-Daudé

On 10/23/20 6:59 PM, Philippe Mathieu-Daudé wrote:

On 10/15/20 8:05 PM, Jagannathan Raman wrote:

From: Elena Ufimtseva 

The Proxy Object sends the PCI config space accesses as messages
to the remote process over the communication channel

...


+static void process_config_read(QIOChannel *ioc, PCIDevice *dev,
+    MPQemuMsg *msg)
+{
+    ConfDataMsg *conf = (ConfDataMsg *)>data.conf_data;
+    MPQemuMsg ret = { 0 };
+    Error *local_err = NULL;
+
+    if ((conf->addr + sizeof(conf->val)) > pci_config_size(dev)) {
+    error_report("Bad address received when reading PCI config, 
pid %d",

+ getpid());
+    ret.data.u64 = UINT64_MAX;
+    } else {
+    ret.data.u64 = pci_default_read_config(dev, conf->addr, 
conf->l);


Isn't it endianess issue here? It might makes sense to
declare ConfDataMsg and PCI_CONFIG_READ/PCI_CONFIG_WRITE
packets in little endian.


Bah Stefan told me to look at the specs which are included in
the latest patch (docs/multi-process.rst). As I process patches
of this series in order I haven't looked at it yet. Still,
why not put it first in your series?

Regards,

Phil.




Re: [qemu-web PATCH 5/7] Simplify and restructure the page footer

2020-10-23 Thread Paolo Bonzini
On 23/10/20 18:46, Daniel P. Berrangé wrote:
>> I would rather keep this column, the idea is that this information can
>> be found with a quick Ctrl-F "bug" or "Ctrl-F "faq".
>
> If there are useful links that are hidden such that people have to use
> "Ctrl-f " to search for them, then I think we've failed at design
> already.

As you said the links are already mostly available from the "contribute"
page.  "Report a bug" is a bit of an in-the-middle case that is niche
enough that it should not be too prominent, but still worth being
available in the home page in some way.

> IMHO the front page has way too much real estate taken up with the
> screenshots and big headings, and very little useful content right
> now.

Yeah, that's true (that is something that was inherited from template I
used, which you can see for reference at https://templated.co/linear).

Paolo




[PATCH v4 5/5] tools/virtiofsd: xattr name mappings: Simple 'map'

2020-10-23 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

The mapping rule system implemented in the last few patches is
extremely flexible, but not easy to use.  Add a simple
'map' type as a sprinkling of sugar to make it easy.

e.g.

  -o xattrmap=":map::user.virtiofs.:"

would be sufficient to prefix all xattr's
or

  -o xattrmap=":map:trusted.:user.virtiofs.:"

would just prefix 'trusted.' xattr's and leave
everything else alone.

Signed-off-by: Dr. David Alan Gilbert 
---
 docs/tools/virtiofsd.rst |  19 ++
 tools/virtiofsd/passthrough_ll.c | 112 ++-
 2 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/docs/tools/virtiofsd.rst b/docs/tools/virtiofsd.rst
index 4e74690eca..24268fd67e 100644
--- a/docs/tools/virtiofsd.rst
+++ b/docs/tools/virtiofsd.rst
@@ -129,6 +129,7 @@ Each rule consists of a number of fields separated with a 
separator that is the
 first non-white space character in the rule.  This separator must then be used
 for the whole rule.
 White space may be added before and after each rule.
+
 Using ':' as the separator a rule is of the form:
 
 ``:type:scope:key:prepend:``
@@ -201,6 +202,14 @@ e.g.:
 
   would hide 'security.' xattr's in listxattr from the server.
 
+A simpler 'map' type provides a shorter syntax for the common case:
+
+``:map:key:prepend:``
+
+The 'map' type adds a number of separate rules to add **prepend** as a prefix
+to the matched **key** (or all attributes if **key** is empty).
+There may be at most one 'map' rule and it must be the last rule in the set.
+
 xattr-mapping Examples
 --
 
@@ -216,6 +225,11 @@ the first rule prefixes and strips 'user.virtiofs.',
 the second rule hides any non-prefixed attributes that
 the host set.
 
+This is equivalent to the 'map' rule:
+
+::
+-o xattrmap=":map::user.virtiofs.:"
+
 2) Prefix 'trusted.' attributes, allow others through
 
 ::
@@ -238,6 +252,11 @@ the 'user.viritofs.' path directly.
 Finally, the fourth rule lets all remaining attributes
 through.
 
+This is equivalent to the 'map' rule:
+
+::
+-o xattrmap="/map/trusted./user.virtiofs./"
+
 3) Hide 'security.' attributes, and allow everything else
 
 ::
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index 57f584ee49..9f1ad9698d 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -2078,6 +2078,109 @@ static void free_xattrmap(struct lo_data *lo)
 lo->xattr_map_nentries = -1;
 }
 
+/*
+ * Handle the 'map' type, which is sugar for a set of commands
+ * for the common case of prefixing a subset or everything,
+ * and allowing anything not prefixed through.
+ * It must be the last entry in the stream, although there
+ * can be other entries before it.
+ * The form is:
+ *:map:key:prefix:
+ *
+ * key maybe empty in which case all entries are prefixed.
+ */
+static void parse_xattrmap_map(struct lo_data *lo,
+   const char *rule, char sep)
+{
+const char *tmp;
+char *key;
+char *prefix;
+XattrMapEntry tmp_entry;
+
+if (*rule != sep) {
+fuse_log(FUSE_LOG_ERR,
+ "%s: Expecting '%c' after 'map' keyword, found '%c'\n",
+ __func__, sep, *rule);
+exit(1);
+}
+
+rule++;
+
+/* At start of 'key' field */
+tmp = strchr(rule, sep);
+if (!tmp) {
+fuse_log(FUSE_LOG_ERR,
+ "%s: Missing '%c' at end of key field in map rule\n",
+ __func__, sep);
+exit(1);
+}
+
+key = g_strndup(rule, tmp - rule);
+rule = tmp + 1;
+
+/* At start of prefix field */
+tmp = strchr(rule, sep);
+if (!tmp) {
+fuse_log(FUSE_LOG_ERR,
+ "%s: Missing '%c' at end of prefix field in map rule\n",
+ __func__, sep);
+exit(1);
+}
+
+prefix = g_strndup(rule, tmp - rule);
+rule = tmp + 1;
+
+/*
+ * This should be the end of the string, we don't allow
+ * any more commands after 'map'.
+ */
+if (*rule) {
+fuse_log(FUSE_LOG_ERR,
+ "%s: Expecting end of command after map, found '%c'\n",
+ __func__, *rule);
+exit(1);
+}
+
+/* 1st: Prefix matches/everything */
+tmp_entry.flags = XATTR_MAP_FLAG_PREFIX | XATTR_MAP_FLAG_ALL;
+tmp_entry.key = g_strdup(key);
+tmp_entry.prepend = g_strdup(prefix);
+add_xattrmap_entry(lo, _entry);
+
+if (!*key) {
+/* Prefix all case */
+
+/* 2nd: Hide any non-prefixed entries on the host */
+tmp_entry.flags = XATTR_MAP_FLAG_BAD | XATTR_MAP_FLAG_ALL;
+tmp_entry.key = g_strdup("");
+tmp_entry.prepend = g_strdup("");
+add_xattrmap_entry(lo, _entry);
+} else {
+/* Prefix matching case */
+
+/* 2nd: Hide non-prefixed but matching entries on the host */
+tmp_entry.flags = XATTR_MAP_FLAG_BAD | XATTR_MAP_FLAG_SERVER;
+tmp_entry.key = g_strdup(""); /* Not used */
+

  1   2   3   4   5   >