Pull request

v4:
  * Add PCI_EXPRESS Kconfig dependency to fix s390x in "multi-process: setup PCI
    host bridge for remote device" [Philippe and Thomas]
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAmAjprYACgkQnKSrs4Gr
 c8g8fwgAspVVcW0x2uBdrbbi2PSOtpTu+GGC8gYcvGS526WSINv+mY8QhUFPdaQO
 MErATW1FuIYuXBkvXcaIRWQGGZkfWd6AyjxjEls2jdcp1ScqJ+wnZmTDsgR8yIb3
 vOdsA03YJugrAmF4Lsdpkyq9KaWYlCUxrdPoagEopQCEETkKeEOXq40c3pxzeIBI
 75s8i28makJ8Logdvr9SBLsR7DL4mpoVQErUe2IMLGGbPSe5F49VD+b/qI20agoI
 7L8mDXqL02nc2qJL63hk2dq7pq++MWq0uDs8bbaCouxiFNrNA8zQ+flLP0VrFcP/
 gJUa92unwoKs+yVVppadBZKwjtkbYA==
 =r5oQ
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/stefanha-gitlab/tags/block-pull-request' into staging

Pull request

v4:
 * Add PCI_EXPRESS Kconfig dependency to fix s390x in "multi-process: setup PCI
   host bridge for remote device" [Philippe and Thomas]

# gpg: Signature made Wed 10 Feb 2021 09:26:14 GMT
# gpg:                using RSA key 8695A8BFD3F97CDAAC35775A9CA4ABB381AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" [full]
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>" [full]
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha-gitlab/tags/block-pull-request: (27 commits)
  docs: fix Parallels Image "dirty bitmap" section
  multi-process: perform device reset in the remote process
  multi-process: Retrieve PCI info from remote process
  multi-process: create IOHUB object to handle irq
  multi-process: Synchronize remote memory
  multi-process: PCI BAR read/write handling for proxy & remote endpoints
  multi-process: Forward PCI config space acceses to the remote process
  multi-process: add proxy communication functions
  multi-process: introduce proxy object
  multi-process: setup memory manager for remote device
  multi-process: Associate fd of a PCIDevice with its object
  multi-process: Initialize message handler in remote device
  multi-process: define MPQemuMsg format and transmission functions
  io: add qio_channel_readv_full_all_eof & qio_channel_readv_full_all helpers
  io: add qio_channel_writev_full_all helper
  multi-process: setup a machine object for remote device process
  multi-process: setup PCI host bridge for remote device
  multi-process: Add config option for multi-process QEMU
  memory: alloc RAM from file at offset
  multi-process: add configure and usage information
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-02-10 15:42:19 +00:00
commit 83339e21d0
53 changed files with 3296 additions and 70 deletions

View file

@ -0,0 +1,30 @@
/*
* PCI Host for remote device
*
* Copyright © 2018, 2021 Oracle and/or its affiliates.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#ifndef REMOTE_PCIHOST_H
#define REMOTE_PCIHOST_H
#include "exec/memory.h"
#include "hw/pci/pcie_host.h"
#define TYPE_REMOTE_PCIHOST "remote-pcihost"
OBJECT_DECLARE_SIMPLE_TYPE(RemotePCIHost, REMOTE_PCIHOST)
struct RemotePCIHost {
/*< private >*/
PCIExpressHost parent_obj;
/*< public >*/
MemoryRegion *mr_pci_mem;
MemoryRegion *mr_sys_io;
MemoryRegion *mr_sys_mem;
};
#endif

View file

@ -192,6 +192,9 @@
#define PCI_DEVICE_ID_SUN_SIMBA 0x5000
#define PCI_DEVICE_ID_SUN_SABRE 0xa000
#define PCI_VENDOR_ID_ORACLE 0x108e
#define PCI_DEVICE_ID_REMOTE_IOHUB 0xb000
#define PCI_VENDOR_ID_CMD 0x1095
#define PCI_DEVICE_ID_CMD_646 0x0646

