Re: [Xen-devel] [RFC v1] ALSA: xen-front: Add Xen para-virtualized frontend driver

2017-11-17 Thread Oleksandr Andrushchenko

ping

On 11/02/2017 03:11 PM, Oleksandr Andrushchenko wrote:

Hi, all!

Foreword


This RFC is aimed to introduce support of para-virtualized sound frontend
driver for Xen [1] and gather opinions from the relevant communities
(ALSA, Xen). It implements the protocol from [2] with the
following limitations:
  - mute/unmute is not supported
  - get/set volume is not supported
Volume control is not supported for the reason that most of the use-cases
(at the moment) are based on scenarios where unprivileged OS
(e.g. Android, AGL etc) uses software mixers.
Both capture and playback are supported.

The relevant backend is implemented as a user-space application [3]
and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen 
hypervisor

(Renesas R-Car ARM based H3/M3 boards, x86).

Discussion
==

During the first attempt to upstream the driver [5] number of comments 
and
concerns were raised, one of the biggest flaws in the design were 
questioned

by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of
synchronization between frontend and backend during capture/playback.
Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to
actual hardwares for semi-realtime data transmission. The
synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces
    of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I
described the above:
1. notifications from DomU to Dom0 about the size of period for
    interrupts from actual hardwares. Or no way from Dom0 to DomU about
    the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

This is implemented as a change to the sndif protocol [8] and allows 
removing

period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS,
   to be used for sending snd_pcm_period_elapsed at frontend (in Linux
   implementation). Sent in bytes, not frames to make the protocol
   generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with
   start/pause/stop/resume sub-ops.

Along with these changes other comments on the driver were addressed,
e.g. split into smaller chunks, moved the driver from misc to xen etc.


Hope, this helps to get the full picture of what was discussed and 
makes it

possible to move forward.

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h

[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] 
http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] 
http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html
[8] 
https://github.com/andr2000/linux/commit/095d7feae00bf00c852c67c4f1044de5601678ed




___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [RFC v1] ALSA: xen-front: Add Xen para-virtualized frontend driver

2017-11-02 Thread Oleksandr Andrushchenko

Hi, all!

Foreword


This RFC is aimed to introduce support of para-virtualized sound frontend
driver for Xen [1] and gather opinions from the relevant communities
(ALSA, Xen). It implements the protocol from [2] with the
following limitations:
  - mute/unmute is not supported
  - get/set volume is not supported
Volume control is not supported for the reason that most of the use-cases
(at the moment) are based on scenarios where unprivileged OS
(e.g. Android, AGL etc) uses software mixers.
Both capture and playback are supported.

The relevant backend is implemented as a user-space application [3]
and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen 
hypervisor

(Renesas R-Car ARM based H3/M3 boards, x86).

Discussion
==

During the first attempt to upstream the driver [5] number of comments and
concerns were raised, one of the biggest flaws in the design were questioned
by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of
synchronization between frontend and backend during capture/playback.
Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to
actual hardwares for semi-realtime data transmission. The
synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces
    of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I
described the above:
1. notifications from DomU to Dom0 about the size of period for
    interrupts from actual hardwares. Or no way from Dom0 to DomU about
    the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

This is implemented as a change to the sndif protocol [8] and allows 
removing

period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS,
   to be used for sending snd_pcm_period_elapsed at frontend (in Linux
   implementation). Sent in bytes, not frames to make the protocol
   generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with
   start/pause/stop/resume sub-ops.

Along with these changes other comments on the driver were addressed,
e.g. split into smaller chunks, moved the driver from misc to xen etc.


Hope, this helps to get the full picture of what was discussed and makes it
possible to move forward.

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h

[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] 
http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] 
http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html
[8] 
https://github.com/andr2000/linux/commit/095d7feae00bf00c852c67c4f1044de5601678ed




___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [RFC] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-11-02 Thread Oleksandr Andrushchenko


On 11/02/2017 11:44 AM, Takashi Sakamoto wrote:

On Oct 30 2017 15:33, Oleksandr Andrushchenko wrote:

This is an attempt to summarize previous discussions on Xen para-virtual
sound driver.

A first attempt has been made to upstream the driver [1] which 
brought number
of fundamental questions, one of the biggest ones was that the 
frontend driver
has no means to synchronize its period elapsed event with the host 
driver,

but uses software emulation on the guest side [2] with a timer.
In order to address this a change to the existing Xen para-virtual sound
protocol [3] was proposed to fill this gap [4] and remove emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS,
to be used for sending snd_pcm_period_elapsed at frontend
(in Linux implementation, sent in bytes, not frames to make the protocol
generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with
start/pause/stop/resume sub-ops.

Along with these changes other comments on the driver were addressed,
e.g. split into smaller chunks, moved the driver from misc to xen 
etc. [5].


Hope, this helps to get the full picture of what was discussed and 
makes it

possible to move forward: if the approach seems ok, then I'll start
upstreaming the changes to the sndif protocol and then will send the 
updated

version of the driver for the further review.


This message has below line in its header.

> In-Reply-To: 

This field is defined in RFC822[1], and recent mail clients use this 
header field to associate the message to a message which the field 
indicates. This results in a series of messages, so-called 'message 
thread'. Iwai-san would like you to start a new message thread for 
your topic. Would you please post this message again without the 
header field?

of course, sorry about that


Generally, receiving no reactions means that readers/reviewers don't 
get enough information for your idea yet. (Of course, there's a 
probability that your work attracts no one...) In this case, 
submitting more resources is better, rather than requesting comments 
to them. For instance, you can point links to backend/frontend 
implementation as para-virtualization drivers which use the new 
feature of interface, if you did work for it. Indicating procedure to 
use a series of your work is better for test, if possible.



will do

[1] https://www.ietf.org/rfc/rfc0822.txt

Regards

Takashi Sakamoto

Thank you,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [RFC] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-10-29 Thread Oleksandr Andrushchenko

Hi, all!

This is an attempt to summarize previous discussions on Xen para-virtual
sound driver.

A first attempt has been made to upstream the driver [1] which brought 
number
of fundamental questions, one of the biggest ones was that the frontend 
driver

has no means to synchronize its period elapsed event with the host driver,
but uses software emulation on the guest side [2] with a timer.
In order to address this a change to the existing Xen para-virtual sound
protocol [3] was proposed to fill this gap [4] and remove emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS,
to be used for sending snd_pcm_period_elapsed at frontend
(in Linux implementation, sent in bytes, not frames to make the protocol
generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with
start/pause/stop/resume sub-ops.

Along with these changes other comments on the driver were addressed,
e.g. split into smaller chunks, moved the driver from misc to xen etc. [5].

Hope, this helps to get the full picture of what was discussed and makes it
possible to move forward: if the approach seems ok, then I'll start
upstreaming the changes to the sndif protocol and then will send the 
updated

version of the driver for the further review.

Thank you,
Oleksandr


[1] https://lkml.org/lkml/2017/8/7/363
[2] https://lkml.org/lkml/2017/8/9/1167
[3] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h

[4] https://lkml.org/lkml/2017/9/19/121
[5] https://github.com/andr2000/linux/tree/snd_upstream_v1/sound/xen


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [alsa-devel] [PATCH RESEND1 00/12] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-10-12 Thread Oleksandr Andrushchenko

ping

On 10/04/2017 09:50 AM, Oleksandr Andrushchenko wrote:

gentle reminder

On 09/26/2017 02:35 PM, Oleksandr Andrushchenko wrote:

Clemens, Sakamoto-san,

could you please review the below if you by chance have a minute?

Thank you,
Oleksandr

On 09/19/2017 11:57 AM, Oleksandr Andrushchenko wrote:

Hi, all!

We did some work on implementing the idea with

feedback events from the backend to the frontend.

Please see attached the changes to the existing sndif protocol [1]:

1. Introduced a new event channel from back to front

2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS,

to be used for sending snd_pcm_period_elapsed at frontend.

Sent in bytes, not frames to make the protocol generic and consistent)

3. New request for playback/capture control (XENSND_OP_TRIGGER)

with start/pause/stop/resume sub-ops.

The implementation we have showed that this is sufficient to
successfully play/capture w/o using emulated interrupts.

Clemens, Sakamoto-san,
could you please review the changes and confirm that these are ok to
be upstreamed to the sndif protocol and are enough for the frontend
driver we want to upstream (we have it implemented, just need to make
sure the general approach is accepted by the ALSA community).

Thank you very much for your time,
Oleksandr Andrushchenko
Oleksandr Grytsov

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h?h=v4.14-rc1


On 09/12/2017 10:52 AM, Oleksandr Grytsov wrote:
On Tue, Sep 5, 2017 at 10:24 AM, Clemens Ladisch 
 wrote:

Oleksandr Andrushchenko wrote:
We understand that emulated interrupt on the frontend side is 
completely not

acceptable

Allow me to expand on that:  Proper synchronization requires that the
exact position is communicated, not estimated.  Just because the 
nominal
rate of the stream is known does not imply that you know the 
actual rate.
Forget for the moment that there even is a nominal rate; assume 
that it
works like, e.g., a storage controller, and that you can know that 
a DMA

buffer was consumed by the device only after it has told you.

It's possible and likely that there is a latency when reporting the
stream position, but that is still better than guessing what the DMA
is doing.  (You would never just try to guess when writing data to
disk, would you?)


and definitely we need to provide some feedback mechanism from
Dom0 to DomU.

In our case it is technically impossible to provide precise 
period interrupt

(mostly because our backend is a user space application).
As far as I can see, all audio APIs (ALSA, PulseAudio, etc.) have 
poll()

or callbacks or similar mechanisms to inform you when new data can be
written, and always allow to query the current position.


[...]
ok, so the main concern here is that we cannot properly 
synchronize Dom0-DomU.
If we put this apart for a second are there any other concerns on 
having ALSA
frontend driver? If not, can we have the driver with timer 
implementation upstreamed
as experimental until we have some acceptable synchronization 
solution?
This will allow broader audience to try and feel the solution and 
probably contribute?
I doubt that the driver architecture will stay completely the 
same, so I

do not think that this experimental driver would demonstrate how the
solution would feel.

As the first step, I would suggest creating a driver with proper
synchronization, even if it has high latency.  Reducing the latency
would then be 'just' an optimization.


Regards,
Clemens

Definitely feedback from the backend side is required. Currently
we are working on synchronized version on the backend
and frontend side. We will be back once we have the solution.

Thanks.









___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] DomD: passthroughing an arbitrary device

2017-10-07 Thread Oleksandr Andrushchenko


On 10/05/2017 06:29 PM, Julien Grall wrote:

Hi,

On 04/10/17 19:10, Oleksandr Andrushchenko wrote:

sorry, pressed send too fast
On 10/04/2017 09:02 PM, Oleksandr Andrushchenko wrote:


On 10/04/2017 08:22 PM, Julien Grall wrote:



On 04/10/17 17:32, Oleksandr Andrushchenko wrote:

Hi, all!


Hello,

We have a use-case where we want to passthrough and arbitrary 
device to driver domain,

e.g. GPIO controller or the like (doesn't do any DMA).


I will assume you are speaking about Xen Arm and not Xen x86. 
Please correct if my assumption is wrong.



you are right, sorry for not being precise enough
I know that for device to be pass throughed it must be tied to an 
IOMMU, but in my case
the controller doesn’t have any. The problem is that it not only 
has MMIO range,
but also has its own interrupt controller, so I have to 
passthrough IRQs as well.
Here comes the limitation I face: as the controller doesn’t have 
any IOMMU I can’t

passthrough its IRQ.


I guess you are saying that when you use "dtdev" it will deny guest 
creation.


at least I used/experimented with dtdev as of now and didn't think 
it is possible not to fill in dtdev's,

but still request IRQs
At the moment, the only purpose of "dtdev" is to setup the SMMU 
correctly. If your device is not protected by an SMMU, then it is 
not necessary. You only need to specific "irqs" and "mmios".



ah, good to know,
could you please confirm that my understanding is correct:
if I put "xen,passthrough" property in guest's device tree node 
which has IRQ(s) and/or MMIO range(s)

it is enough to get that "passive" device passed through?


yes, device will not be hidden from Dom0 and free to be used by any 
other domains.

this does work, thank you


However, you have to ensure it will not be shared between multiple 
domains (this check was done by "dtdev" you don't use here).



yes, for embedded use-cases this shouldn't be a problem



should be
If "xen,passthrough" property in a Dom0 device tree node *together* 
with IRQ(s) and MMIO range(s)
in a *guest config* file is enough to get "passive" device passed 
through
If you wonder why the documentation does not advertise it. It is 
because I consider that any device not protected by an SMMU should 
not be pass-through unless the user really knows what he is doing.


as they say "the best documentation is the source code itself", I 
should have looked more careful


Possible solutions I see could be:

1. Make it possible that Xen allows passing through devices 
without IOMMU assigned:
the problem here is that one can hack Xen then by saying that her 
device is not MMU

protected and writing/reading arbitrary memory then.

2. Make driver domain be marked somehow as a privileged one, so 
Xen can trust it and

allow passing devices without IOMMU.
Q: What if we need to pass this device to DomU?

3. Workaround by introducing a dummy IOMMU for such devices, but 
it still doesn’t

solve the problem with memory protection.

I'm hoping to hear any possible solutions/suggestions which will 
not break security and allow

passing devices at the same time.


Cheers,


Thank you,
Oleksandr




Cheers,





___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] DomD: passthroughing an arbitrary device

2017-10-04 Thread Oleksandr Andrushchenko

sorry, pressed send too fast
On 10/04/2017 09:02 PM, Oleksandr Andrushchenko wrote:


On 10/04/2017 08:22 PM, Julien Grall wrote:



On 04/10/17 17:32, Oleksandr Andrushchenko wrote:

Hi, all!


Hello,

We have a use-case where we want to passthrough and arbitrary device 
to driver domain,

e.g. GPIO controller or the like (doesn't do any DMA).


I will assume you are speaking about Xen Arm and not Xen x86. Please 
correct if my assumption is wrong.



you are right, sorry for not being precise enough
I know that for device to be pass throughed it must be tied to an 
IOMMU, but in my case
the controller doesn’t have any. The problem is that it not only has 
MMIO range,
but also has its own interrupt controller, so I have to passthrough 
IRQs as well.
Here comes the limitation I face: as the controller doesn’t have any 
IOMMU I can’t

passthrough its IRQ.


I guess you are saying that when you use "dtdev" it will deny guest 
creation.


at least I used/experimented with dtdev as of now and didn't think it 
is possible not to fill in dtdev's,

but still request IRQs
At the moment, the only purpose of "dtdev" is to setup the SMMU 
correctly. If your device is not protected by an SMMU, then it is not 
necessary. You only need to specific "irqs" and "mmios".



ah, good to know,
could you please confirm that my understanding is correct:
if I put "xen,passthrough" property in guest's device tree node which 
has IRQ(s) and/or MMIO range(s)

it is enough to get that "passive" device passed through?


should be
If "xen,passthrough" property in a Dom0 device tree node *together* with 
IRQ(s) and MMIO range(s)

in a *guest config* file is enough to get "passive" device passed through
If you wonder why the documentation does not advertise it. It is 
because I consider that any device not protected by an SMMU should 
not be pass-through unless the user really knows what he is doing.


as they say "the best documentation is the source code itself", I 
should have looked more careful


Possible solutions I see could be:

1. Make it possible that Xen allows passing through devices without 
IOMMU assigned:
the problem here is that one can hack Xen then by saying that her 
device is not MMU

protected and writing/reading arbitrary memory then.

2. Make driver domain be marked somehow as a privileged one, so Xen 
can trust it and

allow passing devices without IOMMU.
Q: What if we need to pass this device to DomU?

3. Workaround by introducing a dummy IOMMU for such devices, but it 
still doesn’t

solve the problem with memory protection.

I'm hoping to hear any possible solutions/suggestions which will not 
break security and allow

passing devices at the same time.


Cheers,


Thank you,
Oleksandr



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] DomD: passthroughing an arbitrary device

2017-10-04 Thread Oleksandr Andrushchenko


On 10/04/2017 08:22 PM, Julien Grall wrote:



On 04/10/17 17:32, Oleksandr Andrushchenko wrote:

Hi, all!


Hello,

We have a use-case where we want to passthrough and arbitrary device 
to driver domain,

e.g. GPIO controller or the like (doesn't do any DMA).


I will assume you are speaking about Xen Arm and not Xen x86. Please 
correct if my assumption is wrong.



you are right, sorry for not being precise enough
I know that for device to be pass throughed it must be tied to an 
IOMMU, but in my case
the controller doesn’t have any. The problem is that it not only has 
MMIO range,
but also has its own interrupt controller, so I have to passthrough 
IRQs as well.
Here comes the limitation I face: as the controller doesn’t have any 
IOMMU I can’t

passthrough its IRQ.


I guess you are saying that when you use "dtdev" it will deny guest 
creation.


at least I used/experimented with dtdev as of now and didn't think it is 
possible not to fill in dtdev's,

but still request IRQs
At the moment, the only purpose of "dtdev" is to setup the SMMU 
correctly. If your device is not protected by an SMMU, then it is not 
necessary. You only need to specific "irqs" and "mmios".



ah, good to know,
could you please confirm that my understanding is correct:
if I put "xen,passthrough" property in guest's device tree node which 
has IRQ(s) and/or MMIO range(s)

it is enough to get that "passive" device passed through?

If you wonder why the documentation does not advertise it. It is 
because I consider that any device not protected by an SMMU should not 
be pass-through unless the user really knows what he is doing.


as they say "the best documentation is the source code itself", I should 
have looked more careful


Possible solutions I see could be:

1. Make it possible that Xen allows passing through devices without 
IOMMU assigned:
the problem here is that one can hack Xen then by saying that her 
device is not MMU

protected and writing/reading arbitrary memory then.

2. Make driver domain be marked somehow as a privileged one, so Xen 
can trust it and

allow passing devices without IOMMU.
Q: What if we need to pass this device to DomU?

3. Workaround by introducing a dummy IOMMU for such devices, but it 
still doesn’t

solve the problem with memory protection.

I'm hoping to hear any possible solutions/suggestions which will not 
break security and allow

passing devices at the same time.


Cheers,


Thank you,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] DomD: passthroughing an arbitrary device

2017-10-04 Thread Oleksandr Andrushchenko

Hi, all!

We have a use-case where we want to passthrough and arbitrary device to 
driver domain,

e.g. GPIO controller or the like (doesn't do any DMA).
I know that for device to be pass throughed it must be tied to an IOMMU, 
but in my case
the controller doesn’t have any. The problem is that it not only has 
MMIO range,
but also has its own interrupt controller, so I have to passthrough IRQs 
as well.
Here comes the limitation I face: as the controller doesn’t have any 
IOMMU I can’t

passthrough its IRQ.

Possible solutions I see could be:

1. Make it possible that Xen allows passing through devices without 
IOMMU assigned:
the problem here is that one can hack Xen then by saying that her device 
is not MMU

protected and writing/reading arbitrary memory then.

2. Make driver domain be marked somehow as a privileged one, so Xen can 
trust it and

allow passing devices without IOMMU.
Q: What if we need to pass this device to DomU?

3. Workaround by introducing a dummy IOMMU for such devices, but it 
still doesn’t

solve the problem with memory protection.

I'm hoping to hear any possible solutions/suggestions which will not 
break security and allow

passing devices at the same time.

Thank you for your time,
Oleksandr


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [alsa-devel] [PATCH RESEND1 00/12] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-10-03 Thread Oleksandr Andrushchenko

gentle reminder

On 09/26/2017 02:35 PM, Oleksandr Andrushchenko wrote:

Clemens, Sakamoto-san,

could you please review the below if you by chance have a minute?

Thank you,
Oleksandr

On 09/19/2017 11:57 AM, Oleksandr Andrushchenko wrote:

Hi, all!

We did some work on implementing the idea with

feedback events from the backend to the frontend.

Please see attached the changes to the existing sndif protocol [1]:

1. Introduced a new event channel from back to front

2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS,

to be used for sending snd_pcm_period_elapsed at frontend.

Sent in bytes, not frames to make the protocol generic and consistent)

3. New request for playback/capture control (XENSND_OP_TRIGGER)

with start/pause/stop/resume sub-ops.

The implementation we have showed that this is sufficient to
successfully play/capture w/o using emulated interrupts.

Clemens, Sakamoto-san,
could you please review the changes and confirm that these are ok to
be upstreamed to the sndif protocol and are enough for the frontend
driver we want to upstream (we have it implemented, just need to make
sure the general approach is accepted by the ALSA community).

Thank you very much for your time,
Oleksandr Andrushchenko
Oleksandr Grytsov

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h?h=v4.14-rc1


On 09/12/2017 10:52 AM, Oleksandr Grytsov wrote:
On Tue, Sep 5, 2017 at 10:24 AM, Clemens Ladisch 
 wrote:

Oleksandr Andrushchenko wrote:
We understand that emulated interrupt on the frontend side is 
completely not

acceptable

Allow me to expand on that:  Proper synchronization requires that the
exact position is communicated, not estimated.  Just because the 
nominal
rate of the stream is known does not imply that you know the actual 
rate.
Forget for the moment that there even is a nominal rate; assume 
that it
works like, e.g., a storage controller, and that you can know that 
a DMA

buffer was consumed by the device only after it has told you.

It's possible and likely that there is a latency when reporting the
stream position, but that is still better than guessing what the DMA
is doing.  (You would never just try to guess when writing data to
disk, would you?)


and definitely we need to provide some feedback mechanism from
Dom0 to DomU.

In our case it is technically impossible to provide precise 
period interrupt

(mostly because our backend is a user space application).
As far as I can see, all audio APIs (ALSA, PulseAudio, etc.) have 
poll()

or callbacks or similar mechanisms to inform you when new data can be
written, and always allow to query the current position.


[...]
ok, so the main concern here is that we cannot properly 
synchronize Dom0-DomU.
If we put this apart for a second are there any other concerns on 
having ALSA
frontend driver? If not, can we have the driver with timer 
implementation upstreamed
as experimental until we have some acceptable synchronization 
solution?
This will allow broader audience to try and feel the solution and 
probably contribute?
I doubt that the driver architecture will stay completely the same, 
so I

do not think that this experimental driver would demonstrate how the
solution would feel.

As the first step, I would suggest creating a driver with proper
synchronization, even if it has high latency.  Reducing the latency
would then be 'just' an optimization.


Regards,
Clemens

Definitely feedback from the backend side is required. Currently
we are working on synchronized version on the backend
and frontend side. We will be back once we have the solution.

Thanks.







___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [alsa-devel] [PATCH RESEND1 00/12] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-09-26 Thread Oleksandr Andrushchenko

Clemens, Sakamoto-san,

could you please review the below if you by chance have a minute?

Thank you,
Oleksandr

On 09/19/2017 11:57 AM, Oleksandr Andrushchenko wrote:

Hi, all!

We did some work on implementing the idea with

feedback events from the backend to the frontend.

Please see attached the changes to the existing sndif protocol [1]:

1. Introduced a new event channel from back to front

2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS,

to be used for sending snd_pcm_period_elapsed at frontend.

Sent in bytes, not frames to make the protocol generic and consistent)

3. New request for playback/capture control (XENSND_OP_TRIGGER)

with start/pause/stop/resume sub-ops.

The implementation we have showed that this is sufficient to
successfully play/capture w/o using emulated interrupts.

Clemens, Sakamoto-san,
could you please review the changes and confirm that these are ok to
be upstreamed to the sndif protocol and are enough for the frontend
driver we want to upstream (we have it implemented, just need to make
sure the general approach is accepted by the ALSA community).

Thank you very much for your time,
Oleksandr Andrushchenko
Oleksandr Grytsov

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h?h=v4.14-rc1


On 09/12/2017 10:52 AM, Oleksandr Grytsov wrote:
On Tue, Sep 5, 2017 at 10:24 AM, Clemens Ladisch  
wrote:

Oleksandr Andrushchenko wrote:
We understand that emulated interrupt on the frontend side is 
completely not

acceptable

Allow me to expand on that:  Proper synchronization requires that the
exact position is communicated, not estimated.  Just because the 
nominal
rate of the stream is known does not imply that you know the actual 
rate.

Forget for the moment that there even is a nominal rate; assume that it
works like, e.g., a storage controller, and that you can know that a 
DMA

buffer was consumed by the device only after it has told you.

It's possible and likely that there is a latency when reporting the
stream position, but that is still better than guessing what the DMA
is doing.  (You would never just try to guess when writing data to
disk, would you?)


and definitely we need to provide some feedback mechanism from
Dom0 to DomU.

In our case it is technically impossible to provide precise 
period interrupt

(mostly because our backend is a user space application).
As far as I can see, all audio APIs (ALSA, PulseAudio, etc.) have 
poll()

or callbacks or similar mechanisms to inform you when new data can be
written, and always allow to query the current position.


[...]
ok, so the main concern here is that we cannot properly synchronize 
Dom0-DomU.
If we put this apart for a second are there any other concerns on 
having ALSA
frontend driver? If not, can we have the driver with timer 
implementation upstreamed
as experimental until we have some acceptable synchronization 
solution?
This will allow broader audience to try and feel the solution and 
probably contribute?
I doubt that the driver architecture will stay completely the same, 
so I

do not think that this experimental driver would demonstrate how the
solution would feel.

As the first step, I would suggest creating a driver with proper
synchronization, even if it has high latency.  Reducing the latency
would then be 'just' an optimization.


Regards,
Clemens

Definitely feedback from the backend side is required. Currently
we are working on synchronized version on the backend
and frontend side. We will be back once we have the solution.

Thanks.





___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [alsa-devel] [PATCH RESEND1 00/12] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-09-19 Thread Oleksandr Andrushchenko

Hi, all!

We did some work on implementing the idea with

feedback events from the backend to the frontend.

Please see attached the changes to the existing sndif protocol [1]:

1. Introduced a new event channel from back to front

2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS,

to be used for sending snd_pcm_period_elapsed at frontend.

Sent in bytes, not frames to make the protocol generic and consistent)

3. New request for playback/capture control (XENSND_OP_TRIGGER)

with start/pause/stop/resume sub-ops.

The implementation we have showed that this is sufficient to
successfully play/capture w/o using emulated interrupts.

Clemens, Sakamoto-san,
could you please review the changes and confirm that these are ok to
be upstreamed to the sndif protocol and are enough for the frontend
driver we want to upstream (we have it implemented, just need to make
sure the general approach is accepted by the ALSA community).

Thank you very much for your time,
Oleksandr Andrushchenko
Oleksandr Grytsov

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h?h=v4.14-rc1


On 09/12/2017 10:52 AM, Oleksandr Grytsov wrote:

On Tue, Sep 5, 2017 at 10:24 AM, Clemens Ladisch  wrote:

Oleksandr Andrushchenko wrote:

We understand that emulated interrupt on the frontend side is completely not
acceptable

Allow me to expand on that:  Proper synchronization requires that the
exact position is communicated, not estimated.  Just because the nominal
rate of the stream is known does not imply that you know the actual rate.
Forget for the moment that there even is a nominal rate; assume that it
works like, e.g., a storage controller, and that you can know that a DMA
buffer was consumed by the device only after it has told you.

It's possible and likely that there is a latency when reporting the
stream position, but that is still better than guessing what the DMA
is doing.  (You would never just try to guess when writing data to
disk, would you?)


and definitely we need to provide some feedback mechanism from
Dom0 to DomU.

In our case it is technically impossible to provide precise period interrupt
(mostly because our backend is a user space application).

As far as I can see, all audio APIs (ALSA, PulseAudio, etc.) have poll()
or callbacks or similar mechanisms to inform you when new data can be
written, and always allow to query the current position.


[...]
ok, so the main concern here is that we cannot properly synchronize Dom0-DomU.
If we put this apart for a second are there any other concerns on having ALSA
frontend driver? If not, can we have the driver with timer implementation 
upstreamed
as experimental until we have some acceptable synchronization solution?
This will allow broader audience to try and feel the solution and probably 
contribute?

I doubt that the driver architecture will stay completely the same, so I
do not think that this experimental driver would demonstrate how the
solution would feel.

As the first step, I would suggest creating a driver with proper
synchronization, even if it has high latency.  Reducing the latency
would then be 'just' an optimization.


Regards,
Clemens

Definitely feedback from the backend side is required. Currently
we are working on synchronized version on the backend
and frontend side. We will be back once we have the solution.

Thanks.


