Re: [RFC PATCH] hw/arm/virt: Support NMI injection

2020-01-28 Thread Julien Thierry




On 1/29/20 3:46 AM, Gavin Shan wrote:

On 1/28/20 7:29 PM, Julien Thierry wrote:

Hi Gavin,

On 1/28/20 6:48 AM, Gavin Shan wrote:

[including more folks into the discussion]

On Fri, 17 Jan 2020 at 14:00, Peter Maydell 
 wrote:

On Thu, 19 Dec 2019 at 04:06, Gavin Shan  wrote:
This supports NMI injection for virtual machine and currently it's 
only
supported on GICv3 controller, which is emulated by qemu or host 
kernel.

The design is highlighted as below:

* The NMI is identified by its priority (0x20). In the guest (linux)
kernel, the GICC_PMR is set to 0x80, to block all interrupts except
the NMIs when the external interrupt is disabled. It means the FIQ
and IRQ bit in PSTATE isn't touched when the functionality (NMI) is
functional.
* LPIs aren't considered as NMIs because of their nature. It means 
NMI

is either SPI or PPI. Besides, the NMIs are injected in round-robin
fashion is there are multiple NMIs existing.
* When the GICv3 controller is emulated by qemu, the interrupt states
(e.g. enabled, priority) is fetched from the corresponding data 
struct

directly. However, we have to pause all CPUs to fetch the interrupt
states from host in advance if the GICv3 controller is emulated by
host.

The testing scenario is to tweak guest (linux) kernel where the 
pl011 SPI
can be enabled as NMI by request_nmi(). Check "/proc/interrupts" 
after injecting
several NMIs, to see if the interrupt count is increased or not. 
The result

is just as expected.



So, QEMU is trying to emulate actual hardware. None of this
looks to me like what GICv3 hardware does... If you want to
have the virt board send an interrupt, do it the usual way
by wiring up a qemu_irq from some device to the GIC, please.
(More generally, there is no concept of an "NMI" in the GIC;
there are just interrupts at varying possible guest-programmable
priority levels.)



Peter, I missed to read your reply in time and apologies for late 
response.


Yes, there is no concept of "NMI" in the GIC from hardware perspective.
However, NMI has been supported from the software by kernel commit
bc3c03ccb4641 ("arm64: Enable the support of pseudo-NMIs"). The NMIs
have higher priority than normal ones. NMIs are deliverable after
local_irq_disable() because the SYS_ICC_PMR_EL1 is tweaked so that
normal interrupts are masked only.

It's unclear about the purpose of "nmi" QMP/HMP command. It's why I
put a RFC tag. The command has been supported by multiple architects
including x86/ppc. However, they are having different behaviors. The
system will be restarted on ppc with this command, but a NMI is injected
through LAPIC on x86. So I'm not sure what architect (system reset on
ppc or injecting NMI on x86) aarch64 should follow.



As Peter stated, there is no NMI concept on aarch64 hardware. The 
pseudo-NMI in the Linux port is purely a software concept. The OS 
itself decides which interrupts should have the "NMI" properties and 
sets them up accordingly.


For QEMU to inject a pseudo-NMI into the guest would require it not 
only to know that the guest supports that feature. But also how such 
an interrupt has to be set up (currently there is no guaranty that the 
priority used for the NMI and the mask should stay the same across 
Linux version as it is purely internal to GICv3/arm64, no generic kAPI 
nor uAPI have access to it). And also, you would probably need to know 
what is handling the NMI you are injecting.


QEMU shouldn't try to guess "that might be dealt as an NMI, lets raise 
it".


I'm not familiar with the QMP/HMP nor the inner workings of QEMU, but 
if for some reason QEMU requires to trigger an NMI-like mechanic on 
aarch64, a proper way might be through para-virt. Having some 
"qemu-nmi-driver" in linux which calls "request_nmi()" and does the 
proper handling expected by QEMU.


Cheers,



Julien, thanks for the explanation. The question we're not sure if NMI 
should
be injected on receiving HMP/QMP "nmi" command. It means it's not clear 
what

behavior we should have for this command on ARM. However, I have one more
unrelated question: "pseudo" NMI on ARM64 should be PPI? I mean SPI can't
be "pseudo" NMI.



I'm not sure I understand why you say "SPI can't be "pseudo" NMI". 
Currently both PPI and SPI are supported in the "pseudo" NMI scheme. Do 
you think that should not be the case? If so, can you elaborate?


Thanks,

--
Julien Thierry




Re: [PATCH v3 13/14] dp8393x: Don't reset Silicon Revision register

2020-01-28 Thread Finn Thain
On Wed, 29 Jan 2020, Philippe Mathieu-Daudé wrote:

> > 
> > This would allow the host to change the value of the Silicon Revision 
> > register.
> How the guest can modify it? We have:
> 
> 589 static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data,
> 590   unsigned int size)
> 591 {
> 592 dp8393xState *s = opaque;
> 593 int reg = addr >> s->it_shift;
> 594
> ...
> 597 switch (reg) {
> ...
> 602 /* Prevent write to read-only registers */
> ...
> 606 case SONIC_SR:
> ...
> 608 DPRINTF("writing to reg %d invalid\n", reg);
> 609 break;
> 

My mistake. I had completely overlooked that logic.

I'll revise this patch in accordance with your suggestion.

Re: [PATCH] .travis.yml: Add description to each job

2020-01-28 Thread Thomas Huth
On 28/01/2020 13.55, Alex Bennée wrote:
> 
> Thomas Huth  writes:
> 
>> On 25/01/2020 19.31, Philippe Mathieu-Daudé wrote:
>>> The NAME variable can be used to describe nicely a job (see [*]).
>>> As we currently have 32 jobs, use it. This helps for quickly
>>> finding a particular job.
>>>
>>>   before: https://travis-ci.org/qemu/qemu/builds/639887646
>>>   after: https://travis-ci.org/philmd/qemu/builds/641795043
>>
>> Very good idea, correlating a job in the GUI to an entry in the yml file
>> was really a pain, so far.
>>
>>> [*] 
>>> https://docs.travis-ci.com/user/customizing-the-build/#naming-jobs-within-matrices
>>>
>>> Signed-off-by: Philippe Mathieu-Daudé 
>>> ---
>>>  .travis.yml | 101 ++--
>>>  1 file changed, 67 insertions(+), 34 deletions(-)
>>>
>>> diff --git a/.travis.yml b/.travis.yml
>>> index 6c1038a0f1..d68e35a2c5 100644
>>> --- a/.travis.yml
>>> +++ b/.travis.yml
>>> @@ -94,24 +94,28 @@ after_script:
>>>  
>>>  matrix:
>>>include:
>>> -- env:
>>> +- name: "[x86] GCC static (user)"
>>
>> Could you please drop the [x86] and other architectures from the names?
>> Travis already lists the build architecture in the job status page, so
>> this information is redundant.
> 
> Hmm for me the Travis page mis-renders the architecture (on firefox) so
> I do find the arch in the text fairly handy.

That's really weird, I'm also using Firefox and it looks fine here!

>>>  # Alternate coroutines implementations are only really of interest to 
>>> KVM users
>>>  # However we can't test against KVM on Travis so we can only run unit 
>>> tests
>>> -- env:
>>> +- name: "[x86] check-unit coroutine=ucontext"
>>> +  env:
>>>  - CONFIG="--with-coroutine=ucontext --disable-tcg"
>>>  - TEST_CMD="make check-unit -j3 V=1"
>>>  
>>>  
>>> -- env:
>>> +- name: "[x86] check-unit coroutine=sigaltstack"
>>> +  env:
>>>  - CONFIG="--with-coroutine=sigaltstack --disable-tcg"
>>>  - TEST_CMD="make check-unit -j3 V=1"
>>>
>>
>> Off-topic to your patch, but aren't coroutines something that is only
>> used in the softmmu targets? If so, we could add --disable-user to the
>> above two builds to speed things up a little bit.
> 
> I think --disable-tcg implies --disable-user as you can't run without
> it.

D'oh, of course you're right, --disable-tcg limits the targets to
*86-softmmu!

 Thomas




Re: [PATCH v2 1/7] block/block-copy: specialcase first copy_range request

2020-01-28 Thread Andrey Shinkevich


On 27/11/2019 21:08, Vladimir Sementsov-Ogievskiy wrote:
> In block_copy_do_copy we fallback to read+write if copy_range failed.
> In this case copy_size is larger than defined for buffered IO, and
> there is corresponding commit. Still, backup copies data cluster by
> cluster, and most of requests are limited to one cluster anyway, so the
> only source of this one bad-limited request is copy-before-write
> operation.
> 
> Further patch will move backup to use block_copy directly, than for
> cases where copy_range is not supported, first request will be
> oversized in each backup. It's not good, let's change it now.
> 
> Fix is simple: just limit first copy_range request like buffer-based
> request. If it succeed, set larger copy_range limit.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>   block/block-copy.c | 41 ++---
>   1 file changed, 30 insertions(+), 11 deletions(-)
> 
> diff --git a/block/block-copy.c b/block/block-copy.c
> index 79798a1567..8602e2cae7 100644
> --- a/block/block-copy.c
> +++ b/block/block-copy.c
> @@ -70,16 +70,19 @@ void block_copy_state_free(BlockCopyState *s)
>   g_free(s);
>   }
>   
> +static uint32_t block_copy_max_transfer(BdrvChild *source, BdrvChild *target)
> +{
> +return MIN_NON_ZERO(INT_MAX,
> +MIN_NON_ZERO(source->bs->bl.max_transfer,
> + target->bs->bl.max_transfer));
> +}
> +
>   BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
>int64_t cluster_size,
>BdrvRequestFlags write_flags, Error 
> **errp)
>   {
>   BlockCopyState *s;
>   BdrvDirtyBitmap *copy_bitmap;
> -uint32_t max_transfer =
> -MIN_NON_ZERO(INT_MAX,
> - MIN_NON_ZERO(source->bs->bl.max_transfer,
> -  target->bs->bl.max_transfer));
>   
>   copy_bitmap = bdrv_create_dirty_bitmap(source->bs, cluster_size, NULL,
>  errp);
> @@ -99,7 +102,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, 
> BdrvChild *target,
>   .mem = shres_create(BLOCK_COPY_MAX_MEM),
>   };
>   
> -if (max_transfer < cluster_size) {
> +if (block_copy_max_transfer(source, target) < cluster_size) {
>   /*
>* copy_range does not respect max_transfer. We don't want to bother
>* with requests smaller than block-copy cluster size, so fallback 
> to
> @@ -114,12 +117,11 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, 
> BdrvChild *target,
>   s->copy_size = cluster_size;
>   } else {
>   /*
> - * copy_range does not respect max_transfer (it's a TODO), so we 
> factor
> - * that in here.
> + * We enable copy-range, but keep small copy_size, until first
> + * successful copy_range (look at block_copy_do_copy).
>*/
>   s->use_copy_range = true;
> -s->copy_size = MIN(MAX(cluster_size, BLOCK_COPY_MAX_COPY_RANGE),
> -   QEMU_ALIGN_DOWN(max_transfer, cluster_size));
> +s->copy_size = MAX(s->cluster_size, BLOCK_COPY_MAX_BUFFER);
>   }
>   
>   QLIST_INIT(>inflight_reqs);
> @@ -168,7 +170,21 @@ static int coroutine_fn 
> block_copy_do_copy(BlockCopyState *s,
>   s->use_copy_range = false;
>   s->copy_size = MAX(s->cluster_size, BLOCK_COPY_MAX_BUFFER);
>   /* Fallback to read+write with allocated buffer */
> -} else {
> +} else if (s->use_copy_range) {
> +/*
> + * Successful copy-range. Now increase copy_size.
> + * copy_range does not respect max_transfer (it's a TODO), so we
> + * factor that in here.
> + *
> + * Note: we double-check s->use_copy_range for the case when
> + * parallel block-copy request unset it during previous
unsets

> + * bdrv_co_copy_range call.
> + */
> +s->copy_size =
> +MIN(MAX(s->cluster_size, BLOCK_COPY_MAX_COPY_RANGE),
> +QEMU_ALIGN_DOWN(block_copy_max_transfer(s->source,
> +s->target),
> +s->cluster_size));
>   goto out;
>   }
>   }
> @@ -176,7 +192,10 @@ static int coroutine_fn 
> block_copy_do_copy(BlockCopyState *s,
>   /*
>* In case of failed copy_range request above, we may proceed with 
> buffered
>* request larger than BLOCK_COPY_MAX_BUFFER. Still, further requests 
> will
> - * be properly limited, so don't care too much.
> + * be properly limited, so don't care too much. Moreover the most 
> possible
> + * case (copy_range is unsupported for the configuration, so the very 
> first
> + * copy_range request 

Re: [PATCH rc3 01/30] target/avr: Add basic parameters for new AVR platform

2020-01-28 Thread Philippe Mathieu-Daudé

On 1/28/20 7:01 PM, Aleksandar Markovic wrote:

Works for me too.


16:10 Uto, 28.01.2020. Michael Rolnik > је написао/ла:


Sounds good to me.

On Tue, Jan 28, 2020 at 3:49 PM Aleksandar Markovic
mailto:aleksandar.m.m...@gmail.com>>
wrote:



On Tuesday, January 28, 2020, Michael Rolnik mailto:mrol...@gmail.com>> wrote:

Hi all.

I am totally lost in the email.
Are there any action items for me / someone else ?

Regards,
Michael Rolnik


I think it would be helpful if we have rc4 with two action items:

    - remove CONFIG_USER_ONLY references, and all dead code thay
may have come with it + add check in cpu.h that Philippe suggested.
    - remove "Atmel" word from all elements of the series (patch
names, messages, filenames, structure names, ...)

Needless to say that this must be done with extreme care.

I propose that Philippe do rc4.


I won't have time to work on AVR this week-end and the next one (family 
plans). If I find time I prefer prioritize the raspi machine because I 
want to see some work merged before Igor "use memdev for RAM" series get 
in. So if you guys have time & motivation, go for it!




Sincerely,
Aleksandar


On Mon, Jan 27, 2020 at 10:54 AM Michael Rolnik
mailto:mrol...@gmail.com>> wrote:

Thanks for you help guys.

On Mon, Jan 27, 2020 at 12:55 AM Aleksandar Markovic
mailto:aleksandar.marko...@rt-rk.com>> wrote:

From: Michael Rolnik mailto:mrol...@gmail.com>>

This includes definitions of various basic
parameters needed
for integration of a new platform into QEMU.

Co-developed-by: Michael Rolnik mailto:mrol...@gmail.com>>
Co-developed-by: Sarah Harris mailto:s.e.har...@kent.ac.uk>>
Signed-off-by: Michael Rolnik mailto:mrol...@gmail.com>>
Signed-off-by: Sarah Harris mailto:s.e.har...@kent.ac.uk>>
Signed-off-by: Michael Rolnik mailto:mrol...@gmail.com>>
Acked-by: Igor Mammedov mailto:imamm...@redhat.com>>
Tested-by: Philippe Mathieu-Daudé mailto:phi...@redhat.com>>
Signed-off-by: Richard Henderson
mailto:richard.hender...@linaro.org>>
Signed-off-by: Aleksandar Markovic
mailto:aleksandar.m.m...@gmail.com>>
---
  target/avr/cpu-param.h | 37 ++
  target/avr/cpu.h       | 72
++
  2 files changed, 109 insertions(+)
  create mode 100644 target/avr/cpu-param.h
  create mode 100644 target/avr/cpu.h

diff --git a/target/avr/cpu-param.h
b/target/avr/cpu-param.h
new file mode 100644
index 000..0c29ce4
--- /dev/null
+++ b/target/avr/cpu-param.h
@@ -0,0 +1,37 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019 Michael Rolnik
+ *
+ * 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.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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU
Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#ifndef AVR_CPU_PARAM_H
+#define AVR_CPU_PARAM_H
+
+#define TARGET_LONG_BITS 32
+/*
+ * TARGET_PAGE_BITS cannot be more than 8 bits because
+ * 1.  all IO registers occupy [0x .. 0x00ff]
  

Re: [PATCH] .travis.yml: Add description to each job

2020-01-28 Thread Thomas Huth
On 29/01/2020 08.27, Philippe Mathieu-Daudé wrote:
> On 1/29/20 8:20 AM, Thomas Huth wrote:
>> On 28/01/2020 14.33, Wainer dos Santos Moschetta wrote:
>>>
>>> On 1/28/20 11:18 AM, Philippe Mathieu-Daudé wrote:
 On Tue, Jan 28, 2020 at 1:55 PM Alex Bennée 
 wrote:
> Thomas Huth  writes:
>> On 25/01/2020 19.31, Philippe Mathieu-Daudé wrote:
>>> The NAME variable can be used to describe nicely a job (see [*]).
>>> As we currently have 32 jobs, use it. This helps for quickly
>>> finding a particular job.
>>>
>>>     before: https://travis-ci.org/qemu/qemu/builds/639887646
>>>     after: https://travis-ci.org/philmd/qemu/builds/641795043
>> Very good idea, correlating a job in the GUI to an entry in the yml
>> file
>> was really a pain, so far.
>>
>>> [*]
>>> https://docs.travis-ci.com/user/customizing-the-build/#naming-jobs-within-matrices
>>>
>>>
>>>
>>> Signed-off-by: Philippe Mathieu-Daudé 
>>> ---
>>>    .travis.yml | 101
>>> ++--
>>>    1 file changed, 67 insertions(+), 34 deletions(-)
>>>
>>> diff --git a/.travis.yml b/.travis.yml
>>> index 6c1038a0f1..d68e35a2c5 100644
>>> --- a/.travis.yml
>>> +++ b/.travis.yml
>>> @@ -94,24 +94,28 @@ after_script:
>>>
>>>    matrix:
>>>  include:
>>> -    - env:
>>> +    - name: "[x86] GCC static (user)"
>> Could you please drop the [x86] and other architectures from the
>> names?
>> Travis already lists the build architecture in the job status
>> page, so
>> this information is redundant.
> Hmm for me the Travis page mis-renders the architecture (on
> firefox) so
> I do find the arch in the text fairly handy.
 This might be a font problem, I can't see the architecture on neither
 Firefox nor Chrome:

 https://pasteboard.co/IS3O358.png
>>>
>>>
>>> It is the partially hidden column between the job number and the penguin
>>> (or apple if MacOS).
>>>
>>> Funny, I can see the arch on Philippe's dashboard
>>> (https://travis-ci.org/philmd/qemu) but it disappears on my own
>>> (https://travis-ci.org/wainersm/qemu).
>>
>> I've never had problems here, for me the column shows up correctly
>> everywhere. It looks like this:
>>
>>   http://people.redhat.com/~thuth/travis.png
> 
> OK now I understand better your comment :)
> 
>>
>>> Anyway, most of the jobs run on x86_64. So perhaps mark only the non-x86
>>> ones?
>>
>> Sounds like a good compromise to me!
> 
> I'd rather use one style, rather ARCH explicit on all, or not used at all.

Then I'd vote to drop it (if I've got a vote here at all ;-)), hoping
that Travis fixes their HTML for that column, soon...

 Thomas




Re: [PATCH rc3 23/30] hw/core/loader: Let load_elf populate the processor-specific flags

2020-01-28 Thread Philippe Mathieu-Daudé

Hi Aleksandar,

On 1/28/20 8:25 PM, Aleksandar Markovic wrote:
On Tue, Jan 28, 2020 at 2:27 PM Aleksandar Markovic 
mailto:aleksandar.m.m...@gmail.com>> wrote:




On Tuesday, January 28, 2020, BALATON Zoltan mailto:bala...@eik.bme.hu>> wrote:

On Tue, 28 Jan 2020, Aleksandar Markovic wrote:

On Sunday, January 26, 2020, Aleksandar Markovic <
aleksandar.marko...@rt-rk.com
> wrote:

From: Philippe Mathieu-Daudé mailto:f4...@amsat.org>>

Some platforms (like AVR) need to determine cpu type by
reading
the ELF flags (field e_flags oin ELF header).

This patch enables discovery of the content of that flag
while
using following functions:

   - load_elf()
   - load_elf_as()
   - load_elf_ram()
   - load_elf_ram_sym()

The added argument of these functions is of type
uint32_t*. It is
allowed to pass NULL as that argument, and in such case
no lookup
to the field e_flags will happen, and of course, no
information
will be returned to the caller.


Applied to MIPS queue, with some commit message corrections and fixes.


Sorry I didn't respond earlier, this was a very short delay (patch 
posted yesterday, pull request sent today).


My original patch was much less intrusive:
https://www.mail-archive.com/qemu-devel@nongnu.org/msg673762.html
I don't find comfortable being listed as the author of the current
patch. Do you mind changing the authorship?

Thank you,

Phil.



We plan to use this new functionality for MIPS Malta board,
for detection
of incompatible cpu/kernel combinations, and graceful exit
(right now these
combinations result in hang or crash). I would say other
boards could make
use of it too.

For that reason, if there is no objection, I plan to select
this patch for
next MIPS queue.


No objection but kind of déjà vu:

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

I still think the interface of load_elf may need to be rethinked
but I don't know a good way.



Perhaps having only two, "in" and "out", arguments that are pointers
to structures?

Another thing that I noticed is "endian argument" that it seems
everyone uses in a different way: 0, 1, true, false, bigendian, etc.
Would c enumeration help? This looks to me like a time ticking bomb.

Just to add that some platforms like MIPS and SPARC must load elfs
of more than one value of EM_MACHINE (in MIPS case, EM_MIPS and
EM_NANOMIPS) and current load_elf() interface offers only clumsy
solutions/workarounds in these cases.

Let's think about everything later on.


  This could be fixed in a later patch causing more code churn
again though, so if there's a way to fix this it might be a good
opportunity now. But I don't want to hold your patch series back
so unless someone has a good idea to avoid this situation then
we have to live with it.


Thank you. I will do some minor corrections for obvious unclarities
and typos in the commit message while applying to my qieue.

Regards,
BALATON Zoltan


Regards,
Aleksandar




CC: Richard Henderson mailto:r...@twiddle.net>>
CC: Peter Maydell mailto:peter.mayd...@linaro.org>>
CC: Edgar E. Iglesias mailto:edgar.igles...@gmail.com>>
CC: Michael Walle 
CC: Thomas Huth mailto:h...@tuxfamily.org>>
CC: Laurent Vivier mailto:laur...@vivier.eu>>
CC: Philippe Mathieu-Daudé mailto:f4...@amsat.org>>
CC: Aleksandar Rikalo mailto:aleksandar.rik...@rt-rk.com>>
CC: Aurelien Jarno mailto:aurel...@aurel32.net>>
CC: Jia Liu mailto:pro...@gmail.com>>
CC: David Gibson mailto:da...@gibson.dropbear.id.au>>
CC: Mark Cave-Ayland mailto:mark.cave-ayl...@ilande.co.uk>>
CC: BALATON Zoltan mailto:bala...@eik.bme.hu>>
CC: Christian Borntraeger mailto:borntrae...@de.ibm.com>>
CC: Thomas Huth mailto:th...@redhat.com>>
CC: Artyom Tarasenko mailto:atar4q...@gmail.com>>
CC: Fabien Chouteau mailto:chout...@adacore.com>>
CC: KONRAD Frederic mailto:frederic.kon...@adacore.com>>
CC: Max Filippov mailto:jcmvb...@gmail.com>>

Signed-off-by: Michael Rolnik mailto:mrol...@gmail.com>>
Reviewed-by: Aleksandar Markovic mailto:amarko...@wavecomp.com>>
 

Re: [PATCH] .travis.yml: Add description to each job

2020-01-28 Thread Thomas Huth
On 28/01/2020 14.20, Wainer dos Santos Moschetta wrote:
> 
> On 1/26/20 5:54 AM, Thomas Huth wrote:
>> On 25/01/2020 19.31, Philippe Mathieu-Daudé wrote:
>>> The NAME variable can be used to describe nicely a job (see [*]).
>>> As we currently have 32 jobs, use it. This helps for quickly
>>> finding a particular job.
>>>
>>>    before: https://travis-ci.org/qemu/qemu/builds/639887646
>>>    after: https://travis-ci.org/philmd/qemu/builds/641795043
>> Very good idea, correlating a job in the GUI to an entry in the yml file
>> was really a pain, so far.
>>
>>> [*]
>>> https://docs.travis-ci.com/user/customizing-the-build/#naming-jobs-within-matrices
>>>
>>>
>>> Signed-off-by: Philippe Mathieu-Daudé 
>>> ---
>>>   .travis.yml | 101 ++--
>>>   1 file changed, 67 insertions(+), 34 deletions(-)
>>>
>>> diff --git a/.travis.yml b/.travis.yml
>>> index 6c1038a0f1..d68e35a2c5 100644
>>> --- a/.travis.yml
>>> +++ b/.travis.yml
>>> @@ -94,24 +94,28 @@ after_script:
>>>     matrix:
>>>     include:
>>> -    - env:
>>> +    - name: "[x86] GCC static (user)"
>> Could you please drop the [x86] and other architectures from the names?
>> Travis already lists the build architecture in the job status page, so
>> this information is redundant.
>>
>> [...]
> 
> 
> I agree on dropping the architecture from the names, so:
> 
> Reviewed-by: Wainer dos Santos Moschetta 
> 
> 
>>>   # Alternate coroutines implementations are only really of
>>> interest to KVM users
>>>   # However we can't test against KVM on Travis so we can only
>>> run unit tests
> 
> 
> Yet another off-topic comment: If we switch those coroutine test jobs to
> Bionic then we can use KVM.

Good idea, that's certainly worth a try once your KVM-enablement patch
got included (or maybe you could also respin that patch with KVM enabled
here, too?)

 Thomas




Re: [PATCH] .travis.yml: Add description to each job

2020-01-28 Thread Philippe Mathieu-Daudé

On 1/29/20 8:20 AM, Thomas Huth wrote:

On 28/01/2020 14.33, Wainer dos Santos Moschetta wrote:


On 1/28/20 11:18 AM, Philippe Mathieu-Daudé wrote:

On Tue, Jan 28, 2020 at 1:55 PM Alex Bennée 
wrote:

Thomas Huth  writes:

On 25/01/2020 19.31, Philippe Mathieu-Daudé wrote:

The NAME variable can be used to describe nicely a job (see [*]).
As we currently have 32 jobs, use it. This helps for quickly
finding a particular job.

    before: https://travis-ci.org/qemu/qemu/builds/639887646
    after: https://travis-ci.org/philmd/qemu/builds/641795043

Very good idea, correlating a job in the GUI to an entry in the yml
file
was really a pain, so far.


[*]
https://docs.travis-ci.com/user/customizing-the-build/#naming-jobs-within-matrices


Signed-off-by: Philippe Mathieu-Daudé 
---
   .travis.yml | 101
++--
   1 file changed, 67 insertions(+), 34 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 6c1038a0f1..d68e35a2c5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -94,24 +94,28 @@ after_script:

   matrix:
     include:
-    - env:
+    - name: "[x86] GCC static (user)"

Could you please drop the [x86] and other architectures from the names?
Travis already lists the build architecture in the job status page, so
this information is redundant.

Hmm for me the Travis page mis-renders the architecture (on firefox) so
I do find the arch in the text fairly handy.

This might be a font problem, I can't see the architecture on neither
Firefox nor Chrome:

https://pasteboard.co/IS3O358.png



It is the partially hidden column between the job number and the penguin
(or apple if MacOS).

Funny, I can see the arch on Philippe's dashboard
(https://travis-ci.org/philmd/qemu) but it disappears on my own
(https://travis-ci.org/wainersm/qemu).


I've never had problems here, for me the column shows up correctly
everywhere. It looks like this:

  http://people.redhat.com/~thuth/travis.png


OK now I understand better your comment :)




Anyway, most of the jobs run on x86_64. So perhaps mark only the non-x86
ones?


Sounds like a good compromise to me!


I'd rather use one style, rather ARCH explicit on all, or not used at all.




Re: [PATCH] .travis.yml: Add description to each job

2020-01-28 Thread Thomas Huth
On 28/01/2020 14.33, Wainer dos Santos Moschetta wrote:
> 
> On 1/28/20 11:18 AM, Philippe Mathieu-Daudé wrote:
>> On Tue, Jan 28, 2020 at 1:55 PM Alex Bennée 
>> wrote:
>>> Thomas Huth  writes:
 On 25/01/2020 19.31, Philippe Mathieu-Daudé wrote:
> The NAME variable can be used to describe nicely a job (see [*]).
> As we currently have 32 jobs, use it. This helps for quickly
> finding a particular job.
>
>    before: https://travis-ci.org/qemu/qemu/builds/639887646
>    after: https://travis-ci.org/philmd/qemu/builds/641795043
 Very good idea, correlating a job in the GUI to an entry in the yml
 file
 was really a pain, so far.

> [*]
> https://docs.travis-ci.com/user/customizing-the-build/#naming-jobs-within-matrices
>
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>   .travis.yml | 101
> ++--
>   1 file changed, 67 insertions(+), 34 deletions(-)
>
> diff --git a/.travis.yml b/.travis.yml
> index 6c1038a0f1..d68e35a2c5 100644
> --- a/.travis.yml
> +++ b/.travis.yml
> @@ -94,24 +94,28 @@ after_script:
>
>   matrix:
>     include:
> -    - env:
> +    - name: "[x86] GCC static (user)"
 Could you please drop the [x86] and other architectures from the names?
 Travis already lists the build architecture in the job status page, so
 this information is redundant.
>>> Hmm for me the Travis page mis-renders the architecture (on firefox) so
>>> I do find the arch in the text fairly handy.
>> This might be a font problem, I can't see the architecture on neither
>> Firefox nor Chrome:
>>
>> https://pasteboard.co/IS3O358.png
> 
> 
> It is the partially hidden column between the job number and the penguin
> (or apple if MacOS).
> 
> Funny, I can see the arch on Philippe's dashboard
> (https://travis-ci.org/philmd/qemu) but it disappears on my own
> (https://travis-ci.org/wainersm/qemu).

I've never had problems here, for me the column shows up correctly
everywhere. It looks like this:

 http://people.redhat.com/~thuth/travis.png

> Anyway, most of the jobs run on x86_64. So perhaps mark only the non-x86
> ones?

Sounds like a good compromise to me!

 Thomas




[RFC] coreaudio: fix coreaudio_test.diff

2020-01-28 Thread Volker Rümelin
This is an untested patch that tries to fix the problems in the
patch found at
https://lists.nongnu.org/archive/html/qemu-devel/2020-01/msg02142.html. 

Signed-off-by: Volker Rümelin 
---
 audio/audio_template.h | 16 
 audio/coreaudio.c  |  5 +
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/audio/audio_template.h b/audio/audio_template.h
index a7b46b8363..e6724c5d68 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -153,13 +153,6 @@ static int glue (audio_pcm_sw_init_, TYPE) (
 sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
 #endif
 
-#ifdef FLOAT_MIXENG
-#ifdef DAC
-sw->conv = mixeng_conv_float;
-#else
-sw->clip = mixeng_clip_float;
-#endif
-#else
 #ifdef DAC
 sw->conv = mixeng_conv
 #else
@@ -169,7 +162,6 @@ static int glue (audio_pcm_sw_init_, TYPE) (
 [sw->info.sign]
 [sw->info.swap_endianness]
 [audio_bits_to_index (sw->info.bits)];
-#endif
 
 sw->name = g_strdup (name);
 err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
@@ -284,6 +276,13 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
 goto err1;
 }
 
+#ifdef FLOAT_MIXENG
+#ifdef DAC
+hw->clip = mixeng_clip_float;
+#else
+hw->conv = mixeng_conv_float;
+#endif
+#else
 #ifdef DAC
 hw->clip = mixeng_clip
 #else
@@ -293,6 +292,7 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
 [hw->info.sign]
 [hw->info.swap_endianness]
 [audio_bits_to_index (hw->info.bits)];
+#endif
 
 glue(audio_pcm_hw_alloc_resources_, TYPE)(hw);
 
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 4e7e509ad0..ff0d23fd7d 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -482,6 +482,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 Audiodev *dev = drv_opaque;
 AudiodevCoreaudioPerDirectionOptions *cpdo = dev->u.coreaudio.out;
 int frames;
+struct audsettings fake_as;
 
 /* create mutex */
 err = pthread_mutex_init(>mutex, NULL);
@@ -490,6 +491,10 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct 
audsettings *as,
 return -1;
 }
 
+memcpy(_as, as, sizeof(struct audsettings));
+as = _as;
+/* size of float is 32bits */
+as->fmt = AUDIO_FORMAT_S32;
 audio_pcm_init_info (>info, as);
 
 status = coreaudio_get_voice(>outputDeviceID);
-- 
2.16.4




Re: [PATCH v2] Implement the Screamer sound chip for the mac99 machine type

2020-01-28 Thread Volker Rümelin


>
> Hi Volker,
>
> I can test for coreaudio. Can you let us know exactly what you fixed in the 
> patch?

Hi Howard,

I wrote a patch that tries to fix the problems in Zoltán's patch. The changes 
in coreaudio.c are untested. I'll send it as a reply to this mail. Please apply 
Zoltan's patch and then my patch to qemu master.

> While cross compiling for windows, I saw these errors (besides some casting 
> issues):
> line 56: buffer2  (should be *buffer2?)
> line 455: ret  (should be ret2?)
>
> audio/dsoundaudio.c:56:20: error: variable or field 'buffer2' declared void
>    56 |     void *buffer1, buffer2;
>       |                    ^~~
> audio/dsoundaudio.c: In function 'dsound_get_buffer_out':

I'm sorry, but I can't build and test on Windows.

With best regards,
Volker



[Bug 1823790] Re: QEMU mishandling of SO_PEERSEC forces systemd into tight loop

2020-01-28 Thread Tobias Koch
** Changed in: qemu
   Status: New => Confirmed

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

Title:
  QEMU mishandling of SO_PEERSEC forces systemd into tight loop

Status in QEMU:
  Confirmed

Bug description:
  While building Debian images for embedded ARM target systems I
  detected that QEMU seems to force newer systemd daemons into a tight
  loop.

  My setup is the following:

  Host machine: Ubuntu 18.04, amd64
  LXD container: Debian Buster, arm64, systemd 241
  QEMU: qemu-aarch64-static, 4.0.0-rc2 (custom build) and 3.1.0 (Debian 
1:3.1+dfsg-7)

  To easily reproduce the issue I have created the following repository:
  https://github.com/lueschem/edi-qemu

  The call where systemd gets looping is the following:
  2837 getsockopt(3,1,31,274891889456,274887218756,274888927920) = -1 errno=34 
(Numerical result out of range)

  Furthermore I also verified that the issue is not related to LXD.
  The same behavior can be reproduced using systemd-nspawn.

  This issue reported against systemd seems to be related:
  https://github.com/systemd/systemd/issues/11557

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



Re: [PULL 0/6] MIPS queue for January 28th, 2020

2020-01-28 Thread Philippe Mathieu-Daudé

Hi Peter,

On 1/28/20 9:09 PM, Aleksandar Markovic wrote:

From: Aleksandar Markovic 

The following changes since commit 4c60e3289875ae6c516a37523bcecb87f68ce67c:

   Merge remote-tracking branch 'remotes/rth/tags/pull-pa-20200127' into 
staging (2020-01-28 15:11:04 +)

are available in the git repository at:

   https://github.com/AMarkovic/qemu tags/mips-queue-jan-28-2020

for you to fetch changes up to 370bf3a4196ebef247752a68b89d497522168ebb:

   target/mips: Add implementation of GINVT instruction (2020-01-28 20:52:20 
+0100)



MIPS queue for January 28th, 2020

   A diverse set of fixes and improvements:

 - finalize documentation on deprecating r4k machine
 - enable disassembler to receive target-specific data
 - enable kernel loader to get e_flags from ELF header
 - improve code flow in helper_do_semihosting()
 - amend CP0 WatchHi register implementation
 - add GINVT instruction emulation



Aleksandar Markovic (2):
   target/mips: Rectify documentation on deprecating r4k machine
   disas: Add a field for target-dependant data

Daniel Henrique Barboza (1):
   mips-semi.c: remove 'uhi_done' label in helper_do_semihosting()

Philippe Mathieu-Daudé (1):
   hw/core/loader: Let load_elf() populate the processor-specific flags


Do you mind holding this pull request? I don't feel comfortable being 
listed as the author of this patch. I'll discuss it on the patch thread 
with Aleksandar.




Yongbok Kim (2):
   target/mips: Amend CP0 WatchHi register implementation
   target/mips: Add implementation of GINVT instruction





Re: [PATCH v3 13/14] dp8393x: Don't reset Silicon Revision register

2020-01-28 Thread Philippe Mathieu-Daudé

Hi Finn,

On 1/28/20 11:28 PM, Finn Thain wrote:

On Tue, 28 Jan 2020, Philippe Mathieu-Daud? wrote:

On 1/19/20 11:59 PM, Finn Thain wrote:

The jazzsonic driver in Linux uses the Silicon Revision register value
to probe the chip. The driver fails unless the SR register contains 4.
Unfortunately, reading this register in QEMU usually returns 0 because
the s->regs[] array gets wiped after a software reset.

Fixes: bd8f1ebce4 ("net/dp8393x: fix hardware reset")
Signed-off-by: Finn Thain 
---
   hw/net/dp8393x.c | 5 -
   1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 1b73a8703b..71af0fad51 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -591,6 +591,10 @@ static uint64_t dp8393x_read(void *opaque, hwaddr addr,
unsigned int size)
   val |= s->cam[s->regs[SONIC_CEP] & 0xf][2* (SONIC_CAP0 -
reg)];
   }
   break;
+/* Read-only */
+case SONIC_SR:
+val = 4; /* only revision recognized by Linux/mips */
+break;
   /* All other registers have no special contrainst */
   default:
   val = s->regs[reg];
@@ -971,7 +975,6 @@ static void dp8393x_realize(DeviceState *dev, Error
**errp)
   qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
 s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
-s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
 memory_region_init_ram(>prom, OBJECT(dev),
  "dp8393x-prom", SONIC_PROM_SIZE, _err);



Please fix in dp8393x_reset() instead:

-- >8 --
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index cdc2631c0c..65eb9c23a7 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -862,6 +862,7 @@ static void dp8393x_reset(DeviceState *dev)
  timer_del(s->watchdog);

  memset(s->regs, 0, sizeof(s->regs));
+s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
  s->regs[SONIC_CR] = SONIC_CR_RST | SONIC_CR_STP | SONIC_CR_RXDIS;
  s->regs[SONIC_DCR] &= ~(SONIC_DCR_EXBUS | SONIC_DCR_LBR);
  s->regs[SONIC_RCR] &= ~(SONIC_RCR_LB0 | SONIC_RCR_LB1 | SONIC_RCR_BRD |
SONIC_RCR_RNT);
@@ -914,7 +915,6 @@ static void dp8393x_realize(DeviceState *dev, Error
**errp)
  qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);

  s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
-s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */

  memory_region_init_ram(>prom, OBJECT(dev),
 "dp8393x-prom", SONIC_PROM_SIZE, _err);
---



This would allow the host to change the value of the Silicon Revision
register.

How the guest can modify it? We have:

589 static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data,
590   unsigned int size)
591 {
592 dp8393xState *s = opaque;
593 int reg = addr >> s->it_shift;
594
...
597 switch (reg) {
...
602 /* Prevent write to read-only registers */
...
606 case SONIC_SR:
...
608 DPRINTF("writing to reg %d invalid\n", reg);
609 break;


However, the datasheet says,

 4.3.13 Silicon Revision Register
 This is a 16-bit read only register. It contains information on the
 current revision of the SONIC. The value of the DP83932CVF revision
 register is 6h.

I haven't actually tried storing a different value in this register on
National Semiconductor hardware, but I'm willing to do that test if you
wish.






Re: [PATCH 1/2] ppc/pnv: Add models for POWER9 PHB4 PCIe Host bridge

2020-01-28 Thread David Gibson
On Wed, Jan 29, 2020 at 02:54:19PM +1100, Oliver O'Halloran wrote:
> On Wed, Jan 29, 2020 at 2:09 PM David Gibson
>  wrote:
> >
> > On Mon, Jan 27, 2020 at 03:45:05PM +0100, Cédric Le Goater wrote:
> > > From: Benjamin Herrenschmidt 
> > >
> 
> *snip*
> 
> > > +
> > > +/*
> > > + * The CONFIG_DATA register expects little endian accesses, but as the
> > > + * region is big endian, we have to swap the value.
> > > + */
> > > +static void pnv_phb4_config_write(PnvPHB4 *phb, unsigned off,
> > > +  unsigned size, uint64_t val)
> > > +{
> > > +uint32_t cfg_addr, limit;
> > > +PCIDevice *pdev;
> > > +
> > > +pdev = pnv_phb4_find_cfg_dev(phb);
> > > +if (!pdev) {
> > > +return;
> > > +}
> > > +cfg_addr = (phb->regs[PHB_CONFIG_ADDRESS >> 3] >> 32) & 0xffc;
> > > +cfg_addr |= off;
> > > +limit = pci_config_size(pdev);
> > > +if (limit <= cfg_addr) {
> > > +/*
> > > + * conventional pci device can be behind pcie-to-pci bridge.
> > > + * 256 <= addr < 4K has no effects.
> > > + */
> > > +return;
> > > +}
> > > +switch (size) {
> > > +case 1:
> > > +break;
> > > +case 2:
> > > +val = bswap16(val);
> >
> > I'm a little confused by these byteswaps.  As I see below the device
> > is set to big endian, so the values passed in here should already be
> > in host-native endian.  Why do you need the swap?  Are some of the
> > registers in the bank BE and some LE?
> 
> All the registers are BE except for CONFIG_DATA, which isn't actually
> a register. It's really a window into the config space of the device
> specified in CONFIG_ADDR so it doesn't do any byte-swapping.

Ah, right, that makes sense.

> 
> > > +break;
> > > +case 4:
> > > +val = bswap32(val);
> > > +break;
> > > +default:
> > > +g_assert_not_reached();
> > > +}
> > > +pci_host_config_write_common(pdev, cfg_addr, limit, val, size);
> > > +}
> 

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


signature.asc
Description: PGP signature


Re: [PATCH 0/2] ppc/pnv: Add models for PHB4 and PHB3 PCIe Host bridges

2020-01-28 Thread David Gibson
On Mon, Jan 27, 2020 at 03:45:04PM +0100, Cédric Le Goater wrote:
> Hello,
> 
> These are models for the PCIe Host Bridges, PHB3 and PHB4, as found on
> POWER8 and POWER9 processors. It includes the PowerBus logic interface
> (PBCQ), IOMMU support, a single PCIe Gen.3/4 Root Complex, and support
> for MSI and LSI interrupt sources as found on each system depending on
> the interrupt controller: XICS or XIVE.
> 
> No default device layout is provided and PCI devices can be added on
> any of the available PCIe Root Port (pcie.0 .. 2) with address 0x0 as
> the firwware (skiboot) only accepts a single device per root port. To
> run a simple system with a network and a storage adapters, use a
> command line options such as :
> 
>   -device e1000e,netdev=net0,mac=C0:FF:EE:00:00:02,bus=pcie.0,addr=0x0
>   -netdev 
> bridge,id=net0,helper=/usr/libexec/qemu-bridge-helper,br=virbr0,id=hostnet0
> 
>   -device megasas,id=scsi0,bus=pcie.1,addr=0x0
>   -drive file=$disk,if=none,id=drive-scsi0-0-0-0,format=qcow2,cache=none
>   -device 
> scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=2
> 
> If more are needed, include a bridge.
> 
> Multi chip is supported, each chip adding its set of PHB controllers
> and its PCI busses. The model doesn't emulate the EEH error handling
> and cold plugging PHB devices still needs some work.
> 
> XICS requires some adjustment to support the PHB3 MSI. The changes are
> provided in the PHB3 model but they could be decoupled in prereq
> patches.

Applied to ppc-for-5.0, thanks.

> 
> Thanks,
> 
> C.
> 
> Benjamin Herrenschmidt (1):
>   ppc/pnv: Add models for POWER9 PHB4 PCIe Host bridge
> 
> Cédric Le Goater (1):
>   ppc/pnv: Add models for POWER8 PHB3 PCIe Host bridge
> 
>  include/hw/pci-host/pnv_phb3.h  |  164 +++
>  include/hw/pci-host/pnv_phb3_regs.h |  450 +
>  include/hw/pci-host/pnv_phb4.h  |  230 +
>  include/hw/pci-host/pnv_phb4_regs.h |  553 ++
>  include/hw/pci/pcie_port.h  |1 +
>  include/hw/ppc/pnv.h|   11 +
>  include/hw/ppc/pnv_xscom.h  |   20 +
>  include/hw/ppc/xics.h   |5 +
>  hw/intc/xics.c  |   14 +-
>  hw/pci-host/pnv_phb3.c  | 1195 ++
>  hw/pci-host/pnv_phb3_msi.c  |  349 +++
>  hw/pci-host/pnv_phb3_pbcq.c |  357 +++
>  hw/pci-host/pnv_phb4.c  | 1438 +++
>  hw/pci-host/pnv_phb4_pec.c  |  593 +++
>  hw/ppc/pnv.c|  176 +++-
>  hw/pci-host/Makefile.objs   |2 +
>  hw/ppc/Kconfig  |2 +
>  17 files changed, 5557 insertions(+), 3 deletions(-)
>  create mode 100644 include/hw/pci-host/pnv_phb3.h
>  create mode 100644 include/hw/pci-host/pnv_phb3_regs.h
>  create mode 100644 include/hw/pci-host/pnv_phb4.h
>  create mode 100644 include/hw/pci-host/pnv_phb4_regs.h
>  create mode 100644 hw/pci-host/pnv_phb3.c
>  create mode 100644 hw/pci-host/pnv_phb3_msi.c
>  create mode 100644 hw/pci-host/pnv_phb3_pbcq.c
>  create mode 100644 hw/pci-host/pnv_phb4.c
>  create mode 100644 hw/pci-host/pnv_phb4_pec.c
> 

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


signature.asc
Description: PGP signature


[Bug 1823790] Re: QEMU mishandling of SO_PEERSEC forces systemd into tight loop

2020-01-28 Thread Tobias Koch
I'm a bit surprised that this bug doesn't get more attention, as it
makes it very hard to run qemu-emulated containers of Bionic hosted on
Bionic. Running such containers is a common way to cross-compile
packages for foreign architectures in the absence of sufficiently
powerful target HW.

The documentation on SO_PEERSEC is indeed sparse, but I do want to
second Fritz in his approach. I don't see a reason, why treating the
payload as incorrect and throwing it back at the application is better
than handling it and saying it is not implemented (which is the case).

Arguably, applications should be fixed to handle the error correctly,
but I'm afraid that is a can of worms. I have encountered the same
problem with systemd, apt and getent. Would the maintainers be open to
an SRU request on QEMU for this?

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

Title:
  QEMU mishandling of SO_PEERSEC forces systemd into tight loop

Status in QEMU:
  New

Bug description:
  While building Debian images for embedded ARM target systems I
  detected that QEMU seems to force newer systemd daemons into a tight
  loop.

  My setup is the following:

  Host machine: Ubuntu 18.04, amd64
  LXD container: Debian Buster, arm64, systemd 241
  QEMU: qemu-aarch64-static, 4.0.0-rc2 (custom build) and 3.1.0 (Debian 
1:3.1+dfsg-7)

  To easily reproduce the issue I have created the following repository:
  https://github.com/lueschem/edi-qemu

  The call where systemd gets looping is the following:
  2837 getsockopt(3,1,31,274891889456,274887218756,274888927920) = -1 errno=34 
(Numerical result out of range)

  Furthermore I also verified that the issue is not related to LXD.
  The same behavior can be reproduced using systemd-nspawn.

  This issue reported against systemd seems to be related:
  https://github.com/systemd/systemd/issues/11557

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



Re: [PATCH v2 1/4] monitor: Move monitor option parsing to monitor/monitor.c

2020-01-28 Thread Markus Armbruster
Kevin Wolf  writes:

> Both the system emulators and tools with QMP support (specifically, the
> planned storage daemon) will need to parse monitor options, so move that
> code to monitor/monitor.c, which can be linked into binaries that aren't
> a system emulator.
>
> Signed-off-by: Kevin Wolf 
> Reviewed-by: Markus Armbruster 
> ---
>  include/monitor/monitor.h |  4 
>  include/sysemu/sysemu.h   |  1 -
>  monitor/monitor.c | 48 +++
>  vl.c  | 45 +---
>  4 files changed, 53 insertions(+), 45 deletions(-)
>
> diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
> index a81eeff5f8..ecf6cce827 100644
> --- a/include/monitor/monitor.h
> +++ b/include/monitor/monitor.h
> @@ -3,6 +3,7 @@
>  
>  #include "block/block.h"
>  #include "qapi/qapi-types-misc.h"
> +#include "qemu/option.h"

Superfluous; qemu/typedefs.h already provides what you need.

>  #include "qemu/readline.h"
>  
>  extern __thread Monitor *cur_mon;
> @@ -10,12 +11,15 @@ typedef struct MonitorHMP MonitorHMP;
>  
>  #define QMP_REQ_QUEUE_LEN_MAX 8
>  
> +extern QemuOptsList qemu_mon_opts;
> +
>  bool monitor_cur_is_qmp(void);
>  
>  void monitor_init_globals(void);
>  void monitor_init_globals_core(void);
>  void monitor_init_qmp(Chardev *chr, bool pretty);
>  void monitor_init_hmp(Chardev *chr, bool use_readline);
> +int monitor_init_opts(QemuOpts *opts, Error **errp);
>  void monitor_cleanup(void);
>  
>  int monitor_suspend(Monitor *mon);
[...]

With the superfluous #include dropped:
Reviewed-by: Markus Armbruster 




[PATCH v8 21/21] fuzz: add documentation to docs/devel/

2020-01-28 Thread Bulekov, Alexander
Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
---
 docs/devel/fuzzing.txt | 116 +
 1 file changed, 116 insertions(+)
 create mode 100644 docs/devel/fuzzing.txt

diff --git a/docs/devel/fuzzing.txt b/docs/devel/fuzzing.txt
new file mode 100644
index 00..324d2cd92b
--- /dev/null
+++ b/docs/devel/fuzzing.txt
@@ -0,0 +1,116 @@
+= Fuzzing =
+
+== Introduction ==
+
+This document describes the virtual-device fuzzing infrastructure in QEMU and
+how to use it to implement additional fuzzers.
+
+== Basics ==
+
+Fuzzing operates by passing inputs to an entry point/target function. The
+fuzzer tracks the code coverage triggered by the input. Based on these
+findings, the fuzzer mutates the input and repeats the fuzzing.
+
+To fuzz QEMU, we rely on libfuzzer. Unlike other fuzzers such as AFL, libfuzzer
+is an _in-process_ fuzzer. For the developer, this means that it is their
+responsibility to ensure that state is reset between fuzzing-runs.
+
+== Building the fuzzers ==
+
+NOTE: If possible, build a 32-bit binary. When forking, the 32-bit fuzzer is
+much faster, since the page-map has a smaller size. This is due to the fact 
that
+AddressSanitizer mmaps ~20TB of memory, as part of its detection. This results
+in a large page-map, and a much slower fork().
+
+To build the fuzzers, install a recent version of clang:
+Configure with (substitute the clang binaries with the version you installed):
+
+CC=clang-8 CXX=clang++-8 /path/to/configure --enable-fuzzing
+
+Fuzz targets are built similarly to system/softmmu:
+
+make i386-softmmu/fuzz
+
+This builds ./i386-softmmu/qemu-fuzz-i386
+
+The first option to this command is: --fuzz_taget=FUZZ_NAME
+To list all of the available fuzzers run qemu-fuzz-i386 with no arguments.
+
+eg:
+./i386-softmmu/qemu-fuzz-i386 --fuzz-target=virtio-net-fork-fuzz
+
+Internally, libfuzzer parses all arguments that do not begin with "--".
+Information about these is available by passing -help=1
+
+Now the only thing left to do is wait for the fuzzer to trigger potential
+crashes.
+
+== Adding a new fuzzer ==
+Coverage over virtual devices can be improved by adding additional fuzzers.
+Fuzzers are kept in tests/qtest/fuzz/ and should be added to
+tests/qtest/fuzz/Makefile.include
+
+Fuzzers can rely on both qtest and libqos to communicate with virtual devices.
+
+1. Create a new source file. For example 
``tests/qtest/fuzz/foo-device-fuzz.c``.
+
+2. Write the fuzzing code using the libqtest/libqos API. See existing fuzzers
+for reference.
+
+3. Register the fuzzer in ``tests/fuzz/Makefile.include`` by appending the
+corresponding object to fuzz-obj-y
+
+Fuzzers can be more-or-less thought of as special qtest programs which can
+modify the qtest commands and/or qtest command arguments based on inputs
+provided by libfuzzer. Libfuzzer passes a byte array and length. Commonly the
+fuzzer loops over the byte-array interpreting it as a list of qtest commands,
+addresses, or values.
+
+= Implementation Details =
+
+== The Fuzzer's Lifecycle ==
+
+The fuzzer has two entrypoints that libfuzzer calls. libfuzzer provides it's
+own main(), which performs some setup, and calls the entrypoints:
+
+LLVMFuzzerInitialize: called prior to fuzzing. Used to initialize all of the
+necessary state
+
+LLVMFuzzerTestOneInput: called for each fuzzing run. Processes the input and
+resets the state at the end of each run.
+
+In more detail:
+
+LLVMFuzzerInitialize parses the arguments to the fuzzer (must start with two
+dashes, so they are ignored by libfuzzer main()). Currently, the arguments
+select the fuzz target. Then, the qtest client is initialized. If the target
+requires qos, qgraph is set up and the QOM/LIBQOS modules are initialized.
+Then the QGraph is walked and the QEMU cmd_line is determined and saved.
+
+After this, the vl.c:qemu__main is called to set up the guest. There are
+target-specific hooks that can be called before and after qemu_main, for
+additional setup(e.g. PCI setup, or VM snapshotting).
+
+LLVMFuzzerTestOneInput: Uses qtest/qos functions to act based on the fuzz
+input. It is also responsible for manually calling the main loop/main_loop_wait
+to ensure that bottom halves are executed and any cleanup required before the
+next input.
+
+Since the same process is reused for many fuzzing runs, QEMU state needs to
+be reset at the end of each run. There are currently two implemented
+options for resetting state:
+1. Reboot the guest between runs.
+   Pros: Straightforward and fast for simple fuzz targets.
+   Cons: Depending on the device, does not reset all device state. If the
+   device requires some initialization prior to being ready for fuzzing
+   (common for QOS-based targets), this initialization needs to be done after
+   each reboot.
+   Example target: i440fx-qtest-reboot-fuzz
+2. Run each test case in a separate forked process and copy the coverage
+   information back to the parent. This is fairly 

[PATCH v8 20/21] fuzz: add virtio-scsi fuzz target

2020-01-28 Thread Bulekov, Alexander
The virtio-scsi fuzz target sets up and fuzzes the available virtio-scsi
queues. After an element is placed on a queue, the fuzzer can select
whether to perform a kick, or continue adding elements.

Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
---
 tests/qtest/fuzz/Makefile.include   |   1 +
 tests/qtest/fuzz/virtio_scsi_fuzz.c | 200 
 2 files changed, 201 insertions(+)
 create mode 100644 tests/qtest/fuzz/virtio_scsi_fuzz.c

diff --git a/tests/qtest/fuzz/Makefile.include 
b/tests/qtest/fuzz/Makefile.include
index 77385777ef..cde3e9636c 100644
--- a/tests/qtest/fuzz/Makefile.include
+++ b/tests/qtest/fuzz/Makefile.include
@@ -9,6 +9,7 @@ fuzz-obj-y += tests/qtest/fuzz/qos_fuzz.o
 # Targets
 fuzz-obj-y += tests/qtest/fuzz/i440fx_fuzz.o
 fuzz-obj-y += tests/qtest/fuzz/virtio_net_fuzz.o
+fuzz-obj-y += tests/qtest/fuzz/virtio_scsi_fuzz.o
 
 FUZZ_CFLAGS += -I$(SRC_PATH)/tests -I$(SRC_PATH)/tests/qtest
 
diff --git a/tests/qtest/fuzz/virtio_scsi_fuzz.c 
b/tests/qtest/fuzz/virtio_scsi_fuzz.c
new file mode 100644
index 00..ee7ca5448c
--- /dev/null
+++ b/tests/qtest/fuzz/virtio_scsi_fuzz.c
@@ -0,0 +1,200 @@
+/*
+ * virtio-serial Fuzzing Target
+ *
+ * Copyright Red Hat Inc., 2019
+ *
+ * Authors:
+ *  Alexander Bulekov   
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "tests/qtest/libqtest.h"
+#include "tests/qtest/libqos/virtio-net.h"
+#include "libqos/virtio-scsi.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_pci.h"
+#include "standard-headers/linux/virtio_scsi.h"
+#include "fuzz.h"
+#include "fork_fuzz.h"
+#include "qos_fuzz.h"
+
+#define PCI_SLOT0x02
+#define PCI_FN  0x00
+#define QVIRTIO_SCSI_TIMEOUT_US (1 * 1000 * 1000)
+
+#define MAX_NUM_QUEUES 64
+
+/* Based on tests/virtio-scsi-test.c */
+typedef struct {
+int num_queues;
+QVirtQueue *vq[MAX_NUM_QUEUES + 2];
+} QVirtioSCSIQueues;
+
+static QVirtioSCSIQueues *qvirtio_scsi_init(QVirtioDevice *dev, uint64_t mask)
+{
+QVirtioSCSIQueues *vs;
+uint64_t feat;
+int i;
+
+vs = g_new0(QVirtioSCSIQueues, 1);
+
+feat = qvirtio_get_features(dev);
+if (mask) {
+feat &= ~QVIRTIO_F_BAD_FEATURE | mask;
+} else {
+feat &= ~(QVIRTIO_F_BAD_FEATURE | (1ull << VIRTIO_RING_F_EVENT_IDX));
+}
+qvirtio_set_features(dev, feat);
+
+vs->num_queues = qvirtio_config_readl(dev, 0);
+
+for (i = 0; i < vs->num_queues + 2; i++) {
+vs->vq[i] = qvirtqueue_setup(dev, fuzz_qos_alloc, i);
+}
+
+qvirtio_set_driver_ok(dev);
+
+return vs;
+}
+
+static void virtio_scsi_fuzz(QTestState *s, QVirtioSCSIQueues* queues,
+const unsigned char *Data, size_t Size)
+{
+typedef struct vq_action {
+uint8_t queue;
+uint8_t length;
+uint8_t write;
+uint8_t next;
+uint8_t kick;
+} vq_action;
+
+uint32_t free_head[MAX_NUM_QUEUES + 2] = {0};
+QGuestAllocator *t_alloc = fuzz_qos_alloc;
+
+QVirtioSCSI *scsi = fuzz_qos_obj;
+QVirtioDevice *dev = scsi->vdev;
+QVirtQueue *q;
+vq_action vqa;
+while (Size >= sizeof(vqa)) {
+memcpy(, Data, sizeof(vqa));
+
+Data += sizeof(vqa);
+Size -= sizeof(vqa);
+
+vqa.queue = vqa.queue % queues->num_queues;
+vqa.length = vqa.length >= Size ? Size : vqa.length;
+vqa.write = vqa.write & 1;
+vqa.next = vqa.next & 1;
+vqa.kick = vqa.kick & 1;
+
+
+q = queues->vq[vqa.queue];
+
+uint64_t req_addr = guest_alloc(t_alloc, vqa.length);
+qtest_memwrite(s, req_addr, Data, vqa.length);
+if (free_head[vqa.queue] == 0) {
+free_head[vqa.queue] = qvirtqueue_add(s, q, req_addr, vqa.length,
+vqa.write, vqa.next);
+} else {
+qvirtqueue_add(s, q, req_addr, vqa.length, vqa.write , vqa.next);
+}
+
+if (vqa.kick) {
+qvirtqueue_kick(s, dev, q, free_head[vqa.queue]);
+free_head[vqa.queue] = 0;
+}
+Data += vqa.length;
+Size -= vqa.length;
+}
+for (int i = 0; i < MAX_NUM_QUEUES + 2; i++) {
+if (free_head[i]) {
+qvirtqueue_kick(s, dev, queues->vq[i], free_head[i]);
+}
+}
+}
+
+static void virtio_scsi_fork_fuzz(QTestState *s,
+const unsigned char *Data, size_t Size)
+{
+QVirtioSCSI *scsi = fuzz_qos_obj;
+static QVirtioSCSIQueues *queues;
+if (!queues) {
+queues = qvirtio_scsi_init(scsi->vdev, 0);
+}
+if (fork() == 0) {
+virtio_scsi_fuzz(s, queues, Data, Size);
+flush_events(s);
+_Exit(0);
+} else {
+wait(NULL);
+}
+}
+
+static void virtio_scsi_with_flag_fuzz(QTestState *s,
+const unsigned char 

[PATCH v8 14/21] fuzz: support for fork-based fuzzing.

2020-01-28 Thread Bulekov, Alexander
fork() is a simple way to ensure that state does not leak in between
fuzzing runs. Unfortunately, the fuzzer mutation engine relies on
bitmaps which contain coverage information for each fuzzing run, and
these bitmaps should be copied from the child to the parent(where the
mutation occurs). These bitmaps are created through compile-time
instrumentation and they are not shared with fork()-ed processes, by
default. To address this, we create a shared memory region, adjust its
size and map it _over_ the counter region. Furthermore, libfuzzer
doesn't generally expose the globals that specify the location of the
counters/coverage bitmap. As a workaround, we rely on a custom linker
script which forces all of the bitmaps we care about to be placed in a
contiguous region, which is easy to locate and mmap over.

Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
---
 tests/qtest/fuzz/Makefile.include |  5 +++
 tests/qtest/fuzz/fork_fuzz.c  | 55 +++
 tests/qtest/fuzz/fork_fuzz.h  | 23 +
 tests/qtest/fuzz/fork_fuzz.ld | 37 +
 4 files changed, 120 insertions(+)
 create mode 100644 tests/qtest/fuzz/fork_fuzz.c
 create mode 100644 tests/qtest/fuzz/fork_fuzz.h
 create mode 100644 tests/qtest/fuzz/fork_fuzz.ld

diff --git a/tests/qtest/fuzz/Makefile.include 
b/tests/qtest/fuzz/Makefile.include
index 8632bb89f4..a90915d56d 100644
--- a/tests/qtest/fuzz/Makefile.include
+++ b/tests/qtest/fuzz/Makefile.include
@@ -2,5 +2,10 @@ QEMU_PROG_FUZZ=qemu-fuzz-$(TARGET_NAME)$(EXESUF)
 
 fuzz-obj-y += tests/qtest/libqtest.o
 fuzz-obj-y += tests/qtest/fuzz/fuzz.o # Fuzzer skeleton
+fuzz-obj-y += tests/qtest/fuzz/fork_fuzz.o
 
 FUZZ_CFLAGS += -I$(SRC_PATH)/tests -I$(SRC_PATH)/tests/qtest
+
+# Linker Script to force coverage-counters into known regions which we can mark
+# shared
+FUZZ_LDFLAGS += -Xlinker -T$(SRC_PATH)/tests/qtest/fuzz/fork_fuzz.ld
diff --git a/tests/qtest/fuzz/fork_fuzz.c b/tests/qtest/fuzz/fork_fuzz.c
new file mode 100644
index 00..2bd0851903
--- /dev/null
+++ b/tests/qtest/fuzz/fork_fuzz.c
@@ -0,0 +1,55 @@
+/*
+ * Fork-based fuzzing helpers
+ *
+ * Copyright Red Hat Inc., 2019
+ *
+ * Authors:
+ *  Alexander Bulekov   
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "fork_fuzz.h"
+
+
+void counter_shm_init(void)
+{
+char *shm_path = g_strdup_printf("/qemu-fuzz-cntrs.%d", getpid());
+int fd = shm_open(shm_path, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+g_free(shm_path);
+
+if (fd == -1) {
+perror("Error: ");
+exit(1);
+}
+if (ftruncate(fd, &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START) == -1) {
+perror("Error: ");
+exit(1);
+}
+/* Copy what's in the counter region to the shm.. */
+void *rptr = mmap(NULL ,
+&__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START,
+PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+memcpy(rptr,
+   &__FUZZ_COUNTERS_START,
+   &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START);
+
+munmap(rptr, &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START);
+
+/* And map the shm over the counter region */
+rptr = mmap(&__FUZZ_COUNTERS_START,
+&__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START,
+PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
+
+close(fd);
+
+if (!rptr) {
+perror("Error: ");
+exit(1);
+}
+}
+
+
diff --git a/tests/qtest/fuzz/fork_fuzz.h b/tests/qtest/fuzz/fork_fuzz.h
new file mode 100644
index 00..9ecb8b58ef
--- /dev/null
+++ b/tests/qtest/fuzz/fork_fuzz.h
@@ -0,0 +1,23 @@
+/*
+ * Fork-based fuzzing helpers
+ *
+ * Copyright Red Hat Inc., 2019
+ *
+ * Authors:
+ *  Alexander Bulekov   
+ *
+ * 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 FORK_FUZZ_H
+#define FORK_FUZZ_H
+
+extern uint8_t __FUZZ_COUNTERS_START;
+extern uint8_t __FUZZ_COUNTERS_END;
+
+void counter_shm_init(void);
+
+#endif
+
diff --git a/tests/qtest/fuzz/fork_fuzz.ld b/tests/qtest/fuzz/fork_fuzz.ld
new file mode 100644
index 00..b23a59f194
--- /dev/null
+++ b/tests/qtest/fuzz/fork_fuzz.ld
@@ -0,0 +1,37 @@
+/* We adjust linker script modification to place all of the stuff that needs to
+ * persist across fuzzing runs into a contiguous seciton of memory. Then, it is
+ * easy to re-map the counter-related memory as shared.
+*/
+
+SECTIONS
+{
+  .data.fuzz_start : ALIGN(4K)
+  {
+  __FUZZ_COUNTERS_START = .;
+  __start___sancov_cntrs = .;
+  *(_*sancov_cntrs);
+  __stop___sancov_cntrs = .;
+
+  /* Lowest stack counter */
+  *(__sancov_lowest_stack);
+  }
+  .data.fuzz_ordered :
+  {
+  /* Coverage counters. They're not necessary for fuzzing, but are useful
+   * for analyzing the fuzzing performance
+   

[PATCH v8 12/21] exec: keep ram block across fork when using qtest

2020-01-28 Thread Bulekov, Alexander
Ram blocks were marked MADV_DONTFORK breaking fuzzing-tests which
execute each test-input in a forked process.

Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
---
 exec.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index d4b769d0d4..99368f175b 100644
--- a/exec.c
+++ b/exec.c
@@ -35,6 +35,7 @@
 #include "sysemu/kvm.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/tcg.h"
+#include "sysemu/qtest.h"
 #include "qemu/timer.h"
 #include "qemu/config-file.h"
 #include "qemu/error-report.h"
@@ -2306,8 +2307,15 @@ static void ram_block_add(RAMBlock *new_block, Error 
**errp, bool shared)
 if (new_block->host) {
 qemu_ram_setup_dump(new_block->host, new_block->max_length);
 qemu_madvise(new_block->host, new_block->max_length, 
QEMU_MADV_HUGEPAGE);
-/* MADV_DONTFORK is also needed by KVM in absence of synchronous MMU */
-qemu_madvise(new_block->host, new_block->max_length, 
QEMU_MADV_DONTFORK);
+/*
+ * MADV_DONTFORK is also needed by KVM in absence of synchronous MMU
+ * Configure it unless the machine is a qtest server, in which case
+ * KVM is not used and it may be forked (eg for fuzzing purposes).
+ */
+if (!qtest_enabled()) {
+qemu_madvise(new_block->host, new_block->max_length,
+ QEMU_MADV_DONTFORK);
+}
 ram_block_notify_add(new_block->host, new_block->max_length);
 }
 }
-- 
2.23.0




[PATCH v8 18/21] fuzz: add i440fx fuzz targets

2020-01-28 Thread Bulekov, Alexander
These three targets should simply fuzz reads/writes to a couple ioports,
but they mostly serve as examples of different ways to write targets.
They demonstrate using qtest and qos for fuzzing, as well as using
rebooting and forking to reset state, or not resetting it at all.

Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
---
 tests/qtest/fuzz/Makefile.include |   3 +
 tests/qtest/fuzz/i440fx_fuzz.c| 178 ++
 2 files changed, 181 insertions(+)
 create mode 100644 tests/qtest/fuzz/i440fx_fuzz.c

diff --git a/tests/qtest/fuzz/Makefile.include 
b/tests/qtest/fuzz/Makefile.include
index e3bdd33ff4..38b8cdd9f1 100644
--- a/tests/qtest/fuzz/Makefile.include
+++ b/tests/qtest/fuzz/Makefile.include
@@ -6,6 +6,9 @@ fuzz-obj-y += tests/qtest/fuzz/fuzz.o # Fuzzer skeleton
 fuzz-obj-y += tests/qtest/fuzz/fork_fuzz.o
 fuzz-obj-y += tests/qtest/fuzz/qos_fuzz.o
 
+# Targets
+fuzz-obj-y += tests/qtest/fuzz/i440fx_fuzz.o
+
 FUZZ_CFLAGS += -I$(SRC_PATH)/tests -I$(SRC_PATH)/tests/qtest
 
 # Linker Script to force coverage-counters into known regions which we can mark
diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c
new file mode 100644
index 00..c7791182b8
--- /dev/null
+++ b/tests/qtest/fuzz/i440fx_fuzz.c
@@ -0,0 +1,178 @@
+/*
+ * I440FX Fuzzing Target
+ *
+ * Copyright Red Hat Inc., 2019
+ *
+ * Authors:
+ *  Alexander Bulekov   
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qemu/main-loop.h"
+#include "tests/qtest/libqtest.h"
+#include "tests/qtest/libqos/pci.h"
+#include "tests/qtest/libqos/pci-pc.h"
+#include "fuzz.h"
+#include "fuzz/qos_fuzz.h"
+#include "fuzz/fork_fuzz.h"
+
+
+#define I440FX_PCI_HOST_BRIDGE_CFG 0xcf8
+#define I440FX_PCI_HOST_BRIDGE_DATA 0xcfc
+
+enum action_id {
+WRITEB,
+WRITEW,
+WRITEL,
+READB,
+READW,
+READL,
+ACTION_MAX
+};
+
+static void i440fx_fuzz_qtest(QTestState *s,
+const unsigned char *Data, size_t Size) {
+typedef struct QTestFuzzAction {
+uint32_t value;
+uint8_t id;
+uint8_t addr;
+} QTestFuzzAction;
+QTestFuzzAction a;
+
+while (Size >= sizeof(a)) {
+memcpy(, Data, sizeof(a));
+uint16_t addr = a.addr % 2 ? I440FX_PCI_HOST_BRIDGE_CFG :
+  I440FX_PCI_HOST_BRIDGE_DATA;
+switch (a.id % ACTION_MAX) {
+case WRITEB:
+qtest_outb(s, addr, (uint8_t)a.value);
+break;
+case WRITEW:
+qtest_outw(s, addr, (uint16_t)a.value);
+break;
+case WRITEL:
+qtest_outl(s, addr, (uint32_t)a.value);
+break;
+case READB:
+qtest_inb(s, addr);
+break;
+case READW:
+qtest_inw(s, addr);
+break;
+case READL:
+qtest_inl(s, addr);
+break;
+}
+Size -= sizeof(a);
+Data += sizeof(a);
+}
+flush_events(s);
+}
+
+static void i440fx_fuzz_qos(QTestState *s,
+const unsigned char *Data, size_t Size) {
+
+typedef struct QOSFuzzAction {
+uint32_t value;
+int devfn;
+uint8_t offset;
+uint8_t id;
+} QOSFuzzAction;
+
+static QPCIBus *bus;
+if (!bus) {
+bus = qpci_new_pc(s, fuzz_qos_alloc);
+}
+
+QOSFuzzAction a;
+while (Size >= sizeof(a)) {
+memcpy(, Data, sizeof(a));
+switch (a.id % ACTION_MAX) {
+case WRITEB:
+bus->config_writeb(bus, a.devfn, a.offset, (uint8_t)a.value);
+break;
+case WRITEW:
+bus->config_writew(bus, a.devfn, a.offset, (uint16_t)a.value);
+break;
+case WRITEL:
+bus->config_writel(bus, a.devfn, a.offset, (uint32_t)a.value);
+break;
+case READB:
+bus->config_readb(bus, a.devfn, a.offset);
+break;
+case READW:
+bus->config_readw(bus, a.devfn, a.offset);
+break;
+case READL:
+bus->config_readl(bus, a.devfn, a.offset);
+break;
+}
+Size -= sizeof(a);
+Data += sizeof(a);
+}
+flush_events(s);
+}
+
+static void i440fx_fuzz_qos_fork(QTestState *s,
+const unsigned char *Data, size_t Size) {
+if (fork() == 0) {
+i440fx_fuzz_qos(s, Data, Size);
+_Exit(0);
+} else {
+wait(NULL);
+}
+}
+
+static const char *i440fx_qtest_argv = TARGET_NAME " -machine accel=qtest"
+   "-m 0 -display none";
+static const char *i440fx_argv(FuzzTarget *t)
+{
+return i440fx_qtest_argv;
+}
+
+static void fork_init(void)
+{
+counter_shm_init();
+}
+
+static void register_pci_fuzz_targets(void)
+{
+/* Uses simple qtest commands and reboots to reset state */
+

[PATCH v8 15/21] fuzz: add support for qos-assisted fuzz targets

2020-01-28 Thread Bulekov, Alexander
Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
---
 tests/qtest/fuzz/Makefile.include |   2 +
 tests/qtest/fuzz/qos_fuzz.c   | 229 ++
 tests/qtest/fuzz/qos_fuzz.h   |  33 +
 3 files changed, 264 insertions(+)
 create mode 100644 tests/qtest/fuzz/qos_fuzz.c
 create mode 100644 tests/qtest/fuzz/qos_fuzz.h

diff --git a/tests/qtest/fuzz/Makefile.include 
b/tests/qtest/fuzz/Makefile.include
index a90915d56d..e3bdd33ff4 100644
--- a/tests/qtest/fuzz/Makefile.include
+++ b/tests/qtest/fuzz/Makefile.include
@@ -1,8 +1,10 @@
 QEMU_PROG_FUZZ=qemu-fuzz-$(TARGET_NAME)$(EXESUF)
 
 fuzz-obj-y += tests/qtest/libqtest.o
+fuzz-obj-y += $(libqos-obj-y)
 fuzz-obj-y += tests/qtest/fuzz/fuzz.o # Fuzzer skeleton
 fuzz-obj-y += tests/qtest/fuzz/fork_fuzz.o
+fuzz-obj-y += tests/qtest/fuzz/qos_fuzz.o
 
 FUZZ_CFLAGS += -I$(SRC_PATH)/tests -I$(SRC_PATH)/tests/qtest
 
diff --git a/tests/qtest/fuzz/qos_fuzz.c b/tests/qtest/fuzz/qos_fuzz.c
new file mode 100644
index 00..efdcc6e9d3
--- /dev/null
+++ b/tests/qtest/fuzz/qos_fuzz.c
@@ -0,0 +1,229 @@
+/*
+ * QOS-assisted fuzzing helpers
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
+#include "qemu/main-loop.h"
+
+#include "tests/qtest/libqtest.h"
+#include "tests/qtest/libqos/malloc.h"
+#include "tests/qtest/libqos/qgraph.h"
+#include "tests/qtest/libqos/qgraph_internal.h"
+#include "tests/qtest/libqos/qos_external.h"
+
+#include "fuzz.h"
+#include "qos_fuzz.h"
+
+#include "qapi/qapi-commands-machine.h"
+#include "qapi/qapi-commands-qom.h"
+#include "qapi/qmp/qlist.h"
+
+
+void *fuzz_qos_obj;
+QGuestAllocator *fuzz_qos_alloc;
+
+static const char *fuzz_target_name;
+static char **fuzz_path_vec;
+
+/*
+ * Replaced the qmp commands with direct qmp_marshal calls.
+ * Probably there is a better way to do this
+ */
+static void qos_set_machines_devices_available(void)
+{
+QDict *req = qdict_new();
+QObject *response;
+QDict *args = qdict_new();
+QList *lst;
+Error *err = NULL;
+
+qmp_marshal_query_machines(NULL, , );
+assert(!err);
+lst = qobject_to(QList, response);
+apply_to_qlist(lst, true);
+
+qobject_unref(response);
+
+
+qdict_put_str(req, "execute", "qom-list-types");
+qdict_put_str(args, "implements", "device");
+qdict_put_bool(args, "abstract", true);
+qdict_put_obj(req, "arguments", (QObject *) args);
+
+qmp_marshal_qom_list_types(args, , );
+assert(!err);
+lst = qobject_to(QList, response);
+apply_to_qlist(lst, false);
+qobject_unref(response);
+qobject_unref(req);
+}
+
+static char **current_path;
+
+void *qos_allocate_objects(QTestState *qts, QGuestAllocator **p_alloc)
+{
+return allocate_objects(qts, current_path + 1, p_alloc);
+}
+
+static const char *qos_build_main_args(void)
+{
+char **path = fuzz_path_vec;
+QOSGraphNode *test_node;
+GString *cmd_line = g_string_new(path[0]);
+void *test_arg;
+
+/* Before test */
+current_path = path;
+test_node = qos_graph_get_node(path[(g_strv_length(path) - 1)]);
+test_arg = test_node->u.test.arg;
+if (test_node->u.test.before) {
+test_arg = test_node->u.test.before(cmd_line, test_arg);
+}
+/* Prepend the arguments that we need */
+g_string_prepend(cmd_line,
+TARGET_NAME " -display none -machine accel=qtest -m 64 ");
+return cmd_line->str;
+}
+
+/*
+ * This function is largely a copy of qos-test.c:walk_path. Since walk_path
+ * is itself a callback, its a little annoying to add another argument/layer of
+ * indirection
+ */
+static void walk_path(QOSGraphNode *orig_path, int len)
+{
+QOSGraphNode *path;
+QOSGraphEdge *edge;
+
+/* etype set to QEDGE_CONSUMED_BY so that machine can add to the command 
line */
+QOSEdgeType etype = QEDGE_CONSUMED_BY;
+
+/* twice QOS_PATH_MAX_ELEMENT_SIZE since each edge can have its arg */
+char **path_vec = g_new0(char *, (QOS_PATH_MAX_ELEMENT_SIZE * 2));
+int path_vec_size = 0;
+
+char *after_cmd, *before_cmd, *after_device;
+GString *after_device_str = g_string_new("");
+char *node_name = orig_path->name, *path_str;
+
+GString *cmd_line = 

[PATCH v8 19/21] fuzz: add virtio-net fuzz target

2020-01-28 Thread Bulekov, Alexander
The virtio-net fuzz target feeds inputs to all three virtio-net
virtqueues, and uses forking to avoid leaking state between fuzz runs.

Signed-off-by: Alexander Bulekov 
---
 tests/qtest/fuzz/Makefile.include  |   1 +
 tests/qtest/fuzz/virtio_net_fuzz.c | 195 +
 2 files changed, 196 insertions(+)
 create mode 100644 tests/qtest/fuzz/virtio_net_fuzz.c

diff --git a/tests/qtest/fuzz/Makefile.include 
b/tests/qtest/fuzz/Makefile.include
index 38b8cdd9f1..77385777ef 100644
--- a/tests/qtest/fuzz/Makefile.include
+++ b/tests/qtest/fuzz/Makefile.include
@@ -8,6 +8,7 @@ fuzz-obj-y += tests/qtest/fuzz/qos_fuzz.o
 
 # Targets
 fuzz-obj-y += tests/qtest/fuzz/i440fx_fuzz.o
+fuzz-obj-y += tests/qtest/fuzz/virtio_net_fuzz.o
 
 FUZZ_CFLAGS += -I$(SRC_PATH)/tests -I$(SRC_PATH)/tests/qtest
 
diff --git a/tests/qtest/fuzz/virtio_net_fuzz.c 
b/tests/qtest/fuzz/virtio_net_fuzz.c
new file mode 100644
index 00..e4e3e50865
--- /dev/null
+++ b/tests/qtest/fuzz/virtio_net_fuzz.c
@@ -0,0 +1,195 @@
+/*
+ * virtio-net Fuzzing Target
+ *
+ * Copyright Red Hat Inc., 2019
+ *
+ * Authors:
+ *  Alexander Bulekov   
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "standard-headers/linux/virtio_config.h"
+#include "tests/qtest/libqtest.h"
+#include "tests/qtest/libqos/virtio-net.h"
+#include "fuzz.h"
+#include "fork_fuzz.h"
+#include "qos_fuzz.h"
+
+
+#define QVIRTIO_NET_TIMEOUT_US (30 * 1000 * 1000)
+#define QVIRTIO_RX_VQ 0
+#define QVIRTIO_TX_VQ 1
+#define QVIRTIO_CTRL_VQ 2
+
+static int sockfds[2];
+static bool sockfds_initialized;
+
+static void virtio_net_fuzz_multi(QTestState *s,
+const unsigned char *Data, size_t Size, bool check_used)
+{
+typedef struct vq_action {
+uint8_t queue;
+uint8_t length;
+uint8_t write;
+uint8_t next;
+uint8_t rx;
+} vq_action;
+
+uint32_t free_head = 0;
+
+QGuestAllocator *t_alloc = fuzz_qos_alloc;
+
+QVirtioNet *net_if = fuzz_qos_obj;
+QVirtioDevice *dev = net_if->vdev;
+QVirtQueue *q;
+vq_action vqa;
+while (Size >= sizeof(vqa)) {
+memcpy(, Data, sizeof(vqa));
+Data += sizeof(vqa);
+Size -= sizeof(vqa);
+
+q = net_if->queues[vqa.queue % 3];
+
+vqa.length = vqa.length >= Size ? Size :  vqa.length;
+
+/*
+ * Only attempt to write incoming packets, when using the socket
+ * backend. Otherwise, always place the input on a virtqueue.
+ */
+if (vqa.rx && sockfds_initialized) {
+write(sockfds[0], Data, vqa.length);
+} else {
+vqa.rx = 0;
+uint64_t req_addr = guest_alloc(t_alloc, vqa.length);
+/*
+ * If checking used ring, ensure that the fuzzer doesn't trigger
+ * trivial asserion failure on zero-zied buffer
+ */
+qtest_memwrite(s, req_addr, Data, vqa.length);
+
+
+free_head = qvirtqueue_add(s, q, req_addr, vqa.length,
+vqa.write, vqa.next);
+qvirtqueue_add(s, q, req_addr, vqa.length, vqa.write , vqa.next);
+qvirtqueue_kick(s, dev, q, free_head);
+}
+
+/*
+ * normally, we could just use qvirtio_wait_used_elem, but since we
+ * must manually run the main-loop for all the bhs to run, we use
+ * this hack with flush_events(), to run the main_loop
+ */
+gint64 start_time = g_get_monotonic_time();
+for (;;) {
+/* Run the main loop */
+qtest_clock_step(s, 100);
+flush_events(s);
+/* Poll the used vring only if we added to the TX or CTRL vq */
+if (check_used && !vqa.rx && q != net_if->queues[QVIRTIO_RX_VQ]) {
+uint32_t got_desc_idx;
+/* Input led to a virtio_error */
+if (dev->bus->get_status(dev) & VIRTIO_CONFIG_S_NEEDS_RESET) {
+break;
+}
+if (dev->bus->get_queue_isr_status(dev, q) &&
+qvirtqueue_get_buf(s, q, _desc_idx, NULL)) {
+g_assert_cmpint(got_desc_idx, ==, free_head);
+break;
+}
+g_assert(g_get_monotonic_time() - start_time
+ <= QVIRTIO_NET_TIMEOUT_US);
+} else {
+break;
+}
+}
+Data += vqa.length;
+Size -= vqa.length;
+}
+}
+
+static void virtio_net_fork_fuzz(QTestState *s,
+const unsigned char *Data, size_t Size)
+{
+if (fork() == 0) {
+virtio_net_fuzz_multi(s, Data, Size, false);
+flush_events(s);
+_Exit(0);
+} else {
+wait(NULL);
+}
+}
+
+static void virtio_net_fork_fuzz_check_used(QTestState *s,
+const unsigned char *Data, size_t Size)
+{
+if (fork() 

[PATCH v8 08/21] libqos: rename i2c_send and i2c_recv

2020-01-28 Thread Bulekov, Alexander
The names i2c_send and i2c_recv collide with functions defined in
hw/i2c/core.c. This causes an error when linking against libqos and
softmmu simultaneously (for example when using qtest inproc). Rename the
libqos functions to avoid this.

Signed-off-by: Alexander Bulekov 
Acked-by: Thomas Huth 
Reviewed-by: Stefan Hajnoczi 
---
 tests/qtest/libqos/i2c.c   | 10 +-
 tests/qtest/libqos/i2c.h   |  4 ++--
 tests/qtest/pca9552-test.c | 10 +-
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/tests/qtest/libqos/i2c.c b/tests/qtest/libqos/i2c.c
index 156114e745..38f800dbab 100644
--- a/tests/qtest/libqos/i2c.c
+++ b/tests/qtest/libqos/i2c.c
@@ -10,12 +10,12 @@
 #include "libqos/i2c.h"
 #include "libqtest.h"
 
-void i2c_send(QI2CDevice *i2cdev, const uint8_t *buf, uint16_t len)
+void qi2c_send(QI2CDevice *i2cdev, const uint8_t *buf, uint16_t len)
 {
 i2cdev->bus->send(i2cdev->bus, i2cdev->addr, buf, len);
 }
 
-void i2c_recv(QI2CDevice *i2cdev, uint8_t *buf, uint16_t len)
+void qi2c_recv(QI2CDevice *i2cdev, uint8_t *buf, uint16_t len)
 {
 i2cdev->bus->recv(i2cdev->bus, i2cdev->addr, buf, len);
 }
@@ -23,8 +23,8 @@ void i2c_recv(QI2CDevice *i2cdev, uint8_t *buf, uint16_t len)
 void i2c_read_block(QI2CDevice *i2cdev, uint8_t reg,
 uint8_t *buf, uint16_t len)
 {
-i2c_send(i2cdev, , 1);
-i2c_recv(i2cdev, buf, len);
+qi2c_send(i2cdev, , 1);
+qi2c_recv(i2cdev, buf, len);
 }
 
 void i2c_write_block(QI2CDevice *i2cdev, uint8_t reg,
@@ -33,7 +33,7 @@ void i2c_write_block(QI2CDevice *i2cdev, uint8_t reg,
 uint8_t *cmd = g_malloc(len + 1);
 cmd[0] = reg;
 memcpy([1], buf, len);
-i2c_send(i2cdev, cmd, len + 1);
+qi2c_send(i2cdev, cmd, len + 1);
 g_free(cmd);
 }
 
diff --git a/tests/qtest/libqos/i2c.h b/tests/qtest/libqos/i2c.h
index 945b65b34c..c65f087834 100644
--- a/tests/qtest/libqos/i2c.h
+++ b/tests/qtest/libqos/i2c.h
@@ -47,8 +47,8 @@ struct QI2CDevice {
 void *i2c_device_create(void *i2c_bus, QGuestAllocator *alloc, void *addr);
 void add_qi2c_address(QOSGraphEdgeOptions *opts, QI2CAddress *addr);
 
-void i2c_send(QI2CDevice *dev, const uint8_t *buf, uint16_t len);
-void i2c_recv(QI2CDevice *dev, uint8_t *buf, uint16_t len);
+void qi2c_send(QI2CDevice *dev, const uint8_t *buf, uint16_t len);
+void qi2c_recv(QI2CDevice *dev, uint8_t *buf, uint16_t len);
 
 void i2c_read_block(QI2CDevice *dev, uint8_t reg,
 uint8_t *buf, uint16_t len);
diff --git a/tests/qtest/pca9552-test.c b/tests/qtest/pca9552-test.c
index 4b800d3c3e..d80ed93cd3 100644
--- a/tests/qtest/pca9552-test.c
+++ b/tests/qtest/pca9552-test.c
@@ -32,22 +32,22 @@ static void receive_autoinc(void *obj, void *data, 
QGuestAllocator *alloc)
 
 pca9552_init(i2cdev);
 
-i2c_send(i2cdev, , 1);
+qi2c_send(i2cdev, , 1);
 
 /* PCA9552_LS0 */
-i2c_recv(i2cdev, , 1);
+qi2c_recv(i2cdev, , 1);
 g_assert_cmphex(resp, ==, 0x54);
 
 /* PCA9552_LS1 */
-i2c_recv(i2cdev, , 1);
+qi2c_recv(i2cdev, , 1);
 g_assert_cmphex(resp, ==, 0x55);
 
 /* PCA9552_LS2 */
-i2c_recv(i2cdev, , 1);
+qi2c_recv(i2cdev, , 1);
 g_assert_cmphex(resp, ==, 0x55);
 
 /* PCA9552_LS3 */
-i2c_recv(i2cdev, , 1);
+qi2c_recv(i2cdev, , 1);
 g_assert_cmphex(resp, ==, 0x54);
 }
 
-- 
2.23.0




[PATCH v8 17/21] fuzz: add configure flag --enable-fuzzing

2020-01-28 Thread Bulekov, Alexander
Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Philippe Mathieu-Daudé 
---
 configure | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/configure b/configure
index 08c3a1c1f0..1a1e57eb61 100755
--- a/configure
+++ b/configure
@@ -504,6 +504,7 @@ debug_mutex="no"
 libpmem=""
 default_devices="yes"
 plugins="no"
+fuzzing="no"
 
 supported_cpu="no"
 supported_os="no"
@@ -634,6 +635,15 @@ int main(void) { return 0; }
 EOF
 }
 
+write_c_fuzzer_skeleton() {
+cat > $TMPC <
+#include 
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
+EOF
+}
+
 if check_define __linux__ ; then
   targetos="Linux"
 elif check_define _WIN32 ; then
@@ -1540,6 +1550,10 @@ for opt do
   ;;
   --disable-containers) use_containers="no"
   ;;
+  --enable-fuzzing) fuzzing=yes
+  ;;
+  --disable-fuzzing) fuzzing=no
+  ;;
   *)
   echo "ERROR: unknown option $opt"
   echo "Try '$0 --help' for more information"
@@ -5992,6 +6006,15 @@ EOF
   fi
 fi
 
+##
+# checks for fuzzer
+if test "$fuzzing" = "yes" ; then
+  write_c_fuzzer_skeleton
+  if compile_prog "$CPU_CFLAGS -Werror -fsanitize=address,fuzzer" ""; then
+  have_fuzzer=yes
+  fi
+fi
+
 ##
 # check for libpmem
 
@@ -6576,6 +6599,7 @@ echo "libpmem support   $libpmem"
 echo "libudev   $libudev"
 echo "default devices   $default_devices"
 echo "plugin support$plugins"
+echo "fuzzing support   $fuzzing"
 
 if test "$supported_cpu" = "no"; then
 echo
@@ -7400,6 +7424,16 @@ fi
 if test "$sheepdog" = "yes" ; then
   echo "CONFIG_SHEEPDOG=y" >> $config_host_mak
 fi
+if test "$fuzzing" = "yes" ; then
+  if test "$have_fuzzer" = "yes"; then
+FUZZ_LDFLAGS=" -fsanitize=address,fuzzer"
+FUZZ_CFLAGS=" -fsanitize=address,fuzzer"
+CFLAGS=" -fsanitize=address,fuzzer-no-link"
+  else
+error_exit "Your compiler doesn't support -fsanitize=address,fuzzer"
+exit 1
+  fi
+fi
 
 if test "$plugins" = "yes" ; then
 echo "CONFIG_PLUGIN=y" >> $config_host_mak
@@ -7502,6 +7536,11 @@ if test "$libudev" != "no"; then
 echo "CONFIG_LIBUDEV=y" >> $config_host_mak
 echo "LIBUDEV_LIBS=$libudev_libs" >> $config_host_mak
 fi
+if test "$fuzzing" != "no"; then
+echo "CONFIG_FUZZ=y" >> $config_host_mak
+echo "FUZZ_CFLAGS=$FUZZ_CFLAGS" >> $config_host_mak
+echo "FUZZ_LDFLAGS=$FUZZ_LDFLAGS" >> $config_host_mak
+fi
 
 if test "$edk2_blobs" = "yes" ; then
   echo "DECOMPRESS_EDK2_BLOBS=y" >> $config_host_mak
-- 
2.23.0



[PATCH v8 16/21] fuzz: add target/fuzz makefile rules

2020-01-28 Thread Bulekov, Alexander
Signed-off-by: Alexander Bulekov 
Reviewed-by: Darren Kenny 
Reviewed-by: Stefan Hajnoczi 
---
 Makefile| 15 ++-
 Makefile.objs   |  2 +-
 Makefile.target | 16 
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index e6de7a47bb..dab291455f 100644
--- a/Makefile
+++ b/Makefile
@@ -464,7 +464,7 @@ config-host.h-timestamp: config-host.mak
 qemu-options.def: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > 
$@,"GEN","$@")
 
-TARGET_DIRS_RULES := $(foreach t, all clean install, $(addsuffix /$(t), 
$(TARGET_DIRS)))
+TARGET_DIRS_RULES := $(foreach t, all fuzz clean install, $(addsuffix /$(t), 
$(TARGET_DIRS)))
 
 SOFTMMU_ALL_RULES=$(filter %-softmmu/all, $(TARGET_DIRS_RULES))
 $(SOFTMMU_ALL_RULES): $(authz-obj-y)
@@ -478,6 +478,15 @@ ifdef DECOMPRESS_EDK2_BLOBS
 $(SOFTMMU_ALL_RULES): $(edk2-decompressed)
 endif
 
+SOFTMMU_FUZZ_RULES=$(filter %-softmmu/fuzz, $(TARGET_DIRS_RULES))
+$(SOFTMMU_FUZZ_RULES): $(authz-obj-y)
+$(SOFTMMU_FUZZ_RULES): $(block-obj-y)
+$(SOFTMMU_FUZZ_RULES): $(chardev-obj-y)
+$(SOFTMMU_FUZZ_RULES): $(crypto-obj-y)
+$(SOFTMMU_FUZZ_RULES): $(io-obj-y)
+$(SOFTMMU_FUZZ_RULES): config-all-devices.mak
+$(SOFTMMU_FUZZ_RULES): $(edk2-decompressed)
+
 .PHONY: $(TARGET_DIRS_RULES)
 # The $(TARGET_DIRS_RULES) are of the form SUBDIR/GOAL, so that
 # $(dir $@) yields the sub-directory, and $(notdir $@) yields the sub-goal
@@ -528,6 +537,9 @@ subdir-slirp: slirp/all
 $(filter %/all, $(TARGET_DIRS_RULES)): libqemuutil.a $(common-obj-y) \
$(qom-obj-y)
 
+$(filter %/fuzz, $(TARGET_DIRS_RULES)): libqemuutil.a $(common-obj-y) \
+   $(qom-obj-y) $(crypto-user-obj-$(CONFIG_USER_ONLY))
+
 ROM_DIRS = $(addprefix pc-bios/, $(ROMS))
 ROM_DIRS_RULES=$(foreach t, all clean, $(addsuffix /$(t), $(ROM_DIRS)))
 # Only keep -O and -g cflags
@@ -537,6 +549,7 @@ $(ROM_DIRS_RULES):
 
 .PHONY: recurse-all recurse-clean recurse-install
 recurse-all: $(addsuffix /all, $(TARGET_DIRS) $(ROM_DIRS))
+recurse-fuzz: $(addsuffix /fuzz, $(TARGET_DIRS) $(ROM_DIRS))
 recurse-clean: $(addsuffix /clean, $(TARGET_DIRS) $(ROM_DIRS))
 recurse-install: $(addsuffix /install, $(TARGET_DIRS))
 $(addsuffix /install, $(TARGET_DIRS)): all
diff --git a/Makefile.objs b/Makefile.objs
index 5ab166fed5..9d87a1009e 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -84,8 +84,8 @@ common-obj-$(CONFIG_FDT) += device_tree.o
 # qapi
 
 common-obj-y += qapi/
-
 softmmu-obj-y = main.o
+
 endif
 
 ###
diff --git a/Makefile.target b/Makefile.target
index 8dcf38..fd6fe79495 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -227,6 +227,22 @@ ifdef CONFIG_TRACE_SYSTEMTAP
rm -f *.stp
 endif
 
+ifdef CONFIG_FUZZ
+include $(SRC_PATH)/tests/qtest/fuzz/Makefile.include
+include $(SRC_PATH)/tests/qtest/Makefile.include
+
+fuzz: fuzz-vars
+fuzz-vars: QEMU_CFLAGS := $(FUZZ_CFLAGS) $(QEMU_CFLAGS)
+fuzz-vars: QEMU_LDFLAGS := $(FUZZ_LDFLAGS) $(QEMU_LDFLAGS)
+fuzz-vars: $(QEMU_PROG_FUZZ)
+dummy := $(call unnest-vars,, fuzz-obj-y)
+
+
+$(QEMU_PROG_FUZZ): config-devices.mak $(all-obj-y) $(COMMON_LDADDS) 
$(fuzz-obj-y)
+   $(call LINK, $(filter-out %.mak, $^))
+
+endif
+
 install: all
 ifneq ($(PROGS),)
$(call install-prog,$(PROGS),$(DESTDIR)$(bindir))
-- 
2.23.0




[PATCH v8 11/21] fuzz: add fuzzer skeleton

2020-01-28 Thread Bulekov, Alexander
tests/fuzz/fuzz.c serves as the entry point for the virtual-device
fuzzer. Namely, libfuzzer invokes the LLVMFuzzerInitialize and
LLVMFuzzerTestOneInput functions, both of which are defined in this
file. This change adds a "FuzzTarget" struct, along with the
fuzz_add_target function, which should be used to define new fuzz
targets.

Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
---
 tests/qtest/fuzz/Makefile.include |   6 +
 tests/qtest/fuzz/fuzz.c   | 179 ++
 tests/qtest/fuzz/fuzz.h   |  95 
 3 files changed, 280 insertions(+)
 create mode 100644 tests/qtest/fuzz/Makefile.include
 create mode 100644 tests/qtest/fuzz/fuzz.c
 create mode 100644 tests/qtest/fuzz/fuzz.h

diff --git a/tests/qtest/fuzz/Makefile.include 
b/tests/qtest/fuzz/Makefile.include
new file mode 100644
index 00..8632bb89f4
--- /dev/null
+++ b/tests/qtest/fuzz/Makefile.include
@@ -0,0 +1,6 @@
+QEMU_PROG_FUZZ=qemu-fuzz-$(TARGET_NAME)$(EXESUF)
+
+fuzz-obj-y += tests/qtest/libqtest.o
+fuzz-obj-y += tests/qtest/fuzz/fuzz.o # Fuzzer skeleton
+
+FUZZ_CFLAGS += -I$(SRC_PATH)/tests -I$(SRC_PATH)/tests/qtest
diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c
new file mode 100644
index 00..0d78ac8d36
--- /dev/null
+++ b/tests/qtest/fuzz/fuzz.c
@@ -0,0 +1,179 @@
+/*
+ * fuzzing driver
+ *
+ * Copyright Red Hat Inc., 2019
+ *
+ * Authors:
+ *  Alexander Bulekov   
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+
+#include 
+
+#include "sysemu/qtest.h"
+#include "sysemu/runstate.h"
+#include "sysemu/sysemu.h"
+#include "qemu/main-loop.h"
+#include "tests/qtest/libqtest.h"
+#include "tests/qtest/libqos/qgraph.h"
+#include "fuzz.h"
+
+#define MAX_EVENT_LOOPS 10
+
+typedef struct FuzzTargetState {
+FuzzTarget *target;
+QSLIST_ENTRY(FuzzTargetState) target_list;
+} FuzzTargetState;
+
+typedef QSLIST_HEAD(, FuzzTargetState) FuzzTargetList;
+
+static const char *fuzz_arch = TARGET_NAME;
+
+static FuzzTargetList *fuzz_target_list;
+static FuzzTarget *fuzz_target;
+static QTestState *fuzz_qts;
+
+
+
+void flush_events(QTestState *s)
+{
+int i = MAX_EVENT_LOOPS;
+while (g_main_context_pending(NULL) && i-- > 0) {
+main_loop_wait(false);
+}
+}
+
+static QTestState *qtest_setup(void)
+{
+qtest_server_set_send_handler(_client_inproc_recv, _qts);
+return qtest_inproc_init(_qts, false, fuzz_arch,
+_server_inproc_recv);
+}
+
+void fuzz_add_target(const FuzzTarget *target)
+{
+FuzzTargetState *tmp;
+FuzzTargetState *target_state;
+if (!fuzz_target_list) {
+fuzz_target_list = g_new0(FuzzTargetList, 1);
+}
+
+QSLIST_FOREACH(tmp, fuzz_target_list, target_list) {
+if (g_strcmp0(tmp->target->name, target->name) == 0) {
+fprintf(stderr, "Error: Fuzz target name %s already in use\n",
+target->name);
+abort();
+}
+}
+target_state = g_new0(FuzzTargetState, 1);
+target_state->target = g_new0(FuzzTarget, 1);
+*(target_state->target) = *target;
+QSLIST_INSERT_HEAD(fuzz_target_list, target_state, target_list);
+}
+
+
+
+static void usage(char *path)
+{
+printf("Usage: %s --fuzz-target=FUZZ_TARGET [LIBFUZZER ARGUMENTS]\n", 
path);
+printf("where FUZZ_TARGET is one of:\n");
+FuzzTargetState *tmp;
+if (!fuzz_target_list) {
+fprintf(stderr, "Fuzz target list not initialized\n");
+abort();
+}
+QSLIST_FOREACH(tmp, fuzz_target_list, target_list) {
+printf(" * %s  : %s\n", tmp->target->name,
+tmp->target->description);
+}
+exit(0);
+}
+
+static FuzzTarget *fuzz_get_target(char* name)
+{
+FuzzTargetState *tmp;
+if (!fuzz_target_list) {
+fprintf(stderr, "Fuzz target list not initialized\n");
+abort();
+}
+
+QSLIST_FOREACH(tmp, fuzz_target_list, target_list) {
+if (strcmp(tmp->target->name, name) == 0) {
+return tmp->target;
+}
+}
+return NULL;
+}
+
+
+/* Executed for each fuzzing-input */
+int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size)
+{
+/*
+ * Do the pre-fuzz-initialization before the first fuzzing iteration,
+ * instead of before the actual fuzz loop. This is needed since libfuzzer
+ * may fork off additional workers, prior to the fuzzing loop, and if
+ * pre_fuzz() sets up e.g. shared memory, this should be done for the
+ * individual worker processes
+ */
+static int pre_fuzz_done;
+if (!pre_fuzz_done && fuzz_target->pre_fuzz) {
+fuzz_target->pre_fuzz(fuzz_qts);
+pre_fuzz_done = true;
+}
+
+fuzz_target->fuzz(fuzz_qts, Data, Size);
+return 0;
+}
+
+/* Executed once, prior to fuzzing */
+int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
+{
+
+char *target_name;

[PATCH v8 10/21] libqos: move useful qos-test funcs to qos_external

2020-01-28 Thread Bulekov, Alexander
The moved functions are not specific to qos-test and might be useful
elsewhere. For example the virtual-device fuzzer makes use of them for
qos-assisted fuzz-targets.

Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Philippe Mathieu-Daudé 
---
 tests/qtest/Makefile.include  |   1 +
 tests/qtest/libqos/qos_external.c | 168 ++
 tests/qtest/libqos/qos_external.h |  28 +
 tests/qtest/qos-test.c| 132 +--
 4 files changed, 198 insertions(+), 131 deletions(-)
 create mode 100644 tests/qtest/libqos/qos_external.c
 create mode 100644 tests/qtest/libqos/qos_external.h

diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index 08a48c1252..bdc93d3866 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -172,6 +172,7 @@ libqos-usb-obj-y = $(libqos-spapr-obj-y) $(libqos-pc-obj-y) 
tests/qtest/libqos/u
 # qos devices:
 libqos-obj-y =  $(libqgraph-obj-y)
 libqos-obj-y += $(libqos-pc-obj-y) $(libqos-spapr-obj-y)
+libqos-obj-y += tests/qtest/libqos/qos_external.o
 libqos-obj-y += tests/qtest/libqos/e1000e.o
 libqos-obj-y += tests/qtest/libqos/i2c.o
 libqos-obj-y += tests/qtest/libqos/i2c-imx.o
diff --git a/tests/qtest/libqos/qos_external.c 
b/tests/qtest/libqos/qos_external.c
new file mode 100644
index 00..398556dde0
--- /dev/null
+++ b/tests/qtest/libqos/qos_external.c
@@ -0,0 +1,168 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 
+ */
+
+#include "qemu/osdep.h"
+#include 
+#include "libqtest.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qstring.h"
+#include "qemu/module.h"
+#include "qapi/qmp/qlist.h"
+#include "libqos/malloc.h"
+#include "libqos/qgraph.h"
+#include "libqos/qgraph_internal.h"
+#include "libqos/qos_external.h"
+
+
+
+void apply_to_node(const char *name, bool is_machine, bool is_abstract)
+{
+char *machine_name = NULL;
+if (is_machine) {
+const char *arch = qtest_get_arch();
+machine_name = g_strconcat(arch, "/", name, NULL);
+name = machine_name;
+}
+qos_graph_node_set_availability(name, true);
+if (is_abstract) {
+qos_delete_cmd_line(name);
+}
+g_free(machine_name);
+}
+
+/**
+ * apply_to_qlist(): using QMP queries QEMU for a list of
+ * machines and devices available, and sets the respective node
+ * as true. If a node is found, also all its produced and contained
+ * child are marked available.
+ *
+ * See qos_graph_node_set_availability() for more info
+ */
+void apply_to_qlist(QList *list, bool is_machine)
+{
+const QListEntry *p;
+const char *name;
+bool abstract;
+QDict *minfo;
+QObject *qobj;
+QString *qstr;
+QBool *qbool;
+
+for (p = qlist_first(list); p; p = qlist_next(p)) {
+minfo = qobject_to(QDict, qlist_entry_obj(p));
+qobj = qdict_get(minfo, "name");
+qstr = qobject_to(QString, qobj);
+name = qstring_get_str(qstr);
+
+qobj = qdict_get(minfo, "abstract");
+if (qobj) {
+qbool = qobject_to(QBool, qobj);
+abstract = qbool_get_bool(qbool);
+} else {
+abstract = false;
+}
+
+apply_to_node(name, is_machine, abstract);
+qobj = qdict_get(minfo, "alias");
+if (qobj) {
+qstr = qobject_to(QString, qobj);
+name = qstring_get_str(qstr);
+apply_to_node(name, is_machine, abstract);
+}
+}
+}
+
+QGuestAllocator *get_machine_allocator(QOSGraphObject *obj)
+{
+return obj->get_driver(obj, "memory");
+}
+
+/**
+ * allocate_objects(): given an array of nodes @arg,
+ * walks the path invoking all constructors and
+ * passing the corresponding parameter in order to
+ * continue the objects allocation.
+ * Once the test is reached, return the object it consumes.
+ *
+ * Since the machine and QEDGE_CONSUMED_BY nodes allocate
+ * memory in the constructor, g_test_queue_destroy is used so
+ * that after execution they can be safely free'd.  (The test's
+ * ->before callback is also welcome to use g_test_queue_destroy).
+ *
+ * Note: as specified in walk_path() too, @arg is an array of
+ * char *, where arg[0] is a pointer to the command line
+ * string that will be used to properly start QEMU when executing
+ * the test, and 

[PATCH v8 04/21] qtest: add qtest_server_send abstraction

2020-01-28 Thread Bulekov, Alexander
qtest_server_send is a function pointer specifying the handler used to
transmit data to the qtest client. In the standard configuration, this
calls the CharBackend handler, but now it is possible for other types of
handlers, e.g direct-function calls if the qtest client and server
exist within the same process (inproc)

Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
Acked-by: Thomas Huth 
---
 include/sysemu/qtest.h |  3 +++
 qtest.c| 18 --
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
index 5ed09c80b1..e2f1047fd7 100644
--- a/include/sysemu/qtest.h
+++ b/include/sysemu/qtest.h
@@ -26,4 +26,7 @@ bool qtest_driver(void);
 
 void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error 
**errp);
 
+void qtest_server_set_send_handler(void (*send)(void *, const char *),
+ void *opaque);
+
 #endif
diff --git a/qtest.c b/qtest.c
index 12432f99cf..938c3746d6 100644
--- a/qtest.c
+++ b/qtest.c
@@ -42,6 +42,8 @@ static GString *inbuf;
 static int irq_levels[MAX_IRQ];
 static qemu_timeval start_time;
 static bool qtest_opened;
+static void (*qtest_server_send)(void*, const char*);
+static void *qtest_server_send_opaque;
 
 #define FMT_timeval "%ld.%06ld"
 
@@ -228,8 +230,10 @@ static void GCC_FMT_ATTR(1, 2) qtest_log_send(const char 
*fmt, ...)
 va_end(ap);
 }
 
-static void do_qtest_send(CharBackend *chr, const char *str, size_t len)
+static void qtest_server_char_be_send(void *opaque, const char *str)
 {
+size_t len = strlen(str);
+CharBackend* chr = (CharBackend *)opaque;
 qemu_chr_fe_write_all(chr, (uint8_t *)str, len);
 if (qtest_log_fp && qtest_opened) {
 fprintf(qtest_log_fp, "%s", str);
@@ -238,7 +242,7 @@ static void do_qtest_send(CharBackend *chr, const char 
*str, size_t len)
 
 static void qtest_send(CharBackend *chr, const char *str)
 {
-do_qtest_send(chr, str, strlen(str));
+qtest_server_send(qtest_server_send_opaque, str);
 }
 
 static void GCC_FMT_ATTR(2, 3) qtest_sendf(CharBackend *chr,
@@ -783,6 +787,16 @@ void qtest_server_init(const char *qtest_chrdev, const 
char *qtest_log, Error **
 qemu_chr_fe_set_echo(_chr, true);
 
 inbuf = g_string_new("");
+
+if (!qtest_server_send) {
+qtest_server_set_send_handler(qtest_server_char_be_send, _chr);
+}
+}
+
+void qtest_server_set_send_handler(void (*send)(void*, const char*), void 
*opaque)
+{
+qtest_server_send = send;
+qtest_server_send_opaque = opaque;
 }
 
 bool qtest_driver(void)
-- 
2.23.0




[PATCH v8 06/21] libqtest: make bufwrite rely on the TransportOps

2020-01-28 Thread Bulekov, Alexander
When using qtest "in-process" communication, qtest_sendf directly calls
a function in the server (qtest.c). Previously, bufwrite used
socket_send, which bypasses the TransportOps enabling the call into
qtest.c. This change replaces the socket_send calls with ops->send,
maintaining the benefits of the direct socket_send call, while adding
support for in-process qtest calls.

Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
---
 tests/qtest/libqtest.c | 71 --
 tests/qtest/libqtest.h |  4 +++
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index e5056a1d0f..49075b55a1 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -37,10 +37,18 @@
 
 
 typedef void (*QTestSendFn)(QTestState *s, const char *buf);
+typedef void (*ExternalSendFn)(void *s, const char *buf);
 typedef GString* (*QTestRecvFn)(QTestState *);
 
 typedef struct QTestClientTransportOps {
 QTestSendFn send;  /* for sending qtest commands */
+
+/*
+ * use external_send to send qtest command strings through functions which
+ * do not accept a QTestState as the first parameter.
+ */
+ExternalSendFn  external_send;
+
 QTestRecvFn recv_line; /* for receiving qtest command responses */
 } QTestTransportOps;
 
@@ -1078,8 +1086,8 @@ void qtest_bufwrite(QTestState *s, uint64_t addr, const 
void *data, size_t size)
 
 bdata = g_base64_encode(data, size);
 qtest_sendf(s, "b64write 0x%" PRIx64 " 0x%zx ", addr, size);
-socket_send(s->fd, bdata, strlen(bdata));
-socket_send(s->fd, "\n", 1);
+s->ops.send(s, bdata);
+s->ops.send(s, "\n");
 qtest_rsp(s, 0);
 g_free(bdata);
 }
@@ -1367,3 +1375,62 @@ static void qtest_client_set_rx_handler(QTestState *s, 
QTestRecvFn recv)
 {
 s->ops.recv_line = recv;
 }
+/* A type-safe wrapper for s->send() */
+static void send_wrapper(QTestState *s, const char *buf)
+{
+s->ops.external_send(s, buf);
+}
+
+static GString *qtest_client_inproc_recv_line(QTestState *s)
+{
+GString *line;
+size_t offset;
+char *eol;
+
+eol = strchr(s->rx->str, '\n');
+offset = eol - s->rx->str;
+line = g_string_new_len(s->rx->str, offset);
+g_string_erase(s->rx, 0, offset + 1);
+return line;
+}
+
+QTestState *qtest_inproc_init(QTestState **s, bool log, const char* arch,
+void (*send)(void*, const char*))
+{
+QTestState *qts;
+qts = g_new0(QTestState, 1);
+*s = qts; /* Expose qts early on, since the query endianness relies on it 
*/
+qts->wstatus = 0;
+for (int i = 0; i < MAX_IRQ; i++) {
+qts->irq_level[i] = false;
+}
+
+qtest_client_set_rx_handler(qts, qtest_client_inproc_recv_line);
+
+/* send() may not have a matching protoype, so use a type-safe wrapper */
+qts->ops.external_send = send;
+qtest_client_set_tx_handler(qts, send_wrapper);
+
+qts->big_endian = qtest_query_target_endianness(qts);
+
+/*
+ * Set a dummy path for QTEST_QEMU_BINARY. Doesn't need to exist, but this
+ * way, qtest_get_arch works for inproc qtest.
+ */
+gchar *bin_path = g_strconcat("/qemu-system-", arch, NULL);
+setenv("QTEST_QEMU_BINARY", bin_path, 0);
+g_free(bin_path);
+
+return qts;
+}
+
+void qtest_client_inproc_recv(void *opaque, const char *str)
+{
+QTestState *qts = *(QTestState **)opaque;
+
+if (!qts->rx) {
+qts->rx = g_string_new(NULL);
+}
+g_string_append(qts->rx, str);
+return;
+}
diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
index c9e21e05b3..f5cf93c386 100644
--- a/tests/qtest/libqtest.h
+++ b/tests/qtest/libqtest.h
@@ -729,4 +729,8 @@ bool qtest_probe_child(QTestState *s);
  */
 void qtest_set_expected_status(QTestState *s, int status);
 
+QTestState *qtest_inproc_init(QTestState **s, bool log, const char* arch,
+void (*send)(void*, const char*));
+
+void qtest_client_inproc_recv(void *opaque, const char *str);
 #endif
-- 
2.23.0




[PATCH v8 13/21] main: keep rcu_atfork callback enabled for qtest

2020-01-28 Thread Bulekov, Alexander
The qtest-based fuzzer makes use of forking to reset-state between
tests. Keep the callback enabled, so the call_rcu thread gets created
within the child process.

Signed-off-by: Alexander Bulekov 
---
 vl.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/vl.c b/vl.c
index bb77935f04..cf8e2d3ebb 100644
--- a/vl.c
+++ b/vl.c
@@ -3794,7 +3794,14 @@ void qemu_init(int argc, char **argv, char **envp)
 set_memory_options(_slots, _size, machine_class);
 
 os_daemonize();
-rcu_disable_atfork();
+
+/*
+ * If QTest is enabled, keep the rcu_atfork enabled, since system processes
+ * may be forked testing purposes (e.g. fork-server based fuzzing)
+ */
+if (!qtest_enabled()) {
+rcu_disable_atfork();
+}
 
 if (pid_file && !qemu_write_pidfile(pid_file, )) {
 error_reportf_err(err, "cannot create PID file: ");
-- 
2.23.0




[PATCH v8 07/21] qtest: add in-process incoming command handler

2020-01-28 Thread Bulekov, Alexander
The handler allows a qtest client to send commands to the server by
directly calling a function, rather than using a file/CharBackend

Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
---
 include/sysemu/qtest.h |  1 +
 qtest.c| 13 +
 2 files changed, 14 insertions(+)

diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
index e2f1047fd7..eedd3664f0 100644
--- a/include/sysemu/qtest.h
+++ b/include/sysemu/qtest.h
@@ -28,5 +28,6 @@ void qtest_server_init(const char *qtest_chrdev, const char 
*qtest_log, Error **
 
 void qtest_server_set_send_handler(void (*send)(void *, const char *),
  void *opaque);
+void qtest_server_inproc_recv(void *opaque, const char *buf);
 
 #endif
diff --git a/qtest.c b/qtest.c
index 938c3746d6..ad6eb6a526 100644
--- a/qtest.c
+++ b/qtest.c
@@ -803,3 +803,16 @@ bool qtest_driver(void)
 {
 return qtest_chr.chr != NULL;
 }
+
+void qtest_server_inproc_recv(void *dummy, const char *buf)
+{
+static GString *gstr;
+if (!gstr) {
+gstr = g_string_new(NULL);
+}
+g_string_append(gstr, buf);
+if (gstr->str[gstr->len - 1] == '\n') {
+qtest_process_inbuf(NULL, gstr);
+g_string_truncate(gstr, 0);
+}
+}
-- 
2.23.0




[PATCH v8 01/21] softmmu: split off vl.c:main() into main.c

2020-01-28 Thread Bulekov, Alexander
A program might rely on functions implemented in vl.c, but implement its
own main(). By placing main into a separate source file, there are no
complaints about duplicate main()s when linking against vl.o. For
example, the virtual-device fuzzer uses a main() provided by libfuzzer,
and needs to perform some initialization before running the softmmu
initialization. Now, main simply calls three vl.c functions which
handle the guest initialization, main loop and cleanup.

Signed-off-by: Alexander Bulekov 
---
 Makefile|  1 +
 Makefile.objs   |  2 ++
 Makefile.target |  2 +-
 include/sysemu/sysemu.h |  4 
 main.c  | 53 +
 vl.c| 36 +++-
 6 files changed, 70 insertions(+), 28 deletions(-)
 create mode 100644 main.c

diff --git a/Makefile b/Makefile
index 32bd554480..e6de7a47bb 100644
--- a/Makefile
+++ b/Makefile
@@ -473,6 +473,7 @@ $(SOFTMMU_ALL_RULES): $(chardev-obj-y)
 $(SOFTMMU_ALL_RULES): $(crypto-obj-y)
 $(SOFTMMU_ALL_RULES): $(io-obj-y)
 $(SOFTMMU_ALL_RULES): config-all-devices.mak
+$(SOFTMMU_ALL_RULES): $(softmmu-main-y)
 ifdef DECOMPRESS_EDK2_BLOBS
 $(SOFTMMU_ALL_RULES): $(edk2-decompressed)
 endif
diff --git a/Makefile.objs b/Makefile.objs
index 7c1e50f9d6..5ab166fed5 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -84,6 +84,8 @@ common-obj-$(CONFIG_FDT) += device_tree.o
 # qapi
 
 common-obj-y += qapi/
+
+softmmu-obj-y = main.o
 endif
 
 ###
diff --git a/Makefile.target b/Makefile.target
index 6e61f607b1..8dcf38 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -202,7 +202,7 @@ endif
 COMMON_LDADDS = ../libqemuutil.a
 
 # build either PROG or PROGW
-$(QEMU_PROG_BUILD): $(all-obj-y) $(COMMON_LDADDS)
+$(QEMU_PROG_BUILD): $(all-obj-y) $(COMMON_LDADDS) $(softmmu-obj-y)
$(call LINK, $(filter-out %.mak, $^))
 ifdef CONFIG_DARWIN
$(call quiet-command,Rez -append $(SRC_PATH)/pc-bios/qemu.rsrc -o 
$@,"REZ","$(TARGET_DIR)$@")
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 80c57fdc4e..270df5fa34 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -118,6 +118,10 @@ QemuOpts *qemu_get_machine_opts(void);
 
 bool defaults_enabled(void);
 
+void qemu_init(int argc, char **argv, char **envp);
+void qemu_main_loop(void);
+void qemu_cleanup(void);
+
 extern QemuOptsList qemu_legacy_drive_opts;
 extern QemuOptsList qemu_common_drive_opts;
 extern QemuOptsList qemu_drive_opts;
diff --git a/main.c b/main.c
new file mode 100644
index 00..f10ceda541
--- /dev/null
+++ b/main.c
@@ -0,0 +1,53 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "sysemu/sysemu.h"
+
+#ifdef CONFIG_SDL
+#if defined(__APPLE__) || defined(main)
+#include 
+int main(int argc, char **argv)
+{
+return qemu_main(argc, argv, NULL);
+}
+#undef main
+#define main qemu_main
+#endif
+#endif /* CONFIG_SDL */
+
+#ifdef CONFIG_COCOA
+#undef main
+#define main qemu_main
+#endif /* CONFIG_COCOA */
+
+int main(int argc, char **argv, char **envp)
+{
+qemu_init(argc, argv, envp);
+qemu_main_loop();
+qemu_cleanup();
+
+return 0;
+}
diff --git a/vl.c b/vl.c
index 751401214c..bb77935f04 100644
--- a/vl.c
+++ b/vl.c
@@ -36,25 +36,6 @@
 #include "sysemu/seccomp.h"
 #include "sysemu/tcg.h"
 
-#ifdef CONFIG_SDL
-#if defined(__APPLE__) || defined(main)
-#include 
-int qemu_main(int argc, char **argv, char **envp);
-int main(int argc, char **argv)
-{
-return qemu_main(argc, argv, NULL);
-}
-#undef main
-#define main qemu_main
-#endif
-#endif /* CONFIG_SDL */
-
-#ifdef CONFIG_COCOA
-#undef main
-#define main qemu_main
-#endif /* CONFIG_COCOA */
-
-
 #include "qemu/error-report.h"
 #include "qemu/sockets.h"
 

[PATCH v8 09/21] libqos: split qos-test and libqos makefile vars

2020-01-28 Thread Bulekov, Alexander
Most qos-related objects were specified in the qos-test-obj-y variable.
qos-test-obj-y also included qos-test.o which defines a main().
This made it difficult to repurpose qos-test-obj-y to link anything
beside tests/qos-test against libqos. This change separates objects that
are libqos-specific and ones that are qos-test specific into different
variables.

Signed-off-by: Alexander Bulekov 
Reviewed-by: Darren Kenny 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Philippe Mathieu-Daudé 
---
 tests/qtest/Makefile.include | 71 ++--
 1 file changed, 36 insertions(+), 35 deletions(-)

diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index e6bb4ab28c..08a48c1252 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -157,52 +157,53 @@ check-qtest-s390x-y += migration-test
 # libqos / qgraph :
 libqgraph-obj-y = tests/qtest/libqos/qgraph.o
 
-libqos-obj-y = $(libqgraph-obj-y) tests/qtest/libqos/pci.o 
tests/qtest/libqos/fw_cfg.o
-libqos-obj-y += tests/qtest/libqos/malloc.o
-libqos-obj-y += tests/qtest/libqos/libqos.o
-libqos-spapr-obj-y = $(libqos-obj-y) tests/qtest/libqos/malloc-spapr.o
+libqos-core-obj-y = $(libqgraph-obj-y) tests/qtest/libqos/pci.o 
tests/qtest/libqos/fw_cfg.o
+libqos-core-obj-y += tests/qtest/libqos/malloc.o
+libqos-core-obj-y += tests/qtest/libqos/libqos.o
+libqos-spapr-obj-y = $(libqos-core-obj-y) tests/qtest/libqos/malloc-spapr.o
 libqos-spapr-obj-y += tests/qtest/libqos/libqos-spapr.o
 libqos-spapr-obj-y += tests/qtest/libqos/rtas.o
 libqos-spapr-obj-y += tests/qtest/libqos/pci-spapr.o
-libqos-pc-obj-y = $(libqos-obj-y) tests/qtest/libqos/pci-pc.o
+libqos-pc-obj-y = $(libqos-core-obj-y) tests/qtest/libqos/pci-pc.o
 libqos-pc-obj-y += tests/qtest/libqos/malloc-pc.o 
tests/qtest/libqos/libqos-pc.o
 libqos-pc-obj-y += tests/qtest/libqos/ahci.o
 libqos-usb-obj-y = $(libqos-spapr-obj-y) $(libqos-pc-obj-y) 
tests/qtest/libqos/usb.o
 
 # qos devices:
-qos-test-obj-y = tests/qtest/qos-test.o $(libqgraph-obj-y)
-qos-test-obj-y += $(libqos-pc-obj-y) $(libqos-spapr-obj-y)
-qos-test-obj-y += tests/qtest/libqos/e1000e.o
-qos-test-obj-y += tests/qtest/libqos/i2c.o
-qos-test-obj-y += tests/qtest/libqos/i2c-imx.o
-qos-test-obj-y += tests/qtest/libqos/i2c-omap.o
-qos-test-obj-y += tests/qtest/libqos/sdhci.o
-qos-test-obj-y += tests/qtest/libqos/tpci200.o
-qos-test-obj-y += tests/qtest/libqos/virtio.o
-qos-test-obj-$(CONFIG_VIRTFS) += tests/qtest/libqos/virtio-9p.o
-qos-test-obj-y += tests/qtest/libqos/virtio-balloon.o
-qos-test-obj-y += tests/qtest/libqos/virtio-blk.o
-qos-test-obj-y += tests/qtest/libqos/virtio-mmio.o
-qos-test-obj-y += tests/qtest/libqos/virtio-net.o
-qos-test-obj-y += tests/qtest/libqos/virtio-pci.o
-qos-test-obj-y += tests/qtest/libqos/virtio-pci-modern.o
-qos-test-obj-y += tests/qtest/libqos/virtio-rng.o
-qos-test-obj-y += tests/qtest/libqos/virtio-scsi.o
-qos-test-obj-y += tests/qtest/libqos/virtio-serial.o
+libqos-obj-y =  $(libqgraph-obj-y)
+libqos-obj-y += $(libqos-pc-obj-y) $(libqos-spapr-obj-y)
+libqos-obj-y += tests/qtest/libqos/e1000e.o
+libqos-obj-y += tests/qtest/libqos/i2c.o
+libqos-obj-y += tests/qtest/libqos/i2c-imx.o
+libqos-obj-y += tests/qtest/libqos/i2c-omap.o
+libqos-obj-y += tests/qtest/libqos/sdhci.o
+libqos-obj-y += tests/qtest/libqos/tpci200.o
+libqos-obj-y += tests/qtest/libqos/virtio.o
+libqos-obj-$(CONFIG_VIRTFS) += tests/qtest/libqos/virtio-9p.o
+libqos-obj-y += tests/qtest/libqos/virtio-balloon.o
+libqos-obj-y += tests/qtest/libqos/virtio-blk.o
+libqos-obj-y += tests/qtest/libqos/virtio-mmio.o
+libqos-obj-y += tests/qtest/libqos/virtio-net.o
+libqos-obj-y += tests/qtest/libqos/virtio-pci.o
+libqos-obj-y += tests/qtest/libqos/virtio-pci-modern.o
+libqos-obj-y += tests/qtest/libqos/virtio-rng.o
+libqos-obj-y += tests/qtest/libqos/virtio-scsi.o
+libqos-obj-y += tests/qtest/libqos/virtio-serial.o
 
 # qos machines:
-qos-test-obj-y += tests/qtest/libqos/aarch64-xlnx-zcu102-machine.o
-qos-test-obj-y += tests/qtest/libqos/arm-imx25-pdk-machine.o
-qos-test-obj-y += tests/qtest/libqos/arm-n800-machine.o
-qos-test-obj-y += tests/qtest/libqos/arm-raspi2-machine.o
-qos-test-obj-y += tests/qtest/libqos/arm-sabrelite-machine.o
-qos-test-obj-y += tests/qtest/libqos/arm-smdkc210-machine.o
-qos-test-obj-y += tests/qtest/libqos/arm-virt-machine.o
-qos-test-obj-y += tests/qtest/libqos/arm-xilinx-zynq-a9-machine.o
-qos-test-obj-y += tests/qtest/libqos/ppc64_pseries-machine.o
-qos-test-obj-y += tests/qtest/libqos/x86_64_pc-machine.o
+libqos-obj-y += tests/qtest/libqos/aarch64-xlnx-zcu102-machine.o
+libqos-obj-y += tests/qtest/libqos/arm-imx25-pdk-machine.o
+libqos-obj-y += tests/qtest/libqos/arm-n800-machine.o
+libqos-obj-y += tests/qtest/libqos/arm-raspi2-machine.o
+libqos-obj-y += tests/qtest/libqos/arm-sabrelite-machine.o
+libqos-obj-y += tests/qtest/libqos/arm-smdkc210-machine.o
+libqos-obj-y += tests/qtest/libqos/arm-virt-machine.o
+libqos-obj-y += tests/qtest/libqos/arm-xilinx-zynq-a9-machine.o

[PATCH v8 02/21] module: check module wasn't already initialized

2020-01-28 Thread Bulekov, Alexander
The virtual-device fuzzer must initialize QOM, prior to running
vl:qemu_init, so that it can use the qos_graph to identify the arguments
required to initialize a guest for libqos-assisted fuzzing. This change
prevents errors when vl:qemu_init tries to (re)initialize the previously
initialized QOM module.

Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Darren Kenny 
Reviewed-by: Philippe Mathieu-Daudé 
---
 util/module.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/util/module.c b/util/module.c
index 8c5315a7a3..236a7bb52a 100644
--- a/util/module.c
+++ b/util/module.c
@@ -30,6 +30,7 @@ typedef struct ModuleEntry
 typedef QTAILQ_HEAD(, ModuleEntry) ModuleTypeList;
 
 static ModuleTypeList init_type_list[MODULE_INIT_MAX];
+static bool modules_init_done[MODULE_INIT_MAX];
 
 static ModuleTypeList dso_init_list;
 
@@ -91,11 +92,17 @@ void module_call_init(module_init_type type)
 ModuleTypeList *l;
 ModuleEntry *e;
 
+if (modules_init_done[type]) {
+return;
+}
+
 l = find_type(type);
 
 QTAILQ_FOREACH(e, l, node) {
 e->init();
 }
+
+modules_init_done[type] = true;
 }
 
 #ifdef CONFIG_MODULES
-- 
2.23.0



[PATCH v8 00/21] Add virtual device fuzzing support

2020-01-28 Thread Bulekov, Alexander
This series adds a framework for coverage-guided fuzzing of
virtual-devices. Fuzzing targets are based on qtest and can make use of
the libqos abstractions.

V8:
 * Small fixes to the virtio-net.
 * Keep rcu_atfork when not using qtest.

V7:
 * virtio-net: add virtio-net-check-used which waits for inputs on
 the tx/ctrl vq by watching the used vring.
 * virtio-net: add virtio-net-socket which uses the socket backend and can
 exercise the rx components of virtio-net.
 * virtio-net: add virtio-net-slirp which uses the user backend and exercises
 slirp. This may lead to real traffic emitted by qemu so it is best to
 run in an isolated network environment.
 * build should succeed after each commit

V5/V6:
 * added virtio-scsi fuzzer
 * add support for using fork-based fuzzers with multiple libfuzzer
   workers
 * misc fixes addressing V4 comments
 * cleanup in-process handlers/globals in libqtest.c
 * small fixes to fork-based fuzzing and support for multiple workers
 * changes to the virtio-net fuzzer to kick after each vq add

V4:
 * add/transfer license headers to new files
 * restructure the added QTestClientTransportOps struct
 * restructure the FuzzTarget struct and fuzzer skeleton
 * fork-based fuzzer now directly mmaps shm over the coverage bitmaps
 * fixes to i440 and virtio-net fuzz targets
 * undo the changes to qtest_memwrite
 * possible to build /fuzz and /all in the same build-dir
 * misc fixes to address V3 comments

V3:
 * rebased onto v4.1.0+
 * add the fuzzer as a new build-target type in the build-system
 * add indirection to qtest client/server communication functions
 * remove ramfile and snapshot-based fuzzing support
 * add i440fx fuzz-target as a reference for developers.
 * add linker-script to assist with fork-based fuzzer

V2:
 * split off changes to qos virtio-net and qtest server to other patches
 * move vl:main initialization into new func: qemu_init
 * moved useful functions from qos-test.c to a separate object
 * use struct of function pointers for add_fuzz_target(), instead of
   arguments
 * move ramfile to migration/qemu-file
 * rewrite fork-based fuzzer pending patch to libfuzzer
 * pass check-patch

Alexander Bulekov (21):
  softmmu: split off vl.c:main() into main.c
  module: check module wasn't already initialized
  fuzz: add FUZZ_TARGET module type
  qtest: add qtest_server_send abstraction
  libqtest: add a layer of abstraction to send/recv
  libqtest: make bufwrite rely on the TransportOps
  qtest: add in-process incoming command handler
  libqos: rename i2c_send and i2c_recv
  libqos: split qos-test and libqos makefile vars
  libqos: move useful qos-test funcs to qos_external
  fuzz: add fuzzer skeleton
  exec: keep ram block across fork when using qtest
  main: keep rcu_atfork callback enabled for qtest
  fuzz: support for fork-based fuzzing.
  fuzz: add support for qos-assisted fuzz targets
  fuzz: add target/fuzz makefile rules
  fuzz: add configure flag --enable-fuzzing
  fuzz: add i440fx fuzz targets
  fuzz: add virtio-net fuzz target
  fuzz: add virtio-scsi fuzz target
  fuzz: add documentation to docs/devel/

 Makefile|  16 +-
 Makefile.objs   |   2 +
 Makefile.target |  18 ++-
 configure   |  39 +
 docs/devel/fuzzing.txt  | 116 ++
 exec.c  |  12 +-
 include/qemu/module.h   |   4 +-
 include/sysemu/qtest.h  |   4 +
 include/sysemu/sysemu.h |   4 +
 main.c  |  53 +++
 qtest.c |  31 +++-
 tests/qtest/Makefile.include|  72 -
 tests/qtest/fuzz/Makefile.include   |  18 +++
 tests/qtest/fuzz/fork_fuzz.c|  55 +++
 tests/qtest/fuzz/fork_fuzz.h|  23 +++
 tests/qtest/fuzz/fork_fuzz.ld   |  37 +
 tests/qtest/fuzz/fuzz.c | 179 ++
 tests/qtest/fuzz/fuzz.h |  95 
 tests/qtest/fuzz/i440fx_fuzz.c  | 178 +
 tests/qtest/fuzz/qos_fuzz.c | 229 
 tests/qtest/fuzz/qos_fuzz.h |  33 
 tests/qtest/fuzz/virtio_net_fuzz.c  | 195 +++
 tests/qtest/fuzz/virtio_scsi_fuzz.c | 200 
 tests/qtest/libqos/i2c.c|  10 +-
 tests/qtest/libqos/i2c.h|   4 +-
 tests/qtest/libqos/qos_external.c   | 168 
 tests/qtest/libqos/qos_external.h   |  28 
 tests/qtest/libqtest.c  | 119 +--
 tests/qtest/libqtest.h  |   4 +
 tests/qtest/pca9552-test.c  |  10 +-
 tests/qtest/qos-test.c  | 132 +---
 util/module.c   |   7 +
 vl.c|  45 +++---
 33 files changed, 1916 insertions(+), 224 deletions(-)
 create mode 100644 docs/devel/fuzzing.txt
 create mode 100644 main.c
 create mode 100644 

[PATCH v8 03/21] fuzz: add FUZZ_TARGET module type

2020-01-28 Thread Bulekov, Alexander
Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
---
 include/qemu/module.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/qemu/module.h b/include/qemu/module.h
index 65ba596e46..684753d808 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -46,6 +46,7 @@ typedef enum {
 MODULE_INIT_TRACE,
 MODULE_INIT_XEN_BACKEND,
 MODULE_INIT_LIBQOS,
+MODULE_INIT_FUZZ_TARGET,
 MODULE_INIT_MAX
 } module_init_type;
 
@@ -56,7 +57,8 @@ typedef enum {
 #define xen_backend_init(function) module_init(function, \
MODULE_INIT_XEN_BACKEND)
 #define libqos_init(function) module_init(function, MODULE_INIT_LIBQOS)
-
+#define fuzz_target_init(function) module_init(function, \
+   MODULE_INIT_FUZZ_TARGET)
 #define block_module_load_one(lib) module_load_one("block-", lib)
 #define ui_module_load_one(lib) module_load_one("ui-", lib)
 #define audio_module_load_one(lib) module_load_one("audio-", lib)
-- 
2.23.0




[PATCH v8 05/21] libqtest: add a layer of abstraction to send/recv

2020-01-28 Thread Bulekov, Alexander
This makes it simple to swap the transport functions for qtest commands
to and from the qtest client. For example, now it is possible to
directly pass qtest commands to a server handler that exists within the
same process, without the standard way of writing to a file descriptor.

Signed-off-by: Alexander Bulekov 
Reviewed-by: Stefan Hajnoczi 
---
 tests/qtest/libqtest.c | 48 ++
 1 file changed, 39 insertions(+), 9 deletions(-)

diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 76c9f8eade..e5056a1d0f 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -35,6 +35,15 @@
 #define SOCKET_TIMEOUT 50
 #define SOCKET_MAX_FDS 16
 
+
+typedef void (*QTestSendFn)(QTestState *s, const char *buf);
+typedef GString* (*QTestRecvFn)(QTestState *);
+
+typedef struct QTestClientTransportOps {
+QTestSendFn send;  /* for sending qtest commands */
+QTestRecvFn recv_line; /* for receiving qtest command responses */
+} QTestTransportOps;
+
 struct QTestState
 {
 int fd;
@@ -45,6 +54,7 @@ struct QTestState
 bool big_endian;
 bool irq_level[MAX_IRQ];
 GString *rx;
+QTestTransportOps ops;
 };
 
 static GHookList abrt_hooks;
@@ -52,6 +62,14 @@ static struct sigaction sigact_old;
 
 static int qtest_query_target_endianness(QTestState *s);
 
+static void qtest_client_socket_send(QTestState*, const char *buf);
+static void socket_send(int fd, const char *buf, size_t size);
+
+static GString *qtest_client_socket_recv_line(QTestState *);
+
+static void qtest_client_set_tx_handler(QTestState *s, QTestSendFn send);
+static void qtest_client_set_rx_handler(QTestState *s, QTestRecvFn recv);
+
 static int init_socket(const char *socket_path)
 {
 struct sockaddr_un addr;
@@ -234,6 +252,9 @@ QTestState *qtest_init_without_qmp_handshake(const char 
*extra_args)
 sock = init_socket(socket_path);
 qmpsock = init_socket(qmp_socket_path);
 
+qtest_client_set_rx_handler(s, qtest_client_socket_recv_line);
+qtest_client_set_tx_handler(s, qtest_client_socket_send);
+
 qtest_add_abrt_handler(kill_qemu_hook_func, s);
 
 command = g_strdup_printf("exec %s "
@@ -379,13 +400,9 @@ static void socket_send(int fd, const char *buf, size_t 
size)
 }
 }
 
-static void socket_sendf(int fd, const char *fmt, va_list ap)
+static void qtest_client_socket_send(QTestState *s, const char *buf)
 {
-gchar *str = g_strdup_vprintf(fmt, ap);
-size_t size = strlen(str);
-
-socket_send(fd, str, size);
-g_free(str);
+socket_send(s->fd, buf, strlen(buf));
 }
 
 static void GCC_FMT_ATTR(2, 3) qtest_sendf(QTestState *s, const char *fmt, ...)
@@ -393,8 +410,11 @@ static void GCC_FMT_ATTR(2, 3) qtest_sendf(QTestState *s, 
const char *fmt, ...)
 va_list ap;
 
 va_start(ap, fmt);
-socket_sendf(s->fd, fmt, ap);
+gchar *str = g_strdup_vprintf(fmt, ap);
 va_end(ap);
+
+s->ops.send(s, str);
+g_free(str);
 }
 
 /* Sends a message and file descriptors to the socket.
@@ -431,7 +451,7 @@ static void socket_send_fds(int socket_fd, int *fds, size_t 
fds_num,
 g_assert_cmpint(ret, >, 0);
 }
 
-static GString *qtest_recv_line(QTestState *s)
+static GString *qtest_client_socket_recv_line(QTestState *s)
 {
 GString *line;
 size_t offset;
@@ -468,7 +488,7 @@ static gchar **qtest_rsp(QTestState *s, int expected_args)
 int i;
 
 redo:
-line = qtest_recv_line(s);
+line = s->ops.recv_line(s);
 words = g_strsplit(line->str, " ", 0);
 g_string_free(line, TRUE);
 
@@ -1337,3 +1357,13 @@ void qmp_assert_error_class(QDict *rsp, const char 
*class)
 
 qobject_unref(rsp);
 }
+
+static void qtest_client_set_tx_handler(QTestState *s,
+QTestSendFn send)
+{
+s->ops.send = send;
+}
+static void qtest_client_set_rx_handler(QTestState *s, QTestRecvFn recv)
+{
+s->ops.recv_line = recv;
+}
-- 
2.23.0




Re: [PATCH 1/2] ppc/pnv: Add models for POWER9 PHB4 PCIe Host bridge

2020-01-28 Thread Oliver O'Halloran
On Wed, Jan 29, 2020 at 2:09 PM David Gibson
 wrote:
>
> On Mon, Jan 27, 2020 at 03:45:05PM +0100, Cédric Le Goater wrote:
> > From: Benjamin Herrenschmidt 
> >

*snip*

> > +
> > +/*
> > + * The CONFIG_DATA register expects little endian accesses, but as the
> > + * region is big endian, we have to swap the value.
> > + */
> > +static void pnv_phb4_config_write(PnvPHB4 *phb, unsigned off,
> > +  unsigned size, uint64_t val)
> > +{
> > +uint32_t cfg_addr, limit;
> > +PCIDevice *pdev;
> > +
> > +pdev = pnv_phb4_find_cfg_dev(phb);
> > +if (!pdev) {
> > +return;
> > +}
> > +cfg_addr = (phb->regs[PHB_CONFIG_ADDRESS >> 3] >> 32) & 0xffc;
> > +cfg_addr |= off;
> > +limit = pci_config_size(pdev);
> > +if (limit <= cfg_addr) {
> > +/*
> > + * conventional pci device can be behind pcie-to-pci bridge.
> > + * 256 <= addr < 4K has no effects.
> > + */
> > +return;
> > +}
> > +switch (size) {
> > +case 1:
> > +break;
> > +case 2:
> > +val = bswap16(val);
>
> I'm a little confused by these byteswaps.  As I see below the device
> is set to big endian, so the values passed in here should already be
> in host-native endian.  Why do you need the swap?  Are some of the
> registers in the bank BE and some LE?

All the registers are BE except for CONFIG_DATA, which isn't actually
a register. It's really a window into the config space of the device
specified in CONFIG_ADDR so it doesn't do any byte-swapping.

> > +break;
> > +case 4:
> > +val = bswap32(val);
> > +break;
> > +default:
> > +g_assert_not_reached();
> > +}
> > +pci_host_config_write_common(pdev, cfg_addr, limit, val, size);
> > +}



Re: [RFC PATCH] hw/arm/virt: Support NMI injection

2020-01-28 Thread Gavin Shan

On 1/28/20 7:29 PM, Julien Thierry wrote:

Hi Gavin,

On 1/28/20 6:48 AM, Gavin Shan wrote:

[including more folks into the discussion]


On Fri, 17 Jan 2020 at 14:00, Peter Maydell  wrote:

On Thu, 19 Dec 2019 at 04:06, Gavin Shan  wrote:

This supports NMI injection for virtual machine and currently it's only
supported on GICv3 controller, which is emulated by qemu or host kernel.
The design is highlighted as below:

* The NMI is identified by its priority (0x20). In the guest (linux)
kernel, the GICC_PMR is set to 0x80, to block all interrupts except
the NMIs when the external interrupt is disabled. It means the FIQ
and IRQ bit in PSTATE isn't touched when the functionality (NMI) is
functional.
* LPIs aren't considered as NMIs because of their nature. It means NMI
is either SPI or PPI. Besides, the NMIs are injected in round-robin
fashion is there are multiple NMIs existing.
* When the GICv3 controller is emulated by qemu, the interrupt states
(e.g. enabled, priority) is fetched from the corresponding data struct
directly. However, we have to pause all CPUs to fetch the interrupt
states from host in advance if the GICv3 controller is emulated by
host.

The testing scenario is to tweak guest (linux) kernel where the pl011 SPI
can be enabled as NMI by request_nmi(). Check "/proc/interrupts" after injecting
several NMIs, to see if the interrupt count is increased or not. The result
is just as expected.



So, QEMU is trying to emulate actual hardware. None of this
looks to me like what GICv3 hardware does... If you want to
have the virt board send an interrupt, do it the usual way
by wiring up a qemu_irq from some device to the GIC, please.
(More generally, there is no concept of an "NMI" in the GIC;
there are just interrupts at varying possible guest-programmable
priority levels.)



Peter, I missed to read your reply in time and apologies for late response.

Yes, there is no concept of "NMI" in the GIC from hardware perspective.
However, NMI has been supported from the software by kernel commit
bc3c03ccb4641 ("arm64: Enable the support of pseudo-NMIs"). The NMIs
have higher priority than normal ones. NMIs are deliverable after
local_irq_disable() because the SYS_ICC_PMR_EL1 is tweaked so that
normal interrupts are masked only.

It's unclear about the purpose of "nmi" QMP/HMP command. It's why I
put a RFC tag. The command has been supported by multiple architects
including x86/ppc. However, they are having different behaviors. The
system will be restarted on ppc with this command, but a NMI is injected
through LAPIC on x86. So I'm not sure what architect (system reset on
ppc or injecting NMI on x86) aarch64 should follow.



As Peter stated, there is no NMI concept on aarch64 hardware. The pseudo-NMI in the Linux 
port is purely a software concept. The OS itself decides which interrupts should have the 
"NMI" properties and sets them up accordingly.

For QEMU to inject a pseudo-NMI into the guest would require it not only to 
know that the guest supports that feature. But also how such an interrupt has 
to be set up (currently there is no guaranty that the priority used for the NMI 
and the mask should stay the same across Linux version as it is purely internal 
to GICv3/arm64, no generic kAPI nor uAPI have access to it). And also, you 
would probably need to know what is handling the NMI you are injecting.

QEMU shouldn't try to guess "that might be dealt as an NMI, lets raise it".

I'm not familiar with the QMP/HMP nor the inner workings of QEMU, but if for some reason QEMU 
requires to trigger an NMI-like mechanic on aarch64, a proper way might be through para-virt. 
Having some "qemu-nmi-driver" in linux which calls "request_nmi()" and does the 
proper handling expected by QEMU.

Cheers,



Julien, thanks for the explanation. The question we're not sure if NMI should
be injected on receiving HMP/QMP "nmi" command. It means it's not clear what
behavior we should have for this command on ARM. However, I have one more
unrelated question: "pseudo" NMI on ARM64 should be PPI? I mean SPI can't
be "pseudo" NMI.

Thanks,
Gavin




Re: [RFC PATCH] hw/arm/virt: Support NMI injection

2020-01-28 Thread Gavin Shan

On 1/29/20 1:44 PM, Alexey Kardashevskiy wrote:



On 28/01/2020 17:48, Gavin Shan wrote:

[including more folks into the discussion]


On Fri, 17 Jan 2020 at 14:00, Peter Maydell 
wrote:

On Thu, 19 Dec 2019 at 04:06, Gavin Shan  wrote:

This supports NMI injection for virtual machine and currently it's only
supported on GICv3 controller, which is emulated by qemu or host
kernel.
The design is highlighted as below:

* The NMI is identified by its priority (0x20). In the guest (linux)
kernel, the GICC_PMR is set to 0x80, to block all interrupts except
the NMIs when the external interrupt is disabled. It means the FIQ
and IRQ bit in PSTATE isn't touched when the functionality (NMI) is
functional.
* LPIs aren't considered as NMIs because of their nature. It means NMI
is either SPI or PPI. Besides, the NMIs are injected in round-robin
fashion is there are multiple NMIs existing.
* When the GICv3 controller is emulated by qemu, the interrupt states
(e.g. enabled, priority) is fetched from the corresponding data struct
directly. However, we have to pause all CPUs to fetch the interrupt
states from host in advance if the GICv3 controller is emulated by
host.

The testing scenario is to tweak guest (linux) kernel where the
pl011 SPI
can be enabled as NMI by request_nmi(). Check "/proc/interrupts"
after injecting
several NMIs, to see if the interrupt count is increased or not. The
result
is just as expected.



So, QEMU is trying to emulate actual hardware. None of this
looks to me like what GICv3 hardware does... If you want to
have the virt board send an interrupt, do it the usual way
by wiring up a qemu_irq from some device to the GIC, please.
(More generally, there is no concept of an "NMI" in the GIC;
there are just interrupts at varying possible guest-programmable
priority levels.)



Peter, I missed to read your reply in time and apologies for late response.

Yes, there is no concept of "NMI" in the GIC from hardware perspective.
However, NMI has been supported from the software by kernel commit
bc3c03ccb4641 ("arm64: Enable the support of pseudo-NMIs"). The NMIs
have higher priority than normal ones. NMIs are deliverable after
local_irq_disable() because the SYS_ICC_PMR_EL1 is tweaked so that
normal interrupts are masked only.

It's unclear about the purpose of "nmi" QMP/HMP command. It's why I
put a RFC tag. The command has been supported by multiple architects
including x86/ppc. However, they are having different behaviors. The
system will be restarted on ppc with this command,


We inject "system reset" as it is the closest thing to the idea of NMI
(could be a "machine check").

The system behaviour is configurable on POWERPC, it is either kdump
(store a system dump and reboot) or simple reboot or activate XMON
(in-kernel debugger, needs to be enabled beforehand).

The injector in QEMU is called NMIClass::nmi_monitor_handler and as the
name suggests it is not an NMI (the hardware concept which x86 may be
still has and others do not) but an "nmi" command of the QEMU monitor
which is rather a debug tool - "kick an unresponsive guest" - for us
(POWERPC).



Alexey, thanks for the explanation. The behavior for PowerPC is clear now :)




but a NMI is injected
through LAPIC on x86. So I'm not sure what architect (system reset on
ppc or injecting NMI on x86) aarch64 should follow.


I'd say whatever triggers in-kernel debugger or kdump but I am not
familiar with ARM at all :)



For x86, the behavior is really depending the NMI handler. Currently, it
seems nothing other than outputting below messages. However, it's configurable
to get a system crash via "/proc/sys/kernel/unknown_nmi_panic"

(qemu) nmi
[ 6731.137504] Uhhuh. NMI received for unknown reason 30 on CPU 0.
[ 6731.137511] Do you have a strange power saving mode enabled?
[ 6731.137512] Dazed and confused, but trying to continue

guest# cat /proc/sys/kernel/unknown_nmi_panic
0
guest# echo 1 > /proc/sys/kernel/unknown_nmi_panic
(qemu) nmi
[ 6852.848600] Do you have a strange power saving mode enabled?
[ 6852.848601] Kernel panic - not syncing: NMI: Not continuing
[ 6852.848602] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.0-rc6-gshan+ #21
[ 6852.848604] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 
rel-1.12.0-48-4
[ 6852.848604] Call Trace:
[ 6852.848605]  
[ 6852.848606]  dump_stack+0x6d/0x9a
[ 6852.848607]  panic+0x101/0x2e3
[ 6852.848608]  nmi_panic.cold+0xc/0xc
[ 6852.848609]  unknown_nmi_error.cold+0x46/0x57
[ 6852.848609]  default_do_nmi+0xda/0x110
[ 6852.848610]  do_nmi+0x16e/0x1d0
[ 6852.848611]  end_repeat_nmi+0x16/0x1a
[ 6852.848625] RIP: 0010:native_safe_halt+0xe/0x10
[ 6852.848628] Code: 7b ff ff ff eb bd 90 90 90 90 90 90 e9 07 00 00 00 0f 00 
2d 56 bc5
[ 6852.848639] RSP: 0018:ba603e10 EFLAGS: 0246
[ 6852.848642] RAX: b9ccbdb0 RBX:  RCX: 0001
[ 6852.848643] RDX: 000202ce RSI: 0083 RDI: 
[ 6852.848644] RBP: ba603e30 R08: 

Re: [PATCH qemu] spapr_pci: Create assigned properties for bridges

2020-01-28 Thread David Gibson
On Wed, Jan 29, 2020 at 01:31:11PM +1100, Alexey Kardashevskiy wrote:
> QEMU assigns bus numbers so tell the guest about assigned values.
> 
> This also adds an empty "ranges" to let the existing linux kernels proceed
> far enough to trigger resource reassignment (which is rather a
> hack).

That is rather a hack, but AIUI this makes things better than they
were before, so I've applied it to ppc-for-5.0.

What would a less hacky approach to this look like?

> 
> Signed-off-by: Alexey Kardashevskiy 
> ---
> 
> This is a part of the "kill CAS reboot" effort, the SLOF's side of it was
> posted as "[PATCH slof] fdt: Fix creating new nodes at H_CAS"
> 
> ---
>  hw/ppc/spapr_pci.c | 18 +-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index 723373de732c..877ff1d0d5fa 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -1336,7 +1336,23 @@ static int spapr_dt_pci_bus(SpaprPhbState *sphb, 
> PCIBus *bus,
>  if (pci_bus_is_root(bus)) {
>  owner = OBJECT(sphb);
>  } else {
> -owner = OBJECT(pci_bridge_get_device(bus));
> +PCIDevice *pdev = pci_bridge_get_device(bus);
> +uint8_t pri = pci_default_read_config(pdev, PCI_PRIMARY_BUS, 1);
> +uint8_t sec  = pci_default_read_config(pdev, PCI_SECONDARY_BUS, 1);
> +uint8_t sub  = pci_default_read_config(pdev, PCI_SUBORDINATE_BUS, 1);
> +uint32_t range[] = { cpu_to_be32(sec), cpu_to_be32(sub) };
> +
> +/*
> + * Create these to get existing Linux kernels proceed far enough to
> + * trigger resource reassignment. We creates these for vPHB already.
> + */
> +_FDT(fdt_setprop_cell(fdt, offset, "primary-bus", pri));
> +_FDT(fdt_setprop_cell(fdt, offset, "secondary-bus", sec));
> +_FDT(fdt_setprop_cell(fdt, offset, "subordinate-bus", sub));
> +_FDT(fdt_setprop(fdt, offset, "bus-range", range, sizeof(range)));
> +_FDT(fdt_setprop_string(fdt, offset, "device_type", "pci"));
> +_FDT(fdt_setprop(fdt, offset, "ranges", NULL, 0));
> +owner = OBJECT(pdev);
>  }
>  
>  ret = spapr_dt_drc(fdt, offset, owner,

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


signature.asc
Description: PGP signature


Re: [RFC PATCH] hw/arm/virt: Support NMI injection

2020-01-28 Thread Gavin Shan

On 1/28/20 9:56 PM, Auger Eric wrote:

Hi Marc,
On 1/28/20 10:25 AM, Marc Zyngier wrote:

Gavin, Eric,

On 2020-01-28 08:05, Auger Eric wrote:

Hi,

On 1/28/20 7:48 AM, Gavin Shan wrote:

[including more folks into the discussion]


On Fri, 17 Jan 2020 at 14:00, Peter Maydell 
wrote:

On Thu, 19 Dec 2019 at 04:06, Gavin Shan  wrote:

This supports NMI injection for virtual machine and currently it's
only
supported on GICv3 controller, which is emulated by qemu or host
kernel.
The design is highlighted as below:

* The NMI is identified by its priority (0x20). In the guest (linux)
kernel, the GICC_PMR is set to 0x80, to block all interrupts except
the NMIs when the external interrupt is disabled. It means the FIQ
and IRQ bit in PSTATE isn't touched when the functionality (NMI) is
functional.
* LPIs aren't considered as NMIs because of their nature. It means
NMI
is either SPI or PPI. Besides, the NMIs are injected in round-robin
fashion is there are multiple NMIs existing.
* When the GICv3 controller is emulated by qemu, the interrupt states
(e.g. enabled, priority) is fetched from the corresponding data
struct
directly. However, we have to pause all CPUs to fetch the interrupt
states from host in advance if the GICv3 controller is emulated by
host.

The testing scenario is to tweak guest (linux) kernel where the
pl011 SPI
can be enabled as NMI by request_nmi(). Check "/proc/interrupts"
after injecting
several NMIs, to see if the interrupt count is increased or not. The
result
is just as expected.



So, QEMU is trying to emulate actual hardware. None of this
looks to me like what GICv3 hardware does... If you want to
have the virt board send an interrupt, do it the usual way
by wiring up a qemu_irq from some device to the GIC, please.
(More generally, there is no concept of an "NMI" in the GIC;
there are just interrupts at varying possible guest-programmable
priority levels.)



Peter, I missed to read your reply in time and apologies for late
response.

Yes, there is no concept of "NMI" in the GIC from hardware perspective.
However, NMI has been supported from the software by kernel commit
bc3c03ccb4641 ("arm64: Enable the support of pseudo-NMIs"). The NMIs
have higher priority than normal ones. NMIs are deliverable after
local_irq_disable() because the SYS_ICC_PMR_EL1 is tweaked so that
normal interrupts are masked only.


And none of that is an NMI. This is a completely SW-defined mechanism,
and you can't rely on this to inject something that would behave as
a NMI in in a guest. I thought the "pseudo" prefix would give it away :-(.



Marc, thanks for the explanation.



It's unclear about the purpose of "nmi" QMP/HMP command. It's why I
put a RFC tag. The command has been supported by multiple architects
including x86/ppc. However, they are having different behaviors. The
system will be restarted on ppc with this command, but a NMI is injected
through LAPIC on x86. So I'm not sure what architect (system reset on
ppc or injecting NMI on x86) aarch64 should follow.


The x86 NMI has no equivalent on ARM, full stop. And the only thing that
the ARM implementation should follow is the letter of the architecture,
without added concepts.


arm_pmu driver was reworked to use pseudo-NMIs. I don't know the exact
status of this work though
(https://patchwork.kernel.org/cover/11047407/). So we cannot use any
random NMI for guest injection.

I wonder whether we should implement the KVM_NMI vcpu ioctl once we have
agreed on which behavior is expected upon NMI injection. However the
kernel doc says this ioctl only is well defined if "KVM_CREATE_IRQCHIP
has not been called" (?).


But what architectural concept would you map your KVM_NMI to? The number
of things you can do is pretty limited:

- Reset: we already have this
- Interrupt: you don't get to decide the priority or the group
- SError: Pretty much fatal in all cases

You *could* try something like SDEI [1], but that's a pretty terrible
interface too.


Thank you for the pointer.

So Gavin, not sure the QEMU QMP/HMP NMI command is relevant on ARM (at
least at this point)?



Yes, the primary concern is what behavior we should have for ARM when
QMP/HMP "nmi" command is executed. After that's determined, I can dig
into SDEI if needed.

As Alexey said in another reply, it's used to force the guest to have
crash dump or drop into in-kernel debugger (xmon) on PowerPC. However,
x86 guest will receive NMI after the command is issued. This RFC patch
is following x86 to inject "pseudo" NMIs, but it seems incorrect. So
the question is what behavior we should have for ARM when QMP/HMP "nmi"
command is issued? I'm expecting more input in this regard :)

Thanks,
Gavin


Thanks

Eric




     M.

[1]
https://static.docs.arm.com/den0054/a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf








Re: [PATCH 1/2] ppc/pnv: Add models for POWER9 PHB4 PCIe Host bridge

2020-01-28 Thread David Gibson
On Mon, Jan 27, 2020 at 03:45:05PM +0100, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt 
> 
> These changes introduces models for the PCIe Host Bridge (PHB4) of the
> POWER9 processor. It includes the PowerBus logic interface (PBCQ),
> IOMMU support, a single PCIe Gen.4 Root Complex, and support for MSI
> and LSI interrupt sources as found on a POWER9 system using the XIVE
> interrupt controller.
> 
> POWER9 processor comes with 3 PHB4 PEC (PCI Express Controller) and
> each PEC can have several PHBs. By default,
> 
>   * PEC0 provides 1 PHB  (PHB0)
>   * PEC1 provides 2 PHBs (PHB1 and PHB2)
>   * PEC2 provides 3 PHBs (PHB3, PHB4 and PHB5)
> 
> Each PEC has a set  "global" registers and some "per-stack" (per-PHB)
> registers. Those are organized in two XSCOM ranges, the "Nest" range
> and the "PCI" range, each range contains both some "PEC" registers and
> some "per-stack" registers.
> 
> No default device layout is provided and PCI devices can be added on
> any of the available PCIe Root Port (pcie.0 .. 2 of a Power9 chip)
> with address 0x0 as the firwware (skiboot) only accepts a single
> device per root port. To run a simple system with a network and a
> storage adapters, use a command line options such as :
> 
>   -device e1000e,netdev=net0,mac=C0:FF:EE:00:00:02,bus=pcie.0,addr=0x0
>   -netdev 
> bridge,id=net0,helper=/usr/libexec/qemu-bridge-helper,br=virbr0,id=hostnet0
> 
>   -device megasas,id=scsi0,bus=pcie.1,addr=0x0
>   -drive file=$disk,if=none,id=drive-scsi0-0-0-0,format=qcow2,cache=none
>   -device 
> scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=2
> 
> If more are needed, include a bridge.
> 
> Multi chip is supported, each chip adding its set of PHB4 controllers
> and its PCI busses. The model doesn't emulate the EEH error handling.
> 
> This model is not ready for hotplug yet.
> 
> Signed-off-by: Benjamin Herrenschmidt 

Mostly LGTM, one query below.

> [ clg: - numerous cleanups
>- commit log
>- fix for broken LSI support
>- PHB pic printinfo
>- large QOM rework ]
> Signed-off-by: Cédric Le Goater 
> ---
>  include/hw/pci-host/pnv_phb4.h  |  230 +
>  include/hw/pci-host/pnv_phb4_regs.h |  553 ++
>  include/hw/pci/pcie_port.h  |1 +
>  include/hw/ppc/pnv.h|7 +
>  include/hw/ppc/pnv_xscom.h  |   11 +
>  hw/pci-host/pnv_phb4.c  | 1438 +++
>  hw/pci-host/pnv_phb4_pec.c  |  593 +++
>  hw/ppc/pnv.c|  107 ++
>  hw/pci-host/Makefile.objs   |1 +
>  hw/ppc/Kconfig  |2 +
>  10 files changed, 2943 insertions(+)
>  create mode 100644 include/hw/pci-host/pnv_phb4.h
>  create mode 100644 include/hw/pci-host/pnv_phb4_regs.h
>  create mode 100644 hw/pci-host/pnv_phb4.c
>  create mode 100644 hw/pci-host/pnv_phb4_pec.c
> 
> diff --git a/include/hw/pci-host/pnv_phb4.h b/include/hw/pci-host/pnv_phb4.h
> new file mode 100644
> index ..c882bfd0aa23
> --- /dev/null
> +++ b/include/hw/pci-host/pnv_phb4.h
> @@ -0,0 +1,230 @@
> +/*
> + * QEMU PowerPC PowerNV (POWER9) PHB4 model
> + *
> + * Copyright (c) 2018-2020, IBM Corporation.
> + *
> + * This code is licensed under the GPL version 2 or later. See the
> + * COPYING file in the top-level directory.
> + */
> +
> +#ifndef PCI_HOST_PNV_PHB4_H
> +#define PCI_HOST_PNV_PHB4_H
> +
> +#include "hw/pci/pcie_host.h"
> +#include "hw/pci/pcie_port.h"
> +#include "hw/ppc/xive.h"
> +
> +typedef struct PnvPhb4PecState PnvPhb4PecState;
> +typedef struct PnvPhb4PecStack PnvPhb4PecStack;
> +typedef struct PnvPHB4 PnvPHB4;
> +typedef struct PnvChip PnvChip;
> +
> +/*
> + * We have one such address space wrapper per possible device under
> + * the PHB since they need to be assigned statically at qemu device
> + * creation time. The relationship to a PE is done later
> + * dynamically. This means we can potentially create a lot of these
> + * guys. Q35 stores them as some kind of radix tree but we never
> + * really need to do fast lookups so instead we simply keep a QLIST of
> + * them for now, we can add the radix if needed later on.
> + *
> + * We do cache the PE number to speed things up a bit though.
> + */
> +typedef struct PnvPhb4DMASpace {
> +PCIBus *bus;
> +uint8_t devfn;
> +int pe_num; /* Cached PE number */
> +#define PHB_INVALID_PE (-1)
> +PnvPHB4 *phb;
> +AddressSpace dma_as;
> +IOMMUMemoryRegion dma_mr;
> +MemoryRegion msi32_mr;
> +MemoryRegion msi64_mr;
> +QLIST_ENTRY(PnvPhb4DMASpace) list;
> +} PnvPhb4DMASpace;
> +
> +/*
> + * PHB4 PCIe Root port
> + */
> +#define TYPE_PNV_PHB4_ROOT_BUS "pnv-phb4-root-bus"
> +#define TYPE_PNV_PHB4_ROOT_PORT "pnv-phb4-root-port"
> +
> +typedef struct PnvPHB4RootPort {
> +PCIESlot parent_obj;
> +} PnvPHB4RootPort;
> +
> +/*
> + * PHB4 PCIe Host Bridge for PowerNV machines (POWER9)
> + */
> +#define TYPE_PNV_PHB4 "pnv-phb4"

Re: [PATCH qemu] spapr_pci: Create assigned properties for bridges

2020-01-28 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200129023111.1699-1-...@ozlabs.ru/



Hi,

This series failed build test on FreeBSD host. Please find the details below.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
# Testing script will be invoked under the git checkout with
# HEAD pointing to a commit that has the patches applied on top of "base"
# branch
if qemu-system-x86_64 --help >/dev/null 2>&1; then
  QEMU=qemu-system-x86_64
elif /usr/libexec/qemu-kvm --help >/dev/null 2>&1; then
  QEMU=/usr/libexec/qemu-kvm
else
  exit 1
fi
make vm-build-freebsd J=21 QEMU=$QEMU
exit 0
=== TEST SCRIPT END ===




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

Re: [PATCH qemu] spapr_pci: Create assigned properties for bridges

2020-01-28 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200129023111.1699-1-...@ozlabs.ru/



Hi,

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

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




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

Re: [PATCH qemu] spapr_pci: Create assigned properties for bridges

2020-01-28 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200129023111.1699-1-...@ozlabs.ru/



Hi,

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

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




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

Re: [RFC PATCH] hw/arm/virt: Support NMI injection

2020-01-28 Thread Alexey Kardashevskiy



On 28/01/2020 17:48, Gavin Shan wrote:
> [including more folks into the discussion]
> 
>> On Fri, 17 Jan 2020 at 14:00, Peter Maydell 
>> wrote:
>>> On Thu, 19 Dec 2019 at 04:06, Gavin Shan  wrote:
 This supports NMI injection for virtual machine and currently it's only
 supported on GICv3 controller, which is emulated by qemu or host
 kernel.
 The design is highlighted as below:

 * The NMI is identified by its priority (0x20). In the guest (linux)
 kernel, the GICC_PMR is set to 0x80, to block all interrupts except
 the NMIs when the external interrupt is disabled. It means the FIQ
 and IRQ bit in PSTATE isn't touched when the functionality (NMI) is
 functional.
 * LPIs aren't considered as NMIs because of their nature. It means NMI
 is either SPI or PPI. Besides, the NMIs are injected in round-robin
 fashion is there are multiple NMIs existing.
 * When the GICv3 controller is emulated by qemu, the interrupt states
 (e.g. enabled, priority) is fetched from the corresponding data struct
 directly. However, we have to pause all CPUs to fetch the interrupt
 states from host in advance if the GICv3 controller is emulated by
 host.

 The testing scenario is to tweak guest (linux) kernel where the
 pl011 SPI
 can be enabled as NMI by request_nmi(). Check "/proc/interrupts"
 after injecting
 several NMIs, to see if the interrupt count is increased or not. The
 result
 is just as expected.

>>
>> So, QEMU is trying to emulate actual hardware. None of this
>> looks to me like what GICv3 hardware does... If you want to
>> have the virt board send an interrupt, do it the usual way
>> by wiring up a qemu_irq from some device to the GIC, please.
>> (More generally, there is no concept of an "NMI" in the GIC;
>> there are just interrupts at varying possible guest-programmable
>> priority levels.)
>>
> 
> Peter, I missed to read your reply in time and apologies for late response.
> 
> Yes, there is no concept of "NMI" in the GIC from hardware perspective.
> However, NMI has been supported from the software by kernel commit
> bc3c03ccb4641 ("arm64: Enable the support of pseudo-NMIs"). The NMIs
> have higher priority than normal ones. NMIs are deliverable after
> local_irq_disable() because the SYS_ICC_PMR_EL1 is tweaked so that
> normal interrupts are masked only.
> 
> It's unclear about the purpose of "nmi" QMP/HMP command. It's why I
> put a RFC tag. The command has been supported by multiple architects
> including x86/ppc. However, they are having different behaviors. The
> system will be restarted on ppc with this command,

We inject "system reset" as it is the closest thing to the idea of NMI
(could be a "machine check").

The system behaviour is configurable on POWERPC, it is either kdump
(store a system dump and reboot) or simple reboot or activate XMON
(in-kernel debugger, needs to be enabled beforehand).

The injector in QEMU is called NMIClass::nmi_monitor_handler and as the
name suggests it is not an NMI (the hardware concept which x86 may be
still has and others do not) but an "nmi" command of the QEMU monitor
which is rather a debug tool - "kick an unresponsive guest" - for us
(POWERPC).


> but a NMI is injected
> through LAPIC on x86. So I'm not sure what architect (system reset on
> ppc or injecting NMI on x86) aarch64 should follow.

I'd say whatever triggers in-kernel debugger or kdump but I am not
familiar with ARM at all :)


-- 
Alexey



[PATCH qemu] spapr_pci: Create assigned properties for bridges

2020-01-28 Thread Alexey Kardashevskiy
QEMU assigns bus numbers so tell the guest about assigned values.

This also adds an empty "ranges" to let the existing linux kernels proceed
far enough to trigger resource reassignment (which is rather a hack).

Signed-off-by: Alexey Kardashevskiy 
---

This is a part of the "kill CAS reboot" effort, the SLOF's side of it was
posted as "[PATCH slof] fdt: Fix creating new nodes at H_CAS"

---
 hw/ppc/spapr_pci.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 723373de732c..877ff1d0d5fa 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1336,7 +1336,23 @@ static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus 
*bus,
 if (pci_bus_is_root(bus)) {
 owner = OBJECT(sphb);
 } else {
-owner = OBJECT(pci_bridge_get_device(bus));
+PCIDevice *pdev = pci_bridge_get_device(bus);
+uint8_t pri = pci_default_read_config(pdev, PCI_PRIMARY_BUS, 1);
+uint8_t sec  = pci_default_read_config(pdev, PCI_SECONDARY_BUS, 1);
+uint8_t sub  = pci_default_read_config(pdev, PCI_SUBORDINATE_BUS, 1);
+uint32_t range[] = { cpu_to_be32(sec), cpu_to_be32(sub) };
+
+/*
+ * Create these to get existing Linux kernels proceed far enough to
+ * trigger resource reassignment. We creates these for vPHB already.
+ */
+_FDT(fdt_setprop_cell(fdt, offset, "primary-bus", pri));
+_FDT(fdt_setprop_cell(fdt, offset, "secondary-bus", sec));
+_FDT(fdt_setprop_cell(fdt, offset, "subordinate-bus", sub));
+_FDT(fdt_setprop(fdt, offset, "bus-range", range, sizeof(range)));
+_FDT(fdt_setprop_string(fdt, offset, "device_type", "pci"));
+_FDT(fdt_setprop(fdt, offset, "ranges", NULL, 0));
+owner = OBJECT(pdev);
 }
 
 ret = spapr_dt_drc(fdt, offset, owner,
-- 
2.17.1




Re: [PATCH 0/3] ppc/pnv: Add a "hostboot" mode

2020-01-28 Thread David Gibson
On Mon, Jan 27, 2020 at 03:41:51PM +0100, Cédric Le Goater wrote:
> Hello,
> 
> The QEMU PowerNV machine was first designed to start with a skiboot
> firmware at 0x0, which then loads a kernel and ramfs acting as a boot
> loader. Support of the POWER processor improving in QEMU, it has been
> possible to support other firmwares.
> 
> These changes add support for firmwares mapped at a different address
> than 0x0. First two patches are fixes/cleanups and the last one adds a
> "hb-mode" option to the machine for this purpose. It needs some
> discussion to see how we want to activate this new mode.

Applied to ppc-for-5.0, thanks.

> 
> Thanks,
> 
> C.
> 
> Cédric Le Goater (3):
>   ppc/pnv: Add support for HRMOR on Radix host
>   ppc/pnv: remove useless "core-pir" property alias.
>   ppc/pnv: Add support for "hostboot" mode
> 
>  include/hw/ppc/pnv.h  |  2 ++
>  include/hw/ppc/pnv_core.h |  1 +
>  hw/ppc/pnv.c  | 28 +++-
>  hw/ppc/pnv_core.c | 31 ---
>  hw/ppc/pnv_lpc.c  |  5 -
>  target/ppc/mmu-radix64.c  |  6 ++
>  6 files changed, 56 insertions(+), 17 deletions(-)
> 

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


signature.asc
Description: PGP signature


Re: [PATCH v9 0/6] Add vTPM emulator support for ppc64 platform

2020-01-28 Thread David Gibson
On Tue, Jan 21, 2020 at 10:29:29AM -0500, Stefan Berger wrote:
> 
> The following series of patches adds vTPM emulator support for the
> ppc64 platform (pSeries). 
> 
> It can be tested as follows with swtpm/libtpms:
> 
> mkdir /tmp/mytpm1
> swtpm socket --tpmstate dir=/tmp/mytpm1 \
>   --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
>   --log level=20
> 
> If TPM 2 is desired, add --tpm2 as parameter to the above.
> 
> In another terminal start QEMU:
> 
> sudo ./ppc64-softmmu/qemu-system-ppc64 -display sdl \
>   -machine pseries,accel=kvm \
>   -m 1024 -bios slof.bin -boot menu=on \
>   -nodefaults -device VGA -device pci-ohci -device usb-kbd \
>   -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
>   -tpmdev emulator,id=tpm0,chardev=chrtpm \
>   -device tpm-spapr,tpmdev=tpm0 \
>   -device spapr-vscsi,id=scsi0,reg=0x2000 \
>   -device 
> virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,id=virtio-disk0
>  \
>   -drive file=test.img,format=raw,if=none,id=drive-virtio-disk0
> 
> Links:
>  - libtpms: https://github.com/stefanberger/libtpms/wiki
>  - swtpm: https://github.com/stefanberger/swtpm/wiki

Applied to ppc-for-5.0, thanks.

> 
> Changes:
>  v8->v9:
>   - Allocating buffer now so we can use VMSTATE_VBUFFER_UINT32 for the regular
> buffer (no more suspend buffer)
> 
>  v7->v8:
>   - Folded documentation patch into 3rd patch
>   - Added Marc-André's patch to end of series
> 
>  v6->v7:
>   - Implemented get_dt_compatible() and using it
>   - Moved tpm_this_show_buffer to tpm_util.c
> 
>  v5->v6:
>   - adjusted names of structures and simplified
>   - only transmitting min. necessary bytes to pass to VM after resume
>   - addressed other issues pointed out by D. Gibson
> 
>  v4->v5:
>   - use runstate_check(RUN_STATE_FINISH_MIGRATE) to check whether devices
> are suspending; ditch 3 patches in this series that tried to do similar
> 
>  v3->v4:
>   - addressed comments to v3
>   - reworked suspend/resume support that requires extensions to backends
> 
>  v2->v3:
>   - patch 1: a TPM 2 is identified by IBM,vtpm20 in the compatible node
>   - patch 1: convert to tracing to display Tx and Rx buffers
>   - added documentation patch
>   - added patch to enable TPM device as part of pSeries
> 
>  v1->v2:
>   - followed Cedric Le Goater's suggestions to patch 1
>   - send appropriate CRQ error responses if DMA read or write fails
>   - renamed tpm_spapr_got_payload to tpm_spapr_process_cmd and
> pass endianess-adjusted data pointer from CRQ to it
> 
> Regards,
> Stefan
> 
> 
> Marc-André Lureau (1):
>   docs/specs/tpm: reST-ify TPM documentation
> 
> Stefan Berger (5):
>   tpm: Move tpm_tis_show_buffer to tpm_util.c
>   spapr: Implement get_dt_compatible() callback
>   tpm_spapr: Support TPM for ppc64 using CRQ based interface
>   tpm_spapr: Support suspend and resume
>   hw/ppc/Kconfig: Enable TPM_SPAPR as part of PSERIES config
> 
>  docs/specs/index.rst   |   1 +
>  docs/specs/tpm.rst | 503 +
>  docs/specs/tpm.txt | 427 ---
>  hw/ppc/Kconfig |   1 +
>  hw/ppc/spapr_vio.c |  11 +-
>  hw/tpm/Kconfig |   6 +
>  hw/tpm/Makefile.objs   |   1 +
>  hw/tpm/tpm_spapr.c | 429 +++
>  hw/tpm/tpm_tis.c   |  32 +--
>  hw/tpm/tpm_util.c  |  25 ++
>  hw/tpm/tpm_util.h  |   3 +
>  hw/tpm/trace-events|  16 +-
>  include/hw/ppc/spapr_vio.h |   1 +
>  include/sysemu/tpm.h   |   3 +
>  qapi/tpm.json  |   6 +-
>  15 files changed, 1004 insertions(+), 461 deletions(-)
>  create mode 100644 docs/specs/tpm.rst
>  delete mode 100644 docs/specs/tpm.txt
>  create mode 100644 hw/tpm/tpm_spapr.c
> 

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


signature.asc
Description: PGP signature


Re: Debugging heterogeneous SoC

2020-01-28 Thread Nikita Ermakov
On Wed, 29 Jan 2020 at 03:43, Alistair Francis  wrote:

> Use these commands to attach GDB to QEMU:
>
> target extended-remote :1234
> add-inferior
> inferior 2
> attach 2
> set schedule-multiple
> info threads
>
> Alistair
>
Thank you! It is worked! :)

-- 
Thanks,
Nikita
B8 00 4C CD 21


Re: Debugging heterogeneous SoC

2020-01-28 Thread Alistair Francis
On Tue, Jan 28, 2020 at 4:29 PM Nikita Ermakov  wrote:
>
> Hello,
>
> I am trying to debug the sifive_u SoC in the QEMU with GDB.
> SiFive Unleashed contains one E51 core and four U54 cores.
> In the hw/riscv/sifve_u.c E51 and U54 cores are placed in the different CPU 
> clusters.
> In the gdbstub.c, it is searches only the first cluster and it always finds 
> cluster with E51 core, if I understand it correctly.
> In the GDB with `info threads` I could see only E51 core but none of the U54 
> cores.
>
> Is it possible to somehow get an access to another CPU cluster in the 
> GDB/QEMU?

Use these commands to attach GDB to QEMU:

target extended-remote :1234
add-inferior
inferior 2
attach 2
set schedule-multiple
info threads

Alistair

>
> --
> Thanks,
> Nikita
> B8 00 4C CD 21



Debugging heterogeneous SoC

2020-01-28 Thread Nikita Ermakov
Hello,

I am trying to debug the sifive_u SoC in the QEMU with GDB.
SiFive Unleashed contains one E51 core and four U54 cores.
In the hw/riscv/sifve_u.c E51 and U54 cores are placed in the different CPU
clusters.
In the gdbstub.c, it is searches only the first cluster and it always finds
cluster with E51 core, if I understand it correctly.
In the GDB with `info threads` I could see only E51 core but none of the
U54 cores.

Is it possible to somehow get an access to another CPU cluster in the
GDB/QEMU?

-- 
Thanks,
Nikita
B8 00 4C CD 21


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

2020-01-28 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200128231840.508986-1-kei...@keithp.com/



Hi,

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

Type: series
Message-id: 20200128231840.508986-1-kei...@keithp.com
Subject: [PATCH] riscv: Add semihosting support [v3]

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20200128233216.515171-1-kei...@keithp.com -> 
patchew/20200128233216.515171-1-kei...@keithp.com
Switched to a new branch 'test'
a3ca2be riscv: Add semihosting support [v3]

=== OUTPUT BEGIN ===
WARNING: Block comments use a leading /* on a separate line
#131: FILE: target/riscv/insn_trans/trans_privileged.inc.c:36:
+/* The RISC-V semihosting spec specifies the following

WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#153: 
new file mode 100644

WARNING: Block comments use a leading /* on a separate line
#223: FILE: target/riscv/riscv-semi.c:66:
+/* ADP_Stopped_ApplicationExit is used for exit(0),

WARNING: Block comments use a trailing */ on a separate line
#224: FILE: target/riscv/riscv-semi.c:67:
+ * anything else is implemented as exit(1) */

WARNING: Block comments use a leading /* on a separate line
#453: FILE: target/riscv/riscv-semi.c:296:
+/* Return an address in target memory of 64 bytes where the remote

WARNING: Block comments use a leading /* on a separate line
#470: FILE: target/riscv/riscv-semi.c:313:
+/* The size is always stored in big-endian order, extract

WARNING: Block comments use * on subsequent lines
#471: FILE: target/riscv/riscv-semi.c:314:
+/* The size is always stored in big-endian order, extract
+   the value. We assume the size always fit in 32 bits.  */

WARNING: Block comments use a trailing */ on a separate line
#471: FILE: target/riscv/riscv-semi.c:314:
+   the value. We assume the size always fit in 32 bits.  */

WARNING: Block comments use a leading /* on a separate line
#778: FILE: target/riscv/riscv-semi.c:621:
+/* Read the input value from the argument block; fail the semihosting

ERROR: "foo * bar" should be "foo *bar"
#806: FILE: target/riscv/riscv-semi.c:649:
+char * s;

WARNING: line over 80 characters
#875: FILE: target/riscv/riscv-semi.c:718:
+ret = riscv_gdb_syscall(cpu, riscv_semi_open_cb, "open,%s,%x,1a4", 
arg0,

ERROR: spaces required around that '+' (ctx:VxV)
#876: FILE: target/riscv/riscv-semi.c:719:
+  (int)arg2+1, gdb_open_modeflags[arg1]);
^

ERROR: spaces required around that '+' (ctx:VxV)
#973: FILE: target/riscv/riscv-semi.c:816:
+  arg0, (int)arg1+1);
  ^

ERROR: spaces required around that '+' (ctx:VxV)
#991: FILE: target/riscv/riscv-semi.c:834:
+   arg0, (int)arg1+1, arg2, (int)arg3+1);
   ^

ERROR: spaces required around that '+' (ctx:VxV)
#991: FILE: target/riscv/riscv-semi.c:834:
+   arg0, (int)arg1+1, arg2, (int)arg3+1);
  ^

ERROR: braces {} are necessary for all arms of this statement
#1002: FILE: target/riscv/riscv-semi.c:845:
+if (s2)
[...]

ERROR: braces {} are necessary for all arms of this statement
#1004: FILE: target/riscv/riscv-semi.c:847:
+if (s)
[...]

ERROR: spaces required around that '+' (ctx:VxV)
#1017: FILE: target/riscv/riscv-semi.c:860:
+   arg0, (int)arg1+1);
   ^

WARNING: Block comments use a leading /* on a separate line
#1032: FILE: target/riscv/riscv-semi.c:875:
+/* Build a command-line from the original argv.

WARNING: line over 80 characters
#1176: FILE: target/riscv/riscv-semi.c:1019:
+fail = put_user_ual(retvals[i], arg0 + i * 
sizeof(target_ulong));

total: 8 errors, 12 warnings, 1197 lines checked

Commit a3ca2be73efc (riscv: Add semihosting support [v3]) has style problems, 
please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


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

Re: [PATCH] riscv: Separate FPU register size from core register size in gdbstub

2020-01-28 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200128223955.464556-1-kei...@keithp.com/



Hi,

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

Type: series
Message-id: 20200128223955.464556-1-kei...@keithp.com
Subject: [PATCH] riscv: Separate FPU register size from core register size in 
gdbstub

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  
patchew/1580242161-20333-1-git-send-email-aleksandar.marko...@rt-rk.com -> 
patchew/1580242161-20333-1-git-send-email-aleksandar.marko...@rt-rk.com
 - [tag update]  patchew/20200128223955.464556-1-kei...@keithp.com -> 
patchew/20200128223955.464556-1-kei...@keithp.com
 * [new tag] patchew/20200128231840.508986-1-kei...@keithp.com -> 
patchew/20200128231840.508986-1-kei...@keithp.com
 * [new tag] patchew/20200128233216.515171-1-kei...@keithp.com -> 
patchew/20200128233216.515171-1-kei...@keithp.com
Switched to a new branch 'test'
a2c277b riscv: Separate FPU register size from core register size in gdbstub

=== OUTPUT BEGIN ===
ERROR: braces {} are necessary for all arms of this statement
#45: FILE: target/riscv/gdbstub.c:306:
+if (env->misa & RVD)
[...]

total: 1 errors, 0 warnings, 54 lines checked

Commit a2c277b8eb39 (riscv: Separate FPU register size from core register size 
in gdbstub) has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


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

Re: [PATCH] riscv: Separate FPU register size from core register size in gdbstub [v2]

2020-01-28 Thread Alistair Francis
On Tue, Jan 28, 2020 at 3:33 PM Keith Packard via  wrote:
>
> The size of the FPU registers is dictated by the 'f' and 'd' features,
> not the core processor register size. Processors with the 'd' feature
> have 64-bit FPU registers. Processors without the 'd' feature but with
> the 'f' feature have 32-bit FPU registers.
>
> Signed-off-by: Keith Packard 

Reviewed-by: Alistair Francis 

Alistair

>
> ---
>
> v2:
> Fix checkpatch formatting complaints.
> ---
>  configure  |  4 ++--
>  target/riscv/gdbstub.c | 20 +++-
>  2 files changed, 13 insertions(+), 11 deletions(-)
>
> diff --git a/configure b/configure
> index a72a5def57..c21bff8d10 100755
> --- a/configure
> +++ b/configure
> @@ -7709,13 +7709,13 @@ case "$target_name" in
>  TARGET_BASE_ARCH=riscv
>  TARGET_ABI_DIR=riscv
>  mttcg=yes
> -gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml 
> riscv-32bit-csr.xml riscv-32bit-virtual.xml"
> +gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml 
> riscv-64bit-fpu.xml riscv-32bit-csr.xml riscv-32bit-virtual.xml"
>;;
>riscv64)
>  TARGET_BASE_ARCH=riscv
>  TARGET_ABI_DIR=riscv
>  mttcg=yes
> -gdb_xml_files="riscv-64bit-cpu.xml riscv-64bit-fpu.xml 
> riscv-64bit-csr.xml riscv-64bit-virtual.xml"
> +gdb_xml_files="riscv-64bit-cpu.xml riscv-32bit-fpu.xml 
> riscv-64bit-fpu.xml riscv-64bit-csr.xml riscv-64bit-virtual.xml"
>;;
>sh4|sh4eb)
>  TARGET_ARCH=sh4
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index 1a7947e019..1a72f7be9c 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -303,7 +303,12 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t 
> *mem_buf, int n)
>  static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
>  {
>  if (n < 32) {
> -return gdb_get_reg64(mem_buf, env->fpr[n]);
> +if (env->misa & RVD) {
> +return gdb_get_reg64(mem_buf, env->fpr[n]);
> +}
> +if (env->misa & RVF) {
> +return gdb_get_reg32(mem_buf, env->fpr[n]);
> +}
>  /* there is hole between ft11 and fflags in fpu.xml */
>  } else if (n < 36 && n > 32) {
>  target_ulong val = 0;
> @@ -403,23 +408,20 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState 
> *cs)
>  {
>  RISCVCPU *cpu = RISCV_CPU(cs);
>  CPURISCVState *env = >env;
> -#if defined(TARGET_RISCV32)
> -if (env->misa & RVF) {
> +if (env->misa & RVD) {
> +gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
> + 36, "riscv-64bit-fpu.xml", 0);
> +} else if (env->misa & RVF) {
>  gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
>   36, "riscv-32bit-fpu.xml", 0);
>  }
> -
> +#if defined(TARGET_RISCV32)
>  gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
>   240, "riscv-32bit-csr.xml", 0);
>
>  gdb_register_coprocessor(cs, riscv_gdb_get_virtual, 
> riscv_gdb_set_virtual,
>   1, "riscv-32bit-virtual.xml", 0);
>  #elif defined(TARGET_RISCV64)
> -if (env->misa & RVF) {
> -gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
> - 36, "riscv-64bit-fpu.xml", 0);
> -}
> -
>  gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
>   240, "riscv-64bit-csr.xml", 0);
>
> --
> 2.25.0
>
>



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

2020-01-28 Thread Keith Packard
Keith Packard  writes:

> Adapt the arm semihosting support code for RISCV. This implementation
> is based on the standard for RISC-V semihosting as documented in

Sorry for the noise on the list; I failed to run checkpatch.pl before
submitting. I've re-submittd [v4] with the formatting errors corrected.

-- 
-keith


signature.asc
Description: PGP signature


Re: [PATCH] riscv: Separate FPU register size from core register size in gdbstub

2020-01-28 Thread Keith Packard
Alistair Francis  writes:

> You need brackets around all if statements, besides that:

Sorry for the noise; I caught that and sent another version of this
patch.

> Reviewed-by: Alistair Francis 

Thanks for your review!

-- 
-keith


signature.asc
Description: PGP signature


[PATCH] riscv: Separate FPU register size from core register size in gdbstub [v2]

2020-01-28 Thread Keith Packard via
The size of the FPU registers is dictated by the 'f' and 'd' features,
not the core processor register size. Processors with the 'd' feature
have 64-bit FPU registers. Processors without the 'd' feature but with
the 'f' feature have 32-bit FPU registers.

Signed-off-by: Keith Packard 

---

v2:
Fix checkpatch formatting complaints.
---
 configure  |  4 ++--
 target/riscv/gdbstub.c | 20 +++-
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/configure b/configure
index a72a5def57..c21bff8d10 100755
--- a/configure
+++ b/configure
@@ -7709,13 +7709,13 @@ case "$target_name" in
 TARGET_BASE_ARCH=riscv
 TARGET_ABI_DIR=riscv
 mttcg=yes
-gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-32bit-csr.xml 
riscv-32bit-virtual.xml"
+gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml 
riscv-32bit-csr.xml riscv-32bit-virtual.xml"
   ;;
   riscv64)
 TARGET_BASE_ARCH=riscv
 TARGET_ABI_DIR=riscv
 mttcg=yes
-gdb_xml_files="riscv-64bit-cpu.xml riscv-64bit-fpu.xml riscv-64bit-csr.xml 
riscv-64bit-virtual.xml"
+gdb_xml_files="riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml 
riscv-64bit-csr.xml riscv-64bit-virtual.xml"
   ;;
   sh4|sh4eb)
 TARGET_ARCH=sh4
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 1a7947e019..1a72f7be9c 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -303,7 +303,12 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
 {
 if (n < 32) {
-return gdb_get_reg64(mem_buf, env->fpr[n]);
+if (env->misa & RVD) {
+return gdb_get_reg64(mem_buf, env->fpr[n]);
+}
+if (env->misa & RVF) {
+return gdb_get_reg32(mem_buf, env->fpr[n]);
+}
 /* there is hole between ft11 and fflags in fpu.xml */
 } else if (n < 36 && n > 32) {
 target_ulong val = 0;
@@ -403,23 +408,20 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState 
*cs)
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
-#if defined(TARGET_RISCV32)
-if (env->misa & RVF) {
+if (env->misa & RVD) {
+gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
+ 36, "riscv-64bit-fpu.xml", 0);
+} else if (env->misa & RVF) {
 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
  36, "riscv-32bit-fpu.xml", 0);
 }
-
+#if defined(TARGET_RISCV32)
 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
  240, "riscv-32bit-csr.xml", 0);
 
 gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
  1, "riscv-32bit-virtual.xml", 0);
 #elif defined(TARGET_RISCV64)
-if (env->misa & RVF) {
-gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
- 36, "riscv-64bit-fpu.xml", 0);
-}
-
 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
  240, "riscv-64bit-csr.xml", 0);
 
-- 
2.25.0




[PATCH] riscv: Add semihosting support [v4]

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

https://riscv.org/specifications/

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
---
 default-configs/riscv32-softmmu.mak   |1 +
 linux-user/qemu.h |2 +
 qemu-options.hx   |4 +-
 target/riscv/Makefile.objs|2 +-
 target/riscv/cpu.h|2 +
 target/riscv/cpu_bits.h   |1 +
 target/riscv/cpu_helper.c |9 +
 .../riscv/insn_trans/trans_privileged.inc.c   |   24 +-
 target/riscv/riscv-semi.c | 1084 +
 target/riscv/translate.c  |   11 +
 10 files changed, 1136 insertions(+), 4 deletions(-)
 create mode 100644 target/riscv/riscv-semi.c

diff --git a/default-configs/riscv32-softmmu.mak 
b/default-configs/riscv32-softmmu.mak
index 1ae077ed87..21b7bedf19 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/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/linux-user/qemu.h b/linux-user/qemu.h
index 560a68090e..122d95d6b6 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)
diff --git a/qemu-options.hx b/qemu-options.hx
index 224a8e8712..4892e6b12c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4109,7 +4109,7 @@ ETEXI
 DEF("semihosting", 0, QEMU_OPTION_semihosting,
 "-semihostingsemihosting mode\n",
 QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 |
-QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2)
+QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
 STEXI
 @item -semihosting
 @findex -semihosting
@@ -4119,7 +4119,7 @@ DEF("semihosting-config", HAS_ARG, 
QEMU_OPTION_semihosting_config,
 "-semihosting-config 
[enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]\n" \
 "semihosting configuration\n",
 QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 |
-QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2)
+QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
 STEXI
 @item -semihosting-config 
[enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]
 @findex -semihosting-config
diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index ff651f69f6..6fd7f40e29 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
gdbstub.o
+obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
gdbstub.o riscv-semi.o
 obj-$(CONFIG_SOFTMMU) += pmp.o
 
 ifeq ($(CONFIG_SOFTMMU),y)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index de0a8d893a..310ec6ab40 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -338,6 +338,8 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
 typedef CPURISCVState CPUArchState;
 typedef RISCVCPU ArchCPU;
 
+target_ulong do_riscv_semihosting(CPURISCVState *env);
+
 #include "exec/cpu-all.h"
 
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index e99834856c..c45745d73b 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -496,6 +496,7 @@
 #define RISCV_EXCP_INST_PAGE_FAULT 0xc /* since: priv-1.10.0 */
 #define RISCV_EXCP_LOAD_PAGE_FAULT 0xd /* since: priv-1.10.0 */
 #define RISCV_EXCP_STORE_PAGE_FAULT0xf /* since: priv-1.10.0 */
+#define RISCV_EXCP_SEMIHOST0x10
 
 #define RISCV_EXCP_INT_FLAG0x8000
 #define RISCV_EXCP_INT_MASK0x7fff
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 85403da9c8..6a04469936 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -532,6 +532,15 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 [PRV_M] = RISCV_EXCP_M_ECALL
 };
 
+if  (cause == RISCV_EXCP_SEMIHOST) {
+if (env->priv >= PRV_S) {
+env->gpr[xA0] = do_riscv_semihosting(env);
+env->pc += 4;
+return;
+}
+cause = RISCV_EXCP_BREAKPOINT;
+}
+
 if (!async) {
 /* set tval to badaddr for traps with address information */
 switch (cause) {
diff --git a/target/riscv/insn_trans/trans_privileged.inc.c 

[PATCH] riscv: Add semihosting support [v3]

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

https://riscv.org/specifications/

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.
---
 default-configs/riscv32-softmmu.mak   |1 +
 linux-user/qemu.h |2 +
 qemu-options.hx   |4 +-
 target/riscv/Makefile.objs|2 +-
 target/riscv/cpu.h|2 +
 target/riscv/cpu_bits.h   |1 +
 target/riscv/cpu_helper.c |9 +
 .../riscv/insn_trans/trans_privileged.inc.c   |   23 +-
 target/riscv/riscv-semi.c | 1073 +
 target/riscv/translate.c  |   11 +
 10 files changed, 1124 insertions(+), 4 deletions(-)
 create mode 100644 target/riscv/riscv-semi.c

diff --git a/default-configs/riscv32-softmmu.mak 
b/default-configs/riscv32-softmmu.mak
index 1ae077ed87..21b7bedf19 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/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/linux-user/qemu.h b/linux-user/qemu.h
index 560a68090e..122d95d6b6 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)
diff --git a/qemu-options.hx b/qemu-options.hx
index 224a8e8712..4892e6b12c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4109,7 +4109,7 @@ ETEXI
 DEF("semihosting", 0, QEMU_OPTION_semihosting,
 "-semihostingsemihosting mode\n",
 QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 |
-QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2)
+QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
 STEXI
 @item -semihosting
 @findex -semihosting
@@ -4119,7 +4119,7 @@ DEF("semihosting-config", HAS_ARG, 
QEMU_OPTION_semihosting_config,
 "-semihosting-config 
[enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]\n" \
 "semihosting configuration\n",
 QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 |
-QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2)
+QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
 STEXI
 @item -semihosting-config 
[enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]
 @findex -semihosting-config
diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index ff651f69f6..6fd7f40e29 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
gdbstub.o
+obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
gdbstub.o riscv-semi.o
 obj-$(CONFIG_SOFTMMU) += pmp.o
 
 ifeq ($(CONFIG_SOFTMMU),y)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index de0a8d893a..310ec6ab40 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -338,6 +338,8 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
 typedef CPURISCVState CPUArchState;
 typedef RISCVCPU ArchCPU;
 
+target_ulong do_riscv_semihosting(CPURISCVState *env);
+
 #include "exec/cpu-all.h"
 
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index e99834856c..c45745d73b 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -496,6 +496,7 @@
 #define RISCV_EXCP_INST_PAGE_FAULT 0xc /* since: priv-1.10.0 */
 #define RISCV_EXCP_LOAD_PAGE_FAULT 0xd /* since: priv-1.10.0 */
 #define RISCV_EXCP_STORE_PAGE_FAULT0xf /* since: priv-1.10.0 */
+#define RISCV_EXCP_SEMIHOST0x10
 
 #define RISCV_EXCP_INT_FLAG0x8000
 #define RISCV_EXCP_INT_MASK0x7fff
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 85403da9c8..6a04469936 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -532,6 +532,15 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 [PRV_M] = RISCV_EXCP_M_ECALL
 };
 
+if  (cause == RISCV_EXCP_SEMIHOST) {
+if (env->priv >= PRV_S) {
+env->gpr[xA0] = do_riscv_semihosting(env);
+env->pc += 4;
+return;
+}
+cause = RISCV_EXCP_BREAKPOINT;
+}
+
 if (!async) {
 /* set tval to badaddr for traps with address information */
 switch (cause) {
diff --git a/target/riscv/insn_trans/trans_privileged.inc.c 
b/target/riscv/insn_trans/trans_privileged.inc.c
index c5e4b3e49a..ddc26e889f 100644
--- 

Re: [PATCH] riscv: Separate FPU register size from core register size in gdbstub

2020-01-28 Thread Alistair Francis
On Tue, Jan 28, 2020 at 2:40 PM Keith Packard via  wrote:
>
> The size of the FPU registers is dictated by the 'f' and 'd' features,
> not the core processor register size. Processors with the 'd' feature
> have 64-bit FPU registers. Processors without the 'd' feature but with
> the 'f' feature have 32-bit FPU registers.
>
> Signed-off-by: Keith Packard 
> ---
>  configure  |  4 ++--
>  target/riscv/gdbstub.c | 18 +-
>  2 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/configure b/configure
> index a72a5def57..c21bff8d10 100755
> --- a/configure
> +++ b/configure
> @@ -7709,13 +7709,13 @@ case "$target_name" in
>  TARGET_BASE_ARCH=riscv
>  TARGET_ABI_DIR=riscv
>  mttcg=yes
> -gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml 
> riscv-32bit-csr.xml riscv-32bit-virtual.xml"
> +gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml 
> riscv-64bit-fpu.xml riscv-32bit-csr.xml riscv-32bit-virtual.xml"
>;;
>riscv64)
>  TARGET_BASE_ARCH=riscv
>  TARGET_ABI_DIR=riscv
>  mttcg=yes
> -gdb_xml_files="riscv-64bit-cpu.xml riscv-64bit-fpu.xml 
> riscv-64bit-csr.xml riscv-64bit-virtual.xml"
> +gdb_xml_files="riscv-64bit-cpu.xml riscv-32bit-fpu.xml 
> riscv-64bit-fpu.xml riscv-64bit-csr.xml riscv-64bit-virtual.xml"
>;;
>sh4|sh4eb)
>  TARGET_ARCH=sh4
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index 1a7947e019..c1803a5916 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -303,7 +303,10 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t 
> *mem_buf, int n)
>  static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
>  {
>  if (n < 32) {
> -return gdb_get_reg64(mem_buf, env->fpr[n]);
> +if (env->misa & RVD)
> +return gdb_get_reg64(mem_buf, env->fpr[n]);
> +if (env->misa & RVF)
> +return gdb_get_reg32(mem_buf, env->fpr[n]);

You need brackets around all if statements, besides that:

Reviewed-by: Alistair Francis 

Alistair

>  /* there is hole between ft11 and fflags in fpu.xml */
>  } else if (n < 36 && n > 32) {
>  target_ulong val = 0;
> @@ -403,23 +406,20 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState 
> *cs)
>  {
>  RISCVCPU *cpu = RISCV_CPU(cs);
>  CPURISCVState *env = >env;
> -#if defined(TARGET_RISCV32)
> -if (env->misa & RVF) {
> +if (env->misa & RVD) {
> +gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
> + 36, "riscv-64bit-fpu.xml", 0);
> +} else if (env->misa & RVF) {
>  gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
>   36, "riscv-32bit-fpu.xml", 0);
>  }
> -
> +#if defined(TARGET_RISCV32)
>  gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
>   240, "riscv-32bit-csr.xml", 0);
>
>  gdb_register_coprocessor(cs, riscv_gdb_get_virtual, 
> riscv_gdb_set_virtual,
>   1, "riscv-32bit-virtual.xml", 0);
>  #elif defined(TARGET_RISCV64)
> -if (env->misa & RVF) {
> -gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
> - 36, "riscv-64bit-fpu.xml", 0);
> -}
> -
>  gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
>   240, "riscv-64bit-csr.xml", 0);
>
> --
> 2.25.0
>
>



Re: [PULL 4/6] hw/core/loader: Let load_elf() populate the processor-specific flags

2020-01-28 Thread Aleksandar Markovic
21:10 Uto, 28.01.2020. Aleksandar Markovic 
је написао/ла:
>
> From: Philippe Mathieu-Daudé 
>

Unfortunately, some spelling errors of mine slipped through the cracks:

> While loading the executable, some platforms (like AVR) need to
> determine CPU type that executable is built for by reading the
> field 'e_flags' of the ELF header of tha executable.
>

s/tha/the

> This patch enables such discovery of that field while using any
> of the following functions:
>
>   - load_elf()
>   - load_elf_as()
>   - load_elf_ram()
>   - load_elf_ram_sym()
>
> The argument added to these functions is called 'pflags' and is of
> type 'uint32_t*' (that matches the the pointer to the 'elf_word' -

s/the the/the

May I ask you, Peter, to fix them while applying?

Regards,
Aleksandar

> the type of the field 'e_flags' in both 32-bit and 64-bit variants
> of ELF header). Callers are allowed to pass NULL as that argument,
> and in such case no lookup to the field 'e_flags' will happen, and
> no information will be returned, of course.
>
> CC: Richard Henderson 
> CC: Peter Maydell 
> CC: Edgar E. Iglesias 
> CC: Michael Walle 
> CC: Thomas Huth 
> CC: Laurent Vivier 
> CC: Philippe Mathieu-Daudé 
> CC: Aleksandar Rikalo 
> CC: Aurelien Jarno 
> CC: Jia Liu 
> CC: David Gibson 
> CC: Mark Cave-Ayland 
> CC: BALATON Zoltan 
> CC: Christian Borntraeger 
> CC: Thomas Huth 
> CC: Artyom Tarasenko 
> CC: Fabien Chouteau 
> CC: KONRAD Frederic 
> CC: Max Filippov 
>
> Reviewed-by: Aleksandar Markovic 
> Signed-off-by: Michael Rolnik 
> Signed-off-by: Philippe Mathieu-Daudé 
> Signed-off-by: Aleksandar Markovic 
> Message-Id: <
1580079311-20447-24-git-send-email-aleksandar.marko...@rt-rk.com>
> ---
>  hw/alpha/dp264.c   |  4 ++--
>  hw/arm/armv7m.c|  2 +-
>  hw/arm/boot.c  |  2 +-
>  hw/core/generic-loader.c   |  2 +-
>  hw/core/loader.c   | 37 +++--
>  hw/cris/boot.c |  2 +-
>  hw/hppa/machine.c  |  4 ++--
>  hw/i386/multiboot.c|  2 +-
>  hw/i386/x86.c  |  2 +-
>  hw/lm32/lm32_boards.c  |  4 ++--
>  hw/lm32/milkymist.c|  2 +-
>  hw/m68k/an5206.c   |  2 +-
>  hw/m68k/mcf5208.c  |  2 +-
>  hw/m68k/q800.c |  2 +-
>  hw/microblaze/boot.c   |  4 ++--
>  hw/mips/mips_fulong2e.c|  2 +-
>  hw/mips/mips_malta.c   |  3 ++-
>  hw/mips/mips_mipssim.c |  2 +-
>  hw/mips/mips_r4k.c |  2 +-
>  hw/moxie/moxiesim.c|  2 +-
>  hw/nios2/boot.c|  4 ++--
>  hw/openrisc/openrisc_sim.c |  2 +-
>  hw/pci-host/prep.c |  3 ++-
>  hw/ppc/e500.c  |  2 +-
>  hw/ppc/mac_newworld.c  |  4 ++--
>  hw/ppc/mac_oldworld.c  |  4 ++--
>  hw/ppc/ppc440_bamboo.c |  2 +-
>  hw/ppc/sam460ex.c  |  3 ++-
>  hw/ppc/spapr.c |  6 +++---
>  hw/ppc/virtex_ml507.c  |  2 +-
>  hw/riscv/boot.c|  4 ++--
>  hw/s390x/ipl.c |  7 ---
>  hw/sparc/leon3.c   |  2 +-
>  hw/sparc/sun4m.c   |  4 ++--
>  hw/sparc64/sun4u.c |  5 +++--
>  hw/tricore/tricore_testboard.c |  2 +-
>  hw/xtensa/sim.c|  2 +-
>  hw/xtensa/xtfpga.c |  2 +-
>  include/hw/elf_ops.h   |  6 +-
>  include/hw/loader.h| 21 -
>  40 files changed, 92 insertions(+), 79 deletions(-)
>
> diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
> index f2026fd..a8f9a89 100644
> --- a/hw/alpha/dp264.c
> +++ b/hw/alpha/dp264.c
> @@ -115,7 +115,7 @@ static void clipper_init(MachineState *machine)
>  exit(1);
>  }
>  size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
> -NULL, _entry, _low, _high,
> +NULL, _entry, _low, _high,
NULL,
>  0, EM_ALPHA, 0, 0);
>  if (size < 0) {
>  error_report("could not load palcode '%s'", palcode_filename);
> @@ -134,7 +134,7 @@ static void clipper_init(MachineState *machine)
>  uint64_t param_offset;
>
>  size = load_elf(kernel_filename, NULL,
cpu_alpha_superpage_to_phys,
> -NULL, _entry, _low, _high,
> +NULL, _entry, _low, _high,
NULL,
>  0, EM_ALPHA, 0, 0);
>  if (size < 0) {
>  error_report("could not load kernel '%s'", kernel_filename);
> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index 5d4a581..7531b97 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -331,7 +331,7 @@ void armv7m_load_kernel(ARMCPU *cpu, const char
*kernel_filename, int mem_size)
>
>  if (kernel_filename) {
>  image_size = load_elf_as(kernel_filename, NULL, NULL, NULL,
> - , ,
> + , , NULL,
>   NULL, 

Re: [PATCH v3 01/14] dp8393x: Mask EOL bit from descriptor addresses

2020-01-28 Thread Finn Thain
On Tue, 28 Jan 2020, Philippe Mathieu-Daudé wrote:

> Hi Finn,
> 
> On 1/19/20 11:59 PM, Finn Thain wrote:
> > The Least Significant bit of a descriptor address register is used as
> > an EOL flag. It has to be masked when the register value is to be used
> > as an actual address for copying memory around. But when the registers
> > are to be updated the EOL bit should not be masked.
> > 
> > Signed-off-by: Finn Thain 
> > Tested-by: Laurent Vivier 
> > ---
> > Changed since v1:
> >   - Added macros to name constants as requested by Philippe Mathieu-Daudé.
> > ---
> >   hw/net/dp8393x.c | 19 ---
> >   1 file changed, 12 insertions(+), 7 deletions(-)
> > 
> > diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> > index cdc2631c0c..14901c1445 100644
> > --- a/hw/net/dp8393x.c
> > +++ b/hw/net/dp8393x.c
> > @@ -145,6 +145,9 @@ do { printf("sonic ERROR: %s: " fmt, __func__ , ##
> > __VA_ARGS__); } while (0)
> >   #define SONIC_ISR_PINT   0x0800
> >   #define SONIC_ISR_LCD0x1000
> >   +#define SONIC_DESC_EOL   0x0001
> > +#define SONIC_DESC_ADDR  0xFFFE
> 
> I'd rather not add SONIC_DESC_ADDR and use ~SONIC_DESC_EOL instead.
> 
> Please consider it if you respin the series.
> 

I chose to use 0xFFFE instead of ~SONIC_DESC_EOL because the former 
correctly implies an unsigned short word, while the latter mask may 
suggest some need for sign extension or longer words.

I agree that ~SONIC_DESC_EOL is easily understood as "all the other bits". 
But the bits in SONIC_DESC_EOL will never change, since this value is 
dictated by the hardware.

> Reviewed-by: Philippe Mathieu-Daudé 
> 

Thanks for reviewing this series.

> > +
> >   #define TYPE_DP8393X "dp8393x"
> >   #define DP8393X(obj) OBJECT_CHECK(dp8393xState, (obj), TYPE_DP8393X)
> >   @@ -197,7 +200,8 @@ static uint32_t dp8393x_crba(dp8393xState *s)
> > static uint32_t dp8393x_crda(dp8393xState *s)
> >   {
> > -return (s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA];
> > +return (s->regs[SONIC_URDA] << 16) |
> > +   (s->regs[SONIC_CRDA] & SONIC_DESC_ADDR);
> >   }
> > static uint32_t dp8393x_rbwc(dp8393xState *s)
> > @@ -217,7 +221,8 @@ static uint32_t dp8393x_tsa(dp8393xState *s)
> > static uint32_t dp8393x_ttda(dp8393xState *s)
> >   {
> > -return (s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA];
> > +return (s->regs[SONIC_UTDA] << 16) |
> > +   (s->regs[SONIC_TTDA] & SONIC_DESC_ADDR);
> >   }
> > static uint32_t dp8393x_wt(dp8393xState *s)
> > @@ -506,8 +511,8 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
> >sizeof(uint16_t) *
> >(4 + 3 * s->regs[SONIC_TFC]) * width,
> >   MEMTXATTRS_UNSPECIFIED, (uint8_t *)s->data, size, 0);
> > -s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0) & ~0x1;
> > -if (dp8393x_get(s, width, 0) & 0x1) {
> > +s->regs[SONIC_CTDA] = dp8393x_get(s, width, 0);
> > +if (s->regs[SONIC_CTDA] & SONIC_DESC_EOL) {
> >   /* EOL detected */
> >   break;
> >   }
> > @@ -763,13 +768,13 @@ static ssize_t dp8393x_receive(NetClientState *nc,
> > const uint8_t * buf,
> >   /* XXX: Check byte ordering */
> > /* Check for EOL */
> > -if (s->regs[SONIC_LLFA] & 0x1) {
> > +if (s->regs[SONIC_LLFA] & SONIC_DESC_EOL) {
> >   /* Are we still in resource exhaustion? */
> >   size = sizeof(uint16_t) * 1 * width;
> >   address = dp8393x_crda(s) + sizeof(uint16_t) * 5 * width;
> >   address_space_rw(>as, address, MEMTXATTRS_UNSPECIFIED,
> >(uint8_t *)s->data, size, 0);
> > -if (dp8393x_get(s, width, 0) & 0x1) {
> > +if (dp8393x_get(s, width, 0) & SONIC_DESC_EOL) {
> >   /* Still EOL ; stop reception */
> >   return -1;
> >   } else {
> > @@ -827,7 +832,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const
> > uint8_t * buf,
> >   address_space_rw(>as, dp8393x_crda(s) + sizeof(uint16_t) * 5 *
> > width,
> >   MEMTXATTRS_UNSPECIFIED, (uint8_t *)s->data, size, 0);
> >   s->regs[SONIC_LLFA] = dp8393x_get(s, width, 0);
> > -if (s->regs[SONIC_LLFA] & 0x1) {
> > +if (s->regs[SONIC_LLFA] & SONIC_DESC_EOL) {
> >   /* EOL detected */
> >   s->regs[SONIC_ISR] |= SONIC_ISR_RDE;
> >   } else {
> > 
> 
> 

Re: [PATCH] riscv: Separate FPU register size from core register size in gdbstub

2020-01-28 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20200128223955.464556-1-kei...@keithp.com/



Hi,

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

Type: series
Message-id: 20200128223955.464556-1-kei...@keithp.com
Subject: [PATCH] riscv: Separate FPU register size from core register size in 
gdbstub

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] patchew/20200128223955.464556-1-kei...@keithp.com -> 
patchew/20200128223955.464556-1-kei...@keithp.com
Switched to a new branch 'test'
f8704a8 riscv: Separate FPU register size from core register size in gdbstub

=== OUTPUT BEGIN ===
ERROR: braces {} are necessary for all arms of this statement
#44: FILE: target/riscv/gdbstub.c:306:
+if (env->misa & RVD)
[...]

total: 1 errors, 0 warnings, 54 lines checked

Commit f8704a85f17a (riscv: Separate FPU register size from core register size 
in gdbstub) has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


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

[PATCH] riscv: Separate FPU register size from core register size in gdbstub

2020-01-28 Thread Keith Packard via
The size of the FPU registers is dictated by the 'f' and 'd' features,
not the core processor register size. Processors with the 'd' feature
have 64-bit FPU registers. Processors without the 'd' feature but with
the 'f' feature have 32-bit FPU registers.

Signed-off-by: Keith Packard 
---
 configure  |  4 ++--
 target/riscv/gdbstub.c | 18 +-
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/configure b/configure
index a72a5def57..c21bff8d10 100755
--- a/configure
+++ b/configure
@@ -7709,13 +7709,13 @@ case "$target_name" in
 TARGET_BASE_ARCH=riscv
 TARGET_ABI_DIR=riscv
 mttcg=yes
-gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-32bit-csr.xml 
riscv-32bit-virtual.xml"
+gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml 
riscv-32bit-csr.xml riscv-32bit-virtual.xml"
   ;;
   riscv64)
 TARGET_BASE_ARCH=riscv
 TARGET_ABI_DIR=riscv
 mttcg=yes
-gdb_xml_files="riscv-64bit-cpu.xml riscv-64bit-fpu.xml riscv-64bit-csr.xml 
riscv-64bit-virtual.xml"
+gdb_xml_files="riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml 
riscv-64bit-csr.xml riscv-64bit-virtual.xml"
   ;;
   sh4|sh4eb)
 TARGET_ARCH=sh4
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 1a7947e019..c1803a5916 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -303,7 +303,10 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
 {
 if (n < 32) {
-return gdb_get_reg64(mem_buf, env->fpr[n]);
+if (env->misa & RVD)
+return gdb_get_reg64(mem_buf, env->fpr[n]);
+if (env->misa & RVF)
+return gdb_get_reg32(mem_buf, env->fpr[n]);
 /* there is hole between ft11 and fflags in fpu.xml */
 } else if (n < 36 && n > 32) {
 target_ulong val = 0;
@@ -403,23 +406,20 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState 
*cs)
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
-#if defined(TARGET_RISCV32)
-if (env->misa & RVF) {
+if (env->misa & RVD) {
+gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
+ 36, "riscv-64bit-fpu.xml", 0);
+} else if (env->misa & RVF) {
 gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
  36, "riscv-32bit-fpu.xml", 0);
 }
-
+#if defined(TARGET_RISCV32)
 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
  240, "riscv-32bit-csr.xml", 0);
 
 gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
  1, "riscv-32bit-virtual.xml", 0);
 #elif defined(TARGET_RISCV64)
-if (env->misa & RVF) {
-gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
- 36, "riscv-64bit-fpu.xml", 0);
-}
-
 gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
  240, "riscv-64bit-csr.xml", 0);
 
-- 
2.25.0




Re: [PATCH v3 13/14] dp8393x: Don't reset Silicon Revision register

2020-01-28 Thread Finn Thain
On Tue, 28 Jan 2020, Philippe Mathieu-Daud? wrote:

> On 1/19/20 11:59 PM, Finn Thain wrote:
> > The jazzsonic driver in Linux uses the Silicon Revision register value
> > to probe the chip. The driver fails unless the SR register contains 4.
> > Unfortunately, reading this register in QEMU usually returns 0 because
> > the s->regs[] array gets wiped after a software reset.
> > 
> > Fixes: bd8f1ebce4 ("net/dp8393x: fix hardware reset")
> > Signed-off-by: Finn Thain 
> > ---
> >   hw/net/dp8393x.c | 5 -
> >   1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> > index 1b73a8703b..71af0fad51 100644
> > --- a/hw/net/dp8393x.c
> > +++ b/hw/net/dp8393x.c
> > @@ -591,6 +591,10 @@ static uint64_t dp8393x_read(void *opaque, hwaddr addr,
> > unsigned int size)
> >   val |= s->cam[s->regs[SONIC_CEP] & 0xf][2* (SONIC_CAP0 -
> > reg)];
> >   }
> >   break;
> > +/* Read-only */
> > +case SONIC_SR:
> > +val = 4; /* only revision recognized by Linux/mips */
> > +break;
> >   /* All other registers have no special contrainst */
> >   default:
> >   val = s->regs[reg];
> > @@ -971,7 +975,6 @@ static void dp8393x_realize(DeviceState *dev, Error
> > **errp)
> >   qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
> > s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
> > -s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
> > memory_region_init_ram(>prom, OBJECT(dev),
> >  "dp8393x-prom", SONIC_PROM_SIZE, _err);
> > 
> 
> Please fix in dp8393x_reset() instead:
> 
> -- >8 --
> diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> index cdc2631c0c..65eb9c23a7 100644
> --- a/hw/net/dp8393x.c
> +++ b/hw/net/dp8393x.c
> @@ -862,6 +862,7 @@ static void dp8393x_reset(DeviceState *dev)
>  timer_del(s->watchdog);
> 
>  memset(s->regs, 0, sizeof(s->regs));
> +s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
>  s->regs[SONIC_CR] = SONIC_CR_RST | SONIC_CR_STP | SONIC_CR_RXDIS;
>  s->regs[SONIC_DCR] &= ~(SONIC_DCR_EXBUS | SONIC_DCR_LBR);
>  s->regs[SONIC_RCR] &= ~(SONIC_RCR_LB0 | SONIC_RCR_LB1 | SONIC_RCR_BRD |
> SONIC_RCR_RNT);
> @@ -914,7 +915,6 @@ static void dp8393x_realize(DeviceState *dev, Error
> **errp)
>  qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
> 
>  s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
> -s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
> 
>  memory_region_init_ram(>prom, OBJECT(dev),
> "dp8393x-prom", SONIC_PROM_SIZE, _err);
> ---
> 

This would allow the host to change the value of the Silicon Revision 
register. However, the datasheet says,

4.3.13 Silicon Revision Register
This is a 16-bit read only register. It contains information on the 
current revision of the SONIC. The value of the DP83932CVF revision 
register is 6h.

I haven't actually tried storing a different value in this register on 
National Semiconductor hardware, but I'm willing to do that test if you 
wish.



Re: python3 script header and rhel8

2020-01-28 Thread John Snow



On 1/28/20 11:07 AM, Daniel P. Berrangé wrote:
> On Tue, Jan 28, 2020 at 03:44:04PM +, Vladimir Sementsov-Ogievskiy wrote:
>> Hi all!
>>
>> Hmm Qemu dropped support for python2, and anyway python2 is not supported 
>> now at all.
>>
>> Still, we have a lot of "#!/usr/bin/env python" headings in our scripts, 
>> which is
>> unsupported by rhel8 by default. So, for example, because of such line in
>> tests/qemu-iotests/nbd-fault-injector.py, iotest 277 fails.
>>
>> Of course, it's simple to set python in rhel8 to be python3... But should we 
>> fix
>> all the headings to be "#!/usr/bin/env python3"? Or what is the correct 
>> heading
>> for scripts in a new python3 world?
> 
> Using "#!/usr/bin/env python3" is probably our best choice, as it
> makes it absolutely clear we're not happy with a python2 impl.
> 

On using 'env' or not: for any script anticipated to be executed
directly from the command line, a hardcoded path will inhibit idiomatic
virtual environment usage, so 'env' is preferred.

On python vs python2 vs python3:

https://www.python.org/dev/peps/pep-0394/

PEP 0394 states that 'python3' should be available and that 'python' is
optional.

That answers that, in my opinion. Let's make `#!/usr/bin/env python3`
ubiquitous.

--js




Re: [PATCH v3 16/18] hw/i386: Introduce EPYC mode function handlers

2020-01-28 Thread Babu Moger



On 1/28/20 2:04 PM, Eduardo Habkost wrote:
> Hi,
> 
> Sorry for taking so long.  I was away from the office for a
> month, and now I'm finally back.

no worries.

> 
> On Tue, Dec 03, 2019 at 06:38:46PM -0600, Babu Moger wrote:
>> Introduce following handlers for new epyc mode.
>> x86_apicid_from_cpu_idx_epyc: Generate apicid from cpu index.
>> x86_topo_ids_from_apicid_epyc: Generate topo ids from apic id.
>> x86_apicid_from_topo_ids_epyc: Generate apicid from topo ids.
>>
>> Signed-off-by: Babu Moger 
>> ---
>>  hw/i386/pc.c   |   12 
>>  include/hw/i386/topology.h |4 ++--
>>  2 files changed, 14 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
>> index e6c8a458e7..64e3658873 100644
>> --- a/hw/i386/pc.c
>> +++ b/hw/i386/pc.c
>> @@ -2819,6 +2819,17 @@ static bool pc_hotplug_allowed(MachineState *ms, 
>> DeviceState *dev, Error **errp)
>>  return true;
>>  }
>>  
>> +static void pc_init_apicid_fn(MachineState *ms)
>> +{
>> +PCMachineState *pcms = PC_MACHINE(ms);
>> +
>> +if (!strncmp(ms->cpu_type, "EPYC", 4)) {
> 
> Please never use string comparison to introduce device-specific
> behavior.  I had already pointed this out at

Yes. you did mention before. I was not sure how to achieve  without
comparing the model string

> 
> If you need a CPU model to provide special behavior,
> you have two options:
> 
> * Add a method pointer to X86CPUClass and/or X86CPUDefinition
> * Add a QOM property to enable/disable special behavior, and
>   include the property in the CPU model definition.
> 
> The second option might be preferable long term, but might
> require more work because the property would become visible in
> query-cpu-model-expansion and in the command line.  The first
> option may be acceptable to avoid extra user-visible complexity
> in the first version.

Yes. We need to have a special behavior for specific model.
I will look at both these above approaches closely. Challenge is this
needs to be done much early in the initialization(before parse_numa_opts
or machine_run_board_init). Will research more on this.

> 
> 
> 
>> +pcms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx_epyc;
>> +pcms->topo_ids_from_apicid = x86_topo_ids_from_apicid_epyc;
>> +pcms->apicid_from_topo_ids = x86_apicid_from_topo_ids_epyc;
> 
> Why do you need to override the function pointers in
> PCMachineState instead of just looking up the relevant info at
> X86CPUClass?
> 
> If both machine-types and CPU models are supposed to override the
> APIC ID calculation functions, the interaction between
> machine-type and CPU model needs to be better documented
> (preferably with simple test cases) to ensure we won't break
> compatibility later.
> 
>> +}
>> +}
>> +
>>  static void pc_machine_class_init(ObjectClass *oc, void *data)
>>  {
>>  MachineClass *mc = MACHINE_CLASS(oc);
>> @@ -2847,6 +2858,7 @@ static void pc_machine_class_init(ObjectClass *oc, 
>> void *data)
>>  mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
>>  mc->get_default_cpu_node_id = pc_get_default_cpu_node_id;
>>  mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
>> +mc->init_apicid_fn = pc_init_apicid_fn;
>>  mc->auto_enable_numa_with_memhp = true;
>>  mc->has_hotpluggable_cpus = true;
>>  mc->default_boot_order = "cad";
>> diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
>> index b2b9e93a06..f028d2332a 100644
>> --- a/include/hw/i386/topology.h
>> +++ b/include/hw/i386/topology.h
>> @@ -140,7 +140,7 @@ static inline unsigned 
>> apicid_pkg_offset_epyc(X86CPUTopoInfo *topo_info)
>>   *
>>   * The caller must make sure core_id < nr_cores and smt_id < nr_threads.
>>   */
>> -static inline apic_id_t apicid_from_topo_ids_epyc(X86CPUTopoInfo *topo_info,
>> +static inline apic_id_t x86_apicid_from_topo_ids_epyc(X86CPUTopoInfo 
>> *topo_info,
>>const X86CPUTopoIDs 
>> *topo_ids)
>>  {
>>  return (topo_ids->pkg_id  << apicid_pkg_offset_epyc(topo_info)) |
>> @@ -200,7 +200,7 @@ static inline apic_id_t 
>> x86_apicid_from_cpu_idx_epyc(X86CPUTopoInfo *topo_info,
>>  {
>>  X86CPUTopoIDs topo_ids;
>>  x86_topo_ids_from_idx_epyc(topo_info, cpu_index, _ids);
>> -return apicid_from_topo_ids_epyc(topo_info, _ids);
>> +return x86_apicid_from_topo_ids_epyc(topo_info, _ids);
>>  }
>>  /* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID
>>   *
>>
>>
> 



[Bug 1856724] Re: SB.PCI0.SMB0 device drivers unavailable

2020-01-28 Thread Rafal Kupiec
Any progress? When will you provide a Windows driver for this and/or
ability to disable this device in Qemu?

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

Title:
  SB.PCI0.SMB0 device drivers unavailable

Status in QEMU:
  New

Bug description:
  QEMU 4.2 introduces new device with this code:

  static void build_smb0(Aml *table, I2CBus *smbus, int devnr, int func)
  {
  Aml *scope = aml_scope("_SB.PCI0");
  Aml *dev = aml_device("SMB0");

  aml_append(dev, aml_name_decl("_HID", aml_eisaid("APP0005")));
  aml_append(dev, aml_name_decl("_ADR", aml_int(devnr << 16 | func)));
  build_acpi_ipmi_devices(dev, BUS(smbus), "\\_SB.PCI0.SMB0");
  aml_append(scope, dev);
  aml_append(table, scope);
  }

  It is detected by Windows 10 as 'Unknown Device' and there is no driver 
available.
  Please provide a working Windows driver or give ability to disable this 
device.

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



Re: [GSoC/Outreachy QEMU proposal] Extend support for ioctls in QEMU linux-user mode

2020-01-28 Thread Aleksandar Markovic
On Tue, Jan 28, 2020 at 7:00 PM Peter Maydell 
wrote:

> On Tue, 28 Jan 2020 at 17:51, Aleksandar Markovic
>  wrote:
> >
> > I am personally interested in both. However, learning about syscalls and
> implementation of support for them in QEMU would require more ramp-up time
> from student (as is the case for any new employee in a similar situation
> for that matter). In the worst case, the student would spend much more time
> on learning than on productive work. My impression is at it is better to
> leave the student focused on just one area - ioctl support.
>
> I think they're about the same, really. The level of difficulty is more
> in what the syscall or ioctl does and what its arguments are (ie does
> QEMU have to do much mangling on the way past) rather than whether
> it happens to be a syscall or an ioctl. Some syscalls are hard, but
> some are trivial; same with ioctls.
>
> thanks
> -- PMM
>


How about this:

- I removed the first item (a) of PART I (since I already have an idea how
to do this in, I think, a very good way), to free the student time. I will
send my solution to the list before this summer, I hope.
- I amended all parts to include some syscall-related activities - and the
end result is this:


*Extend support for ioctls and syscalls in QEMU linux-user mode*



*PLANNED ACTIVITIES*

BACKGROUND

There are currently 2500+ ioctls defined in Linux kernel. QEMU linux-user
currently supports only several hundred. There is a constant need for
expanding ioctl support in QEMU. Users use Linux-user mode in variety of
setups (for example, building and testing tools and applications under
chroot environment), and, on a regular basis, efforts by multiple people
are made to fill in missing support.

Regarding syscall support in QEMU linux-user, the coverage is much better
than in case of ioctls. However, kernel syscall interface continuously
develops and grows, and QEMU linux-user support usually lags considerably.
The support for new syscalls is usually left unimplemented, until an end
user reports that it is missing in hers/his usage scenario.

In conclusion, the efforts for supporting ioctls and syscalls in QEMU have
usually been done on a piece-by-piece basis, in a limited way covering a
particular need. This project will take more proactive stance, and try to
improve QEMU before users start complaining.

This contributions of this project will be mostly to QEMU, but some parts
would be also contirbutions to LTP (Linux Test Project).

PART I:

   a) Add strace support for printing the third argument of ioctl() (be it
int, string, structure or array) - limited to selected ioctls that are
frequently used.
   b) Add strace support for printing the arguments of selected syscalls
that are frequently used, and not covered in QEMU strace module so far.

PART II:

   a) Amend support for existing groups of ioctls that are not completed
100% (let's say, filesystem ioctls)
   b) Add support for a selected group of ioctls that are not currently
supported (for example, DM ioctls, Bluetooth ioctls, or Radeon DRM ioctls)
   c) Add support for a selected group of syscalls that were recently
introduced in kernel.

PART III:

  a) Within LTP (Linux Test Project), develop unit tests for selected
ioctls that are supported in QEMU (including some whose support is
developed in PART II).
  b) Within LTP (Linux Test Project), develop unit tests for selected
syscalls that are supported in QEMU (including some whose support is
developed in PART II).



*DELIVERABLES*

The deliverables are in the form of source code for each part, intended to
be upstreamed to either QEMU or LTP open source projects. The time needed
for upstreaming (addressing reviews, etc.) process is included into this
project. The delivery of results can and should be distributed over larger
period of time (2-3 months).


Mentor: open (I propose Laurent Vivier)
Student: open


Re: [PATCH v4 7/7] tests/boot_linux_console: Tag Emcraft Smartfusion2 as running 'u-boot'

2020-01-28 Thread Wainer dos Santos Moschetta



On 1/27/20 2:05 PM, Thomas Huth wrote:

On 21/01/2020 00.51, Philippe Mathieu-Daudé wrote:

Avocado tags are handy to automatically select tests matching
the tags. Since this test also runs U-Boot, tag it.

We can run all the tests using U-Boot as once with:

   $ avocado --show=app run -t u-boot tests/acceptance/
   JOB LOG: avocado/job-results/job-2020-01-21T00.16-ee9344e/job.log
(1/3) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_emcraft_sf2: 
PASS (16.59 s)
(2/3) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_uboot: 
PASS (0.47 s)
(3/3) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_aarch64_raspi3_uboot:
 PASS (2.43 s)
   RESULTS: PASS 3 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | 
CANCEL 0
   JOB TIME   : 19.78 s

Signed-off-by: Philippe Mathieu-Daudé 
---
  tests/acceptance/boot_linux_console.py | 1 +
  1 file changed, 1 insertion(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 22b360118d..4a4cf9d0ea 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -305,6 +305,7 @@ class BootLinuxConsole(Test):
  :avocado: tags=arch:arm
  :avocado: tags=machine:emcraft-sf2
  :avocado: tags=endian:little
+:avocado: tags=u-boot
  """
  uboot_url = ('https://raw.githubusercontent.com/'
   'Subbaraya-Sundeep/qemu-test-binaries/'


We should maybe move that test to another file, too, since it is not
using Linux. Or should we maybe rename boot_linux_console.py to simply
boot_console.py ?


Thinking aloud: maybe create a directory 'boot' (or 'boot_tests') and 
group tests in files according to the 'arch' tag.


Example:

[wainersm@localhost boot]$ tree
.
└── arm.py

0 directories, 1 file
[wainersm@localhost boot]$ cat arm.py
from avocado_qemu import Test

class BootArmTest(Test):
    """
    :avocado: tags=arch:arm
    """
    def test_linux_virt()
    """
    :avocado: tags=machine:virt
    :avocado: tags=linux-boot
    """
    # Test here
    pass

    def test_uboot_emcraft_sf2()
    """
    :avocado: tags=machine:emcraft-sf2
    :avocado: tags=endian:little
    :avocado: tags=u-boot
    """
    # Test here
    pass
--


Back to this patch...

Reviewed-by: Wainer dos Santos Moschetta 




  Thomas







[PULL 4/6] hw/core/loader: Let load_elf() populate the processor-specific flags

2020-01-28 Thread Aleksandar Markovic
From: Philippe Mathieu-Daudé 

While loading the executable, some platforms (like AVR) need to
determine CPU type that executable is built for by reading the
field 'e_flags' of the ELF header of tha executable.

This patch enables such discovery of that field while using any
of the following functions:

  - load_elf()
  - load_elf_as()
  - load_elf_ram()
  - load_elf_ram_sym()

The argument added to these functions is called 'pflags' and is of
type 'uint32_t*' (that matches the the pointer to the 'elf_word' -
the type of the field 'e_flags' in both 32-bit and 64-bit variants
of ELF header). Callers are allowed to pass NULL as that argument,
and in such case no lookup to the field 'e_flags' will happen, and
no information will be returned, of course.

CC: Richard Henderson 
CC: Peter Maydell 
CC: Edgar E. Iglesias 
CC: Michael Walle 
CC: Thomas Huth 
CC: Laurent Vivier 
CC: Philippe Mathieu-Daudé 
CC: Aleksandar Rikalo 
CC: Aurelien Jarno 
CC: Jia Liu 
CC: David Gibson 
CC: Mark Cave-Ayland 
CC: BALATON Zoltan 
CC: Christian Borntraeger 
CC: Thomas Huth 
CC: Artyom Tarasenko 
CC: Fabien Chouteau 
CC: KONRAD Frederic 
CC: Max Filippov 

Reviewed-by: Aleksandar Markovic 
Signed-off-by: Michael Rolnik 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Aleksandar Markovic 
Message-Id: <1580079311-20447-24-git-send-email-aleksandar.marko...@rt-rk.com>
---
 hw/alpha/dp264.c   |  4 ++--
 hw/arm/armv7m.c|  2 +-
 hw/arm/boot.c  |  2 +-
 hw/core/generic-loader.c   |  2 +-
 hw/core/loader.c   | 37 +++--
 hw/cris/boot.c |  2 +-
 hw/hppa/machine.c  |  4 ++--
 hw/i386/multiboot.c|  2 +-
 hw/i386/x86.c  |  2 +-
 hw/lm32/lm32_boards.c  |  4 ++--
 hw/lm32/milkymist.c|  2 +-
 hw/m68k/an5206.c   |  2 +-
 hw/m68k/mcf5208.c  |  2 +-
 hw/m68k/q800.c |  2 +-
 hw/microblaze/boot.c   |  4 ++--
 hw/mips/mips_fulong2e.c|  2 +-
 hw/mips/mips_malta.c   |  3 ++-
 hw/mips/mips_mipssim.c |  2 +-
 hw/mips/mips_r4k.c |  2 +-
 hw/moxie/moxiesim.c|  2 +-
 hw/nios2/boot.c|  4 ++--
 hw/openrisc/openrisc_sim.c |  2 +-
 hw/pci-host/prep.c |  3 ++-
 hw/ppc/e500.c  |  2 +-
 hw/ppc/mac_newworld.c  |  4 ++--
 hw/ppc/mac_oldworld.c  |  4 ++--
 hw/ppc/ppc440_bamboo.c |  2 +-
 hw/ppc/sam460ex.c  |  3 ++-
 hw/ppc/spapr.c |  6 +++---
 hw/ppc/virtex_ml507.c  |  2 +-
 hw/riscv/boot.c|  4 ++--
 hw/s390x/ipl.c |  7 ---
 hw/sparc/leon3.c   |  2 +-
 hw/sparc/sun4m.c   |  4 ++--
 hw/sparc64/sun4u.c |  5 +++--
 hw/tricore/tricore_testboard.c |  2 +-
 hw/xtensa/sim.c|  2 +-
 hw/xtensa/xtfpga.c |  2 +-
 include/hw/elf_ops.h   |  6 +-
 include/hw/loader.h| 21 -
 40 files changed, 92 insertions(+), 79 deletions(-)

diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index f2026fd..a8f9a89 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -115,7 +115,7 @@ static void clipper_init(MachineState *machine)
 exit(1);
 }
 size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
-NULL, _entry, _low, _high,
+NULL, _entry, _low, _high, NULL,
 0, EM_ALPHA, 0, 0);
 if (size < 0) {
 error_report("could not load palcode '%s'", palcode_filename);
@@ -134,7 +134,7 @@ static void clipper_init(MachineState *machine)
 uint64_t param_offset;
 
 size = load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_phys,
-NULL, _entry, _low, _high,
+NULL, _entry, _low, _high, NULL,
 0, EM_ALPHA, 0, 0);
 if (size < 0) {
 error_report("could not load kernel '%s'", kernel_filename);
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 5d4a581..7531b97 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -331,7 +331,7 @@ void armv7m_load_kernel(ARMCPU *cpu, const char 
*kernel_filename, int mem_size)
 
 if (kernel_filename) {
 image_size = load_elf_as(kernel_filename, NULL, NULL, NULL,
- , ,
+ , , NULL,
  NULL, big_endian, EM_ARM, 1, 0, as);
 if (image_size < 0) {
 image_size = load_image_targphys_as(kernel_filename, 0,
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 8fb4a63..0c213ca 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -903,7 +903,7 @@ static int64_t arm_load_elf(struct arm_boot_info *info, 
uint64_t *pentry,
 }
 
 ret = load_elf_as(info->kernel_filename, NULL, NULL, NULL,
-  pentry, lowaddr, highaddr, big_endian, 

[PULL 2/6] disas: Add a field for target-dependant data

2020-01-28 Thread Aleksandar Markovic
From: Aleksandar Markovic 

This patch adds a field "target_info" to the structure
disassemble_info. The purpose of this field is to enable targets
to pass to disassembler code any additional data thet deem suitable.

Reviewed-by: Aleksandar Rikalo 
Signed-off-by: Aleksandar Markovic 
Message-Id: <1579883929-1517-6-git-send-email-aleksandar.marko...@rt-rk.com>
---
 include/disas/dis-asm.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index e9c7dd8..f87f468 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -372,6 +372,9 @@ typedef struct disassemble_info {
   /* Command line options specific to the target disassembler.  */
   char * disassembler_options;
 
+  /* Field intended to be used by targets in any way they deem suitable.  */
+  int64_t target_info;
+
   /* Options for Capstone disassembly.  */
   int cap_arch;
   int cap_mode;
-- 
2.7.4




[PULL 3/6] mips-semi.c: remove 'uhi_done' label in helper_do_semihosting()

2020-01-28 Thread Aleksandar Markovic
From: Daniel Henrique Barboza 

The label 'uhi_done' is a simple 'return' call and can
be removed for a bit more clarity in the code.

CC: Aurelien Jarno 
CC: Aleksandar Markovic 
CC: Aleksandar Rikalo 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Aleksandar Markovic 
Signed-off-by: Daniel Henrique Barboza 
Message-Id: <20200106182425.20312-7-danielhb...@gmail.com>
---
 target/mips/mips-semi.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/target/mips/mips-semi.c b/target/mips/mips-semi.c
index 35bdfd7..10a710c 100644
--- a/target/mips/mips-semi.c
+++ b/target/mips/mips-semi.c
@@ -218,7 +218,7 @@ static int copy_argn_to_target(CPUMIPSState *env, int 
arg_num,
 if (!p) {   \
 gpr[2] = -1;\
 gpr[3] = EFAULT;\
-goto uhi_done;  \
+return; \
 }   \
 } while (0)
 
@@ -228,14 +228,14 @@ static int copy_argn_to_target(CPUMIPSState *env, int 
arg_num,
 if (!p) {   \
 gpr[2] = -1;\
 gpr[3] = EFAULT;\
-goto uhi_done;  \
+return; \
 }   \
 p2 = lock_user_string(addr2);   \
 if (!p2) {  \
 unlock_user(p, addr, 0);\
 gpr[2] = -1;\
 gpr[3] = EFAULT;\
-goto uhi_done;  \
+return; \
 }   \
 } while (0)
 
@@ -272,7 +272,7 @@ void helper_do_semihosting(CPUMIPSState *env)
 if (gpr[4] < 3) {
 /* ignore closing stdin/stdout/stderr */
 gpr[2] = 0;
-goto uhi_done;
+return;
 }
 gpr[2] = close(gpr[4]);
 gpr[3] = errno_mips(errno);
@@ -302,7 +302,7 @@ void helper_do_semihosting(CPUMIPSState *env)
 gpr[2] = fstat(gpr[4], );
 gpr[3] = errno_mips(errno);
 if (gpr[2]) {
-goto uhi_done;
+return;
 }
 gpr[2] = copy_stat_to_target(env, , gpr[5]);
 gpr[3] = errno_mips(errno);
@@ -314,14 +314,14 @@ void helper_do_semihosting(CPUMIPSState *env)
 case UHI_argnlen:
 if (gpr[4] >= semihosting_get_argc()) {
 gpr[2] = -1;
-goto uhi_done;
+return;
 }
 gpr[2] = strlen(semihosting_get_arg(gpr[4]));
 break;
 case UHI_argn:
 if (gpr[4] >= semihosting_get_argc()) {
 gpr[2] = -1;
-goto uhi_done;
+return;
 }
 gpr[2] = copy_argn_to_target(env, gpr[4], gpr[5]);
 break;
@@ -369,6 +369,5 @@ void helper_do_semihosting(CPUMIPSState *env)
 fprintf(stderr, "Unknown UHI operation %d\n", op);
 abort();
 }
-uhi_done:
 return;
 }
-- 
2.7.4




[PULL 5/6] target/mips: Amend CP0 WatchHi register implementation

2020-01-28 Thread Aleksandar Markovic
From: Yongbok Kim 

WatchHi is extended by the field MemoryMapID with the GINVT instruction.
The field is accessible by MTHC0/MFHC0 in 32-bit architectures and DMTC0/
DMFC0 in 64-bit architectures.

Reviewed-by: Aleksandar Rikalo 
Signed-off-by: Yongbok Kim 
Signed-off-by: Aleksandar Markovic 
Message-Id: <1579883929-1517-4-git-send-email-aleksandar.marko...@rt-rk.com>
---
 target/mips/cpu.h   |  2 +-
 target/mips/helper.h|  3 +++
 target/mips/machine.c   |  6 +++---
 target/mips/op_helper.c | 23 +--
 target/mips/translate.c | 42 +-
 5 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index c218ccc..7cf1b49 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -961,7 +961,7 @@ struct CPUMIPSState {
 /*
  * CP0 Register 19
  */
-int32_t CP0_WatchHi[8];
+uint64_t CP0_WatchHi[8];
 #define CP0WH_ASID 16
 /*
  * CP0 Register 20
diff --git a/target/mips/helper.h b/target/mips/helper.h
index 7b8ad74..5b1f8bb 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -78,6 +78,7 @@ DEF_HELPER_1(mfc0_maar, tl, env)
 DEF_HELPER_1(mfhc0_maar, tl, env)
 DEF_HELPER_2(mfc0_watchlo, tl, env, i32)
 DEF_HELPER_2(mfc0_watchhi, tl, env, i32)
+DEF_HELPER_2(mfhc0_watchhi, tl, env, i32)
 DEF_HELPER_1(mfc0_debug, tl, env)
 DEF_HELPER_1(mftc0_debug, tl, env)
 #ifdef TARGET_MIPS64
@@ -89,6 +90,7 @@ DEF_HELPER_1(dmfc0_tcschefback, tl, env)
 DEF_HELPER_1(dmfc0_lladdr, tl, env)
 DEF_HELPER_1(dmfc0_maar, tl, env)
 DEF_HELPER_2(dmfc0_watchlo, tl, env, i32)
+DEF_HELPER_2(dmfc0_watchhi, tl, env, i32)
 DEF_HELPER_1(dmfc0_saar, tl, env)
 #endif /* TARGET_MIPS64 */
 
@@ -159,6 +161,7 @@ DEF_HELPER_2(mthc0_maar, void, env, tl)
 DEF_HELPER_2(mtc0_maari, void, env, tl)
 DEF_HELPER_3(mtc0_watchlo, void, env, tl, i32)
 DEF_HELPER_3(mtc0_watchhi, void, env, tl, i32)
+DEF_HELPER_3(mthc0_watchhi, void, env, tl, i32)
 DEF_HELPER_2(mtc0_xcontext, void, env, tl)
 DEF_HELPER_2(mtc0_framemask, void, env, tl)
 DEF_HELPER_2(mtc0_debug, void, env, tl)
diff --git a/target/mips/machine.c b/target/mips/machine.c
index c139239..8d5b18b 100644
--- a/target/mips/machine.c
+++ b/target/mips/machine.c
@@ -212,8 +212,8 @@ const VMStateDescription vmstate_tlb = {
 
 const VMStateDescription vmstate_mips_cpu = {
 .name = "cpu",
-.version_id = 18,
-.minimum_version_id = 18,
+.version_id = 19,
+.minimum_version_id = 19,
 .post_load = cpu_post_load,
 .fields = (VMStateField[]) {
 /* Active TC */
@@ -296,7 +296,7 @@ const VMStateDescription vmstate_mips_cpu = {
 VMSTATE_INT32(env.CP0_MAARI, MIPSCPU),
 VMSTATE_UINTTL(env.lladdr, MIPSCPU),
 VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8),
-VMSTATE_INT32_ARRAY(env.CP0_WatchHi, MIPSCPU, 8),
+VMSTATE_UINT64_ARRAY(env.CP0_WatchHi, MIPSCPU, 8),
 VMSTATE_UINTTL(env.CP0_XContext, MIPSCPU),
 VMSTATE_INT32(env.CP0_Framemask, MIPSCPU),
 VMSTATE_INT32(env.CP0_Debug, MIPSCPU),
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 79d44da..7425a88 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -945,7 +945,12 @@ target_ulong helper_mfc0_watchlo(CPUMIPSState *env, 
uint32_t sel)
 
 target_ulong helper_mfc0_watchhi(CPUMIPSState *env, uint32_t sel)
 {
-return env->CP0_WatchHi[sel];
+return (int32_t) env->CP0_WatchHi[sel];
+}
+
+target_ulong helper_mfhc0_watchhi(CPUMIPSState *env, uint32_t sel)
+{
+return env->CP0_WatchHi[sel] >> 32;
 }
 
 target_ulong helper_mfc0_debug(CPUMIPSState *env)
@@ -1016,6 +1021,11 @@ target_ulong helper_dmfc0_watchlo(CPUMIPSState *env, 
uint32_t sel)
 return env->CP0_WatchLo[sel];
 }
 
+target_ulong helper_dmfc0_watchhi(CPUMIPSState *env, uint32_t sel)
+{
+return env->CP0_WatchHi[sel];
+}
+
 target_ulong helper_dmfc0_saar(CPUMIPSState *env)
 {
 if ((env->CP0_SAARI & 0x3f) < 2) {
@@ -1869,11 +1879,20 @@ void helper_mtc0_watchlo(CPUMIPSState *env, 
target_ulong arg1, uint32_t sel)
 
 void helper_mtc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
 {
-int mask = 0x4FF8 | (env->CP0_EntryHi_ASID_mask << CP0WH_ASID);
+uint64_t mask = 0x4FF8 | (env->CP0_EntryHi_ASID_mask << CP0WH_ASID);
+if ((env->CP0_Config5 >> CP0C5_MI) & 1) {
+mask |= 0xULL; /* MMID */
+}
 env->CP0_WatchHi[sel] = arg1 & mask;
 env->CP0_WatchHi[sel] &= ~(env->CP0_WatchHi[sel] & arg1 & 0x7);
 }
 
+void helper_mthc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+{
+env->CP0_WatchHi[sel] = ((uint64_t) (arg1) << 32) |
+(env->CP0_WatchHi[sel] & 0xULL);
+}
+
 void helper_mtc0_xcontext(CPUMIPSState *env, target_ulong arg1)
 {
 target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
diff --git a/target/mips/translate.c b/target/mips/translate.c
index efe75e6..d51330c 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c

[PULL 6/6] target/mips: Add implementation of GINVT instruction

2020-01-28 Thread Aleksandar Markovic
From: Yongbok Kim 

Implement emulation of GINVT instruction. As QEMU doesn't support
caches and virtualization, this implementation covers only one
instruction (GINVT - Global Invalidate TLB) among all TLB-related
MIPS instructions.

Reviewed-by: Aleksandar Rikalo 
Signed-off-by: Yongbok Kim 
Signed-off-by: Aleksandar Markovic 
Message-Id: <1579883929-1517-5-git-send-email-aleksandar.marko...@rt-rk.com>
---
 disas/mips.c|  10 
 target/mips/cpu.h   |   2 +-
 target/mips/helper.c|  20 ++--
 target/mips/helper.h|   2 +
 target/mips/internal.h  |   1 +
 target/mips/op_helper.c | 129 +---
 target/mips/translate.c |  46 -
 7 files changed, 184 insertions(+), 26 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index dfefe5e..b9a5204 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -1409,6 +1409,16 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"dvp","t", 0x41600024, 0xffe0, TRAP|WR_t,0, 
I32R6},
 {"evp","",  0x4164, 0x, TRAP, 0, 
I32R6},
 {"evp","t", 0x4164, 0xffe0, TRAP|WR_t,0, 
I32R6},
+{"ginvi",  "v", 0x7c3d, 0xfc1ffcff, TRAP | INSN_TLB,  0, 
I32R6},
+{"ginvt",  "v", 0x7cbd, 0xfc1ffcff, TRAP | INSN_TLB,  0, 
I32R6},
+{"crc32b", "t,v,t", 0x7c0f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, 
I32R6},
+{"crc32h", "t,v,t", 0x7c4f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, 
I32R6},
+{"crc32w", "t,v,t", 0x7c8f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, 
I32R6},
+{"crc32d", "t,v,t", 0x7ccf, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, 
I64R6},
+{"crc32cb","t,v,t", 0x7c00010f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, 
I32R6},
+{"crc32ch","t,v,t", 0x7c00014f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, 
I32R6},
+{"crc32cw","t,v,t", 0x7c00018f, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, 
I32R6},
+{"crc32cd","t,v,t", 0x7c0001cf, 0xfc00ff3f, WR_d | RD_s | RD_t,   0, 
I64R6},
 
 /* MSA */
 {"sll.b",   "+d,+e,+f", 0x780d, 0xffe0003f, WR_VD|RD_VS|RD_VT,  0, MSA},
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 7cf1b49..94d01ea 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -309,7 +309,7 @@ typedef struct mips_def_t mips_def_t;
 #define CP0_REG04__USERLOCAL   2
 #define CP0_REG04__XCONTEXTCONFIG  3
 #define CP0_REG04__DBGCONTEXTID4
-#define CP0_REG00__MMID5
+#define CP0_REG04__MMID5
 /* CP0 Register 05 */
 #define CP0_REG05__PAGEMASK0
 #define CP0_REG05__PAGEGRAIN   1
diff --git a/target/mips/helper.c b/target/mips/helper.c
index 781930a..afd78b1 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -72,8 +72,13 @@ int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int 
*prot,
 target_ulong address, int rw, int access_type)
 {
 uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+uint32_t MMID = env->CP0_MemoryMapID;
+bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
+uint32_t tlb_mmid;
 int i;
 
+MMID = mi ? MMID : (uint32_t) ASID;
+
 for (i = 0; i < env->tlb->tlb_in_use; i++) {
 r4k_tlb_t *tlb = >tlb->mmu.r4k.tlb[i];
 /* 1k pages are not supported. */
@@ -84,8 +89,9 @@ int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int 
*prot,
 tag &= env->SEGMask;
 #endif
 
-/* Check ASID, virtual page number & size */
-if ((tlb->G == 1 || tlb->ASID == ASID) && VPN == tag && !tlb->EHINV) {
+/* Check ASID/MMID, virtual page number & size */
+tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
+if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag && !tlb->EHINV) {
 /* TLB match */
 int n = !!(address & mask & ~(mask >> 1));
 /* Check access rights */
@@ -1418,14 +1424,20 @@ void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int 
use_extra)
 target_ulong addr;
 target_ulong end;
 uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+uint32_t MMID = env->CP0_MemoryMapID;
+bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
+uint32_t tlb_mmid;
 target_ulong mask;
 
+MMID = mi ? MMID : (uint32_t) ASID;
+
 tlb = >tlb->mmu.r4k.tlb[idx];
 /*
- * The qemu TLB is flushed when the ASID changes, so no need to
+ * The qemu TLB is flushed when the ASID/MMID changes, so no need to
  * flush these entries again.
  */
-if (tlb->G == 0 && tlb->ASID != ASID) {
+tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
+if (tlb->G == 0 && tlb_mmid != MMID) {
 return;
 }
 
diff --git a/target/mips/helper.h b/target/mips/helper.h
index 5b1f8bb..84fdd9f 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -120,6 +120,7 @@ DEF_HELPER_2(mtc0_tcschefback, void, env, tl)
 DEF_HELPER_2(mttc0_tcschefback, void, env, tl)
 DEF_HELPER_2(mtc0_entrylo1, void, env, tl)
 DEF_HELPER_2(mtc0_context, 

[PULL 0/6] MIPS queue for January 28th, 2020

2020-01-28 Thread Aleksandar Markovic
From: Aleksandar Markovic 

The following changes since commit 4c60e3289875ae6c516a37523bcecb87f68ce67c:

  Merge remote-tracking branch 'remotes/rth/tags/pull-pa-20200127' into staging 
(2020-01-28 15:11:04 +)

are available in the git repository at:

  https://github.com/AMarkovic/qemu tags/mips-queue-jan-28-2020

for you to fetch changes up to 370bf3a4196ebef247752a68b89d497522168ebb:

  target/mips: Add implementation of GINVT instruction (2020-01-28 20:52:20 
+0100)



MIPS queue for January 28th, 2020

  A diverse set of fixes and improvements:

- finalize documentation on deprecating r4k machine
- enable disassembler to receive target-specific data
- enable kernel loader to get e_flags from ELF header
- improve code flow in helper_do_semihosting()
- amend CP0 WatchHi register implementation
- add GINVT instruction emulation



Aleksandar Markovic (2):
  target/mips: Rectify documentation on deprecating r4k machine
  disas: Add a field for target-dependant data

Daniel Henrique Barboza (1):
  mips-semi.c: remove 'uhi_done' label in helper_do_semihosting()

Philippe Mathieu-Daudé (1):
  hw/core/loader: Let load_elf() populate the processor-specific flags

Yongbok Kim (2):
  target/mips: Amend CP0 WatchHi register implementation
  target/mips: Add implementation of GINVT instruction

 disas/mips.c   |  10 +++
 hw/alpha/dp264.c   |   4 +-
 hw/arm/armv7m.c|   2 +-
 hw/arm/boot.c  |   2 +-
 hw/core/generic-loader.c   |   2 +-
 hw/core/loader.c   |  37 +-
 hw/cris/boot.c |   2 +-
 hw/hppa/machine.c  |   4 +-
 hw/i386/multiboot.c|   2 +-
 hw/i386/x86.c  |   2 +-
 hw/lm32/lm32_boards.c  |   4 +-
 hw/lm32/milkymist.c|   2 +-
 hw/m68k/an5206.c   |   2 +-
 hw/m68k/mcf5208.c  |   2 +-
 hw/m68k/q800.c |   2 +-
 hw/microblaze/boot.c   |   4 +-
 hw/mips/mips_fulong2e.c|   2 +-
 hw/mips/mips_malta.c   |   3 +-
 hw/mips/mips_mipssim.c |   2 +-
 hw/mips/mips_r4k.c |   2 +-
 hw/moxie/moxiesim.c|   2 +-
 hw/nios2/boot.c|   4 +-
 hw/openrisc/openrisc_sim.c |   2 +-
 hw/pci-host/prep.c |   3 +-
 hw/ppc/e500.c  |   2 +-
 hw/ppc/mac_newworld.c  |   4 +-
 hw/ppc/mac_oldworld.c  |   4 +-
 hw/ppc/ppc440_bamboo.c |   2 +-
 hw/ppc/sam460ex.c  |   3 +-
 hw/ppc/spapr.c |   6 +-
 hw/ppc/virtex_ml507.c  |   2 +-
 hw/riscv/boot.c|   4 +-
 hw/s390x/ipl.c |   7 +-
 hw/sparc/leon3.c   |   2 +-
 hw/sparc/sun4m.c   |   4 +-
 hw/sparc64/sun4u.c |   5 +-
 hw/tricore/tricore_testboard.c |   2 +-
 hw/xtensa/sim.c|   2 +-
 hw/xtensa/xtfpga.c |   2 +-
 include/disas/dis-asm.h|   3 +
 include/hw/elf_ops.h   |   6 +-
 include/hw/loader.h|  21 +++---
 qemu-deprecated.texi   |   2 +-
 target/mips/cpu.h  |   4 +-
 target/mips/helper.c   |  20 --
 target/mips/helper.h   |   5 ++
 target/mips/internal.h |   1 +
 target/mips/machine.c  |   6 +-
 target/mips/mips-semi.c|  15 ++--
 target/mips/op_helper.c| 152 +++--
 target/mips/translate.c|  88 +++-
 51 files changed, 356 insertions(+), 121 deletions(-)

-- 
2.7.4




[PULL 1/6] target/mips: Rectify documentation on deprecating r4k machine

2020-01-28 Thread Aleksandar Markovic
From: Aleksandar Markovic 

Change the documented (in file qemu-deprecated.texi) release since
r4k machine is deprecated from 4.2 to 5.0.

Fixes: d32dc61421b

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Aleksandar Markovic 
Message-Id: <1579883929-1517-2-git-send-email-aleksandar.marko...@rt-rk.com>
---
 qemu-deprecated.texi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
index 0968d37..3d2a8ff 100644
--- a/qemu-deprecated.texi
+++ b/qemu-deprecated.texi
@@ -260,7 +260,7 @@ The 'scsi-disk' device is deprecated. Users should use 
'scsi-hd' or
 
 @section System emulator machines
 
-@subsection mips r4k platform (since 4.2)
+@subsection mips r4k platform (since 5.0)
 
 This machine type is very old and unmaintained. Users should use the 'malta'
 machine type instead.
-- 
2.7.4




Re: [PATCH v4 5/7] tests/boot_linux_console: Test booting U-Boot on the Raspberry Pi 2

2020-01-28 Thread Wainer dos Santos Moschetta



On 1/20/20 9:51 PM, Philippe Mathieu-Daudé wrote:

This test runs U-Boot on the Raspberry Pi 2.
It is very simple and fast:

   $ avocado --show=app,console run -t raspi2 -t u-boot tests/acceptance/
   JOB LOG: avocado/job-results/job-2020-01-20T23.40-2424777/job.log
(1/1) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_uboot:
   console: MMC:   sdhci@7e30: 0
   console: Loading Environment from FAT... Card did not respond to voltage 
select!
   console: In:serial
   console: Out:   vidconsole
   console: Err:   vidconsole
   console: Net:   No ethernet found.
   console: starting USB...
   console: USB0:   Port not available.
   console: Hit any key to stop autoboot:  0
   console: U-Boot>
   console: U-Boot> bdinfo
   console: arch_number = 0x
   console: boot_params = 0x0100
   console: DRAM bank   = 0x
   console: -> start= 0x
   console: -> size = 0x3c00
   console: baudrate= 115200 bps
   console: TLB addr= 0x3bff
   console: relocaddr   = 0x3bf64000
   console: reloc off   = 0x3bf5c000
   console: irq_sp  = 0x3bb5fec0
   console: sp start= 0x3bb5feb0
   console: Early malloc usage: 2a4 / 400
   console: fdt_blob= 0x3bfbdfb0
   console: U-Boot> version
   console: U-Boot 2019.01+dfsg-7 (May 14 2019 - 02:07:44 +)
   console: gcc (Debian 8.3.0-7) 8.3.0
   console: GNU ld (GNU Binutils for Debian) 2.31.1
   console: U-Boot> reset
   console: resetting ...
   PASS (0.46 s)

U-Boot is built by the Debian project, see:
https://wiki.debian.org/InstallingDebianOn/Allwinner#Creating_a_bootable_SD_Card_with_u-boot

Signed-off-by: Philippe Mathieu-Daudé 
---
  tests/acceptance/boot_linux_console.py | 28 ++
  1 file changed, 28 insertions(+)



Reviewed-by: Wainer dos Santos Moschetta 




diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index e40b84651b..682b801b4f 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -16,6 +16,7 @@ import shutil
  from avocado import skipUnless
  from avocado_qemu import Test
  from avocado_qemu import exec_command_and_wait_for_pattern
+from avocado_qemu import interrupt_interactive_console_until_pattern
  from avocado_qemu import wait_for_console_pattern
  from avocado.utils import process
  from avocado.utils import archive
@@ -485,6 +486,33 @@ class BootLinuxConsole(Test):
  exec_command_and_wait_for_pattern(self, 'reboot',
  'reboot: Restarting system')
  
+def test_arm_raspi2_uboot(self):

+"""
+:avocado: tags=arch:arm
+:avocado: tags=machine:raspi2
+:avocado: tags=u-boot
+"""
+deb_url = ('https://snapshot.debian.org/archive/debian/'
+   '20190514T084354Z/pool/main/u/u-boot/'
+   'u-boot-rpi_2019.01%2Bdfsg-7_armhf.deb')
+deb_hash = 'ad858cf3afe623b6c3fa2e20dcdd1768fcb9ae83'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+uboot_path = '/usr/lib/u-boot/rpi_2/uboot.elf'
+uboot_path = self.extract_from_deb(deb_path, uboot_path)
+
+self.vm.set_console()
+self.vm.add_args('-kernel', uboot_path,
+ # VideoCore starts CPU with only 1 core enabled
+ '-global', 'bcm2836.enabled-cpus=1',
+ '-no-reboot')
+self.vm.launch()
+interrupt_interactive_console_until_pattern(self,
+   'Hit any key to stop autoboot:',
+   'Config file not found')
+exec_command_and_wait_for_pattern(self, 'bdinfo', 'U-Boot')
+exec_command_and_wait_for_pattern(self, 'version', 'U-Boot')
+exec_command_and_wait_for_pattern(self, 'reset', 'resetting ...')
+
  def test_s390x_s390_ccw_virtio(self):
  """
  :avocado: tags=arch:s390x





Re: [PATCH v3 07/18] machine: Add a new function init_apicid_fn in MachineClass

2020-01-28 Thread Eduardo Habkost
On Tue, Jan 28, 2020 at 01:45:31PM -0600, Babu Moger wrote:
> 
> 
> On 1/28/20 10:29 AM, Igor Mammedov wrote:
> > On Tue, 03 Dec 2019 18:37:42 -0600
> > Babu Moger  wrote:
> > 
> >> Add a new function init_apicid_fn in MachineClass to initialize the mode
> >> specific handlers to decode the apic ids.
> >>
> >> Signed-off-by: Babu Moger 
> >> ---
> >>  include/hw/boards.h |1 +
> >>  vl.c|3 +++
> >>  2 files changed, 4 insertions(+)
> >>
> >> diff --git a/include/hw/boards.h b/include/hw/boards.h
> >> index d4fab218e6..ce5aa365cb 100644
> >> --- a/include/hw/boards.h
> >> +++ b/include/hw/boards.h
> >> @@ -238,6 +238,7 @@ struct MachineClass {
> >>   unsigned 
> >> cpu_index);
> >>  const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
> >>  int64_t (*get_default_cpu_node_id)(const MachineState *ms, int idx);
> >> +void (*init_apicid_fn)(MachineState *ms);
> > it's x86 specific, so why it wasn put into PCMachineClass?
> 
> Yes. It is x86 specific for now. I tried to make it generic function so
> other OSes can use it if required(like we have done in
> possible_cpu_arch_ids). It initializes functions required to build the
> apicid for each CPUs. We need these functions much early in the
> initialization. It should be initialized before parse_numa_opts or
> machine_run_board_init(in v1.c) which are called from generic context. We
> cannot use PCMachineClass at this time.

Even if the only user of the new hook will be x86, you are
introducing a generic API, so a x86-specific name doesn't seem
appropriate.

I suggest using a generic name and documenting its rules and
intended usage explicitly.  Something like "pre_init" might be
good enough, as long as the rules documented clearly (e.g. it
will be called before NUMA initialization, but after CPU model
lookup).

However, I believe we can implement the same functionality
without a new generic initialization hook.  See my reply to patch
16/18.

> 
> > 
> > 
> >>  };
> >>  
> >>  /**
> >> diff --git a/vl.c b/vl.c
> >> index a42c24a77f..b6af604e11 100644
> >> --- a/vl.c
> >> +++ b/vl.c
> >> @@ -4318,6 +4318,9 @@ int main(int argc, char **argv, char **envp)
> >>  current_machine->cpu_type = machine_class->default_cpu_type;
> >>  if (cpu_option) {
> >>  current_machine->cpu_type = parse_cpu_option(cpu_option);
> >> +if (machine_class->init_apicid_fn) {
> >> +machine_class->init_apicid_fn(current_machine);
> >> +}
> >>  }
> >>  parse_numa_opts(current_machine);
> >>  
> >>
> >>
> > 
> 

-- 
Eduardo




Re: [PATCH v4 6/7] tests/boot_linux_console: Test booting U-Boot on the Raspberry Pi 3

2020-01-28 Thread Wainer dos Santos Moschetta



On 1/20/20 9:51 PM, Philippe Mathieu-Daudé wrote:

This test runs U-Boot on the Raspberry Pi 3.
It is very simple and fast:

   $ avocado --show=app,console run -t raspi3 -t u-boot tests/acceptance/
   JOB LOG: avocado/job-results/job-2020-01-20T23.40-2424777/job.log
(1/1) 
tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_aarch64_raspi3_uboot:
   console: MMC:   mmc@7e202000: 0, sdhci@7e30: 1
   console: Loading Environment from FAT... WARNING at 
drivers/mmc/bcm2835_sdhost.c:410/bcm2835_send_command()!
   console: WARNING at drivers/mmc/bcm2835_sdhost.c:410/bcm2835_send_command()!
   console: Card did not respond to voltage select!
   console: In:serial
   console: Out:   vidconsole
   console: Err:   vidconsole
   console: Net:   No ethernet found.
   console: starting USB...
   console: Bus usb@7e98: Port not available.
   console: Hit any key to stop autoboot:  0
   console: U-Boot>
   console: U-Boot>
   console: U-Boot> bdinfo
   console: arch_number = 0x
   console: boot_params = 0x0100
   console: DRAM bank   = 0x
   console: -> start= 0x
   console: -> size = 0x3c00
   console: baudrate= 115200 bps
   console: TLB addr= 0x3bff
   console: relocaddr   = 0x3bf57000
   console: reloc off   = 0x3bed7000
   console: irq_sp  = 0x3bb52dd0
   console: sp start= 0x3bb52dd0
   console: FB base = 0x
   console: Early malloc usage: 7b0 / 2000
   console: fdt_blob= 0x3bfbf200
   console: U-Boot> version
   console: U-Boot 2020.01+dfsg-1 (Jan 08 2020 - 08:19:44 +)
   console: gcc (Debian 9.2.1-22) 9.2.1 20200104
   console: GNU ld (GNU Binutils for Debian) 2.33.1
   console: U-Boot> reset
   console: resetting ...
   PASS (1.79 s)

U-Boot is built by the Debian project, see:
https://wiki.debian.org/InstallingDebianOn/Allwinner#Creating_a_bootable_SD_Card_with_u-boot

Signed-off-by: Philippe Mathieu-Daudé 
---
  tests/acceptance/boot_linux_console.py | 25 +
  1 file changed, 25 insertions(+)



Reviewed-by: Wainer dos Santos Moschetta 




diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 682b801b4f..22b360118d 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -513,6 +513,31 @@ class BootLinuxConsole(Test):
  exec_command_and_wait_for_pattern(self, 'version', 'U-Boot')
  exec_command_and_wait_for_pattern(self, 'reset', 'resetting ...')
  
+def test_aarch64_raspi3_uboot(self):

+"""
+:avocado: tags=arch:aarch64
+:avocado: tags=machine:raspi3
+:avocado: tags=u-boot
+"""
+deb_url = ('https://snapshot.debian.org/archive/debian/'
+   '20200108T145233Z/pool/main/u/u-boot/'
+   'u-boot-rpi_2020.01%2Bdfsg-1_arm64.deb')
+deb_hash = 'f394386e02469d52f2eb3c07a2325b1c95aeb00b'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+uboot_path = '/usr/lib/u-boot/rpi_3/u-boot.bin'
+uboot_path = self.extract_from_deb(deb_path, uboot_path)
+
+self.vm.set_console(console_index=1)
+self.vm.add_args('-kernel', uboot_path,
+ '-no-reboot')
+self.vm.launch()
+interrupt_interactive_console_until_pattern(self,
+   'Hit any key to stop autoboot:',
+   'Config file not found')
+exec_command_and_wait_for_pattern(self, 'bdinfo', 'U-Boot')
+exec_command_and_wait_for_pattern(self, 'version', 'U-Boot')
+exec_command_and_wait_for_pattern(self, 'reset', 'resetting ...')
+
  def test_s390x_s390_ccw_virtio(self):
  """
  :avocado: tags=arch:s390x





Re: [PATCH v3 08/13] monitor/hmp: move hmp_nbd_server* to block-hmp-cmds.c

2020-01-28 Thread Eric Blake

On 1/28/20 12:56 PM, Dr. David Alan Gilbert wrote:

* Maxim Levitsky (mlevi...@redhat.com) wrote:

Signed-off-by: Maxim Levitsky 


Yes, I think that's OK; I can imagine nbd might want to move on it's own
somewhere since it's not really core block code; copying in Eric.


I think that nbd-server-start and friends ARE related to core block 
code; they do not work without a BDS node.  It's not the same as a block 
driver, though, in that it is exposing the BDS to the outside world, 
rather than connecting an outside resource for use internally by the guest.


At any rate, block-hmp-cmds.c seems reasonable enough as a new location 
for these HMP commands.





Reviewed-by: Dr. David Alan Gilbert 


---
  block/monitor/block-hmp-cmds.c | 88 ++
  include/block/block-hmp-commands.h |  5 ++
  include/monitor/hmp.h  |  4 --
  monitor/hmp-cmds.c | 87 -
  4 files changed, 93 insertions(+), 91 deletions(-)


Reviewed-by: Eric Blake 

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




Re: [PATCH v3 16/18] hw/i386: Introduce EPYC mode function handlers

2020-01-28 Thread Eduardo Habkost
Hi,

Sorry for taking so long.  I was away from the office for a
month, and now I'm finally back.

On Tue, Dec 03, 2019 at 06:38:46PM -0600, Babu Moger wrote:
> Introduce following handlers for new epyc mode.
> x86_apicid_from_cpu_idx_epyc: Generate apicid from cpu index.
> x86_topo_ids_from_apicid_epyc: Generate topo ids from apic id.
> x86_apicid_from_topo_ids_epyc: Generate apicid from topo ids.
> 
> Signed-off-by: Babu Moger 
> ---
>  hw/i386/pc.c   |   12 
>  include/hw/i386/topology.h |4 ++--
>  2 files changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index e6c8a458e7..64e3658873 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -2819,6 +2819,17 @@ static bool pc_hotplug_allowed(MachineState *ms, 
> DeviceState *dev, Error **errp)
>  return true;
>  }
>  
> +static void pc_init_apicid_fn(MachineState *ms)
> +{
> +PCMachineState *pcms = PC_MACHINE(ms);
> +
> +if (!strncmp(ms->cpu_type, "EPYC", 4)) {

Please never use string comparison to introduce device-specific
behavior.  I had already pointed this out at
https://lore.kernel.org/qemu-devel/20190801192830.gd20...@habkost.net/

If you need a CPU model to provide special behavior,
you have two options:

* Add a method pointer to X86CPUClass and/or X86CPUDefinition
* Add a QOM property to enable/disable special behavior, and
  include the property in the CPU model definition.

The second option might be preferable long term, but might
require more work because the property would become visible in
query-cpu-model-expansion and in the command line.  The first
option may be acceptable to avoid extra user-visible complexity
in the first version.



> +pcms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx_epyc;
> +pcms->topo_ids_from_apicid = x86_topo_ids_from_apicid_epyc;
> +pcms->apicid_from_topo_ids = x86_apicid_from_topo_ids_epyc;

Why do you need to override the function pointers in
PCMachineState instead of just looking up the relevant info at
X86CPUClass?

If both machine-types and CPU models are supposed to override the
APIC ID calculation functions, the interaction between
machine-type and CPU model needs to be better documented
(preferably with simple test cases) to ensure we won't break
compatibility later.

> +}
> +}
> +
>  static void pc_machine_class_init(ObjectClass *oc, void *data)
>  {
>  MachineClass *mc = MACHINE_CLASS(oc);
> @@ -2847,6 +2858,7 @@ static void pc_machine_class_init(ObjectClass *oc, void 
> *data)
>  mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
>  mc->get_default_cpu_node_id = pc_get_default_cpu_node_id;
>  mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
> +mc->init_apicid_fn = pc_init_apicid_fn;
>  mc->auto_enable_numa_with_memhp = true;
>  mc->has_hotpluggable_cpus = true;
>  mc->default_boot_order = "cad";
> diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
> index b2b9e93a06..f028d2332a 100644
> --- a/include/hw/i386/topology.h
> +++ b/include/hw/i386/topology.h
> @@ -140,7 +140,7 @@ static inline unsigned 
> apicid_pkg_offset_epyc(X86CPUTopoInfo *topo_info)
>   *
>   * The caller must make sure core_id < nr_cores and smt_id < nr_threads.
>   */
> -static inline apic_id_t apicid_from_topo_ids_epyc(X86CPUTopoInfo *topo_info,
> +static inline apic_id_t x86_apicid_from_topo_ids_epyc(X86CPUTopoInfo 
> *topo_info,
>const X86CPUTopoIDs 
> *topo_ids)
>  {
>  return (topo_ids->pkg_id  << apicid_pkg_offset_epyc(topo_info)) |
> @@ -200,7 +200,7 @@ static inline apic_id_t 
> x86_apicid_from_cpu_idx_epyc(X86CPUTopoInfo *topo_info,
>  {
>  X86CPUTopoIDs topo_ids;
>  x86_topo_ids_from_idx_epyc(topo_info, cpu_index, _ids);
> -return apicid_from_topo_ids_epyc(topo_info, _ids);
> +return x86_apicid_from_topo_ids_epyc(topo_info, _ids);
>  }
>  /* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID
>   *
> 
> 

-- 
Eduardo




Re: [PATCH v4 3/7] Acceptance tests: Add interrupt_interactive_console_until_pattern()

2020-01-28 Thread Wainer dos Santos Moschetta



On 1/20/20 9:51 PM, Philippe Mathieu-Daudé wrote:

We need a function to interrupt interactive consoles.

Example: Interrupt U-Boot to set different environment values.

Tested-by: Niek Linnenbank 
Signed-off-by: Philippe Mathieu-Daudé 
---
  tests/acceptance/avocado_qemu/__init__.py | 32 +--
  1 file changed, 30 insertions(+), 2 deletions(-)


Reviewed-by: Wainer dos Santos Moschetta 




diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py
index 0a50fcf2be..d4358eb431 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -56,13 +56,15 @@ def pick_default_qemu_bin(arch=None):
  
  
  def _console_interaction(test, success_message, failure_message,

- send_string):
+ send_string, keep_sending=False):
+assert not keep_sending or send_string
  console = test.vm.console_socket.makefile()
  console_logger = logging.getLogger('console')
  while True:
  if send_string:
  test.vm.console_socket.sendall(send_string.encode())
-send_string = None # send only once
+if not keep_sending:
+send_string = None # send only once
  msg = console.readline().strip()
  if not msg:
  continue
@@ -74,6 +76,32 @@ def _console_interaction(test, success_message, 
failure_message,
  fail = 'Failure message found in console: %s' % failure_message
  test.fail(fail)
  
+def interrupt_interactive_console_until_pattern(test, success_message,

+failure_message=None,
+interrupt_string='\r'):
+"""
+Keep sending a string to interrupt a console prompt, while logging the
+console output. Typical use case is to break a boot loader prompt, such:
+
+Press a key within 5 seconds to interrupt boot process.
+5
+4
+3
+2
+1
+Booting default image...
+
+:param test: an Avocado test containing a VM that will have its console
+ read and probed for a success or failure message
+:type test: :class:`avocado_qemu.Test`
+:param success_message: if this message appears, test succeeds
+:param failure_message: if this message appears, test fails
+:param interrupt_string: a string to send to the console before trying
+ to read a new line
+"""
+_console_interaction(test, success_message, failure_message,
+ interrupt_string, True)
+
  def wait_for_console_pattern(test, success_message, failure_message=None):
  """
  Waits for messages to appear on the console, while logging the content





Re: [PATCH v4 2/7] Acceptance tests: Extract _console_interaction()

2020-01-28 Thread Wainer dos Santos Moschetta



On 1/28/20 5:34 PM, Wainer dos Santos Moschetta wrote:


On 1/20/20 9:51 PM, Philippe Mathieu-Daudé wrote:

Since we are going to re-use the code shared between
wait_for_console_pattern() and exec_command_and_wait_for_pattern(),
extract the common part into a local function.

Tested-by: Niek Linnenbank 
Signed-off-by: Philippe Mathieu-Daudé 
---
  tests/acceptance/avocado_qemu/__init__.py | 31 +--
  1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/tests/acceptance/avocado_qemu/__init__.py 
b/tests/acceptance/avocado_qemu/__init__.py

index 6618ea67c1..0a50fcf2be 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -55,19 +55,14 @@ def pick_default_qemu_bin(arch=None):
  return qemu_bin_from_src_dir_path
    -def wait_for_console_pattern(test, success_message, 
failure_message=None):

-    """
-    Waits for messages to appear on the console, while logging the 
content

-
-    :param test: an Avocado test containing a VM that will have its 
console

- read and probed for a success or failure message
-    :type test: :class:`avocado_qemu.Test`
-    :param success_message: if this message appears, test succeeds
-    :param failure_message: if this message appears, test fails
-    """
+def _console_interaction(test, success_message, failure_message,
+ send_string):



Why not just add send_string as a parameter? Like:

def wait_for_console_pattern(test, success_message, 
failure_message=None, send_msg=None)




  console = test.vm.console_socket.makefile()
  console_logger = logging.getLogger('console')
  while True:
+    if send_string:
+ test.vm.console_socket.sendall(send_string.encode())
+    send_string = None # send only once


If it is going to send the message once, then put it before the loop.


OK, now that I read the next patch in this series (patch 03), I 
understood what you trying to accomplish here. So disregard my comments.


Reviewed-by: Wainer dos Santos Moschetta 






  msg = console.readline().strip()
  if not msg:
  continue
@@ -79,6 +74,17 @@ def wait_for_console_pattern(test, 
success_message, failure_message=None):
  fail = 'Failure message found in console: %s' % 
failure_message

  test.fail(fail)
  +def wait_for_console_pattern(test, success_message, 
failure_message=None):

+    """
+    Waits for messages to appear on the console, while logging the 
content

+
+    :param test: an Avocado test containing a VM that will have its 
console

+ read and probed for a success or failure message
+    :type test: :class:`avocado_qemu.Test`
+    :param success_message: if this message appears, test succeeds
+    :param failure_message: if this message appears, test fails
+    """
+    _console_interaction(test, success_message, failure_message, None)
    def exec_command_and_wait_for_pattern(test, command,
    success_message, 
failure_message=None):

@@ -94,10 +100,7 @@ def exec_command_and_wait_for_pattern(test, command,
  :param success_message: if this message appears, test succeeds
  :param failure_message: if this message appears, test fails
  """
-    command += '\r'
-    test.vm.console_socket.sendall(command.encode())
-    wait_for_console_pattern(test, success_message, failure_message)
-
+    _console_interaction(test, success_message, failure_message, 
command + '\r')

    class Test(avocado.Test):
  def _get_unique_tag_val(self, tag_name):








Re: [PATCH v3 11/13] monitor: Move hmp_drive_add_node to block-hmp-cmds.c

2020-01-28 Thread Maxim Levitsky
On Tue, 2020-01-28 at 19:03 +, Dr. David Alan Gilbert wrote:
> * Maxim Levitsky (mlevi...@redhat.com) wrote:
> > Signed-off-by: Maxim Levitsky 
> 
> Looks OK to me, I'm not clear on the name for 'bdrv_set_monitor_owned'
> I'd want a block person to OK that, but:


The name inspiration came from 'bdrv_next_monitor_owned'. To me it looks
like list of all BlockDriverState which are created by the monitor.
Also comment on 'monitor_list' link chain more or less confirms this.

Thanks for the review!

Best regards,
Maxim Levitsky


> 
> 
> Reviewed-by: Dr. David Alan Gilbert 
> 
> > ---
> >  block/monitor/block-hmp-cmds.c | 30 
> >  blockdev.c | 42 +++---
> >  include/block/block_int.h  |  5 ++--
> >  3 files changed, 41 insertions(+), 36 deletions(-)
> > 
> > diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
> > index a4b1604aee..7bbe4e3814 100644
> > --- a/block/monitor/block-hmp-cmds.c
> > +++ b/block/monitor/block-hmp-cmds.c
> > @@ -33,6 +33,36 @@
> >  #include "monitor/hmp.h"
> >  #include "qemu-io.h"
> >  
> > +static void hmp_drive_add_node(Monitor *mon, const char *optstr)
> > +{
> > +QemuOpts *opts;
> > +QDict *qdict;
> > +Error *local_err = NULL;
> > +
> > +opts = qemu_opts_parse_noisily(_drive_opts, optstr, false);
> > +if (!opts) {
> > +return;
> > +}
> > +
> > +qdict = qemu_opts_to_qdict(opts, NULL);
> > +
> > +if (!qdict_get_try_str(qdict, "node-name")) {
> > +qobject_unref(qdict);
> > +error_report("'node-name' needs to be specified");
> > +goto out;
> > +}
> > +
> > +BlockDriverState *bs = bds_tree_init(qdict, _err);
> > +if (!bs) {
> > +error_report_err(local_err);
> > +goto out;
> > +}
> > +
> > +bdrv_set_monitor_owned(bs);
> > +out:
> > +qemu_opts_del(opts);
> > +}
> > +
> >  void hmp_drive_add(Monitor *mon, const QDict *qdict)
> >  {
> >  Error *err = NULL;
> > diff --git a/blockdev.c b/blockdev.c
> > index df43e0aaef..63805f34b5 100644
> > --- a/blockdev.c
> > +++ b/blockdev.c
> > @@ -64,7 +64,7 @@
> >  #include "qemu/main-loop.h"
> >  #include "qemu/throttle-options.h"
> >  
> > -static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
> > +QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
> >  QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
> >  
> >  static int do_open_tray(const char *blk_name, const char *qdev_id,
> > @@ -75,6 +75,11 @@ static void blockdev_insert_medium(bool has_device, 
> > const char *device,
> > bool has_id, const char *id,
> > const char *node_name, Error **errp);
> >  
> > +void bdrv_set_monitor_owned(BlockDriverState *bs)
> > +{
> > +QTAILQ_INSERT_TAIL(_bdrv_states, bs, monitor_list);
> > +}
> > +
> >  static const char *const if_name[IF_COUNT] = {
> >  [IF_NONE] = "none",
> >  [IF_IDE] = "ide",
> > @@ -652,7 +657,7 @@ err_no_opts:
> >  }
> >  
> >  /* Takes the ownership of bs_opts */
> > -static BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
> > +BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
> >  {
> >  int bdrv_flags = 0;
> >  
> > @@ -4201,37 +4206,6 @@ out:
> >  aio_context_release(aio_context);
> >  }
> >  
> > -void hmp_drive_add_node(Monitor *mon, const char *optstr)
> > -{
> > -QemuOpts *opts;
> > -QDict *qdict;
> > -Error *local_err = NULL;
> > -
> > -opts = qemu_opts_parse_noisily(_drive_opts, optstr, false);
> > -if (!opts) {
> > -return;
> > -}
> > -
> > -qdict = qemu_opts_to_qdict(opts, NULL);
> > -
> > -if (!qdict_get_try_str(qdict, "node-name")) {
> > -qobject_unref(qdict);
> > -error_report("'node-name' needs to be specified");
> > -goto out;
> > -}
> > -
> > -BlockDriverState *bs = bds_tree_init(qdict, _err);
> > -if (!bs) {
> > -error_report_err(local_err);
> > -goto out;
> > -}
> > -
> > -QTAILQ_INSERT_TAIL(_bdrv_states, bs, monitor_list);
> > -
> > -out:
> > -qemu_opts_del(opts);
> > -}
> > -
> >  void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
> >  {
> >  BlockDriverState *bs;
> > @@ -4261,7 +4235,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error 
> > **errp)
> >  goto fail;
> >  }
> >  
> > -QTAILQ_INSERT_TAIL(_bdrv_states, bs, monitor_list);
> > +bdrv_set_monitor_owned(bs);
> >  
> >  fail:
> >  visit_free(v);
> > diff --git a/include/block/block_int.h b/include/block/block_int.h
> > index dd033d0b37..10df257a61 100644
> > --- a/include/block/block_int.h
> > +++ b/include/block/block_int.h
> > @@ -1217,8 +1217,6 @@ BlockJob *backup_job_create(const char *job_id, 
> > BlockDriverState *bs,
> >  BlockCompletionFunc *cb, void *opaque,
> >  JobTxn *txn, Error **errp);
> >  
> > -void 

Re: [PATCH v3 03/13] monitor/hmp: rename device-hotplug.c to block/monitor/block-hmp-cmds.c

2020-01-28 Thread Maxim Levitsky
On Tue, 2020-01-28 at 16:56 +, Dr. David Alan Gilbert wrote:
> * Maxim Levitsky (mlevi...@redhat.com) wrote:
> > These days device-hotplug.c only contains the hmp_drive_add
> > In the next patch, rest of hmp_drive* functions will be moved
> > there.
> > 
> > Also change the license of that file to GPL2+ since most
> > of the code that will be moved there is under that license
> 
> How do we check that's OK?

Currently that code is BSD licensed, and in next patches I will move
here GPLv2+ code, and as far as I know combining them gives you GPLv2+

I wasn't even aware that we have mixed licenses, and so this change was done
after Markus pointed this out in the previous patchset review.

Best regards,
Maxim Levitsky

> 
> > Also add block-hmp-commands.h to contain prototypes of these
> > functions
> > 
> > Signed-off-by: Maxim Levitsky 
> > ---
> >  MAINTAINERS   |  1 +
> >  Makefile.objs |  2 +-
> >  block/Makefile.objs   |  1 +
> >  block/monitor/Makefile.objs   |  1 +
> >  .../monitor/block-hmp-cmds.c  | 23 ---
> >  include/block/block-hmp-commands.h|  8 +++
> >  include/sysemu/sysemu.h   |  3 ---
> >  monitor/misc.c|  1 +
> >  8 files changed, 18 insertions(+), 22 deletions(-)
> >  create mode 100644 block/monitor/Makefile.objs
> >  rename device-hotplug.c => block/monitor/block-hmp-cmds.c (55%)
> >  create mode 100644 include/block/block-hmp-commands.h
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index f6511d5120..5d50d09ad8 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1882,6 +1882,7 @@ Block QAPI, monitor, command line
> >  M: Markus Armbruster 
> >  S: Supported
> >  F: blockdev.c
> > +F: blockdev-hmp-cmds.c
> >  F: block/qapi.c
> >  F: qapi/block*.json
> >  F: qapi/transaction.json
> > diff --git a/Makefile.objs b/Makefile.objs
> > index ff396b9209..15209eb6b5 100644
> > --- a/Makefile.objs
> > +++ b/Makefile.objs
> > @@ -48,7 +48,7 @@ common-obj-y += dump/
> >  common-obj-y += job-qmp.o
> >  common-obj-y += monitor/
> >  common-obj-y += net/
> > -common-obj-y += qdev-monitor.o device-hotplug.o
> > +common-obj-y += qdev-monitor.o
> >  common-obj-$(CONFIG_WIN32) += os-win32.o
> >  common-obj-$(CONFIG_POSIX) += os-posix.o
> >  
> > diff --git a/block/Makefile.objs b/block/Makefile.objs
> > index 330529b0b7..3f65544a6b 100644
> > --- a/block/Makefile.objs
> > +++ b/block/Makefile.objs
> > @@ -44,6 +44,7 @@ block-obj-y += crypto.o
> >  block-obj-y += aio_task.o
> >  block-obj-y += backup-top.o
> >  block-obj-y += filter-compress.o
> > +common-obj-y += monitor/
> >  
> >  common-obj-y += stream.o
> >  
> > diff --git a/block/monitor/Makefile.objs b/block/monitor/Makefile.objs
> > new file mode 100644
> > index 00..0a74f9a8b5
> > --- /dev/null
> > +++ b/block/monitor/Makefile.objs
> > @@ -0,0 +1 @@
> > +common-obj-y += block-hmp-cmds.o
> > diff --git a/device-hotplug.c b/block/monitor/block-hmp-cmds.c
> > similarity index 55%
> > rename from device-hotplug.c
> > rename to block/monitor/block-hmp-cmds.c
> > index 554e4d98db..c65aaa86ea 100644
> > --- a/device-hotplug.c
> > +++ b/block/monitor/block-hmp-cmds.c
> > @@ -1,25 +1,11 @@
> >  /*
> > - * QEMU device hotplug helpers
> > + * Blockdev HMP commands
> >   *
> >   * Copyright (c) 2004 Fabrice Bellard
> >   *
> > - * Permission is hereby granted, free of charge, to any person obtaining a 
> > copy
> > - * of this software and associated documentation files (the "Software"), 
> > to deal
> > - * in the Software without restriction, including without limitation the 
> > rights
> > - * to use, copy, modify, merge, publish, distribute, sublicense, and/or 
> > sell
> > - * copies of the Software, and to permit persons to whom the Software is
> > - * furnished to do so, subject to the following conditions:
> > - *
> > - * The above copyright notice and this permission notice shall be included 
> > in
> > - * all copies or substantial portions of the Software.
> > - *
> > - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
> > OR
> > - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> > - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
> > OTHER
> > - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> > FROM,
> > - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
> > IN
> > - * THE SOFTWARE.
> > + * This work is licensed under the terms of the GNU GPL, version 2.
> > + * or (at your option) any later version.
> > + * See the COPYING file in the top-level directory.
> >   */
> >  
> >  #include "qemu/osdep.h"
> > @@ -33,6 +19,7 @@
> >  #include "sysemu/sysemu.h"
> >  #include "monitor/monitor.h"
> >  #include 

Re: [PATCH 9/9] monitor/hmp: Prefer to use hmp_handle_error for error reporting in block hmp commands

2020-01-28 Thread Dr. David Alan Gilbert
* Maxim Levitsky (mlevi...@redhat.com) wrote:
> On Mon, 2020-01-27 at 14:44 +0100, Markus Armbruster wrote:
> > Maxim Levitsky  writes:
> > 
> > > On Wed, 2019-11-27 at 09:38 +0100, Markus Armbruster wrote:
> > > > Title is too long.  blockdev-hmp-cmds.c will become
> > > > block/monitor/block-hmp-cmds.c in v2.  With this in mind, suggest
> > > > 
> > > > block/monitor: Prefer to use hmp_handle_error() to report HMP errors
> > > > 
> > > > Maxim Levitsky  writes:
> > > > 
> > > > > This way they all will be prefixed with 'Error:' which some parsers
> > > > > (e.g libvirt need)
> > > > 
> > > > Sadly, "all" is far from true.  Consider
> > > > 
> > > > void hmp_drive_add(Monitor *mon, const QDict *qdict)
> > > > {
> > > > Error *err = NULL;
> > > > DriveInfo *dinfo = NULL;
> > > > QemuOpts *opts;
> > > > MachineClass *mc;
> > > > const char *optstr = qdict_get_str(qdict, "opts");
> > > > bool node = qdict_get_try_bool(qdict, "node", false);
> > > > 
> > > > if (node) {
> > > > hmp_drive_add_node(mon, optstr);
> > > > return;
> > > > }
> > > > 
> > > > opts = drive_def(optstr);
> > > > if (!opts)
> > > > return;
> > > > 
> > > > 
> > > > hmp_drive_add_node() uses error_report() and error_report_err().  Easy
> > > > enough to fix if you move the function here, as I suggested in my review
> > > > of PATCH 8.
> > > 
> > > To be honest that involves exporting the monitor_bdrv_states variable and
> > > bds_tree_init, which were both static before, but I created a patch that 
> > > does that,
> > > If that is all right, I'll squash it with some of my patches.
> > > 
> > > 
> > > > 
> > > > drive_def() is a wrapper around qemu_opts_parse_noisily(), which uses
> > > > error_report_err().  You can't change qemu_opts_parse_noisily() to use
> > > > hmp_handle_error().  You'd have to convert drive_def() to Error, which
> > > > involves switching it to qemu_opts_parse() + qemu_opts_print_help().
> > > > 
> > > > These are just the first two error paths in this file.  There's much
> > > > more.  Truly routing all HMP errors through hmp_handle_error() takes a
> > > > *massive* Error conversion effort, with a high risk of missing Error
> > > > conversions, followed by a never-ending risk of non-Error stuff creeping
> > > > in.
> > > 
> > > Oops. Active can of worms is detected. Take cover!
> > 
> > :)
> > 
> > > > There must be an easier way.
> > > > 
> > > > Consider vreport():
> > > > 
> > > > switch (type) {
> > > > case REPORT_TYPE_ERROR:
> > > > break;
> > > > case REPORT_TYPE_WARNING:
> > > > error_printf("warning: ");
> > > > break;
> > > > case REPORT_TYPE_INFO:
> > > > error_printf("info: ");
> > > > break;
> > > > }
> > > > 
> > > > Adding the prefix here (either unconditionally, or if cur_mon) covers
> > > > all HMP errors reported with error_report() & friends in one blow.
> > > 
> > > This is a very good idea.
> > > If feels like this should be done unconditionally, although that will
> > > break probably some scripts that depend on exact value of the error 
> > > message (but to be honest,
> > > scripts shouldn't be doing that in first place).
> > > 
> > > Doing that with cur_mon (took me some time to figure out what that is) 
> > > will
> > > limit the damage but its a bit of a hack.
> > > 
> > > 
> > > I think that this is a very good change anyway though so if everyone 
> > > agrees,
> > > I will be more that happy to do this change.
> > > Thoughts?
> > 
> > I think adding an "error: " tag has been proposed before.
> > 
> > I dislike overly decorated error messages, because decoration tends to
> > obscure information.
> > 
> > However, when there's significant non-error output, or even uncertainty
> > of what's an error and what's something else, decoration can help.
> Yes, also this way it is consistent

Yes I also like it; I wouldn't worry too much about things parsing error
messages for the exact error message; if anything is doing that then the
corresponding case needs to have big red flags around it.

Dave

> > 
> > Perhaps you can give some examples where the proposed decoration helps.
> It helps to tag most monitor messages with error prefix which was the root 
> cause of
> me starting to work on this refactoring.
> You suggested this, and I kind of like that idea.
> 
> > 
> > > > That leaves the ones that are still reported with monitor_printf().
> > > > Converting those to error_report() looks far more tractable to me.
> > > 
> > > Yep, in fact I grepped the tree for monitor_printf and there are not
> > > that much instances of this used for error reporting, so it might
> > > be possible to have 'error' prefix on all monitor errors that way
> > > and not only for the block layer.
> > 
> > I figure "all" would be more useful than "just for the block layer".
> Yep, the cover letter is outdated, now this patch series 

Re: [PATCH rc3 23/30] hw/core/loader: Let load_elf populate the processor-specific flags

2020-01-28 Thread Aleksandar Markovic
On Tue, Jan 28, 2020 at 2:27 PM Aleksandar Markovic <
aleksandar.m.m...@gmail.com> wrote:

>
>
> On Tuesday, January 28, 2020, BALATON Zoltan  wrote:
>
>> On Tue, 28 Jan 2020, Aleksandar Markovic wrote:
>>
>>> On Sunday, January 26, 2020, Aleksandar Markovic <
>>> aleksandar.marko...@rt-rk.com> wrote:
>>>
>>> From: Philippe Mathieu-Daudé 

 Some platforms (like AVR) need to determine cpu type by reading
 the ELF flags (field e_flags oin ELF header).

 This patch enables discovery of the content of that flag while
 using following functions:

   - load_elf()
   - load_elf_as()
   - load_elf_ram()
   - load_elf_ram_sym()

 The added argument of these functions is of type uint32_t*. It is
 allowed to pass NULL as that argument, and in such case no lookup
 to the field e_flags will happen, and of course, no information
 will be returned to the caller.


Applied to MIPS queue, with some commit message corrections and fixes.


>
 We plan to use this new functionality for MIPS Malta board, for
>>> detection
>>> of incompatible cpu/kernel combinations, and graceful exit (right now
>>> these
>>> combinations result in hang or crash). I would say other boards could
>>> make
>>> use of it too.
>>>
>>> For that reason, if there is no objection, I plan to select this patch
>>> for
>>> next MIPS queue.
>>>
>>
>> No objection but kind of déjà vu:
>>
>> https://lists.nongnu.org/archive/html/qemu-devel/2019-01/msg03427.html
>>
>> I still think the interface of load_elf may need to be rethinked but I
>> don't know a good way.
>
>
>>
> Perhaps having only two, "in" and "out", arguments that are pointers to
> structures?
>
> Another thing that I noticed is "endian argument" that it seems everyone
> uses in a different way: 0, 1, true, false, bigendian, etc. Would c
> enumeration help? This looks to me like a time ticking bomb.
>
> Just to add that some platforms like MIPS and SPARC must load elfs of more
> than one value of EM_MACHINE (in MIPS case, EM_MIPS and EM_NANOMIPS) and
> current load_elf() interface offers only clumsy solutions/workarounds in
> these cases.
>
> Let's think about everything later on.
>
>
>>  This could be fixed in a later patch causing more code churn again
>> though, so if there's a way to fix this it might be a good opportunity now.
>> But I don't want to hold your patch series back so unless someone has a
>> good idea to avoid this situation then we have to live with it.
>>
>>
> Thank you. I will do some minor corrections for obvious unclarities and
> typos in the commit message while applying to my qieue.
>
>
>> Regards,
>> BALATON Zoltan
>>
>>
>>> Regards,
>>> Aleksandar
>>>
>>>
>>>
>>>
>>> CC: Richard Henderson 
 CC: Peter Maydell 
 CC: Edgar E. Iglesias 
 CC: Michael Walle 
 CC: Thomas Huth 
 CC: Laurent Vivier 
 CC: Philippe Mathieu-Daudé 
 CC: Aleksandar Rikalo 
 CC: Aurelien Jarno 
 CC: Jia Liu 
 CC: David Gibson 
 CC: Mark Cave-Ayland 
 CC: BALATON Zoltan 
 CC: Christian Borntraeger 
 CC: Thomas Huth 
 CC: Artyom Tarasenko 
 CC: Fabien Chouteau 
 CC: KONRAD Frederic 
 CC: Max Filippov 

 Signed-off-by: Michael Rolnik 
 Reviewed-by: Aleksandar Markovic 
 [PMD: Extracted from bigger patch,
   Replaced 'uint32_t *pe_flags' by 'int proc_flags']
 [AM: Replaced 'int proc_flags' with 'uint32_t *pflags',
  replaced one instance of 'elf_sword' to 'elf_word',
  extended functionality to load_elf()]
 Signed-off-by: Philippe Mathieu-Daudé 
 Signed-off-by: Aleksandar Markovic 
 ---
  hw/alpha/dp264.c   |  4 ++--
  hw/arm/armv7m.c|  2 +-
  hw/arm/boot.c  |  2 +-
  hw/core/generic-loader.c   |  2 +-
  hw/core/loader.c   | 37
 +++--
  hw/cris/boot.c |  2 +-
  hw/hppa/machine.c  |  4 ++--
  hw/i386/multiboot.c|  2 +-
  hw/i386/x86.c  |  2 +-
  hw/lm32/lm32_boards.c  |  4 ++--
  hw/lm32/milkymist.c|  2 +-
  hw/m68k/an5206.c   |  2 +-
  hw/m68k/mcf5208.c  |  2 +-
  hw/m68k/q800.c |  2 +-
  hw/microblaze/boot.c   |  4 ++--
  hw/mips/mips_fulong2e.c|  2 +-
  hw/mips/mips_malta.c   |  3 ++-
  hw/mips/mips_mipssim.c |  2 +-
  hw/mips/mips_r4k.c |  2 +-
  hw/moxie/moxiesim.c|  2 +-
  hw/nios2/boot.c|  4 ++--
  hw/openrisc/openrisc_sim.c |  2 +-
  hw/pci-host/prep.c |  3 ++-
  hw/ppc/e500.c  |  2 +-
  hw/ppc/mac_newworld.c  |  4 ++--
  hw/ppc/mac_oldworld.c  |  4 ++--
  hw/ppc/ppc440_bamboo.c |  2 +-
  hw/ppc/sam460ex.c  |  3 ++-
  hw/ppc/spapr.c  

Re: [PATCH v3 11/13] monitor: Move hmp_drive_add_node to block-hmp-cmds.c

2020-01-28 Thread Dr. David Alan Gilbert
* Maxim Levitsky (mlevi...@redhat.com) wrote:
> Signed-off-by: Maxim Levitsky 

Looks OK to me, I'm not clear on the name for 'bdrv_set_monitor_owned'
I'd want a block person to OK that, but:


Reviewed-by: Dr. David Alan Gilbert 

> ---
>  block/monitor/block-hmp-cmds.c | 30 
>  blockdev.c | 42 +++---
>  include/block/block_int.h  |  5 ++--
>  3 files changed, 41 insertions(+), 36 deletions(-)
> 
> diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
> index a4b1604aee..7bbe4e3814 100644
> --- a/block/monitor/block-hmp-cmds.c
> +++ b/block/monitor/block-hmp-cmds.c
> @@ -33,6 +33,36 @@
>  #include "monitor/hmp.h"
>  #include "qemu-io.h"
>  
> +static void hmp_drive_add_node(Monitor *mon, const char *optstr)
> +{
> +QemuOpts *opts;
> +QDict *qdict;
> +Error *local_err = NULL;
> +
> +opts = qemu_opts_parse_noisily(_drive_opts, optstr, false);
> +if (!opts) {
> +return;
> +}
> +
> +qdict = qemu_opts_to_qdict(opts, NULL);
> +
> +if (!qdict_get_try_str(qdict, "node-name")) {
> +qobject_unref(qdict);
> +error_report("'node-name' needs to be specified");
> +goto out;
> +}
> +
> +BlockDriverState *bs = bds_tree_init(qdict, _err);
> +if (!bs) {
> +error_report_err(local_err);
> +goto out;
> +}
> +
> +bdrv_set_monitor_owned(bs);
> +out:
> +qemu_opts_del(opts);
> +}
> +
>  void hmp_drive_add(Monitor *mon, const QDict *qdict)
>  {
>  Error *err = NULL;
> diff --git a/blockdev.c b/blockdev.c
> index df43e0aaef..63805f34b5 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -64,7 +64,7 @@
>  #include "qemu/main-loop.h"
>  #include "qemu/throttle-options.h"
>  
> -static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
> +QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
>  QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
>  
>  static int do_open_tray(const char *blk_name, const char *qdev_id,
> @@ -75,6 +75,11 @@ static void blockdev_insert_medium(bool has_device, const 
> char *device,
> bool has_id, const char *id,
> const char *node_name, Error **errp);
>  
> +void bdrv_set_monitor_owned(BlockDriverState *bs)
> +{
> +QTAILQ_INSERT_TAIL(_bdrv_states, bs, monitor_list);
> +}
> +
>  static const char *const if_name[IF_COUNT] = {
>  [IF_NONE] = "none",
>  [IF_IDE] = "ide",
> @@ -652,7 +657,7 @@ err_no_opts:
>  }
>  
>  /* Takes the ownership of bs_opts */
> -static BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
> +BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
>  {
>  int bdrv_flags = 0;
>  
> @@ -4201,37 +4206,6 @@ out:
>  aio_context_release(aio_context);
>  }
>  
> -void hmp_drive_add_node(Monitor *mon, const char *optstr)
> -{
> -QemuOpts *opts;
> -QDict *qdict;
> -Error *local_err = NULL;
> -
> -opts = qemu_opts_parse_noisily(_drive_opts, optstr, false);
> -if (!opts) {
> -return;
> -}
> -
> -qdict = qemu_opts_to_qdict(opts, NULL);
> -
> -if (!qdict_get_try_str(qdict, "node-name")) {
> -qobject_unref(qdict);
> -error_report("'node-name' needs to be specified");
> -goto out;
> -}
> -
> -BlockDriverState *bs = bds_tree_init(qdict, _err);
> -if (!bs) {
> -error_report_err(local_err);
> -goto out;
> -}
> -
> -QTAILQ_INSERT_TAIL(_bdrv_states, bs, monitor_list);
> -
> -out:
> -qemu_opts_del(opts);
> -}
> -
>  void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
>  {
>  BlockDriverState *bs;
> @@ -4261,7 +4235,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error 
> **errp)
>  goto fail;
>  }
>  
> -QTAILQ_INSERT_TAIL(_bdrv_states, bs, monitor_list);
> +bdrv_set_monitor_owned(bs);
>  
>  fail:
>  visit_free(v);
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index dd033d0b37..10df257a61 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -1217,8 +1217,6 @@ BlockJob *backup_job_create(const char *job_id, 
> BlockDriverState *bs,
>  BlockCompletionFunc *cb, void *opaque,
>  JobTxn *txn, Error **errp);
>  
> -void hmp_drive_add_node(Monitor *mon, const char *optstr);
> -
>  BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
>const char *child_name,
>const BdrvChildRole *child_role,
> @@ -1320,4 +1318,7 @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, 
> uint64_t src_offset,
>  
>  int refresh_total_sectors(BlockDriverState *bs, int64_t hint);
>  
> +void bdrv_set_monitor_owned(BlockDriverState *bs);
> +BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp);
> +
>  #endif /* BLOCK_INT_H */
> -- 
> 2.17.2
> 
--
Dr. David Alan Gilbert / 

Re: [PATCH v3 12/13] add 'error' prefix to vreport

2020-01-28 Thread Maxim Levitsky
On Mon, 2020-01-27 at 12:36 +0200, Maxim Levitsky wrote:
> This changes most of qemu's error messages,
> but it feels like the right thing to do.
> 
> This is WIP patch, since I updated most of iotests but not all of them,
> and will be updated if this patch is accepeted in the review.
> Also few error message already have 'error' prefix, which should be removed.
> 
> Signed-off-by: Maxim Levitsky 
> Suggested-by: Markus Armbruster 

Since Peter Krempa pointed out that libvirt doesn't need the error prefixes any 
more
(this wasn't the case when I developed this sadly) I guess I'll drop that patch,
although to me it looks just better to have errors cleanly prefixed to be 
honest.

Best regards,
Maxim Levitsky




Re: [PATCH v3 07/18] machine: Add a new function init_apicid_fn in MachineClass

2020-01-28 Thread Babu Moger



On 1/28/20 10:29 AM, Igor Mammedov wrote:
> On Tue, 03 Dec 2019 18:37:42 -0600
> Babu Moger  wrote:
> 
>> Add a new function init_apicid_fn in MachineClass to initialize the mode
>> specific handlers to decode the apic ids.
>>
>> Signed-off-by: Babu Moger 
>> ---
>>  include/hw/boards.h |1 +
>>  vl.c|3 +++
>>  2 files changed, 4 insertions(+)
>>
>> diff --git a/include/hw/boards.h b/include/hw/boards.h
>> index d4fab218e6..ce5aa365cb 100644
>> --- a/include/hw/boards.h
>> +++ b/include/hw/boards.h
>> @@ -238,6 +238,7 @@ struct MachineClass {
>>   unsigned 
>> cpu_index);
>>  const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
>>  int64_t (*get_default_cpu_node_id)(const MachineState *ms, int idx);
>> +void (*init_apicid_fn)(MachineState *ms);
> it's x86 specific, so why it wasn put into PCMachineClass?

Yes. It is x86 specific for now. I tried to make it generic function so
other OSes can use it if required(like we have done in
possible_cpu_arch_ids). It initializes functions required to build the
apicid for each CPUs. We need these functions much early in the
initialization. It should be initialized before parse_numa_opts or
machine_run_board_init(in v1.c) which are called from generic context. We
cannot use PCMachineClass at this time.

> 
> 
>>  };
>>  
>>  /**
>> diff --git a/vl.c b/vl.c
>> index a42c24a77f..b6af604e11 100644
>> --- a/vl.c
>> +++ b/vl.c
>> @@ -4318,6 +4318,9 @@ int main(int argc, char **argv, char **envp)
>>  current_machine->cpu_type = machine_class->default_cpu_type;
>>  if (cpu_option) {
>>  current_machine->cpu_type = parse_cpu_option(cpu_option);
>> +if (machine_class->init_apicid_fn) {
>> +machine_class->init_apicid_fn(current_machine);
>> +}
>>  }
>>  parse_numa_opts(current_machine);
>>  
>>
>>
> 



Re: [PATCH v3 08/13] monitor/hmp: move hmp_nbd_server* to block-hmp-cmds.c

2020-01-28 Thread Dr. David Alan Gilbert
* Maxim Levitsky (mlevi...@redhat.com) wrote:
> Signed-off-by: Maxim Levitsky 

Yes, I think that's OK; I can imagine nbd might want to move on it's own
somewhere since it's not really core block code; copying in Eric.


Reviewed-by: Dr. David Alan Gilbert 

> ---
>  block/monitor/block-hmp-cmds.c | 88 ++
>  include/block/block-hmp-commands.h |  5 ++
>  include/monitor/hmp.h  |  4 --
>  monitor/hmp-cmds.c | 87 -
>  4 files changed, 93 insertions(+), 91 deletions(-)
> 
> diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
> index 9aa94ea6e0..df0178d0f9 100644
> --- a/block/monitor/block-hmp-cmds.c
> +++ b/block/monitor/block-hmp-cmds.c
> @@ -22,8 +22,10 @@
>  #include "qapi/qmp/qerror.h"
>  #include "qemu/config-file.h"
>  #include "qemu/option.h"
> +#include "qemu/sockets.h"
>  #include "sysemu/sysemu.h"
>  #include "monitor/monitor.h"
> +#include "block/nbd.h"
>  #include "block/block_int.h"
>  #include "block/block-hmp-commands.h"
>  #include "monitor/hmp.h"
> @@ -327,3 +329,89 @@ void hmp_snapshot_delete_blkdev_internal(Monitor *mon, 
> const QDict *qdict)
> true, name, );
>  hmp_handle_error(mon, err);
>  }
> +
> +void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
> +{
> +const char *uri = qdict_get_str(qdict, "uri");
> +bool writable = qdict_get_try_bool(qdict, "writable", false);
> +bool all = qdict_get_try_bool(qdict, "all", false);
> +Error *local_err = NULL;
> +BlockInfoList *block_list, *info;
> +SocketAddress *addr;
> +
> +if (writable && !all) {
> +error_setg(_err, "-w only valid together with -a");
> +goto exit;
> +}
> +
> +/* First check if the address is valid and start the server.  */
> +addr = socket_parse(uri, _err);
> +if (local_err != NULL) {
> +goto exit;
> +}
> +
> +nbd_server_start(addr, NULL, NULL, _err);
> +qapi_free_SocketAddress(addr);
> +if (local_err != NULL) {
> +goto exit;
> +}
> +
> +if (!all) {
> +return;
> +}
> +
> +/* Then try adding all block devices.  If one fails, close all and
> + * exit.
> + */
> +block_list = qmp_query_block(NULL);
> +
> +for (info = block_list; info; info = info->next) {
> +if (!info->value->has_inserted) {
> +continue;
> +}
> +
> +qmp_nbd_server_add(info->value->device, false, NULL,
> +   true, writable, false, NULL, _err);
> +
> +if (local_err != NULL) {
> +qmp_nbd_server_stop(NULL);
> +break;
> +}
> +}
> +
> +qapi_free_BlockInfoList(block_list);
> +
> +exit:
> +hmp_handle_error(mon, local_err);
> +}
> +
> +void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
> +{
> +const char *device = qdict_get_str(qdict, "device");
> +const char *name = qdict_get_try_str(qdict, "name");
> +bool writable = qdict_get_try_bool(qdict, "writable", false);
> +Error *local_err = NULL;
> +
> +qmp_nbd_server_add(device, !!name, name, true, writable,
> +   false, NULL, _err);
> +hmp_handle_error(mon, local_err);
> +}
> +
> +void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict)
> +{
> +const char *name = qdict_get_str(qdict, "name");
> +bool force = qdict_get_try_bool(qdict, "force", false);
> +Error *err = NULL;
> +
> +/* Rely on NBD_SERVER_REMOVE_MODE_SAFE being the default */
> +qmp_nbd_server_remove(name, force, NBD_SERVER_REMOVE_MODE_HARD, );
> +hmp_handle_error(mon, err);
> +}
> +
> +void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
> +{
> +Error *err = NULL;
> +
> +qmp_nbd_server_stop();
> +hmp_handle_error(mon, err);
> +}
> diff --git a/include/block/block-hmp-commands.h 
> b/include/block/block-hmp-commands.h
> index 3fc2daf3a9..721b9a1978 100644
> --- a/include/block/block-hmp-commands.h
> +++ b/include/block/block-hmp-commands.h
> @@ -21,4 +21,9 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
>  void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict);
>  void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict);
>  
> +void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
> +void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
> +void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict);
> +void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
> +
>  #endif
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index 6d34e29bb6..736a969131 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -94,10 +94,6 @@ void hmp_getfd(Monitor *mon, const QDict *qdict);
>  void hmp_closefd(Monitor *mon, const QDict *qdict);
>  void hmp_sendkey(Monitor *mon, const QDict *qdict);
>  void hmp_screendump(Monitor *mon, const QDict *qdict);
> -void hmp_nbd_server_start(Monitor 

Re: [PATCH v3 07/13] monitor/hmp: move hmp_snapshot_* to block-hmp-cmds.c

2020-01-28 Thread Dr. David Alan Gilbert
* Maxim Levitsky (mlevi...@redhat.com) wrote:
> Signed-off-by: Maxim Levitsky 

Reviewed-by: Dr. David Alan Gilbert 

> ---
>  block/monitor/block-hmp-cmds.c | 47 ++
>  include/block/block-hmp-commands.h |  4 +++
>  include/monitor/hmp.h  |  3 --
>  monitor/hmp-cmds.c | 47 --
>  4 files changed, 51 insertions(+), 50 deletions(-)
> 
> diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
> index ed3c350143..9aa94ea6e0 100644
> --- a/block/monitor/block-hmp-cmds.c
> +++ b/block/monitor/block-hmp-cmds.c
> @@ -280,3 +280,50 @@ void hmp_block_job_complete(Monitor *mon, const QDict 
> *qdict)
>  
>  hmp_handle_error(mon, error);
>  }
> +
> +void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
> +{
> +const char *device = qdict_get_str(qdict, "device");
> +const char *filename = qdict_get_try_str(qdict, "snapshot-file");
> +const char *format = qdict_get_try_str(qdict, "format");
> +bool reuse = qdict_get_try_bool(qdict, "reuse", false);
> +enum NewImageMode mode;
> +Error *err = NULL;
> +
> +if (!filename) {
> +/* In the future, if 'snapshot-file' is not specified, the snapshot
> +   will be taken internally. Today it's actually required. */
> +error_setg(, QERR_MISSING_PARAMETER, "snapshot-file");
> +hmp_handle_error(mon, err);
> +return;
> +}
> +
> +mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
> +qmp_blockdev_snapshot_sync(true, device, false, NULL,
> +   filename, false, NULL,
> +   !!format, format,
> +   true, mode, );
> +hmp_handle_error(mon, err);
> +}
> +
> +void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
> +{
> +const char *device = qdict_get_str(qdict, "device");
> +const char *name = qdict_get_str(qdict, "name");
> +Error *err = NULL;
> +
> +qmp_blockdev_snapshot_internal_sync(device, name, );
> +hmp_handle_error(mon, err);
> +}
> +
> +void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
> +{
> +const char *device = qdict_get_str(qdict, "device");
> +const char *name = qdict_get_str(qdict, "name");
> +const char *id = qdict_get_try_str(qdict, "id");
> +Error *err = NULL;
> +
> +qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id,
> +   true, name, );
> +hmp_handle_error(mon, err);
> +}
> diff --git a/include/block/block-hmp-commands.h 
> b/include/block/block-hmp-commands.h
> index ea6578a5f6..3fc2daf3a9 100644
> --- a/include/block/block-hmp-commands.h
> +++ b/include/block/block-hmp-commands.h
> @@ -17,4 +17,8 @@ void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
>  void hmp_block_job_resume(Monitor *mon, const QDict *qdict);
>  void hmp_block_job_complete(Monitor *mon, const QDict *qdict);
>  
> +void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
> +void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict);
> +void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict);
> +
>  #endif
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index 592ce0ccfe..6d34e29bb6 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -61,9 +61,6 @@ void hmp_set_link(Monitor *mon, const QDict *qdict);
>  void hmp_block_passwd(Monitor *mon, const QDict *qdict);
>  void hmp_balloon(Monitor *mon, const QDict *qdict);
>  void hmp_block_resize(Monitor *mon, const QDict *qdict);
> -void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
> -void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict);
> -void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict);
>  void hmp_loadvm(Monitor *mon, const QDict *qdict);
>  void hmp_savevm(Monitor *mon, const QDict *qdict);
>  void hmp_delvm(Monitor *mon, const QDict *qdict);
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index 996ce96430..46b46b6dd7 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -1337,53 +1337,6 @@ void hmp_block_resize(Monitor *mon, const QDict *qdict)
>  hmp_handle_error(mon, err);
>  }
>  
> -void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
> -{
> -const char *device = qdict_get_str(qdict, "device");
> -const char *filename = qdict_get_try_str(qdict, "snapshot-file");
> -const char *format = qdict_get_try_str(qdict, "format");
> -bool reuse = qdict_get_try_bool(qdict, "reuse", false);
> -enum NewImageMode mode;
> -Error *err = NULL;
> -
> -if (!filename) {
> -/* In the future, if 'snapshot-file' is not specified, the snapshot
> -   will be taken internally. Today it's actually required. */
> -error_setg(, QERR_MISSING_PARAMETER, "snapshot-file");
> -hmp_handle_error(mon, err);
> -return;
> -}
> -
> -   

Re: [PATCH v3 09/13] monitor/hmp: move remaining hmp_block* functions to block-hmp-cmds.c

2020-01-28 Thread Dr. David Alan Gilbert
* Maxim Levitsky (mlevi...@redhat.com) wrote:
> Signed-off-by: Maxim Levitsky 

Reviewed-by: Dr. David Alan Gilbert 

> ---
>  block/monitor/block-hmp-cmds.c | 138 +
>  include/block/block-hmp-commands.h |   9 ++
>  include/monitor/hmp.h  |   6 --
>  monitor/hmp-cmds.c | 137 
>  4 files changed, 147 insertions(+), 143 deletions(-)
> 
> diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
> index df0178d0f9..60d63bfe18 100644
> --- a/block/monitor/block-hmp-cmds.c
> +++ b/block/monitor/block-hmp-cmds.c
> @@ -29,6 +29,7 @@
>  #include "block/block_int.h"
>  #include "block/block-hmp-commands.h"
>  #include "monitor/hmp.h"
> +#include "qemu-io.h"
>  
>  void hmp_drive_add(Monitor *mon, const QDict *qdict)
>  {
> @@ -415,3 +416,140 @@ void hmp_nbd_server_stop(Monitor *mon, const QDict 
> *qdict)
>  qmp_nbd_server_stop();
>  hmp_handle_error(mon, err);
>  }
> +
> +void hmp_block_resize(Monitor *mon, const QDict *qdict)
> +{
> +const char *device = qdict_get_str(qdict, "device");
> +int64_t size = qdict_get_int(qdict, "size");
> +Error *err = NULL;
> +
> +qmp_block_resize(true, device, false, NULL, size, );
> +hmp_handle_error(mon, err);
> +}
> +
> +void hmp_block_stream(Monitor *mon, const QDict *qdict)
> +{
> +Error *error = NULL;
> +const char *device = qdict_get_str(qdict, "device");
> +const char *base = qdict_get_try_str(qdict, "base");
> +int64_t speed = qdict_get_try_int(qdict, "speed", 0);
> +
> +qmp_block_stream(true, device, device, base != NULL, base, false, NULL,
> + false, NULL, qdict_haskey(qdict, "speed"), speed, true,
> + BLOCKDEV_ON_ERROR_REPORT, false, false, false, false,
> + );
> +
> +hmp_handle_error(mon, error);
> +}
> +
> +void hmp_block_passwd(Monitor *mon, const QDict *qdict)
> +{
> +const char *device = qdict_get_str(qdict, "device");
> +const char *password = qdict_get_str(qdict, "password");
> +Error *err = NULL;
> +
> +qmp_block_passwd(true, device, false, NULL, password, );
> +hmp_handle_error(mon, err);
> +}
> +
> +void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
> +{
> +Error *err = NULL;
> +char *device = (char *) qdict_get_str(qdict, "device");
> +BlockIOThrottle throttle = {
> +.bps = qdict_get_int(qdict, "bps"),
> +.bps_rd = qdict_get_int(qdict, "bps_rd"),
> +.bps_wr = qdict_get_int(qdict, "bps_wr"),
> +.iops = qdict_get_int(qdict, "iops"),
> +.iops_rd = qdict_get_int(qdict, "iops_rd"),
> +.iops_wr = qdict_get_int(qdict, "iops_wr"),
> +};
> +
> +/* qmp_block_set_io_throttle has separate parameters for the
> + * (deprecated) block device name and the qdev ID but the HMP
> + * version has only one, so we must decide which one to pass. */
> +if (blk_by_name(device)) {
> +throttle.has_device = true;
> +throttle.device = device;
> +} else {
> +throttle.has_id = true;
> +throttle.id = device;
> +}
> +
> +qmp_block_set_io_throttle(, );
> +hmp_handle_error(mon, err);
> +}
> +
> +void hmp_eject(Monitor *mon, const QDict *qdict)
> +{
> +bool force = qdict_get_try_bool(qdict, "force", false);
> +const char *device = qdict_get_str(qdict, "device");
> +Error *err = NULL;
> +
> +qmp_eject(true, device, false, NULL, true, force, );
> +hmp_handle_error(mon, err);
> +}
> +
> +void hmp_qemu_io(Monitor *mon, const QDict *qdict)
> +{
> +BlockBackend *blk;
> +BlockBackend *local_blk = NULL;
> +bool qdev = qdict_get_try_bool(qdict, "qdev", false);
> +const char* device = qdict_get_str(qdict, "device");
> +const char* command = qdict_get_str(qdict, "command");
> +Error *err = NULL;
> +int ret;
> +
> +if (qdev) {
> +blk = blk_by_qdev_id(device, );
> +if (!blk) {
> +goto fail;
> +}
> +} else {
> +blk = blk_by_name(device);
> +if (!blk) {
> +BlockDriverState *bs = bdrv_lookup_bs(NULL, device, );
> +if (bs) {
> +blk = local_blk = blk_new(bdrv_get_aio_context(bs),
> +  0, BLK_PERM_ALL);
> +ret = blk_insert_bs(blk, bs, );
> +if (ret < 0) {
> +goto fail;
> +}
> +} else {
> +goto fail;
> +}
> +}
> +}
> +
> +/*
> + * Notably absent: Proper permission management. This is sad, but it 
> seems
> + * almost impossible to achieve without changing the semantics and 
> thereby
> + * limiting the use cases of the qemu-io HMP command.
> + *
> + * In an ideal world we would unconditionally create a new BlockBackend 
> for
> + * qemuio_command(), but we have commands like 'reopen' and want them to
> + * 

  1   2   3   4   5   >