42
include/hw/remote/iohub.h Normal file
View file

@ -0,0 +1,42 @@
/*
* IO Hub for remote device
*
* Copyright © 2018, 2021 Oracle and/or its affiliates.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#ifndef REMOTE_IOHUB_H
#define REMOTE_IOHUB_H
#include "hw/pci/pci.h"
#include "qemu/event_notifier.h"
#include "qemu/thread-posix.h"
#include "hw/remote/mpqemu-link.h"
#define REMOTE_IOHUB_NB_PIRQS PCI_DEVFN_MAX
typedef struct ResampleToken {
void *iohub;
int pirq;
} ResampleToken;
typedef struct RemoteIOHubState {
PCIDevice d;
EventNotifier irqfds[REMOTE_IOHUB_NB_PIRQS];
EventNotifier resamplefds[REMOTE_IOHUB_NB_PIRQS];
unsigned int irq_level[REMOTE_IOHUB_NB_PIRQS];
ResampleToken token[REMOTE_IOHUB_NB_PIRQS];
QemuMutex irq_level_lock[REMOTE_IOHUB_NB_PIRQS];
} RemoteIOHubState;
int remote_iohub_map_irq(PCIDevice *pci_dev, int intx);
void remote_iohub_set_irq(void *opaque, int pirq, int level);
void process_set_irqfd_msg(PCIDevice *pci_dev, MPQemuMsg *msg);
void remote_iohub_init(RemoteIOHubState *iohub);
void remote_iohub_finalize(RemoteIOHubState *iohub);
#endif

View file

@ -0,0 +1,38 @@
/*
* Remote machine configuration
*
* Copyright © 2018, 2021 Oracle and/or its affiliates.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#ifndef REMOTE_MACHINE_H
#define REMOTE_MACHINE_H
#include "qom/object.h"
#include "hw/boards.h"
#include "hw/pci-host/remote.h"
#include "io/channel.h"
#include "hw/remote/iohub.h"
struct RemoteMachineState {
MachineState parent_obj;
RemotePCIHost *host;
RemoteIOHubState iohub;
};
/* Used to pass to co-routine device and ioc. */
typedef struct RemoteCommDev {
PCIDevice *dev;
QIOChannel *ioc;
} RemoteCommDev;
#define TYPE_REMOTE_MACHINE "x-remote-machine"
OBJECT_DECLARE_SIMPLE_TYPE(RemoteMachineState, REMOTE_MACHINE)
void coroutine_fn mpqemu_remote_msg_loop_co(void *data);
#endif

View file

