qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: lementec fabien <fabien.lementec@gmail.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: Stefan Hajnoczi <stefanha@gmail.com>,
	Cam Macdonell <cam@cs.ualberta.ca>,
	Nick Gasson <nick@nickg.me.uk>,
	qemu-devel <qemu-devel@nongnu.org>,
	fred.konrad@greensocs.com
Subject: Re: [Qemu-devel] TCP based PCIE request forwarding
Date: Thu, 22 Nov 2012 12:26:17 +0100	[thread overview]
Message-ID: <CAAPMK-SHTRirg4zj-0NDX8XZePtKjagGdaejhKWpRCMv0ZU7Kg@mail.gmail.com> (raw)
In-Reply-To: <50ADFCC6.6070902@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1417 bytes --]

Hi,

I modified the protocol so that new message types can be
added easily. It is necessary for control related messages,
such as the hello one (I called it init). A type field has
been added to the header.

I did not include a is_reply (or is_request) field, and
prefered having 2 distinct message types. This is because
one may imagine a message type that has no reply (ie. ping ...)

Out of order reception is allowed by the use of a tag field
in request and replies. I did not included the tag in the
header, since not all the messages may need a tag. I plan
to implement this tag as a simple incrementing counter, so
made it large enough.

I did not implement these modifications yet, since I prefer
having feedbacks first. Neither did I have a look to the
the command line option parsing.

Regards,

Fabien.

2012/11/22 Paolo Bonzini <pbonzini@redhat.com>:
> Il 22/11/2012 09:19, Stefan Hajnoczi ha scritto:
>>> > usage
>>> > -----
>>> > PCIEFW devices are instanciated using the following QEMU options:
>>> > -device \
>>> >  pciefw,\
>>> >  laddr=<local_addr>,\
>>> >  lport=<local_port>,\
>>> >  raddr=<remote_addr>,\
>>> >  rport=<remote_port>
>> Take a look at qemu_socket.h:socket_parse().  It should allow you to
>> support TCP, UNIX domain sockets, and arbitrary file descriptors.
>>
>
> Even better it could just be a chardev.  socket_parse() is only used by
> the (human) monitor interface.
>
> Paolo

