Re: [PATCH v2 01/21] qapi/parser: Don't try to handle file errors

2021-05-18 Thread Markus Armbruster
John Snow  writes:

> On 5/18/21 5:28 AM, Markus Armbruster wrote:
>> QAPIError not having .info don't actually exist before this patch.
>
> It's defined by QAPISourceError now, I just missed this spot in
> test-qapi. It isn't used in practice until now, however.

I had QAPIError mentally filed under abstract types / didn't bother to
formally make it one with decorators.  Just as well, because it's not
staying abstract: this patch creates instances.




Re: [PATCH v2 15/21] qapi/parser: add docstrings

2021-05-18 Thread Markus Armbruster
John Snow  writes:

> Signed-off-by: John Snow 
> ---
>  scripts/qapi/parser.py | 68 ++
>  1 file changed, 68 insertions(+)
>
> diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
> index e80e0a7d965..ed543a2b7a4 100644
> --- a/scripts/qapi/parser.py
> +++ b/scripts/qapi/parser.py
> @@ -47,7 +47,27 @@ def __init__(self, parser: 'QAPISchemaParser', msg: str):
>  
>  
>  class QAPISchemaParser:
> +"""
> +Performs syntactic parsing of a QAPI schema source file.

"Syntactic parsing" makes me wonder what non-syntactic parsing could be.

Also, PEP 257 wants imperative mood: "Perform X", not "Performs X".

What about a laconic "Parse QAPI schema source"?

>  
> +Parses a JSON-esque schema file, See qapi-code-gen.txt section

Imperative mood, please.  Period, not comma.

> +"Schema Syntax" for more information. Grammatical validation
> +is handled later by `expr.check_exprs()`.

We could mention the processing of directives.  Perhaps:

   Parse a JSON-esque schema file.  See qapi-code-gen.txt section
   "Schema Syntax" for the exact syntax.  Also process directives.
   Grammatical validation is handled later by `expr.check_exprs()`.

What do you think?

> +
> +:param fname: Source filename.
> +:param previously_included:
> +The absolute pathnames of previously included source files,

Either file name / filename (either spelling, but let's pick one), or
pathname, but not both, please.

Possible resolution:

   :param fname: Source file name.
   :param previously_included:
   The absolute names of previously included source files,

> +if being invoked from another parser.
> +:param incl_info:
> +   `QAPISourceInfo` belonging to the parent module.
> +   ``None`` implies this is the root module.
> +
> +:ivar exprs: Resulting parsed expressions.
> +:ivar docs: Resulting parsed documentation blocks.
> +
> +:raise OSError: For problems opening the root schema document.

Hardly matters, but here we go: its both for open() and .read().  We
could say "reading" instead of "opening".

> +:raise QAPIError: For syntactic or semantic parsing errors.

"Semantic parsing errors" sounds like "triangular squares" :)

I figure you wrote this because we're using both QAPIParseError and
QAPISemError.  The latter gets raised where we do more than just parse,
e.g. in directive processing.  It hardly matters, as we don't really
care for the difference between these error classes anywhere, and
pragmatically use whatever class is convenient.

Perhaps we should have a single class with multiple constructors
instead.  Even if yes, not now.

I recommend to gloss over (irrelevant) details and say "For parse
errors".  Yes, some of the errors aren't parse errors in the theory of
parsing sense, but I doubt readers care.  If *you* care, then maybe "For
errors in the schema source".  And then you might want to tweak the
OSError explanation to "For problems reading the root schema source
file".

> +"""
>  def __init__(self,
>   fname: str,
>   previously_included: Optional[Set[str]] = None,
> @@ -73,6 +93,11 @@ def __init__(self,
>  self._parse()
>  
>  def _parse(self) -> None:
> +"""
> +Parse the QAPI schema document.
> +
> +:return: None. Results are stored in ``.exprs`` and ``.docs``.
> +"""
>  cur_doc = None
>  
>  # May raise OSError; allow the caller to handle it.
> @@ -199,6 +224,49 @@ def check_list_str(name: str, value: object) -> 
> List[str]:
>  raise QAPISemError(info, "unknown pragma '%s'" % name)
>  
>  def accept(self, skip_comment: bool = True) -> None:
> +"""Read and store the next token.
> +
> +:param skip_comment:
> +When false, return COMMENT tokens ("#").
> +This is used when reading documentation blocks.
> +
> +:return:
> +None. Several instance attributes are updated instead:
> +
> +- ``.tok`` represents the token type. See below for values.
> +- ``.info`` describes the token's source location.
> +- ``.val`` is the token's value, if any. See below.
> +- ``.pos`` is the buffer index of the first character of
> +  the token.
> +
> +* Single-character tokens:
> +
> +These are "{", "}", ":", ",", "[", and "]". ``.tok`` holds
> +the single character and ``.val`` is None.
> +
> +* Multi-character tokens:
> +
> +  * COMMENT:
> +
> +This token is not normally returned by the lexer, but it can
> +be when ``skip_comment`` is False. ``.tok`` is "#", and
> +``.val`` is a string including all chars until end-of-line,
> +including the "#" itself.
> +
> +  * STRING:
> +
> +``.tok`` is "'", the single quote. ``.val`` contains the
> +string,

Re: [PATCH] migration/rdma: Fix cm_event used before being initialized

2021-05-18 Thread lizhij...@fujitsu.com


On 17/05/2021 18.00, Dr. David Alan Gilbert wrote:
> * lizhij...@fujitsu.com (lizhij...@fujitsu.com) wrote:
>>
>> On 14/05/2021 01.15, Dr. David Alan Gilbert wrote:
>>> * Li Zhijian (lizhij...@cn.fujitsu.com) wrote:
 A segmentation fault was triggered when i try to abort a postcopy + rdma
 migration.

 since rdma_ack_cm_event releases a uninitialized cm_event in thise case.

 like below:
 2496 ret = rdma_get_cm_event(rdma->channel, &cm_event);
 2497 if (ret) {
 2498 perror("rdma_get_cm_event after rdma_connect");
 2499 ERROR(errp, "connecting to destination!");
 2500 rdma_ack_cm_event(cm_event);  cause segmentation fault
 2501 goto err_rdma_source_connect;
 2502 }

 Signed-off-by: Li Zhijian 
>>> OK, that's an easy fix then; but I wonder if we should perhaps remove
>>> that rdma_ack_cm_event, if it's the get_cm_event that's failed?
>> I also wondered, i checked the man page get_cm_event(3) which has not 
>> documented
>>
>> and checked some rdma examples, some of them try to ack it[1],  but some 
>> not[2].
> I think they're actually consistent:
You are right.
I also checked rdma_get_cm_even() code, indeed, event will be changed only if 
rdma_get_cm_even() returns 0.
So i agree to remove rdma_ack_cm_event(event) in error path. i will update the 
patch soon.

Thanks
Zhijian




Re: Qemu block filter insertion/removal API

2021-05-18 Thread Vladimir Sementsov-Ogievskiy

18.05.2021 19:49, Max Reitz wrote:

On 17.05.21 14:44, Vladimir Sementsov-Ogievskiy wrote:

Hi all!

I'd like to be sure that we know where we are going to.

In blockdev-era where qemu user is aware about block nodes, all nodes have good 
names and controlled by user we can efficiently use block filters.

We already have some useful filters: copy-on-read, throttling, compress. In my 
parallel series I make backup-top filter public and useful without backup block 
jobs. But now filters could be inserted only together with opening their child. 
We can specify filters in qemu cmdline, or filter can take place in the block 
node chain created by blockdev-add.

Still, it would be good to insert/remove filters on demand.

Currently we are going to use x-blockdev-reopen for this. Still it can't be used to 
insert a filter above root node (as x-blockdev-reopen can change only block node options 
and their children). In my series "[PATCH 00/21] block: publish backup-top 
filter" I propose (as Kevin suggested) to modify qom-set, so that it can set drive 
option of running device. That's not difficult, but it means that we have different 
scenario of inserting/removing filters:

1. filter above root node X:

inserting:

   - do blockdev-add to add a filter (and specify X as its child)
   - do qom-set to set new filter as a rood node instead of X

removing

   - do qom-set to make X a root node again
   - do blockdev-del to drop a filter

2. filter between two block nodes P and X. (For example, X is a backing child 
of P)

inserting

   - do blockdev-add to add a filter (and specify X as its child)
   - do blockdev-reopen to set P.backing = filter

remvoing

   - do blockdev-reopen to set P.backing = X
   - do blockdev-del to drop a filter


And, probably we'll want transaction support for all these things.


Is it OK? Or do we need some kind of additional blockdev-replace command, that 
can replace one node by another, so in both cases we will do

inserting:

   - blockdev-add filter
   - blockdev-replace (make all parents of X to point to the new filter instead 
(except for the filter itself of course)

removing
   - blockdev-replace (make all parante of filter to be parents of X instead)
   - blockdev-del filter


It's simple to implement, and it seems for me that it is simpler to use. Any 
thoughts?


I’m afraid as a non-user of the blockdev interface, I can’t give a valuable 
opinion that would have some actual weight.

Doesn’t stop me from giving my personal and potentially invaluable opinion, 
though, obviously:

I think we expect all users to know the block graph, so they should be able to 
distinguish between cases 1 and 2.  However, I can imagine having to 
distinguish still is kind of a pain, especially if it were trivial for qemu to 
let the user not having to worry about it at all.


I discussed it yesterday with my colleagues from Virtuozzo, who will have to be 
users of that interface. And they of course prefer one command for all the 
cases :)



Also, if you want a filter unconditionally above some node, all the qom-set and 
blockdev-reopen operations for all of the original node’s parents would need to 
happen atomically.  As you say, those operations should perhaps be 
transactionable anyway, but...  Implementing blockdev-replace would provide 
this for much less cost now, I suppose?

I guess it can be argued that the downside is that having blockdev-replace 
means less pressure to make qom-set for drive and blockdev-reopen 
transactionable.

But well.  I don’t really have anything against a blockdev-replace, but again, 
I don’t know whether my opinion on this topic really has weight.


Thanks, actually my opinion is the same. I think, I'll prepare a patch a day 
later if no answers here, and we'll be able to continue discussion on top of 
new patch.

Hmm I have one additional (weak, but still) argument for blockdev-replace: it 
just seems good to avoid touching extra subsystem in block-graph operations. 
For block-jobs we don't need to touch qdev guest block devices, we are good now 
with node-names and blockdev-add. So, it's good to save this bit of interface 
beauty if we don't have strict reason to drop it.

--
Best regards,
Vladimir



Re: [PATCH v5 10/13] virtio-gpu: Add helpers to create and destroy dmabuf objects

2021-05-18 Thread Gerd Hoffmann
> +int virtio_gpu_update_dmabuf(VirtIOGPU *g,
> + uint32_t scanout_id,
> + struct virtio_gpu_simple_resource *res,
> + struct virtio_gpu_framebuffer *fb)
> +{
> +struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id];
> +VGPUDMABuf *new_primary, *old_primary;
> +
> +new_primary = virtio_gpu_create_dmabuf(g, scanout_id, res, fb);
> +if (!new_primary) {
> +return -EINVAL;
> +}
> +
> +if (g->dmabuf.primary) {
> +old_primary = g->dmabuf.primary;
> +}
> +
> +g->dmabuf.primary = new_primary;
> +qemu_console_resize(scanout->con,
> + new_primary->buf.width,
> +new_primary->buf.height);
> +dpy_gl_scanout_dmabuf(scanout->con, &new_primary->buf);
> +
> +if (old_primary) {
> +virtio_gpu_free_dmabuf(g, old_primary);
> +}
> +
> +return 0;
> +}

../../hw/display/virtio-gpu-udmabuf.c: In function ‘virtio_gpu_update_dmabuf’:
/home/kraxel/projects/qemu/include/qemu/queue.h:456:62: error: ‘old_primary’ 
may be used uninitialized in this function [-Werror=maybe-uninitialized]

take care,
  Gerd




Re: [PATCH v5 03/13] virtio-gpu: Add udmabuf helpers

2021-05-18 Thread Gerd Hoffmann
> +#ifdef CONFIG_LINUX

> +void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)

> +#else

> +void *virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
> +{
> +/* nothing (stub) */
> +return NULL
> +}

Fails to build for !linux ...

You can place the stubs in a file in the stubs/ directory instead.
They'll be used via weak symbol references instead of #ifdefs then.

Advantage: the stubs are compiled unconditionally so errors like this
don't go unnoticed that easily.

take care,
  Gerd




Re: RFC: Qemu backup interface plans

2021-05-18 Thread Vladimir Sementsov-Ogievskiy

18.05.2021 19:39, Max Reitz wrote:

Hi,

Your proposal sounds good to me in general.  Some small independent building 
blocks that seems to make sense to me.


Thanks! I hope it's not too difficult to read and understand my English.




On 17.05.21 14:07, Vladimir Sementsov-Ogievskiy wrote:

[...]


What we lack in this scheme:

1. handling dirty bitmap in backup-top filter: backup-top does copy-before-write 
operation on any guest write, when actually we are interested only in "dirty" 
regions for incremental backup

Probable solution would allowing specifying bitmap for sync=none mode of 
backup, but I think what I propose below is better.

2. [actually it's a tricky part of 1]: possibility to not do copy-before-write 
operations for regions that was already copied to final backup. With normal 
Qemu backup job, this is achieved by the fact that block-copy state with its 
internal bitmap is shared between backup job and copy-before-write filter.

3. Not a real problem but fact: backup block-job does nothing in the scheme, 
the whole job is done by filter. So, it would be interesting to have a 
possibility to simply insert/remove the filter, and avoid block-job creation 
and managing at all for external backup. (and I'd like to send another RFC on 
how to insert/remove filters, let's not discuss it here).


Next. Think about internal backup. It has one drawback too:
4. If target is remote with slow connection, copy-before-write operations will 
slow down guest writes appreciably.

It may be solved with help of image fleecing: we create temporary qcow2 image, 
setup fleecing scheme, and instead of exporting temp image through NBD we start 
a second backup with source = temporary image and target would be real backup 
target (NBD for example).


How would a second backup work here?  Wouldn’t one want a mirror job to copy 
the data off to the real target?

(Because I see backup as something intrinsically synchronous, whereas mirror by 
default is rather lazy.)

[Note from future me where I read more below: I see you acknowledge that you’ll 
need to modify backup to do what you need here, i.e. not do any CBW operations. 
 So it’s effectively the same as a mirror that ignores new dirty areas.  Which 
could work without changing mirror if block-copy were to set 
BDRV_REQ_WRITE_UNCHANGED for the fleecing case, and bdrv_co_write_req_finish() 
would skip bdrv_set_dirty() for such writes.]


I just feel myself closer with backup block-job than with mirror :) Finally, 
yes, there is no real difference in interface. But in realization, I prefer to 
continue developing block-copy. I hope, finally all jobs and img-convert would 
work through block-copy.

(and I'll need BDRV_REQ_WRITE_UNCHANGED anyway for fleecing, so user can use 
mirror or backup)



I mean, still has the problem that the mirror job can’t tell the CBW filter 
which areas are already copied off and so don’t need to be preserved anymore, 
but...


Still, with such solution there are same [1,2] problems, 3 becomes worse:


Not sure how 3 can become worse when you said above it isn’t a real problem (to 
which I agree).


It's my perfectionism :) Yes, it's still isn't a problem, but number of extra 
user-visible objects in architecture increases, which is not good I think.




5. We'll have two jobs and two automatically inserted filters, when actually 
one filter and one job are enough (as first job is needed only to insert a 
filter, second job doesn't need a filter at all).

Note also, that this (starting two backup jobs to make push backup with 
fleecing) doesn't work now, op-blockers will be against. It's simple to fix 
(and in Virtuozzo we live with downstream-only patch, which allows push backup 
with fleecing, based on starting two backup jobs).. But I never send a patch, 
as I have better plan, which will solve all listed problems.


So, what I propose:

1. We make backup-top filter public, so that it could be inserted/removed where 
user wants through QMP (how to properly insert/remove filter I'll post another 
RFC, as backup-top is not the only filter that can be usefully inserted 
somewhere). For this first step I've sent a series today:

   subject: [PATCH 00/21] block: publish backup-top filter
   id: <20210517064428.16223-1-vsement...@virtuozzo.com>
   patchew: 
https://patchew.org/QEMU/20210517064428.16223-1-vsement...@virtuozzo.com/

(note, that one of things in this series is rename 
s/backup-top/copy-before-write/, still, I call it backup-top in this letter)

This solves [3]. [4, 5] are solved partly: we still have one extra filter, 
created by backup block jobs, and also I didn't test does this work, probably 
some op-blockers or permissions should be tuned. So, let it be step 2:

2. Test, that we can start backup job with source = (target of backup-top filter), so 
that we have "push backup with fleecing". Make an option for backup to start 
without a filter, when we don't need copy-before-write operations, to not create extra 
superfl

Re: [RFC PATCH 14/25] qemu/bswap: Introduce load/store for aligned pointer

2021-05-18 Thread Philippe Mathieu-Daudé
On 5/18/21 10:15 PM, Peter Maydell wrote:
> On Tue, 18 May 2021 at 19:38, Philippe Mathieu-Daudé  
> wrote:
>>
>> When the pointer alignment is known to be safe, we can
>> directly swap the data in place, without having to rely
>> on the compiler builtin code.
>>
>> Load/store methods expecting aligned pointer use the 'a'
>> infix. For example to read a 16-bit unsigned value stored
>> in little endianess at an unaligned pointer:
>>
>>   val = lduw_le_p(&unaligned_ptr);
>>
>> then to store it in big endianess at an aligned pointer:
>>
>>   stw_be_ap(&aligned_ptr, val);
> 
> It sounded from the bug report as if the desired effect
> was "this access is atomic". Nothing in the documentation here
> makes that guarantee of the implementation -- it merely imposes
> an extra requirement on the caller that the pointer alignment
> is "safe" (which term it does not define...) and a valid
> implementation would be to implement the "aligned" versions
> identically to the "unaligned" versions...
> 
> Q: should the functions at the bottom of this stack of APIs
> be using something from the atomic.h header? If not, why not?
> Do we need any of the other atomic primitives ?

I'll defer this question to Stefan/Paolo...




Re: [PATCH v6 0/9] ui: add vdagent implementation and clipboard support.

2021-05-18 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20210519053940.1888907-1-kra...@redhat.com/



Hi,

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

Type: series
Message-id: 20210519053940.1888907-1-kra...@redhat.com
Subject: [PATCH v6 0/9] ui: add vdagent implementation and clipboard support.

=== 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/20210518131542.2941207-1-pbonz...@redhat.com -> 
patchew/20210518131542.2941207-1-pbonz...@redhat.com
 * [new tag] patchew/20210519053940.1888907-1-kra...@redhat.com -> 
patchew/20210519053940.1888907-1-kra...@redhat.com
Switched to a new branch 'test'
f38e1b9 ui/gtk: add clipboard support
b5112a9 ui/gtk: move struct GtkDisplayState to ui/gtk.h
8feb571 ui/vnc: clipboard support
97c5587 ui/vdagent: add clipboard support
76b41e6 ui/vdagent: add mouse support
64a57ad ui/vdagent: core infrastructure
5b03384 ui: add clipboard documentation
a482369 ui: add clipboard infrastructure
fa3c141 build: add separate spice-protocol config option

=== OUTPUT BEGIN ===
1/9 Checking commit fa3c14163bf1 (build: add separate spice-protocol config 
option)
2/9 Checking commit a48236937e4a (ui: add clipboard infrastructure)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#19: 
new file mode 100644

total: 0 errors, 1 warnings, 161 lines checked

Patch 2/9 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/9 Checking commit 5b03384c273a (ui: add clipboard documentation)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#31: 
new file mode 100644

WARNING: line over 80 characters
#90: FILE: include/ui/clipboard.h:43:
+ * @QEMU_CLIPBOARD_SELECTION_PRIMARY: primary selection (select + middle mouse 
button).

total: 0 errors, 2 warnings, 194 lines checked

Patch 3/9 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
4/9 Checking commit 64a57ad8e2a2 (ui/vdagent: core infrastructure)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#102: 
new file mode 100644

ERROR: if this code is redundant consider removing it
#160: FILE: ui/vdagent.c:54:
+#if 0

WARNING: line over 80 characters
#162: FILE: ui/vdagent.c:56:
+[VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB] = 
"clipboard-no-release-on-regrab",

ERROR: if this code is redundant consider removing it
#183: FILE: ui/vdagent.c:77:
+#if 0

WARNING: line over 80 characters
#244: FILE: ui/vdagent.c:138:
+   
sizeof(VDAgentAnnounceCapabilities) +

total: 2 errors, 3 warnings, 412 lines checked

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

5/9 Checking commit 76b41e6999f0 (ui/vdagent: add mouse support)
6/9 Checking commit 97c5587b9065 (ui/vdagent: add clipboard support)
ERROR: if this code is redundant consider removing it
#121: FILE: ui/vdagent.c:120:
+#if 0

WARNING: line over 80 characters
#441: FILE: ui/vdagent.c:759:
+cfg->clipboard = qemu_opt_get_bool(opts, "clipboard", 
VDAGENT_CLIPBOARD_DEFAULT);

total: 1 errors, 1 warnings, 394 lines checked

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

7/9 Checking commit 8feb57182d5c (ui/vnc: clipboard support)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#34: 
new file mode 100644

WARNING: line over 80 characters
#281: FILE: ui/vnc-clipboard.c:243:
+void vnc_client_cut_text_ext(VncState *vs, int32_t len, uint32_t flags, 
uint8_t *data)

WARNING: line over 80 characters
#290: FILE: ui/vnc-clipboard.c:252:
+qemu_clipboard_info_new(&vs->cbpeer, 
QEMU_CLIPBOARD_SELECTION_CLIPBOARD);

WARNING: line over 80 characters
#334: FILE: ui/vnc-clipboard.c:296:
+qemu_clipboard_info_new(&vs->cbpeer, 
QEMU_CLIPBOARD_SELECTION_CLIPBOARD);

WARNING: line over 80 characters
#501: FILE: ui/vnc.h:643:
+void vnc_client_cut_text_ext(VncState *vs, int32_t len, uint32_t flags, 
uint8_t *data);

total: 0 errors, 5 warnings, 451 lines checked

Patch 7/9 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
8/9 Checking commit b5112a9b2973 (ui/gtk: move struct GtkDisplayState to 
ui/gtk.h)
9/9 Checking commit f38e1b93466f (ui/gtk: add clipboard support)
WARNING: added, moved or deleted file(s), does MAINTAINERS ne

[PATCH v6 8/9] ui/gtk: move struct GtkDisplayState to ui/gtk.h

2021-05-18 Thread Gerd Hoffmann
Want place gtk clipboard code in a separate C file, which in turn
requires GtkDisplayState being in a header file.  So move it.  No
functional change.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Marc-André Lureau 
---
 include/ui/gtk.h | 57 
 ui/gtk.c | 55 --
 2 files changed, 57 insertions(+), 55 deletions(-)

diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index 5ae0ad60a600..6e751794043f 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -18,12 +18,15 @@
 #include 
 #endif
 
+#include "ui/console.h"
 #include "ui/kbd-state.h"
 #if defined(CONFIG_OPENGL)
 #include "ui/egl-helpers.h"
 #include "ui/egl-context.h"
 #endif
 
+#define MAX_VCS 10
+
 typedef struct GtkDisplayState GtkDisplayState;
 
 typedef struct VirtualGfxConsole {
@@ -83,6 +86,60 @@ typedef struct VirtualConsole {
 };
 } VirtualConsole;
 
+struct GtkDisplayState {
+GtkWidget *window;
+
+GtkWidget *menu_bar;
+
+GtkAccelGroup *accel_group;
+
+GtkWidget *machine_menu_item;
+GtkWidget *machine_menu;
+GtkWidget *pause_item;
+GtkWidget *reset_item;
+GtkWidget *powerdown_item;
+GtkWidget *quit_item;
+
+GtkWidget *view_menu_item;
+GtkWidget *view_menu;
+GtkWidget *full_screen_item;
+GtkWidget *copy_item;
+GtkWidget *zoom_in_item;
+GtkWidget *zoom_out_item;
+GtkWidget *zoom_fixed_item;
+GtkWidget *zoom_fit_item;
+GtkWidget *grab_item;
+GtkWidget *grab_on_hover_item;
+
+int nb_vcs;
+VirtualConsole vc[MAX_VCS];
+
+GtkWidget *show_tabs_item;
+GtkWidget *untabify_item;
+GtkWidget *show_menubar_item;
+
+GtkWidget *vbox;
+GtkWidget *notebook;
+int button_mask;
+gboolean last_set;
+int last_x;
+int last_y;
+int grab_x_root;
+int grab_y_root;
+VirtualConsole *kbd_owner;
+VirtualConsole *ptr_owner;
+
+gboolean full_screen;
+
+GdkCursor *null_cursor;
+Notifier mouse_mode_notifier;
+gboolean free_scale;
+
+bool external_pause_update;
+
+DisplayOptions *opts;
+};
+
 extern bool gtk_use_gl_area;
 
 /* ui/gtk.c */
diff --git a/ui/gtk.c b/ui/gtk.c
index 1ea12535284a..7da288a25156 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -60,7 +60,6 @@
 #include "chardev/char.h"
 #include "qom/object.h"
 
-#define MAX_VCS 10
 #define VC_WINDOW_X_MIN  320
 #define VC_WINDOW_Y_MIN  240
 #define VC_TERM_X_MIN 80
@@ -119,60 +118,6 @@
 static const guint16 *keycode_map;
 static size_t keycode_maplen;
 
-struct GtkDisplayState {
-GtkWidget *window;
-
-GtkWidget *menu_bar;
-
-GtkAccelGroup *accel_group;
-
-GtkWidget *machine_menu_item;
-GtkWidget *machine_menu;
-GtkWidget *pause_item;
-GtkWidget *reset_item;
-GtkWidget *powerdown_item;
-GtkWidget *quit_item;
-
-GtkWidget *view_menu_item;
-GtkWidget *view_menu;
-GtkWidget *full_screen_item;
-GtkWidget *copy_item;
-GtkWidget *zoom_in_item;
-GtkWidget *zoom_out_item;
-GtkWidget *zoom_fixed_item;
-GtkWidget *zoom_fit_item;
-GtkWidget *grab_item;
-GtkWidget *grab_on_hover_item;
-
-int nb_vcs;
-VirtualConsole vc[MAX_VCS];
-
-GtkWidget *show_tabs_item;
-GtkWidget *untabify_item;
-GtkWidget *show_menubar_item;
-
-GtkWidget *vbox;
-GtkWidget *notebook;
-int button_mask;
-gboolean last_set;
-int last_x;
-int last_y;
-int grab_x_root;
-int grab_y_root;
-VirtualConsole *kbd_owner;
-VirtualConsole *ptr_owner;
-
-gboolean full_screen;
-
-GdkCursor *null_cursor;
-Notifier mouse_mode_notifier;
-gboolean free_scale;
-
-bool external_pause_update;
-
-DisplayOptions *opts;
-};
-
 struct VCChardev {
 Chardev parent;
 VirtualConsole *console;
-- 
2.31.1




[PATCH v6 7/9] ui/vnc: clipboard support

2021-05-18 Thread Gerd Hoffmann
This patch adds support for cut+paste to the qemu vnc server, which
allows the vnc client exchange clipbaord data with qemu and other peers
like the qemu vdagent implementation.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Marc-André Lureau 
---
 ui/vnc.h   |  24 
 ui/vnc-clipboard.c | 323 +
 ui/vnc.c   |  21 ++-
 ui/meson.build |   1 +
 4 files changed, 363 insertions(+), 6 deletions(-)
 create mode 100644 ui/vnc-clipboard.c

diff --git a/ui/vnc.h b/ui/vnc.h
index d4f3e1555809..a7149831f906 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -29,6 +29,7 @@
 
 #include "qemu/queue.h"
 #include "qemu/thread.h"
+#include "ui/clipboard.h"
 #include "ui/console.h"
 #include "audio/audio.h"
 #include "qemu/bitmap.h"
@@ -348,6 +349,10 @@ struct VncState
 
 Notifier mouse_mode_notifier;
 
+QemuClipboardPeer cbpeer;
+QemuClipboardInfo *cbinfo;
+uint32_t cbpending;
+
 QTAILQ_ENTRY(VncState) next;
 };
 
@@ -417,6 +422,7 @@ enum {
 #define VNC_ENCODING_XVP  0XFECB /* -309 */
 #define VNC_ENCODING_ALPHA_CURSOR 0XFEC6 /* -314 */
 #define VNC_ENCODING_WMVi 0x574D5669
+#define VNC_ENCODING_CLIPBOARD_EXT0xc0a1e5ce
 
 /*
  *
@@ -458,6 +464,7 @@ enum VncFeatures {
 VNC_FEATURE_ZYWRLE,
 VNC_FEATURE_LED_STATE,
 VNC_FEATURE_XVP,
+VNC_FEATURE_CLIPBOARD_EXT,
 };
 
 #define VNC_FEATURE_RESIZE_MASK  (1 << VNC_FEATURE_RESIZE)
@@ -474,6 +481,7 @@ enum VncFeatures {
 #define VNC_FEATURE_ZYWRLE_MASK  (1 << VNC_FEATURE_ZYWRLE)
 #define VNC_FEATURE_LED_STATE_MASK   (1 << VNC_FEATURE_LED_STATE)
 #define VNC_FEATURE_XVP_MASK (1 << VNC_FEATURE_XVP)
+#define VNC_FEATURE_CLIPBOARD_EXT_MASK   (1 <<  VNC_FEATURE_CLIPBOARD_EXT)
 
 
 /* Client -> Server message IDs */
@@ -535,6 +543,17 @@ enum VncFeatures {
 #define VNC_XVP_ACTION_REBOOT 3
 #define VNC_XVP_ACTION_RESET 4
 
+/* extended clipboard flags  */
+#define VNC_CLIPBOARD_TEXT (1 << 0)
+#define VNC_CLIPBOARD_RTF  (1 << 1)
+#define VNC_CLIPBOARD_HTML (1 << 2)
+#define VNC_CLIPBOARD_DIB  (1 << 3)
+#define VNC_CLIPBOARD_FILES(1 << 4)
+#define VNC_CLIPBOARD_CAPS (1 << 24)
+#define VNC_CLIPBOARD_REQUEST  (1 << 25)
+#define VNC_CLIPBOARD_PEEK (1 << 26)
+#define VNC_CLIPBOARD_NOTIFY   (1 << 27)
+#define VNC_CLIPBOARD_PROVIDE  (1 << 28)
 
 /*
  *
@@ -618,4 +637,9 @@ int vnc_zrle_send_framebuffer_update(VncState *vs, int x, 
int y, int w, int h);
 int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int 
h);
 void vnc_zrle_clear(VncState *vs);
 
+/* vnc-clipboard.c */
+void vnc_server_cut_text_caps(VncState *vs);
+void vnc_client_cut_text(VncState *vs, size_t len, uint8_t *text);
+void vnc_client_cut_text_ext(VncState *vs, int32_t len, uint32_t flags, 
uint8_t *data);
+
 #endif /* QEMU_VNC_H */
diff --git a/ui/vnc-clipboard.c b/ui/vnc-clipboard.c
new file mode 100644
index ..9f077965d056
--- /dev/null
+++ b/ui/vnc-clipboard.c
@@ -0,0 +1,323 @@
+/*
+ * QEMU VNC display driver -- clipboard support
+ *
+ * Copyright (C) 2021 Gerd Hoffmann 
+ *
+ * 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 "vnc.h"
+#include "vnc-jobs.h"
+
+static uint8_t *inflate_buffer(uint8_t *in, uint32_t in_len, uint32_t *size)
+{
+z_stream stream = {
+.next_in  = in,
+.avail_in = in_len,
+.zalloc   = Z_NULL,
+.zfree= Z_NULL,
+};
+uint32_t out_len = 8;
+uint8_t *out = g_malloc(out_len);
+int ret;
+
+stream.next_out = out + stream.total_out;
+stream.avail_out = out_len - stream.total_out;
+
+ret = inflateInit(&stream);
+if (ret != Z_OK) {
+goto err;
+}
+

[PATCH v6 4/9] ui/vdagent: core infrastructure

2021-05-18 Thread Gerd Hoffmann
The vdagent protocol allows the guest agent (spice-vdagent) and the
spice client exchange messages to implement features which require
guest cooperation, for example clipboard support.

This is a qemu implementation of the spice client side.  This allows
the spice guest agent talk to qemu directly when not using the spice
protocol.

usage: qemu \
  -chardev qemu-vdagent,id=vdagent \
  -device virtserialport,chardev=vdagent,name=com.redhat.spice.0

This patch adds just the protocol basics: initial handshake and
capability negotiation.  The following patches will add actual
functionality and also add fields to the initially empty
ChardevVDAgent qapi struct.

Signed-off-by: Gerd Hoffmann 
Acked-by: Markus Armbruster 
---
 ui/vdagent.c| 361 
 qapi/char.json  |  17 ++-
 ui/meson.build  |   1 +
 ui/trace-events |   8 ++
 4 files changed, 386 insertions(+), 1 deletion(-)
 create mode 100644 ui/vdagent.c

diff --git a/ui/vdagent.c b/ui/vdagent.c
new file mode 100644
index ..21e55a41eaba
--- /dev/null
+++ b/ui/vdagent.c
@@ -0,0 +1,361 @@
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "include/qemu-common.h"
+#include "chardev/char.h"
+#include "qemu/buffer.h"
+#include "qemu/units.h"
+#include "trace.h"
+
+#include "qapi/qapi-types-char.h"
+
+#include "spice/vd_agent.h"
+
+#define VDAGENT_BUFFER_LIMIT (1 * MiB)
+
+struct VDAgentChardev {
+Chardev parent;
+
+/* guest vdagent */
+uint32_t caps;
+VDIChunkHeader chunk;
+uint32_t chunksize;
+uint8_t *msgbuf;
+uint32_t msgsize;
+uint8_t *xbuf;
+uint32_t xoff, xsize;
+Buffer outbuf;
+};
+typedef struct VDAgentChardev VDAgentChardev;
+
+#define TYPE_CHARDEV_QEMU_VDAGENT "chardev-qemu-vdagent"
+
+DECLARE_INSTANCE_CHECKER(VDAgentChardev, QEMU_VDAGENT_CHARDEV,
+ TYPE_CHARDEV_QEMU_VDAGENT);
+
+/* -- */
+/* names, for debug logging   */
+
+static const char *cap_name[] = {
+[VD_AGENT_CAP_MOUSE_STATE]= "mouse-state",
+[VD_AGENT_CAP_MONITORS_CONFIG]= "monitors-config",
+[VD_AGENT_CAP_REPLY]  = "reply",
+[VD_AGENT_CAP_CLIPBOARD]  = "clipboard",
+[VD_AGENT_CAP_DISPLAY_CONFIG] = "display-config",
+[VD_AGENT_CAP_CLIPBOARD_BY_DEMAND]= "clipboard-by-demand",
+[VD_AGENT_CAP_CLIPBOARD_SELECTION]= "clipboard-selection",
+[VD_AGENT_CAP_SPARSE_MONITORS_CONFIG] = "sparse-monitors-config",
+[VD_AGENT_CAP_GUEST_LINEEND_LF]   = "guest-lineend-lf",
+[VD_AGENT_CAP_GUEST_LINEEND_CRLF] = "guest-lineend-crlf",
+[VD_AGENT_CAP_MAX_CLIPBOARD]  = "max-clipboard",
+[VD_AGENT_CAP_AUDIO_VOLUME_SYNC]  = "audio-volume-sync",
+[VD_AGENT_CAP_MONITORS_CONFIG_POSITION]   = "monitors-config-position",
+[VD_AGENT_CAP_FILE_XFER_DISABLED] = "file-xfer-disabled",
+[VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS]  = 
"file-xfer-detailed-errors",
+#if 0
+[VD_AGENT_CAP_GRAPHICS_DEVICE_INFO]   = "graphics-device-info",
+[VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB] = 
"clipboard-no-release-on-regrab",
+[VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL]  = "clipboard-grab-serial",
+#endif
+};
+
+static const char *msg_name[] = {
+[VD_AGENT_MOUSE_STATE]   = "mouse-state",
+[VD_AGENT_MONITORS_CONFIG]   = "monitors-config",
+[VD_AGENT_REPLY] = "reply",
+[VD_AGENT_CLIPBOARD] = "clipboard",
+[VD_AGENT_DISPLAY_CONFIG]= "display-config",
+[VD_AGENT_ANNOUNCE_CAPABILITIES] = "announce-capabilities",
+[VD_AGENT_CLIPBOARD_GRAB]= "clipboard-grab",
+[VD_AGENT_CLIPBOARD_REQUEST] = "clipboard-request",
+[VD_AGENT_CLIPBOARD_RELEASE] = "clipboard-release",
+[VD_AGENT_FILE_XFER_START]   = "file-xfer-start",
+[VD_AGENT_FILE_XFER_STATUS]  = "file-xfer-status",
+[VD_AGENT_FILE_XFER_DATA]= "file-xfer-data",
+[VD_AGENT_CLIENT_DISCONNECTED]   = "client-disconnected",
+[VD_AGENT_MAX_CLIPBOARD] = "max-clipboard",
+[VD_AGENT_AUDIO_VOLUME_SYNC] = "audio-volume-sync",
+#if 0
+[VD_AGENT_GRAPHICS_DEVICE_INFO]  = "graphics-device-info",
+#endif
+};
+
+#define GET_NAME(_m, _v) \
+(((_v) < ARRAY_SIZE(_m) && (_m[_v])) ? (_m[_v]) : "???")
+
+/* -- */
+/* send messages  */
+
+static void vdagent_send_buf(VDAgentChardev *vd)
+{
+uint32_t len;
+
+while (!buffer_empty(&vd->outbuf)) {
+len = qemu_chr_be_can_write(CHARDEV(vd));
+if (len == 0) {
+return;
+}
+if (len > vd->outbuf.offset) {
+len = vd->outbuf.offset;
+}
+   

[PATCH v6 9/9] ui/gtk: add clipboard support

2021-05-18 Thread Gerd Hoffmann
This patch adds clipboard support to the qemu gtk ui.

Signed-off-by: Gerd Hoffmann 
---
 include/ui/gtk.h   |  10 +++
 ui/gtk-clipboard.c | 192 +
 ui/gtk.c   |   1 +
 ui/meson.build |   2 +-
 4 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 ui/gtk-clipboard.c

diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index 6e751794043f..9516670ebc87 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -18,6 +18,7 @@
 #include 
 #endif
 
+#include "ui/clipboard.h"
 #include "ui/console.h"
 #include "ui/kbd-state.h"
 #if defined(CONFIG_OPENGL)
@@ -137,6 +138,12 @@ struct GtkDisplayState {
 
 bool external_pause_update;
 
+QemuClipboardPeer cbpeer;
+QemuClipboardInfo *cbinfo[QEMU_CLIPBOARD_SELECTION__COUNT];
+uint32_t cbpending[QEMU_CLIPBOARD_SELECTION__COUNT];
+GtkClipboard *gtkcb[QEMU_CLIPBOARD_SELECTION__COUNT];
+bool cbowner[QEMU_CLIPBOARD_SELECTION__COUNT];
+
 DisplayOptions *opts;
 };
 
@@ -207,4 +214,7 @@ void gtk_gl_area_init(void);
 int gd_gl_area_make_current(DisplayChangeListener *dcl,
 QEMUGLContext ctx);
 
+/* gtk-clipboard.c */
+void gd_clipboard_init(GtkDisplayState *gd);
+
 #endif /* UI_GTK_H */
diff --git a/ui/gtk-clipboard.c b/ui/gtk-clipboard.c
new file mode 100644
index ..bff28d203014
--- /dev/null
+++ b/ui/gtk-clipboard.c
@@ -0,0 +1,192 @@
+/*
+ * GTK UI -- clipboard support
+ *
+ * Copyright (C) 2021 Gerd Hoffmann 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/main-loop.h"
+
+#include "ui/gtk.h"
+
+static QemuClipboardSelection gd_find_selection(GtkDisplayState *gd,
+GtkClipboard *clipboard)
+{
+QemuClipboardSelection s;
+
+for (s = 0; s < QEMU_CLIPBOARD_SELECTION__COUNT; s++) {
+if (gd->gtkcb[s] == clipboard) {
+return s;
+}
+}
+return QEMU_CLIPBOARD_SELECTION_CLIPBOARD;
+}
+
+static void gd_clipboard_get_data(GtkClipboard *clipboard,
+  GtkSelectionData *selection_data,
+  guint selection_info,
+  gpointer  data)
+{
+GtkDisplayState *gd = data;
+QemuClipboardSelection s = gd_find_selection(gd, clipboard);
+QemuClipboardType type = QEMU_CLIPBOARD_TYPE_TEXT;
+QemuClipboardInfo *info = qemu_clipboard_info_ref(gd->cbinfo[s]);
+
+qemu_clipboard_request(info, type);
+while (info == gd->cbinfo[s] &&
+   info->types[type].available &&
+   info->types[type].data == NULL) {
+main_loop_wait(false);
+}
+
+if (info == gd->cbinfo[s] && gd->cbowner[s]) {
+gtk_selection_data_set_text(selection_data,
+info->types[type].data,
+info->types[type].size);
+} else {
+/* clipboard owner changed while waiting for the data */
+}
+
+qemu_clipboard_info_unref(info);
+}
+
+static void gd_clipboard_clear(GtkClipboard *clipboard,
+   gpointer data)
+{
+GtkDisplayState *gd = data;
+QemuClipboardSelection s = gd_find_selection(gd, clipboard);
+
+gd->cbowner[s] = false;
+}
+
+static void gd_clipboard_notify(Notifier *notifier, void *data)
+{
+GtkDisplayState *gd = container_of(notifier, GtkDisplayState, 
cbpeer.update);
+QemuClipboardInfo *info = data;
+QemuClipboardSelection s = info->selection;
+bool self_update = info->owner == &gd->cbpeer;
+
+if (info != gd->cbinfo[s]) {
+qemu_clipboard_info_unref(gd->cbinfo[s]);
+gd->cbinfo[s] = qemu_clipboard_info_ref(info);
+gd->cbpending[s] = 0;
+if (!self_update) {
+GtkTargetList *list;
+GtkTargetEntry *targets;
+gint n_targets;
+
+list = gtk_target_list_new(NULL, 0);
+if (info->types[QEMU_CLIPBOARD_TYPE_TEXT].available) {
+gtk_target_list_add_text_targets(list, 0);
+}
+targets = gtk_target_table_new_from_list(list, &n_targets);
+
+gtk_clipboard_clear(gd->gtkcb[s]);
+gd->cbowner[s] = true;
+gtk_clipboard_set_with_data(gd->gtkcb[s],
+tar

[PATCH v6 5/9] ui/vdagent: add mouse support

2021-05-18 Thread Gerd Hoffmann
This patch adds support for mouse messages to the vdagent
implementation.  This can be enabled/disabled using the new
'mouse' parameter for the vdagent chardev.  Default is on.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Marc-André Lureau 
---
 chardev/char.c |   3 +
 ui/vdagent.c   | 149 +
 qapi/char.json |   4 +-
 3 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/chardev/char.c b/chardev/char.c
index a4ebfcc5ac20..52c567e8ff00 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -931,6 +931,9 @@ QemuOptsList qemu_chardev_opts = {
 },{
 .name = "logappend",
 .type = QEMU_OPT_BOOL,
+},{
+.name = "mouse",
+.type = QEMU_OPT_BOOL,
 #ifdef CONFIG_LINUX
 },{
 .name = "tight",
diff --git a/ui/vdagent.c b/ui/vdagent.c
index 21e55a41eaba..cf81ab6beb68 100644
--- a/ui/vdagent.c
+++ b/ui/vdagent.c
@@ -3,18 +3,27 @@
 #include "include/qemu-common.h"
 #include "chardev/char.h"
 #include "qemu/buffer.h"
+#include "qemu/option.h"
 #include "qemu/units.h"
+#include "hw/qdev-core.h"
+#include "ui/console.h"
+#include "ui/input.h"
 #include "trace.h"
 
 #include "qapi/qapi-types-char.h"
+#include "qapi/qapi-types-ui.h"
 
 #include "spice/vd_agent.h"
 
 #define VDAGENT_BUFFER_LIMIT (1 * MiB)
+#define VDAGENT_MOUSE_DEFAULT true
 
 struct VDAgentChardev {
 Chardev parent;
 
+/* config */
+bool mouse;
+
 /* guest vdagent */
 uint32_t caps;
 VDIChunkHeader chunk;
@@ -24,6 +33,14 @@ struct VDAgentChardev {
 uint8_t *xbuf;
 uint32_t xoff, xsize;
 Buffer outbuf;
+
+/* mouse */
+DeviceState mouse_dev;
+uint32_t mouse_x;
+uint32_t mouse_y;
+uint32_t mouse_btn;
+uint32_t mouse_display;
+QemuInputHandlerState *mouse_hs;
 };
 typedef struct VDAgentChardev VDAgentChardev;
 
@@ -137,13 +154,113 @@ static void vdagent_send_caps(VDAgentChardev *vd)
 g_autofree VDAgentMessage *msg = g_malloc0(sizeof(VDAgentMessage) +

sizeof(VDAgentAnnounceCapabilities) +
sizeof(uint32_t));
+VDAgentAnnounceCapabilities *caps = (void *)msg->data;
 
 msg->type = VD_AGENT_ANNOUNCE_CAPABILITIES;
 msg->size = sizeof(VDAgentAnnounceCapabilities) + sizeof(uint32_t);
+if (vd->mouse) {
+caps->caps[0] |= (1 << VD_AGENT_CAP_MOUSE_STATE);
+}
 
 vdagent_send_msg(vd, msg);
 }
 
+/* -- */
+/* mouse events   */
+
+static bool have_mouse(VDAgentChardev *vd)
+{
+return vd->mouse &&
+(vd->caps & (1 << VD_AGENT_CAP_MOUSE_STATE));
+}
+
+static void vdagent_send_mouse(VDAgentChardev *vd)
+{
+g_autofree VDAgentMessage *msg = g_malloc0(sizeof(VDAgentMessage) +
+   sizeof(VDAgentMouseState));
+VDAgentMouseState *mouse = (void *)msg->data;
+
+msg->type = VD_AGENT_MOUSE_STATE;
+msg->size = sizeof(VDAgentMouseState);
+
+mouse->x  = vd->mouse_x;
+mouse->y  = vd->mouse_y;
+mouse->buttons= vd->mouse_btn;
+mouse->display_id = vd->mouse_display;
+
+vdagent_send_msg(vd, msg);
+}
+
+static void vdagent_pointer_event(DeviceState *dev, QemuConsole *src,
+  InputEvent *evt)
+{
+static const int bmap[INPUT_BUTTON__MAX] = {
+[INPUT_BUTTON_LEFT]= VD_AGENT_LBUTTON_MASK,
+[INPUT_BUTTON_RIGHT]   = VD_AGENT_RBUTTON_MASK,
+[INPUT_BUTTON_MIDDLE]  = VD_AGENT_MBUTTON_MASK,
+[INPUT_BUTTON_WHEEL_UP]= VD_AGENT_UBUTTON_MASK,
+[INPUT_BUTTON_WHEEL_DOWN]  = VD_AGENT_DBUTTON_MASK,
+#ifdef VD_AGENT_EBUTTON_MASK
+[INPUT_BUTTON_SIDE]= VD_AGENT_SBUTTON_MASK,
+[INPUT_BUTTON_EXTRA]   = VD_AGENT_EBUTTON_MASK,
+#endif
+};
+
+VDAgentChardev *vd = container_of(dev, struct VDAgentChardev, mouse_dev);
+InputMoveEvent *move;
+InputBtnEvent *btn;
+uint32_t xres, yres;
+
+switch (evt->type) {
+case INPUT_EVENT_KIND_ABS:
+move = evt->u.abs.data;
+xres = qemu_console_get_width(src, 1024);
+yres = qemu_console_get_height(src, 768);
+if (move->axis == INPUT_AXIS_X) {
+vd->mouse_x = qemu_input_scale_axis(move->value,
+INPUT_EVENT_ABS_MIN,
+INPUT_EVENT_ABS_MAX,
+0, xres);
+} else if (move->axis == INPUT_AXIS_Y) {
+vd->mouse_y = qemu_input_scale_axis(move->value,
+INPUT_EVENT_ABS_MIN,
+INPUT_EVENT_ABS_MAX,
+0, yres);
+}
+vd->mouse_display = qemu_console_get_index(src

[PATCH v6 6/9] ui/vdagent: add clipboard support

2021-05-18 Thread Gerd Hoffmann
This patch adds support for clipboard messages to the qemu vdagent
implementation, which allows the guest exchange clipboard data with
qemu.  Clipboard support can be enabled/disabled using the new
'clipboard' parameter for the vdagent chardev.  Default is off.

Signed-off-by: Gerd Hoffmann 
---
 chardev/char.c  |   3 +
 ui/vdagent.c| 293 
 qapi/char.json  |   4 +-
 ui/trace-events |   2 +
 4 files changed, 301 insertions(+), 1 deletion(-)

diff --git a/chardev/char.c b/chardev/char.c
index 52c567e8ff00..d959eec5229c 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -934,6 +934,9 @@ QemuOptsList qemu_chardev_opts = {
 },{
 .name = "mouse",
 .type = QEMU_OPT_BOOL,
+},{
+.name = "clipboard",
+.type = QEMU_OPT_BOOL,
 #ifdef CONFIG_LINUX
 },{
 .name = "tight",
diff --git a/ui/vdagent.c b/ui/vdagent.c
index cf81ab6beb68..a253a8fe63a6 100644
--- a/ui/vdagent.c
+++ b/ui/vdagent.c
@@ -6,6 +6,7 @@
 #include "qemu/option.h"
 #include "qemu/units.h"
 #include "hw/qdev-core.h"
+#include "ui/clipboard.h"
 #include "ui/console.h"
 #include "ui/input.h"
 #include "trace.h"
@@ -17,12 +18,14 @@
 
 #define VDAGENT_BUFFER_LIMIT (1 * MiB)
 #define VDAGENT_MOUSE_DEFAULT true
+#define VDAGENT_CLIPBOARD_DEFAULT false
 
 struct VDAgentChardev {
 Chardev parent;
 
 /* config */
 bool mouse;
+bool clipboard;
 
 /* guest vdagent */
 uint32_t caps;
@@ -41,6 +44,11 @@ struct VDAgentChardev {
 uint32_t mouse_btn;
 uint32_t mouse_display;
 QemuInputHandlerState *mouse_hs;
+
+/* clipboard */
+QemuClipboardPeer cbpeer;
+QemuClipboardInfo *cbinfo[QEMU_CLIPBOARD_SELECTION__COUNT];
+uint32_t cbpending[QEMU_CLIPBOARD_SELECTION__COUNT];
 };
 typedef struct VDAgentChardev VDAgentChardev;
 
@@ -96,6 +104,24 @@ static const char *msg_name[] = {
 #endif
 };
 
+static const char *sel_name[] = {
+[VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD] = "clipboard",
+[VD_AGENT_CLIPBOARD_SELECTION_PRIMARY]   = "primary",
+[VD_AGENT_CLIPBOARD_SELECTION_SECONDARY] = "secondary",
+};
+
+static const char *type_name[] = {
+[VD_AGENT_CLIPBOARD_NONE]   = "none",
+[VD_AGENT_CLIPBOARD_UTF8_TEXT]  = "text",
+[VD_AGENT_CLIPBOARD_IMAGE_PNG]  = "png",
+[VD_AGENT_CLIPBOARD_IMAGE_BMP]  = "bmp",
+[VD_AGENT_CLIPBOARD_IMAGE_TIFF] = "tiff",
+[VD_AGENT_CLIPBOARD_IMAGE_JPG]  = "jpg",
+#if 0
+[VD_AGENT_CLIPBOARD_FILE_LIST]  = "files",
+#endif
+};
+
 #define GET_NAME(_m, _v) \
 (((_v) < ARRAY_SIZE(_m) && (_m[_v])) ? (_m[_v]) : "???")
 
@@ -161,6 +187,10 @@ static void vdagent_send_caps(VDAgentChardev *vd)
 if (vd->mouse) {
 caps->caps[0] |= (1 << VD_AGENT_CAP_MOUSE_STATE);
 }
+if (vd->clipboard) {
+caps->caps[0] |= (1 << VD_AGENT_CAP_CLIPBOARD_BY_DEMAND);
+caps->caps[0] |= (1 << VD_AGENT_CAP_CLIPBOARD_SELECTION);
+}
 
 vdagent_send_msg(vd, msg);
 }
@@ -261,6 +291,244 @@ static QemuInputHandler vdagent_mouse_handler = {
 .sync  = vdagent_pointer_sync,
 };
 
+/* -- */
+/* clipboard  */
+
+static bool have_clipboard(VDAgentChardev *vd)
+{
+return vd->clipboard &&
+(vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_BY_DEMAND));
+}
+
+static bool have_selection(VDAgentChardev *vd)
+{
+return vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_SELECTION);
+}
+
+static uint32_t type_qemu_to_vdagent(enum QemuClipboardType type)
+{
+switch (type) {
+case QEMU_CLIPBOARD_TYPE_TEXT:
+return VD_AGENT_CLIPBOARD_UTF8_TEXT;
+default:
+return VD_AGENT_CLIPBOARD_NONE;
+}
+}
+
+static void vdagent_send_clipboard_grab(VDAgentChardev *vd,
+QemuClipboardInfo *info)
+{
+g_autofree VDAgentMessage *msg =
+g_malloc0(sizeof(VDAgentMessage) +
+  sizeof(uint32_t) * (QEMU_CLIPBOARD_TYPE__COUNT + 1));
+uint8_t *s = msg->data;
+uint32_t *data = (uint32_t *)msg->data;
+uint32_t q, type;
+
+if (have_selection(vd)) {
+*s = info->selection;
+data++;
+msg->size += sizeof(uint32_t);
+} else if (info->selection != QEMU_CLIPBOARD_SELECTION_CLIPBOARD) {
+return;
+}
+
+for (q = 0; q < QEMU_CLIPBOARD_TYPE__COUNT; q++) {
+type = type_qemu_to_vdagent(q);
+if (type != VD_AGENT_CLIPBOARD_NONE && info->types[q].available) {
+*data = type;
+data++;
+msg->size += sizeof(uint32_t);
+}
+}
+
+msg->type = VD_AGENT_CLIPBOARD_GRAB;
+vdagent_send_msg(vd, msg);
+}
+
+static void vdagent_send_clipboard_data(VDAgentChardev *vd,
+QemuClipboardInfo *info,
+QemuClipboardType type)
+{
+g_autofree VDAgentMessage *msg = g_malloc0(sizeof(VDAgentMessa

[PATCH v6 0/9] ui: add vdagent implementation and clipboard support.

2021-05-18 Thread Gerd Hoffmann
Fist sketch of cut+paste support for vnc.  On the guest side we are
going to reuse the spice vdagent, so things should work out-of-the-box
with guests in the wild.  So this patch set brings a qemu implemenation
of the vdagent protocol.

Beside that there is the clipboard infrastructure of course.  For now
only text support is there.  The design allows adding more data types,
so we can add image support and maybe more later on.  So far vdagent,
vnc server and gtk ui are hooked up.

Usage: qemu \
  -chardev vdagent,id=vdagent,clipboard=on \
  -device virtio-serial-pci \
  -device virtserialport,chardev=vdagent,name=com.redhat.spice.0

v6:
 - rebase to latest master
 - avoid busy-loop when writing to chardev.
v5:
 - use error_report.
 - error out on bigendian hosts.
 - rename chardev to 'qemu-vdagent'.
 - misc minor tweaks.
v4:
 - rebase to latest master.
 - make spice-protocol a separate build dependency.
 - update qapi version annotation.
 - add documentatin for qemu clipboard.
 - misc little tweaks.
v3:
 - support agents without VD_AGENT_CAP_CLIPBOARD_SELECTION.
 - properly parse chunked messages.
 - test with windows guests, minor fixes.
 - set display_id for agent mouse events.
v2:
 - add a bunch of sanity checks.
 - add proper chunking.
 - use autofree.

Gerd Hoffmann (9):
  build: add separate spice-protocol config option
  ui: add clipboard infrastructure
  ui: add clipboard documentation
  ui/vdagent: core infrastructure
  ui/vdagent: add mouse support
  ui/vdagent: add clipboard support
  ui/vnc: clipboard support
  ui/gtk: move struct GtkDisplayState to ui/gtk.h
  ui/gtk: add clipboard support

 configure  |  36 +-
 include/ui/clipboard.h | 193 ++
 include/ui/gtk.h   |  67 
 ui/vnc.h   |  24 ++
 chardev/char.c |   6 +
 ui/clipboard.c |  92 +
 ui/gtk-clipboard.c | 192 ++
 ui/gtk.c   |  56 +--
 ui/vdagent.c   | 803 +
 ui/vnc-clipboard.c | 323 +
 ui/vnc.c   |  21 +-
 docs/devel/index.rst   |   1 +
 docs/devel/ui.rst  |   8 +
 meson.build|   4 +
 qapi/char.json |  21 +-
 ui/meson.build |   5 +-
 ui/trace-events|  10 +
 17 files changed, 1795 insertions(+), 67 deletions(-)
 create mode 100644 include/ui/clipboard.h
 create mode 100644 ui/clipboard.c
 create mode 100644 ui/gtk-clipboard.c
 create mode 100644 ui/vdagent.c
 create mode 100644 ui/vnc-clipboard.c
 create mode 100644 docs/devel/ui.rst

-- 
2.31.1





[PATCH v6 3/9] ui: add clipboard documentation

2021-05-18 Thread Gerd Hoffmann
Document clipboard infrastructure in qemu.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Marc-André Lureau 
---
 include/ui/clipboard.h | 133 -
 docs/devel/index.rst   |   1 +
 docs/devel/ui.rst  |   8 +++
 3 files changed, 141 insertions(+), 1 deletion(-)
 create mode 100644 docs/devel/ui.rst

diff --git a/include/ui/clipboard.h b/include/ui/clipboard.h
index 876de7621911..e5bcb365ed62 100644
--- a/include/ui/clipboard.h
+++ b/include/ui/clipboard.h
@@ -3,17 +3,47 @@
 
 #include "qemu/notify.h"
 
+/**
+ * DOC: Introduction
+ *
+ * The header ``ui/clipboard.h`` declares the qemu clipboard interface.
+ *
+ * All qemu elements which want use the clipboard can register as
+ * clipboard peer.  Subsequently they can set the clipboard content
+ * and get notifications for clipboard updates.
+ *
+ * Typical users are user interfaces (gtk), remote access protocols
+ * (vnc) and devices talking to the guest (vdagent).
+ *
+ * Even though the design allows different data types only plain text
+ * is supported for now.
+ */
+
 typedef enum QemuClipboardType QemuClipboardType;
 typedef enum QemuClipboardSelection QemuClipboardSelection;
 typedef struct QemuClipboardPeer QemuClipboardPeer;
 typedef struct QemuClipboardInfo QemuClipboardInfo;
 
+/**
+ * enum QemuClipboardType
+ *
+ * @QEMU_CLIPBOARD_TYPE_TEXT: text/plain; charset=utf-8
+ * @QEMU_CLIPBOARD_TYPE__COUNT: type count.
+ */
 enum QemuClipboardType {
-QEMU_CLIPBOARD_TYPE_TEXT,  /* text/plain; charset=utf-8 */
+QEMU_CLIPBOARD_TYPE_TEXT,
 QEMU_CLIPBOARD_TYPE__COUNT,
 };
 
 /* same as VD_AGENT_CLIPBOARD_SELECTION_* */
+/**
+ * enum QemuClipboardSelection
+ *
+ * @QEMU_CLIPBOARD_SELECTION_CLIPBOARD: clipboard (explitcit cut+paste).
+ * @QEMU_CLIPBOARD_SELECTION_PRIMARY: primary selection (select + middle mouse 
button).
+ * @QEMU_CLIPBOARD_SELECTION_SECONDARY: secondary selection (dunno).
+ * @QEMU_CLIPBOARD_SELECTION__COUNT: selection count.
+ */
 enum QemuClipboardSelection {
 QEMU_CLIPBOARD_SELECTION_CLIPBOARD,
 QEMU_CLIPBOARD_SELECTION_PRIMARY,
@@ -21,6 +51,15 @@ enum QemuClipboardSelection {
 QEMU_CLIPBOARD_SELECTION__COUNT,
 };
 
+/**
+ * struct QemuClipboardPeer
+ *
+ * @name: peer name.
+ * @update: notifier for clipboard updates.
+ * @request: callback for clipboard data requests.
+ *
+ * Clipboard peer description.
+ */
 struct QemuClipboardPeer {
 const char *name;
 Notifier update;
@@ -28,6 +67,16 @@ struct QemuClipboardPeer {
 QemuClipboardType type);
 };
 
+/**
+ * struct QemuClipboardInfo
+ *
+ * @refcount: reference counter.
+ * @owner: clipboard owner.
+ * @selection: clipboard selection.
+ * @types: clipboard data array (one entry per type).
+ *
+ * Clipboard content data and metadata.
+ */
 struct QemuClipboardInfo {
 uint32_t refcount;
 QemuClipboardPeer *owner;
@@ -40,18 +89,100 @@ struct QemuClipboardInfo {
 } types[QEMU_CLIPBOARD_TYPE__COUNT];
 };
 
+/**
+ * qemu_clipboard_peer_register
+ *
+ * @peer: peer information.
+ *
+ * Register clipboard peer.  Registering is needed for both active
+ * (set+grab clipboard) and passive (watch clipboard for updates)
+ * interaction with the qemu clipboard.
+ */
 void qemu_clipboard_peer_register(QemuClipboardPeer *peer);
+
+/**
+ * qemu_clipboard_peer_unregister
+ *
+ * @peer: peer information.
+ *
+ * Unregister clipboard peer.
+ */
 void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer);
 
+/**
+ * qemu_clipboard_info_new
+ *
+ * @owner: clipboard owner.
+ * @selection: clipboard selection.
+ *
+ * Allocate a new QemuClipboardInfo and initialize it with the given
+ * @owner and @selection.
+ *
+ * QemuClipboardInfo is a reference-counted struct.  The new struct is
+ * returned with a reference already taken (i.e. reference count is
+ * one).
+ */
 QemuClipboardInfo *qemu_clipboard_info_new(QemuClipboardPeer *owner,
QemuClipboardSelection selection);
+/**
+ * qemu_clipboard_info_ref
+ *
+ * @info: clipboard info.
+ *
+ * Increase @info reference count.
+ */
 QemuClipboardInfo *qemu_clipboard_info_ref(QemuClipboardInfo *info);
+
+/**
+ * qemu_clipboard_info_unref
+ *
+ * @info: clipboard info.
+ *
+ * Decrease @info reference count.  When the count goes down to zero
+ * free the @info struct itself and all clipboard data.
+ */
 void qemu_clipboard_info_unref(QemuClipboardInfo *info);
 
+/**
+ * qemu_clipboard_update
+ *
+ * @info: clipboard info.
+ *
+ * Update the qemu clipboard.  Notify all registered peers (including
+ * the clipboard owner) that the qemu clipboard has been updated.
+ *
+ * This is used for both new completely clipboard content and for
+ * clipboard data updates in response to qemu_clipboard_request()
+ * calls.
+ */
 void qemu_clipboard_update(QemuClipboardInfo *info);
+
+/**
+ * qemu_clipboard_request
+ *
+ * @info: clipboard info.
+ * @type: clipboard data type.
+ *
+ * Request clipboard content.  Typically the clipboard owner

[PATCH v6 1/9] build: add separate spice-protocol config option

2021-05-18 Thread Gerd Hoffmann
When implementing spice vdagent protocol in qemu we only need the
spice-protocol package for that, spice-server is not needed.  So
go split those two build dependencies.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Marc-André Lureau 
---
 configure   | 36 
 meson.build |  4 
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/configure b/configure
index 0e4233fd8ab4..1c45dd4b8c21 100755
--- a/configure
+++ b/configure
@@ -389,6 +389,7 @@ qom_cast_debug="yes"
 trace_backends="log"
 trace_file="trace"
 spice="$default_feature"
+spice_protocol="auto"
 rbd="auto"
 smartcard="$default_feature"
 u2f="auto"
@@ -1132,7 +1133,15 @@ for opt do
   ;;
   --disable-spice) spice="no"
   ;;
-  --enable-spice) spice="yes"
+  --enable-spice)
+  spice_protocol="yes"
+  spice="yes"
+  ;;
+  --disable-spice-protocol)
+  spice_protocol="no"
+  spice="no"
+  ;;
+  --enable-spice-protocol) spice_protocol="yes"
   ;;
   --disable-libiscsi) libiscsi="disabled"
   ;;
@@ -1870,6 +1879,7 @@ disabled with --disable-FEATURE, default is enabled if 
available
   vhost-user-blk-servervhost-user-blk server support
   vhost-vdpa  vhost-vdpa kernel backend support
   spice   spice
+  spice-protocol  spice-protocol
   rbd rados block device (rbd)
   libiscsiiscsi support
   libnfs  nfs support
@@ -4153,6 +4163,19 @@ fi
 
 ##
 # spice probe
+if test "$spice_protocol" != "no" ; then
+  spice_protocol_cflags=$($pkg_config --cflags spice-protocol 2>/dev/null)
+  if $pkg_config --atleast-version=0.12.3 spice-protocol; then
+spice_protocol="yes"
+  else
+if test "$spice_protocol" = "yes" ; then
+  feature_not_found "spice_protocol" \
+  "Install spice-protocol(>=0.12.3) devel"
+fi
+spice_protocol="no"
+  fi
+fi
+
 if test "$spice" != "no" ; then
   cat > $TMPC << EOF
 #include 
@@ -4161,13 +4184,13 @@ EOF
   spice_cflags=$($pkg_config --cflags spice-protocol spice-server 2>/dev/null)
   spice_libs=$($pkg_config --libs spice-protocol spice-server 2>/dev/null)
   if $pkg_config --atleast-version=0.12.5 spice-server && \
- $pkg_config --atleast-version=0.12.3 spice-protocol && \
+ test "$spice_protocol" = "yes" && \
  compile_prog "$spice_cflags" "$spice_libs" ; then
 spice="yes"
   else
 if test "$spice" = "yes" ; then
   feature_not_found "spice" \
-  "Install spice-server(>=0.12.5) and spice-protocol(>=0.12.3) devel"
+  "Install spice-server(>=0.12.5) devel"
 fi
 spice="no"
   fi
@@ -5836,9 +5859,14 @@ fi
 if test "$posix_memalign" = "yes" ; then
   echo "CONFIG_POSIX_MEMALIGN=y" >> $config_host_mak
 fi
+
+if test "$spice_protocol" = "yes" ; then
+  echo "CONFIG_SPICE_PROTOCOL=y" >> $config_host_mak
+  echo "SPICE_PROTOCOL_CFLAGS=$spice_protocol_cflags" >> $config_host_mak
+fi
 if test "$spice" = "yes" ; then
   echo "CONFIG_SPICE=y" >> $config_host_mak
-  echo "SPICE_CFLAGS=$spice_cflags" >> $config_host_mak
+  echo "SPICE_CFLAGS=$spice_cflags $spice_protocol_cflags" >> $config_host_mak
   echo "SPICE_LIBS=$spice_libs" >> $config_host_mak
 fi
 
diff --git a/meson.build b/meson.build
index 8e16e05c2ade..36c17a5ba921 100644
--- a/meson.build
+++ b/meson.build
@@ -458,11 +458,15 @@ if 'CONFIG_LIBJACK' in config_host
 endif
 spice = not_found
 spice_headers = not_found
+spice_protocol = not_found
 if 'CONFIG_SPICE' in config_host
   spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
  link_args: config_host['SPICE_LIBS'].split())
   spice_headers = declare_dependency(compile_args: 
config_host['SPICE_CFLAGS'].split())
 endif
+if 'CONFIG_SPICE_PROTOCOL' in config_host
+  spice_protocol = declare_dependency(compile_args: 
config_host['SPICE_PROTOCOL_CFLAGS'].split())
+endif
 rt = cc.find_library('rt', required: false)
 libdl = not_found
 if 'CONFIG_PLUGIN' in config_host
-- 
2.31.1




[PATCH v6 2/9] ui: add clipboard infrastructure

2021-05-18 Thread Gerd Hoffmann
Add some infrastructure to manage the clipboard in qemu.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Marc-André Lureau 
---
 include/ui/clipboard.h | 62 
 ui/clipboard.c | 92 ++
 ui/meson.build |  1 +
 3 files changed, 155 insertions(+)
 create mode 100644 include/ui/clipboard.h
 create mode 100644 ui/clipboard.c

diff --git a/include/ui/clipboard.h b/include/ui/clipboard.h
new file mode 100644
index ..876de7621911
--- /dev/null
+++ b/include/ui/clipboard.h
@@ -0,0 +1,62 @@
+#ifndef QEMU_CLIPBOARD_H
+#define QEMU_CLIPBOARD_H
+
+#include "qemu/notify.h"
+
+typedef enum QemuClipboardType QemuClipboardType;
+typedef enum QemuClipboardSelection QemuClipboardSelection;
+typedef struct QemuClipboardPeer QemuClipboardPeer;
+typedef struct QemuClipboardInfo QemuClipboardInfo;
+
+enum QemuClipboardType {
+QEMU_CLIPBOARD_TYPE_TEXT,  /* text/plain; charset=utf-8 */
+QEMU_CLIPBOARD_TYPE__COUNT,
+};
+
+/* same as VD_AGENT_CLIPBOARD_SELECTION_* */
+enum QemuClipboardSelection {
+QEMU_CLIPBOARD_SELECTION_CLIPBOARD,
+QEMU_CLIPBOARD_SELECTION_PRIMARY,
+QEMU_CLIPBOARD_SELECTION_SECONDARY,
+QEMU_CLIPBOARD_SELECTION__COUNT,
+};
+
+struct QemuClipboardPeer {
+const char *name;
+Notifier update;
+void (*request)(QemuClipboardInfo *info,
+QemuClipboardType type);
+};
+
+struct QemuClipboardInfo {
+uint32_t refcount;
+QemuClipboardPeer *owner;
+QemuClipboardSelection selection;
+struct {
+bool available;
+bool requested;
+size_t size;
+void *data;
+} types[QEMU_CLIPBOARD_TYPE__COUNT];
+};
+
+void qemu_clipboard_peer_register(QemuClipboardPeer *peer);
+void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer);
+
+QemuClipboardInfo *qemu_clipboard_info_new(QemuClipboardPeer *owner,
+   QemuClipboardSelection selection);
+QemuClipboardInfo *qemu_clipboard_info_ref(QemuClipboardInfo *info);
+void qemu_clipboard_info_unref(QemuClipboardInfo *info);
+
+void qemu_clipboard_update(QemuClipboardInfo *info);
+void qemu_clipboard_request(QemuClipboardInfo *info,
+QemuClipboardType type);
+
+void qemu_clipboard_set_data(QemuClipboardPeer *peer,
+ QemuClipboardInfo *info,
+ QemuClipboardType type,
+ uint32_t size,
+ void *data,
+ bool update);
+
+#endif /* QEMU_CLIPBOARD_H */
diff --git a/ui/clipboard.c b/ui/clipboard.c
new file mode 100644
index ..abf2b98f1f89
--- /dev/null
+++ b/ui/clipboard.c
@@ -0,0 +1,92 @@
+#include "qemu/osdep.h"
+#include "ui/clipboard.h"
+
+static NotifierList clipboard_notifiers =
+NOTIFIER_LIST_INITIALIZER(clipboard_notifiers);
+
+void qemu_clipboard_peer_register(QemuClipboardPeer *peer)
+{
+notifier_list_add(&clipboard_notifiers, &peer->update);
+}
+
+void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer)
+{
+notifier_remove(&peer->update);
+}
+
+void qemu_clipboard_update(QemuClipboardInfo *info)
+{
+notifier_list_notify(&clipboard_notifiers, info);
+}
+
+QemuClipboardInfo *qemu_clipboard_info_new(QemuClipboardPeer *owner,
+   QemuClipboardSelection selection)
+{
+QemuClipboardInfo *info = g_new0(QemuClipboardInfo, 1);
+
+info->owner = owner;
+info->selection = selection;
+info->refcount = 1;
+
+return info;
+}
+
+QemuClipboardInfo *qemu_clipboard_info_ref(QemuClipboardInfo *info)
+{
+info->refcount++;
+return info;
+}
+
+void qemu_clipboard_info_unref(QemuClipboardInfo *info)
+{
+uint32_t type;
+
+if (!info) {
+return;
+}
+
+info->refcount--;
+if (info->refcount > 0) {
+return;
+}
+
+for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) {
+g_free(info->types[type].data);
+}
+g_free(info);
+}
+
+void qemu_clipboard_request(QemuClipboardInfo *info,
+QemuClipboardType type)
+{
+if (info->types[type].data ||
+info->types[type].requested ||
+!info->types[type].available ||
+!info->owner)
+return;
+
+info->types[type].requested = true;
+info->owner->request(info, type);
+}
+
+void qemu_clipboard_set_data(QemuClipboardPeer *peer,
+ QemuClipboardInfo *info,
+ QemuClipboardType type,
+ uint32_t size,
+ void *data,
+ bool update)
+{
+if (!info ||
+info->owner != peer) {
+return;
+}
+
+g_free(info->types[type].data);
+info->types[type].data = g_memdup(data, size);
+info->types[type].size = size;
+info->types[type].available = true;
+
+if (update) {
+qemu_clipboard_update(info);
+}
+}
diff 

Re: [PATCH] qemu-config: load modules when instantiating option groups

2021-05-18 Thread Gerd Hoffmann
On Tue, May 18, 2021 at 09:15:42AM -0400, Paolo Bonzini wrote:
> Right now the SPICE module is special cased to be loaded when processing
> of the -spice command line option.  However, the spice option group
> can also be brought in via -readconfig, in which case the module is
> not loaded.
> 
> Add a generic hook to load modules that provide a QemuOpts group,
> and use it for the "spice" and "iscsi" groups.
> 
> Fixes: #194
> Fixes: https://bugs.launchpad.net/qemu/+bug/1910696
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Gerd Hoffmann 




[PATCH v2 0/2] target/i386: Make sure that vsyscall's tb->size != 0

2021-05-18 Thread Ilya Leoshkevich
This series for the s390-next tree fixes [1]. Patch 1 is the fix, patch
2 is the new test to avoid similar regressions in the future.

[1] https://lists.nongnu.org/archive/html/qemu-devel/2021-05/msg02962.html

v1: https://lists.gnu.org/archive/html/qemu-devel/2021-05/msg03219.html
v1 -> v2: Fixed a problem with compiling the new test on centos7. `make
  docker-all-tests` does not spot any other issues with the
  updated patch (it does fail though: a number of iotests have
  problems, there is a build problem with musl, etc, but this
  all happens without the patch too).

Ilya Leoshkevich (2):
  target/i386: Make sure that vsyscall's tb->size != 0
  tests/tcg/x86_64: add vsyscall smoke test

 target/i386/tcg/translate.c  |  1 +
 tests/tcg/x86_64/Makefile.target |  6 +-
 tests/tcg/x86_64/vsyscall.c  | 12 
 3 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/x86_64/vsyscall.c

-- 
2.31.1




[PATCH v2 2/2] tests/tcg/x86_64: add vsyscall smoke test

2021-05-18 Thread Ilya Leoshkevich
Having a small test will prevent trivial regressions in the future.

Signed-off-by: Ilya Leoshkevich 
---
 tests/tcg/x86_64/Makefile.target |  6 +-
 tests/tcg/x86_64/vsyscall.c  | 12 
 2 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/x86_64/vsyscall.c

diff --git a/tests/tcg/x86_64/Makefile.target b/tests/tcg/x86_64/Makefile.target
index 20bf96202a..2151ea6302 100644
--- a/tests/tcg/x86_64/Makefile.target
+++ b/tests/tcg/x86_64/Makefile.target
@@ -3,14 +3,18 @@
 # x86_64 tests - included from tests/tcg/Makefile.target
 #
 # Currently we only build test-x86_64 and test-i386-ssse3 from
-# $(SRC)/tests/tcg/i386/
+# $(SRC_PATH)/tests/tcg/i386/
 #
 
 include $(SRC_PATH)/tests/tcg/i386/Makefile.target
 
+X86_64_TESTS += vsyscall
 TESTS=$(MULTIARCH_TESTS) $(X86_64_TESTS) test-x86_64
 QEMU_OPTS += -cpu max
 
 test-x86_64: LDFLAGS+=-lm -lc
 test-x86_64: test-i386.c test-i386.h test-i386-shift.h test-i386-muldiv.h
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
+
+vsyscall: $(SRC_PATH)/tests/tcg/x86_64/vsyscall.c
+   $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
diff --git a/tests/tcg/x86_64/vsyscall.c b/tests/tcg/x86_64/vsyscall.c
new file mode 100644
index 00..786b047053
--- /dev/null
+++ b/tests/tcg/x86_64/vsyscall.c
@@ -0,0 +1,12 @@
+#include 
+#include 
+
+#define VSYSCALL_PAGE 0xff60
+#define TIME_OFFSET 0x400
+typedef time_t (*time_func)(time_t *);
+
+int main(void)
+{
+printf("%ld\n", ((time_func)(VSYSCALL_PAGE + TIME_OFFSET))(NULL));
+return 0;
+}
-- 
2.31.1




[PATCH v2 1/2] target/i386: Make sure that vsyscall's tb->size != 0

2021-05-18 Thread Ilya Leoshkevich
tb_gen_code() assumes that tb->size must never be zero, otherwise it
may produce spurious exceptions. For x86_64 this may happen when
creating a translation block for the vsyscall page.

Fix by pretending that vsyscall translation blocks have at least one
instruction.

Signed-off-by: Ilya Leoshkevich 
Reviewed-by: Richard Henderson 
---
 target/i386/tcg/translate.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 880bc45561..b5a2b981e2 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -8572,6 +8572,7 @@ static void i386_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
  */
 if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) {
 gen_exception(dc, EXCP_VSYSCALL, dc->base.pc_next);
+dc->base.pc_next = dc->pc + 1;
 return;
 }
 #endif
-- 
2.31.1




Re: [PATCH 00/24] target/ppc: Clean up mmu translation

2021-05-18 Thread David Gibson
On Tue, May 18, 2021 at 03:11:22PM -0500, Richard Henderson wrote:
> This attempts the cleanup I've been talking about with Bruno.
> 
> On the way, there's a lot of MMUAccessType cleanup, to get the
> code into the form I wanted the interface to share.  There's a
> lot more cleanup that could be done, particularly wrt the older
> mmu models.

I've applied 1..15, still looking at the rest.

-- 
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 v4 00/13] virtio-gpu: Add support for Blob resources feature (v4)

2021-05-18 Thread Kasireddy, Vivek
Hi Gerd,
> 
> On Tue, May 11, 2021 at 03:47:06PM -0700, Vivek Kasireddy wrote:
> > Enabling this feature would eliminate data copies from the resource
> > object in the Guest to the shadow resource in Qemu. This patch series
> > however adds support only for Blobs of type VIRTIO_GPU_BLOB_MEM_GUEST
> > with property VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE.
> >
> > Most of the patches in this series are a rebased, refactored and
> > bugfixed versions of Gerd Hoffmann's patches located here:
> > https://gitlab.freedesktop.org/virgl/qemu/-/commits/virtio-gpu-next
> 
> Doesn't apply cleanly to master, can you rebase and resend?
[Kasireddy, Vivek] Sure, just sent a v5.

Thanks,
Vivek

> 
> thanks,
>   Gerd




Re: [PATCH v2] target/ppc: Fix load endianness for lxvwsx/lxvdsx

2021-05-18 Thread David Gibson
On Tue, May 18, 2021 at 03:30:20PM +0200, Giuseppe Musacchio wrote:
> TARGET_WORDS_BIGENDIAN may not match the machine endianness if that's a
> runtime-configurable parameter.
> 
> Fixes: bcb0b7b1a1c05707304f80ca6f523d557816f85c
> Fixes: afae37d98ae991c0792c867dbd9f32f988044318
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/212
> 
> Signed-off-by: Giuseppe Musacchio 

That looks more like it.  Applied to ppc-for-6.1, thanks.

> ---
>  target/ppc/translate/vsx-impl.c.inc | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/target/ppc/translate/vsx-impl.c.inc 
> b/target/ppc/translate/vsx-impl.c.inc
> index b817d31260..57a7f73bba 100644
> --- a/target/ppc/translate/vsx-impl.c.inc
> +++ b/target/ppc/translate/vsx-impl.c.inc
> @@ -139,7 +139,7 @@ static void gen_lxvwsx(DisasContext *ctx)
>  gen_addr_reg_index(ctx, EA);
>  
>  data = tcg_temp_new_i32();
> -tcg_gen_qemu_ld_i32(data, EA, ctx->mem_idx, MO_TEUL);
> +tcg_gen_qemu_ld_i32(data, EA, ctx->mem_idx, DEF_MEMOP(MO_UL));
>  tcg_gen_gvec_dup_i32(MO_UL, vsr_full_offset(xT(ctx->opcode)), 16, 16, 
> data);
>  
>  tcg_temp_free(EA);
> @@ -162,7 +162,7 @@ static void gen_lxvdsx(DisasContext *ctx)
>  gen_addr_reg_index(ctx, EA);
>  
>  data = tcg_temp_new_i64();
> -tcg_gen_qemu_ld_i64(data, EA, ctx->mem_idx, MO_TEQ);
> +tcg_gen_qemu_ld_i64(data, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
>  tcg_gen_gvec_dup_i64(MO_Q, vsr_full_offset(xT(ctx->opcode)), 16, 16, 
> data);
>  
>  tcg_temp_free(EA);

-- 
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 v2] target/ppc: Fix load endianness for lxvwsx/lxvdsx

2021-05-18 Thread David Gibson
On Tue, May 18, 2021 at 10:42:09AM -0500, Paul A. Clarke wrote:
> Thanks, all!  My original patch which addressed this issue
> for me probably should've been labeled as an RFC.  Thanks for your
> willingness to review it, in spite of its problems.  It was a bit
> of a stab in the dark. I hope it at least helped get to this solution.
> 
> Tested-by: Paul A. Clarke 
> 
> Do I need to do anything about the GitLab issue?
> https://gitlab.com/qemu-project/qemu/-/issues/212

If you could retest and close the issue once the fix is merged, that
would be helpful, thanks.

> 
> (I couldn't even figure out how to subscribe to my own issue,
> or if I already was, or who might have been notified of its
> existence, or if discussion should happen there or here.)
> 
> On Tue, May 18, 2021 at 03:30:20PM +0200, Giuseppe Musacchio wrote:
> > TARGET_WORDS_BIGENDIAN may not match the machine endianness if that's a
> > runtime-configurable parameter.
> > 
> > Fixes: bcb0b7b1a1c05707304f80ca6f523d557816f85c
> > Fixes: afae37d98ae991c0792c867dbd9f32f988044318
> > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/212
> > 
> > Signed-off-by: Giuseppe Musacchio 
> > ---
> >  target/ppc/translate/vsx-impl.c.inc | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/target/ppc/translate/vsx-impl.c.inc 
> > b/target/ppc/translate/vsx-impl.c.inc
> > index b817d31260..57a7f73bba 100644
> > --- a/target/ppc/translate/vsx-impl.c.inc
> > +++ b/target/ppc/translate/vsx-impl.c.inc
> > @@ -139,7 +139,7 @@ static void gen_lxvwsx(DisasContext *ctx)
> >  gen_addr_reg_index(ctx, EA);
> >  
> >  data = tcg_temp_new_i32();
> > -tcg_gen_qemu_ld_i32(data, EA, ctx->mem_idx, MO_TEUL);
> > +tcg_gen_qemu_ld_i32(data, EA, ctx->mem_idx, DEF_MEMOP(MO_UL));
> >  tcg_gen_gvec_dup_i32(MO_UL, vsr_full_offset(xT(ctx->opcode)), 16, 16, 
> > data);
> >  
> >  tcg_temp_free(EA);
> > @@ -162,7 +162,7 @@ static void gen_lxvdsx(DisasContext *ctx)
> >  gen_addr_reg_index(ctx, EA);
> >  
> >  data = tcg_temp_new_i64();
> > -tcg_gen_qemu_ld_i64(data, EA, ctx->mem_idx, MO_TEQ);
> > +tcg_gen_qemu_ld_i64(data, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
> >  tcg_gen_gvec_dup_i64(MO_Q, vsr_full_offset(xT(ctx->opcode)), 16, 16, 
> > data);
> >  
> >  tcg_temp_free(EA);
> 
> PC
> 

-- 
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 v2 1/7] target/ppc: fix ppc_store_sdr1 for user-only compilation

2021-05-18 Thread David Gibson
On Tue, May 18, 2021 at 12:05:09PM -0300, Bruno Larsen (billionai) wrote:
> When the function was moved to cpu.c, it should have been wrapped with
>  #if !defined(CONFIG_USER_ONLY), otherwise linux-user builds don't work.

I already corrected this in my tree, folding it into the original
change to avoid breaking bisect.

> The cleanup suggested by Richard Henderson has also been applied,
> changing error_report(...) to qemu_log_mask(LOG_GUEST_ERROR, ...) in
> that function.

That's a reasonable change, but doesn't belong with the compile fix.
Please rebase and update the commit message.

> 
> Signed-off-by: Bruno Larsen (billionai) 
> ---
>  target/ppc/cpu.c | 10 ++
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c
> index 0ab7ac1af1..82e276349a 100644
> --- a/target/ppc/cpu.c
> +++ b/target/ppc/cpu.c
> @@ -65,6 +65,7 @@ uint32_t ppc_get_vscr(CPUPPCState *env)
>  return env->vscr | (sat << VSCR_SAT);
>  }
>  
> +#if !defined(CONFIG_USER_ONLY)
>  void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
>  {
>  PowerPCCPU *cpu = env_archcpu(env);
> @@ -76,13 +77,13 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
>  target_ulong htabsize = value & SDR_64_HTABSIZE;
>  
>  if (value & ~sdr_mask) {
> -error_report("Invalid bits 0x"TARGET_FMT_lx" set in SDR1",
> - value & ~sdr_mask);
> +qemu_log_mask(LOG_GUEST_ERROR, "Invalid bits 0x"TARGET_FMT_lx
> + " set in SDR1", value & ~sdr_mask);
>  value &= sdr_mask;
>  }
>  if (htabsize > 28) {
> -error_report("Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in 
> SDR1",
> - htabsize);
> +qemu_log_mask(LOG_GUEST_ERROR, "Invalid HTABSIZE 0x" 
> TARGET_FMT_lx
> + " stored in SDR1", htabsize);
>  return;
>  }
>  }
> @@ -90,3 +91,4 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
>  /* FIXME: Should check for valid HTABMASK values in 32-bit case */
>  env->spr[SPR_SDR1] = value;
>  }
> +#endif

-- 
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 v2 7/7] target/ppc: wrapped some TCG only logic with ifdefs

2021-05-18 Thread David Gibson
On Tue, May 18, 2021 at 12:05:15PM -0300, Bruno Larsen (billionai) wrote:
> Wrapped some function calls in cpu_init.c, gdbstub.c, mmu-hash64.c and
> excp_helper.c that were TCG only with ifdef CONFIG_TCG, to support
> building without TCG.
> 
> for excp_helper we also moved the function do_rfi higher in the file to
> reduce the ifdef count.

The description's no longer really accurate since some of the fixups
are no longer ifdef based.


> Signed-off-by: Bruno Larsen (billionai) 
> ---
>  target/ppc/cpu_init.c| 16 +---
>  target/ppc/excp_helper.c | 82 +++-
>  target/ppc/mmu-hash64.c  |  8 
>  3 files changed, 66 insertions(+), 40 deletions(-)
> 
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index 88a8344eea..5ab4d4ef2b 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -1203,15 +1203,13 @@ static void register_BookE206_sprs(CPUPPCState *env, 
> uint32_t mas_mask,
>  /* TLB assist registers */
>  /* XXX : not implemented */
>  for (i = 0; i < 8; i++) {
> -void (*uea_write)(DisasContext *ctx, int sprn, int gprn) =
> -&spr_write_generic32;
> -if (i == 2 && (mas_mask & (1 << i)) && (env->insns_flags & PPC_64B)) 
> {
> -uea_write = &spr_write_generic;
> -}
>  if (mas_mask & (1 << i)) {
>  spr_register(env, mas_sprn[i], mas_names[i],
>   SPR_NOACCESS, SPR_NOACCESS,
> - &spr_read_generic, uea_write,
> + &spr_read_generic,
> + (i == 2 && (mas_mask & (1 << i)) &&
> + (env->insns_flags & PPC_64B))
> + ? &spr_write_generic : &spr_write_generic32,


Looks good.
>   0x);
>  }
>  }
> @@ -8605,11 +8603,13 @@ static void ppc_cpu_realize(DeviceState *dev, Error 
> **errp)
>  }
>  }
>  
> +#ifdef CONFIG_TCG
>  create_ppc_opcodes(cpu, &local_err);
>  if (local_err != NULL) {
>  error_propagate(errp, local_err);
>  goto unrealize;
>  }
> +#endif

In this instance, I think it would be cleaner to create a no-op stub
for create_ppc_opcodes() and destroy_ppc_opcodes() rather than using
ifdefs.

>  init_ppc_proc(cpu);
>  
>  ppc_gdb_init(cs, pcc);
> @@ -8798,7 +8798,9 @@ static void ppc_cpu_unrealize(DeviceState *dev)
>  
>  cpu_remove_sync(CPU(cpu));
>  
> +#ifdef CONFIG_TCG
>  destroy_ppc_opcodes(cpu);
> +#endif
>  }
>  
>  static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
> @@ -9296,7 +9298,9 @@ static void ppc_cpu_class_init(ObjectClass *oc, void 
> *data)
>  cc->class_by_name = ppc_cpu_class_by_name;
>  cc->has_work = ppc_cpu_has_work;
>  cc->dump_state = ppc_cpu_dump_state;
> +#ifdef CONFIG_TCG
>  cc->dump_statistics = ppc_cpu_dump_statistics;
> +#endif
>  cc->set_pc = ppc_cpu_set_pc;
>  cc->gdb_read_register = ppc_cpu_gdb_read_register;
>  cc->gdb_write_register = ppc_cpu_gdb_write_register;
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 80bb6e70e9..a14b529722 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -19,9 +19,13 @@
>  #include "qemu/osdep.h"
>  #include "qemu/main-loop.h"
>  #include "cpu.h"
> +#ifdef CONFIG_TCG
>  #include "exec/helper-proto.h"
> +#endif

I don't like the look of ifdefs amongst the includes.  Generally the
headers themselves should be made safe (if unnecessary) to include for
!TCG builds.

>  #include "exec/exec-all.h"
> +#ifdef CONFIG_TCG
>  #include "exec/cpu_ldst.h"
> +#endif
>  #include "internal.h"
>  #include "helper_regs.h"

The remaining ifdef changes look fine.  Some it would be nice to clean
up better in future, but there's no rush.

-- 
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] Fix `lxvdsx` (issue #212)

2021-05-18 Thread David Gibson
On Tue, May 18, 2021 at 09:30:38AM +0200, Greg Kurz wrote:
> On Tue, 18 May 2021 08:40:36 +0200
> Giuseppe Musacchio  wrote:
> 
> > The ISA [1] specifies the load order to be the target one, hence
> > the use of MO_TEQ in my patch (in both lxvwsx and lxvdsx).
> > 
> > I believe the error is hidden in some of the .mak files: I could not
> > reproduce this problem with Qemu's user-mode emulation in either
> > BE nor LE mode, this lead me to discover that ppc64-softmmu.mak is
> > always defining TARGET_WORDS_BIGENDIAN=y. The user-mode targets are
> > correctly split into ppc64 and ppc64le, where only the former is
> > declared as BE.
> > 
> 
> Yes. In system-mode emulation, modern POWER CPUs are expected to
> be able to switch from BE to LE and vice-versa at runtime. Older
> PowerPC CPUs are BE. The qemu-system-ppc64 binary is thus built
> with TARGET_WORDS_BIGENDIAN=y and every place where runtime
> endianness matters need to do a check and only byteswap if needed.

Right.  With modern POWER (and ARM and several others), "target
endian" isn't really a well-defined concept, since the processor can
switch at runtime.

> 
> Mark's suggestion in another mail of this thread is the way to go.
> 
> > The presence of that define is unconditionally making MO_TE an alias
> > for MO_BE, that's why Paul's patch seems to fix the problem.
> > 
> > I didn't catch this problem earlier as pretty much of our testing is
> > done using the Linux user-mode emulation.
> > 
> > Cheers,
> > G.M.
> > 
> > [1] https://ibm.ent.box.com/s/1hzcwkwf8rbju5h9iyf44wm94amnlcrv
> > 
> > On 18/05/21 03:34, David Gibson wrote:
> > > 
> > > On Mon, May 17, 2021 at 04:40:32PM -0500, Paul A. Clarke wrote:
> > >> `lxvdsx` is byte-swapping the data it loads, which it should not
> > >> do.  Fix it.
> > >>
> > >> Fixes #212.
> > >>
> > >> Fixes: bcb0b7b1a1c05707304f80ca6f523d557816f85c
> > >> Signed-off-by:  Paul A. Clarke  > >nit, missing '>' ...^
> > > 
> > > I'm having a hard time convincing myself this is correct in all cases.
> > > Have you tested it with all combinations of BE/LE host and BE/LE guest
> > > code?
> > > 
> > > The description in the ISA is pretty inscrutable, since it's in terms
> > > of the confusing numbering if different element types in BE vs LE
> > > mode.
> > > 
> > > It looks to me like before bcb0b7b1a1c0 this originally resolved to
> > > MO_Q modified by ctx->default_tcg_memop_mask, which appears to depend
> > > on the current guest endian mode.  That's pretty hard to trace through
> > > the various layers of macros, but for reference, before bcb0b7b1a1c0
> > > this used gen_qemu_ld64_i64(), which appears to be constructed by the
> > > line GEN_QEMU_LOAD_64(ld64,  DEF_MEMOP(MO_Q)) in translate.c.
> > > 
> > > Richard or Giuseppe, care to weigh in?
> > > 
> > >> ---
> > >>  target/ppc/translate/vsx-impl.c.inc | 2 +-
> > >>  1 file changed, 1 insertion(+), 1 deletion(-)
> > >>
> > >> diff --git a/target/ppc/translate/vsx-impl.c.inc 
> > >> b/target/ppc/translate/vsx-impl.c.inc
> > >> index b817d31260bb..46f97c029ca8 100644
> > >> --- a/target/ppc/translate/vsx-impl.c.inc
> > >> +++ b/target/ppc/translate/vsx-impl.c.inc
> > >> @@ -162,7 +162,7 @@ static void gen_lxvdsx(DisasContext *ctx)
> > >>  gen_addr_reg_index(ctx, EA);
> > >>  
> > >>  data = tcg_temp_new_i64();
> > >> -tcg_gen_qemu_ld_i64(data, EA, ctx->mem_idx, MO_TEQ);
> > >> +tcg_gen_qemu_ld_i64(data, EA, ctx->mem_idx, MO_LEQ);
> > >>  tcg_gen_gvec_dup_i64(MO_Q, vsr_full_offset(xT(ctx->opcode)), 16, 
> > >> 16, data);
> > >>  
> > >>  tcg_temp_free(EA);
> > > 
> > 
> 

-- 
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


[PATCH v4] plugins/syscall: Added a table-like summary output

2021-05-18 Thread Mahmoud Mandour
Added a table-like output which contains the total number of calls
for each used syscall along with the number of errors that occurred.

Per-call tracing is still available through supplying the argument
``print`` to the plugin.

Signed-off-by: Mahmoud Mandour 
---
v3 -> v4: Added a missing ``static`` that was causing a compilation 
  error. Otherwise, everything else is left in place.
 tests/plugin/syscall.c | 98 +++---
 1 file changed, 93 insertions(+), 5 deletions(-)

diff --git a/tests/plugin/syscall.c b/tests/plugin/syscall.c
index 53ee2ab6c4..6dd71092e1 100644
--- a/tests/plugin/syscall.c
+++ b/tests/plugin/syscall.c
@@ -16,32 +16,120 @@
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
 
+typedef struct {
+int64_t num;
+int64_t calls;
+int64_t errors;
+} SyscallStats;
+
+static GMutex lock;
+static GHashTable *statistics;
+
+static SyscallStats *get_or_create_entry(int64_t num)
+{
+SyscallStats *entry =
+(SyscallStats *) g_hash_table_lookup(statistics, GINT_TO_POINTER(num));
+
+if (!entry) {
+entry = g_new0(SyscallStats, 1);
+entry->num = num;
+g_hash_table_insert(statistics, GINT_TO_POINTER(num), (gpointer) 
entry);
+}
+
+return entry;
+}
+
 static void vcpu_syscall(qemu_plugin_id_t id, unsigned int vcpu_index,
  int64_t num, uint64_t a1, uint64_t a2,
  uint64_t a3, uint64_t a4, uint64_t a5,
  uint64_t a6, uint64_t a7, uint64_t a8)
 {
-g_autofree gchar *out = g_strdup_printf("syscall #%" PRIi64 "\n", num);
-qemu_plugin_outs(out);
+if (statistics) {
+SyscallStats *entry;
+g_mutex_lock(&lock);
+entry = get_or_create_entry(num);
+entry->calls++;
+g_mutex_unlock(&lock);
+} else {
+g_autofree gchar *out = g_strdup_printf("syscall #%" PRIi64 "\n", num);
+qemu_plugin_outs(out);
+}
 }
 
 static void vcpu_syscall_ret(qemu_plugin_id_t id, unsigned int vcpu_idx,
  int64_t num, int64_t ret)
+{
+if (statistics) {
+SyscallStats *entry;
+
+g_mutex_lock(&lock);
+/* Should always return an existent entry. */
+entry = get_or_create_entry(num);
+if (ret < 0) {
+entry->errors++;
+}
+g_mutex_unlock(&lock);
+} else {
+g_autofree gchar *out;
+out = g_strdup_printf("syscall #%" PRIi64 " returned -> %" PRIi64 "\n",
+num, ret);
+qemu_plugin_outs(out);
+}
+}
+
+static void print_entry(gpointer val, gpointer user_data)
 {
 g_autofree gchar *out;
-out = g_strdup_printf("syscall #%" PRIi64 " returned -> %" PRIi64 "\n",
-num, ret);
+SyscallStats *entry = (SyscallStats *) val;
+int64_t syscall_num = entry->num;
+out = g_strdup_printf(
+"%-13" PRIi64 "%-6" PRIi64 " %" PRIi64 "\n",
+syscall_num, entry->calls, entry->errors);
 qemu_plugin_outs(out);
 }
 
+static gint comp_func(gconstpointer ea, gconstpointer eb)
+{
+SyscallStats *ent_a = (SyscallStats *) ea;
+SyscallStats *ent_b = (SyscallStats *) eb;
+
+return ent_a->calls > ent_b->calls ? -1 : 1;
+}
+
 /* * */
+static void plugin_exit(qemu_plugin_id_t id, void *p)
+{
+if (!statistics) {
+return;
+}
+
+g_mutex_lock(&lock);
+GList *entries = g_hash_table_get_values(statistics);
+entries = g_list_sort(entries, comp_func);
+qemu_plugin_outs("syscall no.  calls  errors\n");
 
-static void plugin_exit(qemu_plugin_id_t id, void *p) {}
+g_list_foreach(entries, print_entry, NULL);
+
+g_list_free(entries);
+g_hash_table_destroy(statistics);
+g_mutex_unlock(&lock);
+}
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
const qemu_info_t *info,
int argc, char **argv)
 {
+if (argc == 0) {
+statistics = g_hash_table_new_full(NULL, g_direct_equal, NULL, g_free);
+} else {
+for (int i = 0; i < argc; i++) {
+if (g_strcmp0(argv[i], "print") != 0) {
+fprintf(stderr, "unsupported argument: %s\n", argv[i]);
+return -1;
+}
+}
+}
+
 qemu_plugin_register_vcpu_syscall_cb(id, vcpu_syscall);
 qemu_plugin_register_vcpu_syscall_ret_cb(id, vcpu_syscall_ret);
 qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
-- 
2.25.1




Re: [RFC PATCH v2 5/6] hw/arm/virt-acpi-build: Add PPTT table

2021-05-18 Thread wangyanan (Y)



On 2021/5/19 3:22, Salil Mehta wrote:

From: Andrew Jones [mailto:drjo...@redhat.com]
Sent: Tuesday, May 18, 2021 8:06 PM
To: Salil Mehta 
Cc: wangyanan (Y) ; Peter Maydell
; Michael S . Tsirkin ; Wanghaibin
(D) ; qemu-devel@nongnu.org; Shannon Zhao
; qemu-...@nongnu.org; Alistair Francis
; Zengtao (B) ;
yangyicong ; yuzenghui ; Igor
Mammedov ; zhukeqian ; lijiajie (H)
; David Gibson ; Linuxarm
; linux...@openeuler.org
Subject: Re: [RFC PATCH v2 5/6] hw/arm/virt-acpi-build: Add PPTT table

On Tue, May 18, 2021 at 06:34:08PM +, Salil Mehta wrote:

  Those benefits, when vcpu pinning is used, are the same benefits

as for the host, which already use PPTT tables to describe topology, even
though hot plug isn't supported.

yes sure, you mean pinning vcpus according to the cpu topology for performance?

Yup

Already Agreed :)


Now, if you're saying we should only generate tables for smp.cpus, not

Correct. This is what I thought we must be doing even now


smp.maxcpus, because hot plug isn't supported anyway, then I see your
point. But, it'd be better to require smp.cpus == smp.maxcpus in our
smp_parse function to do that, which we've never done before, so we may
have trouble supporting existing command lines.

I am trying to recall, if the vcpu Hotplug is not supported then can they
ever be different?

cpus =  (threads * cores * sockets)

static void smp_parse(MachineState *ms, QemuOpts *opts)
{
  [...]

 if (sockets * cores * threads != ms->smp.max_cpus) {
 warn_report("Invalid CPU topology deprecated: "
 "sockets (%u) * cores (%u) * threads (%u) "
 "!= maxcpus (%u)",
 sockets, cores, threads,
 ms->smp.max_cpus);
 }
  [...]
}

Although, above check does not exit(1) and just warns on detecting invalid
CPU topology. Not sure why?

Hmm, not sure what code you have there. I see this in
hw/core/machine.c:smp_parse

 if (ms->smp.max_cpus < cpus) {
 error_report("maxcpus must be equal to or greater than smp");
 exit(1);
 }

 if (sockets * cores * threads != ms->smp.max_cpus) {
 error_report("Invalid CPU topology: "
  "sockets (%u) * cores (%u) * threads (%u) "
  "!= maxcpus (%u)",
  sockets, cores, threads,
  ms->smp.max_cpus);
 exit(1);
 }


Well if you think there are subtleties to support above implementation and
we cannot do it now then sure it is your call. :)

Hi Salil, Drew,

The problem is that -smp 4,maxcpus=8 doesn't error out today, even though
it doesn't do anything. OTOH, -smp 4,cores=2 doesn't error out either, but
we're proposing that it should. Maybe we can start erroring out when
cpus != maxcpus until hot plug is supported?

Agreed, both don't make any sense if hotplug is not supported and ideally should
fail with error. We should block any such topology configuration.

In the ARM-specific function virt_smp_parse() (patch 9), there already
have been some restrictions for the given -smp configuration.
We now only allow:
-smp N
-smp maxcpus=M
-smp N, maxcpus=M

-smp N, sockets=X, cores=Y
-smp N, sockets=X, cores=Y, threads=Z

-smp maxcpus=M, sockets=X, cores=Y
-smp maxcpus=M, sockets=X, cores=Y, threads=Z

-smp N, maxcpus=M, sockets=X, cores=Y
-smp N, maxcpus=M, sockets=X, cores=Y, threads=Z

and disallow the other strange and rare formats that shouldn't be provided.

It's reasonable to block the topology configuration which is not useful
currently. I will add the requirement for "cpus==maxcpus" in this fuction
if the possible conflict with existing command lines is not a big problem.

Thanks,
Yanan


Thanks
Salil
.




Re: [PATCH] fw_cfg: Set the max fw_cfg mem read size to 8 bytes

2021-05-18 Thread yangxiaojuan
Hi,Laszlo

Thanks for your kindly reply.This is my first time to submit
code to the community. I spent some time learning how to configure
the email and reply.

Yes you are right, fw_cfg_init_mem_wide can solve my problem.
I just want to access 8 bytes width.I did not look at the code
carefully.I am so sorry. My patch can be abandoned.

I am from loongson. We want to add a new board support to
the community.Later we will submit more code.

thanks
Xiaojuan Yang


On 5/18/21 11:49 PM, Laszlo Ersek wrote:
> On 05/18/21 14:43, Xiaojuan Yang wrote:
>> From: yangxiaojuan 
>>
>> fw_cfg_data_read() func supports access widths from
>> 1 to 8 bytes while the ops set the wrong read size.
>>
>> Most arch use 8 bytes to send ram_size to bios.
>>
>> Signed-off-by: yangxiaojuan 
>> ---
>>  hw/nvram/fw_cfg.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
>> index 9b8dcca4ea..242614152c 100644
>> --- a/hw/nvram/fw_cfg.c
>> +++ b/hw/nvram/fw_cfg.c
>> @@ -540,7 +540,7 @@ static const MemoryRegionOps fw_cfg_data_mem_ops = {
>>  .endianness = DEVICE_BIG_ENDIAN,
>>  .valid = {
>>  .min_access_size = 1,
>> -.max_access_size = 1,
>> +.max_access_size = 8,
>>  .accepts = fw_cfg_data_mem_valid,
>>  },
>>  };
>>
> 
> This patch conflicts with (adjacent) commits
> 
> - cfaadf0e89e7 ("fw_cfg_mem: introduce the "data_width" property",
> 2014-12-22) and
> 
> - 6c87e3d5967a ("fw_cfg_mem: expose the "data_width" property with
> fw_cfg_init_mem_wide()", 2014-12-22)
> 
> Your board code is supposed to call the fw_cfg_init_mem_wide() function,
> for setting the maximum access width.
> 
> In fact, I see a call to fw_cfg_init_mem_wide() in
> "hw/mips/loongson3_virt.c" already, from commit c76b409fef19 ("hw/mips:
> Add Loongson-3 machine support", 2021-01-04). (I'm only highlighting
> this board because your email address is from domain "loongson.cn".)
> 
> What is the actual problem you're trying to solve?
> 
> Thanks
> Laszlo
> 




GSoC introduction: Rust vhost-user-scsi device

2021-05-18 Thread Gaelan Steele
Hello all,

I'm Gaelan Steele, one of QEMU's Google Summer of Code students this
year. My mentor (Sergio Lopez) has asked me to introduce myself and my
project here.

As you all may know, QEMU supports virtio-scsi in one of two ways: it
can use a built-in C implementation, running in the main QEMU process,
or delegate to another implementation over vhost-user. We have an
existing proof-of-concept vhost-user-scsi implementation in contrib/
that  passes requests through to an iSCSI target, but we don't have
such an implementation for a local disk image. My goal is to write 
one, in Rust. This has a few primary advantages over the existing
in-process SCSI implementation:

* Security - SCSI is a complex binary protocol - a fairly large attack
  surface. By moving the SCSI implementation into a separate process in
  a memory-safe language, we both reduce the risk of bugs in the first
  place, and make it possible to sandbox the vhost-user-scsi process,
  reducing the potential impact even if the process is compromised.
* Reusability - the plan is for this implementation to live with the
  rust-vmm project, where it can be used by QEMU but also by any other
  VMM that speaks vhost-user.
* Performance - living in a separate process might allow some
  optimizations that would be difficult to implement within QEMU proper.

My minimum goal is to implement enough of SCSI for the guest to be able
to mount a block device read-only; if I have time, I'll also implement
write support, add support for forwarding to an iSCSI target, and spend
time benchmarking and optimizing the new implementation.

We're currently in GSoC's "community bonding period", which I'll use
to get acquainted with the community and the rust-vmm codebase, and
nail down any toolchain issues. The coding period proper starts June 7
and continues for 10 weeks until August 16.

Finally, a bit about me: I'm an undergraduate computer science student
at the University of St Andrews, Scotland; physically, I'm at home in
the Pacific Northwest USA for the summer. I've been contributing to
open source for about a decade now.

Thanks for welcoming me into your community!
Gaelan Steele



RE: [PATCH Resend] block/quorum: Provide .bdrv_co_flush instead of .bdrv_co_flush_to_disk

2021-05-18 Thread Zhang, Chen



> -Original Message-
> From: Lukas Straub 
> Sent: Tuesday, May 18, 2021 7:42 PM
> To: qemu-devel 
> Cc: qemu-block ; Alberto Garcia
> ; Kevin Wolf ; Max Reitz
> ; Minghao Yuan ; Zhang, Chen
> ; Zhang Chen 
> Subject: [PATCH Resend] block/quorum: Provide .bdrv_co_flush instead
> of .bdrv_co_flush_to_disk
> 
> The quorum block driver uses a custom flush callback to handle the case
> when some children return io errors. In that case it still returns success if
> enough children are healthy.
> However, it provides it as the .bdrv_co_flush_to_disk callback, not
> as .bdrv_co_flush. This causes the block layer to do it's own generic flushing
> for the children instead, which doesn't handle errors properly.
> 
> Fix this by providing .bdrv_co_flush instead of .bdrv_co_flush_to_disk so the
> block layer uses the custom flush callback.
> 
> Signed-off-by: Lukas Straub 
> Reported-by: Minghao Yuan 

Tested-by: Zhang Chen 

Thanks
Chen

> ---
> 
> Resend: git send-mail put a newline in the Subject: header so the mailing list
> rejected it.
> 
>  block/quorum.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/block/quorum.c b/block/quorum.c index cfc1436abb..f2c0805000
> 100644
> --- a/block/quorum.c
> +++ b/block/quorum.c
> @@ -1279,7 +1279,7 @@ static BlockDriver bdrv_quorum = {
>  .bdrv_dirname   = quorum_dirname,
>  .bdrv_co_block_status   = quorum_co_block_status,
> 
> -.bdrv_co_flush_to_disk  = quorum_co_flush,
> +.bdrv_co_flush  = quorum_co_flush,
> 
>  .bdrv_getlength = quorum_getlength,
> 
> --
> 2.31.1



Re: [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5)

2021-05-18 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20210519001414.786439-1-vivek.kasire...@intel.com/



Hi,

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

Type: series
Message-id: 20210519001414.786439-1-vivek.kasire...@intel.com
Subject: [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature 
(v5)

=== 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/20210519001414.786439-1-vivek.kasire...@intel.com 
-> patchew/20210519001414.786439-1-vivek.kasire...@intel.com
Switched to a new branch 'test'
128a9d2 virtio-gpu: Update cursor data using blob
05f9981 virtio-gpu: Add virtio_gpu_set_scanout_blob
e3c9314 virtio-gpu: Factor out update scanout
dbc67f1 virtio-gpu: Add helpers to create and destroy dmabuf objects
9570991 ui/pixman: Add qemu_pixman_to_drm_format()
45da29f virtio-gpu: Add virtio_gpu_resource_create_blob
2f7f18a virtio-gpu: Add initial definitions for blob resources
7e99cae virtio-gpu: Refactor virtio_gpu_create_mapping_iov
321ce3a virtio-gpu: Refactor virtio_gpu_set_scanout
442ec4a virtio-gpu: Add virtio_gpu_find_check_resource
0d66622 virtio-gpu: Add udmabuf helpers
ae69eca headers: Add udmabuf.h
4d7d9e1 ui: Get the fd associated with udmabuf driver

=== OUTPUT BEGIN ===
1/13 Checking commit 4d7d9e1eb3e4 (ui: Get the fd associated with udmabuf 
driver)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#45: 
new file mode 100644

total: 0 errors, 1 warnings, 54 lines checked

Patch 1/13 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
2/13 Checking commit ae69eca3ab23 (headers: Add udmabuf.h)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#21: 
new file mode 100644

total: 0 errors, 1 warnings, 53 lines checked

Patch 2/13 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/13 Checking commit 0d66622c5482 (virtio-gpu: Add udmabuf helpers)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#42: 
new file mode 100644

total: 0 errors, 1 warnings, 212 lines checked

Patch 3/13 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
4/13 Checking commit 442ec4a6a78d (virtio-gpu: Add 
virtio_gpu_find_check_resource)
5/13 Checking commit 321ce3a6fd5a (virtio-gpu: Refactor virtio_gpu_set_scanout)
6/13 Checking commit 7e99cae8610f (virtio-gpu: Refactor 
virtio_gpu_create_mapping_iov)
7/13 Checking commit 2f7f18ac97ad (virtio-gpu: Add initial definitions for blob 
resources)
8/13 Checking commit 45da29ff2830 (virtio-gpu: Add 
virtio_gpu_resource_create_blob)
9/13 Checking commit 957099133aa4 (ui/pixman: Add qemu_pixman_to_drm_format())
10/13 Checking commit dbc67f12bb53 (virtio-gpu: Add helpers to create and 
destroy dmabuf objects)
ERROR: code indent should never use tabs
#80: FILE: hw/display/virtio-gpu-udmabuf.c:216:
+^I^I^Inew_primary->buf.width,$

total: 1 errors, 0 warnings, 117 lines checked

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

11/13 Checking commit e3c9314bc71a (virtio-gpu: Factor out update scanout)
12/13 Checking commit 05f9981acd94 (virtio-gpu: Add virtio_gpu_set_scanout_blob)
13/13 Checking commit 128a9d200bdc (virtio-gpu: Update cursor data using blob)
=== OUTPUT END ===

Test command exited with code: 1


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

[PATCH v5 13/13] virtio-gpu: Update cursor data using blob

2021-05-18 Thread Vivek Kasireddy
If a blob is available for the cursor, copy the data from the blob.

Based-on-patch-by: Gerd Hoffmann 
Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 hw/display/virtio-gpu.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 8366fa2245..d840fc195b 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -49,6 +49,7 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
 {
 struct virtio_gpu_simple_resource *res;
 uint32_t pixels;
+void *data;
 
 res = virtio_gpu_find_check_resource(g, resource_id, false,
  __func__, NULL);
@@ -56,14 +57,22 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
 return;
 }
 
-if (pixman_image_get_width(res->image)  != s->current_cursor->width ||
-pixman_image_get_height(res->image) != s->current_cursor->height) {
-return;
+if (res->blob_size) {
+if (res->blob_size < (s->current_cursor->width *
+  s->current_cursor->height * 4)) {
+return;
+}
+data = res->blob;
+} else {
+if (pixman_image_get_width(res->image)  != s->current_cursor->width ||
+pixman_image_get_height(res->image) != s->current_cursor->height) {
+return;
+}
+data = pixman_image_get_data(res->image);
 }
 
 pixels = s->current_cursor->width * s->current_cursor->height;
-memcpy(s->current_cursor->data,
-   pixman_image_get_data(res->image),
+memcpy(s->current_cursor->data, data,
pixels * sizeof(uint32_t));
 }
 
-- 
2.30.2




[PATCH v5 11/13] virtio-gpu: Factor out update scanout

2021-05-18 Thread Vivek Kasireddy
Creating a small helper function for updating the scanout
will be useful in the next patch where this needs to be
done early in do_set_scanout before returning.

Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 hw/display/virtio-gpu.c | 35 +++
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index e35c59f74f..9118924018 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -558,6 +558,28 @@ static void virtio_unref_resource(pixman_image_t *image, 
void *data)
 pixman_image_unref(data);
 }
 
+static void virtio_gpu_update_scanout(VirtIOGPU *g,
+  uint32_t scanout_id,
+  struct virtio_gpu_simple_resource *res,
+  struct virtio_gpu_rect *r)
+{
+struct virtio_gpu_simple_resource *ores;
+struct virtio_gpu_scanout *scanout;
+
+scanout = &g->parent_obj.scanout[scanout_id];
+ores = virtio_gpu_find_resource(g, scanout->resource_id);
+if (ores) {
+ores->scanout_bitmask &= ~(1 << scanout_id);
+}
+
+res->scanout_bitmask |= (1 << scanout_id);
+scanout->resource_id = res->resource_id;
+scanout->x = r->x;
+scanout->y = r->y;
+scanout->width = r->width;
+scanout->height = r->height;
+}
+
 static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
   uint32_t scanout_id,
   struct virtio_gpu_framebuffer *fb,
@@ -565,7 +587,6 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
   struct virtio_gpu_rect *r,
   uint32_t *error)
 {
-struct virtio_gpu_simple_resource *ores;
 struct virtio_gpu_scanout *scanout;
 uint8_t *data;
 
@@ -625,17 +646,7 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
 scanout->ds);
 }
 
-ores = virtio_gpu_find_resource(g, scanout->resource_id);
-if (ores) {
-ores->scanout_bitmask &= ~(1 << scanout_id);
-}
-
-res->scanout_bitmask |= (1 << scanout_id);
-scanout->resource_id = res->resource_id;
-scanout->x = r->x;
-scanout->y = r->y;
-scanout->width = r->width;
-scanout->height = r->height;
+virtio_gpu_update_scanout(g, scanout_id, res, r);
 }
 
 static void virtio_gpu_set_scanout(VirtIOGPU *g,
-- 
2.30.2




[PATCH v5 07/13] virtio-gpu: Add initial definitions for blob resources

2021-05-18 Thread Vivek Kasireddy
Add the property bit, configuration flag and other relevant
macros and definitions associated with this feature.

Based-on-patch-by: Gerd Hoffmann 
Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 hw/display/virtio-gpu-base.c   |  3 +++
 hw/display/virtio-gpu.c| 14 ++
 include/hw/virtio/virtio-gpu.h |  3 +++
 3 files changed, 20 insertions(+)

diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index afb3ee7d9a..dd294276cb 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -208,6 +208,9 @@ virtio_gpu_base_get_features(VirtIODevice *vdev, uint64_t 
features,
 if (virtio_gpu_edid_enabled(g->conf)) {
 features |= (1 << VIRTIO_GPU_F_EDID);
 }
+if (virtio_gpu_blob_enabled(g->conf)) {
+features |= (1 << VIRTIO_GPU_F_RESOURCE_BLOB);
+}
 
 return features;
 }
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 7a0db3a860..f77a7fc7dd 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1108,6 +1108,18 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error 
**errp)
 VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
 VirtIOGPU *g = VIRTIO_GPU(qdev);
 
+if (virtio_gpu_blob_enabled(g->parent_obj.conf)) {
+if (!virtio_gpu_have_udmabuf()) {
+error_setg(errp, "cannot enable blob resources without udmabuf");
+return;
+}
+
+if (virtio_gpu_virgl_enabled(g->parent_obj.conf)) {
+error_setg(errp, "blobs and virgl are not compatible (yet)");
+return;
+}
+}
+
 if (!virtio_gpu_base_device_realize(qdev,
 virtio_gpu_handle_ctrl_cb,
 virtio_gpu_handle_cursor_cb,
@@ -1201,6 +1213,8 @@ static Property virtio_gpu_properties[] = {
 VIRTIO_GPU_BASE_PROPERTIES(VirtIOGPU, parent_obj.conf),
 DEFINE_PROP_SIZE("max_hostmem", VirtIOGPU, conf_max_hostmem,
  256 * MiB),
+DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
+VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index dad9a1d221..66e7aaad0e 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -89,6 +89,7 @@ enum virtio_gpu_base_conf_flags {
 VIRTIO_GPU_FLAG_STATS_ENABLED,
 VIRTIO_GPU_FLAG_EDID_ENABLED,
 VIRTIO_GPU_FLAG_DMABUF_ENABLED,
+VIRTIO_GPU_FLAG_BLOB_ENABLED,
 };
 
 #define virtio_gpu_virgl_enabled(_cfg) \
@@ -99,6 +100,8 @@ enum virtio_gpu_base_conf_flags {
 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_EDID_ENABLED))
 #define virtio_gpu_dmabuf_enabled(_cfg) \
 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED))
+#define virtio_gpu_blob_enabled(_cfg) \
+(_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED))
 
 struct virtio_gpu_base_conf {
 uint32_t max_outputs;
-- 
2.30.2




[PATCH v5 06/13] virtio-gpu: Refactor virtio_gpu_create_mapping_iov

2021-05-18 Thread Vivek Kasireddy
Instead of passing the attach_backing object to extract nr_entries
and offset, explicitly pass these as arguments to this function.
This will be helpful when adding create_blob API.

Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 hw/display/virtio-gpu-virgl.c  |  3 ++-
 hw/display/virtio-gpu.c| 19 +--
 include/hw/virtio/virtio-gpu.h |  2 +-
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 72c14d9132..092c6dc380 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -289,7 +289,8 @@ static void virgl_resource_attach_backing(VirtIOGPU *g,
 VIRTIO_GPU_FILL_CMD(att_rb);
 trace_virtio_gpu_cmd_res_back_attach(att_rb.resource_id);
 
-ret = virtio_gpu_create_mapping_iov(g, &att_rb, cmd, NULL, &res_iovs, 
&res_niov);
+ret = virtio_gpu_create_mapping_iov(g, att_rb.nr_entries, sizeof(att_rb),
+cmd, NULL, &res_iovs, &res_niov);
 if (ret != 0) {
 cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
 return;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index fdcedfc61e..7a0db3a860 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -615,7 +615,7 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
 }
 
 int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
-  struct virtio_gpu_resource_attach_backing 
*ab,
+  uint32_t nr_entries, uint32_t offset,
   struct virtio_gpu_ctrl_command *cmd,
   uint64_t **addr, struct iovec **iov,
   uint32_t *niov)
@@ -624,17 +624,17 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
 size_t esize, s;
 int e, v;
 
-if (ab->nr_entries > 16384) {
+if (nr_entries > 16384) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "%s: nr_entries is too big (%d > 16384)\n",
-  __func__, ab->nr_entries);
+  __func__, nr_entries);
 return -1;
 }
 
-esize = sizeof(*ents) * ab->nr_entries;
+esize = sizeof(*ents) * nr_entries;
 ents = g_malloc(esize);
 s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
-   sizeof(*ab), ents, esize);
+   offset, ents, esize);
 if (s != esize) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "%s: command data size incorrect %zu vs %zu\n",
@@ -647,7 +647,7 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
 if (addr) {
 *addr = NULL;
 }
-for (e = 0, v = 0; e < ab->nr_entries; e++) {
+for (e = 0, v = 0; e < nr_entries; e++) {
 uint64_t a = le64_to_cpu(ents[e].addr);
 uint32_t l = le32_to_cpu(ents[e].length);
 hwaddr len;
@@ -659,8 +659,7 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
  a, &len, DMA_DIRECTION_TO_DEVICE);
 if (!map) {
 qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory 
for"
-  " resource %d element %d\n",
-  __func__, ab->resource_id, e);
+  " element %d\n", __func__, e);
 virtio_gpu_cleanup_mapping_iov(g, *iov, v);
 g_free(ents);
 *iov = NULL;
@@ -743,8 +742,8 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
 return;
 }
 
-ret = virtio_gpu_create_mapping_iov(g, &ab, cmd, &res->addrs,
-&res->iov, &res->iov_cnt);
+ret = virtio_gpu_create_mapping_iov(g, ab.nr_entries, sizeof(ab), cmd,
+&res->addrs, &res->iov, &res->iov_cnt);
 if (ret != 0) {
 cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
 return;
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index b83a91a67f..dad9a1d221 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -238,7 +238,7 @@ void virtio_gpu_get_display_info(VirtIOGPU *g,
 void virtio_gpu_get_edid(VirtIOGPU *g,
  struct virtio_gpu_ctrl_command *cmd);
 int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
-  struct virtio_gpu_resource_attach_backing 
*ab,
+  uint32_t nr_entries, uint32_t offset,
   struct virtio_gpu_ctrl_command *cmd,
   uint64_t **addr, struct iovec **iov,
   uint32_t *niov);
-- 
2.30.2




[PATCH v5 05/13] virtio-gpu: Refactor virtio_gpu_set_scanout

2021-05-18 Thread Vivek Kasireddy
Store the meta-data associated with a FB in a new object
(struct virtio_gpu_framebuffer) and pass the object to set_scanout.
Also move code in set_scanout into a do_set_scanout function.
This will be helpful when adding set_scanout_blob API.

Based-on-patch-by: Gerd Hoffmann 
Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 hw/display/virtio-gpu.c| 151 +++--
 include/hw/virtio/virtio-gpu.h |   8 ++
 2 files changed, 95 insertions(+), 64 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 7b5296f0d0..fdcedfc61e 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -500,95 +500,118 @@ static void virtio_unref_resource(pixman_image_t *image, 
void *data)
 pixman_image_unref(data);
 }
 
-static void virtio_gpu_set_scanout(VirtIOGPU *g,
-   struct virtio_gpu_ctrl_command *cmd)
+static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
+  uint32_t scanout_id,
+  struct virtio_gpu_framebuffer *fb,
+  struct virtio_gpu_simple_resource *res,
+  struct virtio_gpu_rect *r,
+  uint32_t *error)
 {
-struct virtio_gpu_simple_resource *res, *ores;
+struct virtio_gpu_simple_resource *ores;
 struct virtio_gpu_scanout *scanout;
-pixman_format_code_t format;
-uint32_t offset;
-int bpp;
-struct virtio_gpu_set_scanout ss;
+uint8_t *data;
 
-VIRTIO_GPU_FILL_CMD(ss);
-virtio_gpu_bswap_32(&ss, sizeof(ss));
-trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
- ss.r.width, ss.r.height, ss.r.x, ss.r.y);
-
-if (ss.scanout_id >= g->parent_obj.conf.max_outputs) {
+if (scanout_id >= g->parent_obj.conf.max_outputs) {
 qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
-  __func__, ss.scanout_id);
-cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
+  __func__, scanout_id);
+*error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
 return;
 }
-
-g->parent_obj.enable = 1;
-if (ss.resource_id == 0) {
-virtio_gpu_disable_scanout(g, ss.scanout_id);
-return;
-}
-
-/* create a surface for this scanout */
-res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
- __func__, &cmd->error);
-if (!res) {
-return;
-}
-
-if (ss.r.x > res->width ||
-ss.r.y > res->height ||
-ss.r.width < 16 ||
-ss.r.height < 16 ||
-ss.r.width > res->width ||
-ss.r.height > res->height ||
-ss.r.x + ss.r.width > res->width ||
-ss.r.y + ss.r.height > res->height) {
+scanout = &g->parent_obj.scanout[scanout_id];
+
+if (r->x > fb->width ||
+r->y > fb->height ||
+r->width < 16 ||
+r->height < 16 ||
+r->width > fb->width ||
+r->height > fb->height ||
+r->x + r->width > fb->width ||
+r->y + r->height > fb->height) {
 qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"
-  " resource %d, (%d,%d)+%d,%d vs %d %d\n",
-  __func__, ss.scanout_id, ss.resource_id, ss.r.x, ss.r.y,
-  ss.r.width, ss.r.height, res->width, res->height);
-cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+  " resource %d, rect (%d,%d)+%d,%d, fb %d %d\n",
+  __func__, scanout_id, res->resource_id,
+  r->x, r->y, r->width, r->height,
+  fb->width, fb->height);
+*error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
 return;
 }
 
-scanout = &g->parent_obj.scanout[ss.scanout_id];
+g->parent_obj.enable = 1;
+data = (uint8_t *)pixman_image_get_data(res->image);
 
-format = pixman_image_get_format(res->image);
-bpp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(format), 8);
-offset = (ss.r.x * bpp) + ss.r.y * pixman_image_get_stride(res->image);
-if (!scanout->ds || surface_data(scanout->ds)
-!= ((uint8_t *)pixman_image_get_data(res->image) + offset) ||
-scanout->width != ss.r.width ||
-scanout->height != ss.r.height) {
+/* create a surface for this scanout */
+if (!scanout->ds ||
+surface_data(scanout->ds) != data + fb->offset ||
+scanout->width != r->width ||
+scanout->height != r->height) {
 pixman_image_t *rect;
-void *ptr = (uint8_t *)pixman_image_get_data(res->image) + offset;
-rect = pixman_image_create_bits(format, ss.r.width, ss.r.height, ptr,
-pixman_image_get_stride(res->image));
-pixman_image_ref(res->image);
-pixman_image_set_destroy_function(rect, virtio_unref_resource,
-

[PATCH v5 03/13] virtio-gpu: Add udmabuf helpers

2021-05-18 Thread Vivek Kasireddy
Add helper functions to create a dmabuf for a resource and mmap it.
Also, introduce the fields blob and blob_size so that these helpers
can start to use them but the full picture will emerge only after
adding create_blob API in patch 8 of this series.

To be able to create a dmabuf using the udmabuf driver, Qemu needs
to be lauched with the memfd memory backend like this:

qemu-system-x86_64 -m 8192m -object memory-backend-memfd,id=mem1,size=8192M
-machine memory-backend=mem1

Based-on-patch-by: Gerd Hoffmann 
Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 hw/display/meson.build  |   2 +-
 hw/display/virtio-gpu-udmabuf.c | 181 
 include/hw/virtio/virtio-gpu.h  |  11 ++
 3 files changed, 193 insertions(+), 1 deletion(-)
 create mode 100644 hw/display/virtio-gpu-udmabuf.c

diff --git a/hw/display/meson.build b/hw/display/meson.build
index aaf797c5e9..224b33f2bb 100644
--- a/hw/display/meson.build
+++ b/hw/display/meson.build
@@ -55,7 +55,7 @@ softmmu_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true: 
files('ati.c', 'ati_2d
 if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
   virtio_gpu_ss = ss.source_set()
   virtio_gpu_ss.add(when: 'CONFIG_VIRTIO_GPU',
-if_true: [files('virtio-gpu-base.c', 'virtio-gpu.c'), 
pixman])
+if_true: [files('virtio-gpu-base.c', 'virtio-gpu.c', 
'virtio-gpu-udmabuf.c'), pixman])
   virtio_gpu_ss.add(when: 'CONFIG_VHOST_USER_GPU', if_true: 
files('vhost-user-gpu.c'))
   hw_display_modules += {'virtio-gpu': virtio_gpu_ss}
 
diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c
new file mode 100644
index 00..3f569ae9c8
--- /dev/null
+++ b/hw/display/virtio-gpu-udmabuf.c
@@ -0,0 +1,181 @@
+/*
+ * Virtio GPU Device
+ *
+ * Copyright Red Hat, Inc. 2013-2014
+ *
+ * Authors:
+ * Dave Airlie 
+ * Gerd Hoffmann 
+ *
+ * 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/units.h"
+#include "qemu-common.h"
+#include "qemu/iov.h"
+#include "ui/console.h"
+#include "hw/virtio/virtio-gpu.h"
+#include "hw/virtio/virtio-gpu-pixman.h"
+#include "trace.h"
+
+#ifdef CONFIG_LINUX
+
+#include "exec/ramblock.h"
+#include "sysemu/hostmem.h"
+#include 
+#include 
+#include 
+#include "standard-headers/linux/udmabuf.h"
+
+static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+struct udmabuf_create_list *list;
+RAMBlock *rb;
+ram_addr_t offset;
+int udmabuf, i;
+
+udmabuf = udmabuf_fd();
+if (udmabuf < 0) {
+return;
+}
+
+list = g_malloc0(sizeof(struct udmabuf_create_list) +
+ sizeof(struct udmabuf_create_item) * res->iov_cnt);
+
+for (i = 0; i < res->iov_cnt; i++) {
+rcu_read_lock();
+rb = qemu_ram_block_from_host(res->iov[i].iov_base, false, &offset);
+rcu_read_unlock();
+
+if (!rb || rb->fd < 0) {
+g_free(list);
+return;
+}
+
+list->list[i].memfd  = rb->fd;
+list->list[i].offset = offset;
+list->list[i].size   = res->iov[i].iov_len;
+}
+
+list->count = res->iov_cnt;
+list->flags = UDMABUF_FLAGS_CLOEXEC;
+
+res->dmabuf_fd = ioctl(udmabuf, UDMABUF_CREATE_LIST, list);
+if (res->dmabuf_fd < 0) {
+warn_report("%s: UDMABUF_CREATE_LIST: %s", __func__,
+strerror(errno));
+}
+g_free(list);
+}
+
+static void virtio_gpu_remap_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+res->remapped = mmap(NULL, res->blob_size, PROT_READ,
+ MAP_SHARED, res->dmabuf_fd, 0);
+if (res->remapped == MAP_FAILED) {
+warn_report("%s: dmabuf mmap failed: %s", __func__,
+strerror(errno));
+res->remapped = NULL;
+}
+}
+
+static void virtio_gpu_destroy_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+if (res->remapped) {
+munmap(res->remapped, res->blob_size);
+res->remapped = NULL;
+}
+if (res->dmabuf_fd >= 0) {
+close(res->dmabuf_fd);
+res->dmabuf_fd = -1;
+}
+}
+
+static int find_memory_backend_type(Object *obj, void *opaque)
+{
+bool *memfd_backend = opaque;
+int ret;
+
+if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
+HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+RAMBlock *rb = backend->mr.ram_block;
+
+if (rb && rb->fd > 0) {
+ret = fcntl(rb->fd, F_GET_SEALS);
+if (ret > 0) {
+*memfd_backend = true;
+}
+}
+}
+
+return 0;
+}
+
+bool virtio_gpu_have_udmabuf(void)
+{
+Object *memdev_root;
+int udmabuf;
+bool memfd_backend = false;
+
+udmabuf = udmabuf_fd();
+if (udmabuf < 0) {
+return false;
+}
+
+memdev_root = object_resolve_path("/objects", NULL);
+object_child_foreach(memdev_roo

[PATCH v5 12/13] virtio-gpu: Add virtio_gpu_set_scanout_blob

2021-05-18 Thread Vivek Kasireddy
This API allows Qemu to set the blob allocated by the Guest as
the scanout buffer. If Opengl support is available, then the
scanout buffer would be submitted as a dmabuf to the UI; if not,
a pixman image is created from the scanout buffer and is
submitted to the UI via the display surface.

Based-on-patch-by: Gerd Hoffmann 
Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 hw/display/trace-events  |   1 +
 hw/display/virtio-gpu.c  | 102 +--
 include/hw/virtio/virtio-gpu-bswap.h |   7 ++
 3 files changed, 103 insertions(+), 7 deletions(-)

diff --git a/hw/display/trace-events b/hw/display/trace-events
index f3f77b6984..e47264af5d 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -30,6 +30,7 @@ virtio_gpu_features(bool virgl) "virgl %d"
 virtio_gpu_cmd_get_display_info(void) ""
 virtio_gpu_cmd_get_edid(uint32_t scanout) "scanout %d"
 virtio_gpu_cmd_set_scanout(uint32_t id, uint32_t res, uint32_t w, uint32_t h, 
uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
+virtio_gpu_cmd_set_scanout_blob(uint32_t id, uint32_t res, uint32_t w, 
uint32_t h, uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
 virtio_gpu_cmd_res_create_2d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t 
h) "res 0x%x, fmt 0x%x, w %d, h %d"
 virtio_gpu_cmd_res_create_3d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t 
h, uint32_t d) "res 0x%x, fmt 0x%x, w %d, h %d, d %d"
 virtio_gpu_cmd_res_create_blob(uint32_t res, uint64_t size) "res 0x%x, size %" 
PRId64
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 9118924018..8366fa2245 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -405,7 +405,7 @@ static void virtio_gpu_resource_destroy(VirtIOGPU *g,
 }
 }
 
-pixman_image_unref(res->image);
+qemu_pixman_image_unref(res->image);
 virtio_gpu_cleanup_mapping(g, res);
 QTAILQ_REMOVE(&g->reslist, res, next);
 g->hostmem -= res->hostmem;
@@ -494,6 +494,7 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 {
 struct virtio_gpu_simple_resource *res;
 struct virtio_gpu_resource_flush rf;
+struct virtio_gpu_scanout *scanout;
 pixman_region16_t flush_region;
 int i;
 
@@ -504,16 +505,29 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 
 res = virtio_gpu_find_check_resource(g, rf.resource_id, false,
  __func__, &cmd->error);
-if (!res || res->blob) {
+if (!res) {
 return;
 }
 
-if (rf.r.x > res->width ||
+if (res->blob) {
+for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
+scanout = &g->parent_obj.scanout[i];
+if (scanout->resource_id == res->resource_id &&
+console_has_gl(scanout->con)) {
+dpy_gl_update(scanout->con, 0, 0, scanout->width,
+  scanout->height);
+return;
+}
+}
+}
+
+if (!res->blob &&
+(rf.r.x > res->width ||
 rf.r.y > res->height ||
 rf.r.width > res->width ||
 rf.r.height > res->height ||
 rf.r.x + rf.r.width > res->width ||
-rf.r.y + rf.r.height > res->height) {
+rf.r.y + rf.r.height > res->height)) {
 qemu_log_mask(LOG_GUEST_ERROR, "%s: flush bounds outside resource"
   " bounds for resource %d: %d %d %d %d vs %d %d\n",
   __func__, rf.resource_id, rf.r.x, rf.r.y,
@@ -525,7 +539,6 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 pixman_region_init_rect(&flush_region,
 rf.r.x, rf.r.y, rf.r.width, rf.r.height);
 for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
-struct virtio_gpu_scanout *scanout;
 pixman_region16_t region, finalregion;
 pixman_box16_t *extents;
 
@@ -616,10 +629,23 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
 }
 
 g->parent_obj.enable = 1;
-data = (uint8_t *)pixman_image_get_data(res->image);
+
+if (res->blob) {
+if (console_has_gl(scanout->con)) {
+if (!virtio_gpu_update_dmabuf(g, scanout_id, res, fb)) {
+virtio_gpu_update_scanout(g, scanout_id, res, r);
+return;
+}
+}
+
+data = res->blob;
+} else {
+data = (uint8_t *)pixman_image_get_data(res->image);
+}
 
 /* create a surface for this scanout */
-if (!scanout->ds ||
+if ((res->blob && !console_has_gl(scanout->con)) ||
+!scanout->ds ||
 surface_data(scanout->ds) != data + fb->offset ||
 scanout->width != r->width ||
 scanout->height != r->height) {
@@ -683,6 +709,61 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
   &fb, res, &ss.r, &cmd->error);
 }
 
+static void virtio_gpu_set_scanout_blob(VirtIOGPU *g,
+struct virtio_gpu_ctrl_command *cmd)
+{
+

[PATCH v5 02/13] headers: Add udmabuf.h

2021-05-18 Thread Vivek Kasireddy
This adds udmabuf header to standard headers so that the
relevant udmabuf objects can be accessed in subsequent
patches.

Based-on-patch-by: Gerd Hoffmann 
Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 include/standard-headers/linux/udmabuf.h | 32 
 scripts/update-linux-headers.sh  |  3 +++
 2 files changed, 35 insertions(+)
 create mode 100644 include/standard-headers/linux/udmabuf.h

diff --git a/include/standard-headers/linux/udmabuf.h 
b/include/standard-headers/linux/udmabuf.h
new file mode 100644
index 00..e19eb5b5ce
--- /dev/null
+++ b/include/standard-headers/linux/udmabuf.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_UDMABUF_H
+#define _LINUX_UDMABUF_H
+
+#include "standard-headers/linux/types.h"
+
+#define UDMABUF_FLAGS_CLOEXEC  0x01
+
+struct udmabuf_create {
+   uint32_t memfd;
+   uint32_t flags;
+   uint64_t offset;
+   uint64_t size;
+};
+
+struct udmabuf_create_item {
+   uint32_t memfd;
+   uint32_t __pad;
+   uint64_t offset;
+   uint64_t size;
+};
+
+struct udmabuf_create_list {
+   uint32_t flags;
+   uint32_t count;
+   struct udmabuf_create_item list[];
+};
+
+#define UDMABUF_CREATE   _IOW('u', 0x42, struct udmabuf_create)
+#define UDMABUF_CREATE_LIST  _IOW('u', 0x43, struct udmabuf_create_list)
+
+#endif /* _LINUX_UDMABUF_H */
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 1050e36169..fea4d6eb65 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -34,6 +34,7 @@ cp_portable() {
 if
 grep '#include' "$f" | grep -v -e 'linux/virtio' \
  -e 'linux/types' \
+ -e 'linux/ioctl' \
  -e 'stdint' \
  -e 'linux/if_ether' \
  -e 'input-event-codes' \
@@ -66,6 +67,7 @@ cp_portable() {
 -e 's/__BITS_PER_LONG/HOST_LONG_BITS/' \
 -e '/\"drm.h\"/d' \
 -e '/sys\/ioctl.h/d' \
+-e '/linux\/ioctl.h/d' \
 -e 's/SW_MAX/SW_MAX_/' \
 -e 's/atomic_t/int/' \
 -e 's/__kernel_long_t/long/' \
@@ -190,6 +192,7 @@ for i in "$tmpdir"/include/linux/*virtio*.h \
  "$tmpdir/include/linux/fuse.h" \
  "$tmpdir/include/linux/input.h" \
  "$tmpdir/include/linux/input-event-codes.h" \
+ "$tmpdir/include/linux/udmabuf.h" \
  "$tmpdir/include/linux/pci_regs.h" \
  "$tmpdir/include/linux/ethtool.h" \
  "$tmpdir/include/linux/const.h" \
-- 
2.30.2




[PATCH v5 10/13] virtio-gpu: Add helpers to create and destroy dmabuf objects

2021-05-18 Thread Vivek Kasireddy
These helpers can be useful for creating dmabuf objects from blobs
and submitting them to the UI.

Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 hw/display/virtio-gpu-udmabuf.c | 74 +
 include/hw/virtio/virtio-gpu.h  | 15 +++
 2 files changed, 89 insertions(+)

diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c
index 3f569ae9c8..d486419a26 100644
--- a/hw/display/virtio-gpu-udmabuf.c
+++ b/hw/display/virtio-gpu-udmabuf.c
@@ -159,6 +159,71 @@ void virtio_gpu_fini_udmabuf(struct 
virtio_gpu_simple_resource *res)
 }
 }
 
+static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDMABuf *dmabuf)
+{
+struct virtio_gpu_scanout *scanout;
+
+scanout = &g->parent_obj.scanout[dmabuf->scanout_id];
+dpy_gl_release_dmabuf(scanout->con, &dmabuf->buf);
+QTAILQ_REMOVE(&g->dmabuf.bufs, dmabuf, next);
+g_free(dmabuf);
+}
+
+static VGPUDMABuf
+*virtio_gpu_create_dmabuf(VirtIOGPU *g,
+  uint32_t scanout_id,
+  struct virtio_gpu_simple_resource *res,
+  struct virtio_gpu_framebuffer *fb)
+{
+VGPUDMABuf *dmabuf;
+
+if (res->dmabuf_fd < 0) {
+return NULL;
+}
+
+dmabuf = g_new0(VGPUDMABuf, 1);
+dmabuf->buf.width = fb->width;
+dmabuf->buf.height = fb->height;
+dmabuf->buf.stride = fb->stride;
+dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format);
+dmabuf->buf.fd = res->dmabuf_fd;
+
+dmabuf->scanout_id = scanout_id;
+QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next);
+
+return dmabuf;
+}
+
+int virtio_gpu_update_dmabuf(VirtIOGPU *g,
+ uint32_t scanout_id,
+ struct virtio_gpu_simple_resource *res,
+ struct virtio_gpu_framebuffer *fb)
+{
+struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id];
+VGPUDMABuf *new_primary, *old_primary;
+
+new_primary = virtio_gpu_create_dmabuf(g, scanout_id, res, fb);
+if (!new_primary) {
+return -EINVAL;
+}
+
+if (g->dmabuf.primary) {
+old_primary = g->dmabuf.primary;
+}
+
+g->dmabuf.primary = new_primary;
+qemu_console_resize(scanout->con,
+   new_primary->buf.width,
+new_primary->buf.height);
+dpy_gl_scanout_dmabuf(scanout->con, &new_primary->buf);
+
+if (old_primary) {
+virtio_gpu_free_dmabuf(g, old_primary);
+}
+
+return 0;
+}
+
 #else
 
 bool virtio_gpu_have_udmabuf(void)
@@ -178,4 +243,13 @@ void virtio_gpu_fini_udmabuf(struct 
virtio_gpu_simple_resource *res)
 /* nothing (stub) */
 }
 
+int virtio_gpu_update_dmabuf(VirtIOGPU *g,
+ uint32_t scanout_id,
+ struct virtio_gpu_simple_resource *res,
+ struct virtio_gpu_framebuffer *fb)
+{
+/* nothing (stub) */
+return 0;
+}
+
 #endif
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 66e7aaad0e..bcf54d970f 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -150,6 +150,12 @@ struct VirtIOGPUBaseClass {
 DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1024), \
 DEFINE_PROP_UINT32("yres", _state, _conf.yres, 768)
 
+typedef struct VGPUDMABuf {
+QemuDmaBuf buf;
+uint32_t scanout_id;
+QTAILQ_ENTRY(VGPUDMABuf) next;
+} VGPUDMABuf;
+
 struct VirtIOGPU {
 VirtIOGPUBase parent_obj;
 
@@ -178,6 +184,11 @@ struct VirtIOGPU {
 uint32_t req_3d;
 uint32_t bytes_3d;
 } stats;
+
+struct {
+QTAILQ_HEAD(, VGPUDMABuf) bufs;
+VGPUDMABuf *primary;
+} dmabuf;
 };
 
 struct VirtIOGPUClass {
@@ -259,6 +270,10 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
 bool virtio_gpu_have_udmabuf(void);
 void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);
 void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res);
+int virtio_gpu_update_dmabuf(VirtIOGPU *g,
+ uint32_t scanout_id,
+ struct virtio_gpu_simple_resource *res,
+ struct virtio_gpu_framebuffer *fb);
 
 /* virtio-gpu-3d.c */
 void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
-- 
2.30.2




[PATCH v5 09/13] ui/pixman: Add qemu_pixman_to_drm_format()

2021-05-18 Thread Vivek Kasireddy
This new function to get the drm_format associated with a pixman
format will be useful while creating a dmabuf.

Based-on-patch-by: Gerd Hoffmann 
Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 include/ui/qemu-pixman.h |  1 +
 ui/qemu-pixman.c | 35 ---
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index 87737a6f16..806ddcd7cd 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -62,6 +62,7 @@ typedef struct PixelFormat {
 PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format);
 pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian);
 pixman_format_code_t qemu_drm_format_to_pixman(uint32_t drm_format);
+uint32_t qemu_pixman_to_drm_format(pixman_format_code_t pixman);
 int qemu_pixman_get_type(int rshift, int gshift, int bshift);
 pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf);
 bool qemu_pixman_check_format(DisplayChangeListener *dcl,
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index 85f2945e88..3ab7e2e958 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -89,21 +89,34 @@ pixman_format_code_t qemu_default_pixman_format(int bpp, 
bool native_endian)
 }
 
 /* Note: drm is little endian, pixman is native endian */
+static const struct {
+uint32_t drm_format;
+pixman_format_code_t pixman_format;
+} drm_format_pixman_map[] = {
+{ DRM_FORMAT_RGB888,   PIXMAN_LE_r8g8b8   },
+{ DRM_FORMAT_ARGB, PIXMAN_LE_a8r8g8b8 },
+{ DRM_FORMAT_XRGB, PIXMAN_LE_x8r8g8b8 }
+};
+
 pixman_format_code_t qemu_drm_format_to_pixman(uint32_t drm_format)
 {
-static const struct {
-uint32_t drm_format;
-pixman_format_code_t pixman;
-} map[] = {
-{ DRM_FORMAT_RGB888,   PIXMAN_LE_r8g8b8   },
-{ DRM_FORMAT_ARGB, PIXMAN_LE_a8r8g8b8 },
-{ DRM_FORMAT_XRGB, PIXMAN_LE_x8r8g8b8 }
-};
 int i;
 
-for (i = 0; i < ARRAY_SIZE(map); i++) {
-if (drm_format == map[i].drm_format) {
-return map[i].pixman;
+for (i = 0; i < ARRAY_SIZE(drm_format_pixman_map); i++) {
+if (drm_format == drm_format_pixman_map[i].drm_format) {
+return drm_format_pixman_map[i].pixman_format;
+}
+}
+return 0;
+}
+
+uint32_t qemu_pixman_to_drm_format(pixman_format_code_t pixman_format)
+{
+int i;
+
+for (i = 0; i < ARRAY_SIZE(drm_format_pixman_map); i++) {
+if (pixman_format == drm_format_pixman_map[i].pixman_format) {
+return drm_format_pixman_map[i].drm_format;
 }
 }
 return 0;
-- 
2.30.2




[PATCH v5 01/13] ui: Get the fd associated with udmabuf driver

2021-05-18 Thread Vivek Kasireddy
Try to open the udmabuf dev node for the first time or return the
fd if the device was previously opened.

Based-on-patch-by: Gerd Hoffmann 
Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 include/ui/console.h |  3 +++
 ui/meson.build   |  1 +
 ui/udmabuf.c | 40 
 3 files changed, 44 insertions(+)
 create mode 100644 ui/udmabuf.c

diff --git a/include/ui/console.h b/include/ui/console.h
index ca3c7af6a6..b30b63976a 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -471,4 +471,7 @@ bool vnc_display_reload_certs(const char *id,  Error 
**errp);
 /* input.c */
 int index_from_key(const char *key, size_t key_length);
 
+/* udmabuf.c */
+int udmabuf_fd(void);
+
 #endif
diff --git a/ui/meson.build b/ui/meson.build
index e8d3ff41b9..7a709ff548 100644
--- a/ui/meson.build
+++ b/ui/meson.build
@@ -11,6 +11,7 @@ softmmu_ss.add(files(
   'kbd-state.c',
   'keymaps.c',
   'qemu-pixman.c',
+  'udmabuf.c',
 ))
 softmmu_ss.add([spice_headers, files('spice-module.c')])
 
diff --git a/ui/udmabuf.c b/ui/udmabuf.c
new file mode 100644
index 00..e6234fd86f
--- /dev/null
+++ b/ui/udmabuf.c
@@ -0,0 +1,40 @@
+/*
+ * udmabuf helper functions.
+ *
+ * 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 "qapi/error.h"
+#include "ui/console.h"
+
+#ifdef CONFIG_LINUX
+
+#include 
+#include 
+
+int udmabuf_fd(void)
+{
+static bool first = true;
+static int udmabuf;
+
+if (!first) {
+return udmabuf;
+}
+first = false;
+
+udmabuf = open("/dev/udmabuf", O_RDWR);
+if (udmabuf < 0) {
+warn_report("open /dev/udmabuf: %s", strerror(errno));
+}
+return udmabuf;
+}
+
+#else
+
+int udmabuf_fd(void)
+{
+return -1;
+}
+
+#endif
-- 
2.30.2




[PATCH v5 08/13] virtio-gpu: Add virtio_gpu_resource_create_blob

2021-05-18 Thread Vivek Kasireddy
This API allows Qemu to register the blob allocated by the Guest
as a new resource and map its backing storage.

Based-on-patch-by: Gerd Hoffmann 
Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 hw/display/trace-events  |  1 +
 hw/display/virtio-gpu.c  | 75 ++--
 include/hw/virtio/virtio-gpu-bswap.h |  9 
 3 files changed, 82 insertions(+), 3 deletions(-)

diff --git a/hw/display/trace-events b/hw/display/trace-events
index 9fccca18a1..f3f77b6984 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -32,6 +32,7 @@ virtio_gpu_cmd_get_edid(uint32_t scanout) "scanout %d"
 virtio_gpu_cmd_set_scanout(uint32_t id, uint32_t res, uint32_t w, uint32_t h, 
uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
 virtio_gpu_cmd_res_create_2d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t 
h) "res 0x%x, fmt 0x%x, w %d, h %d"
 virtio_gpu_cmd_res_create_3d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t 
h, uint32_t d) "res 0x%x, fmt 0x%x, w %d, h %d, d %d"
+virtio_gpu_cmd_res_create_blob(uint32_t res, uint64_t size) "res 0x%x, size %" 
PRId64
 virtio_gpu_cmd_res_unref(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_back_attach(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_back_detach(uint32_t res) "res 0x%x"
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index f77a7fc7dd..e35c59f74f 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -137,7 +137,7 @@ virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t 
resource_id,
 }
 
 if (require_backing) {
-if (!res->iov || !res->image) {
+if (!res->iov || (!res->image && !res->blob)) {
 qemu_log_mask(LOG_GUEST_ERROR, "%s: no backing storage %d\n",
   caller, resource_id);
 if (error) {
@@ -313,6 +313,64 @@ static void virtio_gpu_resource_create_2d(VirtIOGPU *g,
 g->hostmem += res->hostmem;
 }
 
+static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
+struct virtio_gpu_ctrl_command 
*cmd)
+{
+struct virtio_gpu_simple_resource *res;
+struct virtio_gpu_resource_create_blob cblob;
+int ret;
+
+VIRTIO_GPU_FILL_CMD(cblob);
+virtio_gpu_create_blob_bswap(&cblob);
+trace_virtio_gpu_cmd_res_create_blob(cblob.resource_id, cblob.size);
+
+if (cblob.resource_id == 0) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
+  __func__);
+cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+return;
+}
+
+res = virtio_gpu_find_resource(g, cblob.resource_id);
+if (res) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
+  __func__, cblob.resource_id);
+cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+return;
+}
+
+res = g_new0(struct virtio_gpu_simple_resource, 1);
+res->resource_id = cblob.resource_id;
+res->blob_size = cblob.size;
+
+if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_GUEST &&
+cblob.blob_flags != VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid memory type\n",
+  __func__);
+cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+g_free(res);
+return;
+}
+
+if (res->iov) {
+cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+return;
+}
+
+ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
+cmd, &res->addrs, &res->iov,
+&res->iov_cnt);
+if (ret != 0) {
+cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+return;
+}
+
+res->iov_cnt = cblob.nr_entries;
+virtio_gpu_init_udmabuf(res);
+
+QTAILQ_INSERT_HEAD(&g->reslist, res, next);
+}
+
 static void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id)
 {
 struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id];
@@ -390,7 +448,7 @@ static void virtio_gpu_transfer_to_host_2d(VirtIOGPU *g,
 
 res = virtio_gpu_find_check_resource(g, t2d.resource_id, true,
  __func__, &cmd->error);
-if (!res) {
+if (!res || res->blob) {
 return;
 }
 
@@ -446,7 +504,7 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 
 res = virtio_gpu_find_check_resource(g, rf.resource_id, false,
  __func__, &cmd->error);
-if (!res) {
+if (!res || res->blob) {
 return;
 }
 
@@ -715,6 +773,10 @@ static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
 res->iov_cnt = 0;
 g_free(res->addrs);
 res->addrs = NULL;
+
+if (res->blob) {
+virtio_gpu_fini_udmabuf(res);
+}
 }
 
 static void
@@ -785,6 +847,13 @@ void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
 case VIRTIO_GPU_CMD_RESOURCE_CREATE_2D:
 virtio_gpu_resource_create_2d(g, cmd);
 

Re: [PATCH v3] target/xtensa: clean up unaligned access

2021-05-18 Thread Max Filippov
Hi Richard,

On Tue, May 18, 2021 at 1:11 PM Richard Henderson
 wrote:
> On 5/17/21 3:52 PM, Max Filippov wrote:
> > @@ -1784,10 +1770,11 @@ static void translate_l32e(DisasContext *dc, const 
> > OpcodeArg arg[],
> >  const uint32_t par[])
> >   {
> >   TCGv_i32 addr = tcg_temp_new_i32();
> > +MemOp al;
> >
> >   tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
> > -gen_load_store_alignment(dc, 2, addr, false);
> > -tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->ring, MO_TEUL);
> > +al = gen_load_store_alignment(dc, 2, addr, false);
> > +tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->ring, MO_TEUL | al);
>
> You're duplicating the information about the size of the alignment.
>
> I think it would be better to pass the partial MemOp into
> get_load_store_alignment and return the complete MemOp.  E.g.:

That indeed looks better. Let me make another version of this patch.
Thanks for taking a look!

-- 
Thanks.
-- Max



[PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5)

2021-05-18 Thread Vivek Kasireddy
Enabling this feature would eliminate data copies from the resource
object in the Guest to the shadow resource in Qemu. This patch series
however adds support only for Blobs of type
VIRTIO_GPU_BLOB_MEM_GUEST with property VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE.

Most of the patches in this series are a rebased, refactored and bugfixed 
versions of Gerd Hoffmann's patches located here:
https://gitlab.freedesktop.org/virgl/qemu/-/commits/virtio-gpu-next

v2:
- Moved dpy_gl_update from set_scanout to resource_flush
- Dropped the modifier
- Rebase and other minor refactoring

v3:
- Rebased on top of Gerd's virgl device split series
- Split the udmabuf helpers patch from the previous 
  version into two (Gerd)
- Added explicit flush feature (last 7 patches)

v4 (Gerd):
- Dropped explicit flush feature patches from the series
- Slightly refactored udmabuf helpers patch (#3) to introduce
  and use blob and blob_size fields
- Fixed indentation issues and made other small changes in
  set_scanout_blob patch (#12)

v5:
- Rebase (only #6 - Refactor virtio_gpu_create_mapping_iov)

Cc: Gerd Hoffmann 

Vivek Kasireddy (13):
  ui: Get the fd associated with udmabuf driver
  headers: Add udmabuf.h
  virtio-gpu: Add udmabuf helpers
  virtio-gpu: Add virtio_gpu_find_check_resource
  virtio-gpu: Refactor virtio_gpu_set_scanout
  virtio-gpu: Refactor virtio_gpu_create_mapping_iov
  virtio-gpu: Add initial definitions for blob resources
  virtio-gpu: Add virtio_gpu_resource_create_blob
  ui/pixman: Add qemu_pixman_to_drm_format()
  virtio-gpu: Add helpers to create and destroy dmabuf objects
  virtio-gpu: Factor out update scanout
  virtio-gpu: Add virtio_gpu_set_scanout_blob
  virtio-gpu: Update cursor data using blob

 hw/display/meson.build   |   2 +-
 hw/display/trace-events  |   2 +
 hw/display/virtio-gpu-base.c |   3 +
 hw/display/virtio-gpu-udmabuf.c  | 255 +
 hw/display/virtio-gpu-virgl.c|   3 +-
 hw/display/virtio-gpu.c  | 433 ++-
 include/hw/virtio/virtio-gpu-bswap.h |  16 +
 include/hw/virtio/virtio-gpu.h   |  39 +-
 include/standard-headers/linux/udmabuf.h |  32 ++
 include/ui/console.h |   3 +
 include/ui/qemu-pixman.h |   1 +
 scripts/update-linux-headers.sh  |   3 +
 ui/meson.build   |   1 +
 ui/qemu-pixman.c |  35 +-
 ui/udmabuf.c |  40 +++
 15 files changed, 758 insertions(+), 110 deletions(-)
 create mode 100644 hw/display/virtio-gpu-udmabuf.c
 create mode 100644 include/standard-headers/linux/udmabuf.h
 create mode 100644 ui/udmabuf.c

-- 
2.30.2




[PATCH v5 04/13] virtio-gpu: Add virtio_gpu_find_check_resource

2021-05-18 Thread Vivek Kasireddy
Move finding the resource and validating its backing storage into one
function.

Based-on-patch-by: Gerd Hoffmann 
Cc: Gerd Hoffmann 
Signed-off-by: Vivek Kasireddy 
---
 hw/display/virtio-gpu.c | 66 +
 1 file changed, 47 insertions(+), 19 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index db56f0454a..7b5296f0d0 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -35,6 +35,10 @@
 
 static struct virtio_gpu_simple_resource*
 virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
+static struct virtio_gpu_simple_resource *
+virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
+   bool require_backing,
+   const char *caller, uint32_t *error);
 
 static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
struct virtio_gpu_simple_resource *res);
@@ -46,7 +50,8 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
 struct virtio_gpu_simple_resource *res;
 uint32_t pixels;
 
-res = virtio_gpu_find_resource(g, resource_id);
+res = virtio_gpu_find_check_resource(g, resource_id, false,
+ __func__, NULL);
 if (!res) {
 return;
 }
@@ -114,6 +119,37 @@ virtio_gpu_find_resource(VirtIOGPU *g, uint32_t 
resource_id)
 return NULL;
 }
 
+static struct virtio_gpu_simple_resource *
+virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
+   bool require_backing,
+   const char *caller, uint32_t *error)
+{
+struct virtio_gpu_simple_resource *res;
+
+res = virtio_gpu_find_resource(g, resource_id);
+if (!res) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid resource specified %d\n",
+  caller, resource_id);
+if (error) {
+*error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+}
+return NULL;
+}
+
+if (require_backing) {
+if (!res->iov || !res->image) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: no backing storage %d\n",
+  caller, resource_id);
+if (error) {
+*error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+}
+return NULL;
+}
+}
+
+return res;
+}
+
 void virtio_gpu_ctrl_response(VirtIOGPU *g,
   struct virtio_gpu_ctrl_command *cmd,
   struct virtio_gpu_ctrl_hdr *resp,
@@ -352,11 +388,9 @@ static void virtio_gpu_transfer_to_host_2d(VirtIOGPU *g,
 virtio_gpu_t2d_bswap(&t2d);
 trace_virtio_gpu_cmd_res_xfer_toh_2d(t2d.resource_id);
 
-res = virtio_gpu_find_resource(g, t2d.resource_id);
-if (!res || !res->iov) {
-qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-  __func__, t2d.resource_id);
-cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+res = virtio_gpu_find_check_resource(g, t2d.resource_id, true,
+ __func__, &cmd->error);
+if (!res) {
 return;
 }
 
@@ -410,11 +444,9 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 trace_virtio_gpu_cmd_res_flush(rf.resource_id,
rf.r.width, rf.r.height, rf.r.x, rf.r.y);
 
-res = virtio_gpu_find_resource(g, rf.resource_id);
+res = virtio_gpu_find_check_resource(g, rf.resource_id, false,
+ __func__, &cmd->error);
 if (!res) {
-qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-  __func__, rf.resource_id);
-cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
 return;
 }
 
@@ -497,11 +529,9 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
 }
 
 /* create a surface for this scanout */
-res = virtio_gpu_find_resource(g, ss.resource_id);
+res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
+ __func__, &cmd->error);
 if (!res) {
-qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-  __func__, ss.resource_id);
-cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
 return;
 }
 
@@ -709,11 +739,9 @@ virtio_gpu_resource_detach_backing(VirtIOGPU *g,
 virtio_gpu_bswap_32(&detach, sizeof(detach));
 trace_virtio_gpu_cmd_res_back_detach(detach.resource_id);
 
-res = virtio_gpu_find_resource(g, detach.resource_id);
-if (!res || !res->iov) {
-qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-  __func__, detach.resource_id);
-cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+res = virtio_gpu_find_check_resource(g, detach.resource_id, true,
+ __func__, &cmd->error);
+if (!res) {
 ret

[PATCH 3/3] sensor: Move hardware sensors from misc to a sensor directory

2021-05-18 Thread minyard
From: Corey Minyard 

Lots of this are expected to be coming in, create a directory for them.

Also move the tmp105.h file into the include directory where it
should be.

Cc: Cédric Le Goater 
Cc: Peter Maydell 
Cc: Andrew Jeffery 
Cc: Joel Stanley 
Cc: Andrzej Zaborowski 
Cc: qemu-...@nongnu.org
Signed-off-by: Corey Minyard 
---
 hw/Kconfig |  1 +
 hw/arm/aspeed.c|  2 +-
 hw/arm/nseries.c   |  2 +-
 hw/meson.build |  1 +
 hw/misc/Kconfig| 12 
 hw/misc/meson.build|  3 ---
 hw/sensor/Kconfig  | 11 +++
 hw/{misc => sensor}/emc141x.c  |  2 +-
 hw/sensor/meson.build  |  3 +++
 hw/{misc => sensor}/tmp105.c   |  2 +-
 hw/{misc => sensor}/tmp421.c   |  0
 include/hw/{misc => sensor}/emc141x_regs.h |  0
 {hw/misc => include/hw/sensor}/tmp105.h|  2 +-
 include/hw/{misc => sensor}/tmp105_regs.h  |  0
 tests/qtest/emc141x-test.c |  2 +-
 tests/qtest/npcm7xx_smbus-test.c   |  2 +-
 tests/qtest/tmp105-test.c  |  2 +-
 17 files changed, 24 insertions(+), 23 deletions(-)
 create mode 100644 hw/sensor/Kconfig
 rename hw/{misc => sensor}/emc141x.c (99%)
 create mode 100644 hw/sensor/meson.build
 rename hw/{misc => sensor}/tmp105.c (99%)
 rename hw/{misc => sensor}/tmp421.c (100%)
 rename include/hw/{misc => sensor}/emc141x_regs.h (100%)
 rename {hw/misc => include/hw/sensor}/tmp105.h (97%)
 rename include/hw/{misc => sensor}/tmp105_regs.h (100%)

diff --git a/hw/Kconfig b/hw/Kconfig
index 805860f564..8cb7664d70 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -32,6 +32,7 @@ source remote/Kconfig
 source rtc/Kconfig
 source scsi/Kconfig
 source sd/Kconfig
+source sensor/Kconfig
 source smbios/Kconfig
 source ssi/Kconfig
 source timer/Kconfig
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 3fe6c55744..272b17f999 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -16,7 +16,7 @@
 #include "hw/arm/aspeed_soc.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
-#include "hw/misc/tmp105.h"
+#include "hw/sensor/tmp105.h"
 #include "hw/misc/led.h"
 #include "hw/qdev-properties.h"
 #include "sysemu/block-backend.h"
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 0aefa5d0f3..a10d8f53b5 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -36,7 +36,7 @@
 #include "hw/display/blizzard.h"
 #include "hw/input/tsc2xxx.h"
 #include "hw/misc/cbus.h"
-#include "hw/misc/tmp105.h"
+#include "hw/sensor/tmp105.h"
 #include "hw/qdev-properties.h"
 #include "hw/block/flash.h"
 #include "hw/hw.h"
diff --git a/hw/meson.build b/hw/meson.build
index ba0601e36e..b3366c888e 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -31,6 +31,7 @@ subdir('rdma')
 subdir('rtc')
 subdir('scsi')
 subdir('sd')
+subdir('sensor')
 subdir('smbios')
 subdir('ssi')
 subdir('timer')
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 996d45aff5..507058d8bf 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -11,18 +11,6 @@ config ARMSSE_MHU
 config ARMSSE_CPU_PWRCTRL
 bool
 
-config TMP105
-bool
-depends on I2C
-
-config TMP421
-bool
-depends on I2C
-
-config EMC141X
-bool
-depends on I2C
-
 config ISA_DEBUG
 bool
 depends on ISA_BUS
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index b0a8ee8994..046c7e0c72 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -6,9 +6,6 @@ softmmu_ss.add(when: 'CONFIG_ISA_TESTDEV', if_true: 
files('pc-testdev.c'))
 softmmu_ss.add(when: 'CONFIG_PCA9552', if_true: files('pca9552.c'))
 softmmu_ss.add(when: 'CONFIG_PCI_TESTDEV', if_true: files('pci-testdev.c'))
 softmmu_ss.add(when: 'CONFIG_SGA', if_true: files('sga.c'))
-softmmu_ss.add(when: 'CONFIG_TMP105', if_true: files('tmp105.c'))
-softmmu_ss.add(when: 'CONFIG_TMP421', if_true: files('tmp421.c'))
-softmmu_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
 softmmu_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c'))
 softmmu_ss.add(when: 'CONFIG_EMPTY_SLOT', if_true: files('empty_slot.c'))
 softmmu_ss.add(when: 'CONFIG_LED', if_true: files('led.c'))
diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
new file mode 100644
index 00..097cb8f11e
--- /dev/null
+++ b/hw/sensor/Kconfig
@@ -0,0 +1,11 @@
+config TMP105
+bool
+depends on I2C
+
+config TMP421
+bool
+depends on I2C
+
+config EMC141X
+bool
+depends on I2C
diff --git a/hw/misc/emc141x.c b/hw/sensor/emc141x.c
similarity index 99%
rename from hw/misc/emc141x.c
rename to hw/sensor/emc141x.c
index f7c53d48a4..7ce8f4e979 100644
--- a/hw/misc/emc141x.c
+++ b/hw/sensor/emc141x.c
@@ -25,7 +25,7 @@
 #include "qapi/visitor.h"
 #include "qemu/module.h"
 #include "qom/object.h"
-#include "hw/misc/emc141x_regs.h"
+#include "hw/sensor/emc141x_regs.h"
 
 #define SENSORS_COUNT_MAX4
 
diff --git a/hw/sensor/meson.build

[PATCH 2/3] adc: Move the max111x driver to the adc directory

2021-05-18 Thread minyard
From: Corey Minyard 

It's an adc, put it where it belongs.

Cc: Andrzej Zaborowski 
Cc: Peter Maydell 
Cc: qemu-...@nongnu.org
Signed-off-by: Corey Minyard 
---
 MAINTAINERS| 4 ++--
 hw/adc/Kconfig | 3 +++
 hw/{misc => adc}/max111x.c | 2 +-
 hw/adc/meson.build | 3 ++-
 hw/arm/spitz.c | 2 +-
 hw/misc/Kconfig| 3 ---
 hw/misc/meson.build| 1 -
 include/hw/{misc => adc}/max111x.h | 0
 8 files changed, 9 insertions(+), 9 deletions(-)
 rename hw/{misc => adc}/max111x.c (99%)
 rename include/hw/{misc => adc}/max111x.h (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6cb3b15f97..4fbedc7c11 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -834,8 +834,8 @@ F: hw/display/tc6393xb.c
 F: hw/gpio/max7310.c
 F: hw/gpio/zaurus.c
 F: hw/misc/mst_fpga.c
-F: hw/misc/max111x.c
-F: include/hw/misc/max111x.h
+F: hw/adc/max111x.c
+F: include/hw/adc/max111x.h
 F: include/hw/arm/pxa.h
 F: include/hw/arm/sharpsl.h
 F: include/hw/display/tc6393xb.h
diff --git a/hw/adc/Kconfig b/hw/adc/Kconfig
index 25d2229fb8..a825bd3d34 100644
--- a/hw/adc/Kconfig
+++ b/hw/adc/Kconfig
@@ -1,2 +1,5 @@
 config STM32F2XX_ADC
 bool
+
+config MAX111X
+bool
diff --git a/hw/misc/max111x.c b/hw/adc/max111x.c
similarity index 99%
rename from hw/misc/max111x.c
rename to hw/adc/max111x.c
index 1b3234a519..e8bf4cccd4 100644
--- a/hw/misc/max111x.c
+++ b/hw/adc/max111x.c
@@ -11,7 +11,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "hw/misc/max111x.h"
+#include "hw/adc/max111x.h"
 #include "hw/irq.h"
 #include "migration/vmstate.h"
 #include "qemu/module.h"
diff --git a/hw/adc/meson.build b/hw/adc/meson.build
index 3d397b4ea1..ac4f093fea 100644
--- a/hw/adc/meson.build
+++ b/hw/adc/meson.build
@@ -1,3 +1,4 @@
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_ADC', if_true: files('stm32f2xx_adc.c'))
 softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_adc.c'))
-softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq-xadc.c'))
\ No newline at end of file
+softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq-xadc.c'))
+softmmu_ss.add(when: 'CONFIG_MAX111X', if_true: files('max111x.c'))
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index b45a929cbd..0e2626125e 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -30,7 +30,7 @@
 #include "audio/audio.h"
 #include "hw/boards.h"
 #include "hw/sysbus.h"
-#include "hw/misc/max111x.h"
+#include "hw/adc/max111x.h"
 #include "migration/vmstate.h"
 #include "exec/address-spaces.h"
 #include "cpu.h"
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index c71ed25820..996d45aff5 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -11,9 +11,6 @@ config ARMSSE_MHU
 config ARMSSE_CPU_PWRCTRL
 bool
 
-config MAX111X
-bool
-
 config TMP105
 bool
 depends on I2C
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 508fce50c7..b0a8ee8994 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -3,7 +3,6 @@ softmmu_ss.add(when: 'CONFIG_EDU', if_true: files('edu.c'))
 softmmu_ss.add(when: 'CONFIG_FW_CFG_DMA', if_true: files('vmcoreinfo.c'))
 softmmu_ss.add(when: 'CONFIG_ISA_DEBUG', if_true: files('debugexit.c'))
 softmmu_ss.add(when: 'CONFIG_ISA_TESTDEV', if_true: files('pc-testdev.c'))
-softmmu_ss.add(when: 'CONFIG_MAX111X', if_true: files('max111x.c'))
 softmmu_ss.add(when: 'CONFIG_PCA9552', if_true: files('pca9552.c'))
 softmmu_ss.add(when: 'CONFIG_PCI_TESTDEV', if_true: files('pci-testdev.c'))
 softmmu_ss.add(when: 'CONFIG_SGA', if_true: files('sga.c'))
diff --git a/include/hw/misc/max111x.h b/include/hw/adc/max111x.h
similarity index 100%
rename from include/hw/misc/max111x.h
rename to include/hw/adc/max111x.h
-- 
2.25.1




[PATCH 1/3] adc: Move the zynq-xadc file to the adc directories

2021-05-18 Thread minyard
From: Corey Minyard 

It's an ADC, put it where it belongs.

Cc: Edgar E. Iglesias 
Cc: Alistair Francis 
Cc: Peter Maydell 
Cc: qemu-...@nongnu.org
Signed-off-by: Corey Minyard 
---
 MAINTAINERS  | 6 --
 hw/adc/meson.build   | 1 +
 hw/{misc => adc}/zynq-xadc.c | 2 +-
 hw/arm/xilinx_zynq.c | 2 +-
 hw/misc/meson.build  | 2 +-
 include/hw/{misc => adc}/zynq-xadc.h | 0
 6 files changed, 8 insertions(+), 5 deletions(-)
 rename hw/{misc => adc}/zynq-xadc.c (99%)
 rename include/hw/{misc => adc}/zynq-xadc.h (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index eab178aeee..6cb3b15f97 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -913,8 +913,10 @@ L: qemu-...@nongnu.org
 S: Maintained
 F: hw/*/xilinx_*
 F: hw/*/cadence_*
-F: hw/misc/zynq*
-F: include/hw/misc/zynq*
+F: hw/misc/zynq_slcr.c
+F: hw/adc/zynq-xadc.c
+F: include/hw/misc/zynq_slcr.h
+F: include/hw/adc/zynq-xadc.h
 X: hw/ssi/xilinx_*
 
 Xilinx ZynqMP and Versal
diff --git a/hw/adc/meson.build b/hw/adc/meson.build
index 6ddee23813..3d397b4ea1 100644
--- a/hw/adc/meson.build
+++ b/hw/adc/meson.build
@@ -1,2 +1,3 @@
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_ADC', if_true: files('stm32f2xx_adc.c'))
 softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_adc.c'))
+softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq-xadc.c'))
\ No newline at end of file
diff --git a/hw/misc/zynq-xadc.c b/hw/adc/zynq-xadc.c
similarity index 99%
rename from hw/misc/zynq-xadc.c
rename to hw/adc/zynq-xadc.c
index 7b1972ce06..cfc7bab065 100644
--- a/hw/misc/zynq-xadc.c
+++ b/hw/adc/zynq-xadc.c
@@ -15,7 +15,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/irq.h"
-#include "hw/misc/zynq-xadc.h"
+#include "hw/adc/zynq-xadc.h"
 #include "migration/vmstate.h"
 #include "qemu/timer.h"
 #include "qemu/log.h"
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 81af32dc42..245af81bbb 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -26,7 +26,7 @@
 #include "hw/boards.h"
 #include "hw/block/flash.h"
 #include "hw/loader.h"
-#include "hw/misc/zynq-xadc.h"
+#include "hw/adc/zynq-xadc.h"
 #include "hw/ssi/ssi.h"
 #include "hw/usb/chipidea.h"
 #include "qemu/error-report.h"
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 66e1648533..508fce50c7 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -84,7 +84,7 @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
   'bcm2835_cprman.c',
 ))
 softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
-softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 
'zynq-xadc.c'))
+softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
 softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-xramc.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: 
files('stm32f2xx_syscfg.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: 
files('stm32f4xx_syscfg.c'))
diff --git a/include/hw/misc/zynq-xadc.h b/include/hw/adc/zynq-xadc.h
similarity index 100%
rename from include/hw/misc/zynq-xadc.h
rename to include/hw/adc/zynq-xadc.h
-- 
2.25.1




[PATCH 0/3] Move some things out of hw/misc

2021-05-18 Thread minyard
hw/misc has collected a few things that could be moved elsewhere.

Move two ADC devices into the adc directory.

Create a sensor directory and move the sensors into it.  There's only a
few for now, but the people driving the BMC work are going to be adding
many more, and it would really clutter up hw/misc.  This is the main
reason for the patch set.

I was unable to run the tests to completion, but I think I ran the ones
that matter.  The end of master fails the BIOS tests for i386, at least,
and it hangs the test run.  I backed out these changes and
double-checked.

-corey





[Bug 1875702] Re: madvise reports success, but doesn't implement WIPEONFORK.

2021-05-18 Thread Thomas Huth
This is an automated cleanup. This bug report has been moved to QEMU's
new bug tracker on gitlab.com and thus gets marked as 'expired' now.
Please continue with the discussion here:

 https://gitlab.com/qemu-project/qemu/-/issues/343


** Changed in: qemu
   Status: Confirmed => Expired

** Changed in: qemu
 Assignee: Laurent Vivier (laurent-vivier) => (unassigned)

** Bug watch added: gitlab.com/qemu-project/qemu/-/issues #343
   https://gitlab.com/qemu-project/qemu/-/issues/343

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

Title:
  madvise reports success, but doesn't implement WIPEONFORK.

Status in QEMU:
  Expired

Bug description:
  The implementation of madvise (linux-user/syscall.c:11331, tag
  v5.0.0-rc4) always returns zero (i.e. success). However, an
  application requesting (at least) MADV_WIPEONFORK may need to know
  whether the call was actually successful. If not (because the kernel
  doesn't support WIPEONFORK) then it will need to take other measures
  to provide fork-safety (such as drawing entropy from the kernel in
  every case). But, if the application believes that WIPEONFORK is
  supported (because madvise returned zero), but it actually isn't (as
  in qemu), then it may forego those protections on the assumption that
  WIPEONFORK will provide fork-safety.

  Roughly, the comment in qemu that says "This is a hint, so ignoring
  and returning success is ok." is no longer accurate in the presence of
  MADV_WIPEONFORK.

  (This is not purely academic: BoringSSL is planning on acting in this
  way. We found the qemu behaviour in pre-release testing and are
  planning on making an madvise call with advice=-1 first to test
  whether unknown advice values actually produce EINVAL.)

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



[Bug 1915535] Re: Assertion `child->perm & BLK_PERM_WRITE' failed in bdrv_co_write_req_prepare through atapi

2021-05-18 Thread Thomas Huth
This is an automated cleanup. This bug report has been moved to QEMU's
new bug tracker on gitlab.com and thus gets marked as 'expired' now.
Please continue with the discussion here:

 https://gitlab.com/qemu-project/qemu/-/issues/342


** Changed in: qemu
   Status: New => Expired

** Changed in: qemu
 Assignee: John Snow (jnsnow) => (unassigned)

** Bug watch added: gitlab.com/qemu-project/qemu/-/issues #342
   https://gitlab.com/qemu-project/qemu/-/issues/342

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

Title:
  Assertion `child->perm & BLK_PERM_WRITE' failed in
  bdrv_co_write_req_prepare through atapi

Status in QEMU:
  Expired

Bug description:
  Maybe this is a duplicate of https://bugs.launchpad.net/qemu/+bug/1906693 ... 
  In any case, ATAPI is probably a lot more common than megasas, so this might 
be a more useful  reproducer

  ==Reproducer==

  cat << EOF | ./qemu-system-i386 -display none \
  -m 512M -machine q35 -nodefaults \
  -drive file=null-co://,if=none,format=raw,id=disk0 \
  -device ide-cd,drive=disk0 -machine accel=qtest -qtest stdio
  outl 0xcf8 0x8000fa24
  outl 0xcfc 0xe000
  outl 0xcf8 0x8000fa04
  outw 0xcfc 0x06
  write 0xe398 0x1 0x01
  write 0x63 0x1 0x06
  write 0x68 0x1 0x06
  write 0x69 0x1 0xf8
  write 0x6a 0x1 0xff
  write 0xfff806 0x1 0x27
  write 0xfff807 0x1 0x80
  write 0xfff808 0x1 0x61
  write 0x1005734 0x1 0x3f
  write 0x1005774 0x1 0x20
  write 0x1005784 0x1 0x34
  write 0x10057a4 0x1 0x27
  write 0x10057b4 0x1 0x3f
  write 0x10057c3 0x1 0xce
  write 0x10057d4 0x1 0x1a
  write 0x10057e3 0x1 0xff
  write 0x10057e4 0x1 0x3f
  write 0x10057f4 0x1 0x38
  write 0x1005814 0x1 0x3e
  write 0x1005823 0x1 0x60
  write 0x1005824 0x1 0x2d
  write 0x1005833 0x1 0x74
  write 0x1005834 0x1 0x01
  write 0x1005863 0x1 0xff
  write 0x1005883 0x1 0x5a
  write 0x1005884 0x1 0x06
  write 0xe3b8 0x1 0x08
  EOF

  
  ==Stack Trace==
  i386: ahci: PRDT length for NCQ command (0x0) is smaller than the requested 
size (0x5a00)
  qemu-fuzz-i386-target-generic-fuzz-ahci-atapi: ../block/io.c:1982: int
  bdrv_co_write_req_prepare(BdrvChild *, int64_t, int64_t, BdrvTrackedRequest
  *, int): Assertion `child->perm & BLK_PERM_WRITE' failed.
  ==279048== ERROR: libFuzzer: deadly signal
  #0 0x560c92718f50 in __sanitizer_print_stack_trace 
/src/llvm-project/compiler-rt/lib/ubsan/ubsan_diag_standalone.cpp:33:3
  #1 0x560c926c2f98 in fuzzer::PrintStackTrace() 
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerUtil.cpp:210:5
  #2 0x560c926a7fd3 in fuzzer::Fuzzer::CrashCallback() 
/src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:233:3
  #3 0x7ff7d707038f in libpthread.so.0
  #4 0x7ff7d66a8437 in raise
  #5 0x7ff7d66aa039 in abort
  #6 0x7ff7d66a0be6 in libc.so.6
  #7 0x7ff7d66a0c91 in __assert_fail
  #8 0x560c92f4fc79 in bdrv_co_write_req_prepare /src/qemu/block/io.c:1982:13
  #9 0x560c92f4c974 in bdrv_aligned_pwritev /src/qemu/block/io.c:2065:11
  #10 0x560c92f4b937 in bdrv_co_pwritev_part /src/qemu/block/io.c:2270:11
  #11 0x560c92f392e7 in blk_do_pwritev_part 
/src/qemu/block/block-backend.c:1260:11
  #12 0x560c92f39a55 in blk_aio_write_entry 
/src/qemu/block/block-backend.c:1476:17
  #13 0x560c930d19d5 in coroutine_trampoline 
/src/qemu/util/coroutine-ucontext.c:173:9
  #14 0x7ff7d66bd5df in libc.so.6

  OSS-Fuzz link: https://bugs.chromium.org/p/oss-
  fuzz/issues/detail?id=30857

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



[Bug 1915539] Re: Null-ptr dereference on AHCICmdHdr in ahci_pio_transfer

2021-05-18 Thread Thomas Huth
This is an automated cleanup. This bug report has been moved to QEMU's
new bug tracker on gitlab.com and thus gets marked as 'expired' now.
Please continue with the discussion here:

 https://gitlab.com/qemu-project/qemu/-/issues/341


** Changed in: qemu
   Status: Confirmed => Expired

** Changed in: qemu
 Assignee: John Snow (jnsnow) => (unassigned)

** Bug watch added: gitlab.com/qemu-project/qemu/-/issues #341
   https://gitlab.com/qemu-project/qemu/-/issues/341

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

Title:
  Null-ptr dereference on AHCICmdHdr in ahci_pio_transfer

Status in QEMU:
  Expired

Bug description:
  == Reproducer ==

  cat << EOF | ./qemu-system-i386 -display none \
  -m 512M -machine q35 -nodefaults \
  -drive file=null-co://,if=none,format=raw,id=disk0 \
  -device ide-hd,drive=disk0 -machine accel=qtest -qtest stdio
  outl 0xcf8 0x8000fa24
  outl 0xcfc 0xe000
  outl 0xcf8 0x8000fa04
  outw 0xcfc 0x06
  write 0x10a 0x1 0x02
  write 0xe398 0x1 0x01
  write 0x2 0x1 0x27
  write 0x20001 0x1 0x80
  write 0x20002 0x1 0x20
  write 0x20005 0x1 0x02
  write 0xe3b8 0x2 0x0101
  write 0xe004 0x1 0x01
  write 0x2bb 0x1 0x00
  write 0x2bf 0x1 0x00
  write 0x2cf 0x1 0x00
  write 0x2db 0x1 0x00
  write 0x2df 0x1 0x00
  write 0x2ed 0x1 0x00
  write 0x2ef 0x1 0x00
  write 0x2fb 0x1 0x00
  write 0x2ff 0x1 0x00
  write 0x31f 0x1 0x00
  write 0x32b 0x1 0x00
  write 0x32f 0x1 0x00
  write 0x337 0x1 0x00
  write 0x33f 0x1 0x00
  write 0x347 0x1 0x00
  write 0x357 0x1 0x00
  write 0x35f 0x1 0x00
  write 0x36b 0x1 0x00
  write 0x36f 0x1 0x00
  write 0x377 0x1 0x00
  write 0x37f 0x1 0x00
  write 0x397 0x1 0x00
  write 0x39f 0x1 0x00
  write 0x3ab 0x1 0x00
  write 0x3af 0x1 0x00
  write 0x3b7 0x1 0x00
  write 0x3bf 0x1 0x00
  write 0x3c7 0x1 0x00
  write 0x3d7 0x1 0x00
  write 0x3df 0x1 0x00
  write 0x3eb 0x1 0x00
  write 0x3ef 0x1 0x00
  write 0x3f7 0x1 0x00
  write 0x3ff 0x1 0x00
  write 0xe394 0x1 0x00
  write 0xe398 0x1 0x01
  EOF

  == Stack Trace ==
  ../hw/ide/ahci.c:1349:46: runtime error: member access within null pointer of
  type 'AHCICmdHdr' (aka 'struct AHCICmdHdr') SUMMARY:
  UndefinedBehaviorSanitizer: undefined-behavior ../hw/ide/ahci.c:1349:46 in
  ../hw/ide/ahci.c:1349:46: runtime error: load of null pointer of type
  'uint16_t' (aka 'unsigned short')
  SUMMARY: UndefinedBehaviorSanitizer:
  undefined-behavior ../hw/ide/ahci.c:1349:46 in AddressSanitizer:DEADLYSIGNAL
  =
  ==238806==ERROR: AddressSanitizer: SEGV on unknown address 0x (pc
  0x555787d414c9 bp 0x7fffe1bb41a0 sp 0x7fffe1bb3fe0 T0)
  ==238806==The signal is caused by a READ memory access.
  ==238806==Hint: address points to the zero page.
  #0 0x555787d414c9 in ahci_pio_transfer build/../hw/ide/ahci.c:1349:46
  #1 0x5557886089d6 in ide_transfer_start_norecurse build/../hw/ide/core.c:553:5
  #2 0x555788638945 in ide_transfer_start build/../hw/ide/core.c:560:9
  #3 0x555788638945 in ide_sector_read_cb build/../hw/ide/core.c:761:5
  #4 0x55578860c989 in ide_buffered_readv_cb build/../hw/ide/core.c:656:9
  #5 0x5557898999d6 in blk_aio_complete build/../block/block-backend.c:1412:9
  #6 0x555789db8d26 in aio_bh_poll build/../util/async.c:164:13
  #7 0x555789d80704 in aio_dispatch build/../util/aio-posix.c:381:5
  #8 0x555789dbd94c in aio_ctx_dispatch build/../util/async.c:306:5
  #9 0x7f6dcedcfbaa in g_main_context_dispatch 
(/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51baa)
  #10 0x555789dc3763 in glib_pollfds_poll build/../util/main-loop.c:232:9
  #11 0x555789dc3763 in os_host_main_loop_wait build/../util/main-loop.c:255:5
  #12 0x555789dc3763 in main_loop_wait build/../util/main-loop.c:531:11
  #13 0x555789206a49 in qemu_main_loop build/../softmmu/runstate.c:722:9
  #14 0x555787d052ed in main build/../softmmu/main.c:50:5
  #15 0x7f6dcd84ecc9 in __libc_start_main csu/../csu/libc-start.c:308:16
  #16 0x555787c5b619 in _start (system-i386+0x2a13619)

  AddressSanitizer can not provide additional info.
  SUMMARY: AddressSanitizer: SEGV build/../hw/ide/ahci.c:1349:46 in 
ahci_pio_transfer
  ==238806==ABORTING

  OSS-Fuzz link: https://bugs.chromium.org/p/oss-
  fuzz/issues/detail?id=30861

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



Re: [PATCH 4/4] aspeed: sonorapass: enable pca954x muxes

2021-05-18 Thread Joel Stanley
On Tue, 18 May 2021 at 19:41, Patrick Venture  wrote:
>
> Enables the pca954x muxes in the bmc board configuration.
>
> Signed-off-by: Patrick Venture 
> Reviewed-by: Hao Wu 

Not sure about this one, there's no device tree for it in Linux.

> ---
>  hw/arm/aspeed.c | 22 +++---
>  1 file changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 35a28b0e8b..27fd51980c 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -541,14 +541,16 @@ static void swift_bmc_i2c_init(AspeedMachineState *bmc)
>
>  static void sonorapass_bmc_i2c_init(AspeedMachineState *bmc)
>  {
> +I2CSlave *i2c_mux;
>  AspeedSoCState *soc = &bmc->soc;
>
>  /* bus 2 : */
>  i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 2), "tmp105", 
> 0x48);
>  i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 2), "tmp105", 
> 0x49);
> -/* bus 2 : pca9546 @ 0x73 */
> +i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 2), "pca9546", 
> 0x73);
>
> -/* bus 3 : pca9548 @ 0x70 */
> +/* bus 3 : */
> +i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 3), "pca9548", 
> 0x70);
>
>  /* bus 4 : */
>  uint8_t *eeprom4_54 = g_malloc0(8 * 1024);
> @@ -562,7 +564,7 @@ static void sonorapass_bmc_i2c_init(AspeedMachineState 
> *bmc)
>  /* bus 6 : */
>  i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6), "tmp105", 
> 0x48);
>  i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6), "tmp105", 
> 0x49);
> -/* bus 6 : pca9546 @ 0x73 */
> +i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6), "pca9546", 
> 0x73);
>
>  /* bus 8 : */
>  uint8_t *eeprom8_56 = g_malloc0(8 * 1024);
> @@ -573,14 +575,12 @@ static void sonorapass_bmc_i2c_init(AspeedMachineState 
> *bmc)
>  /* bus 8 : adc128d818 @ 0x1d */
>  /* bus 8 : adc128d818 @ 0x1f */
>
> -/*
> - * bus 13 : pca9548 @ 0x71
> - *  - channel 3:
> - *  - tmm421 @ 0x4c
> - *  - tmp421 @ 0x4e
> - *  - tmp421 @ 0x4f
> - */
> -
> +/* bus 13 : */
> +i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 13),
> +  "pca9548", 0x71);
> +i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 3), "tmp421", 0x4c);
> +i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 3), "tmp421", 0x4e);
> +i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 3), "tmp421", 0x4f);
>  }
>
>  static void witherspoon_bmc_i2c_init(AspeedMachineState *bmc)
> --
> 2.31.1.751.gd2f1c929bd-goog
>



Re: [PATCH 3/4] hw/arm: quanta-q71l add pca954x muxes

2021-05-18 Thread Joel Stanley
On Tue, 18 May 2021 at 19:41, Patrick Venture  wrote:
>
> Adds the pca954x muxes expected.
>
> Tested: Booted quanta-q71l image to userspace.
> Signed-off-by: Patrick Venture 
> Reviewed-by: Hao Wu 

Reviewed-by: Joel Stanley 



Re: [PATCH 2/4] hw/arm: gsj add pca9548

2021-05-18 Thread Joel Stanley
On Tue, 18 May 2021 at 19:41, Patrick Venture  wrote:
>
> Tested: Quanta-gsj firmware booted.
>
> i2c /dev entries driver
> I2C init bus 1 freq 10
> I2C init bus 2 freq 10
> I2C init bus 3 freq 10
> I2C init bus 4 freq 10
> I2C init bus 8 freq 10
> I2C init bus 9 freq 10
> at24 9-0055: 8192 byte 24c64 EEPROM, writable, 1 bytes/write
> I2C init bus 10 freq 10
> at24 10-0055: 8192 byte 24c64 EEPROM, writable, 1 bytes/write
> I2C init bus 12 freq 10
> I2C init bus 15 freq 10
> i2c i2c-15: Added multiplexed i2c bus 16
> i2c i2c-15: Added multiplexed i2c bus 17
> i2c i2c-15: Added multiplexed i2c bus 18
> i2c i2c-15: Added multiplexed i2c bus 19
> i2c i2c-15: Added multiplexed i2c bus 20
> i2c i2c-15: Added multiplexed i2c bus 21
> i2c i2c-15: Added multiplexed i2c bus 22
> i2c i2c-15: Added multiplexed i2c bus 23
> pca954x 15-0075: registered 8 multiplexed busses for I2C switch pca9548
>
> Signed-off-by: Patrick Venture 
> Reviewed-by: Hao Wu 

Reviewed-by: Joel Stanley 



Re: [PATCH 1/4] hw/arm: gsj add i2c comments

2021-05-18 Thread Joel Stanley
On Tue, 18 May 2021 at 19:41, Patrick Venture  wrote:
>
> Adds comments to the board init to identify missing i2c devices.
>
> Signed-off-by: Patrick Venture 
> Reviewed-by: Hao Wu 

Reviewed-by: Joel Stanley 



Re: [RFC PATCH 02/11] hw/ide: Add PCIIDEState::isa_bus link

2021-05-18 Thread BALATON Zoltan

On Tue, 18 May 2021, Philippe Mathieu-Daudé wrote:

IDE bus depends on ISA bus for IRQ/DMA.

Add an ISABus reference in PCIIDEState, and add link properties
to it in the PIIX and VIA objects (which inherit PCI_IDE).

Signed-off-by: Philippe Mathieu-Daudé 
---
include/hw/ide/pci.h |  1 +
hw/ide/piix.c| 11 ++-
hw/ide/via.c | 10 +-
3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
index d8384e1c422..e790722ed14 100644
--- a/include/hw/ide/pci.h
+++ b/include/hw/ide/pci.h
@@ -47,6 +47,7 @@ struct PCIIDEState {
PCIDevice parent_obj;
/*< public >*/

+ISABus *isa_bus;


I'm not sure that this belongs here. Previously we managed to remove 
device specific fields from this structure so it's now really just holds 
stuff related to PCI IDE (except the remaining "secondary" field specific 
to CMD646). PCI IDE normaly has nothing to do with ISA except for those 
south bridges that have IDE with legacy mode. So this ISABus reference 
should be in those south bridges instead. But that may need a new subclass 
just for this so putting it here is just avoiding boilerplate of declaring 
new subclasses in piix and via-ide. I can sympathise with that but I'd 
still prefer to keep it off here but I wonder if there's a way to do that 
without subclassing and storing an ISABus ref? If I understand correctly 
this ISABus ref is just needed to get appropriate ISA irqs. But could we 
just store a ref to those irqs directly so we don't need to keep the ref 
to the ISA bus? There's already a qemu_irq in BMDMAState but I'm not sure 
how those are set and if you could store an isa irq there to simplify 
this. I don't know the details and could not detangle it by a brief look 
so not sure it can be done but conceptually it feels better to keep PCI 
IDE separate from ISA and let it raise either PCI irq or ISA irq as 
needed. For that a ref to the irq should be enough and that can either 
come from a PCI bus (which is normaly expected for PCI IDE) or an ISA 
bridge for legacy modes. Hope it makes sense and you get what I'm trying 
to say. (Longer term we may want to make it changeable also after the 
device is created to allow switching between legacy and PCI mode but so 
far we could get away without emulating that so it's not a requirement 
just something to consider when you're changing this. The real problem 
that prevents switching modes is not irq I think but ioports and that ISA 
devices are not configurable after creating them but that would need 
QOM'ifying ISA emulation which probably does not worth the effort unless 
we come across some guest that needs this.)


Regards,
BALATON Zoltan


IDEBus bus[2];
BMDMAState bmdma[2];
uint32_t secondary; /* used only for cmd646 */
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index b9860e35a5c..48da68da37f 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -30,8 +30,9 @@
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "sysemu/dma.h"
-
+#include "qapi/error.h"
#include "hw/ide/pci.h"
+#include "hw/isa/isa.h"
#include "trace.h"

static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size)
@@ -207,6 +208,12 @@ static void pci_piix_ide_exitfn(PCIDevice *dev)
}
}

+static Property piix_ide_properties[] = {
+DEFINE_PROP_LINK("isa-bus", PCIIDEState, isa_bus,
+ TYPE_ISA_BUS, ISABus *),
+DEFINE_PROP_END_OF_LIST(),
+};
+
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
static void piix3_ide_class_init(ObjectClass *klass, void *data)
{
@@ -221,6 +228,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void 
*data)
k->class_id = PCI_CLASS_STORAGE_IDE;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->hotpluggable = false;
+device_class_set_props(dc, piix_ide_properties);
}

static const TypeInfo piix3_ide_info = {
@@ -249,6 +257,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void 
*data)
k->class_id = PCI_CLASS_STORAGE_IDE;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->hotpluggable = false;
+device_class_set_props(dc, piix_ide_properties);
}

static const TypeInfo piix4_ide_info = {
diff --git a/hw/ide/via.c b/hw/ide/via.c
index be09912b334..65fdca6dcf4 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -28,8 +28,9 @@
#include "hw/pci/pci.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
+#include "qapi/error.h"
#include "sysemu/dma.h"
-
+#include "hw/isa/isa.h"
#include "hw/ide/pci.h"
#include "trace.h"

@@ -210,6 +211,12 @@ static void via_ide_exitfn(PCIDevice *dev)
}
}

+static Property via_ide_properties[] = {
+DEFINE_PROP_LINK("isa-bus", PCIIDEState, isa_bus,
+ TYPE_ISA_BUS, ISABus *),
+DEFINE_PROP_END_OF_LIST(),
+};
+
static void via_ide_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -224,6 +231,7 @@ static void via_ide_class_init(ObjectClass *klass, void 
*data)
k->

[PATCH 1/2] Hexagon (target/hexagon) fix bug in fLSBNEW*

2021-05-18 Thread Taylor Simpson
Change fLSBNEW/fLSBNEW0/fLSBNEW1 from copy to "x & 1"
Remove gen_logical_not function
Clean up fLSBNEWNOT to use andi-1 followed by xori-1

Test cases added to tests/tcg/hexagon/misc.c

Signed-off-by: Taylor Simpson 
---
 target/hexagon/macros.h| 27 ++-
 target/hexagon/op_helper.c |  5 -
 tests/tcg/hexagon/misc.c   | 39 ++-
 3 files changed, 48 insertions(+), 23 deletions(-)

diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index b726c3b..2b208f3 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -239,33 +239,26 @@ static inline void gen_pred_cancel(TCGv pred, int 
slot_num)
 #endif
 
 #ifdef QEMU_GENERATE
-#define fLSBNEW(PVAL)   tcg_gen_mov_tl(LSB, (PVAL))
-#define fLSBNEW0tcg_gen_mov_tl(LSB, hex_new_pred_value[0])
-#define fLSBNEW1tcg_gen_mov_tl(LSB, hex_new_pred_value[1])
+#define fLSBNEW(PVAL)   tcg_gen_andi_tl(LSB, (PVAL), 1)
+#define fLSBNEW0tcg_gen_andi_tl(LSB, hex_new_pred_value[0], 1)
+#define fLSBNEW1tcg_gen_andi_tl(LSB, hex_new_pred_value[1], 1)
 #else
-#define fLSBNEW(PVAL)   (PVAL)
-#define fLSBNEW0new_pred_value(env, 0)
-#define fLSBNEW1new_pred_value(env, 1)
+#define fLSBNEW(PVAL)   ((PVAL) & 1)
+#define fLSBNEW0(env->new_pred_value[0] & 1)
+#define fLSBNEW1(env->new_pred_value[1] & 1)
 #endif
 
 #ifdef QEMU_GENERATE
-static inline void gen_logical_not(TCGv dest, TCGv src)
-{
-TCGv one = tcg_const_tl(1);
-TCGv zero = tcg_const_tl(0);
-
-tcg_gen_movcond_tl(TCG_COND_NE, dest, src, zero, zero, one);
-
-tcg_temp_free(one);
-tcg_temp_free(zero);
-}
 #define fLSBOLDNOT(VAL) \
 do { \
 tcg_gen_andi_tl(LSB, (VAL), 1); \
 tcg_gen_xori_tl(LSB, LSB, 1); \
 } while (0)
 #define fLSBNEWNOT(PNUM) \
-gen_logical_not(LSB, (PNUM))
+do { \
+tcg_gen_andi_tl(LSB, (PNUM), 1); \
+tcg_gen_xori_tl(LSB, LSB, 1); \
+} while (0)
 #else
 #define fLSBNEWNOT(PNUM) (!fLSBNEW(PNUM))
 #define fLSBOLDNOT(VAL) (!fLSBOLD(VAL))
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 63dd685..4595559 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -128,11 +128,6 @@ void HELPER(debug_start_packet)(CPUHexagonState *env)
 }
 }
 
-static int32_t new_pred_value(CPUHexagonState *env, int pnum)
-{
-return env->new_pred_value[pnum];
-}
-
 /* Checks for bookkeeping errors between disassembly context and runtime */
 void HELPER(debug_check_store_width)(CPUHexagonState *env, int slot, int check)
 {
diff --git a/tests/tcg/hexagon/misc.c b/tests/tcg/hexagon/misc.c
index 17c3919..9e139f3 100644
--- a/tests/tcg/hexagon/misc.c
+++ b/tests/tcg/hexagon/misc.c
@@ -181,6 +181,19 @@ static inline void S4_storeirifnew_io(void *p, int pred)
: "p0", "memory");
 }
 
+static int L2_ploadrifnew_pi(void *p, int pred)
+{
+  int result;
+  asm volatile("%0 = #31\n\t"
+   "{\n\t"
+   "p0 = cmp.eq(%1, #1)\n\t"
+   "if (!p0.new) %0 = memw(%2++#4)\n\t"
+   "}\n\t"
+   : "=r"(result) : "r"(pred), "r"(p)
+   : "p0");
+  return result;
+}
+
 /*
  * Test that compound-compare-jump is executed in 2 parts
  * First we have to do all the compares in the packet and
@@ -298,8 +311,24 @@ static int auto_and(void)
 return retval;
 }
 
+void test_lsbnew(void)
+{
+int result;
+
+asm("r0 = #2\n\t"
+"r1 = #5\n\t"
+"{\n\t"
+"p0 = r0\n\t"
+"if (p0.new) r1 = #3\n\t"
+"}\n\t"
+"%0 = r1\n\t"
+: "=r"(result) :: "r0", "r1", "p0");
+check(result, 5);
+}
+
 int main()
 {
+int res;
 long long res64;
 int pred;
 
@@ -394,6 +423,12 @@ int main()
 S4_storeirifnew_io(&array[8], 1);
 check(array[9], 9);
 
+memcpy(array, init, sizeof(array));
+res = L2_ploadrifnew_pi(&array[6], 0);
+check(res, 6);
+res = L2_ploadrifnew_pi(&array[7], 1);
+check(res, 31);
+
 int x = cmpnd_cmp_jump();
 check(x, 12);
 
@@ -406,7 +441,7 @@ int main()
 check((int)pair, 5);
 check((int)(pair >> 32), 7);
 
-int res = test_clrtnew(1, 7);
+res = test_clrtnew(1, 7);
 check(res, 0);
 res = test_clrtnew(2, 7);
 check(res, 7);
@@ -422,6 +457,8 @@ int main()
 res = auto_and();
 check(res, 0);
 
+test_lsbnew();
+
 puts(err ? "FAIL" : "PASS");
 return err;
 }
-- 
2.7.4



[PATCH 0/2] Hexagon (target/hexagon) bug fixes

2021-05-18 Thread Taylor Simpson
Fixes for bugs found by inspection and internal testing
Tests added to tests/tcg/hexagon/misc.c

Taylor Simpson (2):
  Hexagon (target/hexagon) fix bug in fLSBNEW*
  Hexagon (target/hexagon) fix l2fetch instructions

 target/hexagon/gen_tcg.h  | 11 
 target/hexagon/macros.h   | 27 
 target/hexagon/op_helper.c|  5 
 tests/tcg/hexagon/misc.c  | 48 ++-
 target/hexagon/imported/encode_pp.def |  3 +++
 5 files changed, 71 insertions(+), 23 deletions(-)

-- 
2.7.4



[PATCH 2/2] Hexagon (target/hexagon) fix l2fetch instructions

2021-05-18 Thread Taylor Simpson
Y4_l2fetch == l2fetch(Rs32, Rt32)
Y5_l2fetch == l2fetch(Rs32, Rtt32)

The semantics for these instructions are present, but the encodings
are missing.

Note that these are treated as nops in qemu, so we add overrides.

Test case added to tests/tcg/hexagon/misc.c

Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h  | 11 +++
 tests/tcg/hexagon/misc.c  |  9 +
 target/hexagon/imported/encode_pp.def |  3 +++
 3 files changed, 23 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 18fcdbc..a375d6a 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -734,4 +734,15 @@
 #define fGEN_TCG_F2_dfmpyhh(SHORTCODE) \
 gen_helper_dfmpyhh(RxxV, cpu_env, RxxV, RssV, RttV)
 
+/* Nothing to do for these in qemu, need to suppress compiler warnings */
+#define fGEN_TCG_Y4_l2fetch(SHORTCODE) \
+do { \
+RsV = RsV; \
+RtV = RtV; \
+} while (0)
+#define fGEN_TCG_Y5_l2fetch(SHORTCODE) \
+do { \
+RsV = RsV; \
+} while (0)
+
 #endif
diff --git a/tests/tcg/hexagon/misc.c b/tests/tcg/hexagon/misc.c
index 9e139f3..f0b1947 100644
--- a/tests/tcg/hexagon/misc.c
+++ b/tests/tcg/hexagon/misc.c
@@ -326,6 +326,13 @@ void test_lsbnew(void)
 check(result, 5);
 }
 
+void test_l2fetch(void)
+{
+/* These don't do anything in qemu, just make sure they don't assert */
+asm volatile ("l2fetch(r0, r1)\n\t"
+  "l2fetch(r0, r3:2)\n\t");
+}
+
 int main()
 {
 int res;
@@ -459,6 +466,8 @@ int main()
 
 test_lsbnew();
 
+test_l2fetch();
+
 puts(err ? "FAIL" : "PASS");
 return err;
 }
diff --git a/target/hexagon/imported/encode_pp.def 
b/target/hexagon/imported/encode_pp.def
index 35ae3d2..939c6fc 100644
--- a/target/hexagon/imported/encode_pp.def
+++ b/target/hexagon/imported/encode_pp.def
@@ -493,6 +493,9 @@ DEF_ENC32(Y2_dccleana, ICLASS_ST" 000 00 00s 
PP-- ")
 DEF_ENC32(Y2_dcinva,   ICLASS_ST" 000 00 01s PP-- ")
 DEF_ENC32(Y2_dccleaninva,  ICLASS_ST" 000 00 10s PP-- ")
 
+DEF_ENC32(Y4_l2fetch,  ICLASS_ST" 011 00 00s PP-t 000-")
+DEF_ENC32(Y5_l2fetch,  ICLASS_ST" 011 01 00s PP-t ")
+
 /***/
 /* */
 /* */
-- 
2.7.4



[PATCH 1/2] Hexagon (target/hexagon) fix bug in fLSBNEW*

2021-05-18 Thread Taylor Simpson
Change fLSBNEW/fLSBNEW0/fLSBNEW1 from copy to "x & 1"
Remove gen_logical_not function
Clean up fLSBNEWNOT to use andi-1 followed by xori-1

Test cases added to tests/tcg/hexagon/misc.c

Signed-off-by: Taylor Simpson 
---
 target/hexagon/macros.h| 27 ++-
 target/hexagon/op_helper.c |  5 -
 tests/tcg/hexagon/misc.c   | 39 ++-
 3 files changed, 48 insertions(+), 23 deletions(-)

diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index b726c3b..2b208f3 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -239,33 +239,26 @@ static inline void gen_pred_cancel(TCGv pred, int 
slot_num)
 #endif
 
 #ifdef QEMU_GENERATE
-#define fLSBNEW(PVAL)   tcg_gen_mov_tl(LSB, (PVAL))
-#define fLSBNEW0tcg_gen_mov_tl(LSB, hex_new_pred_value[0])
-#define fLSBNEW1tcg_gen_mov_tl(LSB, hex_new_pred_value[1])
+#define fLSBNEW(PVAL)   tcg_gen_andi_tl(LSB, (PVAL), 1)
+#define fLSBNEW0tcg_gen_andi_tl(LSB, hex_new_pred_value[0], 1)
+#define fLSBNEW1tcg_gen_andi_tl(LSB, hex_new_pred_value[1], 1)
 #else
-#define fLSBNEW(PVAL)   (PVAL)
-#define fLSBNEW0new_pred_value(env, 0)
-#define fLSBNEW1new_pred_value(env, 1)
+#define fLSBNEW(PVAL)   ((PVAL) & 1)
+#define fLSBNEW0(env->new_pred_value[0] & 1)
+#define fLSBNEW1(env->new_pred_value[1] & 1)
 #endif
 
 #ifdef QEMU_GENERATE
-static inline void gen_logical_not(TCGv dest, TCGv src)
-{
-TCGv one = tcg_const_tl(1);
-TCGv zero = tcg_const_tl(0);
-
-tcg_gen_movcond_tl(TCG_COND_NE, dest, src, zero, zero, one);
-
-tcg_temp_free(one);
-tcg_temp_free(zero);
-}
 #define fLSBOLDNOT(VAL) \
 do { \
 tcg_gen_andi_tl(LSB, (VAL), 1); \
 tcg_gen_xori_tl(LSB, LSB, 1); \
 } while (0)
 #define fLSBNEWNOT(PNUM) \
-gen_logical_not(LSB, (PNUM))
+do { \
+tcg_gen_andi_tl(LSB, (PNUM), 1); \
+tcg_gen_xori_tl(LSB, LSB, 1); \
+} while (0)
 #else
 #define fLSBNEWNOT(PNUM) (!fLSBNEW(PNUM))
 #define fLSBOLDNOT(VAL) (!fLSBOLD(VAL))
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 63dd685..4595559 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -128,11 +128,6 @@ void HELPER(debug_start_packet)(CPUHexagonState *env)
 }
 }
 
-static int32_t new_pred_value(CPUHexagonState *env, int pnum)
-{
-return env->new_pred_value[pnum];
-}
-
 /* Checks for bookkeeping errors between disassembly context and runtime */
 void HELPER(debug_check_store_width)(CPUHexagonState *env, int slot, int check)
 {
diff --git a/tests/tcg/hexagon/misc.c b/tests/tcg/hexagon/misc.c
index 17c3919..9e139f3 100644
--- a/tests/tcg/hexagon/misc.c
+++ b/tests/tcg/hexagon/misc.c
@@ -181,6 +181,19 @@ static inline void S4_storeirifnew_io(void *p, int pred)
: "p0", "memory");
 }
 
+static int L2_ploadrifnew_pi(void *p, int pred)
+{
+  int result;
+  asm volatile("%0 = #31\n\t"
+   "{\n\t"
+   "p0 = cmp.eq(%1, #1)\n\t"
+   "if (!p0.new) %0 = memw(%2++#4)\n\t"
+   "}\n\t"
+   : "=r"(result) : "r"(pred), "r"(p)
+   : "p0");
+  return result;
+}
+
 /*
  * Test that compound-compare-jump is executed in 2 parts
  * First we have to do all the compares in the packet and
@@ -298,8 +311,24 @@ static int auto_and(void)
 return retval;
 }
 
+void test_lsbnew(void)
+{
+int result;
+
+asm("r0 = #2\n\t"
+"r1 = #5\n\t"
+"{\n\t"
+"p0 = r0\n\t"
+"if (p0.new) r1 = #3\n\t"
+"}\n\t"
+"%0 = r1\n\t"
+: "=r"(result) :: "r0", "r1", "p0");
+check(result, 5);
+}
+
 int main()
 {
+int res;
 long long res64;
 int pred;
 
@@ -394,6 +423,12 @@ int main()
 S4_storeirifnew_io(&array[8], 1);
 check(array[9], 9);
 
+memcpy(array, init, sizeof(array));
+res = L2_ploadrifnew_pi(&array[6], 0);
+check(res, 6);
+res = L2_ploadrifnew_pi(&array[7], 1);
+check(res, 31);
+
 int x = cmpnd_cmp_jump();
 check(x, 12);
 
@@ -406,7 +441,7 @@ int main()
 check((int)pair, 5);
 check((int)(pair >> 32), 7);
 
-int res = test_clrtnew(1, 7);
+res = test_clrtnew(1, 7);
 check(res, 0);
 res = test_clrtnew(2, 7);
 check(res, 7);
@@ -422,6 +457,8 @@ int main()
 res = auto_and();
 check(res, 0);
 
+test_lsbnew();
+
 puts(err ? "FAIL" : "PASS");
 return err;
 }
-- 
2.7.4



[PATCH 2/2] Hexagon (target/hexagon) fix l2fetch instructions

2021-05-18 Thread Taylor Simpson
Y4_l2fetch == l2fetch(Rs32, Rt32)
Y5_l2fetch == l2fetch(Rs32, Rtt32)

The semantics for these instructions are present, but the encodings
are missing.

Note that these are treated as nops in qemu, so we add overrides.

Test case added to tests/tcg/hexagon/misc.c

Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h  | 11 +++
 tests/tcg/hexagon/misc.c  |  9 +
 target/hexagon/imported/encode_pp.def |  3 +++
 3 files changed, 23 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 18fcdbc..a375d6a 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -734,4 +734,15 @@
 #define fGEN_TCG_F2_dfmpyhh(SHORTCODE) \
 gen_helper_dfmpyhh(RxxV, cpu_env, RxxV, RssV, RttV)
 
+/* Nothing to do for these in qemu, need to suppress compiler warnings */
+#define fGEN_TCG_Y4_l2fetch(SHORTCODE) \
+do { \
+RsV = RsV; \
+RtV = RtV; \
+} while (0)
+#define fGEN_TCG_Y5_l2fetch(SHORTCODE) \
+do { \
+RsV = RsV; \
+} while (0)
+
 #endif
diff --git a/tests/tcg/hexagon/misc.c b/tests/tcg/hexagon/misc.c
index 9e139f3..f0b1947 100644
--- a/tests/tcg/hexagon/misc.c
+++ b/tests/tcg/hexagon/misc.c
@@ -326,6 +326,13 @@ void test_lsbnew(void)
 check(result, 5);
 }
 
+void test_l2fetch(void)
+{
+/* These don't do anything in qemu, just make sure they don't assert */
+asm volatile ("l2fetch(r0, r1)\n\t"
+  "l2fetch(r0, r3:2)\n\t");
+}
+
 int main()
 {
 int res;
@@ -459,6 +466,8 @@ int main()
 
 test_lsbnew();
 
+test_l2fetch();
+
 puts(err ? "FAIL" : "PASS");
 return err;
 }
diff --git a/target/hexagon/imported/encode_pp.def 
b/target/hexagon/imported/encode_pp.def
index 35ae3d2..939c6fc 100644
--- a/target/hexagon/imported/encode_pp.def
+++ b/target/hexagon/imported/encode_pp.def
@@ -493,6 +493,9 @@ DEF_ENC32(Y2_dccleana, ICLASS_ST" 000 00 00s 
PP-- ")
 DEF_ENC32(Y2_dcinva,   ICLASS_ST" 000 00 01s PP-- ")
 DEF_ENC32(Y2_dccleaninva,  ICLASS_ST" 000 00 10s PP-- ")
 
+DEF_ENC32(Y4_l2fetch,  ICLASS_ST" 011 00 00s PP-t 000-")
+DEF_ENC32(Y5_l2fetch,  ICLASS_ST" 011 01 00s PP-t ")
+
 /***/
 /* */
 /* */
-- 
2.7.4



[RFC PATCH 10/11] hw/isa: Remove use of global isa bus

2021-05-18 Thread Philippe Mathieu-Daudé
In the previous commit we removed all call to these functions
passing a NULL ISADevice argument. We can simplify and remove
the use of the global isabus object.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/isa-bus.c | 23 +--
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index c79d7e338b0..a19e3688c28 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -136,6 +136,10 @@ static inline void isa_init_ioport(ISADevice *dev, 
uint16_t ioport)
 
 void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
 {
+ISABus *isabus;
+
+assert(dev);
+isabus = isa_bus_from_device(dev);
 memory_region_add_subregion(isabus->address_space_io, start, io);
 isa_init_ioport(dev, start);
 }
@@ -156,6 +160,11 @@ void isa_register_portio_list(ISADevice *dev,
   const MemoryRegionPortio *pio_start,
   void *opaque, const char *name)
 {
+ISABus *isabus;
+
+assert(dev);
+isabus = isa_bus_from_device(dev);
+
 /* START is how we should treat DEV, regardless of the actual
contents of the portio array.  This is how the old code
actually handled e.g. the FDC device.  */
@@ -302,18 +311,20 @@ static char *isabus_get_fw_dev_path(DeviceState *dev)
 
 MemoryRegion *isa_address_space(ISADevice *dev)
 {
-if (dev) {
-return isa_bus_from_device(dev)->address_space;
-}
+ISABus *isabus;
+
+assert(dev);
+isabus = isa_bus_from_device(dev);
 
 return isabus->address_space;
 }
 
 MemoryRegion *isa_address_space_io(ISADevice *dev)
 {
-if (dev) {
-return isa_bus_from_device(dev)->address_space_io;
-}
+ISABus *isabus;
+
+assert(dev);
+isabus = isa_bus_from_device(dev);
 
 return isabus->address_space_io;
 }
-- 
2.26.3




[RFC PATCH 07/11] hw/isa: Simplify isa_get_irq()

2021-05-18 Thread Philippe Mathieu-Daudé
Previous commit removed the calls to isa_get_irq() passing a NULL
ISADevice. Simplify the assertion, removing the use on the global
isabus object.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/isa-bus.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index b946e6dc478..65a26ac6c2c 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -89,7 +89,11 @@ qemu_irq isa_bus_get_irq(ISABus *bus, unsigned isairq)
  */
 qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq)
 {
-assert(!dev || ISA_BUS(qdev_get_parent_bus(DEVICE(dev))) == isabus);
+ISABus *isabus;
+
+assert(dev);
+isabus = isa_bus_from_device(dev);
+
 return isa_bus_get_irq(isabus, isairq);
 }
 
-- 
2.26.3




[RFC PATCH 08/11] hw/isa: Extract bus part from isa_register_portio_list()

2021-05-18 Thread Philippe Mathieu-Daudé
isa_register_portio_list() takes an ISADevice argument mostly
to resolve the ISA bus. Extract the bus logic to a new function:
isa_bus_register_portio_list().

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/isa/isa.h |  4 
 hw/isa/isa-bus.c | 17 +
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index fd8b84d8007..ce31eef8858 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -139,6 +139,10 @@ void isa_register_portio_list(ISADevice *dev,
   uint16_t start,
   const MemoryRegionPortio *portio,
   void *opaque, const char *name);
+void isa_bus_register_portio_list(ISABus *isabus, Object *owner,
+  PortioList *piolist, uint16_t start,
+  const MemoryRegionPortio *portio,
+  void *opaque, const char *name);
 
 static inline ISABus *isa_bus_from_device(ISADevice *d)
 {
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 65a26ac6c2c..c79d7e338b0 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -140,20 +140,29 @@ void isa_register_ioport(ISADevice *dev, MemoryRegion 
*io, uint16_t start)
 isa_init_ioport(dev, start);
 }
 
+void isa_bus_register_portio_list(ISABus *isabus, Object *owner,
+  PortioList *piolist, uint16_t start,
+  const MemoryRegionPortio *portio,
+  void *opaque, const char *name)
+{
+assert(piolist && !piolist->owner);
+
+portio_list_init(piolist, owner, portio, opaque, name);
+portio_list_add(piolist, isabus->address_space_io, start);
+}
+
 void isa_register_portio_list(ISADevice *dev,
   PortioList *piolist, uint16_t start,
   const MemoryRegionPortio *pio_start,
   void *opaque, const char *name)
 {
-assert(piolist && !piolist->owner);
-
 /* START is how we should treat DEV, regardless of the actual
contents of the portio array.  This is how the old code
actually handled e.g. the FDC device.  */
 isa_init_ioport(dev, start);
 
-portio_list_init(piolist, OBJECT(dev), pio_start, opaque, name);
-portio_list_add(piolist, isabus->address_space_io, start);
+isa_bus_register_portio_list(isabus, OBJECT(dev), piolist, start,
+ pio_start, opaque, name);
 }
 
 static void isa_device_init(Object *obj)
-- 
2.26.3




[RFC PATCH 04/11] hw/ide/via: Set the ISA-bus QOM link

2021-05-18 Thread Philippe Mathieu-Daudé
Set the ISA Bus link property on the VIA IDE object from the
two unique users, the Fuloong and Pegasos machines.

Add a check in via_ide_realize() to be sure this property is set.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ide/via.c| 5 +
 hw/mips/fuloong2e.c | 4 
 hw/ppc/pegasos2.c   | 4 
 3 files changed, 13 insertions(+)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index 65fdca6dcf4..654e15edfed 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -165,6 +165,11 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
 uint8_t *pci_conf = dev->config;
 int i;
 
+if (!d->isa_bus) {
+error_setg(errp, "via-ide: 'isa-bus' link not set");
+return;
+}
+
 pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy mode */
 pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0);
 dev->wmask[PCI_INTERRUPT_LINE] = 0;
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 40e9a645e1b..7e644a701bc 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -201,12 +201,16 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, 
int slot, qemu_irq intc,
I2CBus **i2c_bus)
 {
 PCIDevice *dev;
+BusState *isa_bus;
 
 dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true,
   TYPE_VT82C686B_ISA);
+isa_bus = qdev_get_child_bus(DEVICE(dev), "isa.0");
 qdev_connect_gpio_out(DEVICE(dev), 0, intc);
 
 dev = pci_new(PCI_DEVFN(slot, 1), "via-ide");
+object_property_set_link(OBJECT(dev), "isa-bus",
+ OBJECT(isa_bus), &error_abort);
 pci_realize_and_unref(dev, pci_bus, &error_abort);
 pci_ide_create_devs(dev);
 
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 8486a2eb8c6..ed6ddc3569b 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -57,6 +57,7 @@ static void pegasos2_init(MachineState *machine)
 PCIBus *pci_bus;
 PCIDevice *dev;
 I2CBus *i2c_bus;
+BusState *isa_bus;
 const char *fwname = machine->firmware ?: PROM_FILENAME;
 char *filename;
 int sz;
@@ -104,11 +105,14 @@ static void pegasos2_init(MachineState *machine)
 /* VT8231 function 0: PCI-to-ISA Bridge */
 dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true,
   TYPE_VT8231_ISA);
+isa_bus = qdev_get_child_bus(DEVICE(dev), "isa.0");
 qdev_connect_gpio_out(DEVICE(dev), 0,
   qdev_get_gpio_in_named(mv, "gpp", 31));
 
 /* VT8231 function 1: IDE Controller */
 dev = pci_new(PCI_DEVFN(12, 1), "via-ide");
+object_property_set_link(OBJECT(dev), "isa-bus",
+ OBJECT(isa_bus), &error_abort);
 pci_realize_and_unref(dev, pci_bus, &error_abort);
 pci_ide_create_devs(dev);
 
-- 
2.26.3




[RFC PATCH 09/11] hw/ide: Let ide_init_ioport() take an ISA bus argument instead of device

2021-05-18 Thread Philippe Mathieu-Daudé
Both callers to ide_init_ioport() have access to the ISA bus of the
device, so can pass it directly. This allows ide_init_ioport() to
directly call isa_bus_register_portio_list().

Note, now the callers become the owner of the PortioList.

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/ide/internal.h |  3 ++-
 hw/ide/ioport.c   | 11 ++-
 hw/ide/isa.c  |  3 ++-
 hw/ide/piix.c |  4 ++--
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
index 2d09162eeb7..141f53006a9 100644
--- a/include/hw/ide/internal.h
+++ b/include/hw/ide/internal.h
@@ -624,7 +624,8 @@ int ide_init_drive(IDEState *s, BlockBackend *blk, 
IDEDriveKind kind,
int chs_trans, Error **errp);
 void ide_init2(IDEBus *bus, qemu_irq irq);
 void ide_exit(IDEState *s);
-void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2);
+void ide_init_ioport(IDEBus *bus, ISABus *isabus, Object *owner,
+ int iobase, int iobase2);
 void ide_register_restart_cb(IDEBus *bus);
 
 void ide_exec_cmd(IDEBus *bus, uint32_t val);
diff --git a/hw/ide/ioport.c b/hw/ide/ioport.c
index b613ff3bbaf..be2309459e1 100644
--- a/hw/ide/ioport.c
+++ b/hw/ide/ioport.c
@@ -50,15 +50,16 @@ static const MemoryRegionPortio ide_portio2_list[] = {
 PORTIO_END_OF_LIST(),
 };
 
-void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2)
+void ide_init_ioport(IDEBus *bus, ISABus *isabus, Object *owner,
+ int iobase, int iobase2)
 {
 /* ??? Assume only ISA and PCI configurations, and that the PCI-ISA
bridge has been setup properly to always register with ISA.  */
-isa_register_portio_list(dev, &bus->portio_list,
- iobase, ide_portio_list, bus, "ide");
+isa_bus_register_portio_list(isabus, owner, &bus->portio_list,
+iobase, ide_portio_list, bus, "ide");
 
 if (iobase2) {
-isa_register_portio_list(dev, &bus->portio2_list,
- iobase2, ide_portio2_list, bus, "ide");
+isa_bus_register_portio_list(isabus, owner, &bus->portio2_list,
+ iobase2, ide_portio2_list, bus, "ide");
 }
 }
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 6bc19de2265..e7cf6714c8f 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -74,7 +74,8 @@ static void isa_ide_realizefn(DeviceState *dev, Error **errp)
 ISAIDEState *s = ISA_IDE(dev);
 
 ide_bus_new(&s->bus, sizeof(s->bus), dev, 0, 2);
-ide_init_ioport(&s->bus, isadev, s->iobase, s->iobase2);
+ide_init_ioport(&s->bus, isa_bus_from_device(isadev), OBJECT(dev),
+s->iobase, s->iobase2);
 isa_init_irq(isadev, &s->irq, s->isairq);
 ide_init2(&s->bus, s->irq);
 vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_isa, s);
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index debbc0023dc..0d6966fc7cb 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -137,8 +137,8 @@ static void pci_piix_init_ports(PCIIDEState *d) {
 
 for (i = 0; i < 2; i++) {
 ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
-ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
-port_info[i].iobase2);
+ide_init_ioport(&d->bus[i], d->isa_bus, OBJECT(d),
+port_info[i].iobase, port_info[i].iobase2);
 ide_init2(&d->bus[i], isa_bus_get_irq(d->isa_bus, 
port_info[i].isairq));
 
 bmdma_init(&d->bus[i], &d->bmdma[i], d);
-- 
2.26.3




[RFC PATCH 11/11] hw/isa: Rename isabus singleton as 'g_isabus'

2021-05-18 Thread Philippe Mathieu-Daudé
To make explicit the isabus singleton isn't used anywhere else,
move it's static declaration locally to isa_bus_new() and rename
it as 'g_isabus'.

Unfortunately we provide the get_system_io() call which expose
an unique I/O bus to a machine, and the ISA bus rely on this I/O
bus, so we can not remove the ISA bus singleton until we remove
the get_system_io() API.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/isa-bus.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index a19e3688c28..422eb9615f4 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -26,8 +26,6 @@
 #include "sysemu/sysemu.h"
 #include "hw/isa/isa.h"
 
-static ISABus *isabus;
-
 static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 static char *isabus_get_fw_dev_path(DeviceState *dev);
 
@@ -55,7 +53,10 @@ static const TypeInfo isa_bus_info = {
 ISABus *isa_bus_new(DeviceState *dev, MemoryRegion* address_space,
 MemoryRegion *address_space_io, Error **errp)
 {
-if (isabus) {
+static ISABus *g_isabus;
+ISABus *isabus;
+
+if (g_isabus) {
 error_setg(errp, "Can't create a second ISA bus");
 return NULL;
 }
@@ -67,6 +68,7 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion* 
address_space,
 isabus = ISA_BUS(qbus_create(TYPE_ISA_BUS, dev, NULL));
 isabus->address_space = address_space;
 isabus->address_space_io = address_space_io;
+g_isabus = isabus;
 return isabus;
 }
 
-- 
2.26.3




[RFC PATCH 01/11] hw/isa: Explode pci_create_simple() calls

2021-05-18 Thread Philippe Mathieu-Daudé
To be able to set a property on the ISA-IDE bridges objects
before they are realized, explode the pci_create_simple()
calls as pci_new() + pci_realize_and_unref().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc_piix.c   | 5 +++--
 hw/isa/piix4.c  | 3 ++-
 hw/mips/fuloong2e.c | 3 ++-
 hw/ppc/pegasos2.c   | 3 ++-
 4 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 30b8bd6ea92..fb606c14768 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -244,8 +244,9 @@ static void pc_init1(MachineState *machine,
 if (pcmc->pci_enabled) {
 PCIDevice *dev;
 
-dev = pci_create_simple(pci_bus, piix3_devfn + 1,
-xen_enabled() ? "piix3-ide-xen" : "piix3-ide");
+dev = pci_new(piix3_devfn + 1,
+  xen_enabled() ? "piix3-ide-xen" : "piix3-ide");
+pci_realize_and_unref(dev, pci_bus, &error_abort);
 pci_ide_create_devs(dev);
 idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
 idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 0fe7b69bc4c..d60f161ecf4 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -261,7 +261,8 @@ DeviceState *piix4_create(PCIBus *pci_bus, ISABus 
**isa_bus, I2CBus **smbus)
 *isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
 }
 
-pci = pci_create_simple(pci_bus, devfn + 1, "piix4-ide");
+pci = pci_new(devfn + 1, "piix4-ide");
+pci_realize_and_unref(pci, pci_bus, &error_abort);
 pci_ide_create_devs(pci);
 
 pci_create_simple(pci_bus, devfn + 2, "piix4-usb-uhci");
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index c1b8066a13b..40e9a645e1b 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -206,7 +206,8 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int 
slot, qemu_irq intc,
   TYPE_VT82C686B_ISA);
 qdev_connect_gpio_out(DEVICE(dev), 0, intc);
 
-dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), "via-ide");
+dev = pci_new(PCI_DEVFN(slot, 1), "via-ide");
+pci_realize_and_unref(dev, pci_bus, &error_abort);
 pci_ide_create_devs(dev);
 
 pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci");
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 0bfd0928aa5..8486a2eb8c6 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -108,7 +108,8 @@ static void pegasos2_init(MachineState *machine)
   qdev_get_gpio_in_named(mv, "gpp", 31));
 
 /* VT8231 function 1: IDE Controller */
-dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), "via-ide");
+dev = pci_new(PCI_DEVFN(12, 1), "via-ide");
+pci_realize_and_unref(dev, pci_bus, &error_abort);
 pci_ide_create_devs(dev);
 
 /* VT8231 function 2-3: USB Ports */
-- 
2.26.3




[RFC PATCH 02/11] hw/ide: Add PCIIDEState::isa_bus link

2021-05-18 Thread Philippe Mathieu-Daudé
IDE bus depends on ISA bus for IRQ/DMA.

Add an ISABus reference in PCIIDEState, and add link properties
to it in the PIIX and VIA objects (which inherit PCI_IDE).

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/ide/pci.h |  1 +
 hw/ide/piix.c| 11 ++-
 hw/ide/via.c | 10 +-
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
index d8384e1c422..e790722ed14 100644
--- a/include/hw/ide/pci.h
+++ b/include/hw/ide/pci.h
@@ -47,6 +47,7 @@ struct PCIIDEState {
 PCIDevice parent_obj;
 /*< public >*/
 
+ISABus *isa_bus;
 IDEBus bus[2];
 BMDMAState bmdma[2];
 uint32_t secondary; /* used only for cmd646 */
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index b9860e35a5c..48da68da37f 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -30,8 +30,9 @@
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/dma.h"
-
+#include "qapi/error.h"
 #include "hw/ide/pci.h"
+#include "hw/isa/isa.h"
 #include "trace.h"
 
 static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size)
@@ -207,6 +208,12 @@ static void pci_piix_ide_exitfn(PCIDevice *dev)
 }
 }
 
+static Property piix_ide_properties[] = {
+DEFINE_PROP_LINK("isa-bus", PCIIDEState, isa_bus,
+ TYPE_ISA_BUS, ISABus *),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
 static void piix3_ide_class_init(ObjectClass *klass, void *data)
 {
@@ -221,6 +228,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void 
*data)
 k->class_id = PCI_CLASS_STORAGE_IDE;
 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 dc->hotpluggable = false;
+device_class_set_props(dc, piix_ide_properties);
 }
 
 static const TypeInfo piix3_ide_info = {
@@ -249,6 +257,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void 
*data)
 k->class_id = PCI_CLASS_STORAGE_IDE;
 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 dc->hotpluggable = false;
+device_class_set_props(dc, piix_ide_properties);
 }
 
 static const TypeInfo piix4_ide_info = {
diff --git a/hw/ide/via.c b/hw/ide/via.c
index be09912b334..65fdca6dcf4 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -28,8 +28,9 @@
 #include "hw/pci/pci.h"
 #include "migration/vmstate.h"
 #include "qemu/module.h"
+#include "qapi/error.h"
 #include "sysemu/dma.h"
-
+#include "hw/isa/isa.h"
 #include "hw/ide/pci.h"
 #include "trace.h"
 
@@ -210,6 +211,12 @@ static void via_ide_exitfn(PCIDevice *dev)
 }
 }
 
+static Property via_ide_properties[] = {
+DEFINE_PROP_LINK("isa-bus", PCIIDEState, isa_bus,
+ TYPE_ISA_BUS, ISABus *),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void via_ide_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -224,6 +231,7 @@ static void via_ide_class_init(ObjectClass *klass, void 
*data)
 k->revision = 0x06;
 k->class_id = PCI_CLASS_STORAGE_IDE;
 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+device_class_set_props(dc, via_ide_properties);
 }
 
 static const TypeInfo via_ide_info = {
-- 
2.26.3




[RFC PATCH 06/11] hw/ide: Replace isa_get_irq() by isa_bus_get_irq()

2021-05-18 Thread Philippe Mathieu-Daudé
Both PIIX/VIA objects inherit PCI_IDE, thus have a pointer to an
ISA bus. Pass this bus argument to isa_bus_get_irq() instead of
calling isa_get_irq() with a NULL device.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ide/piix.c | 2 +-
 hw/ide/via.c  | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 3aef9b1e21c..debbc0023dc 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -139,7 +139,7 @@ static void pci_piix_init_ports(PCIIDEState *d) {
 ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
 ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
 port_info[i].iobase2);
-ide_init2(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
+ide_init2(&d->bus[i], isa_bus_get_irq(d->isa_bus, 
port_info[i].isairq));
 
 bmdma_init(&d->bus[i], &d->bmdma[i], d);
 d->bmdma[i].bus = &d->bus[i];
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 654e15edfed..53545aac474 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -106,6 +106,7 @@ static void bmdma_setup_bar(PCIIDEState *d)
 static void via_ide_set_irq(void *opaque, int n, int level)
 {
 PCIDevice *d = PCI_DEVICE(opaque);
+PCIIDEState *id = PCI_IDE(d);
 
 if (level) {
 d->config[0x70 + n * 8] |= 0x80;
@@ -113,7 +114,7 @@ static void via_ide_set_irq(void *opaque, int n, int level)
 d->config[0x70 + n * 8] &= ~0x80;
 }
 
-qemu_set_irq(isa_get_irq(NULL, 14 + n), level);
+qemu_set_irq(isa_bus_get_irq(id->isa_bus, 14 + n), level);
 }
 
 static void via_ide_reset(DeviceState *dev)
-- 
2.26.3




[RFC PATCH 05/11] hw/isa: Extract isa_bus_get_irq() from isa_get_irq()

2021-05-18 Thread Philippe Mathieu-Daudé
isa_get_irq() takes an ISADevice argument mostly to resolve
the ISA bus. Extract the bus logic to isa_bus_get_irq().

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/isa/isa.h | 1 +
 hw/isa/isa-bus.c | 9 +++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index ddaae89a853..fd8b84d8007 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -91,6 +91,7 @@ struct ISADevice {
 ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space,
 MemoryRegion *address_space_io, Error **errp);
 void isa_bus_irqs(ISABus *bus, qemu_irq *irqs);
+qemu_irq isa_bus_get_irq(ISABus *bus, unsigned isairq);
 qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq);
 void isa_init_irq(ISADevice *dev, qemu_irq *p, unsigned isairq);
 void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, unsigned isairq);
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 7820068e6e1..b946e6dc478 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -75,6 +75,12 @@ void isa_bus_irqs(ISABus *bus, qemu_irq *irqs)
 bus->irqs = irqs;
 }
 
+qemu_irq isa_bus_get_irq(ISABus *bus, unsigned isairq)
+{
+assert(isairq < ISA_NUM_IRQS);
+return bus->irqs[isairq];
+}
+
 /*
  * isa_get_irq() returns the corresponding qemu_irq entry for the i8259.
  *
@@ -84,8 +90,7 @@ void isa_bus_irqs(ISABus *bus, qemu_irq *irqs)
 qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq)
 {
 assert(!dev || ISA_BUS(qdev_get_parent_bus(DEVICE(dev))) == isabus);
-assert(isairq < ISA_NUM_IRQS);
-return isabus->irqs[isairq];
+return isa_bus_get_irq(isabus, isairq);
 }
 
 void isa_init_irq(ISADevice *dev, qemu_irq *p, unsigned isairq)
-- 
2.26.3




[RFC PATCH 03/11] hw/ide/piix: Set the ISA-bus QOM link

2021-05-18 Thread Philippe Mathieu-Daudé
Set the ISA Bus link property on the PIIX IDE object from the
two unique users, the PC machine and the PIIX4 function.

Add a check in pci_piix_ide_realize() to be sure this property
is set.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc_piix.c |  2 ++
 hw/ide/piix.c |  5 +
 hw/isa/piix4.c| 10 +++---
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index fb606c14768..d799c8004df 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -246,6 +246,8 @@ static void pc_init1(MachineState *machine,
 
 dev = pci_new(piix3_devfn + 1,
   xen_enabled() ? "piix3-ide-xen" : "piix3-ide");
+object_property_set_link(OBJECT(dev), "isa-bus",
+ OBJECT(isa_bus), &error_abort);
 pci_realize_and_unref(dev, pci_bus, &error_abort);
 pci_ide_create_devs(dev);
 idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 48da68da37f..3aef9b1e21c 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -152,6 +152,11 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error 
**errp)
 PCIIDEState *d = PCI_IDE(dev);
 uint8_t *pci_conf = dev->config;
 
+if (!d->isa_bus) {
+error_setg(errp, "piix-ide: 'isa-bus' link not set");
+return;
+}
+
 pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
 
 bmdma_setup_bar(d);
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index d60f161ecf4..ef11c2d1f8d 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -248,20 +248,24 @@ static void piix4_register_types(void)
 
 type_init(piix4_register_types)
 
-DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus)
+DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_busp, I2CBus **smbus)
 {
 PCIDevice *pci;
 DeviceState *dev;
+ISABus *isa_bus;
 int devfn = PCI_DEVFN(10, 0);
 
 pci = pci_create_simple_multifunction(pci_bus, devfn,  true,
   TYPE_PIIX4_PCI_DEVICE);
 dev = DEVICE(pci);
-if (isa_bus) {
-*isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
+isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
+if (isa_busp) {
+*isa_busp = isa_bus;
 }
 
 pci = pci_new(devfn + 1, "piix4-ide");
+object_property_set_link(OBJECT(pci), "isa-bus",
+ OBJECT(isa_bus), &error_abort);
 pci_realize_and_unref(pci, pci_bus, &error_abort);
 pci_ide_create_devs(pci);
 
-- 
2.26.3




[RFC PATCH 00/11] hw/isa: Remove dependencies on ISA bus singleton

2021-05-18 Thread Philippe Mathieu-Daudé
Hi,

This series implements the suggestions from Markus analysis:
https://www.mail-archive.com/qemu-block@nongnu.org/msg84090.html
on the ISA bus.

There is still work to do (remove global get_system_io?) but
this is enough to convert a crash to an error message, and
the changes are simple, so posting now as RFC.

TBC...

Philippe Mathieu-Daudé (11):
  hw/isa: Explode pci_create_simple() calls
  hw/ide: Add PCIIDEState::isa_bus link
  hw/ide/piix: Set the ISA-bus QOM link
  hw/ide/via: Set the ISA-bus QOM link
  hw/isa: Extract isa_bus_get_irq() from isa_get_irq()
  hw/ide: Replace isa_get_irq() by isa_bus_get_irq()
  hw/isa: Simplify isa_get_irq()
  hw/isa: Extract bus part from isa_register_portio_list()
  hw/ide: Let ide_init_ioport() take an ISA bus argument instead of
device
  hw/isa: Remove use of global isa bus
  hw/isa: Rename isabus singleton as 'g_isabus'

 include/hw/ide/internal.h |  3 +-
 include/hw/ide/pci.h  |  1 +
 include/hw/isa/isa.h  |  5 
 hw/i386/pc_piix.c |  7 +++--
 hw/ide/ioport.c   | 11 +++
 hw/ide/isa.c  |  3 +-
 hw/ide/piix.c | 22 +++---
 hw/ide/via.c  | 18 ++--
 hw/isa/isa-bus.c  | 61 +--
 hw/isa/piix4.c| 13 ++---
 hw/mips/fuloong2e.c   |  7 -
 hw/ppc/pegasos2.c |  7 -
 12 files changed, 122 insertions(+), 36 deletions(-)

-- 
2.26.3





Re: [PATCH v3 0/5] Add support for PMBus in QEMU

2021-05-18 Thread Titus Rwantare
That would be great.

On Tue, 18 May 2021, 16:59 Corey Minyard,  wrote:
>
> On Tue, May 18, 2021 at 03:50:57PM -0400, Titus Rwantare wrote:
> > I would also like a directory for sensors. There are quite a few of
> > those incoming. Any objections?
>
> None from me.  I'll add a patch to move all the sensors from misc into
> it, if you like.



[PATCH v2 5/7] virtiofsd: Simplify skip byte logic

2021-05-18 Thread Vivek Goyal
We need to skip bytes in two cases.

a. Before we start reading into in_sg, we need to skip iov_len bytes
   in the beginning which typically will have fuse_out_header.

b. If preadv() does a short read, then we need to retry preadv() with
   remainig bytes and skip the bytes preadv() read in short read.

For case a, there is no reason that skipping logic be inside the while
loop. Move it outside. And only retain logic "b" inside while loop.

Also get rid of variable "skip_size". Looks like we can do without it.

Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Connor Kuehl 
Signed-off-by: Vivek Goyal 
---
 tools/virtiofsd/fuse_virtio.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index ed5146d7a6..49c7dd788a 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -392,17 +392,11 @@ int virtio_send_data_iov(struct fuse_session *se, struct 
fuse_chan *ch,
 unsigned int in_sg_cpy_count = in_num;
 
 /* skip over parts of in_sg that contained the header iov */
-size_t skip_size = iov_len;
+iov_discard_front(&in_sg_ptr, &in_sg_cpy_count, iov_len);
 
 do {
-if (skip_size != 0) {
-iov_discard_front(&in_sg_ptr, &in_sg_cpy_count, skip_size);
-}
-
-fuse_log(FUSE_LOG_DEBUG,
- "%s: after skip skip_size=%zd in_sg_cpy_count=%d "
- "len remaining=%zd\n", __func__, skip_size, in_sg_cpy_count,
- len);
+fuse_log(FUSE_LOG_DEBUG, "%s: in_sg_cpy_count=%d len remaining=%zd\n",
+ __func__, in_sg_cpy_count, len);
 
 ret = preadv(buf->buf[0].fd, in_sg_ptr, in_sg_cpy_count,
  buf->buf[0].pos);
@@ -421,7 +415,7 @@ int virtio_send_data_iov(struct fuse_session *se, struct 
fuse_chan *ch,
 if (ret < len && ret) {
 fuse_log(FUSE_LOG_DEBUG, "%s: ret < len\n", __func__);
 /* Skip over this much next time around */
-skip_size = ret;
+iov_discard_front(&in_sg_ptr, &in_sg_cpy_count, ret);
 buf->buf[0].pos += ret;
 len -= ret;
 
-- 
2.25.4




[PATCH v2 2/7] virtiofsd: Get rid of unreachable code in read

2021-05-18 Thread Vivek Goyal
pvreadv() can return following.

- error
- 0 in case of EOF
- short read

We seem to handle all the cases already. We are retrying read in case
of short read. So another check for short read seems like dead code.
Get rid of it.

Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Connor Kuehl 
Signed-off-by: Vivek Goyal 
---
 tools/virtiofsd/fuse_virtio.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index 755d7fb25c..28e2974d1a 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -446,11 +446,6 @@ int virtio_send_data_iov(struct fuse_session *se, struct 
fuse_chan *ch,
  in_sg_left);
 break;
 }
-if (ret != len) {
-fuse_log(FUSE_LOG_DEBUG, "%s: ret!=len\n", __func__);
-ret = EIO;
-goto err;
-}
 in_sg_left -= ret;
 len -= ret;
 } while (in_sg_left);
-- 
2.25.4




[PATCH v2 1/7] virtiofsd: Check for EINTR in preadv() and retry

2021-05-18 Thread Vivek Goyal
We don't seem to check for EINTR and retry. There are other places
in code where we check for EINTR. So lets add a check.

Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Connor Kuehl 
Signed-off-by: Vivek Goyal 
---
 tools/virtiofsd/fuse_virtio.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index 9efdbd8ffd..755d7fb25c 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -421,6 +421,9 @@ int virtio_send_data_iov(struct fuse_session *se, struct 
fuse_chan *ch,
 
 if (ret == -1) {
 ret = errno;
+if (ret == EINTR) {
+continue;
+}
 fuse_log(FUSE_LOG_DEBUG, "%s: preadv failed (%m) len=%zd\n",
  __func__, len);
 goto err;
-- 
2.25.4




[PATCH v2 7/7] virtiofsd: Set req->reply_sent right after sending reply

2021-05-18 Thread Vivek Goyal
There is no reason to set it in label "err". We should be able to set
it right after sending reply. It is easier to read.

Also got rid of label "err" because now only thing it was doing was
return a code. We can return from the error location itself and no
need to first jump to label "err".

Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Connor Kuehl 
Signed-off-by: Vivek Goyal 
---
 tools/virtiofsd/fuse_virtio.c | 19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index 99f91c9d87..fa4aff9b0e 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -366,14 +366,12 @@ int virtio_send_data_iov(struct fuse_session *se, struct 
fuse_chan *ch,
 if (in_len < sizeof(struct fuse_out_header)) {
 fuse_log(FUSE_LOG_ERR, "%s: elem %d too short for out_header\n",
  __func__, elem->index);
-ret = E2BIG;
-goto err;
+return E2BIG;
 }
 if (in_len < tosend_len) {
 fuse_log(FUSE_LOG_ERR, "%s: elem %d too small for data len %zd\n",
  __func__, elem->index, tosend_len);
-ret = E2BIG;
-goto err;
+return E2BIG;
 }
 
 /* TODO: Limit to 'len' */
@@ -408,7 +406,7 @@ int virtio_send_data_iov(struct fuse_session *se, struct 
fuse_chan *ch,
 }
 fuse_log(FUSE_LOG_DEBUG, "%s: preadv failed (%m) len=%zd\n",
  __func__, len);
-goto err;
+return ret;
 }
 
 if (!ret) {
@@ -438,21 +436,14 @@ int virtio_send_data_iov(struct fuse_session *se, struct 
fuse_chan *ch,
 out_sg->len = tosend_len;
 }
 
-ret = 0;
-
 vu_dispatch_rdlock(qi->virtio_dev);
 pthread_mutex_lock(&qi->vq_lock);
 vu_queue_push(dev, q, elem, tosend_len);
 vu_queue_notify(dev, q);
 pthread_mutex_unlock(&qi->vq_lock);
 vu_dispatch_unlock(qi->virtio_dev);
-
-err:
-if (ret == 0) {
-req->reply_sent = true;
-}
-
-return ret;
+req->reply_sent = true;
+return 0;
 }
 
 static __thread bool clone_fs_called;
-- 
2.25.4




[PATCH v2 0/7] virtiofsd: Few cleanups in virtio_send_data_iov()

2021-05-18 Thread Vivek Goyal
Hi,

This is V2 of the patches. Changes since V1 are.

- Took care of coding style issue.
- Got rid of label "err" completely in last patch. (Dave, Connor). 
- Captured Reviewed-by tags from Connor and David.

Code in virtio_send_data_iov() little twisted and complicated. This
patch series just tries to simplify it a bit to make it little easier
to read this piece of code.

Thanks
Vivek


Vivek Goyal (7):
  virtiofsd: Check for EINTR in preadv() and retry
  virtiofsd: Get rid of unreachable code in read
  virtiofsd: Use iov_discard_front() to skip bytes
  virtiofsd: get rid of in_sg_left variable
  virtiofsd: Simplify skip byte logic
  virtiofsd: Check EOF before short read
  virtiofsd: Set req->reply_sent right after sending reply

 tools/virtiofsd/fuse_virtio.c | 81 +++
 1 file changed, 25 insertions(+), 56 deletions(-)

-- 
2.25.4




[PATCH v2 6/7] virtiofsd: Check EOF before short read

2021-05-18 Thread Vivek Goyal
In virtio_send_data_iov() we are checking first for short read and then
EOF condition. Change the order. Basically check for error and EOF first
and last remaining piece is short ready which will lead to retry
automatically at the end of while loop.

Just that it is little simpler to read to the code. There is no need
to call "continue" and also one less call of "len-=ret".

Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Connor Kuehl 
Signed-off-by: Vivek Goyal 
---
 tools/virtiofsd/fuse_virtio.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index 49c7dd788a..99f91c9d87 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -410,25 +410,24 @@ int virtio_send_data_iov(struct fuse_session *se, struct 
fuse_chan *ch,
  __func__, len);
 goto err;
 }
-fuse_log(FUSE_LOG_DEBUG, "%s: preadv ret=%d len=%zd\n", __func__,
- ret, len);
-if (ret < len && ret) {
-fuse_log(FUSE_LOG_DEBUG, "%s: ret < len\n", __func__);
-/* Skip over this much next time around */
-iov_discard_front(&in_sg_ptr, &in_sg_cpy_count, ret);
-buf->buf[0].pos += ret;
-len -= ret;
 
-/* Lets do another read */
-continue;
-}
 if (!ret) {
 /* EOF case? */
 fuse_log(FUSE_LOG_DEBUG, "%s: !ret len remaining=%zd\n", __func__,
  len);
 break;
 }
+fuse_log(FUSE_LOG_DEBUG, "%s: preadv ret=%d len=%zd\n", __func__,
+ ret, len);
+
 len -= ret;
+/* Short read. Retry reading remaining bytes */
+if (len) {
+fuse_log(FUSE_LOG_DEBUG, "%s: ret < len\n", __func__);
+/* Skip over this much next time around */
+iov_discard_front(&in_sg_ptr, &in_sg_cpy_count, ret);
+buf->buf[0].pos += ret;
+}
 } while (len);
 
 /* Need to fix out->len on EOF */
-- 
2.25.4




[PATCH v2 4/7] virtiofsd: get rid of in_sg_left variable

2021-05-18 Thread Vivek Goyal
in_sg_left seems to be being used primarly for debugging purpose. It is
keeping track of how many bytes are left in the scatter list we are
reading into.

We already have another variable "len" which keeps track how many bytes
are left to be read. And in_sg_left is greater than or equal to len. We
have already ensured that in the beginning of function.

if (in_len < tosend_len) {
fuse_log(FUSE_LOG_ERR, "%s: elem %d too small for data len %zd\n",
 __func__, elem->index, tosend_len);
ret = E2BIG;
goto err;
}

So in_sg_left seems like a redundant variable. It probably was useful for
debugging when code was being developed. Get rid of it. It helps simplify
this function.

Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Connor Kuehl 
Signed-off-by: Vivek Goyal 
---
 tools/virtiofsd/fuse_virtio.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index 09674f2e90..ed5146d7a6 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -394,20 +394,16 @@ int virtio_send_data_iov(struct fuse_session *se, struct 
fuse_chan *ch,
 /* skip over parts of in_sg that contained the header iov */
 size_t skip_size = iov_len;
 
-size_t in_sg_left = 0;
 do {
 if (skip_size != 0) {
 iov_discard_front(&in_sg_ptr, &in_sg_cpy_count, skip_size);
 }
 
-int i;
-for (i = 0, in_sg_left = 0; i < in_sg_cpy_count; i++) {
-in_sg_left += in_sg_ptr[i].iov_len;
-}
 fuse_log(FUSE_LOG_DEBUG,
  "%s: after skip skip_size=%zd in_sg_cpy_count=%d "
- "in_sg_left=%zd\n",
- __func__, skip_size, in_sg_cpy_count, in_sg_left);
+ "len remaining=%zd\n", __func__, skip_size, in_sg_cpy_count,
+ len);
+
 ret = preadv(buf->buf[0].fd, in_sg_ptr, in_sg_cpy_count,
  buf->buf[0].pos);
 
@@ -434,13 +430,12 @@ int virtio_send_data_iov(struct fuse_session *se, struct 
fuse_chan *ch,
 }
 if (!ret) {
 /* EOF case? */
-fuse_log(FUSE_LOG_DEBUG, "%s: !ret in_sg_left=%zd\n", __func__,
- in_sg_left);
+fuse_log(FUSE_LOG_DEBUG, "%s: !ret len remaining=%zd\n", __func__,
+ len);
 break;
 }
-in_sg_left -= ret;
 len -= ret;
-} while (in_sg_left);
+} while (len);
 
 /* Need to fix out->len on EOF */
 if (len) {
-- 
2.25.4




[PATCH v2 3/7] virtiofsd: Use iov_discard_front() to skip bytes

2021-05-18 Thread Vivek Goyal
There are places where we need to skip few bytes from front of the iovec
array. We have our own custom code for that. Looks like iov_discard_front()
can do same thing. So use that helper instead.

Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Connor Kuehl 
Signed-off-by: Vivek Goyal 
---
 tools/virtiofsd/fuse_virtio.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index 28e2974d1a..09674f2e90 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -389,23 +389,15 @@ int virtio_send_data_iov(struct fuse_session *se, struct 
fuse_chan *ch,
 memcpy(in_sg_cpy, in_sg, sizeof(struct iovec) * in_num);
 /* These get updated as we skip */
 struct iovec *in_sg_ptr = in_sg_cpy;
-int in_sg_cpy_count = in_num;
+unsigned int in_sg_cpy_count = in_num;
 
 /* skip over parts of in_sg that contained the header iov */
 size_t skip_size = iov_len;
 
 size_t in_sg_left = 0;
 do {
-while (skip_size != 0 && in_sg_cpy_count) {
-if (skip_size >= in_sg_ptr[0].iov_len) {
-skip_size -= in_sg_ptr[0].iov_len;
-in_sg_ptr++;
-in_sg_cpy_count--;
-} else {
-in_sg_ptr[0].iov_len -= skip_size;
-in_sg_ptr[0].iov_base += skip_size;
-break;
-}
+if (skip_size != 0) {
+iov_discard_front(&in_sg_ptr, &in_sg_cpy_count, skip_size);
 }
 
 int i;
-- 
2.25.4




[PATCH 2/2] esp: only set ESP_RSEQ at the start of the select sequence

2021-05-18 Thread Mark Cave-Ayland
When processing a command to select a target and send a CDB, the ESP device
maintains a sequence step register so that if an error occurs the host can
determine which part of the selection/CDB submission sequence failed.

The old Linux 2.6 driver is really pedantic here: it checks the sequence step
register even if a command succeeds and complains loudly on the console if the
sequence step register doesn't match the expected bus phase and interrupt flags.

This reason this mismatch occurs is because the ESP emulation currently doesn't
update the bus phase until the next TI (Transfer Information) command and so the
cleared sequence step register is considered invalid for the stale bus phase.

Normally this isn't an issue as the host only checks the sequence step register
if an error occurs but the old Linux 2.6 driver does this in several places
causing a large stream of "esp0: STEP_ASEL for tgt 0" messages to appear on the
console during the boot process.

Fix this by not clearing the sequence step register when reading the interrupt
register and clearing the DMA status, so the guest sees a valid sequence step
and bus phase combination at the end of the command phase. No other change is
required since the sequence step register is correctly updated throughout the
selection/CDB submission sequence once one of the select commands is issued.

Signed-off-by: Mark Cave-Ayland 
Fixes: 1b9e48a5bd ("esp: implement non-DMA transfers in PDMA mode")
---
 hw/scsi/esp.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 000e45a624..18d4d56392 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -481,7 +481,6 @@ static void esp_dma_done(ESPState *s)
 {
 s->rregs[ESP_RSTAT] |= STAT_TC;
 s->rregs[ESP_RINTR] |= INTR_BS;
-s->rregs[ESP_RSEQ] = 0;
 s->rregs[ESP_RFLAGS] = 0;
 esp_set_tc(s, 0);
 esp_raise_irq(s);
@@ -917,7 +916,15 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
 val = s->rregs[ESP_RINTR];
 s->rregs[ESP_RINTR] = 0;
 s->rregs[ESP_RSTAT] &= ~STAT_TC;
-s->rregs[ESP_RSEQ] = SEQ_0;
+/*
+ * According to the datasheet ESP_RSEQ should be cleared, but as the
+ * emulation currently defers information transfers to the next TI
+ * command leave it for now so that pedantic guests such as the old
+ * Linux 2.6 driver see the correct flags before the next SCSI phase
+ * transition.
+ *
+ * s->rregs[ESP_RSEQ] = SEQ_0;
+ */
 esp_lower_irq(s);
 break;
 case ESP_TCHI:
-- 
2.20.1




[PATCH 0/2] esp: minor fixes for older Linux versions

2021-05-18 Thread Mark Cave-Ayland
Following on from the ESP changes in QEMU 6.0 someone pointed out that the old
Linux 2.6 ESP driver as used in Aurelian's SPARC image at
https://people.debian.org/~aurel32/qemu/sparc/ emits a constant stream of
"esp0: STEP_ASEL for tgt 0" messages to the console during boot.

These patches solve the issue so that the older image is able to boot cleanly
once again. The first patch is a genuine bug fix for the QEMU 6.0 changes whilst
the second works around the delayed bus phase change when deferring IO transfers
from the end of the command phase to the start of the information transfer
phase.

I've tested this using the extended suite of images used for the QEMU 6.0 
changes
and confirmed that there are no other regressions.

Signed-off-by: Mark Cave-Ayland 


Mark Cave-Ayland (2):
  esp: only assert INTR_DC interrupt flag if selection fails
  esp: only set ESP_RSEQ at the start of the select sequence

 hw/scsi/esp.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

-- 
2.20.1




[PATCH 1/2] esp: only assert INTR_DC interrupt flag if selection fails

2021-05-18 Thread Mark Cave-Ayland
The datasheet sequence tables confirm that when a target selection fails, only
the INTR_DC interrupt flag should be asserted.

Signed-off-by: Mark Cave-Ayland 
Fixes: cf47a41e05 ("esp: latch individual bits in ESP_RINTR register")
---
 hw/scsi/esp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index b668acef82..000e45a624 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -213,7 +213,7 @@ static int esp_select(ESPState *s)
 if (!s->current_dev) {
 /* No such drive */
 s->rregs[ESP_RSTAT] = 0;
-s->rregs[ESP_RINTR] |= INTR_DC;
+s->rregs[ESP_RINTR] = INTR_DC;
 s->rregs[ESP_RSEQ] = SEQ_0;
 esp_raise_irq(s);
 return -1;
-- 
2.20.1




[PATCH qemu] Add basic power management to raspi.

2021-05-18 Thread ~nolanl
From: Nolan Leake 

This is just enough to make reboot and poweroff work. Notably, the
watchdog timer functionality is not yet implemented.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
Signed-off-by: Nolan Leake 
---
 hw/arm/bcm2835_peripherals.c |  13 ++-
 hw/misc/bcm2835_powermgt.c   | 157 +++
 hw/misc/meson.build  |   1 +
 include/hw/arm/bcm2835_peripherals.h |   3 +-
 include/hw/misc/bcm2835_powermgt.h   |  29 +
 5 files changed, 201 insertions(+), 2 deletions(-)
 create mode 100644 hw/misc/bcm2835_powermgt.c
 create mode 100644 include/hw/misc/bcm2835_powermgt.h

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index dcff13433e..48538c9360 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -126,6 +126,10 @@ static void bcm2835_peripherals_init(Object *obj)
 
 object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
OBJECT(&s->gpu_bus_mr));
+
+/* Power Management */
+object_initialize_child(obj, "powermgt", &s->powermgt,
+TYPE_BCM2835_POWERMGT);
 }
 
 static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
@@ -364,9 +368,16 @@ static void bcm2835_peripherals_realize(DeviceState *dev, 
Error **errp)
 qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
INTERRUPT_USB));
 
+/* Power Management */
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
+return;
+}
+
+memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
+
 create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
 create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 
0x40);
-create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
 create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
 create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
 create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
new file mode 100644
index 00..81107ecc8f
--- /dev/null
+++ b/hw/misc/bcm2835_powermgt.c
@@ -0,0 +1,157 @@
+/*
+ * BCM2835 Power Management emulation
+ *
+ * Copyright (C) 2017 Marcin Chojnacki 
+ * Copyright (C) 2021 Nolan Leake 
+ *
+ * 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/log.h"
+#include "qemu/module.h"
+#include "hw/misc/bcm2835_powermgt.h"
+#include "migration/vmstate.h"
+#include "sysemu/runstate.h"
+
+#define PASSWORD 0x5a00
+#define PASSWORD_MASK 0xff00
+
+#define R_RSTC 0x1c
+#define V_RSTC_RESET 0x20
+#define R_RSTS 0x20
+#define V_RSTS_POWEROFF 0x555
+#define R_WDOG 0x24
+
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
+  unsigned size)
+{
+BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
+uint32_t res = 0;
+
+assert(size == 4);
+
+switch (offset) {
+case R_RSTC:
+res = s->rstc;
+break;
+case R_RSTS:
+res = s->rsts;
+break;
+case R_WDOG:
+res = s->wdog;
+break;
+
+default:
+qemu_log_mask(LOG_UNIMP,
+  "bcm2835_powermgt_read: Unknown offset %x\n",
+  (int)offset);
+res = 0;
+break;
+}
+
+return res;
+}
+
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
+   uint64_t value, unsigned size)
+{
+BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
+
+assert(size == 4);
+
+if ((value & PASSWORD_MASK) != PASSWORD) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "bcm2835_powermgt_write: Bad password %x at offset %x\n",
+  (uint32_t)value, (int)offset);
+return;
+}
+
+value = value & ~PASSWORD_MASK;
+
+switch (offset) {
+case R_RSTC:
+s->rstc = value;
+if (value & V_RSTC_RESET) {
+if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
+/* Linux uses partition 63 to indicate halt. */
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+} else {
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+}
+}
+break;
+case R_RSTS:
+s->rsts = value;
+break;
+case R_WDOG:
+s->wdog = value;
+break;
+
+default:
+qemu_log_mask(LOG_UNIMP,
+  "bcm2835_powermgt_write: Unknown offset %x\n",
+  (int)offset);
+break;
+}
+}
+
+static const MemoryRegionOps bcm2835_powermgt_ops = {
+.read = bcm2835_powermgt_read,
+.write = bcm2835_powermgt_write,
+   

Re: [PATCH] hw/ide: Fix crash when plugging a piix3-ide device into the x-remote machine

2021-05-18 Thread John Snow

On 4/28/21 5:32 AM, Thomas Huth wrote:

On 28/04/2021 11.24, Stefan Hajnoczi wrote:

On Fri, Apr 16, 2021 at 02:52:56PM +0200, Thomas Huth wrote:
@@ -158,7 +166,11 @@ static void pci_piix_ide_realize(PCIDevice *dev, 
Error **errp)

  vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_pci, d);
-    pci_piix_init_ports(d);
+    rc = pci_piix_init_ports(d);
+    if (rc) {
+    error_setg_errno(errp, -rc, "Failed to realize %s",
+ object_get_typename(OBJECT(dev)));
+    }


Is there an error message explaining the reason for the failure
somewhere. I can't see one in the patch and imagine users will be
puzzled/frustrated by a generic "Failed to realize" error message. Can
you make it more meaningful?


Do you have a suggestion for a better message?

  Thomas



Hi Thomas. Looks like there's some more discussion, and Philippe has a 
counter-proposal he wants to send.


I guess I'll de-queue this for now, and I'll see you on the review for 
Philippe's series?


--js




Re: [PATCH v3 0/5] Add support for PMBus in QEMU

2021-05-18 Thread Corey Minyard
On Tue, May 18, 2021 at 03:50:57PM -0400, Titus Rwantare wrote:
> I would also like a directory for sensors. There are quite a few of
> those incoming. Any objections?

None from me.  I'll add a patch to move all the sensors from misc into
it, if you like.

-corey

> 
> -Titus
> 
> On Tue, 18 May 2021 at 15:45, Corey Minyard  wrote:
> >
> > On Tue, May 18, 2021 at 11:45:22AM -0700, Titus Rwantare wrote:
> > > Hello,
> > >
> > > This patch series adds an interface to start supporting PMBus devices in 
> > > QEMU.
> > > I’ve included two PMBus devices: MAX34451 and ADM1272.
> >
> > I've reviewed all these patches, and beyond my one comment, they look
> > good.
> >
> > I'm not too excited about putting the device files in misc.  I know some
> > SMBus sensors are in there, but they really aren't miscellaneous.  They
> > are really sensors.  But unless we want to create a sensors directory
> > and move things into that, misc will have to do, I guess.
> >
> > -corey
> >
> > >
> > > PMBus is a variant of SMBus meant for digital management of power 
> > > supplies.
> > > PMBus adds to the SMBus standard by defining a number of constants and 
> > > commands
> > > used by compliant devices. The specification for PMBus can be found at:
> > >
> > > https://pmbus.org/specification-archives/
> > >
> > > Currently, the goal for these devices is to emulate basic functionality by
> > > reading and writing registers. Timing, and some logical operation is not
> > > implemented. This implementation supports nearly all available registers 
> > > for
> > > PMBus including:
> > >- Voltage inputs and outputs
> > >- Current inputs and outputs
> > >- Temperature sensors
> > >
> > > Unimplimented registers get passed through to the device model, and device
> > > models can opt out of using the standard registers with flags. The 
> > > included
> > > devices make use of these fields and illustrate how to interface with the 
> > > pmbus
> > > class.
> > >
> > > Datasheets for sensors:
> > >
> > > https://datasheets.maximintegrated.com/en/ds/MAX34451.pdf
> > > https://www.analog.com/media/en/technical-documentation/data-sheets/ADM1272.pdf
> > >
> > > Since v2:
> > > - bump for feedback
> > > - removed commented out code
> > >
> > > Since v1:
> > > - addressed Joel's comments
> > > - split out tests into their own patches
> > >
> > > Thanks for reviewing,
> > >
> > > Titus Rwantare
> > >
> > > Titus Rwantare (5):
> > >   hw/i2c: add support for PMBus
> > >   hw/misc: add ADM1272 device
> > >   tests/qtest: add tests for ADM1272 device model
> > >   hw/misc: add MAX34451 device
> > >   tests/qtest: add tests for MAX34451 device model
> > >
> > >  include/hw/i2c/pmbus_device.h |  506 +++
> > >  hw/i2c/pmbus_device.c | 1596 +
> > >  hw/misc/adm1272.c |  543 +++
> > >  hw/misc/max34451.c|  716 +++
> > >  tests/qtest/adm1272-test.c|  445 +
> > >  tests/qtest/max34451-test.c   |  336 +++
> > >  hw/arm/Kconfig|3 +
> > >  hw/i2c/Kconfig|4 +
> > >  hw/i2c/meson.build|1 +
> > >  hw/misc/Kconfig   |8 +
> > >  hw/misc/meson.build   |2 +
> > >  tests/qtest/meson.build   |2 +
> > >  12 files changed, 4162 insertions(+)
> > >  create mode 100644 include/hw/i2c/pmbus_device.h
> > >  create mode 100644 hw/i2c/pmbus_device.c
> > >  create mode 100644 hw/misc/adm1272.c
> > >  create mode 100644 hw/misc/max34451.c
> > >  create mode 100644 tests/qtest/adm1272-test.c
> > >  create mode 100644 tests/qtest/max34451-test.c
> > >
> > > --
> > > 2.31.1.751.gd2f1c929bd-goog
> > >



Re: [PULL 00/59] Linux user for 6.1 patches

2021-05-18 Thread Peter Maydell
On Tue, 18 May 2021 at 06:33, Laurent Vivier  wrote:
>
> The following changes since commit 6d34aa9969ff85ca6eaeb4dc1988a4d4e13e7d79:
>
>   Merge remote-tracking branch 'remotes/marcandre/tags/rtd-pull-request' into 
> staging (2021-05-14 17:20:08 +0100)
>
> are available in the Git repository at:
>
>   git://github.com/vivier/qemu.git tags/linux-user-for-6.1-pull-request
>
> for you to fetch changes up to 4a1e8931eca05077afd0b7ed092ab0f10c5b457e:
>
>   linux-user/elfload: add s390x core dumping support (2021-05-18 07:10:46 
> +0200)
>
> 
> linux-user pull request 20210517
>
> - alpha sigaction fixes/cleanups
> - s390x sigaction fixes/cleanup
> - sparc sigaction fixes/cleanup
> - s390x core dumping support
> - core dump fix (app name)
> - arm  fpa11 fix and cleanup
> - strace fixes (unshare(), llseek())
> - fix copy_file_range()
> - use GDateTime
> - Remove dead code
>


Applied, thanks.

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

-- PMM



[PATCH 24/24] target/ppc: Restrict ppc_cpu_tlb_fill to TCG

2021-05-18 Thread Richard Henderson
This function is used by TCGCPUOps, and is thus TCG specific.

Signed-off-by: Richard Henderson 
---
 target/ppc/mmu_helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index 2535ea1836..78e6f7496b 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -2964,6 +2964,7 @@ hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 return -1;
 }
 
+#ifdef CONFIG_TCG
 bool ppc_cpu_tlb_fill(CPUState *cs, vaddr eaddr, int size,
   MMUAccessType access_type, int mmu_idx,
   bool probe, uintptr_t retaddr)
@@ -2984,3 +2985,4 @@ bool ppc_cpu_tlb_fill(CPUState *cs, vaddr eaddr, int size,
 raise_exception_err_ra(&cpu->env, cs->exception_index,
cpu->env.error_code, retaddr);
 }
+#endif
-- 
2.25.1




[PATCH 23/24] target/ppc: Introduce ppc_xlate

2021-05-18 Thread Richard Henderson
Create one common dispatch for all of the ppc_*_xlate functions.
Use ppc64_v3_radix to directly dispatch between ppc_radix64_xlate
and ppc_hash64_xlate.

Remove the separate *_handle_mmu_fault and *_get_phys_page_debug
functions, using common code for ppc_cpu_tlb_fill and
ppc_cpu_get_phys_page_debug.

Signed-off-by: Richard Henderson 
---
 target/ppc/mmu-book3s-v3.h |   5 --
 target/ppc/mmu-hash32.h|   6 +--
 target/ppc/mmu-hash64.h|   6 +--
 target/ppc/mmu-radix64.h   |   6 +--
 target/ppc/mmu-book3s-v3.c |  19 ---
 target/ppc/mmu-hash32.c|  38 ++---
 target/ppc/mmu-hash64.c|  37 ++---
 target/ppc/mmu-radix64.c   |  38 ++---
 target/ppc/mmu_helper.c| 106 ++---
 9 files changed, 58 insertions(+), 203 deletions(-)

diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h
index 7b89be54b8..a1326df969 100644
--- a/target/ppc/mmu-book3s-v3.h
+++ b/target/ppc/mmu-book3s-v3.h
@@ -67,11 +67,6 @@ static inline bool ppc64_v3_radix(PowerPCCPU *cpu)
 return !!(cpu->env.spr[SPR_LPCR] & LPCR_HR);
 }
 
-hwaddr ppc64_v3_get_phys_page_debug(PowerPCCPU *cpu, vaddr eaddr);
-
-int ppc64_v3_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
-  int mmu_idx);
-
 static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
 {
 uint64_t base;
diff --git a/target/ppc/mmu-hash32.h b/target/ppc/mmu-hash32.h
index 30e35718a7..8694eccabd 100644
--- a/target/ppc/mmu-hash32.h
+++ b/target/ppc/mmu-hash32.h
@@ -4,9 +4,9 @@
 #ifndef CONFIG_USER_ONLY
 
 hwaddr get_pteg_offset32(PowerPCCPU *cpu, hwaddr hash);
-hwaddr ppc_hash32_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr);
-int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr address,
-MMUAccessType access_type, int mmu_idx);
+bool ppc_hash32_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
+  hwaddr *raddrp, int *psizep, int *protp,
+  bool guest_visible);
 
 /*
  * Segment register definitions
diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
index 3e8a8eec1f..9f338e1fe9 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -7,9 +7,9 @@
 void dump_slb(PowerPCCPU *cpu);
 int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
   target_ulong esid, target_ulong vsid);
-hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr);
-int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr address,
-MMUAccessType access_type, int mmu_idx);
+bool ppc_hash64_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
+  hwaddr *raddrp, int *psizep, int *protp,
+  bool guest_visible);
 void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
target_ulong pte_index,
target_ulong pte0, target_ulong pte1);
diff --git a/target/ppc/mmu-radix64.h b/target/ppc/mmu-radix64.h
index 94bd72cb38..6b13b89b64 100644
--- a/target/ppc/mmu-radix64.h
+++ b/target/ppc/mmu-radix64.h
@@ -44,9 +44,9 @@
 
 #ifdef TARGET_PPC64
 
-int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
- MMUAccessType access_type, int mmu_idx);
-hwaddr ppc_radix64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr);
+bool ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
+   hwaddr *raddr, int *psizep, int *protp,
+   bool guest_visible);
 
 static inline int ppc_radix64_get_prot_eaa(uint64_t pte)
 {
diff --git a/target/ppc/mmu-book3s-v3.c b/target/ppc/mmu-book3s-v3.c
index c78fd8dc0e..f4985bae78 100644
--- a/target/ppc/mmu-book3s-v3.c
+++ b/target/ppc/mmu-book3s-v3.c
@@ -23,25 +23,6 @@
 #include "mmu-book3s-v3.h"
 #include "mmu-radix64.h"
 
-int ppc64_v3_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
-  int mmu_idx)
-{
-if (ppc64_v3_radix(cpu)) { /* Guest uses radix */
-return ppc_radix64_handle_mmu_fault(cpu, eaddr, rwx, mmu_idx);
-} else { /* Guest uses hash */
-return ppc_hash64_handle_mmu_fault(cpu, eaddr, rwx, mmu_idx);
-}
-}
-
-hwaddr ppc64_v3_get_phys_page_debug(PowerPCCPU *cpu, vaddr eaddr)
-{
-if (ppc64_v3_radix(cpu)) {
-return ppc_radix64_get_phys_page_debug(cpu, eaddr);
-} else {
-return ppc_hash64_get_phys_page_debug(cpu, eaddr);
-}
-}
-
 bool ppc64_v3_get_pate(PowerPCCPU *cpu, target_ulong lpid, ppc_v3_pate_t 
*entry)
 {
 uint64_t patb = cpu->env.spr[SPR_PTCR] & PTCR_PATB;
diff --git a/target/ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c
index 959dc2ab53..32d1f4a954 100644
--- a/target/ppc/mmu-hash32.c
+++ b/target/ppc/mmu-hash32.c
@@ -425,10 +425,9 @@ static hwaddr ppc_hash32_pte_raddr(target_ulong sr, 
ppc_hash_pte32_t pte,
 return (rpn & ~mask) | (eaddr & mask);
 }
 
-static bool ppc_hash32_xlate(PowerPCCPU *cpu, v

[PATCH 22/24] target/ppc: Split out ppc_jumbo_xlate

2021-05-18 Thread Richard Henderson
Mirror the interface of ppc_radix64_xlate (mostly), putting all
of the logic for older mmu translation into a single entry point.
For booke, we need to add mmu_idx to the xlate-style interface.

Signed-off-by: Richard Henderson 
---
 target/ppc/mmu_helper.c | 181 +---
 1 file changed, 97 insertions(+), 84 deletions(-)

diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index 863e556a22..68c2e59238 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -1427,48 +1427,6 @@ static int get_physical_address(CPUPPCState *env, 
mmu_ctx_t *ctx,
 return get_physical_address_wtlb(env, ctx, eaddr, access_type, type, 0);
 }
 
-hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-{
-PowerPCCPU *cpu = POWERPC_CPU(cs);
-CPUPPCState *env = &cpu->env;
-mmu_ctx_t ctx;
-
-switch (env->mmu_model) {
-#if defined(TARGET_PPC64)
-case POWERPC_MMU_64B:
-case POWERPC_MMU_2_03:
-case POWERPC_MMU_2_06:
-case POWERPC_MMU_2_07:
-return ppc_hash64_get_phys_page_debug(cpu, addr);
-case POWERPC_MMU_3_00:
-return ppc64_v3_get_phys_page_debug(cpu, addr);
-#endif
-
-case POWERPC_MMU_32B:
-case POWERPC_MMU_601:
-return ppc_hash32_get_phys_page_debug(cpu, addr);
-
-default:
-;
-}
-
-if (unlikely(get_physical_address(env, &ctx, addr, MMU_DATA_LOAD,
-  ACCESS_INT) != 0)) {
-
-/*
- * Some MMUs have separate TLBs for code and data. If we only
- * try an ACCESS_INT, we may not be able to read instructions
- * mapped by code TLBs, so we also try a ACCESS_CODE.
- */
-if (unlikely(get_physical_address(env, &ctx, addr, MMU_INST_FETCH,
-  ACCESS_CODE) != 0)) {
-return -1;
-}
-}
-
-return ctx.raddr & TARGET_PAGE_MASK;
-}
-
 static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong 
address,
  MMUAccessType access_type, int 
mmu_idx)
 {
@@ -1524,30 +1482,38 @@ static void booke206_update_mas_tlb_miss(CPUPPCState 
*env, target_ulong address,
 }
 
 /* Perform address translation */
-static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
-MMUAccessType access_type, int mmu_idx)
+/* TODO: Split this by mmu_model. */
+static bool ppc_jumbo_xlate(PowerPCCPU *cpu, vaddr eaddr,
+MMUAccessType access_type,
+hwaddr *raddrp, int *psizep, int *protp,
+int mmu_idx, bool guest_visible)
 {
-CPUState *cs = env_cpu(env);
-PowerPCCPU *cpu = POWERPC_CPU(cs);
+CPUState *cs = CPU(cpu);
+CPUPPCState *env = &cpu->env;
 mmu_ctx_t ctx;
 int type;
-int ret = 0;
+int ret;
 
 if (access_type == MMU_INST_FETCH) {
 /* code access */
 type = ACCESS_CODE;
-} else {
+} else if (guest_visible) {
 /* data access */
 type = env->access_type;
+} else {
+type = ACCESS_INT;
 }
-ret = get_physical_address_wtlb(env, &ctx, address, access_type,
+
+ret = get_physical_address_wtlb(env, &ctx, eaddr, access_type,
 type, mmu_idx);
 if (ret == 0) {
-tlb_set_page(cs, address & TARGET_PAGE_MASK,
- ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
- mmu_idx, TARGET_PAGE_SIZE);
-ret = 0;
-} else if (ret < 0) {
+*raddrp = ctx.raddr;
+*protp = ctx.prot;
+*psizep = TARGET_PAGE_BITS;
+return true;
+}
+
+if (guest_visible) {
 LOG_MMU_STATE(cs);
 if (type == ACCESS_CODE) {
 switch (ret) {
@@ -1557,7 +1523,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, 
target_ulong address,
 case POWERPC_MMU_SOFT_6xx:
 cs->exception_index = POWERPC_EXCP_IFTLB;
 env->error_code = 1 << 18;
-env->spr[SPR_IMISS] = address;
+env->spr[SPR_IMISS] = eaddr;
 env->spr[SPR_ICMP] = 0x8000 | ctx.ptem;
 goto tlb_miss;
 case POWERPC_MMU_SOFT_74xx:
@@ -1567,29 +1533,25 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, 
target_ulong address,
 case POWERPC_MMU_SOFT_4xx_Z:
 cs->exception_index = POWERPC_EXCP_ITLB;
 env->error_code = 0;
-env->spr[SPR_40x_DEAR] = address;
+env->spr[SPR_40x_DEAR] = eaddr;
 env->spr[SPR_40x_ESR] = 0x;
 break;
 case POWERPC_MMU_BOOKE206:
-booke206_update_mas_tlb_miss(env, address, 2, mmu_idx);
+booke206_update_mas_tlb_miss(env, eaddr, 2, mmu_idx);
 /* fall through */
  

[PATCH 20/24] target/ppc: Split out ppc_hash64_xlate

2021-05-18 Thread Richard Henderson
Mirror the interface of ppc_radix64_xlate, putting all of
the logic for hash64 translation into a single function.

Signed-off-by: Richard Henderson 
---
 target/ppc/mmu-hash64.c | 125 +++-
 1 file changed, 59 insertions(+), 66 deletions(-)

diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index 877a01a296..3024dd1e8c 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -866,8 +866,10 @@ static int build_vrma_slbe(PowerPCCPU *cpu, ppc_slb_t *slb)
 return -1;
 }
 
-int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
-MMUAccessType access_type, int mmu_idx)
+static bool ppc_hash64_xlate(PowerPCCPU *cpu, vaddr eaddr,
+ MMUAccessType access_type,
+ hwaddr *raddrp, int *psizep, int *protp,
+ bool guest_visible)
 {
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = &cpu->env;
@@ -911,9 +913,11 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr 
eaddr,
 slb = &vrma_slbe;
 if (build_vrma_slbe(cpu, slb) != 0) {
 /* Invalid VRMA setup, machine check */
-cs->exception_index = POWERPC_EXCP_MCHECK;
-env->error_code = 0;
-return 1;
+if (guest_visible) {
+cs->exception_index = POWERPC_EXCP_MCHECK;
+env->error_code = 0;
+}
+return false;
 }
 
 goto skip_slb_search;
@@ -922,6 +926,9 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr 
eaddr,
 
 /* Emulated old-style RMO mode, bounds check against RMLS */
 if (raddr >= limit) {
+if (!guest_visible) {
+return false;
+}
 switch (access_type) {
 case MMU_INST_FETCH:
 ppc_hash64_set_isi(cs, SRR1_PROTFAULT);
@@ -936,15 +943,16 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr 
eaddr,
 default:
 g_assert_not_reached();
 }
-return 1;
+return false;
 }
 
 raddr |= env->spr[SPR_RMOR];
 }
-tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
- PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx,
- TARGET_PAGE_SIZE);
-return 0;
+
+*raddrp = raddr;
+*protp = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+*psizep = TARGET_PAGE_BITS;
+return true;
 }
 
 /* 2. Translation is on, so look up the SLB */
@@ -957,6 +965,9 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr 
eaddr,
 exit(1);
 }
 /* Segment still not found, generate the appropriate interrupt */
+if (!guest_visible) {
+return false;
+}
 switch (access_type) {
 case MMU_INST_FETCH:
 cs->exception_index = POWERPC_EXCP_ISEG;
@@ -971,20 +982,25 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr 
eaddr,
 default:
 g_assert_not_reached();
 }
-return 1;
+return false;
 }
 
-skip_slb_search:
+ skip_slb_search:
 
 /* 3. Check for segment level no-execute violation */
 if (access_type == MMU_INST_FETCH && (slb->vsid & SLB_VSID_N)) {
-ppc_hash64_set_isi(cs, SRR1_NOEXEC_GUARD);
-return 1;
+if (guest_visible) {
+ppc_hash64_set_isi(cs, SRR1_NOEXEC_GUARD);
+}
+return false;
 }
 
 /* 4. Locate the PTE in the hash table */
 ptex = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte, &apshift);
 if (ptex == -1) {
+if (!guest_visible) {
+return false;
+}
 switch (access_type) {
 case MMU_INST_FETCH:
 ppc_hash64_set_isi(cs, SRR1_NOPTE);
@@ -998,7 +1014,7 @@ skip_slb_search:
 default:
 g_assert_not_reached();
 }
-return 1;
+return false;
 }
 qemu_log_mask(CPU_LOG_MMU,
   "found PTE at index %08" HWADDR_PRIx "\n", ptex);
@@ -1014,6 +1030,9 @@ skip_slb_search:
 if (need_prot & ~prot) {
 /* Access right violation */
 qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
+if (!guest_visible) {
+return false;
+}
 if (access_type == MMU_INST_FETCH) {
 int srr1 = 0;
 if (PAGE_EXEC & ~exec_prot) {
@@ -1038,7 +1057,7 @@ skip_slb_search:
 }
 ppc_hash64_set_dsi(cs, eaddr, dsisr);
 }
-return 1;
+return false;
 }
 
 qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
@@ -1062,66 +1081,40 @@ skip_slb_search:
 
 /* 7. Determine the real address from the PTE */
 
-raddr = deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, eaddr);
+*raddrp = deposit

  1   2   3   4   5   >