@ -0,0 +1,19 @@
/*
* Memory manager for remote device
*
* Copyright © 2018, 2021 Oracle and/or its affiliates.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#ifndef REMOTE_MEMORY_H
#define REMOTE_MEMORY_H
#include "exec/hwaddr.h"
#include "hw/remote/mpqemu-link.h"
void remote_sysmem_reconfig(MPQemuMsg *msg, Error **errp);
#endif

View file

@ -0,0 +1,99 @@
/*
* Communication channel between QEMU and remote device process
*
* Copyright © 2018, 2021 Oracle and/or its affiliates.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#ifndef MPQEMU_LINK_H
#define MPQEMU_LINK_H
#include "qom/object.h"
#include "qemu/thread.h"
#include "io/channel.h"
#include "exec/hwaddr.h"
#include "io/channel-socket.h"
#include "hw/remote/proxy.h"
#define REMOTE_MAX_FDS 8
#define MPQEMU_MSG_HDR_SIZE offsetof(MPQemuMsg, data.u64)
/**
* MPQemuCmd:
*
* MPQemuCmd enum type to specify the command to be executed on the remote
* device.
*
* This uses a private protocol between QEMU and the remote process. vfio-user
* protocol would supersede this in the future.
*
*/
typedef enum {
MPQEMU_CMD_SYNC_SYSMEM,
MPQEMU_CMD_RET,
MPQEMU_CMD_PCI_CFGWRITE,
MPQEMU_CMD_PCI_CFGREAD,
MPQEMU_CMD_BAR_WRITE,
MPQEMU_CMD_BAR_READ,
MPQEMU_CMD_SET_IRQFD,
MPQEMU_CMD_DEVICE_RESET,
MPQEMU_CMD_MAX,
} MPQemuCmd;
typedef struct {
hwaddr gpas[REMOTE_MAX_FDS];
uint64_t sizes[REMOTE_MAX_FDS];
off_t offsets[REMOTE_MAX_FDS];
} SyncSysmemMsg;
typedef struct {
uint32_t addr;
uint32_t val;
int len;
} PciConfDataMsg;
typedef struct {
hwaddr addr;
uint64_t val;
unsigned size;
bool memory;
} BarAccessMsg;
/**
* MPQemuMsg:
* @cmd: The remote command
* @size: Size of the data to be shared
* @data: Structured data
* @fds: File descriptors to be shared with remote device
*
* MPQemuMsg Format of the message sent to the remote device from QEMU.
*
*/
typedef struct {
int cmd;
size_t size;
union {
uint64_t u64;
PciConfDataMsg pci_conf_data;
SyncSysmemMsg sync_sysmem;
BarAccessMsg bar_access;
} data;
int fds[REMOTE_MAX_FDS];
int num_fds;
} MPQemuMsg;
bool mpqemu_msg_send(MPQemuMsg *msg, QIOChannel *ioc, Error **errp);
bool mpqemu_msg_recv(MPQemuMsg *msg, QIOChannel *ioc, Error **errp);
uint64_t mpqemu_msg_send_and_await_reply(MPQemuMsg *msg, PCIProxyDev *pdev,
Error **errp);
bool mpqemu_msg_valid(MPQemuMsg *msg);
#endif

View file

@ -0,0 +1,28 @@
/*
* Copyright © 2018, 2021 Oracle and/or its affiliates.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#ifndef PROXY_MEMORY_LISTENER_H
#define PROXY_MEMORY_LISTENER_H
#include "exec/memory.h"
#include "io/channel.h"
typedef struct ProxyMemoryListener {
MemoryListener listener;
int n_mr_sections;
MemoryRegionSection *mr_sections;
QIOChannel *ioc;
} ProxyMemoryListener;
void proxy_memory_listener_configure(ProxyMemoryListener *proxy_listener,
QIOChannel *ioc);
void proxy_memory_listener_deconfigure(ProxyMemoryListener *proxy_listener);
#endif

48
include/hw/remote/proxy.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright © 2018, 2021 Oracle and/or its affiliates.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#ifndef PROXY_H
#define PROXY_H
#include "hw/pci/pci.h"
#include "io/channel.h"
#include "hw/remote/proxy-memory-listener.h"
#include "qemu/event_notifier.h"
#define TYPE_PCI_PROXY_DEV "x-pci-proxy-dev"
OBJECT_DECLARE_SIMPLE_TYPE(PCIProxyDev, PCI_PROXY_DEV)
typedef struct ProxyMemoryRegion {
PCIProxyDev *dev;
MemoryRegion mr;
bool memory;
bool present;
uint8_t type;
} ProxyMemoryRegion;
struct PCIProxyDev {
PCIDevice parent_dev;
char *fd;
/*
* Mutex used to protect the QIOChannel fd from
* the concurrent access by the VCPUs since proxy
* blocks while awaiting for the replies from the
* process remote.
*/
QemuMutex io_mutex;
QIOChannel *ioc;
Error *migration_blocker;
ProxyMemoryListener proxy_listener;
int virq;
EventNotifier intr;
EventNotifier resample;
ProxyMemoryRegion region[PCI_NUM_REGIONS];
};
#endif /* PROXY_H */