diff --git a/include/xen/interface/io/sndif.h b/include/xen/interface/io/sndif.h
index 5c918276835e..763a3f0164f4 100644
--- a/include/xen/interface/io/sndif.h
+++ b/include/xen/interface/io/sndif.h
@@ -38,6 +38,13 @@
 
 /*
  **
+ *   Protocol version
+ **
+ */
+#define XENDISPL_PROTOCOL_VERSION	"2"
+
+/*
+ **
  *  Feature and Parameter Negotiation
  **
  *
@@ -104,8 +111,10 @@
  * /local/domain/1/device/vsnd/0/0/0/sample-formats = "s8,u8"
  * /local/domain/1/device/vsnd/0/0/0/unique-id = "0"
  *
- * /local/domain/1/device/vsnd/0/0/0/ring-ref = "386"
- * /local/domain/1/device/vsnd/0/0/0/event-channel = "15"
+ * /local/domain/1/device/vsnd/0/0/0/req-ring-ref = "386"
+ * /local/domain/1/device/vsnd/0/0/0/req-event-channel = "15"
+ * /local/domain/1/device/vsnd/0/0/0/evt-ring-ref = "1386"
+ * /local/domain/1/device/vsnd/0/0/0/evt-event-channel = "215"
  *
  *-- Stream 1, capture 
  *
@@ -113,8 +122,10 @@
  * /local/domain/1/device/vsnd/0/0/1/channels-max = "2"
  * /local/domain/1/device/vsnd/0/0/1/unique-id = "1"
  *
- * /local/domain/1/device/vsnd/0/0

Re: [Xen-devel] [PATCH RESEND1 00/12] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-09-04 Thread Oleksandr Andrushchenko


On 08/24/2017 10:04 AM, Oleksandr Andrushchenko wrote:

Hello,

On 08/24/2017 07:38 AM, Takashi Sakamoto wrote:

On Aug 23 2017 23:51, Oleksandr Grytsov wrote:

Hi,

Thank you for detailed explanation.

We understand that emulated interrupt on the frontend side is 
completely not
acceptable and definitely we need to provide some feedback mechanism 
from

Dom0 to DomU.

In our case it is technically impossible to provide precise period 
interrupt

(mostly because our backend is a user space application).
The best we can implement it is provide number of frames (time, 
bytes etc.)
consumed by real HW. This info will be outdated due to different 
delays but

we can provide precise timestamps when this info was acquired.


Stuffs of ALSA PCM in kernel land is an abstraction layer for actual
hardware for data transmission. The stuffs get affects from a design of
actual hardware. Furthermore, sound subsystems on the other operating
systems such as Microsoft Windows are also designed with a consideration
about actual hardware. When you design any interfaces as an abstraction
for such software layer, it's better to understand actual hardware and
design of low-level software layer somehow.

Actually the 'sndif' has no good abstraction for actual hardware,
therefore an idea to implement frontend driver as an ALSA driver is not
reasonable at all. 
the reason for that is that you can use the same frontend driver for 
various
DomUs without the need to write yet another HAL/application, e.g. if 
one of the

DomUs has no PulseAudio (uses ALSA) and yet another DomU has PulseAudio,
then using the same driver allows you to enable both out of the box 
with the

same codebase.
If we can imagine something else running on top of ALSA (say some other
mixing software other than PulseAudio) then we will have to support 
that as well



It's better to implement it as an application in
the other software layer, e.g. sinks/sources of PulseAudio in DomU

please see our reasoning above

via
Xenbus. This idea is nearer an original concept of Xen framework, I
guess. But I don't know we can write any applications of Xenbus in user
land of DomU or not.

Anyway, it's not a good idea to have an ALSA driver for the present 
'sndif', in my opinion.


ok, so the main concern here is that we cannot properly synchronize 
Dom0-DomU.
If we put this apart for a second are there any other concerns on 
having ALSA
frontend driver? If not, can we have the driver with timer 
implementation upstreamed

as experimental until we have some acceptable synchronization solution?
This will allow broader audience to try and feel the solution and 
probably contribute?

any thoughts on this?


Regards

Takashi Sakamoto

Thank you very much for your time,
Oleksandr Andrushchenko



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RESEND1 00/12] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-08-24 Thread Oleksandr Andrushchenko

Hello,

On 08/24/2017 07:38 AM, Takashi Sakamoto wrote:

On Aug 23 2017 23:51, Oleksandr Grytsov wrote:

Hi,

Thank you for detailed explanation.

We understand that emulated interrupt on the frontend side is 
completely not
acceptable and definitely we need to provide some feedback mechanism 
from

Dom0 to DomU.

In our case it is technically impossible to provide precise period 
interrupt

(mostly because our backend is a user space application).
The best we can implement it is provide number of frames (time, bytes 
etc.)
consumed by real HW. This info will be outdated due to different 
delays but

we can provide precise timestamps when this info was acquired.


Stuffs of ALSA PCM in kernel land is an abstraction layer for actual
hardware for data transmission. The stuffs get affects from a design of
actual hardware. Furthermore, sound subsystems on the other operating
systems such as Microsoft Windows are also designed with a consideration
about actual hardware. When you design any interfaces as an abstraction
for such software layer, it's better to understand actual hardware and
design of low-level software layer somehow.

Actually the 'sndif' has no good abstraction for actual hardware,
therefore an idea to implement frontend driver as an ALSA driver is not
reasonable at all. 

the reason for that is that you can use the same frontend driver for various
DomUs without the need to write yet another HAL/application, e.g. if one 
of the

DomUs has no PulseAudio (uses ALSA) and yet another DomU has PulseAudio,
then using the same driver allows you to enable both out of the box with the
same codebase.
If we can imagine something else running on top of ALSA (say some other
mixing software other than PulseAudio) then we will have to support that 
as well



It's better to implement it as an application in
the other software layer, e.g. sinks/sources of PulseAudio in DomU

please see our reasoning above

via
Xenbus. This idea is nearer an original concept of Xen framework, I
guess. But I don't know we can write any applications of Xenbus in user
land of DomU or not.

Anyway, it's not a good idea to have an ALSA driver for the present 
'sndif', in my opinion.


ok, so the main concern here is that we cannot properly synchronize 
Dom0-DomU.
If we put this apart for a second are there any other concerns on having 
ALSA
frontend driver? If not, can we have the driver with timer 
implementation upstreamed

as experimental until we have some acceptable synchronization solution?
This will allow broader audience to try and feel the solution and 
probably contribute?


Regards

Takashi Sakamoto

Thank you very much for your time,
Oleksandr Andrushchenko

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] Xen 4.10 Development Update

2017-08-21 Thread Oleksandr Andrushchenko

Hi, Julien!

On 08/21/2017 01:07 PM, Julien Grall wrote:

This email only tracks big items for xen.git tree. Please reply for items you
woulk like to see in 4.10 so that people have an idea what is going on and
prioritise accordingly.

You're welcome to provide description and use cases of the feature you're
working on.


== Toolstack ==


we are working on adding support for sound/display/mtouch
into libxl/xl: display support patches + framework
refactoring patches are on review now: Oleksandr Grytsov is in charge
Patch set version: 4

== PV Drivers ==

*  Multi-touch
   -  Oleksandr Andrushchenko
   -  Oleksanr Grytsov

nothing to be done in Xen, mtouch support is already
in the Linux kernel. We are not considering QEMU's backend atm


*  Sound
   -  Oleksandr Andrushchenko
   -  Oleksanr Grytsov

nothing to be done in Xen atm, Linux kernel frontend
is on review now - may need interface extension
Patch set version: initial

*  Display
   -  Oleksandr Andrushchenko
   -  Oleksanr Grytsov

nothing to be done in Xen atm, Linux frontend is not yet
ready to be upstreamed

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RESEND1 00/12] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-08-18 Thread Oleksandr Andrushchenko


On 08/18/2017 10:17 AM, Takashi Sakamoto wrote:

On Aug 18 2017 14:56, Oleksandr Andrushchenko wrote:
Taking into account the fact that the backend we have is a user-space 
application

running on top of ALSA/PulseAudio we cannot get HW pointers from actual
hardware by any means (PulseAudio use-case is the most tough thing in 
equation)


You mean that any alsa-lib or libpulse applications run on Dom0 as a
backend driver for the frontend driver on DomU?

No, the sound backend [1] is a user-space application (ALSA/PulseAudio 
client)

which runs as a Xen para-virtual backend in Dom0 and serves all the
frontends running in DomU(s).
Other ALSA/PulseAudio clients in Dom0 are also allowed to run at the
same time.


Regards

Takashi Sakamoto

Thank you,
Oleksandr

[1] https://github.com/xen-troops/snd_be

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RESEND1 00/12] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-08-17 Thread Oleksandr Andrushchenko

Hello,

On 08/18/2017 08:43 AM, Takashi Sakamoto wrote:

On Aug 17 2017 19:05, Oleksandr Grytsov wrote:
So, from the above we think that period elapsed event derived in the 
described
ways may not improve latency and will complicate the system. So, for 
that
reason we are thinking of the option 2) (Positions of actual data 
transmission

in any serial sound interfaces of actual hardwares.)


Please declare the way to enable stuffs on DomU to get the positions 
from actual hardware.


This is what we haven't investigated yet in detail as we were mostly 
focusing on

period elapsed approach, so we can report our findings to the community.

Taking into account the fact that the backend we have is a user-space 
application

running on top of ALSA/PulseAudio we cannot get HW pointers from actual
hardware by any means (PulseAudio use-case is the most tough thing in 
equation)


At the moment we are seeking for any advise from more experienced developers
in the field on possible ways to solve the problem of Dom0/DomU 
synchronization.
Hope, together we can identify such a way that would be accepted by the 
community.


If you have something on your mind could you please share your thoughts?


Regards

Takashi Sakamoto

Thank you,
Oleksandr Andrushchenko

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] Xen Backend for sound sharing for arm

2017-08-10 Thread Oleksandr Andrushchenko

Hi,

On 08/10/2017 12:03 PM, ajmalmalib4u wrote:

Hi,
I need to do sound sharing in RCar H3.

Great that there is some interest in the work we do
I'm just curious, what is the nature of your interest?
Are you going to just use that sound solution or may want
to contribute as well (development/design/testing)?
I am currently using Xen 4.8.0. Itried to patch the guest kernel(v 
4.6.0) using the patch series [[RESEND1,01/12] ALSA: vsnd: Introduce 
Xen para-virtualized sound frontend driver] to add the support for Xen 
para-virtualized sound frontend driver which was made available a few 
days ago.


I got some errors which I guess were due to the old kernel version.

the series is based on [1] which is 4.13, this is why
So I downloaded the current stable Linux 4.12.5 from kernel.org 
 and tried to add the patches to it. But the patch 
failed due to missing fields in snd_pcm_ops in pcm.h. As such, I had 
to patch the kernel with a different patch series[[v2,02/27] ALSA: 
pcm: Introduce copy_user, copy_kernel and fill_silence ops],[ALSA: 
sound/isa: constify snd_kcontrol_new structures][ALSA: gus: remove 
unused local flag] to add the new fields to pcm.h. Also, I had to copy 
an SoC specific firmware file[r8a779x_usb3_v2.dlmem] to the 
firmware directory of the kernel directory. Finally after applying all 
these patches to v4.12.5 and building the kernel, I got the 
snd-xen-front.ko file in sound/drivers/.


How can I test whether the sound frontend is working? Is the backend 
for sound available for sndif.h?


You also need to run a user-space backend [2] in Dom0 and configure Xen 
store values

(not implemented yet)



Regards,

Ajmal


Thank you,
Oleksandr



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/log/?h=for-next

[2] https://github.com/xen-troops/snd_be/tree/vgpu-dev

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RESEND1 00/12] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-08-10 Thread Oleksandr Andrushchenko

Hi,

thank you very much for valuable comments and your time!

On 08/10/2017 06:14 AM, Takashi Sakamoto wrote:

Hi,

On Aug 7 2017 21:22, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

This patch series adds support for Xen [1] para-virtualized
sound frontend driver. It implements the protocol from
include/xen/interface/io/sndif.h with the following limitations:
- mute/unmute is not supported
- get/set volume is not supported
Volume control is not supported for the reason that most of the
use-cases (at the moment) are based on scenarious where
unprivileged OS (e.g. Android, AGL etc) use software mixers.

Both capture and playback are supported.

Thank you,
Oleksandr

Resending because of rebase onto [2] + added missing patch

[1] https://xenproject.org/
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/log/?h=for-next


Oleksandr Andrushchenko (12):
   ALSA: vsnd: Introduce Xen para-virtualized sound frontend driver
   ALSA: vsnd: Implement driver's probe/remove
   ALSA: vsnd: Implement Xen bus state handling
   ALSA: vsnd: Read sound driver configuration from Xen store
   ALSA: vsnd: Implement Xen event channel handling
   ALSA: vsnd: Implement handling of shared buffers
   ALSA: vsnd: Introduce ALSA virtual sound driver
   ALSA: vsnd: Initialize virtul sound card
   ALSA: vsnd: Add timer for period interrupt emulation
   ALSA: vsnd: Implement ALSA PCM operations
   ALSA: vsnd: Implement communication with backend
   ALSA: vsnd: Introduce Kconfig option to enable Xen PV sound

  sound/drivers/Kconfig |   12 +
  sound/drivers/Makefile|2 +
  sound/drivers/xen-front.c | 2107 
+

  3 files changed, 2121 insertions(+)
  create mode 100644 sound/drivers/xen-front.c


For this patchset, I have the same concern which Clemens Ladisch
denoted[1]. If I can understand your explanation about queueing between
Dom0/DomU stuffs, the concern can be described in short words; this
driver works without any synchronization to data transmission by actual
sound hardwares.


Yes, both your concerns and understanding are correct

In design of ALSA PCM core, drivers are expected to synchronize to
actual hardwares for semi-realtime data transmission. The
synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces
   of actual hardwares.

These two points comes from typical designs of actual hardwares, thus
they doesn't come from unfair, unreasonable, intrusive demands from
software side.


This clear, thank you

In design of typical stuffs on para-virtualization, Dom0 stuffs are hard
to give enough abstraction of sound hardwares in these two points for
DomU stuffs. Especially, it cannot abstract point 2) at all because the
value of position should be accurate against actual time frame, while
there's an overhead for DomU stuffs to read it. When DomU stuffs handles
the value, the value is enough past due to context switches between
Dom0/DomU. Therefore, this driver must rely on point 1) to synchronize
to actual sound hardwares.

Which will also introduce some latency too: time needed to deliver and
handle interrupt from Dom0 to DomU

Typically, drivers configure hardwares to
generate interrupts per period of PCM buffer. This means that this
driver should notify to Dom0 about the value of period size requested
by applications.

In 'include/xen/interface/io/sndif.h', there's no functionalities I
described the above:
1. notifications from DomU to Dom0 about the size of period for
   interrupts from actual hardwares. Or no way from Dom0 to DomU about
   the configured size of the period.

Ok, then on "open" command I will pass from DomU to Dom0 an additional
parameter, period size. Then Dom0 will respond with actual period size
for DomU to use. So, this way period size will be negotiated.
Does the above look ok to you?

2. notifications of the interrupts from actual hardwares to DomU.


Ok, I will introduce an event from Dom0 to DomU to signal period elapsed.

Taking into account the fact that period size may be as small as,
say, 1ms, do you think we can/need to mangle period size in 1) on Dom0 side
to be reasonable, so we do not flood with interrupts/events from Dom0 to 
DomU?

Do you see any "formula" to determine that reasonable/acceptable
period limit, so both Dom0 and DomU are happy?


For the reasons, your driver used kernel's timer interface to generate
'pseudo' interrupts for the purpose. However, it depends on Dom0's
abstraction different from sound hardwares and Linux kernel's
abstraction for timer functionality. In this case, gap between 'actual'
interrupts from hardware and the 'pseudo' interrupts from a combination
of several components brings unexpected result on several situations.


You are right

I think this is defects of 's

Re: [Xen-devel] [alsa-devel] [PATCH 08/11] ALSA: vsnd: Add timer for period interrupt emulation

2017-08-07 Thread Oleksandr Andrushchenko

On 08/07/2017 06:14 PM, Oleksandr Andrushchenko wrote:


On 08/07/2017 04:55 PM, Clemens Ladisch wrote:

Oleksandr Andrushchenko wrote:

On 08/07/2017 04:11 PM, Clemens Ladisch wrote:

How does that interface work?

For the buffer received in .copy_user/.copy_kernel we send
a request to the backend and get response back (async) when it has 
copied
the bytes into HW/mixer/etc, so the buffer at frontend side can be 
reused.

So if the frontend sends too many (too large) requests, does the
backend wait until there is enough free space in the buffer before
it does the actual copying and then acks?

Well, the frontend should be backend agnostic,
In our implementation backend is a user-space application which sits
either on top of ALSA driver or PulseAudio: so, it acks correspondingly,
e.g, when, for example, ALSA driver completes .copy_user and returns
from the kernel

If yes, then these acks can be used as interrupts.

we can probably teach our backend to track periods elapsed for ALSA,
but not sure if it is possible for PulseAudio - do you know if this is 
also

doable for pulse?

Let's assume backend blocks until the buffer played/consumed...

   (You still
have to count frames, and call snd_pcm_period_elapsed() exactly
when a period boundary was reached or crossed.)
... and what if the buffer has multiple periods? So, that the backend 
sends
a single response for multiple periods (buffers with fractional period 
number

can be handled separately)?
We will have to either send snd_pcm_period_elapsed once (wrong, because
multiple periods consumed) or multiple times at one time with no delay 
(wrong,
because there will be a confusion that multiple periods were not 
reported for quite

some long time and then there is a burst of events)
Either way the behavior will not be the one desired (please correct me
if I am wrong here)


Splitting a large read/write into smaller requests to the backend
would improve the granularity of the known stream position.

The overall latency would be the sum of the sizes of the frontend
and backend buffers.


Why is the protocol designed this way?
We also work on para-virtualizing display device and there we tried to 
use

page flip events from backend to frontend to signal similar to
period interrupt for audio. When multiple displays (read multiple 
audio streams)
were in place we flooded with the system interrupts (which are period 
events in our case)

and performance dropped significantly. This is why we switched to
interrupt emulation, here via timer for audio. The main measures were:
1. Number of events between front and back
2. Latency
With timer approach we reduce 1) to the minimum which is a must (no 
period

interrupts), but 2) is still here
With emulated period interrupts (protocol events) we have issue with 1)
and still 2) remains.


BTW, there is one more approach to solve this [1],
but it uses its own Xen sound protocol and heavily relies
on Linux implementation, which cannot be a part of a generic protocol

So, to me, neither approach solves the problem for 100%, so we decided
to stick to timers. Hope, this gives more background on why we did things
the way we did.

  Wasn't the goal to expose
some 'real' sound card?


yes, but it can be implemented in different ways, please see above

Regards,
Clemens

Thank you for your interest,
Oleksandr


[1] 
https://github.com/OpenXT/pv-linux-drivers/blob/master/archive/openxt-audio/main.c#L356


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [alsa-devel] [PATCH 08/11] ALSA: vsnd: Add timer for period interrupt emulation

2017-08-07 Thread Oleksandr Andrushchenko


On 08/07/2017 04:55 PM, Clemens Ladisch wrote:

Oleksandr Andrushchenko wrote:

On 08/07/2017 04:11 PM, Clemens Ladisch wrote:

How does that interface work?

For the buffer received in .copy_user/.copy_kernel we send
a request to the backend and get response back (async) when it has copied
the bytes into HW/mixer/etc, so the buffer at frontend side can be reused.

So if the frontend sends too many (too large) requests, does the
backend wait until there is enough free space in the buffer before
it does the actual copying and then acks?

Well, the frontend should be backend agnostic,
In our implementation backend is a user-space application which sits
either on top of ALSA driver or PulseAudio: so, it acks correspondingly,
e.g, when, for example, ALSA driver completes .copy_user and returns
from the kernel

If yes, then these acks can be used as interrupts.

we can probably teach our backend to track periods elapsed for ALSA,
but not sure if it is possible for PulseAudio - do you know if this is also
doable for pulse?

Let's assume backend blocks until the buffer played/consumed...

   (You still
have to count frames, and call snd_pcm_period_elapsed() exactly
when a period boundary was reached or crossed.)

... and what if the buffer has multiple periods? So, that the backend sends
a single response for multiple periods (buffers with fractional period 
number

can be handled separately)?
We will have to either send snd_pcm_period_elapsed once (wrong, because
multiple periods consumed) or multiple times at one time with no delay 
(wrong,
because there will be a confusion that multiple periods were not 
reported for quite

some long time and then there is a burst of events)
Either way the behavior will not be the one desired (please correct me
if I am wrong here)


Splitting a large read/write into smaller requests to the backend
would improve the granularity of the known stream position.

The overall latency would be the sum of the sizes of the frontend
and backend buffers.


Why is the protocol designed this way?

We also work on para-virtualizing display device and there we tried to use
page flip events from backend to frontend to signal similar to
period interrupt for audio. When multiple displays (read multiple audio 
streams)
were in place we flooded with the system interrupts (which are period 
events in our case)

and performance dropped significantly. This is why we switched to
interrupt emulation, here via timer for audio. The main measures were:
1. Number of events between front and back
2. Latency
With timer approach we reduce 1) to the minimum which is a must (no period
interrupts), but 2) is still here
With emulated period interrupts (protocol events) we have issue with 1)
and still 2) remains.

So, to me, neither approach solves the problem for 100%, so we decided
to stick to timers. Hope, this gives more background on why we did things
the way we did.

  Wasn't the goal to expose
some 'real' sound card?


yes, but it can be implemented in different ways, please see above

Regards,
Clemens

Thank you for your interest,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [alsa-devel] [PATCH 08/11] ALSA: vsnd: Add timer for period interrupt emulation

2017-08-07 Thread Oleksandr Andrushchenko

On 08/07/2017 04:11 PM, Clemens Ladisch wrote:

Oleksandr Andrushchenko wrote:

On 08/07/2017 01:27 PM, Clemens Ladisch wrote:

You have to implement period interrupts (and the .pointer callback)
based on when the samples are actually moved from/to the backend.

Do you think I can implement this in a slightly different way,
without a timer at all, by updating
substream->runtime->hw_ptr_base explicitly in the frontend driver?

As far as I am aware, hw_ptr_base is an internal field that drivers
are not supposed to change.

I know that and always considered not a good solution,
this is why I have timer to emulate things

Just use your own variable, and return it from the .pointer callback.

this can work, but see below

So, that way, whenever I get an ack/response from the backend that it has
successfully played the buffer

That response should come after every period.



How does that interface work?

For the buffer received in .copy_user/.copy_kernel we send
a request to the backend and get response back (async) when it has copied
the bytes into HW/mixer/etc, so the buffer at frontend side can be reused.
So, the amount of bytes in this exchange is not necessarily
a multiply of the period. Also, there is no way to synchronize period
sizes in the front driver and backend to make those equal.
There is also no event from the backend in the
protocol to tell that the period has elapsed, so
sending data in period's size buffers will not probably
help because of possible underruns

  Is it possible to change the period size,
or at least to detect what it is?


Unfortunately no, this is not in the protocol.




Regards,
Clemens

you can see the protocol at [1]

Thank you,
Oleksandr

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/tree/include/xen/interface/io/sndif.h?h=for-next


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RESEND 00/11] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-08-07 Thread Oleksandr Andrushchenko



On 08/07/2017 03:30 PM, Takashi Sakamoto wrote:

On Aug 7 2017 21:18, Oleksandr Andrushchenko wrote:
Your first patch includes code difference under line 26, thus it 
expects existence of a file 'sound/drivers/xen-front.c' in tree. 
However, the file is not introduced in any upstream yet; at least, 
Linus's tree and Iwai-san's tree.

I missed the very first patch in the series, this is why, my bad


When I did the same mistake, I take git-hash for a first commit in 
series as an argument into git-format-patch command. But this 
operation generated patchset which starts at second commit. I solved 
this to add '~', like.


$ git format-patch -s the-git-hash~...

Or pick up the hash for a commit just before a first commit in the 
series. For your information ;)



thank you for the hint, will use instead of specifying number of patches
(this is why I missed one and made so much noise)


Regards

Takashi Sakamoto

Thank you,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RESEND1 09/12] ALSA: vsnd: Add timer for period interrupt emulation

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Front sound driver has no real interrupts, so
playback/capture period passed interrupt needs to be emulated:
this is done via timer. Add required timer operations,
this is based on sound/drivers/dummy.c.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 121 ++
 1 file changed, 121 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 9f31e6832086..507c5eb343c8 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -67,12 +67,29 @@ struct sh_buf_info {
size_t vbuffer_sz;
 };
 
+struct sdev_alsa_timer_info {
+   spinlock_t lock;
+   struct timer_list timer;
+   unsigned long base_time;
+   /* fractional sample position (based HZ) */
+   unsigned int frac_pos;
+   unsigned int frac_period_rest;
+   /* buffer_size * HZ */
+   unsigned int frac_buffer_size;
+   /* period_size * HZ */
+   unsigned int frac_period_size;
+   unsigned int rate;
+   int elapsed;
+   struct snd_pcm_substream *substream;
+};
+
 struct sdev_pcm_stream_info {
int unique_id;
struct snd_pcm_hardware pcm_hw;
struct xdrv_evtchnl_info *evt_chnl;
bool is_open;
uint8_t req_next_id;
+   struct sdev_alsa_timer_info timer;
struct sh_buf_info sh_buf;
 };
 
@@ -148,6 +165,110 @@ static struct sdev_pcm_stream_info *sdrv_stream_get(
return stream;
 }
 