[-- Attachment #2: pciefw.protocol --]
[-- Type: application/octet-stream, Size: 4239 bytes --]

* rationale
-----------

PCIE access forwarding was made to implement a PCIE endpoint in a process
external to QEMU, possibly on a remote host. The main reason is to allow
interfacing QEMU with PCIE devices simulated in a third party environment.
Being an external process also has several benefits: independence from the
QEMU event loop, using compilation tools not supported by the QEMU build
system ...



* usage
-------

PCIEFW devices are instanciated using the following QEMU options:
-device \
 pciefw,\
 laddr=<local_addr>,\
 lport=<local_port>,\
 raddr=<remote_addr>,\
 rport=<remote_port>



* theory of operation
---------------------

PCIEFW is a PCIE accesses forwarding device added to the QEMU source
tree. At initialization, this device opens a bidirectionnal point to
point communication channel with an external process. This process
actually implements the PCIE endpoint. That is, a PCIE access made by
QEMU is forwarded to the process. Reciprocally, replies and accesses
messages from the process are forwarded to QEMU.



* communication protocol
------------------------

The communication assumes a reliable transport layer. Currently, a
bidirectionnal point to point TCP socket based channel is used. Byte
ordering is little endian.


** communication messages
-------------------------

A protocol message always starts with a header:

typedef struct pciefw_header
{
  uint16_t size;

#define PCIEFW_TYPE_INIT_REQ 0x00
#define PCIEFW_TYPE_INIT_REP 0x01
#define PCIEFW_TYPE_ACCESS_REQ 0x01
#define PCIEFW_TYPE_ACCESS_REP 0x02
  uint8_t type;

} __attribute__((packed)) pciefw_header_t;

Where:
. size is the total message size,
. type is the message type, one of PCIEFW_TYPE_XXX.


** initialization sequence
--------------------------

At initialization, QEMU sends an initialization message:

typedef pciefw_init_req
{
  pciefw_header_t header;
  uint8_t version;
} __attribute__((packed)) pciefw_init_req_t;

Where:
. version is used to identify the protocol version.

The process answers with a pciefw_init_rep message:

typedef pciefw_init_rep
{
  pciefw_header_t header;

#define PCIEFW_STATUS_SUCCESS 0x00
#define PCIEFW_STATUS_FAILURE 0xff
  uint8_t status;

} __attribute__((packed)) pciefw_init_rep_t;

Where:
. status if not PCIEFW_STATUS_SUCCESS, indicates the protocol is
not supported and no further communication should be attempted.


** access messages
------------------

PCIEFW initiates a request upon access from QEMU. It sends a message
whose format is described by the pciefw_access_req_t type:

typedef struct pciefw_access_req
{
#define PCIEFW_ACCESS_MAX_SIZE (offsetof(pciefw_msg_t, data) + 0x1000)

  pciefw_header_t header;
  uint32_t tag;

#define PCIEFW_OP_READ_CONFIG 0
#define PCIEFW_OP_WRITE_CONFIG 1
#define PCIEFW_OP_READ_MEM 2
#define PCIEFW_OP_WRITE_MEM 3
#define PCIEFW_OP_READ_IO 4
#define PCIEFW_OP_WRITE_IO 5
#define PCIEFW_OP_INT 6
#define PCIEFW_OP_MSI 7
#define PCIEFW_OP_MSIX 8
  uint8_t op;

  uint8_t bar;
  uint64_t addr;
  uint16_t size;
  uint8_t data[1];

} __attribute__((packed)) pciefw_access_req_t;

Where:
. tag is sent back by the reply as opaque field,
. op operation type, one of PCIEFW_OP_XXX,
. bar the PCIE BAR, in [0:5],
. addr the target address,
. size the data size in bytes,
. data is a variable length field containing the access data.

The PCIE endpoint process can initiate pciefw_access_req_t messages to
perform write operations of its own. This is used to perform data transfers
(DMA engines ...) and send interrupts.

In the case of a read operation, the PCIE endpoint process replies with
a pciefw_reply_t formatted message:

typedef struct pciefw_access_rep
{
  pciefw_header_t header;
  uint32_t tag;
  uint8_t status;
  uint8_t data[8];
} __attribute__((packed)) pciefw_access_rep_t;

Where:
. tag is the initiating access tag,
. status is the access status, one of PCIEFW_STATUS_XXX,
. data contains the replied data.



* limitations
-------------

The process acts as the server, and must be started before QEMU starts.
The QEMU event loop is blocked while awaiting for a device reply.
Read operations from the process are not supported.
The transport layer should be abstracted, allowing non TCP to be used.
MSIX are not supported.

  reply	other threads:[~2012-11-22 11:26 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-16  8:39 [Qemu-devel] TCP based PCIE request forwarding lementec fabien
2012-11-16 12:10 ` Stefan Hajnoczi
2012-11-16 13:05   ` lementec fabien
2012-11-19  8:55     ` Stefan Hajnoczi
2012-11-19 16:00       ` lementec fabien
2012-11-21 14:27       ` lementec fabien
2012-11-22  8:19         ` Stefan Hajnoczi
2012-11-22 10:08           ` lementec fabien
2012-11-22 10:21           ` Paolo Bonzini
2012-11-22 11:26             ` lementec fabien [this message]
2012-11-22 12:38             ` Stefan Hajnoczi
2012-11-20 16:41 ` Jason Baron
2012-11-21 13:13   ` lementec fabien

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAAPMK-SHTRirg4zj-0NDX8XZePtKjagGdaejhKWpRCMv0ZU7Kg@mail.gmail.com \
    --to=fabien.lementec@gmail.com \
    --cc=cam@cs.ualberta.ca \
    --cc=fred.konrad@greensocs.com \
    --cc=nick@nickg.me.uk \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).