+static inline void sdrv_alsa_timer_rearm(struct sdev_alsa_timer_info *dpcm)
+{
+   mod_timer(&dpcm->timer, jiffies +
+   (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate);
+}
+
+static void sdrv_alsa_timer_update(struct sdev_alsa_timer_info *dpcm)
+{
+   unsigned long delta;
+
+   delta = jiffies - dpcm->base_time;
+   if (!delta)
+   return;
+   dpcm->base_time += delta;
+   delta *= dpcm->rate;
+   dpcm->frac_pos += delta;
+   while (dpcm->frac_pos >= dpcm->frac_buffer_size)
+   dpcm->frac_pos -= dpcm->frac_buffer_size;
+   while (dpcm->frac_period_rest <= delta) {
+   dpcm->elapsed++;
+   dpcm->frac_period_rest += dpcm->frac_period_size;
+   }
+   dpcm->frac_period_rest -= delta;
+}
+
+static int sdrv_alsa_timer_start(struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   spin_lock(&dpcm->lock);
+   dpcm->base_time = jiffies;
+   sdrv_alsa_timer_rearm(dpcm);
+   spin_unlock(&dpcm->lock);
+   return 0;
+}
+
+static int sdrv_alsa_timer_stop(struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   spin_lock(&dpcm->lock);
+   del_timer(&dpcm->timer);
+   spin_unlock(&dpcm->lock);
+   return 0;
+}
+
+static int sdrv_alsa_timer_prepare(struct snd_pcm_substream *substream)
+{
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   dpcm->frac_pos = 0;
+   dpcm->rate = runtime->rate;
+   dpcm->frac_buffer_size = runtime->buffer_size * HZ;
+   dpcm->frac_period_size = runtime->period_size * HZ;
+   dpcm->frac_period_rest = dpcm->frac_period_size;
+   dpcm->elapsed = 0;
+   return 0;
+}
+
+static void sdrv_alsa_timer_callback(unsigned long data)
+{
+   struct sdev_alsa_timer_info *dpcm = (struct sdev_alsa_timer_info *)data;
+   int elapsed;
+
+   spin_lock(&dpcm->lock);
+   sdrv_alsa_timer_update(dpcm);
+   sdrv_alsa_timer_rearm(dpcm);
+   elapsed = dpcm->elapsed;
+   dpcm->elapsed = 0;
+   spin_unlock(&dpcm->lock);
+   if (elapsed)
+   snd_pcm_period_elapsed(dpcm->substream);
+}
+
+static snd_pcm_uframes_t sdrv_alsa_timer_pointer(
+   struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+   snd_pcm_uframes_t pos;
+
+   spin_lock(&dpcm->lock);
+   sdrv_alsa_timer_update(dpcm);
+   pos = dpcm->frac_pos / HZ;
+   spin_unlock(&dpcm->lock);
+   return pos;
+}
+
+static int sdrv_alsa_timer_create(struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   spin_lock_init(&dpcm->lock);
+   dpcm->substream = substream;
+   setup_timer(&dpcm->

[Xen-devel] [PATCH RESEND1 06/12] ALSA: vsnd: Implement handling of shared buffers

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement shared buffer handling according to the
para-virtualized sound device protocol at xen/interface/io/sndif.h:
- manage buffer memory
- handle granted references
- handle page directories

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 178 ++
 1 file changed, 178 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index a92459b2737e..04ebc15757f4 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -58,6 +58,14 @@ struct xdrv_evtchnl_info {
uint16_t resp_id;
 };
 
+struct sh_buf_info {
+   int num_grefs;
+   grant_ref_t *grefs;
+   uint8_t *vdirectory;
+   uint8_t *vbuffer;
+   size_t vbuffer_sz;
+};
+
 struct cfg_stream {
int unique_id;
char *xenstore_path;
@@ -825,6 +833,176 @@ static void xdrv_remove_internal(struct xdrv_info 
*drv_info)
xdrv_evtchnl_free_all(drv_info);
 }
 
+static inline grant_ref_t sh_buf_get_dir_start(struct sh_buf_info *buf)
+{
+   if (!buf->grefs)
+   return GRANT_INVALID_REF;
+   return buf->grefs[0];
+}
+
+static inline void sh_buf_clear(struct sh_buf_info *buf)
+{
+   memset(buf, 0, sizeof(*buf));
+}
+
+static void sh_buf_free(struct sh_buf_info *buf)
+{
+   int i;
+
+   if (buf->grefs) {
+   for (i = 0; i < buf->num_grefs; i++)
+   if (buf->grefs[i] != GRANT_INVALID_REF)
+   gnttab_end_foreign_access(buf->grefs[i],
+   0, 0UL);
+   kfree(buf->grefs);
+   }
+   kfree(buf->vdirectory);
+   free_pages_exact(buf->vbuffer, buf->vbuffer_sz);
+   sh_buf_clear(buf);
+}
+
+/*
+ * number of grant references a page can hold with respect to the
+ * xendispl_page_directory header
+ */
+#define XENSND_NUM_GREFS_PER_PAGE ((XEN_PAGE_SIZE - \
+   offsetof(struct xensnd_page_directory, gref)) / \
+   sizeof(grant_ref_t))
+
+static void sh_buf_fill_page_dir(struct sh_buf_info *buf, int num_pages_dir)
+{
+   struct xensnd_page_directory *page_dir;
+   unsigned char *ptr;
+   int i, cur_gref, grefs_left, to_copy;
+
+   ptr = buf->vdirectory;
+   grefs_left = buf->num_grefs - num_pages_dir;
+   /*
+* skip grant references at the beginning, they are for pages granted
+* for the page directory itself
+*/
+   cur_gref = num_pages_dir;
+   for (i = 0; i < num_pages_dir; i++) {
+   page_dir = (struct xensnd_page_directory *)ptr;
+   if (grefs_left <= XENSND_NUM_GREFS_PER_PAGE) {
+   to_copy = grefs_left;
+   page_dir->gref_dir_next_page = GRANT_INVALID_REF;
+   } else {
+   to_copy = XENSND_NUM_GREFS_PER_PAGE;
+   page_dir->gref_dir_next_page = buf->grefs[i + 1];
+   }
+   memcpy(&page_dir->gref, &buf->grefs[cur_gref],
+   to_copy * sizeof(grant_ref_t));
+   ptr += XEN_PAGE_SIZE;
+   grefs_left -= to_copy;
+   cur_gref += to_copy;
+   }
+}
+
+static int sh_buf_grant_refs(struct xenbus_device *xb_dev,
+   struct sh_buf_info *buf,
+   int num_pages_dir, int num_pages_vbuffer, int num_grefs)
+{
+   grant_ref_t priv_gref_head;
+   int ret, i, j, cur_ref;
+   int otherend_id;
+
+   ret = gnttab_alloc_grant_references(num_grefs, &priv_gref_head);
+   if (ret)
+   return ret;
+
+   buf->num_grefs = num_grefs;
+   otherend_id = xb_dev->otherend_id;
+   j = 0;
+
+   for (i = 0; i < num_pages_dir; i++) {
+   cur_ref = gnttab_claim_grant_reference(&priv_gref_head);
+   if (cur_ref < 0) {
+   ret = cur_ref;
+   goto fail;
+   }
+
+   gnttab_grant_foreign_access_ref(cur_ref, otherend_id,
+   xen_page_to_gfn(virt_to_page(buf->vdirectory +
+   XEN_PAGE_SIZE * i)), 0);
+   buf->grefs[j++] = cur_ref;
+   }
+
+   for (i = 0; i < num_pages_vbuffer; i++) {
+   cur_ref = gnttab_claim_grant_reference(&priv_gref_head);
+   if (cur_ref < 0) {
+   ret = cur_ref;
+   goto fail;
+   }
+
+   gnttab_grant_foreign_access_ref(cur_ref, otherend_id,
+   xen_page_to_gfn(virt_to_page(buf->vbuffer +
+   XEN_PAGE_SIZE * i)), 0);
+   buf->grefs[j++] = cur_ref;
+   }
+
+   gnttab_free_grant_references(priv_gref_head);
+   sh_buf_fill_page_dir(buf, num_pages_dir);
+   return 0;
+
+fail:
+   gnttab_free_grant_references(priv_gref_hea

[Xen-devel] [PATCH RESEND1 07/12] ALSA: vsnd: Introduce ALSA virtual sound driver

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement essential initialization of the sound driver:
- introduce required data structures
- handle driver registration
- handle sound card registration
- register sound driver on backend connection
- remove sound driver on backend disconnect

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 161 +-
 1 file changed, 159 insertions(+), 2 deletions(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 04ebc15757f4..f3e3f64f0aa6 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -19,13 +19,14 @@
  */
 
 #include 
+#include 
 
 #include 
 #include 
 
-#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -66,6 +67,33 @@ struct sh_buf_info {
size_t vbuffer_sz;
 };
 
+struct sdev_pcm_stream_info {
+   int unique_id;
+   struct snd_pcm_hardware pcm_hw;
+   struct xdrv_evtchnl_info *evt_chnl;
+   bool is_open;
+   uint8_t req_next_id;
+   struct sh_buf_info sh_buf;
+};
+
+struct sdev_pcm_instance_info {
+   struct sdev_card_info *card_info;
+   struct snd_pcm *pcm;
+   struct snd_pcm_hardware pcm_hw;
+   int num_pcm_streams_pb;
+   struct sdev_pcm_stream_info *streams_pb;
+   int num_pcm_streams_cap;
+   struct sdev_pcm_stream_info *streams_cap;
+};
+
+struct sdev_card_info {
+   struct xdrv_info *xdrv_info;
+   struct snd_card *card;
+   struct snd_pcm_hardware pcm_hw;
+   int num_pcm_instances;
+   struct sdev_pcm_instance_info *pcm_instances;
+};
+
 struct cfg_stream {
int unique_id;
char *xenstore_path;
@@ -99,6 +127,8 @@ struct xdrv_info {
struct xenbus_device *xb_dev;
spinlock_t io_lock;
struct mutex mutex;
+   bool sdrv_registered;
+   struct platform_device *sdrv_pdev;
int num_evt_channels;
struct xdrv_evtchnl_info *evt_chnls;
struct sdev_card_plat_data cfg_plat_data;
@@ -138,6 +168,132 @@ static struct snd_pcm_hardware sdrv_pcm_hw_default = {
.fifo_size = 0,
 };
 
+static int sdrv_new_pcm(struct sdev_card_info *card_info,
+   struct cfg_pcm_instance *instance_config,
+   struct sdev_pcm_instance_info *pcm_instance_info)
+{
+   return 0;
+}
+
+static int sdrv_probe(struct platform_device *pdev)
+{
+   struct sdev_card_info *card_info;
+   struct sdev_card_plat_data *platdata;
+   struct snd_card *card;
+   int ret, i;
+
+   platdata = dev_get_platdata(&pdev->dev);
+
+   dev_dbg(&pdev->dev, "Creating virtual sound card\n");
+
+   ret = snd_card_new(&pdev->dev, 0, XENSND_DRIVER_NAME, THIS_MODULE,
+   sizeof(struct sdev_card_info), &card);
+   if (ret < 0)
+   return ret;
+
+   card_info = card->private_data;
+   card_info->xdrv_info = platdata->xdrv_info;
+   card_info->card = card;
+   card_info->pcm_instances = devm_kcalloc(&pdev->dev,
+   platdata->cfg_card.num_pcm_instances,
+   sizeof(struct sdev_pcm_instance_info), GFP_KERNEL);
+   if (!card_info->pcm_instances) {
+   ret = -ENOMEM;
+   goto fail;
+   }
+
+   card_info->num_pcm_instances = platdata->cfg_card.num_pcm_instances;
+   card_info->pcm_hw = platdata->cfg_card.pcm_hw;
+
+   for (i = 0; i < platdata->cfg_card.num_pcm_instances; i++) {
+   ret = sdrv_new_pcm(card_info,
+   &platdata->cfg_card.pcm_instances[i],
+   &card_info->pcm_instances[i]);
+   if (ret < 0)
+   goto fail;
+   }
+
+   strncpy(card->driver, XENSND_DRIVER_NAME, sizeof(card->driver));
+   strncpy(card->shortname, platdata->cfg_card.name_short,
+   sizeof(card->shortname));
+   strncpy(card->longname, platdata->cfg_card.name_long,
+   sizeof(card->longname));
+
+   ret = snd_card_register(card);
+   if (ret < 0)
+   goto fail;
+
+   platform_set_drvdata(pdev, card);
+   return 0;
+
+fail:
+   snd_card_free(card);
+   return ret;
+}
+
+static int sdrv_remove(struct platform_device *pdev)
+{
+   struct sdev_card_info *info;
+   struct snd_card *card = platform_get_drvdata(pdev);
+
+   info = card->private_data;
+   dev_dbg(&pdev->dev, "Removing virtual sound card %d\n",
+   info->card->number);
+   snd_card_free(card);
+   return 0;
+}
+
+static struct platform_driver sdrv_info = {
+   .probe  = sdrv_probe,
+   .remove = sdrv_remove,
+   .driver = {
+   .name   = XENSND_DRIVER_NAME,
+   },
+};
+
+static void sdrv_cleanup(struct xdrv_info *drv_info)
+{
+   if (!drv_info->sdrv_registered)
+   return;
+
+   i

[Xen-devel] [PATCH RESEND1 10/12] ALSA: vsnd: Implement ALSA PCM operations

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement ALSA driver operations including:
- start/stop period interrupt emulation
- manage frontend/backend shraed buffers
- manage Xen bus event channel state

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 175 ++
 1 file changed, 163 insertions(+), 12 deletions(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 507c5eb343c8..7275e9cb38c0 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -151,6 +151,11 @@ struct xdrv_info {
struct sdev_card_plat_data cfg_plat_data;
 };
 
+static inline void sh_buf_clear(struct sh_buf_info *buf);
+static void sh_buf_free(struct sh_buf_info *buf);
+static int sh_buf_alloc(struct xenbus_device *xb_dev, struct sh_buf_info *buf,
+   unsigned int buffer_size);
+
 static struct sdev_pcm_stream_info *sdrv_stream_get(
struct snd_pcm_substream *substream)
 {
@@ -311,71 +316,217 @@ static void sdrv_copy_pcm_hw(struct snd_pcm_hardware 
*dst,
 
 static int sdrv_alsa_open(struct snd_pcm_substream *substream)
 {
-   return 0;
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct xdrv_info *xdrv_info;
+   unsigned long flags;
+   int ret;
+
+   sdrv_copy_pcm_hw(&runtime->hw, &stream->pcm_hw, &pcm_instance->pcm_hw);
+   runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
+   SNDRV_PCM_INFO_MMAP_VALID |
+   SNDRV_PCM_INFO_DOUBLE |
+   SNDRV_PCM_INFO_BATCH |
+   SNDRV_PCM_INFO_NONINTERLEAVED |
+   SNDRV_PCM_INFO_RESUME |
+   SNDRV_PCM_INFO_PAUSE);
+   runtime->hw.info |= SNDRV_PCM_INFO_INTERLEAVED;
+
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+
+   ret = sdrv_alsa_timer_create(substream);
+
+   spin_lock_irqsave(&xdrv_info->io_lock, flags);
+   sh_buf_clear(&stream->sh_buf);
+   stream->evt_chnl = &xdrv_info->evt_chnls[stream->unique_id];
+   if (ret < 0)
+   stream->evt_chnl->state = EVTCHNL_STATE_DISCONNECTED;
+   else
+   stream->evt_chnl->state = EVTCHNL_STATE_CONNECTED;
+   spin_unlock_irqrestore(&xdrv_info->io_lock, flags);
+   return ret;
 }
 
 static int sdrv_alsa_close(struct snd_pcm_substream *substream)
 {
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct xdrv_info *xdrv_info;
+   unsigned long flags;
+
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+
+   sdrv_alsa_timer_stop(substream);
+
+   spin_lock_irqsave(&xdrv_info->io_lock, flags);
+   stream->evt_chnl->state = EVTCHNL_STATE_DISCONNECTED;
+   spin_unlock_irqrestore(&xdrv_info->io_lock, flags);
return 0;
 }
 
 static int sdrv_alsa_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
 {
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct xdrv_info *xdrv_info;
+   unsigned int buffer_size;
+   int ret;
+
+   buffer_size = params_buffer_bytes(params);
+   sh_buf_clear(&stream->sh_buf);
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+   ret = sh_buf_alloc(xdrv_info->xb_dev,
+   &stream->sh_buf, buffer_size);
+   if (ret < 0)
+   goto fail;
return 0;
+
+fail:
+   dev_err(&xdrv_info->xb_dev->dev,
+   "Failed to allocate buffers for stream idx %d\n",
+   stream->unique_id);
+   return ret;
 }
 
 static int sdrv_alsa_hw_free(struct snd_pcm_substream *substream)
 {
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct xdrv_info *xdrv_info;
+   unsigned long flags;
+
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+   spin_lock_irqsave(&xdrv_info->io_lock, flags);
+   sh_buf_free(&stream->sh_buf);
+   spin_unlock_irqrestore(&xdrv_info->io_lock, flags);
return 0;
 }
 
 static int sdrv_alsa_prepare(struct snd_pcm_substream *substream)
 {
-   return 0;
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   int ret = 0;
+
+   if (!stream->is_open)
+   ret = sdrv_alsa_timer_prepare(substream);
+   return ret;
 }
 
 static int sdrv_alsa_trigger(struct snd_p

[Xen-devel] [PATCH RESEND1 08/12] ALSA: vsnd: Initialize virtul sound card

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Initialize virtual sound card with streams according to the
Xen store configuration.
Add stubs for stream PCM operations.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 232 ++
 1 file changed, 232 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index f3e3f64f0aa6..9f31e6832086 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -134,6 +134,129 @@ struct xdrv_info {
struct sdev_card_plat_data cfg_plat_data;
 };
 
+static struct sdev_pcm_stream_info *sdrv_stream_get(
+   struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream;
+
+   if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+   stream = &pcm_instance->streams_pb[substream->number];
+   else
+   stream = &pcm_instance->streams_cap[substream->number];
+   return stream;
+}
+
+static void sdrv_copy_pcm_hw(struct snd_pcm_hardware *dst,
+   struct snd_pcm_hardware *src,
+   struct snd_pcm_hardware *ref_pcm_hw)
+{
+   *dst = *ref_pcm_hw;
+
+   if (src->formats)
+   dst->formats = src->formats;
+   if (src->buffer_bytes_max)
+   dst->buffer_bytes_max =
+   src->buffer_bytes_max;
+   if (src->period_bytes_min)
+   dst->period_bytes_min =
+   src->period_bytes_min;
+   if (src->period_bytes_max)
+   dst->period_bytes_max =
+   src->period_bytes_max;
+   if (src->periods_min)
+   dst->periods_min = src->periods_min;
+   if (src->periods_max)
+   dst->periods_max = src->periods_max;
+   if (src->rates)
+   dst->rates = src->rates;
+   if (src->rate_min)
+   dst->rate_min = src->rate_min;
+   if (src->rate_max)
+   dst->rate_max = src->rate_max;
+   if (src->channels_min)
+   dst->channels_min = src->channels_min;
+   if (src->channels_max)
+   dst->channels_max = src->channels_max;
+   if (src->buffer_bytes_max) {
+   dst->buffer_bytes_max = src->buffer_bytes_max;
+   dst->period_bytes_max = src->buffer_bytes_max /
+   src->periods_max;
+   dst->periods_max = dst->buffer_bytes_max /
+   dst->period_bytes_max;
+   }
+}
+
+static int sdrv_alsa_open(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_close(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_hw_params(struct snd_pcm_substream *substream,
+   struct snd_pcm_hw_params *params)
+{
+   return 0;
+}
+
+static int sdrv_alsa_hw_free(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_prepare(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+   return 0;
+}
+
+static inline snd_pcm_uframes_t sdrv_alsa_pointer(
+   struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_playback_copy_user(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void __user *buf,
+   unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_playback_copy_kernel(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void *buf, unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_capture_copy_user(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void __user *buf,
+   unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_capture_copy_kernel(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void *buf, unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_playback_fill_silence(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, unsigned long bytes)
+{
+   return 0;
+}
+
 #define MAX_XEN_BUFFER_SIZE(64 * 1024)
 #define MAX_BUFFER_SIZEMAX_XEN_BUFFER_SIZE
 #define MIN_PERIOD_SIZE64
@@ -168,10 +291,119 @@ static struct snd_pcm_hardware sdrv_pcm_hw_default = {
.fifo_size = 0,
 };
 
+/*
+ * FIXME: The mmaped data transfer is asynchronous and there is no
+ * ack signal from user-space when it is done. This is the
+ * reason it is not implemented in the PV driver as we do need
+ * to know when the buffer can be transferred to the backend.
+ */
+
+static struct snd_pcm_ops sdrv_alsa_playback_ops = {
+   .op

[Xen-devel] [PATCH RESEND1 12/12] ALSA: vsnd: Introduce Kconfig option to enable Xen PV sound

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Introduce Kconfig option to enable Xen para-virtualized sound
frontend driver. Also add sound frontend to the Makefile.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/Kconfig  | 12 
 sound/drivers/Makefile |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 7144cc36e8ae..6b8fa6110ca3 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -235,4 +235,16 @@ config SND_AC97_POWER_SAVE_DEFAULT
 
  See SND_AC97_POWER_SAVE for more details.
 
+config SND_XEN_FRONTEND
+   tristate "Xen virtual sound front-end driver"
+   depends on SND_PCM && XEN
+   select XEN_XENBUS_FRONTEND
+   default n
+   help
+ This driver implements a front-end for the Xen
+ para-virtualized sound.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-xen-front.
+
 endif  # SND_DRIVERS
diff --git a/sound/drivers/Makefile b/sound/drivers/Makefile
index 1a8440c8b138..70ed920a030f 100644
--- a/sound/drivers/Makefile
+++ b/sound/drivers/Makefile
@@ -11,6 +11,7 @@ snd-portman2x4-objs := portman2x4.o
 snd-serial-u16550-objs := serial-u16550.o
 snd-virmidi-objs := virmidi.o
 snd-ml403-ac97cr-objs := ml403-ac97cr.o pcm-indirect2.o
+snd-xen-front-objs := xen-front.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_DUMMY) += snd-dummy.o
@@ -21,5 +22,6 @@ obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o
 obj-$(CONFIG_SND_MTS64) += snd-mts64.o
 obj-$(CONFIG_SND_PORTMAN2X4) += snd-portman2x4.o
 obj-$(CONFIG_SND_ML403_AC97CR) += snd-ml403-ac97cr.o
+obj-$(CONFIG_SND_XEN_FRONTEND) += snd-xen-front.o
 
 obj-$(CONFIG_SND) += opl3/ opl4/ mpu401/ vx/ pcsp/
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RESEND1 11/12] ALSA: vsnd: Implement communication with backend

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement frontend to backend communication according to
the para-virtualized sound protocol: xen/interface/io/sndif.h.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 302 +++---
 1 file changed, 288 insertions(+), 14 deletions(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 7275e9cb38c0..8bfec43ef03a 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -38,6 +38,8 @@
  * because of the fact it is already in use/reserved by the PV console.
  */
 #define GRANT_INVALID_REF  0
+/* timeout in ms to wait for backend to respond */
+#define VSND_WAIT_BACK_MS  3000
 /* maximum number of supported streams */
 #define VSND_MAX_STREAM8
 
@@ -151,10 +153,12 @@ struct xdrv_info {
struct sdev_card_plat_data cfg_plat_data;
 };
 
+static inline void xdrv_evtchnl_flush(struct xdrv_evtchnl_info *channel);
 static inline void sh_buf_clear(struct sh_buf_info *buf);
 static void sh_buf_free(struct sh_buf_info *buf);
 static int sh_buf_alloc(struct xenbus_device *xb_dev, struct sh_buf_info *buf,
unsigned int buffer_size);
+static grant_ref_t sh_buf_get_dir_start(struct sh_buf_info *buf);
 
 static struct sdev_pcm_stream_info *sdrv_stream_get(
struct snd_pcm_substream *substream)
@@ -314,6 +318,234 @@ static void sdrv_copy_pcm_hw(struct snd_pcm_hardware *dst,
}
 }
 
+struct ALSA_SNDIF_SAMPLE_FORMAT {
+   uint8_t sndif;
+   snd_pcm_format_t alsa;
+};
+
+static struct ALSA_SNDIF_SAMPLE_FORMAT alsa_sndif_formats[] = {
+   {
+   .sndif = XENSND_PCM_FORMAT_U8,
+   .alsa = SNDRV_PCM_FORMAT_U8
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S8,
+   .alsa = SNDRV_PCM_FORMAT_S8
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U16_LE,
+   .alsa = SNDRV_PCM_FORMAT_U16_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U16_BE,
+   .alsa = SNDRV_PCM_FORMAT_U16_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S16_LE,
+   .alsa = SNDRV_PCM_FORMAT_S16_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S16_BE,
+   .alsa = SNDRV_PCM_FORMAT_S16_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U24_LE,
+   .alsa = SNDRV_PCM_FORMAT_U24_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U24_BE,
+   .alsa = SNDRV_PCM_FORMAT_U24_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S24_LE,
+   .alsa = SNDRV_PCM_FORMAT_S24_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S24_BE,
+   .alsa = SNDRV_PCM_FORMAT_S24_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U32_LE,
+   .alsa = SNDRV_PCM_FORMAT_U32_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U32_BE,
+   .alsa = SNDRV_PCM_FORMAT_U32_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S32_LE,
+   .alsa = SNDRV_PCM_FORMAT_S32_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S32_BE,
+   .alsa = SNDRV_PCM_FORMAT_S32_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_A_LAW,
+   .alsa = SNDRV_PCM_FORMAT_A_LAW
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_MU_LAW,
+   .alsa = SNDRV_PCM_FORMAT_MU_LAW
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F32_LE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F32_BE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F64_LE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT64_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F64_BE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT64_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE,
+   .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE,
+   .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IMA_ADPCM,
+   .alsa = SNDRV_PCM_FORMAT_IMA_ADPCM
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_MPEG,
+   .alsa = SNDRV_PCM_FORMAT_MPEG
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_GSM,
+   .alsa = SNDRV_PCM_FORMAT_GSM
+   },
+};
+
+static int alsa_to_sndif_format(snd_pcm_format_t format)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(alsa_sndif_formats); i++)
+   if (alsa_sndif_formats[i].alsa == format)
+   return alsa_sndif_formats[i].sndif;
+   return -EINVAL;
+}
+
+static void sdrv_stream_clear(str

[Xen-devel] [PATCH RESEND1 03/12] ALSA: vsnd: Implement Xen bus state handling

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Initial handling for Xen bus states: implement
Xen bus state machine for the front driver according to
the state diagram and recovery flow from sound para-virtualized
protocol: xen/interface/io/sndif.h.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 92 +++
 1 file changed, 92 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 8c5de7b0e7b5..c4fd21cac3a7 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -36,9 +36,99 @@ static void xdrv_remove_internal(struct xdrv_info *drv_info)
 {
 }
 
+static int xdrv_be_on_initwait(struct xdrv_info *drv_info)
+{
+   return 0;
+}
+
+static inline int xdrv_be_on_connected(struct xdrv_info *drv_info)
+{
+   return 0;
+}
+
+static inline void xdrv_be_on_disconnected(struct xdrv_info *drv_info)
+{
+   xdrv_remove_internal(drv_info);
+}
+
 static void xdrv_be_on_changed(struct xenbus_device *xb_dev,
enum xenbus_state backend_state)
 {
+   struct xdrv_info *drv_info = dev_get_drvdata(&xb_dev->dev);
+   int ret;
+
+   switch (backend_state) {
+   case XenbusStateReconfiguring:
+   /* fall through */
+   case XenbusStateReconfigured:
+   /* fall through */
+   case XenbusStateInitialised:
+   /* fall through */
+   break;
+
+   case XenbusStateInitialising:
+   if (xb_dev->state == XenbusStateInitialising)
+   break;
+
+   /* recovering after backend unexpected closure */
+   mutex_lock(&drv_info->mutex);
+   xdrv_be_on_disconnected(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   xenbus_switch_state(xb_dev, XenbusStateInitialising);
+   break;
+
+   case XenbusStateInitWait:
+   if (xb_dev->state != XenbusStateInitialising)
+   break;
+
+   mutex_lock(&drv_info->mutex);
+   ret = xdrv_be_on_initwait(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   if (ret < 0) {
+   xenbus_dev_fatal(xb_dev, ret,
+   "initializing " XENSND_DRIVER_NAME);
+   break;
+   }
+
+   xenbus_switch_state(xb_dev, XenbusStateInitialised);
+   break;
+
+   case XenbusStateConnected:
+   if (xb_dev->state != XenbusStateInitialised)
+   break;
+
+   mutex_lock(&drv_info->mutex);
+   ret = xdrv_be_on_connected(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   if (ret < 0) {
+   xenbus_dev_fatal(xb_dev, ret,
+   "connecting " XENSND_DRIVER_NAME);
+   break;
+   }
+
+   xenbus_switch_state(xb_dev, XenbusStateConnected);
+   break;
+
+   case XenbusStateClosing:
+   /*
+* in this state backend starts freeing resources,
+* so let it go into closed state first, so we can also
+* remove ours
+*/
+   break;
+
+   case XenbusStateUnknown:
+   /* fall through */
+   case XenbusStateClosed:
+   if (xb_dev->state == XenbusStateClosed)
+   break;
+
+   mutex_lock(&drv_info->mutex);
+   xdrv_be_on_disconnected(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   xenbus_switch_state(xb_dev, XenbusStateInitialising);
+   break;
+   }
 }
 
 static int xdrv_probe(struct xenbus_device *xb_dev,
@@ -56,6 +146,7 @@ static int xdrv_probe(struct xenbus_device *xb_dev,
spin_lock_init(&drv_info->io_lock);
mutex_init(&drv_info->mutex);
dev_set_drvdata(&xb_dev->dev, drv_info);
+   xenbus_switch_state(xb_dev, XenbusStateInitialising);
return 0;
 }
 
@@ -63,6 +154,7 @@ static int xdrv_remove(struct xenbus_device *dev)
 {
struct xdrv_info *drv_info = dev_get_drvdata(&dev->dev);
 
+   xenbus_switch_state(dev, XenbusStateClosed);
mutex_lock(&drv_info->mutex);
xdrv_remove_internal(drv_info);
mutex_unlock(&drv_info->mutex);
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RESEND1 05/12] ALSA: vsnd: Implement Xen event channel handling

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

1. Create event channels for all configured streams and publish
corresponding ring references and event channels in Xen store,
so backend can connect.
2. Implement event channel interrupt handler.
3. Create and destroy event channels with respect to Xen bus state.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 269 +-
 1 file changed, 268 insertions(+), 1 deletion(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index ef48cbf44cf2..a92459b2737e 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -24,14 +24,40 @@
 #include 
 
 #include 
+#include 
+#include 
 #include 
 #include 
 
 #include 
 
+/*
+ * FIXME: usage of grant reference 0 as invalid grant reference:
+ * grant reference 0 is valid, but never exposed to a PV driver,
+ * because of the fact it is already in use/reserved by the PV console.
+ */
+#define GRANT_INVALID_REF  0
 /* maximum number of supported streams */
 #define VSND_MAX_STREAM8
 
+enum xdrv_evtchnl_state {
+   EVTCHNL_STATE_DISCONNECTED,
+   EVTCHNL_STATE_CONNECTED,
+};
+
+struct xdrv_evtchnl_info {
+   struct xdrv_info *drv_info;
+   struct xen_sndif_front_ring ring;
+   int ring_ref;
+   int port;
+   int irq;
+   struct completion completion;
+   enum xdrv_evtchnl_state state;
+   /* latest response status and its corresponding id */
+   int resp_status;
+   uint16_t resp_id;
+};
+
 struct cfg_stream {
int unique_id;
char *xenstore_path;
@@ -65,6 +91,8 @@ struct xdrv_info {
struct xenbus_device *xb_dev;
spinlock_t io_lock;
struct mutex mutex;
+   int num_evt_channels;
+   struct xdrv_evtchnl_info *evt_chnls;
struct sdev_card_plat_data cfg_plat_data;
 };
 
@@ -102,6 +130,244 @@ static struct snd_pcm_hardware sdrv_pcm_hw_default = {
.fifo_size = 0,
 };
 
+static irqreturn_t xdrv_evtchnl_interrupt(int irq, void *dev_id)
+{
+   struct xdrv_evtchnl_info *channel = dev_id;
+   struct xdrv_info *drv_info = channel->drv_info;
+   struct xensnd_resp *resp;
+   RING_IDX i, rp;
+   unsigned long flags;
+
+   spin_lock_irqsave(&drv_info->io_lock, flags);
+   if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
+   goto out;
+
+again:
+   rp = channel->ring.sring->rsp_prod;
+   /* ensure we see queued responses up to rp */
+   rmb();
+
+   for (i = channel->ring.rsp_cons; i != rp; i++) {
+   resp = RING_GET_RESPONSE(&channel->ring, i);
+   if (resp->id != channel->resp_id)
+   continue;
+   switch (resp->operation) {
+   case XENSND_OP_OPEN:
+   /* fall through */
+   case XENSND_OP_CLOSE:
+   /* fall through */
+   case XENSND_OP_READ:
+   /* fall through */
+   case XENSND_OP_WRITE:
+   channel->resp_status = resp->status;
+   complete(&channel->completion);
+   break;
+
+   default:
+   dev_err(&drv_info->xb_dev->dev,
+   "Operation %d is not supported\n",
+   resp->operation);
+   break;
+   }
+   }
+
+   channel->ring.rsp_cons = i;
+   if (i != channel->ring.req_prod_pvt) {
+   int more_to_do;
+
+   RING_FINAL_CHECK_FOR_RESPONSES(&channel->ring, more_to_do);
+   if (more_to_do)
+   goto again;
+   } else
+   channel->ring.sring->rsp_event = i + 1;
+
+out:
+   spin_unlock_irqrestore(&drv_info->io_lock, flags);
+   return IRQ_HANDLED;
+}
+
+static inline void xdrv_evtchnl_flush(
+   struct xdrv_evtchnl_info *channel)
+{
+   int notify;
+
+   channel->ring.req_prod_pvt++;
+   RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&channel->ring, notify);
+   if (notify)
+   notify_remote_via_irq(channel->irq);
+}
+
+static void xdrv_evtchnl_free(struct xdrv_info *drv_info,
+   struct xdrv_evtchnl_info *channel)
+{
+   if (!channel->ring.sring)
+   return;
+
+   channel->state = EVTCHNL_STATE_DISCONNECTED;
+   channel->resp_status = -EIO;
+   complete_all(&channel->completion);
+
+   if (channel->irq)
+   unbind_from_irqhandler(channel->irq, channel);
+   channel->irq = 0;
+
+   if (channel->port)
+   xenbus_free_evtchn(drv_info->xb_dev, channel->port);
+   channel->port = 0;
+
+   if (channel->ring_ref != GRANT_INVALID_REF)
+   gnttab_end_foreign_access(channel->

[Xen-devel] [PATCH RESEND1 02/12] ALSA: vsnd: Implement driver's probe/remove

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Add essential driver private info structure, initialize
locks and implement probe/remove of the Xen frontend
driver.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 61779c36cae3..8c5de7b0e7b5 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -26,6 +26,16 @@
 
 #include 
 
+struct xdrv_info {
+   struct xenbus_device *xb_dev;
+   spinlock_t io_lock;
+   struct mutex mutex;
+};
+
+static void xdrv_remove_internal(struct xdrv_info *drv_info)
+{
+}
+
 static void xdrv_be_on_changed(struct xenbus_device *xb_dev,
enum xenbus_state backend_state)
 {
@@ -34,11 +44,28 @@ static void xdrv_be_on_changed(struct xenbus_device *xb_dev,
 static int xdrv_probe(struct xenbus_device *xb_dev,
const struct xenbus_device_id *id)
 {
+   struct xdrv_info *drv_info;
+
+   drv_info = devm_kzalloc(&xb_dev->dev, sizeof(*drv_info), GFP_KERNEL);
+   if (!drv_info) {
+   xenbus_dev_fatal(xb_dev, -ENOMEM, "allocating device memory");
+   return -ENOMEM;
+   }
+
+   drv_info->xb_dev = xb_dev;
+   spin_lock_init(&drv_info->io_lock);
+   mutex_init(&drv_info->mutex);
+   dev_set_drvdata(&xb_dev->dev, drv_info);
return 0;
 }
 
 static int xdrv_remove(struct xenbus_device *dev)
 {
+   struct xdrv_info *drv_info = dev_get_drvdata(&dev->dev);
+
+   mutex_lock(&drv_info->mutex);
+   xdrv_remove_internal(drv_info);
+   mutex_unlock(&drv_info->mutex);
return 0;
 }
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RESEND1 04/12] ALSA: vsnd: Read sound driver configuration from Xen store

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Read configuration values from Xen store according
to xen/interface/io/sndif.h protocol:
- introduce configuration structures for different
  components, e.g. sound card, device, stream
- read PCM HW parameters, e.g rate, format etc.
- detect stream type (capture/playback)
- read device and card parameters

Fill in platform data with the configuration read, so
it can be passed to sound driver later.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 530 ++
 1 file changed, 530 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index c4fd21cac3a7..ef48cbf44cf2 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -20,24 +20,554 @@
 
 #include 
 
+#include 
+#include 
+
 #include 
 #include 
 #include 
 
 #include 
 
+/* maximum number of supported streams */
+#define VSND_MAX_STREAM8
+
+struct cfg_stream {
+   int unique_id;
+   char *xenstore_path;
+   struct snd_pcm_hardware pcm_hw;
+};
+
+struct cfg_pcm_instance {
+   char name[80];
+   int device_id;
+   struct snd_pcm_hardware pcm_hw;
+   int  num_streams_pb;
+   struct cfg_stream *streams_pb;
+   int  num_streams_cap;
+   struct cfg_stream *streams_cap;
+};
+
+struct cfg_card {
+   char name_short[32];
+   char name_long[80];
+   struct snd_pcm_hardware pcm_hw;
+   int num_pcm_instances;
+   struct cfg_pcm_instance *pcm_instances;
+};
+
+struct sdev_card_plat_data {
+   struct xdrv_info *xdrv_info;
+   struct cfg_card cfg_card;
+};
+
 struct xdrv_info {
struct xenbus_device *xb_dev;
spinlock_t io_lock;
struct mutex mutex;
+   struct sdev_card_plat_data cfg_plat_data;
 };
 
+#define MAX_XEN_BUFFER_SIZE(64 * 1024)
+#define MAX_BUFFER_SIZEMAX_XEN_BUFFER_SIZE
+#define MIN_PERIOD_SIZE64
+#define MAX_PERIOD_SIZE(MAX_BUFFER_SIZE / 8)
+#define USE_FORMATS(SNDRV_PCM_FMTBIT_U8 | \
+SNDRV_PCM_FMTBIT_S16_LE)
+#define USE_RATE   (SNDRV_PCM_RATE_CONTINUOUS | \
+SNDRV_PCM_RATE_8000_48000)
+#define USE_RATE_MIN   5512
+#define USE_RATE_MAX   48000
+#define USE_CHANNELS_MIN   1
+#define USE_CHANNELS_MAX   2
+#define USE_PERIODS_MIN2
+#define USE_PERIODS_MAX8
+
+static struct snd_pcm_hardware sdrv_pcm_hw_default = {
+   .info = (SNDRV_PCM_INFO_MMAP |
+SNDRV_PCM_INFO_INTERLEAVED |
+SNDRV_PCM_INFO_RESUME |
+SNDRV_PCM_INFO_MMAP_VALID),
+   .formats = USE_FORMATS,
+   .rates = USE_RATE,
+   .rate_min = USE_RATE_MIN,
+   .rate_max = USE_RATE_MAX,
+   .channels_min = USE_CHANNELS_MIN,
+   .channels_max = USE_CHANNELS_MAX,
+   .buffer_bytes_max = MAX_BUFFER_SIZE,
+   .period_bytes_min = MIN_PERIOD_SIZE,
+   .period_bytes_max = MAX_PERIOD_SIZE,
+   .periods_min = USE_PERIODS_MIN,
+   .periods_max = USE_PERIODS_MAX,
+   .fifo_size = 0,
+};
+
+struct CFG_HW_SAMPLE_RATE {
+   const char *name;
+   unsigned int mask;
+   unsigned int value;
+};
+
+static struct CFG_HW_SAMPLE_RATE cfg_hw_supported_rates[] = {
+   { .name = "5512",   .mask = SNDRV_PCM_RATE_5512,   .value = 5512 },
+   { .name = "8000",   .mask = SNDRV_PCM_RATE_8000,   .value = 8000 },
+   { .name = "11025",  .mask = SNDRV_PCM_RATE_11025,  .value = 11025 },
+   { .name = "16000",  .mask = SNDRV_PCM_RATE_16000,  .value = 16000 },
+   { .name = "22050",  .mask = SNDRV_PCM_RATE_22050,  .value = 22050 },
+   { .name = "32000",  .mask = SNDRV_PCM_RATE_32000,  .value = 32000 },
+   { .name = "44100",  .mask = SNDRV_PCM_RATE_44100,  .value = 44100 },
+   { .name = "48000",  .mask = SNDRV_PCM_RATE_48000,  .value = 48000 },
+   { .name = "64000",  .mask = SNDRV_PCM_RATE_64000,  .value = 64000 },
+   { .name = "96000",  .mask = SNDRV_PCM_RATE_96000,  .value = 96000 },
+   { .name = "176400", .mask = SNDRV_PCM_RATE_176400, .value = 176400 },
+   { .name = "192000", .mask = SNDRV_PCM_RATE_192000, .value = 192000 },
+};
+
+struct CFG_HW_SAMPLE_FORMAT {
+   const char *name;
+   u64 mask;
+};
+
+static struct CFG_HW_SAMPLE_FORMAT cfg_hw_supported_formats[] = {
+   {
+   .name = XENSND_PCM_FORMAT_U8_STR,
+   .mask = SNDRV_PCM_FMTBIT_U8
+   },
+   {
+   .name = XENSND_PCM_FORMAT_S8_STR,
+   .mask = SNDRV_PCM_FMTBIT_S8
+   },
+   {
+   .name = XENSND_PCM_FORMAT_U16_LE_STR,
+   .mask = SNDRV_PCM_FMTBIT_U16_LE
+   },
+   {
+   .name = XENSND_PCM_FORMAT_U16_BE_STR,
+   .mask = 

[Xen-devel] [PATCH RESEND1 01/12] ALSA: vsnd: Introduce Xen para-virtualized sound frontend driver

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Introduce skeleton of the para-virtualized Xen sound
frontend driver. This patch only adds required
essential stubs.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 78 +++
 1 file changed, 78 insertions(+)
 create mode 100644 sound/drivers/xen-front.c

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
new file mode 100644
index ..61779c36cae3
--- /dev/null
+++ b/sound/drivers/xen-front.c
@@ -0,0 +1,78 @@
+/*
+ * Xen para-virtual sound device
+ *
+ *   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.
+ *
+ * Based on: sound/drivers/dummy.c
+ *
+ * Copyright (C) 2016-2017 EPAM Systems Inc.
+ *
+ * Author: Oleksandr Andrushchenko 
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+static void xdrv_be_on_changed(struct xenbus_device *xb_dev,
+   enum xenbus_state backend_state)
+{
+}
+
+static int xdrv_probe(struct xenbus_device *xb_dev,
+   const struct xenbus_device_id *id)
+{
+   return 0;
+}
+
+static int xdrv_remove(struct xenbus_device *dev)
+{
+   return 0;
+}
+
+static const struct xenbus_device_id xdrv_ids[] = {
+   { XENSND_DRIVER_NAME },
+   { "" }
+};
+
+static struct xenbus_driver xen_driver = {
+   .ids = xdrv_ids,
+   .probe = xdrv_probe,
+   .remove = xdrv_remove,
+   .otherend_changed = xdrv_be_on_changed,
+};
+
+static int __init xdrv_init(void)
+{
+   if (!xen_domain())
+   return -ENODEV;
+
+   pr_info("Initialising Xen " XENSND_DRIVER_NAME " frontend driver\n");
+   return xenbus_register_frontend(&xen_driver);
+}
+
+static void __exit xdrv_cleanup(void)
+{
+   pr_info("Unregistering Xen " XENSND_DRIVER_NAME " frontend driver\n");
+   xenbus_unregister_driver(&xen_driver);
+}
+
+module_init(xdrv_init);
+module_exit(xdrv_cleanup);
+
+MODULE_DESCRIPTION("Xen virtual sound device frontend");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("xen:"XENSND_DRIVER_NAME);
+MODULE_SUPPORTED_DEVICE("{{ALSA,Virtual soundcard}}");
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RESEND1 00/12] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

This patch series adds support for Xen [1] para-virtualized
sound frontend driver. It implements the protocol from
include/xen/interface/io/sndif.h with the following limitations:
- mute/unmute is not supported
- get/set volume is not supported
Volume control is not supported for the reason that most of the
use-cases (at the moment) are based on scenarious where
unprivileged OS (e.g. Android, AGL etc) use software mixers.

Both capture and playback are supported.

Thank you,
Oleksandr

Resending because of rebase onto [2] + added missing patch

[1] https://xenproject.org/
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/log/?h=for-next

Oleksandr Andrushchenko (12):
  ALSA: vsnd: Introduce Xen para-virtualized sound frontend driver
  ALSA: vsnd: Implement driver's probe/remove
  ALSA: vsnd: Implement Xen bus state handling
  ALSA: vsnd: Read sound driver configuration from Xen store
  ALSA: vsnd: Implement Xen event channel handling
  ALSA: vsnd: Implement handling of shared buffers
  ALSA: vsnd: Introduce ALSA virtual sound driver
  ALSA: vsnd: Initialize virtul sound card
  ALSA: vsnd: Add timer for period interrupt emulation
  ALSA: vsnd: Implement ALSA PCM operations
  ALSA: vsnd: Implement communication with backend
  ALSA: vsnd: Introduce Kconfig option to enable Xen PV sound

 sound/drivers/Kconfig |   12 +
 sound/drivers/Makefile|2 +
 sound/drivers/xen-front.c | 2107 +
 3 files changed, 2121 insertions(+)
 create mode 100644 sound/drivers/xen-front.c

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH RESEND 00/11] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-08-07 Thread Oleksandr Andrushchenko

On 08/07/2017 03:09 PM, Takashi Sakamoto wrote:

Hi,

On Aug 7 2017 20:50, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

This patch series adds support for Xen [1] para-virtualized
sound frontend driver. It implements the protocol from
include/xen/interface/io/sndif.h with the following limitations:
- mute/unmute is not supported
- get/set volume is not supported
Volume control is not supported for the reason that most of the
use-cases (at the moment) are based on scenarious where
unprivileged OS (e.g. Android, AGL etc) use software mixers.

Both capture and playback are supported.

Thank you,
Oleksandr

Resending because of rebase onto [2]

[1] https://xenproject.org/
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/log/?h=for-next


Oleksandr Andrushchenko (11):
   ALSA: vsnd: Implement driver's probe/remove
   ALSA: vsnd: Implement Xen bus state handling
   ALSA: vsnd: Read sound driver configuration from Xen store
   ALSA: vsnd: Implement Xen event channel handling
   ALSA: vsnd: Implement handling of shared buffers
   ALSA: vsnd: Introduce ALSA virtual sound driver
   ALSA: vsnd: Initialize virtul sound card
   ALSA: vsnd: Add timer for period interrupt emulation
   ALSA: vsnd: Implement ALSA PCM operations
   ALSA: vsnd: Implement communication with backend
   ALSA: vsnd: Introduce Kconfig option to enable Xen PV sound

  sound/drivers/Kconfig |   12 +
  sound/drivers/Makefile|2 +
  sound/drivers/xen-front.c | 2029 
+

  3 files changed, 2043 insertions(+)


This patchset is not proper yet.


really sorry for the mess :(
Your first patch includes code difference under line 26, thus it 
expects existence of a file 'sound/drivers/xen-front.c' in tree. 
However, the file is not introduced in any upstream yet; at least, 
Linus's tree and Iwai-san's tree.

I missed the very first patch in the series, this is why, my bad


You still work on your local branch, not for us.


sorry


Regards

Takashi Sakamoto



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RESEND 10/11] ALSA: vsnd: Implement communication with backend

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement frontend to backend communication according to
the para-virtualized sound protocol: xen/interface/io/sndif.h.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 302 +++---
 1 file changed, 288 insertions(+), 14 deletions(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 7275e9cb38c0..8bfec43ef03a 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -38,6 +38,8 @@
  * because of the fact it is already in use/reserved by the PV console.
  */
 #define GRANT_INVALID_REF  0
+/* timeout in ms to wait for backend to respond */
+#define VSND_WAIT_BACK_MS  3000
 /* maximum number of supported streams */
 #define VSND_MAX_STREAM8
 
@@ -151,10 +153,12 @@ struct xdrv_info {
struct sdev_card_plat_data cfg_plat_data;
 };
 
+static inline void xdrv_evtchnl_flush(struct xdrv_evtchnl_info *channel);
 static inline void sh_buf_clear(struct sh_buf_info *buf);
 static void sh_buf_free(struct sh_buf_info *buf);
 static int sh_buf_alloc(struct xenbus_device *xb_dev, struct sh_buf_info *buf,
unsigned int buffer_size);
+static grant_ref_t sh_buf_get_dir_start(struct sh_buf_info *buf);
 
 static struct sdev_pcm_stream_info *sdrv_stream_get(
struct snd_pcm_substream *substream)
@@ -314,6 +318,234 @@ static void sdrv_copy_pcm_hw(struct snd_pcm_hardware *dst,
}
 }
 
+struct ALSA_SNDIF_SAMPLE_FORMAT {
+   uint8_t sndif;
+   snd_pcm_format_t alsa;
+};
+
+static struct ALSA_SNDIF_SAMPLE_FORMAT alsa_sndif_formats[] = {
+   {
+   .sndif = XENSND_PCM_FORMAT_U8,
+   .alsa = SNDRV_PCM_FORMAT_U8
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S8,
+   .alsa = SNDRV_PCM_FORMAT_S8
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U16_LE,
+   .alsa = SNDRV_PCM_FORMAT_U16_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U16_BE,
+   .alsa = SNDRV_PCM_FORMAT_U16_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S16_LE,
+   .alsa = SNDRV_PCM_FORMAT_S16_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S16_BE,
+   .alsa = SNDRV_PCM_FORMAT_S16_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U24_LE,
+   .alsa = SNDRV_PCM_FORMAT_U24_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U24_BE,
+   .alsa = SNDRV_PCM_FORMAT_U24_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S24_LE,
+   .alsa = SNDRV_PCM_FORMAT_S24_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S24_BE,
+   .alsa = SNDRV_PCM_FORMAT_S24_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U32_LE,
+   .alsa = SNDRV_PCM_FORMAT_U32_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U32_BE,
+   .alsa = SNDRV_PCM_FORMAT_U32_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S32_LE,
+   .alsa = SNDRV_PCM_FORMAT_S32_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S32_BE,
+   .alsa = SNDRV_PCM_FORMAT_S32_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_A_LAW,
+   .alsa = SNDRV_PCM_FORMAT_A_LAW
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_MU_LAW,
+   .alsa = SNDRV_PCM_FORMAT_MU_LAW
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F32_LE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F32_BE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F64_LE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT64_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F64_BE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT64_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE,
+   .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE,
+   .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IMA_ADPCM,
+   .alsa = SNDRV_PCM_FORMAT_IMA_ADPCM
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_MPEG,
+   .alsa = SNDRV_PCM_FORMAT_MPEG
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_GSM,
+   .alsa = SNDRV_PCM_FORMAT_GSM
+   },
+};
+
+static int alsa_to_sndif_format(snd_pcm_format_t format)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(alsa_sndif_formats); i++)
+   if (alsa_sndif_formats[i].alsa == format)
+   return alsa_sndif_formats[i].sndif;
+   return -EINVAL;
+}
+
+static void sdrv_stream_clear(str

[Xen-devel] [PATCH RESEND 04/11] ALSA: vsnd: Implement Xen event channel handling

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

1. Create event channels for all configured streams and publish
corresponding ring references and event channels in Xen store,
so backend can connect.
2. Implement event channel interrupt handler.
3. Create and destroy event channels with respect to Xen bus state.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 269 +-
 1 file changed, 268 insertions(+), 1 deletion(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index ef48cbf44cf2..a92459b2737e 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -24,14 +24,40 @@
 #include 
 
 #include 
+#include 
+#include 
 #include 
 #include 
 
 #include 
 
+/*
+ * FIXME: usage of grant reference 0 as invalid grant reference:
+ * grant reference 0 is valid, but never exposed to a PV driver,
+ * because of the fact it is already in use/reserved by the PV console.
+ */
+#define GRANT_INVALID_REF  0
 /* maximum number of supported streams */
 #define VSND_MAX_STREAM8
 
+enum xdrv_evtchnl_state {
+   EVTCHNL_STATE_DISCONNECTED,
+   EVTCHNL_STATE_CONNECTED,
+};
+
+struct xdrv_evtchnl_info {
+   struct xdrv_info *drv_info;
+   struct xen_sndif_front_ring ring;
+   int ring_ref;
+   int port;
+   int irq;
+   struct completion completion;
+   enum xdrv_evtchnl_state state;
+   /* latest response status and its corresponding id */
+   int resp_status;
+   uint16_t resp_id;
+};
+
 struct cfg_stream {
int unique_id;
char *xenstore_path;
@@ -65,6 +91,8 @@ struct xdrv_info {
struct xenbus_device *xb_dev;
spinlock_t io_lock;
struct mutex mutex;
+   int num_evt_channels;
+   struct xdrv_evtchnl_info *evt_chnls;
struct sdev_card_plat_data cfg_plat_data;
 };
 
@@ -102,6 +130,244 @@ static struct snd_pcm_hardware sdrv_pcm_hw_default = {
.fifo_size = 0,
 };
 
+static irqreturn_t xdrv_evtchnl_interrupt(int irq, void *dev_id)
+{
+   struct xdrv_evtchnl_info *channel = dev_id;
+   struct xdrv_info *drv_info = channel->drv_info;
+   struct xensnd_resp *resp;
+   RING_IDX i, rp;
+   unsigned long flags;
+
+   spin_lock_irqsave(&drv_info->io_lock, flags);
+   if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
+   goto out;
+
+again:
+   rp = channel->ring.sring->rsp_prod;
+   /* ensure we see queued responses up to rp */
+   rmb();
+
+   for (i = channel->ring.rsp_cons; i != rp; i++) {
+   resp = RING_GET_RESPONSE(&channel->ring, i);
+   if (resp->id != channel->resp_id)
+   continue;
+   switch (resp->operation) {
+   case XENSND_OP_OPEN:
+   /* fall through */
+   case XENSND_OP_CLOSE:
+   /* fall through */
+   case XENSND_OP_READ:
+   /* fall through */
+   case XENSND_OP_WRITE:
+   channel->resp_status = resp->status;
+   complete(&channel->completion);
+   break;
+
+   default:
+   dev_err(&drv_info->xb_dev->dev,
+   "Operation %d is not supported\n",
+   resp->operation);
+   break;
+   }
+   }
+
+   channel->ring.rsp_cons = i;
+   if (i != channel->ring.req_prod_pvt) {
+   int more_to_do;
+
+   RING_FINAL_CHECK_FOR_RESPONSES(&channel->ring, more_to_do);
+   if (more_to_do)
+   goto again;
+   } else
+   channel->ring.sring->rsp_event = i + 1;
+
+out:
+   spin_unlock_irqrestore(&drv_info->io_lock, flags);
+   return IRQ_HANDLED;
+}
+
+static inline void xdrv_evtchnl_flush(
+   struct xdrv_evtchnl_info *channel)
+{
+   int notify;
+
+   channel->ring.req_prod_pvt++;
+   RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&channel->ring, notify);
+   if (notify)
+   notify_remote_via_irq(channel->irq);
+}
+
+static void xdrv_evtchnl_free(struct xdrv_info *drv_info,
+   struct xdrv_evtchnl_info *channel)
+{
+   if (!channel->ring.sring)
+   return;
+
+   channel->state = EVTCHNL_STATE_DISCONNECTED;
+   channel->resp_status = -EIO;
+   complete_all(&channel->completion);
+
+   if (channel->irq)
+   unbind_from_irqhandler(channel->irq, channel);
+   channel->irq = 0;
+
+   if (channel->port)
+   xenbus_free_evtchn(drv_info->xb_dev, channel->port);
+   channel->port = 0;
+
+   if (channel->ring_ref != GRANT_INVALID_REF)
+   gnttab_end_foreign_access(channel->

[Xen-devel] [PATCH RESEND 06/11] ALSA: vsnd: Introduce ALSA virtual sound driver

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement essential initialization of the sound driver:
- introduce required data structures
- handle driver registration
- handle sound card registration
- register sound driver on backend connection
- remove sound driver on backend disconnect

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 161 +-
 1 file changed, 159 insertions(+), 2 deletions(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 04ebc15757f4..f3e3f64f0aa6 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -19,13 +19,14 @@
  */
 
 #include 
+#include 
 
 #include 
 #include 
 
-#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -66,6 +67,33 @@ struct sh_buf_info {
size_t vbuffer_sz;
 };
 
+struct sdev_pcm_stream_info {
+   int unique_id;
+   struct snd_pcm_hardware pcm_hw;
+   struct xdrv_evtchnl_info *evt_chnl;
+   bool is_open;
+   uint8_t req_next_id;
+   struct sh_buf_info sh_buf;
+};
+
+struct sdev_pcm_instance_info {
+   struct sdev_card_info *card_info;
+   struct snd_pcm *pcm;
+   struct snd_pcm_hardware pcm_hw;
+   int num_pcm_streams_pb;
+   struct sdev_pcm_stream_info *streams_pb;
+   int num_pcm_streams_cap;
+   struct sdev_pcm_stream_info *streams_cap;
+};
+
+struct sdev_card_info {
+   struct xdrv_info *xdrv_info;
+   struct snd_card *card;
+   struct snd_pcm_hardware pcm_hw;
+   int num_pcm_instances;
+   struct sdev_pcm_instance_info *pcm_instances;
+};
+
 struct cfg_stream {
int unique_id;
char *xenstore_path;
@@ -99,6 +127,8 @@ struct xdrv_info {
struct xenbus_device *xb_dev;
spinlock_t io_lock;
struct mutex mutex;
+   bool sdrv_registered;
+   struct platform_device *sdrv_pdev;
int num_evt_channels;
struct xdrv_evtchnl_info *evt_chnls;
struct sdev_card_plat_data cfg_plat_data;
@@ -138,6 +168,132 @@ static struct snd_pcm_hardware sdrv_pcm_hw_default = {
.fifo_size = 0,
 };
 
+static int sdrv_new_pcm(struct sdev_card_info *card_info,
+   struct cfg_pcm_instance *instance_config,
+   struct sdev_pcm_instance_info *pcm_instance_info)
+{
+   return 0;
+}
+
+static int sdrv_probe(struct platform_device *pdev)
+{
+   struct sdev_card_info *card_info;
+   struct sdev_card_plat_data *platdata;
+   struct snd_card *card;
+   int ret, i;
+
+   platdata = dev_get_platdata(&pdev->dev);
+
+   dev_dbg(&pdev->dev, "Creating virtual sound card\n");
+
+   ret = snd_card_new(&pdev->dev, 0, XENSND_DRIVER_NAME, THIS_MODULE,
+   sizeof(struct sdev_card_info), &card);
+   if (ret < 0)
+   return ret;
+
+   card_info = card->private_data;
+   card_info->xdrv_info = platdata->xdrv_info;
+   card_info->card = card;
+   card_info->pcm_instances = devm_kcalloc(&pdev->dev,
+   platdata->cfg_card.num_pcm_instances,
+   sizeof(struct sdev_pcm_instance_info), GFP_KERNEL);
+   if (!card_info->pcm_instances) {
+   ret = -ENOMEM;
+   goto fail;
+   }
+
+   card_info->num_pcm_instances = platdata->cfg_card.num_pcm_instances;
+   card_info->pcm_hw = platdata->cfg_card.pcm_hw;
+
+   for (i = 0; i < platdata->cfg_card.num_pcm_instances; i++) {
+   ret = sdrv_new_pcm(card_info,
+   &platdata->cfg_card.pcm_instances[i],
+   &card_info->pcm_instances[i]);
+   if (ret < 0)
+   goto fail;
+   }
+
+   strncpy(card->driver, XENSND_DRIVER_NAME, sizeof(card->driver));
+   strncpy(card->shortname, platdata->cfg_card.name_short,
+   sizeof(card->shortname));
+   strncpy(card->longname, platdata->cfg_card.name_long,
+   sizeof(card->longname));
+
+   ret = snd_card_register(card);
+   if (ret < 0)
+   goto fail;
+
+   platform_set_drvdata(pdev, card);
+   return 0;
+
+fail:
+   snd_card_free(card);
+   return ret;
+}
+
+static int sdrv_remove(struct platform_device *pdev)
+{
+   struct sdev_card_info *info;
+   struct snd_card *card = platform_get_drvdata(pdev);
+
+   info = card->private_data;
+   dev_dbg(&pdev->dev, "Removing virtual sound card %d\n",
+   info->card->number);
+   snd_card_free(card);
+   return 0;
+}
+
+static struct platform_driver sdrv_info = {
+   .probe  = sdrv_probe,
+   .remove = sdrv_remove,
+   .driver = {
+   .name   = XENSND_DRIVER_NAME,
+   },
+};
+
+static void sdrv_cleanup(struct xdrv_info *drv_info)
+{
+   if (!drv_info->sdrv_registered)
+   return;
+
+   i

[Xen-devel] [PATCH RESEND 02/11] ALSA: vsnd: Implement Xen bus state handling

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Initial handling for Xen bus states: implement
Xen bus state machine for the front driver according to
the state diagram and recovery flow from sound para-virtualized
protocol: xen/interface/io/sndif.h.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 92 +++
 1 file changed, 92 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 8c5de7b0e7b5..c4fd21cac3a7 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -36,9 +36,99 @@ static void xdrv_remove_internal(struct xdrv_info *drv_info)
 {
 }
 
+static int xdrv_be_on_initwait(struct xdrv_info *drv_info)
+{
+   return 0;
+}
+
+static inline int xdrv_be_on_connected(struct xdrv_info *drv_info)
+{
+   return 0;
+}
+
+static inline void xdrv_be_on_disconnected(struct xdrv_info *drv_info)
+{
+   xdrv_remove_internal(drv_info);
+}
+
 static void xdrv_be_on_changed(struct xenbus_device *xb_dev,
enum xenbus_state backend_state)
 {
+   struct xdrv_info *drv_info = dev_get_drvdata(&xb_dev->dev);
+   int ret;
+
+   switch (backend_state) {
+   case XenbusStateReconfiguring:
+   /* fall through */
+   case XenbusStateReconfigured:
+   /* fall through */
+   case XenbusStateInitialised:
+   /* fall through */
+   break;
+
+   case XenbusStateInitialising:
+   if (xb_dev->state == XenbusStateInitialising)
+   break;
+
+   /* recovering after backend unexpected closure */
+   mutex_lock(&drv_info->mutex);
+   xdrv_be_on_disconnected(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   xenbus_switch_state(xb_dev, XenbusStateInitialising);
+   break;
+
+   case XenbusStateInitWait:
+   if (xb_dev->state != XenbusStateInitialising)
+   break;
+
+   mutex_lock(&drv_info->mutex);
+   ret = xdrv_be_on_initwait(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   if (ret < 0) {
+   xenbus_dev_fatal(xb_dev, ret,
+   "initializing " XENSND_DRIVER_NAME);
+   break;
+   }
+
+   xenbus_switch_state(xb_dev, XenbusStateInitialised);
+   break;
+
+   case XenbusStateConnected:
+   if (xb_dev->state != XenbusStateInitialised)
+   break;
+
+   mutex_lock(&drv_info->mutex);
+   ret = xdrv_be_on_connected(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   if (ret < 0) {
+   xenbus_dev_fatal(xb_dev, ret,
+   "connecting " XENSND_DRIVER_NAME);
+   break;
+   }
+
+   xenbus_switch_state(xb_dev, XenbusStateConnected);
+   break;
+
+   case XenbusStateClosing:
+   /*
+* in this state backend starts freeing resources,
+* so let it go into closed state first, so we can also
+* remove ours
+*/
+   break;
+
+   case XenbusStateUnknown:
+   /* fall through */
+   case XenbusStateClosed:
+   if (xb_dev->state == XenbusStateClosed)
+   break;
+
+   mutex_lock(&drv_info->mutex);
+   xdrv_be_on_disconnected(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   xenbus_switch_state(xb_dev, XenbusStateInitialising);
+   break;
+   }
 }
 
 static int xdrv_probe(struct xenbus_device *xb_dev,
@@ -56,6 +146,7 @@ static int xdrv_probe(struct xenbus_device *xb_dev,
spin_lock_init(&drv_info->io_lock);
mutex_init(&drv_info->mutex);
dev_set_drvdata(&xb_dev->dev, drv_info);
+   xenbus_switch_state(xb_dev, XenbusStateInitialising);
return 0;
 }
 
@@ -63,6 +154,7 @@ static int xdrv_remove(struct xenbus_device *dev)
 {
struct xdrv_info *drv_info = dev_get_drvdata(&dev->dev);
 
+   xenbus_switch_state(dev, XenbusStateClosed);
mutex_lock(&drv_info->mutex);
xdrv_remove_internal(drv_info);
mutex_unlock(&drv_info->mutex);
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RESEND 05/11] ALSA: vsnd: Implement handling of shared buffers

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement shared buffer handling according to the
para-virtualized sound device protocol at xen/interface/io/sndif.h:
- manage buffer memory
- handle granted references
- handle page directories

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 178 ++
 1 file changed, 178 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index a92459b2737e..04ebc15757f4 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -58,6 +58,14 @@ struct xdrv_evtchnl_info {
uint16_t resp_id;
 };
 
+struct sh_buf_info {
+   int num_grefs;
+   grant_ref_t *grefs;
+   uint8_t *vdirectory;
+   uint8_t *vbuffer;
+   size_t vbuffer_sz;
+};
+
 struct cfg_stream {
int unique_id;
char *xenstore_path;
@@ -825,6 +833,176 @@ static void xdrv_remove_internal(struct xdrv_info 
*drv_info)
xdrv_evtchnl_free_all(drv_info);
 }
 
+static inline grant_ref_t sh_buf_get_dir_start(struct sh_buf_info *buf)
+{
+   if (!buf->grefs)
+   return GRANT_INVALID_REF;
+   return buf->grefs[0];
+}
+
+static inline void sh_buf_clear(struct sh_buf_info *buf)
+{
+   memset(buf, 0, sizeof(*buf));
+}
+
+static void sh_buf_free(struct sh_buf_info *buf)
+{
+   int i;
+
+   if (buf->grefs) {
+   for (i = 0; i < buf->num_grefs; i++)
+   if (buf->grefs[i] != GRANT_INVALID_REF)
+   gnttab_end_foreign_access(buf->grefs[i],
+   0, 0UL);
+   kfree(buf->grefs);
+   }
+   kfree(buf->vdirectory);
+   free_pages_exact(buf->vbuffer, buf->vbuffer_sz);
+   sh_buf_clear(buf);
+}
+
+/*
+ * number of grant references a page can hold with respect to the
+ * xendispl_page_directory header
+ */
+#define XENSND_NUM_GREFS_PER_PAGE ((XEN_PAGE_SIZE - \
+   offsetof(struct xensnd_page_directory, gref)) / \
+   sizeof(grant_ref_t))
+
+static void sh_buf_fill_page_dir(struct sh_buf_info *buf, int num_pages_dir)
+{
+   struct xensnd_page_directory *page_dir;
+   unsigned char *ptr;
+   int i, cur_gref, grefs_left, to_copy;
+
+   ptr = buf->vdirectory;
+   grefs_left = buf->num_grefs - num_pages_dir;
+   /*
+* skip grant references at the beginning, they are for pages granted
+* for the page directory itself
+*/
+   cur_gref = num_pages_dir;
+   for (i = 0; i < num_pages_dir; i++) {
+   page_dir = (struct xensnd_page_directory *)ptr;
+   if (grefs_left <= XENSND_NUM_GREFS_PER_PAGE) {
+   to_copy = grefs_left;
+   page_dir->gref_dir_next_page = GRANT_INVALID_REF;
+   } else {
+   to_copy = XENSND_NUM_GREFS_PER_PAGE;
+   page_dir->gref_dir_next_page = buf->grefs[i + 1];
+   }
+   memcpy(&page_dir->gref, &buf->grefs[cur_gref],
+   to_copy * sizeof(grant_ref_t));
+   ptr += XEN_PAGE_SIZE;
+   grefs_left -= to_copy;
+   cur_gref += to_copy;
+   }
+}
+
+static int sh_buf_grant_refs(struct xenbus_device *xb_dev,
+   struct sh_buf_info *buf,
+   int num_pages_dir, int num_pages_vbuffer, int num_grefs)
+{
+   grant_ref_t priv_gref_head;
+   int ret, i, j, cur_ref;
+   int otherend_id;
+
+   ret = gnttab_alloc_grant_references(num_grefs, &priv_gref_head);
+   if (ret)
+   return ret;
+
+   buf->num_grefs = num_grefs;
+   otherend_id = xb_dev->otherend_id;
+   j = 0;
+
+   for (i = 0; i < num_pages_dir; i++) {
+   cur_ref = gnttab_claim_grant_reference(&priv_gref_head);
+   if (cur_ref < 0) {
+   ret = cur_ref;
+   goto fail;
+   }
+
+   gnttab_grant_foreign_access_ref(cur_ref, otherend_id,
+   xen_page_to_gfn(virt_to_page(buf->vdirectory +
+   XEN_PAGE_SIZE * i)), 0);
+   buf->grefs[j++] = cur_ref;
+   }
+
+   for (i = 0; i < num_pages_vbuffer; i++) {
+   cur_ref = gnttab_claim_grant_reference(&priv_gref_head);
+   if (cur_ref < 0) {
+   ret = cur_ref;
+   goto fail;
+   }
+
+   gnttab_grant_foreign_access_ref(cur_ref, otherend_id,
+   xen_page_to_gfn(virt_to_page(buf->vbuffer +
+   XEN_PAGE_SIZE * i)), 0);
+   buf->grefs[j++] = cur_ref;
+   }
+
+   gnttab_free_grant_references(priv_gref_head);
+   sh_buf_fill_page_dir(buf, num_pages_dir);
+   return 0;
+
+fail:
+   gnttab_free_grant_references(priv_gref_hea

[Xen-devel] [PATCH RESEND 01/11] ALSA: vsnd: Implement driver's probe/remove

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Add essential driver private info structure, initialize
locks and implement probe/remove of the Xen frontend
driver.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 61779c36cae3..8c5de7b0e7b5 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -26,6 +26,16 @@
 
 #include 
 
+struct xdrv_info {
+   struct xenbus_device *xb_dev;
+   spinlock_t io_lock;
+   struct mutex mutex;
+};
+
+static void xdrv_remove_internal(struct xdrv_info *drv_info)
+{
+}
+
 static void xdrv_be_on_changed(struct xenbus_device *xb_dev,
enum xenbus_state backend_state)
 {
@@ -34,11 +44,28 @@ static void xdrv_be_on_changed(struct xenbus_device *xb_dev,
 static int xdrv_probe(struct xenbus_device *xb_dev,
const struct xenbus_device_id *id)
 {
+   struct xdrv_info *drv_info;
+
+   drv_info = devm_kzalloc(&xb_dev->dev, sizeof(*drv_info), GFP_KERNEL);
+   if (!drv_info) {
+   xenbus_dev_fatal(xb_dev, -ENOMEM, "allocating device memory");
+   return -ENOMEM;
+   }
+
+   drv_info->xb_dev = xb_dev;
+   spin_lock_init(&drv_info->io_lock);
+   mutex_init(&drv_info->mutex);
+   dev_set_drvdata(&xb_dev->dev, drv_info);
return 0;
 }
 
 static int xdrv_remove(struct xenbus_device *dev)
 {
+   struct xdrv_info *drv_info = dev_get_drvdata(&dev->dev);
+
+   mutex_lock(&drv_info->mutex);
+   xdrv_remove_internal(drv_info);
+   mutex_unlock(&drv_info->mutex);
return 0;
 }
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RESEND 07/11] ALSA: vsnd: Initialize virtul sound card

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Initialize virtual sound card with streams according to the
Xen store configuration.
Add stubs for stream PCM operations.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 232 ++
 1 file changed, 232 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index f3e3f64f0aa6..9f31e6832086 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -134,6 +134,129 @@ struct xdrv_info {
struct sdev_card_plat_data cfg_plat_data;
 };
 
+static struct sdev_pcm_stream_info *sdrv_stream_get(
+   struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream;
+
+   if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+   stream = &pcm_instance->streams_pb[substream->number];
+   else
+   stream = &pcm_instance->streams_cap[substream->number];
+   return stream;
+}
+
+static void sdrv_copy_pcm_hw(struct snd_pcm_hardware *dst,
+   struct snd_pcm_hardware *src,
+   struct snd_pcm_hardware *ref_pcm_hw)
+{
+   *dst = *ref_pcm_hw;
+
+   if (src->formats)
+   dst->formats = src->formats;
+   if (src->buffer_bytes_max)
+   dst->buffer_bytes_max =
+   src->buffer_bytes_max;
+   if (src->period_bytes_min)
+   dst->period_bytes_min =
+   src->period_bytes_min;
+   if (src->period_bytes_max)
+   dst->period_bytes_max =
+   src->period_bytes_max;
+   if (src->periods_min)
+   dst->periods_min = src->periods_min;
+   if (src->periods_max)
+   dst->periods_max = src->periods_max;
+   if (src->rates)
+   dst->rates = src->rates;
+   if (src->rate_min)
+   dst->rate_min = src->rate_min;
+   if (src->rate_max)
+   dst->rate_max = src->rate_max;
+   if (src->channels_min)
+   dst->channels_min = src->channels_min;
+   if (src->channels_max)
+   dst->channels_max = src->channels_max;
+   if (src->buffer_bytes_max) {
+   dst->buffer_bytes_max = src->buffer_bytes_max;
+   dst->period_bytes_max = src->buffer_bytes_max /
+   src->periods_max;
+   dst->periods_max = dst->buffer_bytes_max /
+   dst->period_bytes_max;
+   }
+}
+
+static int sdrv_alsa_open(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_close(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_hw_params(struct snd_pcm_substream *substream,
+   struct snd_pcm_hw_params *params)
+{
+   return 0;
+}
+
+static int sdrv_alsa_hw_free(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_prepare(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+   return 0;
+}
+
+static inline snd_pcm_uframes_t sdrv_alsa_pointer(
+   struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_playback_copy_user(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void __user *buf,
+   unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_playback_copy_kernel(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void *buf, unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_capture_copy_user(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void __user *buf,
+   unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_capture_copy_kernel(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void *buf, unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_playback_fill_silence(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, unsigned long bytes)
+{
+   return 0;
+}
+
 #define MAX_XEN_BUFFER_SIZE(64 * 1024)
 #define MAX_BUFFER_SIZEMAX_XEN_BUFFER_SIZE
 #define MIN_PERIOD_SIZE64
@@ -168,10 +291,119 @@ static struct snd_pcm_hardware sdrv_pcm_hw_default = {
.fifo_size = 0,
 };
 
+/*
+ * FIXME: The mmaped data transfer is asynchronous and there is no
+ * ack signal from user-space when it is done. This is the
+ * reason it is not implemented in the PV driver as we do need
+ * to know when the buffer can be transferred to the backend.
+ */
+
+static struct snd_pcm_ops sdrv_alsa_playback_ops = {
+   .op

[Xen-devel] [PATCH RESEND 00/11] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

This patch series adds support for Xen [1] para-virtualized
sound frontend driver. It implements the protocol from
include/xen/interface/io/sndif.h with the following limitations:
- mute/unmute is not supported
- get/set volume is not supported
Volume control is not supported for the reason that most of the
use-cases (at the moment) are based on scenarious where
unprivileged OS (e.g. Android, AGL etc) use software mixers.

Both capture and playback are supported.

Thank you,
Oleksandr

Resending because of rebase onto [2]

[1] https://xenproject.org/
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/log/?h=for-next

Oleksandr Andrushchenko (11):
  ALSA: vsnd: Implement driver's probe/remove
  ALSA: vsnd: Implement Xen bus state handling
  ALSA: vsnd: Read sound driver configuration from Xen store
  ALSA: vsnd: Implement Xen event channel handling
  ALSA: vsnd: Implement handling of shared buffers
  ALSA: vsnd: Introduce ALSA virtual sound driver
  ALSA: vsnd: Initialize virtul sound card
  ALSA: vsnd: Add timer for period interrupt emulation
  ALSA: vsnd: Implement ALSA PCM operations
  ALSA: vsnd: Implement communication with backend
  ALSA: vsnd: Introduce Kconfig option to enable Xen PV sound

 sound/drivers/Kconfig |   12 +
 sound/drivers/Makefile|2 +
 sound/drivers/xen-front.c | 2029 +
 3 files changed, 2043 insertions(+)

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH RESEND 08/11] ALSA: vsnd: Add timer for period interrupt emulation

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Front sound driver has no real interrupts, so
playback/capture period passed interrupt needs to be emulated:
this is done via timer. Add required timer operations,
this is based on sound/drivers/dummy.c.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 121 ++
 1 file changed, 121 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 9f31e6832086..507c5eb343c8 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -67,12 +67,29 @@ struct sh_buf_info {
size_t vbuffer_sz;
 };
 
+struct sdev_alsa_timer_info {
+   spinlock_t lock;
+   struct timer_list timer;
+   unsigned long base_time;
+   /* fractional sample position (based HZ) */
+   unsigned int frac_pos;
+   unsigned int frac_period_rest;
+   /* buffer_size * HZ */
+   unsigned int frac_buffer_size;
+   /* period_size * HZ */
+   unsigned int frac_period_size;
+   unsigned int rate;
+   int elapsed;
+   struct snd_pcm_substream *substream;
+};
+
 struct sdev_pcm_stream_info {
int unique_id;
struct snd_pcm_hardware pcm_hw;
struct xdrv_evtchnl_info *evt_chnl;
bool is_open;
uint8_t req_next_id;
+   struct sdev_alsa_timer_info timer;
struct sh_buf_info sh_buf;
 };
 
@@ -148,6 +165,110 @@ static struct sdev_pcm_stream_info *sdrv_stream_get(
return stream;
 }
 
+static inline void sdrv_alsa_timer_rearm(struct sdev_alsa_timer_info *dpcm)
+{
+   mod_timer(&dpcm->timer, jiffies +
+   (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate);
+}
+
+static void sdrv_alsa_timer_update(struct sdev_alsa_timer_info *dpcm)
+{
+   unsigned long delta;
+
+   delta = jiffies - dpcm->base_time;
+   if (!delta)
+   return;
+   dpcm->base_time += delta;
+   delta *= dpcm->rate;
+   dpcm->frac_pos += delta;
+   while (dpcm->frac_pos >= dpcm->frac_buffer_size)
+   dpcm->frac_pos -= dpcm->frac_buffer_size;
+   while (dpcm->frac_period_rest <= delta) {
+   dpcm->elapsed++;
+   dpcm->frac_period_rest += dpcm->frac_period_size;
+   }
+   dpcm->frac_period_rest -= delta;
+}
+
+static int sdrv_alsa_timer_start(struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   spin_lock(&dpcm->lock);
+   dpcm->base_time = jiffies;
+   sdrv_alsa_timer_rearm(dpcm);
+   spin_unlock(&dpcm->lock);
+   return 0;
+}
+
+static int sdrv_alsa_timer_stop(struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   spin_lock(&dpcm->lock);
+   del_timer(&dpcm->timer);
+   spin_unlock(&dpcm->lock);
+   return 0;
+}
+
+static int sdrv_alsa_timer_prepare(struct snd_pcm_substream *substream)
+{
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   dpcm->frac_pos = 0;
+   dpcm->rate = runtime->rate;
+   dpcm->frac_buffer_size = runtime->buffer_size * HZ;
+   dpcm->frac_period_size = runtime->period_size * HZ;
+   dpcm->frac_period_rest = dpcm->frac_period_size;
+   dpcm->elapsed = 0;
+   return 0;
+}
+
+static void sdrv_alsa_timer_callback(unsigned long data)
+{
+   struct sdev_alsa_timer_info *dpcm = (struct sdev_alsa_timer_info *)data;
+   int elapsed;
+
+   spin_lock(&dpcm->lock);
+   sdrv_alsa_timer_update(dpcm);
+   sdrv_alsa_timer_rearm(dpcm);
+   elapsed = dpcm->elapsed;
+   dpcm->elapsed = 0;
+   spin_unlock(&dpcm->lock);
+   if (elapsed)
+   snd_pcm_period_elapsed(dpcm->substream);
+}
+
+static snd_pcm_uframes_t sdrv_alsa_timer_pointer(
+   struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+   snd_pcm_uframes_t pos;
+
+   spin_lock(&dpcm->lock);
+   sdrv_alsa_timer_update(dpcm);
+   pos = dpcm->frac_pos / HZ;
+   spin_unlock(&dpcm->lock);
+   return pos;
+}
+
+static int sdrv_alsa_timer_create(struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   spin_lock_init(&dpcm->lock);
+   dpcm->substream = substream;
+   setup_timer(&dpcm->

[Xen-devel] [PATCH RESEND 03/11] ALSA: vsnd: Read sound driver configuration from Xen store

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Read configuration values from Xen store according
to xen/interface/io/sndif.h protocol:
- introduce configuration structures for different
  components, e.g. sound card, device, stream
- read PCM HW parameters, e.g rate, format etc.
- detect stream type (capture/playback)
- read device and card parameters

Fill in platform data with the configuration read, so
it can be passed to sound driver later.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 530 ++
 1 file changed, 530 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index c4fd21cac3a7..ef48cbf44cf2 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -20,24 +20,554 @@
 
 #include 
 
+#include 
+#include 
+
 #include 
 #include 
 #include 
 
 #include 
 
+/* maximum number of supported streams */
+#define VSND_MAX_STREAM8
+
+struct cfg_stream {
+   int unique_id;
+   char *xenstore_path;
+   struct snd_pcm_hardware pcm_hw;
+};
+
+struct cfg_pcm_instance {
+   char name[80];
+   int device_id;
+   struct snd_pcm_hardware pcm_hw;
+   int  num_streams_pb;
+   struct cfg_stream *streams_pb;
+   int  num_streams_cap;
+   struct cfg_stream *streams_cap;
+};
+
+struct cfg_card {
+   char name_short[32];
+   char name_long[80];
+   struct snd_pcm_hardware pcm_hw;
+   int num_pcm_instances;
+   struct cfg_pcm_instance *pcm_instances;
+};
+
+struct sdev_card_plat_data {
+   struct xdrv_info *xdrv_info;
+   struct cfg_card cfg_card;
+};
+
 struct xdrv_info {
struct xenbus_device *xb_dev;
spinlock_t io_lock;
struct mutex mutex;
+   struct sdev_card_plat_data cfg_plat_data;
 };
 
+#define MAX_XEN_BUFFER_SIZE(64 * 1024)
+#define MAX_BUFFER_SIZEMAX_XEN_BUFFER_SIZE
+#define MIN_PERIOD_SIZE64
+#define MAX_PERIOD_SIZE(MAX_BUFFER_SIZE / 8)
+#define USE_FORMATS(SNDRV_PCM_FMTBIT_U8 | \
+SNDRV_PCM_FMTBIT_S16_LE)
+#define USE_RATE   (SNDRV_PCM_RATE_CONTINUOUS | \
+SNDRV_PCM_RATE_8000_48000)
+#define USE_RATE_MIN   5512
+#define USE_RATE_MAX   48000
+#define USE_CHANNELS_MIN   1
+#define USE_CHANNELS_MAX   2
+#define USE_PERIODS_MIN2
+#define USE_PERIODS_MAX8
+
+static struct snd_pcm_hardware sdrv_pcm_hw_default = {
+   .info = (SNDRV_PCM_INFO_MMAP |
+SNDRV_PCM_INFO_INTERLEAVED |
+SNDRV_PCM_INFO_RESUME |
+SNDRV_PCM_INFO_MMAP_VALID),
+   .formats = USE_FORMATS,
+   .rates = USE_RATE,
+   .rate_min = USE_RATE_MIN,
+   .rate_max = USE_RATE_MAX,
+   .channels_min = USE_CHANNELS_MIN,
+   .channels_max = USE_CHANNELS_MAX,
+   .buffer_bytes_max = MAX_BUFFER_SIZE,
+   .period_bytes_min = MIN_PERIOD_SIZE,
+   .period_bytes_max = MAX_PERIOD_SIZE,
+   .periods_min = USE_PERIODS_MIN,
+   .periods_max = USE_PERIODS_MAX,
+   .fifo_size = 0,
+};
+
+struct CFG_HW_SAMPLE_RATE {
+   const char *name;
+   unsigned int mask;
+   unsigned int value;
+};
+
+static struct CFG_HW_SAMPLE_RATE cfg_hw_supported_rates[] = {
+   { .name = "5512",   .mask = SNDRV_PCM_RATE_5512,   .value = 5512 },
+   { .name = "8000",   .mask = SNDRV_PCM_RATE_8000,   .value = 8000 },
+   { .name = "11025",  .mask = SNDRV_PCM_RATE_11025,  .value = 11025 },
+   { .name = "16000",  .mask = SNDRV_PCM_RATE_16000,  .value = 16000 },
+   { .name = "22050",  .mask = SNDRV_PCM_RATE_22050,  .value = 22050 },
+   { .name = "32000",  .mask = SNDRV_PCM_RATE_32000,  .value = 32000 },
+   { .name = "44100",  .mask = SNDRV_PCM_RATE_44100,  .value = 44100 },
+   { .name = "48000",  .mask = SNDRV_PCM_RATE_48000,  .value = 48000 },
+   { .name = "64000",  .mask = SNDRV_PCM_RATE_64000,  .value = 64000 },
+   { .name = "96000",  .mask = SNDRV_PCM_RATE_96000,  .value = 96000 },
+   { .name = "176400", .mask = SNDRV_PCM_RATE_176400, .value = 176400 },
+   { .name = "192000", .mask = SNDRV_PCM_RATE_192000, .value = 192000 },
+};
+
+struct CFG_HW_SAMPLE_FORMAT {
+   const char *name;
+   u64 mask;
+};
+
+static struct CFG_HW_SAMPLE_FORMAT cfg_hw_supported_formats[] = {
+   {
+   .name = XENSND_PCM_FORMAT_U8_STR,
+   .mask = SNDRV_PCM_FMTBIT_U8
+   },
+   {
+   .name = XENSND_PCM_FORMAT_S8_STR,
+   .mask = SNDRV_PCM_FMTBIT_S8
+   },
+   {
+   .name = XENSND_PCM_FORMAT_U16_LE_STR,
+   .mask = SNDRV_PCM_FMTBIT_U16_LE
+   },
+   {
+   .name = XENSND_PCM_FORMAT_U16_BE_STR,
+   .mask = 

[Xen-devel] [PATCH RESEND 09/11] ALSA: vsnd: Implement ALSA PCM operations

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement ALSA driver operations including:
- start/stop period interrupt emulation
- manage frontend/backend shraed buffers
- manage Xen bus event channel state

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 175 ++
 1 file changed, 163 insertions(+), 12 deletions(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 507c5eb343c8..7275e9cb38c0 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -151,6 +151,11 @@ struct xdrv_info {
struct sdev_card_plat_data cfg_plat_data;
 };
 
+static inline void sh_buf_clear(struct sh_buf_info *buf);
+static void sh_buf_free(struct sh_buf_info *buf);
+static int sh_buf_alloc(struct xenbus_device *xb_dev, struct sh_buf_info *buf,
+   unsigned int buffer_size);
+
 static struct sdev_pcm_stream_info *sdrv_stream_get(
struct snd_pcm_substream *substream)
 {
@@ -311,71 +316,217 @@ static void sdrv_copy_pcm_hw(struct snd_pcm_hardware 
*dst,
 
 static int sdrv_alsa_open(struct snd_pcm_substream *substream)
 {
-   return 0;
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct xdrv_info *xdrv_info;
+   unsigned long flags;
+   int ret;
+
+   sdrv_copy_pcm_hw(&runtime->hw, &stream->pcm_hw, &pcm_instance->pcm_hw);
+   runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
+   SNDRV_PCM_INFO_MMAP_VALID |
+   SNDRV_PCM_INFO_DOUBLE |
+   SNDRV_PCM_INFO_BATCH |
+   SNDRV_PCM_INFO_NONINTERLEAVED |
+   SNDRV_PCM_INFO_RESUME |
+   SNDRV_PCM_INFO_PAUSE);
+   runtime->hw.info |= SNDRV_PCM_INFO_INTERLEAVED;
+
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+
+   ret = sdrv_alsa_timer_create(substream);
+
+   spin_lock_irqsave(&xdrv_info->io_lock, flags);
+   sh_buf_clear(&stream->sh_buf);
+   stream->evt_chnl = &xdrv_info->evt_chnls[stream->unique_id];
+   if (ret < 0)
+   stream->evt_chnl->state = EVTCHNL_STATE_DISCONNECTED;
+   else
+   stream->evt_chnl->state = EVTCHNL_STATE_CONNECTED;
+   spin_unlock_irqrestore(&xdrv_info->io_lock, flags);
+   return ret;
 }
 
 static int sdrv_alsa_close(struct snd_pcm_substream *substream)
 {
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct xdrv_info *xdrv_info;
+   unsigned long flags;
+
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+
+   sdrv_alsa_timer_stop(substream);
+
+   spin_lock_irqsave(&xdrv_info->io_lock, flags);
+   stream->evt_chnl->state = EVTCHNL_STATE_DISCONNECTED;
+   spin_unlock_irqrestore(&xdrv_info->io_lock, flags);
return 0;
 }
 
 static int sdrv_alsa_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
 {
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct xdrv_info *xdrv_info;
+   unsigned int buffer_size;
+   int ret;
+
+   buffer_size = params_buffer_bytes(params);
+   sh_buf_clear(&stream->sh_buf);
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+   ret = sh_buf_alloc(xdrv_info->xb_dev,
+   &stream->sh_buf, buffer_size);
+   if (ret < 0)
+   goto fail;
return 0;
+
+fail:
+   dev_err(&xdrv_info->xb_dev->dev,
+   "Failed to allocate buffers for stream idx %d\n",
+   stream->unique_id);
+   return ret;
 }
 
 static int sdrv_alsa_hw_free(struct snd_pcm_substream *substream)
 {
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct xdrv_info *xdrv_info;
+   unsigned long flags;
+
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+   spin_lock_irqsave(&xdrv_info->io_lock, flags);
+   sh_buf_free(&stream->sh_buf);
+   spin_unlock_irqrestore(&xdrv_info->io_lock, flags);
return 0;
 }
 
 static int sdrv_alsa_prepare(struct snd_pcm_substream *substream)
 {
-   return 0;
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   int ret = 0;
+
+   if (!stream->is_open)
+   ret = sdrv_alsa_timer_prepare(substream);
+   return ret;
 }
 
 static int sdrv_alsa_trigger(struct snd_p

[Xen-devel] [PATCH RESEND 11/11] ALSA: vsnd: Introduce Kconfig option to enable Xen PV sound

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Introduce Kconfig option to enable Xen para-virtualized sound
frontend driver. Also add sound frontend to the Makefile.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/Kconfig  | 12 
 sound/drivers/Makefile |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 7144cc36e8ae..6b8fa6110ca3 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -235,4 +235,16 @@ config SND_AC97_POWER_SAVE_DEFAULT
 
  See SND_AC97_POWER_SAVE for more details.
 
+config SND_XEN_FRONTEND
+   tristate "Xen virtual sound front-end driver"
+   depends on SND_PCM && XEN
+   select XEN_XENBUS_FRONTEND
+   default n
+   help
+ This driver implements a front-end for the Xen
+ para-virtualized sound.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-xen-front.
+
 endif  # SND_DRIVERS
diff --git a/sound/drivers/Makefile b/sound/drivers/Makefile
index 1a8440c8b138..70ed920a030f 100644
--- a/sound/drivers/Makefile
+++ b/sound/drivers/Makefile
@@ -11,6 +11,7 @@ snd-portman2x4-objs := portman2x4.o
 snd-serial-u16550-objs := serial-u16550.o
 snd-virmidi-objs := virmidi.o
 snd-ml403-ac97cr-objs := ml403-ac97cr.o pcm-indirect2.o
+snd-xen-front-objs := xen-front.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_DUMMY) += snd-dummy.o
@@ -21,5 +22,6 @@ obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o
 obj-$(CONFIG_SND_MTS64) += snd-mts64.o
 obj-$(CONFIG_SND_PORTMAN2X4) += snd-portman2x4.o
 obj-$(CONFIG_SND_ML403_AC97CR) += snd-ml403-ac97cr.o
+obj-$(CONFIG_SND_XEN_FRONTEND) += snd-xen-front.o
 
 obj-$(CONFIG_SND) += opl3/ opl4/ mpu401/ vx/ pcsp/
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 00/11] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-08-07 Thread Oleksandr Andrushchenko

Hi,

On 08/07/2017 02:28 PM, Takashi Sakamoto wrote:

Hi,

On Aug 7 2017 16:43, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

This patch series adds support for Xen [1] para-virtualized
sound frontend driver. It implements the protocol from
include/xen/interface/io/sndif.h with the following limitations:
- mute/unmute is not supported
- get/set volume is not supported
Volume control is not supported for the reason that most of the
use-cases (at the moment) are based on scenarious where
unprivileged OS (e.g. Android, AGL etc) use software mixers.

Both capture and playback are supported.

Thank you,
Oleksandr

[1] https://xenproject.org/

Oleksandr Andrushchenko (11):
   ALSA: vsnd: Implement driver's probe/remove
   ALSA: vsnd: Implement Xen bus state handling
   ALSA: vsnd: Read sound driver configuration from Xen store
   ALSA: vsnd: Implement Xen event channel handling
   ALSA: vsnd: Implement handling of shared buffers
   ALSA: vsnd: Introduce ALSA virtual sound driver
   ALSA: vsnd: Initialize virtul sound card
   ALSA: vsnd: Add timer for period interrupt emulation
   ALSA: vsnd: Implement ALSA PCM operations
   ALSA: vsnd: Implement communication with backend
   ALSA: vsnd: Introduce Kconfig option to enable Xen PV sound

  sound/drivers/Kconfig |   12 +
  sound/drivers/Makefile|2 +
  sound/drivers/xen-front.c | 2029 
+

  3 files changed, 2043 insertions(+)


As a quick glance of your first patch, it's apparently based on your 
local working branch. 

sorry about that, I based the changes on v4.13-rc3 kernel sources
I'd like you to post patchset again, which were rebased on current 
upstream[1], so that code reviewers can do their work.

sure, will do that now


[1] 'for-next' branch in Iwai-san's tree
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/log/?h=for-next 




Regards

Takashi Sakamoto



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [alsa-devel] [PATCH 08/11] ALSA: vsnd: Add timer for period interrupt emulation

2017-08-07 Thread Oleksandr Andrushchenko

Hi, Clemens!

On 08/07/2017 01:27 PM, Clemens Ladisch wrote:

Oleksandr Andrushchenko wrote:

Front sound driver has no real interrupts, so
playback/capture period passed interrupt needs to be emulated:
this is done via timer. Add required timer operations,
this is based on sound/drivers/dummy.c.

A 'real' sound card use the interrupt to synchronize the stream position
between the hardware and the driver.  The hardware triggers an interrupt
immediately after a period has been completely read (for playback) from
the ring buffer by the DMA unit; this tells the driver that it is now
again allowed to write to that part of the buffer.

Yes, I know that, thank you

The dummy driver has no hardware that accesses the buffer, so the period
interrupts are not synchronized to anything.

Exactly

   This is not a suitable
implementation when the samples are actually used.



If you issue interrupts based on the system timer, the position reported
by the .pointer callback and the position where the hardware (backend)
actually accesses the buffer will diverge, which will eventually corrupt
data.

Makes sense, but in my case the buffer from the frontend
is copied into backend's memory, so they don't share the
same buffer as real HW does. But it is still possible that
the new portion of data may arrive and backend will overwrite
the memory which hasn't been played yet because pointers are not
synchronized

You have to implement period interrupts (and the .pointer callback)
based on when the samples are actually moved from/to the backend.

Do you think I can implement this in a slightly different way,
without a timer at all, by updating
substream->runtime->hw_ptr_base explicitly in the frontend driver?
Like it was implemented [1], see virtualcard_pcm_pointer
(unfortunately, that driver didn't make it to the kernel).
So, that way, whenever I get an ack/response from the backend that it has
successfully played the buffer I can update hw_ptr_base at the frontend
and thus be always in sync to the backend.

Regards,
Clemens

Thank you,
Oleksandr

[1] http://marc.info/?l=xen-devel&m=142185395013970&w=4

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH 08/11] ALSA: vsnd: Add timer for period interrupt emulation

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Front sound driver has no real interrupts, so
playback/capture period passed interrupt needs to be emulated:
this is done via timer. Add required timer operations,
this is based on sound/drivers/dummy.c.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 121 ++
 1 file changed, 121 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 9f31e6832086..507c5eb343c8 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -67,12 +67,29 @@ struct sh_buf_info {
size_t vbuffer_sz;
 };
 
+struct sdev_alsa_timer_info {
+   spinlock_t lock;
+   struct timer_list timer;
+   unsigned long base_time;
+   /* fractional sample position (based HZ) */
+   unsigned int frac_pos;
+   unsigned int frac_period_rest;
+   /* buffer_size * HZ */
+   unsigned int frac_buffer_size;
+   /* period_size * HZ */
+   unsigned int frac_period_size;
+   unsigned int rate;
+   int elapsed;
+   struct snd_pcm_substream *substream;
+};
+
 struct sdev_pcm_stream_info {
int unique_id;
struct snd_pcm_hardware pcm_hw;
struct xdrv_evtchnl_info *evt_chnl;
bool is_open;
uint8_t req_next_id;
+   struct sdev_alsa_timer_info timer;
struct sh_buf_info sh_buf;
 };
 
@@ -148,6 +165,110 @@ static struct sdev_pcm_stream_info *sdrv_stream_get(
return stream;
 }
 
+static inline void sdrv_alsa_timer_rearm(struct sdev_alsa_timer_info *dpcm)
+{
+   mod_timer(&dpcm->timer, jiffies +
+   (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate);
+}
+
+static void sdrv_alsa_timer_update(struct sdev_alsa_timer_info *dpcm)
+{
+   unsigned long delta;
+
+   delta = jiffies - dpcm->base_time;
+   if (!delta)
+   return;
+   dpcm->base_time += delta;
+   delta *= dpcm->rate;
+   dpcm->frac_pos += delta;
+   while (dpcm->frac_pos >= dpcm->frac_buffer_size)
+   dpcm->frac_pos -= dpcm->frac_buffer_size;
+   while (dpcm->frac_period_rest <= delta) {
+   dpcm->elapsed++;
+   dpcm->frac_period_rest += dpcm->frac_period_size;
+   }
+   dpcm->frac_period_rest -= delta;
+}
+
+static int sdrv_alsa_timer_start(struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   spin_lock(&dpcm->lock);
+   dpcm->base_time = jiffies;
+   sdrv_alsa_timer_rearm(dpcm);
+   spin_unlock(&dpcm->lock);
+   return 0;
+}
+
+static int sdrv_alsa_timer_stop(struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   spin_lock(&dpcm->lock);
+   del_timer(&dpcm->timer);
+   spin_unlock(&dpcm->lock);
+   return 0;
+}
+
+static int sdrv_alsa_timer_prepare(struct snd_pcm_substream *substream)
+{
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   dpcm->frac_pos = 0;
+   dpcm->rate = runtime->rate;
+   dpcm->frac_buffer_size = runtime->buffer_size * HZ;
+   dpcm->frac_period_size = runtime->period_size * HZ;
+   dpcm->frac_period_rest = dpcm->frac_period_size;
+   dpcm->elapsed = 0;
+   return 0;
+}
+
+static void sdrv_alsa_timer_callback(unsigned long data)
+{
+   struct sdev_alsa_timer_info *dpcm = (struct sdev_alsa_timer_info *)data;
+   int elapsed;
+
+   spin_lock(&dpcm->lock);
+   sdrv_alsa_timer_update(dpcm);
+   sdrv_alsa_timer_rearm(dpcm);
+   elapsed = dpcm->elapsed;
+   dpcm->elapsed = 0;
+   spin_unlock(&dpcm->lock);
+   if (elapsed)
+   snd_pcm_period_elapsed(dpcm->substream);
+}
+
+static snd_pcm_uframes_t sdrv_alsa_timer_pointer(
+   struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+   snd_pcm_uframes_t pos;
+
+   spin_lock(&dpcm->lock);
+   sdrv_alsa_timer_update(dpcm);
+   pos = dpcm->frac_pos / HZ;
+   spin_unlock(&dpcm->lock);
+   return pos;
+}
+
+static int sdrv_alsa_timer_create(struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct sdev_alsa_timer_info *dpcm = &stream->timer;
+
+   spin_lock_init(&dpcm->lock);
+   dpcm->substream = substream;
+   setup_timer(&dpcm->

[Xen-devel] [PATCH 00/11] ALSA: vsnd: Add Xen para-virtualized frontend driver

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

This patch series adds support for Xen [1] para-virtualized
sound frontend driver. It implements the protocol from
include/xen/interface/io/sndif.h with the following limitations:
- mute/unmute is not supported
- get/set volume is not supported
Volume control is not supported for the reason that most of the
use-cases (at the moment) are based on scenarious where
unprivileged OS (e.g. Android, AGL etc) use software mixers.

Both capture and playback are supported.

Thank you,
Oleksandr

[1] https://xenproject.org/

Oleksandr Andrushchenko (11):
  ALSA: vsnd: Implement driver's probe/remove
  ALSA: vsnd: Implement Xen bus state handling
  ALSA: vsnd: Read sound driver configuration from Xen store
  ALSA: vsnd: Implement Xen event channel handling
  ALSA: vsnd: Implement handling of shared buffers
  ALSA: vsnd: Introduce ALSA virtual sound driver
  ALSA: vsnd: Initialize virtul sound card
  ALSA: vsnd: Add timer for period interrupt emulation
  ALSA: vsnd: Implement ALSA PCM operations
  ALSA: vsnd: Implement communication with backend
  ALSA: vsnd: Introduce Kconfig option to enable Xen PV sound

 sound/drivers/Kconfig |   12 +
 sound/drivers/Makefile|2 +
 sound/drivers/xen-front.c | 2029 +
 3 files changed, 2043 insertions(+)

-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH 07/11] ALSA: vsnd: Initialize virtul sound card

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Initialize virtual sound card with streams according to the
Xen store configuration.
Add stubs for stream PCM operations.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 232 ++
 1 file changed, 232 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index f3e3f64f0aa6..9f31e6832086 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -134,6 +134,129 @@ struct xdrv_info {
struct sdev_card_plat_data cfg_plat_data;
 };
 
+static struct sdev_pcm_stream_info *sdrv_stream_get(
+   struct snd_pcm_substream *substream)
+{
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream;
+
+   if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+   stream = &pcm_instance->streams_pb[substream->number];
+   else
+   stream = &pcm_instance->streams_cap[substream->number];
+   return stream;
+}
+
+static void sdrv_copy_pcm_hw(struct snd_pcm_hardware *dst,
+   struct snd_pcm_hardware *src,
+   struct snd_pcm_hardware *ref_pcm_hw)
+{
+   *dst = *ref_pcm_hw;
+
+   if (src->formats)
+   dst->formats = src->formats;
+   if (src->buffer_bytes_max)
+   dst->buffer_bytes_max =
+   src->buffer_bytes_max;
+   if (src->period_bytes_min)
+   dst->period_bytes_min =
+   src->period_bytes_min;
+   if (src->period_bytes_max)
+   dst->period_bytes_max =
+   src->period_bytes_max;
+   if (src->periods_min)
+   dst->periods_min = src->periods_min;
+   if (src->periods_max)
+   dst->periods_max = src->periods_max;
+   if (src->rates)
+   dst->rates = src->rates;
+   if (src->rate_min)
+   dst->rate_min = src->rate_min;
+   if (src->rate_max)
+   dst->rate_max = src->rate_max;
+   if (src->channels_min)
+   dst->channels_min = src->channels_min;
+   if (src->channels_max)
+   dst->channels_max = src->channels_max;
+   if (src->buffer_bytes_max) {
+   dst->buffer_bytes_max = src->buffer_bytes_max;
+   dst->period_bytes_max = src->buffer_bytes_max /
+   src->periods_max;
+   dst->periods_max = dst->buffer_bytes_max /
+   dst->period_bytes_max;
+   }
+}
+
+static int sdrv_alsa_open(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_close(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_hw_params(struct snd_pcm_substream *substream,
+   struct snd_pcm_hw_params *params)
+{
+   return 0;
+}
+
+static int sdrv_alsa_hw_free(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_prepare(struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+   return 0;
+}
+
+static inline snd_pcm_uframes_t sdrv_alsa_pointer(
+   struct snd_pcm_substream *substream)
+{
+   return 0;
+}
+
+static int sdrv_alsa_playback_copy_user(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void __user *buf,
+   unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_playback_copy_kernel(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void *buf, unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_capture_copy_user(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void __user *buf,
+   unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_capture_copy_kernel(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, void *buf, unsigned long bytes)
+{
+   return 0;
+}
+
+static int sdrv_alsa_playback_fill_silence(struct snd_pcm_substream *substream,
+   int channel, unsigned long pos, unsigned long bytes)
+{
+   return 0;
+}
+
 #define MAX_XEN_BUFFER_SIZE(64 * 1024)
 #define MAX_BUFFER_SIZEMAX_XEN_BUFFER_SIZE
 #define MIN_PERIOD_SIZE64
@@ -168,10 +291,119 @@ static struct snd_pcm_hardware sdrv_pcm_hw_default = {
.fifo_size = 0,
 };
 
+/*
+ * FIXME: The mmaped data transfer is asynchronous and there is no
+ * ack signal from user-space when it is done. This is the
+ * reason it is not implemented in the PV driver as we do need
+ * to know when the buffer can be transferred to the backend.
+ */
+
+static struct snd_pcm_ops sdrv_alsa_playback_ops = {
+   .op

[Xen-devel] [PATCH 04/11] ALSA: vsnd: Implement Xen event channel handling

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

1. Create event channels for all configured streams and publish
corresponding ring references and event channels in Xen store,
so backend can connect.
2. Implement event channel interrupt handler.
3. Create and destroy event channels with respect to Xen bus state.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 269 +-
 1 file changed, 268 insertions(+), 1 deletion(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index ef48cbf44cf2..a92459b2737e 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -24,14 +24,40 @@
 #include 
 
 #include 
+#include 
+#include 
 #include 
 #include 
 
 #include 
 
+/*
+ * FIXME: usage of grant reference 0 as invalid grant reference:
+ * grant reference 0 is valid, but never exposed to a PV driver,
+ * because of the fact it is already in use/reserved by the PV console.
+ */
+#define GRANT_INVALID_REF  0
 /* maximum number of supported streams */
 #define VSND_MAX_STREAM8
 
+enum xdrv_evtchnl_state {
+   EVTCHNL_STATE_DISCONNECTED,
+   EVTCHNL_STATE_CONNECTED,
+};
+
+struct xdrv_evtchnl_info {
+   struct xdrv_info *drv_info;
+   struct xen_sndif_front_ring ring;
+   int ring_ref;
+   int port;
+   int irq;
+   struct completion completion;
+   enum xdrv_evtchnl_state state;
+   /* latest response status and its corresponding id */
+   int resp_status;
+   uint16_t resp_id;
+};
+
 struct cfg_stream {
int unique_id;
char *xenstore_path;
@@ -65,6 +91,8 @@ struct xdrv_info {
struct xenbus_device *xb_dev;
spinlock_t io_lock;
struct mutex mutex;
+   int num_evt_channels;
+   struct xdrv_evtchnl_info *evt_chnls;
struct sdev_card_plat_data cfg_plat_data;
 };
 
@@ -102,6 +130,244 @@ static struct snd_pcm_hardware sdrv_pcm_hw_default = {
.fifo_size = 0,
 };
 
+static irqreturn_t xdrv_evtchnl_interrupt(int irq, void *dev_id)
+{
+   struct xdrv_evtchnl_info *channel = dev_id;
+   struct xdrv_info *drv_info = channel->drv_info;
+   struct xensnd_resp *resp;
+   RING_IDX i, rp;
+   unsigned long flags;
+
+   spin_lock_irqsave(&drv_info->io_lock, flags);
+   if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
+   goto out;
+
+again:
+   rp = channel->ring.sring->rsp_prod;
+   /* ensure we see queued responses up to rp */
+   rmb();
+
+   for (i = channel->ring.rsp_cons; i != rp; i++) {
+   resp = RING_GET_RESPONSE(&channel->ring, i);
+   if (resp->id != channel->resp_id)
+   continue;
+   switch (resp->operation) {
+   case XENSND_OP_OPEN:
+   /* fall through */
+   case XENSND_OP_CLOSE:
+   /* fall through */
+   case XENSND_OP_READ:
+   /* fall through */
+   case XENSND_OP_WRITE:
+   channel->resp_status = resp->status;
+   complete(&channel->completion);
+   break;
+
+   default:
+   dev_err(&drv_info->xb_dev->dev,
+   "Operation %d is not supported\n",
+   resp->operation);
+   break;
+   }
+   }
+
+   channel->ring.rsp_cons = i;
+   if (i != channel->ring.req_prod_pvt) {
+   int more_to_do;
+
+   RING_FINAL_CHECK_FOR_RESPONSES(&channel->ring, more_to_do);
+   if (more_to_do)
+   goto again;
+   } else
+   channel->ring.sring->rsp_event = i + 1;
+
+out:
+   spin_unlock_irqrestore(&drv_info->io_lock, flags);
+   return IRQ_HANDLED;
+}
+
+static inline void xdrv_evtchnl_flush(
+   struct xdrv_evtchnl_info *channel)
+{
+   int notify;
+
+   channel->ring.req_prod_pvt++;
+   RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&channel->ring, notify);
+   if (notify)
+   notify_remote_via_irq(channel->irq);
+}
+
+static void xdrv_evtchnl_free(struct xdrv_info *drv_info,
+   struct xdrv_evtchnl_info *channel)
+{
+   if (!channel->ring.sring)
+   return;
+
+   channel->state = EVTCHNL_STATE_DISCONNECTED;
+   channel->resp_status = -EIO;
+   complete_all(&channel->completion);
+
+   if (channel->irq)
+   unbind_from_irqhandler(channel->irq, channel);
+   channel->irq = 0;
+
+   if (channel->port)
+   xenbus_free_evtchn(drv_info->xb_dev, channel->port);
+   channel->port = 0;
+
+   if (channel->ring_ref != GRANT_INVALID_REF)
+   gnttab_end_foreign_access(channel->

[Xen-devel] [PATCH 03/11] ALSA: vsnd: Read sound driver configuration from Xen store

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Read configuration values from Xen store according
to xen/interface/io/sndif.h protocol:
- introduce configuration structures for different
  components, e.g. sound card, device, stream
- read PCM HW parameters, e.g rate, format etc.
- detect stream type (capture/playback)
- read device and card parameters

Fill in platform data with the configuration read, so
it can be passed to sound driver later.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 530 ++
 1 file changed, 530 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index c4fd21cac3a7..ef48cbf44cf2 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -20,24 +20,554 @@
 
 #include 
 
+#include 
+#include 
+
 #include 
 #include 
 #include 
 
 #include 
 
+/* maximum number of supported streams */
+#define VSND_MAX_STREAM8
+
+struct cfg_stream {
+   int unique_id;
+   char *xenstore_path;
+   struct snd_pcm_hardware pcm_hw;
+};
+
+struct cfg_pcm_instance {
+   char name[80];
+   int device_id;
+   struct snd_pcm_hardware pcm_hw;
+   int  num_streams_pb;
+   struct cfg_stream *streams_pb;
+   int  num_streams_cap;
+   struct cfg_stream *streams_cap;
+};
+
+struct cfg_card {
+   char name_short[32];
+   char name_long[80];
+   struct snd_pcm_hardware pcm_hw;
+   int num_pcm_instances;
+   struct cfg_pcm_instance *pcm_instances;
+};
+
+struct sdev_card_plat_data {
+   struct xdrv_info *xdrv_info;
+   struct cfg_card cfg_card;
+};
+
 struct xdrv_info {
struct xenbus_device *xb_dev;
spinlock_t io_lock;
struct mutex mutex;
+   struct sdev_card_plat_data cfg_plat_data;
 };
 
+#define MAX_XEN_BUFFER_SIZE(64 * 1024)
+#define MAX_BUFFER_SIZEMAX_XEN_BUFFER_SIZE
+#define MIN_PERIOD_SIZE64
+#define MAX_PERIOD_SIZE(MAX_BUFFER_SIZE / 8)
+#define USE_FORMATS(SNDRV_PCM_FMTBIT_U8 | \
+SNDRV_PCM_FMTBIT_S16_LE)
+#define USE_RATE   (SNDRV_PCM_RATE_CONTINUOUS | \
+SNDRV_PCM_RATE_8000_48000)
+#define USE_RATE_MIN   5512
+#define USE_RATE_MAX   48000
+#define USE_CHANNELS_MIN   1
+#define USE_CHANNELS_MAX   2
+#define USE_PERIODS_MIN2
+#define USE_PERIODS_MAX8
+
+static struct snd_pcm_hardware sdrv_pcm_hw_default = {
+   .info = (SNDRV_PCM_INFO_MMAP |
+SNDRV_PCM_INFO_INTERLEAVED |
+SNDRV_PCM_INFO_RESUME |
+SNDRV_PCM_INFO_MMAP_VALID),
+   .formats = USE_FORMATS,
+   .rates = USE_RATE,
+   .rate_min = USE_RATE_MIN,
+   .rate_max = USE_RATE_MAX,
+   .channels_min = USE_CHANNELS_MIN,
+   .channels_max = USE_CHANNELS_MAX,
+   .buffer_bytes_max = MAX_BUFFER_SIZE,
+   .period_bytes_min = MIN_PERIOD_SIZE,
+   .period_bytes_max = MAX_PERIOD_SIZE,
+   .periods_min = USE_PERIODS_MIN,
+   .periods_max = USE_PERIODS_MAX,
+   .fifo_size = 0,
+};
+
+struct CFG_HW_SAMPLE_RATE {
+   const char *name;
+   unsigned int mask;
+   unsigned int value;
+};
+
+static struct CFG_HW_SAMPLE_RATE cfg_hw_supported_rates[] = {
+   { .name = "5512",   .mask = SNDRV_PCM_RATE_5512,   .value = 5512 },
+   { .name = "8000",   .mask = SNDRV_PCM_RATE_8000,   .value = 8000 },
+   { .name = "11025",  .mask = SNDRV_PCM_RATE_11025,  .value = 11025 },
+   { .name = "16000",  .mask = SNDRV_PCM_RATE_16000,  .value = 16000 },
+   { .name = "22050",  .mask = SNDRV_PCM_RATE_22050,  .value = 22050 },
+   { .name = "32000",  .mask = SNDRV_PCM_RATE_32000,  .value = 32000 },
+   { .name = "44100",  .mask = SNDRV_PCM_RATE_44100,  .value = 44100 },
+   { .name = "48000",  .mask = SNDRV_PCM_RATE_48000,  .value = 48000 },
+   { .name = "64000",  .mask = SNDRV_PCM_RATE_64000,  .value = 64000 },
+   { .name = "96000",  .mask = SNDRV_PCM_RATE_96000,  .value = 96000 },
+   { .name = "176400", .mask = SNDRV_PCM_RATE_176400, .value = 176400 },
+   { .name = "192000", .mask = SNDRV_PCM_RATE_192000, .value = 192000 },
+};
+
+struct CFG_HW_SAMPLE_FORMAT {
+   const char *name;
+   u64 mask;
+};
+
+static struct CFG_HW_SAMPLE_FORMAT cfg_hw_supported_formats[] = {
+   {
+   .name = XENSND_PCM_FORMAT_U8_STR,
+   .mask = SNDRV_PCM_FMTBIT_U8
+   },
+   {
+   .name = XENSND_PCM_FORMAT_S8_STR,
+   .mask = SNDRV_PCM_FMTBIT_S8
+   },
+   {
+   .name = XENSND_PCM_FORMAT_U16_LE_STR,
+   .mask = SNDRV_PCM_FMTBIT_U16_LE
+   },
+   {
+   .name = XENSND_PCM_FORMAT_U16_BE_STR,
+   .mask = 

[Xen-devel] [PATCH 09/11] ALSA: vsnd: Implement ALSA PCM operations

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement ALSA driver operations including:
- start/stop period interrupt emulation
- manage frontend/backend shraed buffers
- manage Xen bus event channel state

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 175 ++
 1 file changed, 163 insertions(+), 12 deletions(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 507c5eb343c8..7275e9cb38c0 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -151,6 +151,11 @@ struct xdrv_info {
struct sdev_card_plat_data cfg_plat_data;
 };
 
+static inline void sh_buf_clear(struct sh_buf_info *buf);
+static void sh_buf_free(struct sh_buf_info *buf);
+static int sh_buf_alloc(struct xenbus_device *xb_dev, struct sh_buf_info *buf,
+   unsigned int buffer_size);
+
 static struct sdev_pcm_stream_info *sdrv_stream_get(
struct snd_pcm_substream *substream)
 {
@@ -311,71 +316,217 @@ static void sdrv_copy_pcm_hw(struct snd_pcm_hardware 
*dst,
 
 static int sdrv_alsa_open(struct snd_pcm_substream *substream)
 {
-   return 0;
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct xdrv_info *xdrv_info;
+   unsigned long flags;
+   int ret;
+
+   sdrv_copy_pcm_hw(&runtime->hw, &stream->pcm_hw, &pcm_instance->pcm_hw);
+   runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
+   SNDRV_PCM_INFO_MMAP_VALID |
+   SNDRV_PCM_INFO_DOUBLE |
+   SNDRV_PCM_INFO_BATCH |
+   SNDRV_PCM_INFO_NONINTERLEAVED |
+   SNDRV_PCM_INFO_RESUME |
+   SNDRV_PCM_INFO_PAUSE);
+   runtime->hw.info |= SNDRV_PCM_INFO_INTERLEAVED;
+
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+
+   ret = sdrv_alsa_timer_create(substream);
+
+   spin_lock_irqsave(&xdrv_info->io_lock, flags);
+   sh_buf_clear(&stream->sh_buf);
+   stream->evt_chnl = &xdrv_info->evt_chnls[stream->unique_id];
+   if (ret < 0)
+   stream->evt_chnl->state = EVTCHNL_STATE_DISCONNECTED;
+   else
+   stream->evt_chnl->state = EVTCHNL_STATE_CONNECTED;
+   spin_unlock_irqrestore(&xdrv_info->io_lock, flags);
+   return ret;
 }
 
 static int sdrv_alsa_close(struct snd_pcm_substream *substream)
 {
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct xdrv_info *xdrv_info;
+   unsigned long flags;
+
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+
+   sdrv_alsa_timer_stop(substream);
+
+   spin_lock_irqsave(&xdrv_info->io_lock, flags);
+   stream->evt_chnl->state = EVTCHNL_STATE_DISCONNECTED;
+   spin_unlock_irqrestore(&xdrv_info->io_lock, flags);
return 0;
 }
 
 static int sdrv_alsa_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
 {
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct xdrv_info *xdrv_info;
+   unsigned int buffer_size;
+   int ret;
+
+   buffer_size = params_buffer_bytes(params);
+   sh_buf_clear(&stream->sh_buf);
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+   ret = sh_buf_alloc(xdrv_info->xb_dev,
+   &stream->sh_buf, buffer_size);
+   if (ret < 0)
+   goto fail;
return 0;
+
+fail:
+   dev_err(&xdrv_info->xb_dev->dev,
+   "Failed to allocate buffers for stream idx %d\n",
+   stream->unique_id);
+   return ret;
 }
 
 static int sdrv_alsa_hw_free(struct snd_pcm_substream *substream)
 {
+   struct sdev_pcm_instance_info *pcm_instance =
+   snd_pcm_substream_chip(substream);
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   struct xdrv_info *xdrv_info;
+   unsigned long flags;
+
+   xdrv_info = pcm_instance->card_info->xdrv_info;
+   spin_lock_irqsave(&xdrv_info->io_lock, flags);
+   sh_buf_free(&stream->sh_buf);
+   spin_unlock_irqrestore(&xdrv_info->io_lock, flags);
return 0;
 }
 
 static int sdrv_alsa_prepare(struct snd_pcm_substream *substream)
 {
-   return 0;
+   struct sdev_pcm_stream_info *stream = sdrv_stream_get(substream);
+   int ret = 0;
+
+   if (!stream->is_open)
+   ret = sdrv_alsa_timer_prepare(substream);
+   return ret;
 }
 
 static int sdrv_alsa_trigger(struct snd_p

[Xen-devel] [PATCH 11/11] ALSA: vsnd: Introduce Kconfig option to enable Xen PV sound

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Introduce Kconfig option to enable Xen para-virtualized sound
frontend driver. Also add sound frontend to the Makefile.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/Kconfig  | 12 
 sound/drivers/Makefile |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 7144cc36e8ae..6b8fa6110ca3 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -235,4 +235,16 @@ config SND_AC97_POWER_SAVE_DEFAULT
 
  See SND_AC97_POWER_SAVE for more details.
 
+config SND_XEN_FRONTEND
+   tristate "Xen virtual sound front-end driver"
+   depends on SND_PCM && XEN
+   select XEN_XENBUS_FRONTEND
+   default n
+   help
+ This driver implements a front-end for the Xen
+ para-virtualized sound.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-xen-front.
+
 endif  # SND_DRIVERS
diff --git a/sound/drivers/Makefile b/sound/drivers/Makefile
index 1a8440c8b138..70ed920a030f 100644
--- a/sound/drivers/Makefile
+++ b/sound/drivers/Makefile
@@ -11,6 +11,7 @@ snd-portman2x4-objs := portman2x4.o
 snd-serial-u16550-objs := serial-u16550.o
 snd-virmidi-objs := virmidi.o
 snd-ml403-ac97cr-objs := ml403-ac97cr.o pcm-indirect2.o
+snd-xen-front-objs := xen-front.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_DUMMY) += snd-dummy.o
@@ -21,5 +22,6 @@ obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o
 obj-$(CONFIG_SND_MTS64) += snd-mts64.o
 obj-$(CONFIG_SND_PORTMAN2X4) += snd-portman2x4.o
 obj-$(CONFIG_SND_ML403_AC97CR) += snd-ml403-ac97cr.o
+obj-$(CONFIG_SND_XEN_FRONTEND) += snd-xen-front.o
 
 obj-$(CONFIG_SND) += opl3/ opl4/ mpu401/ vx/ pcsp/
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH 01/11] ALSA: vsnd: Implement driver's probe/remove

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Add essential driver private info structure, initialize
locks and implement probe/remove of the Xen frontend
driver.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 61779c36cae3..8c5de7b0e7b5 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -26,6 +26,16 @@
 
 #include 
 
+struct xdrv_info {
+   struct xenbus_device *xb_dev;
+   spinlock_t io_lock;
+   struct mutex mutex;
+};
+
+static void xdrv_remove_internal(struct xdrv_info *drv_info)
+{
+}
+
 static void xdrv_be_on_changed(struct xenbus_device *xb_dev,
enum xenbus_state backend_state)
 {
@@ -34,11 +44,28 @@ static void xdrv_be_on_changed(struct xenbus_device *xb_dev,
 static int xdrv_probe(struct xenbus_device *xb_dev,
const struct xenbus_device_id *id)
 {
+   struct xdrv_info *drv_info;
+
+   drv_info = devm_kzalloc(&xb_dev->dev, sizeof(*drv_info), GFP_KERNEL);
+   if (!drv_info) {
+   xenbus_dev_fatal(xb_dev, -ENOMEM, "allocating device memory");
+   return -ENOMEM;
+   }
+
+   drv_info->xb_dev = xb_dev;
+   spin_lock_init(&drv_info->io_lock);
+   mutex_init(&drv_info->mutex);
+   dev_set_drvdata(&xb_dev->dev, drv_info);
return 0;
 }
 
 static int xdrv_remove(struct xenbus_device *dev)
 {
+   struct xdrv_info *drv_info = dev_get_drvdata(&dev->dev);
+
+   mutex_lock(&drv_info->mutex);
+   xdrv_remove_internal(drv_info);
+   mutex_unlock(&drv_info->mutex);
return 0;
 }
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH 06/11] ALSA: vsnd: Introduce ALSA virtual sound driver

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement essential initialization of the sound driver:
- introduce required data structures
- handle driver registration
- handle sound card registration
- register sound driver on backend connection
- remove sound driver on backend disconnect

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 161 +-
 1 file changed, 159 insertions(+), 2 deletions(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 04ebc15757f4..f3e3f64f0aa6 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -19,13 +19,14 @@
  */
 
 #include 
+#include 
 
 #include 
 #include 
 
-#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -66,6 +67,33 @@ struct sh_buf_info {
size_t vbuffer_sz;
 };
 
+struct sdev_pcm_stream_info {
+   int unique_id;
+   struct snd_pcm_hardware pcm_hw;
+   struct xdrv_evtchnl_info *evt_chnl;
+   bool is_open;
+   uint8_t req_next_id;
+   struct sh_buf_info sh_buf;
+};
+
+struct sdev_pcm_instance_info {
+   struct sdev_card_info *card_info;
+   struct snd_pcm *pcm;
+   struct snd_pcm_hardware pcm_hw;
+   int num_pcm_streams_pb;
+   struct sdev_pcm_stream_info *streams_pb;
+   int num_pcm_streams_cap;
+   struct sdev_pcm_stream_info *streams_cap;
+};
+
+struct sdev_card_info {
+   struct xdrv_info *xdrv_info;
+   struct snd_card *card;
+   struct snd_pcm_hardware pcm_hw;
+   int num_pcm_instances;
+   struct sdev_pcm_instance_info *pcm_instances;
+};
+
 struct cfg_stream {
int unique_id;
char *xenstore_path;
@@ -99,6 +127,8 @@ struct xdrv_info {
struct xenbus_device *xb_dev;
spinlock_t io_lock;
struct mutex mutex;
+   bool sdrv_registered;
+   struct platform_device *sdrv_pdev;
int num_evt_channels;
struct xdrv_evtchnl_info *evt_chnls;
struct sdev_card_plat_data cfg_plat_data;
@@ -138,6 +168,132 @@ static struct snd_pcm_hardware sdrv_pcm_hw_default = {
.fifo_size = 0,
 };
 
+static int sdrv_new_pcm(struct sdev_card_info *card_info,
+   struct cfg_pcm_instance *instance_config,
+   struct sdev_pcm_instance_info *pcm_instance_info)
+{
+   return 0;
+}
+
+static int sdrv_probe(struct platform_device *pdev)
+{
+   struct sdev_card_info *card_info;
+   struct sdev_card_plat_data *platdata;
+   struct snd_card *card;
+   int ret, i;
+
+   platdata = dev_get_platdata(&pdev->dev);
+
+   dev_dbg(&pdev->dev, "Creating virtual sound card\n");
+
+   ret = snd_card_new(&pdev->dev, 0, XENSND_DRIVER_NAME, THIS_MODULE,
+   sizeof(struct sdev_card_info), &card);
+   if (ret < 0)
+   return ret;
+
+   card_info = card->private_data;
+   card_info->xdrv_info = platdata->xdrv_info;
+   card_info->card = card;
+   card_info->pcm_instances = devm_kcalloc(&pdev->dev,
+   platdata->cfg_card.num_pcm_instances,
+   sizeof(struct sdev_pcm_instance_info), GFP_KERNEL);
+   if (!card_info->pcm_instances) {
+   ret = -ENOMEM;
+   goto fail;
+   }
+
+   card_info->num_pcm_instances = platdata->cfg_card.num_pcm_instances;
+   card_info->pcm_hw = platdata->cfg_card.pcm_hw;
+
+   for (i = 0; i < platdata->cfg_card.num_pcm_instances; i++) {
+   ret = sdrv_new_pcm(card_info,
+   &platdata->cfg_card.pcm_instances[i],
+   &card_info->pcm_instances[i]);
+   if (ret < 0)
+   goto fail;
+   }
+
+   strncpy(card->driver, XENSND_DRIVER_NAME, sizeof(card->driver));
+   strncpy(card->shortname, platdata->cfg_card.name_short,
+   sizeof(card->shortname));
+   strncpy(card->longname, platdata->cfg_card.name_long,
+   sizeof(card->longname));
+
+   ret = snd_card_register(card);
+   if (ret < 0)
+   goto fail;
+
+   platform_set_drvdata(pdev, card);
+   return 0;
+
+fail:
+   snd_card_free(card);
+   return ret;
+}
+
+static int sdrv_remove(struct platform_device *pdev)
+{
+   struct sdev_card_info *info;
+   struct snd_card *card = platform_get_drvdata(pdev);
+
+   info = card->private_data;
+   dev_dbg(&pdev->dev, "Removing virtual sound card %d\n",
+   info->card->number);
+   snd_card_free(card);
+   return 0;
+}
+
+static struct platform_driver sdrv_info = {
+   .probe  = sdrv_probe,
+   .remove = sdrv_remove,
+   .driver = {
+   .name   = XENSND_DRIVER_NAME,
+   },
+};
+
+static void sdrv_cleanup(struct xdrv_info *drv_info)
+{
+   if (!drv_info->sdrv_registered)
+   return;
+
+   i

[Xen-devel] [PATCH 10/11] ALSA: vsnd: Implement communication with backend

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement frontend to backend communication according to
the para-virtualized sound protocol: xen/interface/io/sndif.h.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 302 +++---
 1 file changed, 288 insertions(+), 14 deletions(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 7275e9cb38c0..8bfec43ef03a 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -38,6 +38,8 @@
  * because of the fact it is already in use/reserved by the PV console.
  */
 #define GRANT_INVALID_REF  0
+/* timeout in ms to wait for backend to respond */
+#define VSND_WAIT_BACK_MS  3000
 /* maximum number of supported streams */
 #define VSND_MAX_STREAM8
 
@@ -151,10 +153,12 @@ struct xdrv_info {
struct sdev_card_plat_data cfg_plat_data;
 };
 
+static inline void xdrv_evtchnl_flush(struct xdrv_evtchnl_info *channel);
 static inline void sh_buf_clear(struct sh_buf_info *buf);
 static void sh_buf_free(struct sh_buf_info *buf);
 static int sh_buf_alloc(struct xenbus_device *xb_dev, struct sh_buf_info *buf,
unsigned int buffer_size);
+static grant_ref_t sh_buf_get_dir_start(struct sh_buf_info *buf);
 
 static struct sdev_pcm_stream_info *sdrv_stream_get(
struct snd_pcm_substream *substream)
@@ -314,6 +318,234 @@ static void sdrv_copy_pcm_hw(struct snd_pcm_hardware *dst,
}
 }
 
+struct ALSA_SNDIF_SAMPLE_FORMAT {
+   uint8_t sndif;
+   snd_pcm_format_t alsa;
+};
+
+static struct ALSA_SNDIF_SAMPLE_FORMAT alsa_sndif_formats[] = {
+   {
+   .sndif = XENSND_PCM_FORMAT_U8,
+   .alsa = SNDRV_PCM_FORMAT_U8
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S8,
+   .alsa = SNDRV_PCM_FORMAT_S8
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U16_LE,
+   .alsa = SNDRV_PCM_FORMAT_U16_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U16_BE,
+   .alsa = SNDRV_PCM_FORMAT_U16_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S16_LE,
+   .alsa = SNDRV_PCM_FORMAT_S16_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S16_BE,
+   .alsa = SNDRV_PCM_FORMAT_S16_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U24_LE,
+   .alsa = SNDRV_PCM_FORMAT_U24_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U24_BE,
+   .alsa = SNDRV_PCM_FORMAT_U24_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S24_LE,
+   .alsa = SNDRV_PCM_FORMAT_S24_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S24_BE,
+   .alsa = SNDRV_PCM_FORMAT_S24_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U32_LE,
+   .alsa = SNDRV_PCM_FORMAT_U32_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U32_BE,
+   .alsa = SNDRV_PCM_FORMAT_U32_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S32_LE,
+   .alsa = SNDRV_PCM_FORMAT_S32_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S32_BE,
+   .alsa = SNDRV_PCM_FORMAT_S32_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_A_LAW,
+   .alsa = SNDRV_PCM_FORMAT_A_LAW
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_MU_LAW,
+   .alsa = SNDRV_PCM_FORMAT_MU_LAW
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F32_LE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F32_BE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F64_LE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT64_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F64_BE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT64_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE,
+   .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE,
+   .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IMA_ADPCM,
+   .alsa = SNDRV_PCM_FORMAT_IMA_ADPCM
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_MPEG,
+   .alsa = SNDRV_PCM_FORMAT_MPEG
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_GSM,
+   .alsa = SNDRV_PCM_FORMAT_GSM
+   },
+};
+
+static int alsa_to_sndif_format(snd_pcm_format_t format)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(alsa_sndif_formats); i++)
+   if (alsa_sndif_formats[i].alsa == format)
+   return alsa_sndif_formats[i].sndif;
+   return -EINVAL;
+}
+
+static void sdrv_stream_clear(str

[Xen-devel] [PATCH 05/11] ALSA: vsnd: Implement handling of shared buffers

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement shared buffer handling according to the
para-virtualized sound device protocol at xen/interface/io/sndif.h:
- manage buffer memory
- handle granted references
- handle page directories

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 178 ++
 1 file changed, 178 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index a92459b2737e..04ebc15757f4 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -58,6 +58,14 @@ struct xdrv_evtchnl_info {
uint16_t resp_id;
 };
 
+struct sh_buf_info {
+   int num_grefs;
+   grant_ref_t *grefs;
+   uint8_t *vdirectory;
+   uint8_t *vbuffer;
+   size_t vbuffer_sz;
+};
+
 struct cfg_stream {
int unique_id;
char *xenstore_path;
@@ -825,6 +833,176 @@ static void xdrv_remove_internal(struct xdrv_info 
*drv_info)
xdrv_evtchnl_free_all(drv_info);
 }
 
+static inline grant_ref_t sh_buf_get_dir_start(struct sh_buf_info *buf)
+{
+   if (!buf->grefs)
+   return GRANT_INVALID_REF;
+   return buf->grefs[0];
+}
+
+static inline void sh_buf_clear(struct sh_buf_info *buf)
+{
+   memset(buf, 0, sizeof(*buf));
+}
+
+static void sh_buf_free(struct sh_buf_info *buf)
+{
+   int i;
+
+   if (buf->grefs) {
+   for (i = 0; i < buf->num_grefs; i++)
+   if (buf->grefs[i] != GRANT_INVALID_REF)
+   gnttab_end_foreign_access(buf->grefs[i],
+   0, 0UL);
+   kfree(buf->grefs);
+   }
+   kfree(buf->vdirectory);
+   free_pages_exact(buf->vbuffer, buf->vbuffer_sz);
+   sh_buf_clear(buf);
+}
+
+/*
+ * number of grant references a page can hold with respect to the
+ * xendispl_page_directory header
+ */
+#define XENSND_NUM_GREFS_PER_PAGE ((XEN_PAGE_SIZE - \
+   offsetof(struct xensnd_page_directory, gref)) / \
+   sizeof(grant_ref_t))
+
+static void sh_buf_fill_page_dir(struct sh_buf_info *buf, int num_pages_dir)
+{
+   struct xensnd_page_directory *page_dir;
+   unsigned char *ptr;
+   int i, cur_gref, grefs_left, to_copy;
+
+   ptr = buf->vdirectory;
+   grefs_left = buf->num_grefs - num_pages_dir;
+   /*
+* skip grant references at the beginning, they are for pages granted
+* for the page directory itself
+*/
+   cur_gref = num_pages_dir;
+   for (i = 0; i < num_pages_dir; i++) {
+   page_dir = (struct xensnd_page_directory *)ptr;
+   if (grefs_left <= XENSND_NUM_GREFS_PER_PAGE) {
+   to_copy = grefs_left;
+   page_dir->gref_dir_next_page = GRANT_INVALID_REF;
+   } else {
+   to_copy = XENSND_NUM_GREFS_PER_PAGE;
+   page_dir->gref_dir_next_page = buf->grefs[i + 1];
+   }
+   memcpy(&page_dir->gref, &buf->grefs[cur_gref],
+   to_copy * sizeof(grant_ref_t));
+   ptr += XEN_PAGE_SIZE;
+   grefs_left -= to_copy;
+   cur_gref += to_copy;
+   }
+}
+
+static int sh_buf_grant_refs(struct xenbus_device *xb_dev,
+   struct sh_buf_info *buf,
+   int num_pages_dir, int num_pages_vbuffer, int num_grefs)
+{
+   grant_ref_t priv_gref_head;
+   int ret, i, j, cur_ref;
+   int otherend_id;
+
+   ret = gnttab_alloc_grant_references(num_grefs, &priv_gref_head);
+   if (ret)
+   return ret;
+
+   buf->num_grefs = num_grefs;
+   otherend_id = xb_dev->otherend_id;
+   j = 0;
+
+   for (i = 0; i < num_pages_dir; i++) {
+   cur_ref = gnttab_claim_grant_reference(&priv_gref_head);
+   if (cur_ref < 0) {
+   ret = cur_ref;
+   goto fail;
+   }
+
+   gnttab_grant_foreign_access_ref(cur_ref, otherend_id,
+   xen_page_to_gfn(virt_to_page(buf->vdirectory +
+   XEN_PAGE_SIZE * i)), 0);
+   buf->grefs[j++] = cur_ref;
+   }
+
+   for (i = 0; i < num_pages_vbuffer; i++) {
+   cur_ref = gnttab_claim_grant_reference(&priv_gref_head);
+   if (cur_ref < 0) {
+   ret = cur_ref;
+   goto fail;
+   }
+
+   gnttab_grant_foreign_access_ref(cur_ref, otherend_id,
+   xen_page_to_gfn(virt_to_page(buf->vbuffer +
+   XEN_PAGE_SIZE * i)), 0);
+   buf->grefs[j++] = cur_ref;
+   }
+
+   gnttab_free_grant_references(priv_gref_head);
+   sh_buf_fill_page_dir(buf, num_pages_dir);
+   return 0;
+
+fail:
+   gnttab_free_grant_references(priv_gref_hea

[Xen-devel] [PATCH 02/11] ALSA: vsnd: Implement Xen bus state handling

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Initial handling for Xen bus states: implement
Xen bus state machine for the front driver according to
the state diagram and recovery flow from sound para-virtualized
protocol: xen/interface/io/sndif.h.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 92 +++
 1 file changed, 92 insertions(+)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 8c5de7b0e7b5..c4fd21cac3a7 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -36,9 +36,99 @@ static void xdrv_remove_internal(struct xdrv_info *drv_info)
 {
 }
 
+static int xdrv_be_on_initwait(struct xdrv_info *drv_info)
+{
+   return 0;
+}
+
+static inline int xdrv_be_on_connected(struct xdrv_info *drv_info)
+{
+   return 0;
+}
+
+static inline void xdrv_be_on_disconnected(struct xdrv_info *drv_info)
+{
+   xdrv_remove_internal(drv_info);
+}
+
 static void xdrv_be_on_changed(struct xenbus_device *xb_dev,
enum xenbus_state backend_state)
 {
+   struct xdrv_info *drv_info = dev_get_drvdata(&xb_dev->dev);
+   int ret;
+
+   switch (backend_state) {
+   case XenbusStateReconfiguring:
+   /* fall through */
+   case XenbusStateReconfigured:
+   /* fall through */
+   case XenbusStateInitialised:
+   /* fall through */
+   break;
+
+   case XenbusStateInitialising:
+   if (xb_dev->state == XenbusStateInitialising)
+   break;
+
+   /* recovering after backend unexpected closure */
+   mutex_lock(&drv_info->mutex);
+   xdrv_be_on_disconnected(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   xenbus_switch_state(xb_dev, XenbusStateInitialising);
+   break;
+
+   case XenbusStateInitWait:
+   if (xb_dev->state != XenbusStateInitialising)
+   break;
+
+   mutex_lock(&drv_info->mutex);
+   ret = xdrv_be_on_initwait(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   if (ret < 0) {
+   xenbus_dev_fatal(xb_dev, ret,
+   "initializing " XENSND_DRIVER_NAME);
+   break;
+   }
+
+   xenbus_switch_state(xb_dev, XenbusStateInitialised);
+   break;
+
+   case XenbusStateConnected:
+   if (xb_dev->state != XenbusStateInitialised)
+   break;
+
+   mutex_lock(&drv_info->mutex);
+   ret = xdrv_be_on_connected(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   if (ret < 0) {
+   xenbus_dev_fatal(xb_dev, ret,
+   "connecting " XENSND_DRIVER_NAME);
+   break;
+   }
+
+   xenbus_switch_state(xb_dev, XenbusStateConnected);
+   break;
+
+   case XenbusStateClosing:
+   /*
+* in this state backend starts freeing resources,
+* so let it go into closed state first, so we can also
+* remove ours
+*/
+   break;
+
+   case XenbusStateUnknown:
+   /* fall through */
+   case XenbusStateClosed:
+   if (xb_dev->state == XenbusStateClosed)
+   break;
+
+   mutex_lock(&drv_info->mutex);
+   xdrv_be_on_disconnected(drv_info);
+   mutex_unlock(&drv_info->mutex);
+   xenbus_switch_state(xb_dev, XenbusStateInitialising);
+   break;
+   }
 }
 
 static int xdrv_probe(struct xenbus_device *xb_dev,
@@ -56,6 +146,7 @@ static int xdrv_probe(struct xenbus_device *xb_dev,
spin_lock_init(&drv_info->io_lock);
mutex_init(&drv_info->mutex);
dev_set_drvdata(&xb_dev->dev, drv_info);
+   xenbus_switch_state(xb_dev, XenbusStateInitialising);
return 0;
 }
 
@@ -63,6 +154,7 @@ static int xdrv_remove(struct xenbus_device *dev)
 {
struct xdrv_info *drv_info = dev_get_drvdata(&dev->dev);
 
+   xenbus_switch_state(dev, XenbusStateClosed);
mutex_lock(&drv_info->mutex);
xdrv_remove_internal(drv_info);
mutex_unlock(&drv_info->mutex);
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] PV drivers and zero copying

2017-08-01 Thread Oleksandr Andrushchenko

Hi, Stefano!

On 07/31/2017 11:28 PM, Stefano Stabellini wrote:

On Mon, 31 Jul 2017, Oleksandr Andrushchenko wrote:

3 Sharing with page exchange (XENMEM_exchange)
==

This API was pointed to me by Stefano Stabellini as one of the possible ways
to
achieve zero copying and share physically contiguous buffers. It is used by
x86
SWIOTLB code (xen_create_contiguous_region, [5]), but as per my understanding
this API cannot be used on ARM as of now [6].  Conclusion: not an option for
ARM
at the moment

Let me elaborate on this. The purpose of XENMEM_exchange is to exchange
a number of memory pages with an equal number of contiguous memory
pages, possibly even under 4G. The original purpose of the hypercall was
to get DMA-able memory.

this is good to know


So far, it has only been used by Dom0 on x86. Dom0 on ARM doesn't need
it because it is mapped 1:1 by default and device assignment is not
allowed without an IOMMU. However it should work on ARM too, as the
implementation is all common code in Xen.

well, according to [6]:
"Currently XENMEM_exchange is not supported on ARM because the steal_page is
left unimplemented.

However, even if steal_page is implemented, the hypercall can't work for ARM
because:
- Direct mapped domain is not supported
- ARM doesn't have a M2P and therefore usage of mfn_to_gmfn is
invalid"
And what I see at [7] is that it is still EOPNOTSUPP
So, yes, common code is usable for both ARM and x86, but
underlying support for ARM is till not there.
Please correct me if I am wrong here

  Also, looking at the
implementation (xen/common/memory.c:memory_exchange) it would seem that
it can be called from a DomU too (but I have never tried).

good

Thus, if you have a platform without IOMMU and you disabled the IOMMU
checks in Xen to assign a device to a DomU anyway, then you could use
this hypercall from DomU to get memory under 4G to be used for DMA with
this device.

There is no real device assigned to DomU, but a PV frontend


As far as I can tell XENMEM_exchange could help in the design of
zero-copy PV protocols only to address this specific use case:

- you have a frontend in DomU and a backend in Dom0
- pages shared by DomU get mapped in Dom0 and potentially used for DMA

yes, this is crucial for zero copying in my case: DMA

- the device has under 4G DMA restrictions

Normally Dom0 maps a DomU page, then at the time of using the mapped
page for DMA it checks whether it is suitable for DMA (under 4G if the
device requires so). If it is not, Dom0 uses a bounce buffer borrowed
from the swiotlb. Obviously this introduces one or two memcpys.

Instead, if DomU calls XENMEM_exchange to get memory under 4G, and
shares one of the pages with Dom0 via PV frontends, then Dom0 wouldn't
have to use a bounce buffer to do DMA to this page.

Does it make sense?

yes, it does, thank you, but [6], [7] :(


[7] 
https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=xen/arch/arm/mm.c;h=411bab1ea9f7f14789a134056ebff9f68fd4a4c7;hb=a15516c0cf21d7ac84799f1e2e500b0bb22d2300#l1161



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] PV drivers and zero copying

2017-07-31 Thread Oleksandr Andrushchenko

On 07/31/2017 02:58 PM, Joao Martins wrote:

On 07/31/2017 12:41 PM, Oleksandr Andrushchenko wrote:

Hi, Joao!

On 07/31/2017 02:03 PM, Joao Martins wrote:

Hey Oleksandr,

On 07/31/2017 09:34 AM, Oleksandr Andrushchenko wrote:

Hi, all!


[snip]

Comparison for display use-case
===

1 Number of grant references used
1-1 grant references: nr_pages
1-2 GNTTABOP_transfer: nr_pages
1-3 XENMEM_exchange: not an option

2 Effect of DomU crash on Dom0 (its mapped pages)
2-1 grant references: pages can be unmapped by Dom0, Dom0 is fully
recovered
2-2 GNTTABOP_transfer: pages will be returned to the Hypervisor, lost
for Dom0
2-3 XENMEM_exchange: not an option

3 Security issues from sharing Dom0 pages to DomU
1-1 grant references: none
1-2 GNTTABOP_transfer: none
1-3 XENMEM_exchange: not an option

At the moment approach 1 with granted references seems to be a winner for
sharing buffers both ways, e.g. Dom0 -> DomU and DomU -> Dom0.

Conclusion
==

I would like to get some feedback from the community on which approach
is more
suitable for sharing large buffers and to have a clear vision on cons
and pros
of each one: please feel free to add other metrics I missed and correct
the ones
I commented on.  I would appreciate help on comparing approaches 2 and 3
as I
have little knowledge of these APIs (2 seems to be addressed by
Christopher, and
3 seems to be relevant to what Konrad/Stefano do WRT SWIOTLB).

Depending on your performance/memory requirements - there could be another
option which is to keep the guest mapped on Domain-0 (what was discussed with
Zerogrant session[0][1] that will be formally proposed in the next month or so).

Unfortunately I missed that session during the Summit
due to overlapping sessions

Hmm - Zerocopy Rx (Dom0 -> DomU) would indeed be an interesting topic to bring 
up.


it is, especially for the systems which require physically contiguous
buffers

But that would only solve the grant maps/unmaps/copies done on Domain-0 (given
the numbers you pasted a bit ago, you might not really need to go to such 
extents)

[0]
http://schd.ws/hosted_files/xendeveloperanddesignsummit2017/05/zerogrant_spec.pdf
[1]
http://schd.ws/hosted_files/xendeveloperanddesignsummit2017/a8/zerogrant_slides.pdf

I will read these, thank you for the links

For the buffers allocated on Dom0 and safely grant buffers from Dom0 to DomU
(which I am not so sure it is possible today :()

We have this working in our setup for display (we have implemented
z-copy with grant references already)

Allow me to clarify :) I meant "possible to do it in a safely manner", IOW,
regarding what I mentioned below in following paragraphs. But your answer below
clarifies on that aspect.

good :)

, maybe a "contract" from DomU
provide a set of transferable pages that Dom0 holds on for each Dom-0 gref
provided to the guest (and assuming this is only a handful couple of guests as
grant table is not that big).

It is an option

   IIUC, From what you pasted above on "Buffer
allocated @Dom0" sounds like Domain-0 could quickly ran out of pages/OOM (and
grants), if you're guest is misbehaving/buggy or malicious; *also* domain-0
grant table is a rather finite/small resource (even though you can override the
number of frames in the arguments).

Well, you are right. But, we are focusing on embedded appliances,
so those systems we use are not that "dynamic" with that respect.
Namely: we have fixed number of domains and their functionality
is well known, so we can do rather precise assumption on resource
usage.

Interesting! So here I presume backend trusts the frontend.

yes, this is the case. What is more backend can make decision
on if to allow buffer allocation or reject the request

Cheers,
Joao



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] PV drivers and zero copying

2017-07-31 Thread Oleksandr Andrushchenko

Hi, Joao!

On 07/31/2017 02:03 PM, Joao Martins wrote:

Hey Oleksandr,

On 07/31/2017 09:34 AM, Oleksandr Andrushchenko wrote:

Hi, all!


[snip]

Comparison for display use-case
===

1 Number of grant references used
1-1 grant references: nr_pages
1-2 GNTTABOP_transfer: nr_pages
1-3 XENMEM_exchange: not an option

2 Effect of DomU crash on Dom0 (its mapped pages)
2-1 grant references: pages can be unmapped by Dom0, Dom0 is fully
recovered
2-2 GNTTABOP_transfer: pages will be returned to the Hypervisor, lost
for Dom0
2-3 XENMEM_exchange: not an option

3 Security issues from sharing Dom0 pages to DomU
1-1 grant references: none
1-2 GNTTABOP_transfer: none
1-3 XENMEM_exchange: not an option

At the moment approach 1 with granted references seems to be a winner for
sharing buffers both ways, e.g. Dom0 -> DomU and DomU -> Dom0.

Conclusion
==

I would like to get some feedback from the community on which approach
is more
suitable for sharing large buffers and to have a clear vision on cons
and pros
of each one: please feel free to add other metrics I missed and correct
the ones
I commented on.  I would appreciate help on comparing approaches 2 and 3
as I
have little knowledge of these APIs (2 seems to be addressed by
Christopher, and
3 seems to be relevant to what Konrad/Stefano do WRT SWIOTLB).

Depending on your performance/memory requirements - there could be another
option which is to keep the guest mapped on Domain-0 (what was discussed with
Zerogrant session[0][1] that will be formally proposed in the next month or so).

Unfortunately I missed that session during the Summit
due to overlapping sessions

But that would only solve the grant maps/unmaps/copies done on Domain-0 (given
the numbers you pasted a bit ago, you might not really need to go to such 
extents)

[0]
http://schd.ws/hosted_files/xendeveloperanddesignsummit2017/05/zerogrant_spec.pdf
[1]
http://schd.ws/hosted_files/xendeveloperanddesignsummit2017/a8/zerogrant_slides.pdf

I will read these, thank you for the links

For the buffers allocated on Dom0 and safely grant buffers from Dom0 to DomU
(which I am not so sure it is possible today :()

We have this working in our setup for display (we have implemented
z-copy with grant references already)

, maybe a "contract" from DomU
provide a set of transferable pages that Dom0 holds on for each Dom-0 gref
provided to the guest (and assuming this is only a handful couple of guests as
grant table is not that big).

It is an option

  IIUC, From what you pasted above on "Buffer
allocated @Dom0" sounds like Domain-0 could quickly ran out of pages/OOM (and
grants), if you're guest is misbehaving/buggy or malicious; *also* domain-0
grant table is a rather finite/small resource (even though you can override the
number of frames in the arguments).

Well, you are right. But, we are focusing on embedded appliances,
so those systems we use are not that "dynamic" with that respect.
Namely: we have fixed number of domains and their functionality
is well known, so we can do rather precise assumption on resource
usage.

Joao

Thank you,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [XenSummit 2017] Build tools follow up

2017-07-31 Thread Oleksandr Andrushchenko

ping

On 07/17/2017 03:47 PM, Oleksandr Andrushchenko wrote:

Hi, all!

This is a follow-up on Xen distribution build systems we saw at the
summit and invitation for sharing thoughts and ways we build our 
images and
distros. I would like to specifically ask OpenXT project to reply with 
the
description of their build system so we have clear picture of what is 
being
developed and used around. And of course if there are other approaches 
to do the

same you are welcome to share those as well.

On our side at EPAM we have developed a distribution which is called 
xt-distro

(xt stays for Xen troops [0]) with the following goals in mind:
1. Make it possible to easily build different images as a single 
distribution

   - Separate images for different domains should be combined into a
 distribution, e.g. set of images/artifacts required to run them as a
 system
   - Xt-distro allows doing so as easy as running bitbake with the 
predefined

 target, e.g. “bitbake xt-image”
2. Easily deal with different BSPs for different platforms using a 
unified way

   with little or no EPAM specific code/scripts
   - We use bitbake and stripped version of Poky/meta-openembedded, so 
there are
 little in-house extensions we added to deal with Yocto based BSPs 
[1], [2]
   - We use bitbake’s well defined scripting language [3], so no yet 
another

 language to learn
   - We use Google repo tool to maintain sets of meta layers as 
manifest files [4]

3. Ability to easily collect component revisions, so any build can be
   reproduced if need be
   - We save commit IDs of every component of the build including 
versions of the

 meta layers
4. Ability to easily customize and tune builds, e.g. URIs, 
versions/commitIDs,

   branches used
   - This is purely done in bitbake’s recipe language
5. Make patching process easy
   - With our extensions you can use bblayers.conf, local.conf, 
patches which

 are part of a meta layer which is usually a manual step
6. Code reuse is a must, e.g. the same set of software must be easily 
built for
   different platforms without copying build scripts of the existing 
components
   - With bitbake’s meta layers we define generic recipes, e.g. 
suitable for all

 platforms [5] (think of it as a library) and tuning meta layers [6]
 (we use product concept here) which define specific 
versions/revisions of the

 components, apply specific patches and add/remove software
7. Cross compilation must be an easy task to do
   - This is easily achieved with Yocto builds and usually not a 
problem for other

 build systems as well (with SDKs)
   - Allows building for x86/ARM and other architectures as well
8. There must be a simple way to share build artifacts of different 
domains between
   each other, for example, DomU’s kernel should be a part of Dom0’s 
rootfs, so

   xl/libxl can access it
   - This is achieved with bitbake’s recipes, so no EPAM extensions
9. Possibility to easily use different build systems for different 
components of

   the system.
   - Bitbake allows you building makefile based projects, CMake etc. 
out of the box,

 so adding firmware, stubdoms made easy
10. Development support
   - We use SDKs built by bitbake so during everyday development you 
are packed with
 all that is needed to re-create build environment (with both host 
and target

 environments, e.g. x86 host tools and ARM cross-compiler)
   - Speed up builds for developers within organization, e.g. we reuse 
downloads and

 build cache between all of the developer’s machines on our network
11. Make the build system suitable for build automation
- We have created a python script which can easily be used with
  Jenkins or even cron [7]

For example, with xt-distro our development product delivers: Xen 
image and
policy file, Dom0 kernel and dtb images (Dom0 + DomU), Dom0 rootfs 
image (with

embedded kernels and configuration for DomU), DomU rootfs image. This
effectively means, that the build system can provide you with the 
complete set

of images to run your product/distribution.

We are looking forward for any kind of feedback and will be glad to 
collaborate

on the above.

Thank you,
Xen-troops at EPAM

[0] https://github.com/xen-troops/xt-distro
[1] https://git.yoctoproject.org/cgit/cgit.cgi/poky
[2] http://cgit.openembedded.org/meta-openembedded
[3] 
http://www.yoctoproject.org/docs/2.3/bitbake-user-manual/bitbake-user-manual.html

[4] https://gerrit.googlesource.com/git-repo
[5] https://github.com/xen-troops/meta-xt-images
[6] https://github.com/xen-troops/meta-xt-prod-devel
[7] https://github.com/xen-troops/build-scripts




___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] PV drivers and zero copying

2017-07-31 Thread Oleksandr Andrushchenko



On 07/31/2017 01:04 PM, Julien Grall wrote:



On 31/07/17 10:52, Oleksandr Andrushchenko wrote:

On 07/31/2017 12:47 PM, Julien Grall wrote:

On 31/07/17 10:46, Oleksandr Andrushchenko wrote:
Do you have any example of hardware? What are the performance you
require with them?


Currently our target is Renesas R-Car Gen3
At the moment I don't have clean requirements, but
ideally, PV driver introduces 0% performance drop
Some time soon I will have numbers on running display/GPU
with and without zero-copy - will keep updated


PV driver with 0% performance drop sounds a stretch target.

It is, but we should always get as close as possible
But this is does not answer to my question. Do you have any hardware 
that does not support scatter/gather

AFAIK display driver which doesn't support scatter-gather on our platform
(BSP based on 4.9 kernel, rcar_du uses DRM CMA - DRM contiguous memory 
allocator)

Anyways, for pages above 4GB even scatter-gather will not help
devices with 32-bit DMA

or not protected by an IOMMU that will be interfaced with PV drivers?


As per my understanding, IOMMU is solely owned by the hypervisor now
and there is no API to tell Xen from Dom0 to setup IOMMU for such
a buffer (pages), so display HW can do DMA with that buffer.
Thus, Dom0 has no means to do that work and make PV driver produce
buffers which can be used by the real HW driver without bounce buffering.

Cheers,




___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] PV drivers and zero copying

2017-07-31 Thread Oleksandr Andrushchenko

On 07/31/2017 12:47 PM, Julien Grall wrote:



On 31/07/17 10:46, Oleksandr Andrushchenko wrote:

Hi, Julien!


On 07/31/2017 12:24 PM, Julien Grall wrote:

(+ Joao)

On 31/07/17 09:34, Oleksandr Andrushchenko wrote:

Hi, all!


Hi Oleksandr,

The aim of this mail is to highlight and discuss possible 
approaches to
implementing zero copying for PV drivers. Rationale behind this is 
that

there
are use-cases when drivers operate with big shared buffers, e.g.
display, when
memory copying from front’s buffer into back’s one may 
significantly hit
performance of the system (for example, for para-virtual display 
running

at full
HD resolution at 60Hz it is approximately 475MB/sec).

Assumptions (which actually fit ARM platforms, but can be extended to
other
platforms as well): Dom0 is a 1:1 mapped privileged domain, runs 
backend

driver/software DomU is an unprivileged domain without 1:1 memory
mapping, runs
frontend driver


I would rather avoid to stick with this assumption on ARM. This was
only meant to be a workaround for platform without IOMMU (see [1]) and
we will get into trouble when using IOMMU.

You are correct, thank you


For instance, there are no requirement to have the IOMMU supporting as
many as address bits than the processor. So 1:1 mapping here will not
be an option.



Buffer origin: while implementing zero copying the buffer 
allocation can

happen
either on DomU’s end or Dom0’s one depending on the use-case and HW
capabilities/availability: When DomU allocates: It cannot guarantee
physical
memory continuity of the buffers allocated Dom0’s HW *can* handle
non-contiguous
memory buffers allocated by DomU for memory operations (DMA, for
example), e.g.
either with IOMMU help or by any other means (HW block’s own MMU).  
When

Dom0
allocates as it is mapped 1:1 it can allocate physically contiguous
memory
Dom0’s HW *cannot* handle non-contiguous memory buffers allocated by
DomU for
memory operations by any means.


I am not sure to follow this. How zero copy is related to 1:1 mapping?
Is it because you have hardware that does not support scatter/gather
IO or IOMMU?

yes, you got it right


Do you have any example of hardware? What are the performance you 
require with them?



Currently our target is Renesas R-Car Gen3
At the moment I don't have clean requirements, but
ideally, PV driver introduces 0% performance drop
Some time soon I will have numbers on running display/GPU
with and without zero-copy - will keep updated

Cheers,




___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] PV drivers and zero copying

2017-07-31 Thread Oleksandr Andrushchenko

Hi, Julien!


On 07/31/2017 12:24 PM, Julien Grall wrote:

(+ Joao)

On 31/07/17 09:34, Oleksandr Andrushchenko wrote:

Hi, all!


Hi Oleksandr,


The aim of this mail is to highlight and discuss possible approaches to
implementing zero copying for PV drivers. Rationale behind this is that
there
are use-cases when drivers operate with big shared buffers, e.g.
display, when
memory copying from front’s buffer into back’s one may significantly hit
performance of the system (for example, for para-virtual display running
at full
HD resolution at 60Hz it is approximately 475MB/sec).

Assumptions (which actually fit ARM platforms, but can be extended to 
other

platforms as well): Dom0 is a 1:1 mapped privileged domain, runs backend
driver/software DomU is an unprivileged domain without 1:1 memory
mapping, runs
frontend driver


I would rather avoid to stick with this assumption on ARM. This was 
only meant to be a workaround for platform without IOMMU (see [1]) and 
we will get into trouble when using IOMMU.

You are correct, thank you


For instance, there are no requirement to have the IOMMU supporting as 
many as address bits than the processor. So 1:1 mapping here will not 
be an option.




Buffer origin: while implementing zero copying the buffer allocation can
happen
either on DomU’s end or Dom0’s one depending on the use-case and HW
capabilities/availability: When DomU allocates: It cannot guarantee
physical
memory continuity of the buffers allocated Dom0’s HW *can* handle
non-contiguous
memory buffers allocated by DomU for memory operations (DMA, for
example), e.g.
either with IOMMU help or by any other means (HW block’s own MMU).  When
Dom0
allocates as it is mapped 1:1 it can allocate physically contiguous 
memory

Dom0’s HW *cannot* handle non-contiguous memory buffers allocated by
DomU for
memory operations by any means.


I am not sure to follow this. How zero copy is related to 1:1 mapping? 
Is it because you have hardware that does not support scatter/gather 
IO or IOMMU?

yes, you got it right




1 Sharing with granted references
==

1-1 Buffer allocated @DomU
--
@DomU
alloc_xenballooned_pages(nr_pages, pages);
cur_ref = gnttab_claim_grant_reference(&priv_gref_head);
gnttab_grant_foreign_access_ref(cur_ref, otherend_id, ...);

@Dom0
alloc_xenballooned_pages(nr_pages, pages);
gnttab_set_map_op(&map_ops[i], addr, GNTMAP_host_map |
GNTMAP_device_map,
grefs[i], otherend_id);
gnttab_map_refs(map_ops, NULL, pages, nr_pages);

1-2 Buffer allocated @Dom0
--
@Dom0
 PV MMU support as seen in the balloon driver, the difference is 
that

 pages are explicitly allocated to be used for DMA>
dma_alloc_wc(dev, size, &dev_addr, GFP_KERNEL | __GFP_NOWARN);
HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
cur_ref = gnttab_claim_grant_reference(&priv_gref_head);
gnttab_grant_foreign_access_ref(cur_ref, otherend_id, ...);

@Dom0
alloc_xenballooned_pages(nr_pages, pages);
gnttab_set_map_op(&map_ops[i], addr, GNTMAP_host_map, grefs[i],
otherend_id);
gnttab_map_refs(map_ops, NULL, pages, nr_pages);

2 Sharing with page transfers (GNTTABOP_transfer)
==
FIXME: This use-case seems to be only needed while allocating physically
contiguous buffers at Dom0. For the reverse path 1-1 method can be used.

This approach relies on GNTTABOP_transfer API: “transfer  to a
foreign
domain. The foreign domain has previously registered its interest in the
transfer via ”, for full documentation see [1]. The 
process of

transferring pages is explained by Christopher Clark at [2] and is
available as
implementation at [3], [4]. The relevant logic is in:
xen/common/grant_table.c :
gnttab_transfer.

Basic workflow explained to me by Christopher:
- The mfn starts as owned by the sending domain, and that domain removes
any
  mappings of it from its page tables. Xen will enforce that the
reference count
must be low enough for the transfer to succeed.
- The receiving domain indicates interest for receiving a page by
writing an
  entry in its grant table.
- You'll need to communicate the grant ref from the receiver to the
sender (eg.
  via xenstore or another existing channel)
- The sending domain invokes the hypercall, with the grant ref from the
  receiving domain.
- The sending domain notifies the receiving domain somehow that the
transfer has
  completed. (eg. send an event or via xenstore)
- Once the transfer has completed, the receiving domain will need to map
the
  newly assigned page.
- Note: For the transfer, the receiving domain must have enough 
headroom to

  receive the new page, which means it must not have allocated all of
its memory
quota already prior to the transfer. Typically this can be ensured by
freeing
enough memory back to Xen before writing the grant ref.

3 Sharing wit

Re: [Xen-devel] PV drivers and zero copying

2017-07-31 Thread Oleksandr Andrushchenko

On 07/31/2017 12:31 PM, Andrew Cooper wrote:

On 31/07/17 10:03, Paul Durrant wrote:

-Original Message-

[snip]

Comparison for display use-case
===

1 Number of grant references used
1-1 grant references: nr_pages
1-2 GNTTABOP_transfer: nr_pages
1-3 XENMEM_exchange: not an option

2 Effect of DomU crash on Dom0 (its mapped pages)
2-1 grant references: pages can be unmapped by Dom0, Dom0 is fully
recovered
2-2 GNTTABOP_transfer: pages will be returned to the Hypervisor, lost
for Dom0
2-3 XENMEM_exchange: not an option

3 Security issues from sharing Dom0 pages to DomU
1-1 grant references: none
1-2 GNTTABOP_transfer: none
1-3 XENMEM_exchange: not an option

At the moment approach 1 with granted references seems to be a winner for
sharing buffers both ways, e.g. Dom0 -> DomU and DomU -> Dom0.

Conclusion
==

I would like to get some feedback from the community on which approach
is more
suitable for sharing large buffers and to have a clear vision on cons
and pros
of each one: please feel free to add other metrics I missed and correct
the ones
I commented on.  I would appreciate help on comparing approaches 2 and 3
as I
have little knowledge of these APIs (2 seems to be addressed by
Christopher, and
3 seems to be relevant to what Konrad/Stefano do WRT SWIOTLB).


Hi,

   I once implemented a scheme where network frontends used memory granted from 
backends and this hit quite a few problems:

- If domU is allowed to grant map memory from dom0, there is not currently a 
way to forcibly take it back (so I don't think you're quite correct in 2-1 
above... but I may have missed something). Hence the domU can hold dom0's 
memory to ransom. (In the network case this was avoided by using grant table v2 
'copy-only' grants).
- If you end up having to grant buffers which do not originate in dom0 (i.e. 
they were grant mapped from another domU) then this creates similar problems 
with one domU holding another domU's memory to ransom, even when using 
copy-only grants. I don’t think this would be an issue in your use-case.
- Currently the default grant table size is 32 pages and it may not take that 
many guests using a protocol where dom0 grants memory to domU to exhaust dom0's 
grant table (depending on how many grants-per-domU the protocol allows). If 
you're intending to grant large buffers then you may need quite a few grants 
(since they are per-4k-chunk) to do this, so you might run into this limit.

To follow up on what Paul said, google for XenServer Receive Side Copy.

I will, thank you

The issue is that it looks very attractive (from an offloading things
out of dom0 perspective), and does work at small scale, but the failure
cases are far more tricky than we imagined, and you run dom0 out of
grants very quickly, which puts a hard upper bound on scalability.  It
is high on the list of "worst mistakes we put into production".

It is not safe at all for dom0 to grant frames to domU without dom0
having a mechanism to revoke the grant.

Other than that, are there any other concerns, e.g. from
security POV?

  (There was work looking into
this in the past, but it suffered from a lack of free time.)

~Andrew

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

Thank you,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] PV drivers and zero copying

2017-07-31 Thread Oleksandr Andrushchenko

Hi, Paul!


On 07/31/2017 12:03 PM, Paul Durrant wrote:

-Original Message-

[snip]

Comparison for display use-case
===

1 Number of grant references used
1-1 grant references: nr_pages
1-2 GNTTABOP_transfer: nr_pages
1-3 XENMEM_exchange: not an option

2 Effect of DomU crash on Dom0 (its mapped pages)
2-1 grant references: pages can be unmapped by Dom0, Dom0 is fully
recovered
2-2 GNTTABOP_transfer: pages will be returned to the Hypervisor, lost
for Dom0
2-3 XENMEM_exchange: not an option

3 Security issues from sharing Dom0 pages to DomU
1-1 grant references: none
1-2 GNTTABOP_transfer: none
1-3 XENMEM_exchange: not an option

At the moment approach 1 with granted references seems to be a winner for
sharing buffers both ways, e.g. Dom0 -> DomU and DomU -> Dom0.

Conclusion
==

I would like to get some feedback from the community on which approach
is more
suitable for sharing large buffers and to have a clear vision on cons
and pros
of each one: please feel free to add other metrics I missed and correct
the ones
I commented on.  I would appreciate help on comparing approaches 2 and 3
as I
have little knowledge of these APIs (2 seems to be addressed by
Christopher, and
3 seems to be relevant to what Konrad/Stefano do WRT SWIOTLB).


Hi,

   I once implemented a scheme where network frontends used memory granted from 
backends and this hit quite a few problems:

- If domU is allowed to grant map memory from dom0, there is not currently a 
way to forcibly take it back (so I don't think you're quite correct in 2-1 
above... but I may have missed something).

This is where I was not 100% confident, so you seem to be right here.

  Hence the domU can hold dom0's memory to ransom.

Yes, this is the problem

  (In the network case this was avoided by using grant table v2 'copy-only' 
grants).
- If you end up having to grant buffers which do not originate in dom0 (i.e. 
they were grant mapped from another domU) then this creates similar problems 
with one domU holding another domU's memory to ransom, even when using 
copy-only grants. I don’t think this would be an issue in your use-case.
In our use-cases we will only share from Dom0 to DomU in case Dom0 is 
1:1 mapped

Otherwise, HW should be capable of dealing with non-contiguous memory

- Currently the default grant table size is 32 pages and it may not take that 
many guests using a protocol where dom0 grants memory to domU to exhaust dom0's 
grant table

Yes, I know about this limitation, thank you

  (depending on how many grants-per-domU the protocol allows). If you're 
intending to grant large buffers then you may need quite a few grants (since 
they are per-4k-chunk) to do this, so you might run into this limit.

   Cheers,

 Paul

Thank you for comments,
so in both cases (with grant refs or memory transfer) there is no way to 
cleanly
recover from DomU crash (either grants cannot be returned or memory goes 
to the

hypervisor, not Dom0).
Is this correct?

Thank you,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] PV drivers and zero copying

2017-07-31 Thread Oleksandr Andrushchenko

Hi, all!

The aim of this mail is to highlight and discuss possible approaches to
implementing zero copying for PV drivers. Rationale behind this is that 
there
are use-cases when drivers operate with big shared buffers, e.g. 
display, when

memory copying from front’s buffer into back’s one may significantly hit
performance of the system (for example, for para-virtual display running 
at full

HD resolution at 60Hz it is approximately 475MB/sec).

Assumptions (which actually fit ARM platforms, but can be extended to other
platforms as well): Dom0 is a 1:1 mapped privileged domain, runs backend
driver/software DomU is an unprivileged domain without 1:1 memory 
mapping, runs

frontend driver

Buffer origin: while implementing zero copying the buffer allocation can 
happen

either on DomU’s end or Dom0’s one depending on the use-case and HW
capabilities/availability: When DomU allocates: It cannot guarantee physical
memory continuity of the buffers allocated Dom0’s HW *can* handle 
non-contiguous
memory buffers allocated by DomU for memory operations (DMA, for 
example), e.g.
either with IOMMU help or by any other means (HW block’s own MMU).  When 
Dom0

allocates as it is mapped 1:1 it can allocate physically contiguous memory
Dom0’s HW *cannot* handle non-contiguous memory buffers allocated by 
DomU for

memory operations by any means.

1 Sharing with granted references
==

1-1 Buffer allocated @DomU
--
@DomU
alloc_xenballooned_pages(nr_pages, pages);
cur_ref = gnttab_claim_grant_reference(&priv_gref_head);
gnttab_grant_foreign_access_ref(cur_ref, otherend_id, ...);

@Dom0
alloc_xenballooned_pages(nr_pages, pages);
gnttab_set_map_op(&map_ops[i], addr, GNTMAP_host_map | 
GNTMAP_device_map,

grefs[i], otherend_id);
gnttab_map_refs(map_ops, NULL, pages, nr_pages);

1-2 Buffer allocated @Dom0
--
@Dom0

dma_alloc_wc(dev, size, &dev_addr, GFP_KERNEL | __GFP_NOWARN);
HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
cur_ref = gnttab_claim_grant_reference(&priv_gref_head);
gnttab_grant_foreign_access_ref(cur_ref, otherend_id, ...);

@Dom0
alloc_xenballooned_pages(nr_pages, pages);
gnttab_set_map_op(&map_ops[i], addr, GNTMAP_host_map, grefs[i], 
otherend_id);

gnttab_map_refs(map_ops, NULL, pages, nr_pages);

2 Sharing with page transfers (GNTTABOP_transfer)
==
FIXME: This use-case seems to be only needed while allocating physically
contiguous buffers at Dom0. For the reverse path 1-1 method can be used.

This approach relies on GNTTABOP_transfer API: “transfer  to a 
foreign

domain. The foreign domain has previously registered its interest in the
transfer via ”, for full documentation see [1]. The process of
transferring pages is explained by Christopher Clark at [2] and is 
available as
implementation at [3], [4]. The relevant logic is in: 
xen/common/grant_table.c :

gnttab_transfer.

Basic workflow explained to me by Christopher:
- The mfn starts as owned by the sending domain, and that domain removes any
  mappings of it from its page tables. Xen will enforce that the 
reference count

must be low enough for the transfer to succeed.
- The receiving domain indicates interest for receiving a page by writing an
  entry in its grant table.
- You'll need to communicate the grant ref from the receiver to the 
sender (eg.

  via xenstore or another existing channel)
- The sending domain invokes the hypercall, with the grant ref from the
  receiving domain.
- The sending domain notifies the receiving domain somehow that the 
transfer has

  completed. (eg. send an event or via xenstore)
- Once the transfer has completed, the receiving domain will need to map the
  newly assigned page.
- Note: For the transfer, the receiving domain must have enough headroom to
  receive the new page, which means it must not have allocated all of 
its memory
quota already prior to the transfer. Typically this can be ensured by 
freeing

enough memory back to Xen before writing the grant ref.

3 Sharing with page exchange (XENMEM_exchange)
==

This API was pointed to me by Stefano Stabellini as one of the possible 
ways to
achieve zero copying and share physically contiguous buffers. It is used 
by x86
SWIOTLB code (xen_create_contiguous_region, [5]), but as per my 
understanding
this API cannot be used on ARM as of now [6].  Conclusion: not an option 
for ARM

at the moment

Comparison for display use-case
===

1 Number of grant references used
1-1 grant references: nr_pages
1-2 GNTTABOP_transfer: nr_pages
1-3 XENMEM_exchange: not an option

2 Effect of DomU crash on Dom0 (its mapped pages)
2-1 grant references: pages can be unmapped by Dom0, Dom0 is fully 
recovered
2-2 GNTTABOP_transfer: pages will be returned to the Hypervisor, lost 
for Dom0

2-3 XENMEM

Re: [Xen-devel] [PATCH v4 00/13] libxl: add PV display device driver interface

2017-07-27 Thread Oleksandr Andrushchenko

ping


On 07/18/2017 05:25 PM, Oleksandr Grytsov wrote:

From: Oleksandr Grytsov 

Changes since V3:
   * libxl__device_add renamed to libxl__device_add_async and reworked
 to match the former design;
   * libxl__device_add used for devices which don't require updating domain
 config but simple write to Xen Store (9pfs, vkb, vfb);
   * following devices are changed to use the libxl__device_add:
 9pfs, vkb, vfb, nic, vtpm. Other device (console, pci, usb, disk) have
 very different adding pattern and required to unreasonable extend
 libxl__device_add_async and its parameters;
   * disk device list changed to use libxl__device_list;
   * previous comments are applied.

Patches on github [1].

[1] https://github.com/al1img/xen/tree/xl-vdispl-v4

Oleksandr Grytsov (13):
   libxl: add generic function to add device
   libxl: add generic functions to get and free device list
   libxl: add vdispl device
   xl: add PV display device commands
   docs: add PV display driver information
   libxl: change p9 to use generec add function
   libxl: change vkb to use generec add function
   libxl: change vfb to use generec add function
   libxl: change disk to use generic getting list functions
   libxl: change nic to use generec add function
   libxl: change vtpm to use generec add function
   libxl: remove unneeded DEVICE_ADD macro
   libxl: make pci and usb setdefault function generic

  docs/man/xl.cfg.pod.5.in  |  49 ++
  docs/man/xl.pod.1.in  |  42 +
  tools/libxl/Makefile  |   2 +-
  tools/libxl/libxl.h   |  54 +--
  tools/libxl/libxl_9pfs.c  |  67 +++-
  tools/libxl/libxl_checkpoint_device.c |  16 +-
  tools/libxl/libxl_colo_save.c |   4 +-
  tools/libxl/libxl_console.c   | 153 --
  tools/libxl/libxl_create.c|  17 +-
  tools/libxl/libxl_device.c| 262 ++
  tools/libxl/libxl_disk.c  | 101 
  tools/libxl/libxl_dm.c|  10 +-
  tools/libxl/libxl_internal.h  | 126 ++-
  tools/libxl/libxl_nic.c   | 212 +
  tools/libxl/libxl_pci.c   |  10 +-
  tools/libxl/libxl_types.idl   |  40 -
  tools/libxl/libxl_types_internal.idl  |   1 +
  tools/libxl/libxl_usb.c   |  21 ++-
  tools/libxl/libxl_utils.h |   4 +
  tools/libxl/libxl_vdispl.c| 289 ++
  tools/libxl/libxl_vtpm.c  | 229 ---
  tools/ocaml/libs/xl/xenlight_stubs.c  |   6 +-
  tools/xl/Makefile |   1 +
  tools/xl/xl.h |   3 +
  tools/xl/xl_block.c   |   3 +-
  tools/xl/xl_cmdtable.c|  19 +++
  tools/xl/xl_nic.c |   3 +-
  tools/xl/xl_parse.c   |  79 +-
  tools/xl/xl_parse.h   |   2 +-
  tools/xl/xl_vdispl.c  | 163 +++
  tools/xl/xl_vtpm.c|   3 +-
  31 files changed, 1293 insertions(+), 698 deletions(-)
  create mode 100644 tools/libxl/libxl_vdispl.c
  create mode 100644 tools/xl/xl_vdispl.c




___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] Next Xen ARM community call - Wednesday 2nd August 2017

2017-07-27 Thread Oleksandr Andrushchenko

Works for EPAM as well


On 07/27/2017 12:12 AM, Edgar E. Iglesias wrote:
Hi, this time works for me too. I'd like to have a slot to introduce 
and discuss the work that Xilinx and Aggios are doing on Power 
management for Xen/Arm.


Cheers,
Edgar

Sent from my phone

On Jul 26, 2017 6:59 PM, "Stefano Stabellini" > wrote:


On Wed, 26 Jul 2017, Julien Grall wrote:
> Hi all,
>
> The next Xen ARM community call will be Wednesday 2nd August
2017 5pm BST.
>
> Do you have any specific topic you would like to discuss?

These date and time work for me. I don't have any specific topics to
discuss.


> Call +44 1223 406065  (Local dial in)
> and enter the access code below followed by # key.
> Participant code: 4915191
>
> Mobile Auto Dial:
> VoIP: voip://+441223406065 ;4915191#
> iOS devices: +44 1223 406065
,4915191 and press #
> Other devices: +44 1223 406065x4915191
#
>
> Additional Calling Information:
>
> UK +44 1142828002 
> US CA +1 4085761502 
> US TX +1 5123141073 
> JP +81 453455355 
> DE +49 8945604050 
> NO +47 73187518 
> SE +46 46313131 
> FR +33 497235101 
> TW +886 35657119
> HU +36 13275600
> IE +353 91337900
>
> Toll Free
>
> UK 0800 1412084
> US +1 8668801148
> CN +86 4006782367
> IN 0008009868365
> IN +918049282778
> TW 08000 22065
> HU 0680981587
> IE 1800800022
> KF +972732558877

___
Xen-devel mailing list
Xen-devel@lists.xen.org 
https://lists.xen.org/xen-devel 



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [XenSummit 2017] Build tools follow up

2017-07-17 Thread Oleksandr Andrushchenko

Hi, all!

This is a follow-up on Xen distribution build systems we saw at the
summit and invitation for sharing thoughts and ways we build our images and
distros. I would like to specifically ask OpenXT project to reply with the
description of their build system so we have clear picture of what is being
developed and used around. And of course if there are other approaches 
to do the

same you are welcome to share those as well.

On our side at EPAM we have developed a distribution which is called 
xt-distro

(xt stays for Xen troops [0]) with the following goals in mind:
1. Make it possible to easily build different images as a single 
distribution

   - Separate images for different domains should be combined into a
 distribution, e.g. set of images/artifacts required to run them as a
 system
   - Xt-distro allows doing so as easy as running bitbake with the 
predefined

 target, e.g. “bitbake xt-image”
2. Easily deal with different BSPs for different platforms using a 
unified way

   with little or no EPAM specific code/scripts
   - We use bitbake and stripped version of Poky/meta-openembedded, so 
there are
 little in-house extensions we added to deal with Yocto based BSPs 
[1], [2]
   - We use bitbake’s well defined scripting language [3], so no yet 
another

 language to learn
   - We use Google repo tool to maintain sets of meta layers as 
manifest files [4]

3. Ability to easily collect component revisions, so any build can be
   reproduced if need be
   - We save commit IDs of every component of the build including 
versions of the

 meta layers
4. Ability to easily customize and tune builds, e.g. URIs, 
versions/commitIDs,

   branches used
   - This is purely done in bitbake’s recipe language
5. Make patching process easy
   - With our extensions you can use bblayers.conf, local.conf, patches 
which

 are part of a meta layer which is usually a manual step
6. Code reuse is a must, e.g. the same set of software must be easily 
built for
   different platforms without copying build scripts of the existing 
components
   - With bitbake’s meta layers we define generic recipes, e.g. 
suitable for all

 platforms [5] (think of it as a library) and tuning meta layers [6]
 (we use product concept here) which define specific 
versions/revisions of the

 components, apply specific patches and add/remove software
7. Cross compilation must be an easy task to do
   - This is easily achieved with Yocto builds and usually not a 
problem for other

 build systems as well (with SDKs)
   - Allows building for x86/ARM and other architectures as well
8. There must be a simple way to share build artifacts of different 
domains between
   each other, for example, DomU’s kernel should be a part of Dom0’s 
rootfs, so

   xl/libxl can access it
   - This is achieved with bitbake’s recipes, so no EPAM extensions
9. Possibility to easily use different build systems for different 
components of

   the system.
   - Bitbake allows you building makefile based projects, CMake etc. 
out of the box,

 so adding firmware, stubdoms made easy
10. Development support
   - We use SDKs built by bitbake so during everyday development you 
are packed with
 all that is needed to re-create build environment (with both host 
and target

 environments, e.g. x86 host tools and ARM cross-compiler)
   - Speed up builds for developers within organization, e.g. we reuse 
downloads and

 build cache between all of the developer’s machines on our network
11. Make the build system suitable for build automation
- We have created a python script which can easily be used with
  Jenkins or even cron [7]

For example, with xt-distro our development product delivers: Xen image and
policy file, Dom0 kernel and dtb images (Dom0 + DomU), Dom0 rootfs image 
(with

embedded kernels and configuration for DomU), DomU rootfs image. This
effectively means, that the build system can provide you with the 
complete set

of images to run your product/distribution.

We are looking forward for any kind of feedback and will be glad to 
collaborate

on the above.

Thank you,
Xen-troops at EPAM

[0] https://github.com/xen-troops/xt-distro
[1] https://git.yoctoproject.org/cgit/cgit.cgi/poky
[2] http://cgit.openembedded.org/meta-openembedded
[3] 
http://www.yoctoproject.org/docs/2.3/bitbake-user-manual/bitbake-user-manual.html

[4] https://gerrit.googlesource.com/git-repo
[5] https://github.com/xen-troops/meta-xt-images
[6] https://github.com/xen-troops/meta-xt-prod-devel
[7] https://github.com/xen-troops/build-scripts


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH] kbdif: Define "feature-raw-pointer" and "request-raw-pointer"

2017-07-03 Thread Oleksandr Andrushchenko

Hi, Owen!

On 07/03/2017 03:57 PM, Owen Smith wrote:

determine the difference between older
backends and newer backends. In the case I'm interested in, the difference
between old QEMU vkbd backend which blocks waiting for the vfb device, which
is not present on HVM guests, and a newer QEMU backend

For how long will it remain "new" and what will be the
next patch for yet another new backend?
So, in addition to your patch I would suggest we add backend
type and its version to get the information you need and rely
on that deterministically, not making indirect decisions on
if the pointer is raw for new backend only.
Please see [1] where backend "type" entry was discussed.

BTW, we are working on decoupling QEMU's vkbd from vfb
as it is required for vkbd to work with vdispl, not vfb,
so from having type and version we will also benefit.

Thank you,
Oleksandr

[1] https://patchwork.kernel.org/patch/9674807/

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v1] xen/input: add multi-touch support

2017-06-30 Thread Oleksandr Andrushchenko

Hi, Dmitry!

On 06/29/2017 10:24 PM, Dmitry Torokhov wrote:

On June 29, 2017 11:40:30 AM PDT, Oleksandr Andrushchenko  
wrote:

Hi, Dmitry!

First of all thank you for both the comments and the patch

On 06/29/2017 11:17 AM, Dmitry Torokhov wrote:

Hi Oleksandr,

On Fri, Jun 23, 2017 at 09:09:55AM +0300, Oleksandr Andrushchenko

wrote:

+   switch (event->mtouch.event_type) {
+   case XENKBD_MT_EV_DOWN:
+   input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+  true);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+   event->mtouch.u.pos.abs_y);
+   input_event(dev, EV_ABS, ABS_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_Y,
+   event->mtouch.u.pos.abs_y);

I was looking at this and realized that this breaks the single touch
emulation for MT interface: for ST you are supposed to report the

oldest

contact, here you report data for all of them. Luckily
input_mt_report_pointer_emulation() that is called as part of
input_mt_sync_frame() reports the correct ABS_X/ABS_Y data and fixes
that for you.

We should simply remove reporting ABS_X/ABS_Y here and in
XENKBD_MT_EV_MOTION as well.


+
+   input_set_capability(mtouch, EV_KEY, BTN_TOUCH);
+   input_set_abs_params(mtouch, ABS_X,
+0, width, 0, 0);
+   input_set_abs_params(mtouch, ABS_Y,
+0, height, 0, 0);
+   input_set_abs_params(mtouch, ABS_PRESSURE,
+0, 255, 0, 0);

This is done automatically by input_mt_init_slots() when called with
INPUT_MT_DIRECT (as in your case) or INPUT_MT_POINTER, so this can be
removed as well.

Great, I was not actually convinced that ABS is really needed
to be put here while dealing with MT devices,
so the above can be removed

Does the patch below (on top of yours) work for you?

Unfortunately I didn't have time to test the patch today, but will try
to do so tomorrow.

Beside that, do you think that the removals above should go into my
patch
and the rest of yours (it looks like needed refactoring to me) should
go
into
a separate one, not named "MT support fixups", but rather "Xen input
driver refactoring"? Because part of the changes seems to be MT
relevant
and part is pure refactoring.
If so, do you want me to rework your patch with these changes and add
on
top of mine (I will put your signed off) or you will handle it on your
own?

I was planning on simply folding my changes into your patch and calling it a 
day, unless your testing would show there is an issue.

I found no issue with the patches, but I have only tested that
on ARM with our new kbd/ptr/mt backend [1]. I am not able to test that
on x86 unfortunately, thus cannot confirm QEMU's backend is ok as well.
What will be the next steps on my side to get MT in?

  It wasn't intended to be a separate patch in it's own right, I simply sent it 
out this way to show what exactly I was changing.


Thanks.


Thank you,
Oleksandr

[1] https://github.com/xen-troops/displ_be

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v1] xen/input: add multi-touch support

2017-06-29 Thread Oleksandr Andrushchenko

Hi, Dmitry!

First of all thank you for both the comments and the patch

On 06/29/2017 11:17 AM, Dmitry Torokhov wrote:

Hi Oleksandr,

On Fri, Jun 23, 2017 at 09:09:55AM +0300, Oleksandr Andrushchenko wrote:

+   switch (event->mtouch.event_type) {
+   case XENKBD_MT_EV_DOWN:
+   input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+  true);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+   event->mtouch.u.pos.abs_y);
+   input_event(dev, EV_ABS, ABS_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_Y,
+   event->mtouch.u.pos.abs_y);

I was looking at this and realized that this breaks the single touch
emulation for MT interface: for ST you are supposed to report the oldest
contact, here you report data for all of them. Luckily
input_mt_report_pointer_emulation() that is called as part of
input_mt_sync_frame() reports the correct ABS_X/ABS_Y data and fixes
that for you.

We should simply remove reporting ABS_X/ABS_Y here and in
XENKBD_MT_EV_MOTION as well.


+
+   input_set_capability(mtouch, EV_KEY, BTN_TOUCH);
+   input_set_abs_params(mtouch, ABS_X,
+0, width, 0, 0);
+   input_set_abs_params(mtouch, ABS_Y,
+0, height, 0, 0);
+   input_set_abs_params(mtouch, ABS_PRESSURE,
+0, 255, 0, 0);

This is done automatically by input_mt_init_slots() when called with
INPUT_MT_DIRECT (as in your case) or INPUT_MT_POINTER, so this can be
removed as well.

Great, I was not actually convinced that ABS is really needed
to be put here while dealing with MT devices,
so the above can be removed

Does the patch below (on top of yours) work for you?

Unfortunately I didn't have time to test the patch today, but will try
to do so tomorrow.

Beside that, do you think that the removals above should go into my patch
and the rest of yours (it looks like needed refactoring to me) should go 
into

a separate one, not named "MT support fixups", but rather "Xen input
driver refactoring"? Because part of the changes seems to be MT relevant
and part is pure refactoring.
If so, do you want me to rework your patch with these changes and add on
top of mine (I will put your signed off) or you will handle it on your own?

Thanks.


Thank you,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH v1] xen/input: add multi-touch support

2017-06-28 Thread Oleksandr Andrushchenko

ping

On 06/23/2017 09:09 AM, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

Extend xen_kbdfront to provide multi-touch support
to unprivileged domains.

Signed-off-by: Oleksandr Andrushchenko 

---
Changes since initial:
  - use input_set_capability instead of setting flags directly
  - input_mt_init_slots: let userspace better chance of figuring
how to handle the device: use INPUT_MT_DIRECT,
drop INPUT_MT_DROP_UNUSED
  - add error handling for input_mt_init_slots
  - remove module paramters
  - remove odd unlikely
---
  drivers/input/misc/xen-kbdfront.c | 135 +-
  1 file changed, 133 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c
index eb770613a9bd..9fa005038773 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  
  #include 

@@ -34,11 +35,14 @@
  struct xenkbd_info {
struct input_dev *kbd;
struct input_dev *ptr;
+   struct input_dev *mtouch;
struct xenkbd_page *page;
int gref;
int irq;
struct xenbus_device *xbdev;
char phys[32];
+   /* current MT slot/contact ID we are injecting events in */
+   int mtouch_cur_contact_id;
  };
  
  enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };

@@ -100,6 +104,60 @@ static irqreturn_t input_handler(int rq, void *dev_id)
input_report_rel(dev, REL_WHEEL,
 -event->pos.rel_z);
break;
+   case XENKBD_TYPE_MTOUCH:
+   dev = info->mtouch;
+   if (unlikely(!dev))
+   break;
+   if (event->mtouch.contact_id !=
+   info->mtouch_cur_contact_id) {
+   info->mtouch_cur_contact_id =
+   event->mtouch.contact_id;
+   input_mt_slot(dev, event->mtouch.contact_id);
+   }
+   switch (event->mtouch.event_type) {
+   case XENKBD_MT_EV_DOWN:
+   input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+  true);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+   event->mtouch.u.pos.abs_y);
+   input_event(dev, EV_ABS, ABS_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_Y,
+   event->mtouch.u.pos.abs_y);
+   break;
+   case XENKBD_MT_EV_UP:
+   input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+  false);
+   break;
+   case XENKBD_MT_EV_MOTION:
+   input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+   event->mtouch.u.pos.abs_y);
+   input_event(dev, EV_ABS, ABS_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_Y,
+   event->mtouch.u.pos.abs_y);
+   break;
+   case XENKBD_MT_EV_SYN:
+   input_mt_sync_frame(dev);
+   break;
+   case XENKBD_MT_EV_SHAPE:
+   input_event(dev, EV_ABS, ABS_MT_TOUCH_MAJOR,
+   event->mtouch.u.shape.major);
+   input_event(dev, EV_ABS, ABS_MT_TOUCH_MINOR,
+   event->mtouch.u.shape.minor);
+   break;
+   case XENKBD_MT_EV_ORIENT:
+   input_event(dev, EV_ABS, ABS_MT_ORIENTATION,
+   event->mtouch.u.orientation);
+   break;
+   }
+   /* only report syn when requested */
+   if (event->mtouch.event_type != XENKBD_MT_EV_SYN)
+   dev = NULL;
}
   

Re: [Xen-devel] [For 4.9] Updating https://wiki.xenproject.org/wiki/Xen_Project_Release_Features to reflect support status of new features

2017-06-27 Thread Oleksandr Andrushchenko

On 06/27/2017 04:30 PM, Lars Kurth wrote:

Removing security@

On 27/06/2017, 14:28, "Oleksandr Andrushchenko"  wrote:


Did I miss anything?


Please consider adding new topics:
1. Shared coprocessor framework
2. Native applications, e.g. EL0 app, stubdoms

I am only adding committed stuff: these are 4.10 items
Lars

Ah, sorry about messing things up

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [For 4.9] Updating https://wiki.xenproject.org/wiki/Xen_Project_Release_Features to reflect support status of new features

2017-06-27 Thread Oleksandr Andrushchenko



Did I miss anything?


Please consider adding new topics:
1. Shared coprocessor framework
2. Native applications, e.g. EL0 app, stubdoms

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [For 4.9] Updating https://wiki.xenproject.org/wiki/Xen_Project_Release_Features to reflect support status of new features

2017-06-27 Thread Oleksandr Andrushchenko

Hi, all


New Heading:  PV Protocols and Drivers
- PV Protocols and Drivers > pvcalls : tech preview or experimental
- PV Protocols and Drivers > 9pfs : tech preview or experimental
- PV Protocols and Drivers* > sndif (sound device) : tech preview or 
experimental
- PV Protocols and Drivers* > displif (PV display) : tech preview or 
experimental



Let me update on PV development EPAM does (everything is
publicly available at the links below, primary source is [1]):

1. Multi-touch:
1.1. Protocol changes are already in both Kernel and Xen
1.2. Front-end support for multi-touch is on review, hope
it will be merged soon [2]
1.3. Backend support is part of our user-space display backend [3]

2. Sound
2.1. Protocol is already in both Kernel and Xen
2.2. We have a user-space backend [4], need to get it ready for upstreaming
2.3. Frontend is available at [6], need to get it ready for upstreaming

3. Display
2.1. Protocol is already in both Kernel and Xen
2.2. We have a user-space backend [3], need to get it ready for upstreaming
2.3. Frontend is available at [6], need to get it ready for upstreaming
2.4. DRM zero copy driver is available at [6], need to get it ready
for upstreaming

4. libxl/xl changes
We are working on adding support for mtouch/display/sound into libxl/xl
4.1. Display changes, patches on review [5]
4.2. Mtouch and sound are in progress, no patches yet

[1] https://github.com/xen-troops
[2] https://patchwork.kernel.org/patch/9805741/
[3] https://github.com/xen-troops/displ_be
[4] https://github.com/al1img/snd_be
[5] https://www.mail-archive.com/xen-devel@lists.xen.org/msg112690.html
[6] https://github.com/xen-troops/linux/tree/vgpu-dev

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v1] xen/input: add multi-touch support

2017-06-22 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Extend xen_kbdfront to provide multi-touch support
to unprivileged domains.

Signed-off-by: Oleksandr Andrushchenko 

---
Changes since initial:
 - use input_set_capability instead of setting flags directly
 - input_mt_init_slots: let userspace better chance of figuring
   how to handle the device: use INPUT_MT_DIRECT,
   drop INPUT_MT_DROP_UNUSED
 - add error handling for input_mt_init_slots
 - remove module paramters
 - remove odd unlikely
---
 drivers/input/misc/xen-kbdfront.c | 135 +-
 1 file changed, 133 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c
index eb770613a9bd..9fa005038773 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -34,11 +35,14 @@
 struct xenkbd_info {
struct input_dev *kbd;
struct input_dev *ptr;
+   struct input_dev *mtouch;
struct xenkbd_page *page;
int gref;
int irq;
struct xenbus_device *xbdev;
char phys[32];
+   /* current MT slot/contact ID we are injecting events in */
+   int mtouch_cur_contact_id;
 };
 
 enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
@@ -100,6 +104,60 @@ static irqreturn_t input_handler(int rq, void *dev_id)
input_report_rel(dev, REL_WHEEL,
 -event->pos.rel_z);
break;
+   case XENKBD_TYPE_MTOUCH:
+   dev = info->mtouch;
+   if (unlikely(!dev))
+   break;
+   if (event->mtouch.contact_id !=
+   info->mtouch_cur_contact_id) {
+   info->mtouch_cur_contact_id =
+   event->mtouch.contact_id;
+   input_mt_slot(dev, event->mtouch.contact_id);
+   }
+   switch (event->mtouch.event_type) {
+   case XENKBD_MT_EV_DOWN:
+   input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+  true);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+   event->mtouch.u.pos.abs_y);
+   input_event(dev, EV_ABS, ABS_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_Y,
+   event->mtouch.u.pos.abs_y);
+   break;
+   case XENKBD_MT_EV_UP:
+   input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+  false);
+   break;
+   case XENKBD_MT_EV_MOTION:
+   input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+   event->mtouch.u.pos.abs_y);
+   input_event(dev, EV_ABS, ABS_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_Y,
+   event->mtouch.u.pos.abs_y);
+   break;
+   case XENKBD_MT_EV_SYN:
+   input_mt_sync_frame(dev);
+   break;
+   case XENKBD_MT_EV_SHAPE:
+   input_event(dev, EV_ABS, ABS_MT_TOUCH_MAJOR,
+   event->mtouch.u.shape.major);
+   input_event(dev, EV_ABS, ABS_MT_TOUCH_MINOR,
+   event->mtouch.u.shape.minor);
+   break;
+   case XENKBD_MT_EV_ORIENT:
+   input_event(dev, EV_ABS, ABS_MT_ORIENTATION,
+   event->mtouch.u.orientation);
+   break;
+   }
+   /* only report syn when requested */
+   if (event->mtouch.event_type != XENKBD_MT_EV_SYN)
+   dev = NULL;
}
if (dev)
input_sync(dev);
@@ -115,9

Re: [Xen-devel] [PATCH 2/2] xen/input: add multi-touch support

2017-06-21 Thread Oleksandr Andrushchenko

Hi, Dmitry!

On 06/21/2017 10:24 AM, Dmitry Torokhov wrote:

On Thu, Jun 08, 2017 at 09:45:18AM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 06/07/2017 07:56 PM, Dmitry Torokhov wrote:

On Wed, May 31, 2017 at 12:06:56PM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 05/30/2017 07:37 PM, Dmitry Torokhov wrote:

On Tue, May 30, 2017 at 03:50:20PM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 05/30/2017 08:51 AM, Dmitry Torokhov wrote:

On Fri, Apr 21, 2017 at 09:40:36AM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 04/21/2017 05:10 AM, Dmitry Torokhov wrote:

Hi Oleksandr,

On Thu, Apr 13, 2017 at 02:38:04PM +0300, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

Extend xen_kbdfront to provide multi-touch support
to unprivileged domains.

Signed-off-by: Oleksandr Andrushchenko 
---
  drivers/input/misc/xen-kbdfront.c | 142 +-
  1 file changed, 140 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c
index 01c27b4c3288..e5d064aaa237 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
@@ -34,11 +35,14 @@
  struct xenkbd_info {
struct input_dev *kbd;
struct input_dev *ptr;
+   struct input_dev *mtouch;
struct xenkbd_page *page;
int gref;
int irq;
struct xenbus_device *xbdev;
char phys[32];
+   /* current MT slot/contact ID we are injecting events in */
+   int mtouch_cur_contact_id;
  };
  enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
@@ -47,6 +51,12 @@ module_param_array(ptr_size, int, NULL, 0444);
  MODULE_PARM_DESC(ptr_size,
"Pointing device width, height in pixels (default 800,600)");
+enum { KPARAM_MT_X, KPARAM_MT_Y, KPARAM_MT_CNT };
+static int mtouch_size[KPARAM_MT_CNT] = { XENFB_WIDTH, XENFB_HEIGHT };
+module_param_array(mtouch_size, int, NULL, 0444);
+MODULE_PARM_DESC(ptr_size,
+   "Multi-touch device width, height in pixels (default 800,600)");
+

Why do you need separate module parameters for multi-touch device?

please see below

  static int xenkbd_remove(struct xenbus_device *);
  static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info 
*);
  static void xenkbd_disconnect_backend(struct xenkbd_info *);
@@ -100,6 +110,60 @@ static irqreturn_t input_handler(int rq, void *dev_id)
input_report_rel(dev, REL_WHEEL,
 -event->pos.rel_z);
break;
+   case XENKBD_TYPE_MTOUCH:
+   dev = info->mtouch;
+   if (unlikely(!dev))
+   break;
+   if (unlikely(event->mtouch.contact_id !=
+   info->mtouch_cur_contact_id)) {

Why is this unlikely? Does contact ID changes once in 1000 packets or
even less?

Mu assumption was that regardless of the fact that we are multi-touch
device still single touches will come in more frequently
But I can remove *unlikely* if my assumption is not correct

I think the normal expectation is that "unlikely" is supposed for
something that happens once in a blue moon, so I'd rather remove it.


agree, removed "unlikely"

+   info->mtouch_cur_contact_id =
+   event->mtouch.contact_id;
+   input_mt_slot(dev, event->mtouch.contact_id);
+   }
+   switch (event->mtouch.event_type) {
+   case XENKBD_MT_EV_DOWN:
+   input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+  true);

Should we establish tool event? We have MT_TOOL_PEN, etc.

I think that for multi-touch MT_TOOL_FINGER is enough
any reason we would also want MT_TOOL_PEN here?

Why would not you? Let's say you have a drawing application running in
guest that can make use of tool types. Why would not you want to tell it
that the tool user is currently using is in fact a pen and not finger?

But it is a finger :) we are multi-touch, not multi pen

So for tablets that support both touch and stylus you would export them
as 2 separate devices?

this could be done in different ways, but please see on
pen support below

Besides, that, if I am about to implement pen support
(which I still not convinced we really need), how will I
do that?

I do not know what you have on the backend side, but roughly speaking if
you detect a pen/stylus you let your guest know that the contact is not
a finger, but pen. How you plumb it through is up to you.

we do not detect pen, only finger at the moment
and the existing protocol has no means to tell
type of

Re: [Xen-devel] [PATCH 2/2] xen/input: add multi-touch support

2017-06-19 Thread Oleksandr Andrushchenko

Ping

On 06/08/2017 09:45 AM, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 06/07/2017 07:56 PM, Dmitry Torokhov wrote:

On Wed, May 31, 2017 at 12:06:56PM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 05/30/2017 07:37 PM, Dmitry Torokhov wrote:
On Tue, May 30, 2017 at 03:50:20PM +0300, Oleksandr Andrushchenko 
wrote:

Hi, Dmitry!

On 05/30/2017 08:51 AM, Dmitry Torokhov wrote:
On Fri, Apr 21, 2017 at 09:40:36AM +0300, Oleksandr Andrushchenko 
wrote:

Hi, Dmitry!

On 04/21/2017 05:10 AM, Dmitry Torokhov wrote:

Hi Oleksandr,

On Thu, Apr 13, 2017 at 02:38:04PM +0300, Oleksandr 
Andrushchenko wrote:

From: Oleksandr Andrushchenko 

Extend xen_kbdfront to provide multi-touch support
to unprivileged domains.

Signed-off-by: Oleksandr Andrushchenko 


---
  drivers/input/misc/xen-kbdfront.c | 142 
+-

  1 file changed, 140 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c

index 01c27b4c3288..e5d064aaa237 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
@@ -34,11 +35,14 @@
  struct xenkbd_info {
  struct input_dev *kbd;
  struct input_dev *ptr;
+struct input_dev *mtouch;
  struct xenkbd_page *page;
  int gref;
  int irq;
  struct xenbus_device *xbdev;
  char phys[32];
+/* current MT slot/contact ID we are injecting events in */
+int mtouch_cur_contact_id;
  };
  enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
@@ -47,6 +51,12 @@ module_param_array(ptr_size, int, NULL, 0444);
  MODULE_PARM_DESC(ptr_size,
  "Pointing device width, height in pixels (default 
800,600)");

+enum { KPARAM_MT_X, KPARAM_MT_Y, KPARAM_MT_CNT };
+static int mtouch_size[KPARAM_MT_CNT] = { XENFB_WIDTH, 
XENFB_HEIGHT };

+module_param_array(mtouch_size, int, NULL, 0444);
+MODULE_PARM_DESC(ptr_size,
+"Multi-touch device width, height in pixels (default 
800,600)");

+

Why do you need separate module parameters for multi-touch device?

please see below

  static int xenkbd_remove(struct xenbus_device *);
  static int xenkbd_connect_backend(struct xenbus_device *, 
struct xenkbd_info *);

  static void xenkbd_disconnect_backend(struct xenkbd_info *);
@@ -100,6 +110,60 @@ static irqreturn_t input_handler(int rq, 
void *dev_id)

  input_report_rel(dev, REL_WHEEL,
   -event->pos.rel_z);
  break;
+case XENKBD_TYPE_MTOUCH:
+dev = info->mtouch;
+if (unlikely(!dev))
+break;
+if (unlikely(event->mtouch.contact_id !=
+ info->mtouch_cur_contact_id)) {
Why is this unlikely? Does contact ID changes once in 1000 
packets or

even less?
Mu assumption was that regardless of the fact that we are 
multi-touch

device still single touches will come in more frequently
But I can remove *unlikely* if my assumption is not correct

I think the normal expectation is that "unlikely" is supposed for
something that happens once in a blue moon, so I'd rather remove it.


agree, removed "unlikely"

+ info->mtouch_cur_contact_id =
+event->mtouch.contact_id;
+input_mt_slot(dev, event->mtouch.contact_id);
+}
+switch (event->mtouch.event_type) {
+case XENKBD_MT_EV_DOWN:
+input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+   true);

Should we establish tool event? We have MT_TOOL_PEN, etc.

I think that for multi-touch MT_TOOL_FINGER is enough
any reason we would also want MT_TOOL_PEN here?

Why would not you? Let's say you have a drawing application running in
guest that can make use of tool types. Why would not you want to 
tell it

that the tool user is currently using is in fact a pen and not finger?

But it is a finger :) we are multi-touch, not multi pen

So for tablets that support both touch and stylus you would export them
as 2 separate devices?

this could be done in different ways, but please see on
pen support below

Besides, that, if I am about to implement pen support
(which I still not convinced we really need), how will I
do that?

I do not know what you have on the backend side, but roughly speaking if
you detect a pen/stylus you let your guest know that the contact is not
a finger, but pen. How you plumb it through is up to you.

we do not detect pen, only finger at the moment
and the existing protocol has no means to tell
type of the tool used, everything is supposed to
be "finger", so front-end has no possibility to
tell one tool from another

My understanding is that I need 2 different slots to report
the same coordinates for finger and pen. This is because
input_mt_report_slot_state has a check that if tool has
changed for the current slot then a new tracking ID is set.

Re: [Xen-devel] [PATCH] kbdif.h: Introduce feature-vkbd-standalone

2017-06-14 Thread Oleksandr Andrushchenko

Hi, Owen!

On 06/13/2017 05:59 PM, Owen Smith wrote:


Hi Oleksandr,

The reason I’m proposing the additional feature flag is to 
differentiate between


older, broken, backends that will not connect without the vfb device

(qemu-upstream’s implementation in hw/display/xenfb.c) and fixed backends

(like patches I’ve posted to fix the qemu backend). Without a 
differentiator,


a frontend I’ve developed will get stuck waiting for the backend to 
connect,


and under Windows this effectively hangs the system.


I do understand your intention, but this way we are about to solve
particular problem of a particular implementation.
IMO, protocol is something that does not dictate how a backend
or frontend should be implemented. Neither if some particular
implementation has bugs then provide a way those can be worked around.


The Qemu backend should be fixed to make the vkbd and vfb independent

devices.


That is my point, if back/front are broken then we should fix those,
not help via protocol changes to work around. What will be the next
change if some other back/front steps in?


This proposal will help detect an incompatible backend and avoid a

VM hang.

(frontend WIP: 
http://xenbits.xen.org/gitweb/?p=pvdrivers/win/xenvkbd.git;a=tree)


Owen


Anyway, I would like to hear from Konrad on this


*From: *Oleksandr Andrushchenko <mailto:andr2...@gmail.com>
*Sent: *12 June 2017 08:07
*To: *Owen Smith <mailto:owen.sm...@citrix.com>; 
xen-de...@lists.xenproject.org <mailto:xen-de...@lists.xenproject.org>
*Subject: *Re: [Xen-devel] [PATCH] kbdif.h: Introduce 
feature-vkbd-standalone


Hi, Owen!

On 06/08/2017 04:09 PM, Owen Smith wrote:
> Backends set "feature-vkbd-standalone" to 1 if they can connect
> without waiting for the PV framebuffer. If this value is missing
> or not 1, then a backend will wait for the PV framebuffer before
> connecting, potentially causing the frontend to wait indefinitely.
This means that by the new option we *fix an existing
backend* and its particular behavior. What is more,
we introduce knowledge of virtual fb into generic virtual
kbd/ptr protocol which seems to be not correct (IMO).
For the reasons above, I would recommend fixing the
corresponding backend instead, for example by configuring
it appropriately wrt use-case you have.
> Frontends set "request-vkbd-standalone" to 1 to request that the
> backend does not wait for the PV framebuffer. Frontends that
> require a standalone vkbd device should not attempt to connect
> unless the backend advertises "feature-vkbd-standalone", and
> should set "request-vkbd-standalone".
Again, this looks very use-case specific
> Backends that are standalone (i.e. do not have an associated PV
> framebuffer) do not rescale absolute mouse or touch coordinates
> to a the size of the (non-existant) PV framebuffer, and use the
> range of [0, 0x7fff] for absolute values.
>
> Signed-off-by: Owen Smith 
> ---
>   xen/include/public/io/kbdif.h | 15 +++
>   1 file changed, 15 insertions(+)
>
> diff --git a/xen/include/public/io/kbdif.h 
b/xen/include/public/io/kbdif.h

> index dcbd71a..ca09080 100644
> --- a/xen/include/public/io/kbdif.h
> +++ b/xen/include/public/io/kbdif.h
> @@ -63,6 +63,12 @@
>*  Backends, which support reporting of multi-touch events
>*  should set this to 1.
>*
> + * feature-vkbd-standalone
> + *  Values: 
> + *
> + *  Backends, which support a standalone vkbd, without 
requiring a vfb

> + *  device, should set this to 1.
> + *
>*- Pointer Device Parameters 


>*
>* width
> @@ -98,6 +104,13 @@
>*
>*  Request backend to report multi-touch events.
>*
> + * request-vkbd-standalone
> + *  Values: 
> + *
> + *  Request backend to connect vkbd device without waiting for the
> + *  vfb device. Any absolute coordinates will NOT be scaled to
> + *  screen size, and will remain in the range [0, 0x7fff]
> + *
>*--- Request Transport Parameters 
---

>*
>* event-channel
> @@ -165,8 +178,10 @@
>
>   #define XENKBD_FIELD_FEAT_ABS_POINTER "feature-abs-pointer"
>   #define XENKBD_FIELD_FEAT_MTOUCH "feature-multi-touch"
> +#define XENKBD_FIELD_FEAT_STANDALONE "feature-vkbd-standalone"
>   #define XENKBD_FIELD_REQ_ABS_POINTER "request-abs-pointer"
>   #define XENKBD_FIELD_REQ_MTOUCH "request-multi-touch"
> +#define XENKBD_FIELD_REQ_STANDALONE "request-vkbd-standalone"
>   #define XENKBD_FIELD_RING_GREF "page-gref"
>   #define XENKBD_FIELD_EVT_CHANNEL "event-channel"
>   #define XENKBD_FIELD_WIDTH "width"
Thank you,
Oleksandr

Thank you,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH] kbdif.h: Introduce feature-vkbd-standalone

2017-06-12 Thread Oleksandr Andrushchenko

Hi, Owen!

On 06/08/2017 04:09 PM, Owen Smith wrote:

Backends set "feature-vkbd-standalone" to 1 if they can connect
without waiting for the PV framebuffer. If this value is missing
or not 1, then a backend will wait for the PV framebuffer before
connecting, potentially causing the frontend to wait indefinitely.

This means that by the new option we *fix an existing
backend* and its particular behavior. What is more,
we introduce knowledge of virtual fb into generic virtual
kbd/ptr protocol which seems to be not correct (IMO).
For the reasons above, I would recommend fixing the
corresponding backend instead, for example by configuring
it appropriately wrt use-case you have.

Frontends set "request-vkbd-standalone" to 1 to request that the
backend does not wait for the PV framebuffer. Frontends that
require a standalone vkbd device should not attempt to connect
unless the backend advertises "feature-vkbd-standalone", and
should set "request-vkbd-standalone".

Again, this looks very use-case specific

Backends that are standalone (i.e. do not have an associated PV
framebuffer) do not rescale absolute mouse or touch coordinates
to a the size of the (non-existant) PV framebuffer, and use the
range of [0, 0x7fff] for absolute values.

Signed-off-by: Owen Smith 
---
  xen/include/public/io/kbdif.h | 15 +++
  1 file changed, 15 insertions(+)

diff --git a/xen/include/public/io/kbdif.h b/xen/include/public/io/kbdif.h
index dcbd71a..ca09080 100644
--- a/xen/include/public/io/kbdif.h
+++ b/xen/include/public/io/kbdif.h
@@ -63,6 +63,12 @@
   *  Backends, which support reporting of multi-touch events
   *  should set this to 1.
   *
+ * feature-vkbd-standalone
+ *  Values: 
+ *
+ *  Backends, which support a standalone vkbd, without requiring a vfb
+ *  device, should set this to 1.
+ *
   *- Pointer Device Parameters 
   *
   * width
@@ -98,6 +104,13 @@
   *
   *  Request backend to report multi-touch events.
   *
+ * request-vkbd-standalone
+ *  Values: 
+ *
+ *  Request backend to connect vkbd device without waiting for the
+ *  vfb device. Any absolute coordinates will NOT be scaled to
+ *  screen size, and will remain in the range [0, 0x7fff]
+ *
   *--- Request Transport Parameters ---
   *
   * event-channel
@@ -165,8 +178,10 @@
  
  #define XENKBD_FIELD_FEAT_ABS_POINTER  "feature-abs-pointer"

  #define XENKBD_FIELD_FEAT_MTOUCH   "feature-multi-touch"
+#define XENKBD_FIELD_FEAT_STANDALONE   "feature-vkbd-standalone"
  #define XENKBD_FIELD_REQ_ABS_POINTER   "request-abs-pointer"
  #define XENKBD_FIELD_REQ_MTOUCH"request-multi-touch"
+#define XENKBD_FIELD_REQ_STANDALONE"request-vkbd-standalone"
  #define XENKBD_FIELD_RING_GREF "page-gref"
  #define XENKBD_FIELD_EVT_CHANNEL   "event-channel"
  #define XENKBD_FIELD_WIDTH "width"

Thank you,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 2/2] xen/input: add multi-touch support

2017-06-07 Thread Oleksandr Andrushchenko

Hi, Dmitry!

On 06/07/2017 07:56 PM, Dmitry Torokhov wrote:

On Wed, May 31, 2017 at 12:06:56PM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 05/30/2017 07:37 PM, Dmitry Torokhov wrote:

On Tue, May 30, 2017 at 03:50:20PM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 05/30/2017 08:51 AM, Dmitry Torokhov wrote:

On Fri, Apr 21, 2017 at 09:40:36AM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 04/21/2017 05:10 AM, Dmitry Torokhov wrote:

Hi Oleksandr,

On Thu, Apr 13, 2017 at 02:38:04PM +0300, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

Extend xen_kbdfront to provide multi-touch support
to unprivileged domains.

Signed-off-by: Oleksandr Andrushchenko 
---
  drivers/input/misc/xen-kbdfront.c | 142 +-
  1 file changed, 140 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c
index 01c27b4c3288..e5d064aaa237 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
@@ -34,11 +35,14 @@
  struct xenkbd_info {
struct input_dev *kbd;
struct input_dev *ptr;
+   struct input_dev *mtouch;
struct xenkbd_page *page;
int gref;
int irq;
struct xenbus_device *xbdev;
char phys[32];
+   /* current MT slot/contact ID we are injecting events in */
+   int mtouch_cur_contact_id;
  };
  enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
@@ -47,6 +51,12 @@ module_param_array(ptr_size, int, NULL, 0444);
  MODULE_PARM_DESC(ptr_size,
"Pointing device width, height in pixels (default 800,600)");
+enum { KPARAM_MT_X, KPARAM_MT_Y, KPARAM_MT_CNT };
+static int mtouch_size[KPARAM_MT_CNT] = { XENFB_WIDTH, XENFB_HEIGHT };
+module_param_array(mtouch_size, int, NULL, 0444);
+MODULE_PARM_DESC(ptr_size,
+   "Multi-touch device width, height in pixels (default 800,600)");
+

Why do you need separate module parameters for multi-touch device?

please see below

  static int xenkbd_remove(struct xenbus_device *);
  static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info 
*);
  static void xenkbd_disconnect_backend(struct xenkbd_info *);
@@ -100,6 +110,60 @@ static irqreturn_t input_handler(int rq, void *dev_id)
input_report_rel(dev, REL_WHEEL,
 -event->pos.rel_z);
break;
+   case XENKBD_TYPE_MTOUCH:
+   dev = info->mtouch;
+   if (unlikely(!dev))
+   break;
+   if (unlikely(event->mtouch.contact_id !=
+   info->mtouch_cur_contact_id)) {

Why is this unlikely? Does contact ID changes once in 1000 packets or
even less?

Mu assumption was that regardless of the fact that we are multi-touch
device still single touches will come in more frequently
But I can remove *unlikely* if my assumption is not correct

I think the normal expectation is that "unlikely" is supposed for
something that happens once in a blue moon, so I'd rather remove it.


agree, removed "unlikely"

+   info->mtouch_cur_contact_id =
+   event->mtouch.contact_id;
+   input_mt_slot(dev, event->mtouch.contact_id);
+   }
+   switch (event->mtouch.event_type) {
+   case XENKBD_MT_EV_DOWN:
+   input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+  true);

Should we establish tool event? We have MT_TOOL_PEN, etc.

I think that for multi-touch MT_TOOL_FINGER is enough
any reason we would also want MT_TOOL_PEN here?

Why would not you? Let's say you have a drawing application running in
guest that can make use of tool types. Why would not you want to tell it
that the tool user is currently using is in fact a pen and not finger?

But it is a finger :) we are multi-touch, not multi pen

So for tablets that support both touch and stylus you would export them
as 2 separate devices?

this could be done in different ways, but please see on
pen support below

Besides, that, if I am about to implement pen support
(which I still not convinced we really need), how will I
do that?

I do not know what you have on the backend side, but roughly speaking if
you detect a pen/stylus you let your guest know that the contact is not
a finger, but pen. How you plumb it through is up to you.

we do not detect pen, only finger at the moment
and the existing protocol has no means to tell
type of the tool used, everything is supposed to
be "finger", so front-end has no possibility to
tell one tool from another

My understa

Re: [Xen-devel] [PATCH 2/2] xen/input: add multi-touch support

2017-06-07 Thread Oleksandr Andrushchenko

Hi, Dmitry!

I would appreciate your comments on the below

On 05/31/2017 12:06 PM, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 05/30/2017 07:37 PM, Dmitry Torokhov wrote:

On Tue, May 30, 2017 at 03:50:20PM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 05/30/2017 08:51 AM, Dmitry Torokhov wrote:
On Fri, Apr 21, 2017 at 09:40:36AM +0300, Oleksandr Andrushchenko 
wrote:

Hi, Dmitry!

On 04/21/2017 05:10 AM, Dmitry Torokhov wrote:

Hi Oleksandr,

On Thu, Apr 13, 2017 at 02:38:04PM +0300, Oleksandr Andrushchenko 
wrote:

From: Oleksandr Andrushchenko 

Extend xen_kbdfront to provide multi-touch support
to unprivileged domains.

Signed-off-by: Oleksandr Andrushchenko 


---
  drivers/input/misc/xen-kbdfront.c | 142 
+-

  1 file changed, 140 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c

index 01c27b4c3288..e5d064aaa237 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
@@ -34,11 +35,14 @@
  struct xenkbd_info {
  struct input_dev *kbd;
  struct input_dev *ptr;
+struct input_dev *mtouch;
  struct xenkbd_page *page;
  int gref;
  int irq;
  struct xenbus_device *xbdev;
  char phys[32];
+/* current MT slot/contact ID we are injecting events in */
+int mtouch_cur_contact_id;
  };
  enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
@@ -47,6 +51,12 @@ module_param_array(ptr_size, int, NULL, 0444);
  MODULE_PARM_DESC(ptr_size,
  "Pointing device width, height in pixels (default 800,600)");
+enum { KPARAM_MT_X, KPARAM_MT_Y, KPARAM_MT_CNT };
+static int mtouch_size[KPARAM_MT_CNT] = { XENFB_WIDTH, 
XENFB_HEIGHT };

+module_param_array(mtouch_size, int, NULL, 0444);
+MODULE_PARM_DESC(ptr_size,
+"Multi-touch device width, height in pixels (default 
800,600)");

+

Why do you need separate module parameters for multi-touch device?

please see below

  static int xenkbd_remove(struct xenbus_device *);
  static int xenkbd_connect_backend(struct xenbus_device *, 
struct xenkbd_info *);

  static void xenkbd_disconnect_backend(struct xenkbd_info *);
@@ -100,6 +110,60 @@ static irqreturn_t input_handler(int rq, 
void *dev_id)

  input_report_rel(dev, REL_WHEEL,
   -event->pos.rel_z);
  break;
+case XENKBD_TYPE_MTOUCH:
+dev = info->mtouch;
+if (unlikely(!dev))
+break;
+if (unlikely(event->mtouch.contact_id !=
+info->mtouch_cur_contact_id)) {
Why is this unlikely? Does contact ID changes once in 1000 
packets or

even less?

Mu assumption was that regardless of the fact that we are multi-touch
device still single touches will come in more frequently
But I can remove *unlikely* if my assumption is not correct

I think the normal expectation is that "unlikely" is supposed for
something that happens once in a blue moon, so I'd rather remove it.


agree, removed "unlikely"

+ info->mtouch_cur_contact_id =
+event->mtouch.contact_id;
+input_mt_slot(dev, event->mtouch.contact_id);
+}
+switch (event->mtouch.event_type) {
+case XENKBD_MT_EV_DOWN:
+input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+   true);

Should we establish tool event? We have MT_TOOL_PEN, etc.

I think that for multi-touch MT_TOOL_FINGER is enough
any reason we would also want MT_TOOL_PEN here?

Why would not you? Let's say you have a drawing application running in
guest that can make use of tool types. Why would not you want to tell it
that the tool user is currently using is in fact a pen and not finger?

But it is a finger :) we are multi-touch, not multi pen

Besides, that, if I am about to implement pen support
(which I still not convinced we really need), how will I
do that?
My understanding is that I need 2 different slots to report
the same coordinates for finger and pen. This is because
input_mt_report_slot_state has a check that if tool has
changed for the current slot then a new tracking ID is set.
Do I also need to allocate twice more slots, so I can
report 2 * num_contacts events simultaneously (one for finger
and another for pen)?
That said, I believe we can start with multi-touch support
and if need be then add pen support as a separate change,
does that make sense for you?



(I guess MT_TOOL_PALM is not appropriate anyways)

Depends on if you do straight pass-through from the host side or not. If
you stack does palm rejection before passing the data through then you
would not see MT_TOOL_PALM in guest.

the protocol used between guest and host is a generic one,
not using Linux types/constants/events.
So, no PALM/TOOL support is in place

Re: [Xen-devel] [PATCH 2/2] xen/input: add multi-touch support

2017-05-31 Thread Oleksandr Andrushchenko

Hi, Dmitry!

On 05/30/2017 07:37 PM, Dmitry Torokhov wrote:

On Tue, May 30, 2017 at 03:50:20PM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 05/30/2017 08:51 AM, Dmitry Torokhov wrote:

On Fri, Apr 21, 2017 at 09:40:36AM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 04/21/2017 05:10 AM, Dmitry Torokhov wrote:

Hi Oleksandr,

On Thu, Apr 13, 2017 at 02:38:04PM +0300, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

Extend xen_kbdfront to provide multi-touch support
to unprivileged domains.

Signed-off-by: Oleksandr Andrushchenko 
---
  drivers/input/misc/xen-kbdfront.c | 142 +-
  1 file changed, 140 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c
index 01c27b4c3288..e5d064aaa237 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
@@ -34,11 +35,14 @@
  struct xenkbd_info {
struct input_dev *kbd;
struct input_dev *ptr;
+   struct input_dev *mtouch;
struct xenkbd_page *page;
int gref;
int irq;
struct xenbus_device *xbdev;
char phys[32];
+   /* current MT slot/contact ID we are injecting events in */
+   int mtouch_cur_contact_id;
  };
  enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
@@ -47,6 +51,12 @@ module_param_array(ptr_size, int, NULL, 0444);
  MODULE_PARM_DESC(ptr_size,
"Pointing device width, height in pixels (default 800,600)");
+enum { KPARAM_MT_X, KPARAM_MT_Y, KPARAM_MT_CNT };
+static int mtouch_size[KPARAM_MT_CNT] = { XENFB_WIDTH, XENFB_HEIGHT };
+module_param_array(mtouch_size, int, NULL, 0444);
+MODULE_PARM_DESC(ptr_size,
+   "Multi-touch device width, height in pixels (default 800,600)");
+

Why do you need separate module parameters for multi-touch device?

please see below

  static int xenkbd_remove(struct xenbus_device *);
  static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info 
*);
  static void xenkbd_disconnect_backend(struct xenkbd_info *);
@@ -100,6 +110,60 @@ static irqreturn_t input_handler(int rq, void *dev_id)
input_report_rel(dev, REL_WHEEL,
 -event->pos.rel_z);
break;
+   case XENKBD_TYPE_MTOUCH:
+   dev = info->mtouch;
+   if (unlikely(!dev))
+   break;
+   if (unlikely(event->mtouch.contact_id !=
+   info->mtouch_cur_contact_id)) {

Why is this unlikely? Does contact ID changes once in 1000 packets or
even less?

Mu assumption was that regardless of the fact that we are multi-touch
device still single touches will come in more frequently
But I can remove *unlikely* if my assumption is not correct

I think the normal expectation is that "unlikely" is supposed for
something that happens once in a blue moon, so I'd rather remove it.


agree, removed "unlikely"

+   info->mtouch_cur_contact_id =
+   event->mtouch.contact_id;
+   input_mt_slot(dev, event->mtouch.contact_id);
+   }
+   switch (event->mtouch.event_type) {
+   case XENKBD_MT_EV_DOWN:
+   input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+  true);

Should we establish tool event? We have MT_TOOL_PEN, etc.

I think that for multi-touch MT_TOOL_FINGER is enough
any reason we would also want MT_TOOL_PEN here?

Why would not you? Let's say you have a drawing application running in
guest that can make use of tool types. Why would not you want to tell it
that the tool user is currently using is in fact a pen and not finger?

But it is a finger :) we are multi-touch, not multi pen

Besides, that, if I am about to implement pen support
(which I still not convinced we really need), how will I
do that?
My understanding is that I need 2 different slots to report
the same coordinates for finger and pen. This is because
input_mt_report_slot_state has a check that if tool has
changed for the current slot then a new tracking ID is set.
Do I also need to allocate twice more slots, so I can
report 2 * num_contacts events simultaneously (one for finger
and another for pen)?
That said, I believe we can start with multi-touch support
and if need be then add pen support as a separate change,
does that make sense for you?



(I guess MT_TOOL_PALM is not appropriate anyways)

Depends on if you do straight pass-through from the host side or not. If
you stack does palm rejection before passing the data through then you
would not see MT_TOOL_PALM in gu

Re: [Xen-devel] [PATCH 2/2] xen/input: add multi-touch support

2017-05-30 Thread Oleksandr Andrushchenko

Hi, Dmitry!

On 05/30/2017 08:51 AM, Dmitry Torokhov wrote:

On Fri, Apr 21, 2017 at 09:40:36AM +0300, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 04/21/2017 05:10 AM, Dmitry Torokhov wrote:

Hi Oleksandr,

On Thu, Apr 13, 2017 at 02:38:04PM +0300, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

Extend xen_kbdfront to provide multi-touch support
to unprivileged domains.

Signed-off-by: Oleksandr Andrushchenko 
---
  drivers/input/misc/xen-kbdfront.c | 142 +-
  1 file changed, 140 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c
index 01c27b4c3288..e5d064aaa237 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
@@ -34,11 +35,14 @@
  struct xenkbd_info {
struct input_dev *kbd;
struct input_dev *ptr;
+   struct input_dev *mtouch;
struct xenkbd_page *page;
int gref;
int irq;
struct xenbus_device *xbdev;
char phys[32];
+   /* current MT slot/contact ID we are injecting events in */
+   int mtouch_cur_contact_id;
  };
  enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
@@ -47,6 +51,12 @@ module_param_array(ptr_size, int, NULL, 0444);
  MODULE_PARM_DESC(ptr_size,
"Pointing device width, height in pixels (default 800,600)");
+enum { KPARAM_MT_X, KPARAM_MT_Y, KPARAM_MT_CNT };
+static int mtouch_size[KPARAM_MT_CNT] = { XENFB_WIDTH, XENFB_HEIGHT };
+module_param_array(mtouch_size, int, NULL, 0444);
+MODULE_PARM_DESC(ptr_size,
+   "Multi-touch device width, height in pixels (default 800,600)");
+

Why do you need separate module parameters for multi-touch device?

please see below

  static int xenkbd_remove(struct xenbus_device *);
  static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info 
*);
  static void xenkbd_disconnect_backend(struct xenkbd_info *);
@@ -100,6 +110,60 @@ static irqreturn_t input_handler(int rq, void *dev_id)
input_report_rel(dev, REL_WHEEL,
 -event->pos.rel_z);
break;
+   case XENKBD_TYPE_MTOUCH:
+   dev = info->mtouch;
+   if (unlikely(!dev))
+   break;
+   if (unlikely(event->mtouch.contact_id !=
+   info->mtouch_cur_contact_id)) {

Why is this unlikely? Does contact ID changes once in 1000 packets or
even less?

Mu assumption was that regardless of the fact that we are multi-touch
device still single touches will come in more frequently
But I can remove *unlikely* if my assumption is not correct

I think the normal expectation is that "unlikely" is supposed for
something that happens once in a blue moon, so I'd rather remove it.


agree, removed "unlikely"

+   info->mtouch_cur_contact_id =
+   event->mtouch.contact_id;
+   input_mt_slot(dev, event->mtouch.contact_id);
+   }
+   switch (event->mtouch.event_type) {
+   case XENKBD_MT_EV_DOWN:
+   input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+  true);

Should we establish tool event? We have MT_TOOL_PEN, etc.

I think that for multi-touch MT_TOOL_FINGER is enough
any reason we would also want MT_TOOL_PEN here?
(I guess MT_TOOL_PALM is not appropriate anyways)

+   input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+   event->mtouch.u.pos.abs_y);
+   input_event(dev, EV_ABS, ABS_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_Y,
+   event->mtouch.u.pos.abs_y);
+   break;
+   case XENKBD_MT_EV_UP:
+   input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+  false);
+   break;
+   case XENKBD_MT_EV_MOTION:
+   input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+   event->mtouch.u.pos.abs_x);
+   input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+   event->mtouch.u.pos.abs_y);
+ 

Re: [Xen-devel] [PATCH 1/2] xen/input: use string constants from PV protocol

2017-05-30 Thread Oleksandr Andrushchenko

Hi, Dmitry!

On 04/21/2017 05:11 AM, Dmitry Torokhov wrote:

On Thu, Apr 13, 2017 at 02:38:03PM +0300, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

Xen input para-virtual protocol defines string constants
used by both back and frontend. Use those instead of
explicit strings in the frontend driver.

Signed-off-by: Oleksandr Andrushchenko 

I'll have to postpone it until I receive changes containing these new
string constants. Otherwise it looks OK.

May I put your "Reviewed-by" for this change?



---
  drivers/input/misc/xen-kbdfront.c | 22 +-
  1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c
index 2fc7895373ab..01c27b4c3288 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -135,14 +135,17 @@ static int xenkbd_probe(struct xenbus_device *dev,
goto error_nomem;
  
  	/* Set input abs params to match backend screen res */

-   abs = xenbus_read_unsigned(dev->otherend, "feature-abs-pointer", 0);
-   ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend, "width",
+   abs = xenbus_read_unsigned(dev->otherend,
+  XENKBD_FIELD_FEAT_ABS_POINTER, 0);
+   ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend,
+ XENKBD_FIELD_WIDTH,
  ptr_size[KPARAM_X]);
-   ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend, "height",
+   ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend,
+ XENKBD_FIELD_HEIGHT,
  ptr_size[KPARAM_Y]);
if (abs) {
ret = xenbus_write(XBT_NIL, dev->nodename,
-  "request-abs-pointer", "1");
+  XENKBD_FIELD_REQ_ABS_POINTER, "1");
if (ret) {
pr_warning("xenkbd: can't request abs-pointer");
abs = 0;
@@ -271,14 +274,15 @@ static int xenkbd_connect_backend(struct xenbus_device 
*dev,
xenbus_dev_fatal(dev, ret, "starting transaction");
goto error_irqh;
}
-   ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
+   ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_REF, "%lu",
virt_to_gfn(info->page));
if (ret)
goto error_xenbus;
-   ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", info->gref);
+   ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_GREF,
+   "%u", info->gref);
if (ret)
goto error_xenbus;
-   ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
+   ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_EVT_CHANNEL, "%u",
evtchn);
if (ret)
goto error_xenbus;
@@ -353,7 +357,7 @@ static void xenkbd_backend_changed(struct xenbus_device 
*dev,
  }
  
  static const struct xenbus_device_id xenkbd_ids[] = {

-   { "vkbd" },
+   { XENKBD_DRIVER_NAME },
{ "" }
  };
  
@@ -390,4 +394,4 @@ module_exit(xenkbd_cleanup);
  
  MODULE_DESCRIPTION("Xen virtual keyboard/pointer device frontend");

  MODULE_LICENSE("GPL");
-MODULE_ALIAS("xen:vkbd");
+MODULE_ALIAS("xen:" XENKBD_DRIVER_NAME);
--
2.7.4


Thank you,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 2/2] xen/input: add multi-touch support

2017-05-22 Thread Oleksandr Andrushchenko

Hi, Dmitry!

It's been quite a while now, I'm just wondering if
you had a chance to look at the patch?

Thank you,
Oleksandr

On 05/12/2017 04:44 PM, Oleksandr Andrushchenko wrote:

gentle reminder


On 05/05/2017 07:45 AM, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 04/21/2017 09:40 AM, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 04/21/2017 05:10 AM, Dmitry Torokhov wrote:

Hi Oleksandr,

On Thu, Apr 13, 2017 at 02:38:04PM +0300, Oleksandr Andrushchenko 
wrote:

From: Oleksandr Andrushchenko 

Extend xen_kbdfront to provide multi-touch support
to unprivileged domains.

Signed-off-by: Oleksandr Andrushchenko 


---
  drivers/input/misc/xen-kbdfront.c | 142 
+-

  1 file changed, 140 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c

index 01c27b4c3288..e5d064aaa237 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
#include 
@@ -34,11 +35,14 @@
  struct xenkbd_info {
  struct input_dev *kbd;
  struct input_dev *ptr;
+struct input_dev *mtouch;
  struct xenkbd_page *page;
  int gref;
  int irq;
  struct xenbus_device *xbdev;
  char phys[32];
+/* current MT slot/contact ID we are injecting events in */
+int mtouch_cur_contact_id;
  };
enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
@@ -47,6 +51,12 @@ module_param_array(ptr_size, int, NULL, 0444);
  MODULE_PARM_DESC(ptr_size,
  "Pointing device width, height in pixels (default 800,600)");
  +enum { KPARAM_MT_X, KPARAM_MT_Y, KPARAM_MT_CNT };
+static int mtouch_size[KPARAM_MT_CNT] = { XENFB_WIDTH, 
XENFB_HEIGHT };

+module_param_array(mtouch_size, int, NULL, 0444);
+MODULE_PARM_DESC(ptr_size,
+"Multi-touch device width, height in pixels (default 800,600)");
+

Why do you need separate module parameters for multi-touch device?

please see below



  static int xenkbd_remove(struct xenbus_device *);
  static int xenkbd_connect_backend(struct xenbus_device *, struct 
xenkbd_info *);

  static void xenkbd_disconnect_backend(struct xenkbd_info *);
@@ -100,6 +110,60 @@ static irqreturn_t input_handler(int rq, void 
*dev_id)

  input_report_rel(dev, REL_WHEEL,
   -event->pos.rel_z);
  break;
+case XENKBD_TYPE_MTOUCH:
+dev = info->mtouch;
+if (unlikely(!dev))
+break;
+if (unlikely(event->mtouch.contact_id !=
+info->mtouch_cur_contact_id)) {

Why is this unlikely? Does contact ID changes once in 1000 packets or
even less?

Mu assumption was that regardless of the fact that we are multi-touch
device still single touches will come in more frequently
But I can remove *unlikely* if my assumption is not correct

+ info->mtouch_cur_contact_id =
+event->mtouch.contact_id;
+input_mt_slot(dev, event->mtouch.contact_id);
+}
+switch (event->mtouch.event_type) {
+case XENKBD_MT_EV_DOWN:
+input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+   true);
+input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+event->mtouch.u.pos.abs_y);
+input_event(dev, EV_ABS, ABS_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_Y,
+event->mtouch.u.pos.abs_y);
+break;
+case XENKBD_MT_EV_UP:
+input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+   false);
+break;
+case XENKBD_MT_EV_MOTION:
+input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+event->mtouch.u.pos.abs_y);
+input_event(dev, EV_ABS, ABS_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_Y,
+event->mtouch.u.pos.abs_y);
+break;
+case XENKBD_MT_EV_SYN:
+input_mt_sync_frame(dev);
+break;
+case XENKBD_MT_EV_SHAPE:
+input_event(dev, EV_ABS, ABS_MT_TOUCH_MAJOR,
+event->mtouch.u.shape.major);
+input_event(dev, EV_ABS, ABS_MT_TOUCH_MINOR,
+event->mtouch.u.shape.minor);
+break;
+case XENKBD_MT_EV_ORIENT:
+input_event(dev, EV_ABS, ABS_MT_ORIENTATION,
+event->mtouch.u.orientation)

Re: [Xen-devel] [PATCH 1/2] xen/input: use string constants from PV protocol

2017-05-22 Thread Oleksandr Andrushchenko

Hi, Dmitry!

It's been quite a while now, I'm just wondering if
you had a chance to look at the patch?

Thank you,
Oleksandr

On 05/12/2017 04:43 PM, Oleksandr Andrushchenko wrote:

gentle reminder


On 05/05/2017 07:43 AM, Oleksandr Andrushchenko wrote:

Hello, Dmitry!
On 04/21/2017 09:42 AM, Oleksandr Andrushchenko wrote:

On 04/21/2017 05:11 AM, Dmitry Torokhov wrote:
On Thu, Apr 13, 2017 at 02:38:03PM +0300, Oleksandr Andrushchenko 
wrote:

From: Oleksandr Andrushchenko 

Xen input para-virtual protocol defines string constants
used by both back and frontend. Use those instead of
explicit strings in the frontend driver.

Signed-off-by: Oleksandr Andrushchenko 


I'll have to postpone it until I receive changes containing these new
string constants.

fair enough

  Otherwise it looks OK.

thank you

As all the dependencies are now merged into the kernel,
can we please proceed with this patch?


  drivers/input/misc/xen-kbdfront.c | 22 +-
  1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c

index 2fc7895373ab..01c27b4c3288 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -135,14 +135,17 @@ static int xenkbd_probe(struct xenbus_device 
*dev,

  goto error_nomem;
/* Set input abs params to match backend screen res */
-abs = xenbus_read_unsigned(dev->otherend, 
"feature-abs-pointer", 0);
-ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend, 
"width",

+abs = xenbus_read_unsigned(dev->otherend,
+   XENKBD_FIELD_FEAT_ABS_POINTER, 0);
+ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend,
+  XENKBD_FIELD_WIDTH,
ptr_size[KPARAM_X]);
-ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend, 
"height",

+ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend,
+  XENKBD_FIELD_HEIGHT,
ptr_size[KPARAM_Y]);
  if (abs) {
  ret = xenbus_write(XBT_NIL, dev->nodename,
-   "request-abs-pointer", "1");
+   XENKBD_FIELD_REQ_ABS_POINTER, "1");
  if (ret) {
  pr_warning("xenkbd: can't request abs-pointer");
  abs = 0;
@@ -271,14 +274,15 @@ static int xenkbd_connect_backend(struct 
xenbus_device *dev,

  xenbus_dev_fatal(dev, ret, "starting transaction");
  goto error_irqh;
  }
-ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
+ret = xenbus_printf(xbt, dev->nodename, 
XENKBD_FIELD_RING_REF, "%lu",

  virt_to_gfn(info->page));
  if (ret)
  goto error_xenbus;
-ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", 
info->gref);

+ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_GREF,
+"%u", info->gref);
  if (ret)
  goto error_xenbus;
-ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
+ret = xenbus_printf(xbt, dev->nodename, 
XENKBD_FIELD_EVT_CHANNEL, "%u",

  evtchn);
  if (ret)
  goto error_xenbus;
@@ -353,7 +357,7 @@ static void xenkbd_backend_changed(struct 
xenbus_device *dev,

  }
static const struct xenbus_device_id xenkbd_ids[] = {
-{ "vkbd" },
+{ XENKBD_DRIVER_NAME },
  { "" }
  };
  @@ -390,4 +394,4 @@ module_exit(xenkbd_cleanup);
MODULE_DESCRIPTION("Xen virtual keyboard/pointer device 
frontend");

  MODULE_LICENSE("GPL");
-MODULE_ALIAS("xen:vkbd");
+MODULE_ALIAS("xen:" XENKBD_DRIVER_NAME);
--
2.7.4


Thank you,
Oleksandr

Thank you,
Oleksandr





___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 2/2] xen/input: add multi-touch support

2017-05-12 Thread Oleksandr Andrushchenko

gentle reminder


On 05/05/2017 07:45 AM, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 04/21/2017 09:40 AM, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 04/21/2017 05:10 AM, Dmitry Torokhov wrote:

Hi Oleksandr,

On Thu, Apr 13, 2017 at 02:38:04PM +0300, Oleksandr Andrushchenko 
wrote:

From: Oleksandr Andrushchenko 

Extend xen_kbdfront to provide multi-touch support
to unprivileged domains.

Signed-off-by: Oleksandr Andrushchenko 


---
  drivers/input/misc/xen-kbdfront.c | 142 
+-

  1 file changed, 140 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c

index 01c27b4c3288..e5d064aaa237 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
#include 
@@ -34,11 +35,14 @@
  struct xenkbd_info {
  struct input_dev *kbd;
  struct input_dev *ptr;
+struct input_dev *mtouch;
  struct xenkbd_page *page;
  int gref;
  int irq;
  struct xenbus_device *xbdev;
  char phys[32];
+/* current MT slot/contact ID we are injecting events in */
+int mtouch_cur_contact_id;
  };
enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
@@ -47,6 +51,12 @@ module_param_array(ptr_size, int, NULL, 0444);
  MODULE_PARM_DESC(ptr_size,
  "Pointing device width, height in pixels (default 800,600)");
  +enum { KPARAM_MT_X, KPARAM_MT_Y, KPARAM_MT_CNT };
+static int mtouch_size[KPARAM_MT_CNT] = { XENFB_WIDTH, 
XENFB_HEIGHT };

+module_param_array(mtouch_size, int, NULL, 0444);
+MODULE_PARM_DESC(ptr_size,
+"Multi-touch device width, height in pixels (default 800,600)");
+

Why do you need separate module parameters for multi-touch device?

please see below



  static int xenkbd_remove(struct xenbus_device *);
  static int xenkbd_connect_backend(struct xenbus_device *, struct 
xenkbd_info *);

  static void xenkbd_disconnect_backend(struct xenkbd_info *);
@@ -100,6 +110,60 @@ static irqreturn_t input_handler(int rq, void 
*dev_id)

  input_report_rel(dev, REL_WHEEL,
   -event->pos.rel_z);
  break;
+case XENKBD_TYPE_MTOUCH:
+dev = info->mtouch;
+if (unlikely(!dev))
+break;
+if (unlikely(event->mtouch.contact_id !=
+info->mtouch_cur_contact_id)) {

Why is this unlikely? Does contact ID changes once in 1000 packets or
even less?

Mu assumption was that regardless of the fact that we are multi-touch
device still single touches will come in more frequently
But I can remove *unlikely* if my assumption is not correct

+ info->mtouch_cur_contact_id =
+event->mtouch.contact_id;
+input_mt_slot(dev, event->mtouch.contact_id);
+}
+switch (event->mtouch.event_type) {
+case XENKBD_MT_EV_DOWN:
+input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+   true);
+input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+event->mtouch.u.pos.abs_y);
+input_event(dev, EV_ABS, ABS_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_Y,
+event->mtouch.u.pos.abs_y);
+break;
+case XENKBD_MT_EV_UP:
+input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+   false);
+break;
+case XENKBD_MT_EV_MOTION:
+input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+event->mtouch.u.pos.abs_y);
+input_event(dev, EV_ABS, ABS_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_Y,
+event->mtouch.u.pos.abs_y);
+break;
+case XENKBD_MT_EV_SYN:
+input_mt_sync_frame(dev);
+break;
+case XENKBD_MT_EV_SHAPE:
+input_event(dev, EV_ABS, ABS_MT_TOUCH_MAJOR,
+event->mtouch.u.shape.major);
+input_event(dev, EV_ABS, ABS_MT_TOUCH_MINOR,
+event->mtouch.u.shape.minor);
+break;
+case XENKBD_MT_EV_ORIENT:
+input_event(dev, EV_ABS, ABS_MT_ORIENTATION,
+event->mtouch.u.orientation);
+break;
+}
+/* only report syn when requested */
+if (event->mtouch.event_type != XENKBD_MT_EV_SYN)
+dev = NULL;

Re: [Xen-devel] [PATCH 1/2] xen/input: use string constants from PV protocol

2017-05-12 Thread Oleksandr Andrushchenko

gentle reminder


On 05/05/2017 07:43 AM, Oleksandr Andrushchenko wrote:

Hello, Dmitry!
On 04/21/2017 09:42 AM, Oleksandr Andrushchenko wrote:

On 04/21/2017 05:11 AM, Dmitry Torokhov wrote:
On Thu, Apr 13, 2017 at 02:38:03PM +0300, Oleksandr Andrushchenko 
wrote:

From: Oleksandr Andrushchenko 

Xen input para-virtual protocol defines string constants
used by both back and frontend. Use those instead of
explicit strings in the frontend driver.

Signed-off-by: Oleksandr Andrushchenko 


I'll have to postpone it until I receive changes containing these new
string constants.

fair enough

  Otherwise it looks OK.

thank you

As all the dependencies are now merged into the kernel,
can we please proceed with this patch?


  drivers/input/misc/xen-kbdfront.c | 22 +-
  1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c

index 2fc7895373ab..01c27b4c3288 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -135,14 +135,17 @@ static int xenkbd_probe(struct xenbus_device 
*dev,

  goto error_nomem;
/* Set input abs params to match backend screen res */
-abs = xenbus_read_unsigned(dev->otherend, 
"feature-abs-pointer", 0);

-ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend, "width",
+abs = xenbus_read_unsigned(dev->otherend,
+   XENKBD_FIELD_FEAT_ABS_POINTER, 0);
+ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend,
+  XENKBD_FIELD_WIDTH,
ptr_size[KPARAM_X]);
-ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend, 
"height",

+ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend,
+  XENKBD_FIELD_HEIGHT,
ptr_size[KPARAM_Y]);
  if (abs) {
  ret = xenbus_write(XBT_NIL, dev->nodename,
-   "request-abs-pointer", "1");
+   XENKBD_FIELD_REQ_ABS_POINTER, "1");
  if (ret) {
  pr_warning("xenkbd: can't request abs-pointer");
  abs = 0;
@@ -271,14 +274,15 @@ static int xenkbd_connect_backend(struct 
xenbus_device *dev,

  xenbus_dev_fatal(dev, ret, "starting transaction");
  goto error_irqh;
  }
-ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
+ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_REF, 
"%lu",

  virt_to_gfn(info->page));
  if (ret)
  goto error_xenbus;
-ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", 
info->gref);

+ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_GREF,
+"%u", info->gref);
  if (ret)
  goto error_xenbus;
-ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
+ret = xenbus_printf(xbt, dev->nodename, 
XENKBD_FIELD_EVT_CHANNEL, "%u",

  evtchn);
  if (ret)
  goto error_xenbus;
@@ -353,7 +357,7 @@ static void xenkbd_backend_changed(struct 
xenbus_device *dev,

  }
static const struct xenbus_device_id xenkbd_ids[] = {
-{ "vkbd" },
+{ XENKBD_DRIVER_NAME },
  { "" }
  };
  @@ -390,4 +394,4 @@ module_exit(xenkbd_cleanup);
MODULE_DESCRIPTION("Xen virtual keyboard/pointer device 
frontend");

  MODULE_LICENSE("GPL");
-MODULE_ALIAS("xen:vkbd");
+MODULE_ALIAS("xen:" XENKBD_DRIVER_NAME);
--
2.7.4


Thank you,
Oleksandr

Thank you,
Oleksandr



___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 2/2] xen/input: add multi-touch support

2017-05-04 Thread Oleksandr Andrushchenko

Hi, Dmitry!

On 04/21/2017 09:40 AM, Oleksandr Andrushchenko wrote:

Hi, Dmitry!

On 04/21/2017 05:10 AM, Dmitry Torokhov wrote:

Hi Oleksandr,

On Thu, Apr 13, 2017 at 02:38:04PM +0300, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

Extend xen_kbdfront to provide multi-touch support
to unprivileged domains.

Signed-off-by: Oleksandr Andrushchenko 


---
  drivers/input/misc/xen-kbdfront.c | 142 
+-

  1 file changed, 140 insertions(+), 2 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c

index 01c27b4c3288..e5d064aaa237 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
#include 
@@ -34,11 +35,14 @@
  struct xenkbd_info {
  struct input_dev *kbd;
  struct input_dev *ptr;
+struct input_dev *mtouch;
  struct xenkbd_page *page;
  int gref;
  int irq;
  struct xenbus_device *xbdev;
  char phys[32];
+/* current MT slot/contact ID we are injecting events in */
+int mtouch_cur_contact_id;
  };
enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
@@ -47,6 +51,12 @@ module_param_array(ptr_size, int, NULL, 0444);
  MODULE_PARM_DESC(ptr_size,
  "Pointing device width, height in pixels (default 800,600)");
  +enum { KPARAM_MT_X, KPARAM_MT_Y, KPARAM_MT_CNT };
+static int mtouch_size[KPARAM_MT_CNT] = { XENFB_WIDTH, XENFB_HEIGHT };
+module_param_array(mtouch_size, int, NULL, 0444);
+MODULE_PARM_DESC(ptr_size,
+"Multi-touch device width, height in pixels (default 800,600)");
+

Why do you need separate module parameters for multi-touch device?

please see below



  static int xenkbd_remove(struct xenbus_device *);
  static int xenkbd_connect_backend(struct xenbus_device *, struct 
xenkbd_info *);

  static void xenkbd_disconnect_backend(struct xenkbd_info *);
@@ -100,6 +110,60 @@ static irqreturn_t input_handler(int rq, void 
*dev_id)

  input_report_rel(dev, REL_WHEEL,
   -event->pos.rel_z);
  break;
+case XENKBD_TYPE_MTOUCH:
+dev = info->mtouch;
+if (unlikely(!dev))
+break;
+if (unlikely(event->mtouch.contact_id !=
+info->mtouch_cur_contact_id)) {

Why is this unlikely? Does contact ID changes once in 1000 packets or
even less?

Mu assumption was that regardless of the fact that we are multi-touch
device still single touches will come in more frequently
But I can remove *unlikely* if my assumption is not correct

+ info->mtouch_cur_contact_id =
+event->mtouch.contact_id;
+input_mt_slot(dev, event->mtouch.contact_id);
+}
+switch (event->mtouch.event_type) {
+case XENKBD_MT_EV_DOWN:
+input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+   true);
+input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+event->mtouch.u.pos.abs_y);
+input_event(dev, EV_ABS, ABS_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_Y,
+event->mtouch.u.pos.abs_y);
+break;
+case XENKBD_MT_EV_UP:
+input_mt_report_slot_state(dev, MT_TOOL_FINGER,
+   false);
+break;
+case XENKBD_MT_EV_MOTION:
+input_event(dev, EV_ABS, ABS_MT_POSITION_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_MT_POSITION_Y,
+event->mtouch.u.pos.abs_y);
+input_event(dev, EV_ABS, ABS_X,
+event->mtouch.u.pos.abs_x);
+input_event(dev, EV_ABS, ABS_Y,
+event->mtouch.u.pos.abs_y);
+break;
+case XENKBD_MT_EV_SYN:
+input_mt_sync_frame(dev);
+break;
+case XENKBD_MT_EV_SHAPE:
+input_event(dev, EV_ABS, ABS_MT_TOUCH_MAJOR,
+event->mtouch.u.shape.major);
+input_event(dev, EV_ABS, ABS_MT_TOUCH_MINOR,
+event->mtouch.u.shape.minor);
+break;
+case XENKBD_MT_EV_ORIENT:
+input_event(dev, EV_ABS, ABS_MT_ORIENTATION,
+event->mtouch.u.orientation);
+break;
+}
+/* only report syn when requested */
+if (event->mtouch.event_type != XENKBD_MT_EV_SYN)
+dev = NULL;
  }
  if (dev)
  input_sync(dev);
@@ -115,9 +179,9 @@ sta

Re: [Xen-devel] [PATCH 1/2] xen/input: use string constants from PV protocol

2017-05-04 Thread Oleksandr Andrushchenko

Hello, Dmitry!
On 04/21/2017 09:42 AM, Oleksandr Andrushchenko wrote:

On 04/21/2017 05:11 AM, Dmitry Torokhov wrote:

On Thu, Apr 13, 2017 at 02:38:03PM +0300, Oleksandr Andrushchenko wrote:

From: Oleksandr Andrushchenko 

Xen input para-virtual protocol defines string constants
used by both back and frontend. Use those instead of
explicit strings in the frontend driver.

Signed-off-by: Oleksandr Andrushchenko 


I'll have to postpone it until I receive changes containing these new
string constants.

fair enough

  Otherwise it looks OK.

thank you

As all the dependencies are now merged into the kernel,
can we please proceed with this patch?


  drivers/input/misc/xen-kbdfront.c | 22 +-
  1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/input/misc/xen-kbdfront.c 
b/drivers/input/misc/xen-kbdfront.c

index 2fc7895373ab..01c27b4c3288 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -135,14 +135,17 @@ static int xenkbd_probe(struct xenbus_device 
*dev,

  goto error_nomem;
/* Set input abs params to match backend screen res */
-abs = xenbus_read_unsigned(dev->otherend, 
"feature-abs-pointer", 0);

-ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend, "width",
+abs = xenbus_read_unsigned(dev->otherend,
+   XENKBD_FIELD_FEAT_ABS_POINTER, 0);
+ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend,
+  XENKBD_FIELD_WIDTH,
ptr_size[KPARAM_X]);
-ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend, "height",
+ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend,
+  XENKBD_FIELD_HEIGHT,
ptr_size[KPARAM_Y]);
  if (abs) {
  ret = xenbus_write(XBT_NIL, dev->nodename,
-   "request-abs-pointer", "1");
+   XENKBD_FIELD_REQ_ABS_POINTER, "1");
  if (ret) {
  pr_warning("xenkbd: can't request abs-pointer");
  abs = 0;
@@ -271,14 +274,15 @@ static int xenkbd_connect_backend(struct 
xenbus_device *dev,

  xenbus_dev_fatal(dev, ret, "starting transaction");
  goto error_irqh;
  }
-ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
+ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_REF, 
"%lu",

  virt_to_gfn(info->page));
  if (ret)
  goto error_xenbus;
-ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", 
info->gref);

+ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_GREF,
+"%u", info->gref);
  if (ret)
  goto error_xenbus;
-ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
+ret = xenbus_printf(xbt, dev->nodename, 
XENKBD_FIELD_EVT_CHANNEL, "%u",

  evtchn);
  if (ret)
  goto error_xenbus;
@@ -353,7 +357,7 @@ static void xenkbd_backend_changed(struct 
xenbus_device *dev,

  }
static const struct xenbus_device_id xenkbd_ids[] = {
-{ "vkbd" },
+{ XENKBD_DRIVER_NAME },
  { "" }
  };
  @@ -390,4 +394,4 @@ module_exit(xenkbd_cleanup);
MODULE_DESCRIPTION("Xen virtual keyboard/pointer device frontend");
  MODULE_LICENSE("GPL");
-MODULE_ALIAS("xen:vkbd");
+MODULE_ALIAS("xen:" XENKBD_DRIVER_NAME);
--
2.7.4


Thank you,
Oleksandr

Thank you,
Oleksandr

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


Re: [Xen-devel] x86: mapping from Dom0 to DomU

2017-04-24 Thread Oleksandr Andrushchenko

On 04/24/2017 09:43 AM, Jan Beulich wrote:

On 24.04.17 at 08:10,  wrote:

On 04/21/2017 06:55 PM, Jan Beulich wrote:

On 21.04.17 at 15:04,  wrote:

I am working on a zero-copy scenario for x86
and for that I am mapping pages from Dom0 to DomU
(yes, I know there are at least security concerns).

Everything is just fine, e.g. I can map grefs from Dom0 in DomU
with gnttab_map_refs, until I try to mmap those pages in DomU
with vm_insert_page and Xen starts to complain:

(XEN) mm.c:989:d1v0 pg_owner 1 l1e_owner 1, but real_pg_owner 0
(XEN) mm.c:1061:d1v0 Error getting mfn 20675a (pfn 1ac8de) from L1 entry
80020675a027 for l1e_owner=1, pg_owner=1

Can anybody please explain why the use-case I am trying to implement
is treated as error from Xen's POV and what would be the right way to
do so?

Granted pages can be mapped only through the grant-table hypercall,

If this is gnttab_map_refs call you mean then, yes,
I do that to map grefs

see public/grant_table.h's explanation of GNTMAP_host_map used
with out without GNTMAP_contains_pte.

I know about these options and according to [1] I can use
option to map with "host virtual address", e.g. without
GNTMAP_contains_pte flag, because GNTMAP_contains_pte requires me to
provide machine address which I don't want.

   Other mapping attempts
have to be refused, or else the accounting done by the grant table
code would be undermined.

So, either I didn't understand what you mean or was not clear
to explain that I see no problem while mapping grefs with
gnttab_map_refs, but see the problem when vm_insert_page
is called to mmap the pages into user-space (vm_insert_page
internally does set_pte_at which it silently fails, but kernel
knows nothing about that because no error reported [2]).

Indeed you seem to have misunderstood: _All_ mappings of the
granted page need to be done using the grant table hypercalls,
not just the initial one. set_pte() establishes a second mapping,
and that does not use the grant table op.

Jan


thank you,
it seems like I'll have to duplicate code from gntdev [1],
so my use-case also works on x86, not only ARM

[1] http://lxr.free-electrons.com/source/drivers/xen/gntdev.c#L981

___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


  1   2   3   4   >