mirror of https://github.com/xemu-project/xemu.git
Xen 2018/05/31
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJbEEeNAAoJEIlPj0hw4a6QGmcQANSCmDdD1/cU9erxOEVaTlW3 SvPvZpLUm5wJWQCBh7kkdkCQRHXz+NbnyqzVygKOK1bPi+B1dP5EO6ArGMfgZ7lw xaSE2lNk5DPWC7IAPYsiL9WV5VQuABIFgSgPQWxj/QBgjqgvzvTP0D1nxPY1pkh0 Y1Gj3TvEpth836x86YRGUqZPxTI7zqC8/bMvUExfpL8XyYltz1fdUjJBs4q1VW7h zx8uKEKP6HwT38tC2CADXjfxE+abOInlxkF44m8Im9L0XmrvQR0FqdE1OE3DFKzD 9694f9LGC47oXKdEfFxji0BVtzrzncPD3B9+vJrA4UNTY/h4fg5wyJiEhdPZVPVG 1fJF+waSb5tEzENZ+mLQsfAuqSOIvtRtK+ONPBsqSib5cHV89MS01oSdo2c4kZi0 MKWrsISstT8JcpkBkWZegkyEfpTqs/xIWQgfiMgR6Xoge66aiwgZ0YSxPWrNL2Ar 2vwvk1bPAehSlLy/jwJTM4Br2ANqJ0i3++3w6HmVgFi/niJ/sp1vfy8BYUZn9YcM ExXRM66sJWiN01KPVRbaZjfflMsZyYUX3jNg+ulfA33y+TblyL96ZAT70KjwkgH+ Vq1j/f9jQnkwt80cW4Yn4I38nChlR6clQ2d/BJOgXCe96Os+hdyXjLcZu/AZCJab iwQMal5KpdU6uTIt9T7i =q/Oy -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/sstabellini-http/tags/xen-20180531-tag' into staging Xen 2018/05/31 # gpg: Signature made Thu 31 May 2018 20:05:49 BST # gpg: using RSA key 894F8F4870E1AE90 # gpg: Good signature from "Stefano Stabellini <stefano.stabellini@eu.citrix.com>" # gpg: aka "Stefano Stabellini <sstabellini@kernel.org>" # Primary key fingerprint: D04E 33AB A51F 67BA 07D3 0AEA 894F 8F48 70E1 AE90 * remotes/sstabellini-http/tags/xen-20180531-tag: xen-hvm: stop faking I/O to access PCI config space xen-hvm: try to use xenforeignmemory_map_resource() to map ioreq pages xen/hvm: correct reporting of modified memory under physmap during migration Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
14fc618461
|
@ -2231,12 +2231,17 @@ EOF
|
||||||
#undef XC_WANT_COMPAT_DEVICEMODEL_API
|
#undef XC_WANT_COMPAT_DEVICEMODEL_API
|
||||||
#define __XEN_TOOLS__
|
#define __XEN_TOOLS__
|
||||||
#include <xendevicemodel.h>
|
#include <xendevicemodel.h>
|
||||||
|
#include <xenforeignmemory.h>
|
||||||
int main(void) {
|
int main(void) {
|
||||||
xendevicemodel_handle *xd;
|
xendevicemodel_handle *xd;
|
||||||
|
xenforeignmemory_handle *xfmem;
|
||||||
|
|
||||||
xd = xendevicemodel_open(0, 0);
|
xd = xendevicemodel_open(0, 0);
|
||||||
xendevicemodel_pin_memory_cacheattr(xd, 0, 0, 0, 0);
|
xendevicemodel_pin_memory_cacheattr(xd, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
xfmem = xenforeignmemory_open(0, 0);
|
||||||
|
xenforeignmemory_map_resource(xfmem, 0, 0, 0, 0, 0, NULL, 0, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
|
@ -15,6 +15,9 @@ cpu_ioreq_pio(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64
|
||||||
cpu_ioreq_pio_read_reg(void *req, uint64_t data, uint64_t addr, uint32_t size) "I/O=%p pio read reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
|
cpu_ioreq_pio_read_reg(void *req, uint64_t data, uint64_t addr, uint32_t size) "I/O=%p pio read reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
|
||||||
cpu_ioreq_pio_write_reg(void *req, uint64_t data, uint64_t addr, uint32_t size) "I/O=%p pio write reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
|
cpu_ioreq_pio_write_reg(void *req, uint64_t data, uint64_t addr, uint32_t size) "I/O=%p pio write reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
|
||||||
cpu_ioreq_move(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p copy dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
|
cpu_ioreq_move(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p copy dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
|
||||||
|
xen_map_resource_ioreq(uint32_t id, void *addr) "id: %u addr: %p"
|
||||||
|
cpu_ioreq_config_read(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
|
||||||
|
cpu_ioreq_config_write(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
|
||||||
|
|
||||||
# xen-mapcache.c
|
# xen-mapcache.c
|
||||||
xen_map_cache(uint64_t phys_addr) "want 0x%"PRIx64
|
xen_map_cache(uint64_t phys_addr) "want 0x%"PRIx64
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "hw/pci/pci.h"
|
#include "hw/pci/pci.h"
|
||||||
|
#include "hw/pci/pci_host.h"
|
||||||
#include "hw/i386/pc.h"
|
#include "hw/i386/pc.h"
|
||||||
#include "hw/i386/apic-msidef.h"
|
#include "hw/i386/apic-msidef.h"
|
||||||
#include "hw/xen/xen_common.h"
|
#include "hw/xen/xen_common.h"
|
||||||
|
@ -86,6 +87,14 @@ typedef struct XenPhysmap {
|
||||||
QLIST_ENTRY(XenPhysmap) list;
|
QLIST_ENTRY(XenPhysmap) list;
|
||||||
} XenPhysmap;
|
} XenPhysmap;
|
||||||
|
|
||||||
|
static QLIST_HEAD(, XenPhysmap) xen_physmap;
|
||||||
|
|
||||||
|
typedef struct XenPciDevice {
|
||||||
|
PCIDevice *pci_dev;
|
||||||
|
uint32_t sbdf;
|
||||||
|
QLIST_ENTRY(XenPciDevice) entry;
|
||||||
|
} XenPciDevice;
|
||||||
|
|
||||||
typedef struct XenIOState {
|
typedef struct XenIOState {
|
||||||
ioservid_t ioservid;
|
ioservid_t ioservid;
|
||||||
shared_iopage_t *shared_page;
|
shared_iopage_t *shared_page;
|
||||||
|
@ -106,8 +115,8 @@ typedef struct XenIOState {
|
||||||
struct xs_handle *xenstore;
|
struct xs_handle *xenstore;
|
||||||
MemoryListener memory_listener;
|
MemoryListener memory_listener;
|
||||||
MemoryListener io_listener;
|
MemoryListener io_listener;
|
||||||
|
QLIST_HEAD(, XenPciDevice) dev_list;
|
||||||
DeviceListener device_listener;
|
DeviceListener device_listener;
|
||||||
QLIST_HEAD(, XenPhysmap) physmap;
|
|
||||||
hwaddr free_phys_offset;
|
hwaddr free_phys_offset;
|
||||||
const XenPhysmap *log_for_dirtybit;
|
const XenPhysmap *log_for_dirtybit;
|
||||||
|
|
||||||
|
@ -274,14 +283,13 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
|
||||||
g_free(pfn_list);
|
g_free(pfn_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static XenPhysmap *get_physmapping(XenIOState *state,
|
static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size)
|
||||||
hwaddr start_addr, ram_addr_t size)
|
|
||||||
{
|
{
|
||||||
XenPhysmap *physmap = NULL;
|
XenPhysmap *physmap = NULL;
|
||||||
|
|
||||||
start_addr &= TARGET_PAGE_MASK;
|
start_addr &= TARGET_PAGE_MASK;
|
||||||
|
|
||||||
QLIST_FOREACH(physmap, &state->physmap, list) {
|
QLIST_FOREACH(physmap, &xen_physmap, list) {
|
||||||
if (range_covers_byte(physmap->start_addr, physmap->size, start_addr)) {
|
if (range_covers_byte(physmap->start_addr, physmap->size, start_addr)) {
|
||||||
return physmap;
|
return physmap;
|
||||||
}
|
}
|
||||||
|
@ -289,23 +297,21 @@ static XenPhysmap *get_physmapping(XenIOState *state,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XEN_COMPAT_PHYSMAP
|
static hwaddr xen_phys_offset_to_gaddr(hwaddr phys_offset, ram_addr_t size)
|
||||||
static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
|
|
||||||
ram_addr_t size, void *opaque)
|
|
||||||
{
|
{
|
||||||
hwaddr addr = start_addr & TARGET_PAGE_MASK;
|
hwaddr addr = phys_offset & TARGET_PAGE_MASK;
|
||||||
XenIOState *xen_io_state = opaque;
|
|
||||||
XenPhysmap *physmap = NULL;
|
XenPhysmap *physmap = NULL;
|
||||||
|
|
||||||
QLIST_FOREACH(physmap, &xen_io_state->physmap, list) {
|
QLIST_FOREACH(physmap, &xen_physmap, list) {
|
||||||
if (range_covers_byte(physmap->phys_offset, physmap->size, addr)) {
|
if (range_covers_byte(physmap->phys_offset, physmap->size, addr)) {
|
||||||
return physmap->start_addr;
|
return physmap->start_addr + (phys_offset - physmap->phys_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return start_addr;
|
return phys_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef XEN_COMPAT_PHYSMAP
|
||||||
static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
|
static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
|
||||||
{
|
{
|
||||||
char path[80], value[17];
|
char path[80], value[17];
|
||||||
|
@ -355,7 +361,7 @@ static int xen_add_to_physmap(XenIOState *state,
|
||||||
hwaddr phys_offset = memory_region_get_ram_addr(mr);
|
hwaddr phys_offset = memory_region_get_ram_addr(mr);
|
||||||
const char *mr_name;
|
const char *mr_name;
|
||||||
|
|
||||||
if (get_physmapping(state, start_addr, size)) {
|
if (get_physmapping(start_addr, size)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
|
@ -384,7 +390,7 @@ go_physmap:
|
||||||
physmap->name = mr_name;
|
physmap->name = mr_name;
|
||||||
physmap->phys_offset = phys_offset;
|
physmap->phys_offset = phys_offset;
|
||||||
|
|
||||||
QLIST_INSERT_HEAD(&state->physmap, physmap, list);
|
QLIST_INSERT_HEAD(&xen_physmap, physmap, list);
|
||||||
|
|
||||||
if (runstate_check(RUN_STATE_INMIGRATE)) {
|
if (runstate_check(RUN_STATE_INMIGRATE)) {
|
||||||
/* Now when we have a physmap entry we can replace a dummy mapping with
|
/* Now when we have a physmap entry we can replace a dummy mapping with
|
||||||
|
@ -428,7 +434,7 @@ static int xen_remove_from_physmap(XenIOState *state,
|
||||||
XenPhysmap *physmap = NULL;
|
XenPhysmap *physmap = NULL;
|
||||||
hwaddr phys_offset = 0;
|
hwaddr phys_offset = 0;
|
||||||
|
|
||||||
physmap = get_physmapping(state, start_addr, size);
|
physmap = get_physmapping(start_addr, size);
|
||||||
if (physmap == NULL) {
|
if (physmap == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -570,6 +576,12 @@ static void xen_device_realize(DeviceListener *listener,
|
||||||
|
|
||||||
if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||||
PCIDevice *pci_dev = PCI_DEVICE(dev);
|
PCIDevice *pci_dev = PCI_DEVICE(dev);
|
||||||
|
XenPciDevice *xendev = g_new(XenPciDevice, 1);
|
||||||
|
|
||||||
|
xendev->pci_dev = pci_dev;
|
||||||
|
xendev->sbdf = PCI_BUILD_BDF(pci_dev_bus_num(pci_dev),
|
||||||
|
pci_dev->devfn);
|
||||||
|
QLIST_INSERT_HEAD(&state->dev_list, xendev, entry);
|
||||||
|
|
||||||
xen_map_pcidev(xen_domid, state->ioservid, pci_dev);
|
xen_map_pcidev(xen_domid, state->ioservid, pci_dev);
|
||||||
}
|
}
|
||||||
|
@ -582,8 +594,17 @@ static void xen_device_unrealize(DeviceListener *listener,
|
||||||
|
|
||||||
if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||||
PCIDevice *pci_dev = PCI_DEVICE(dev);
|
PCIDevice *pci_dev = PCI_DEVICE(dev);
|
||||||
|
XenPciDevice *xendev, *next;
|
||||||
|
|
||||||
xen_unmap_pcidev(xen_domid, state->ioservid, pci_dev);
|
xen_unmap_pcidev(xen_domid, state->ioservid, pci_dev);
|
||||||
|
|
||||||
|
QLIST_FOREACH_SAFE(xendev, &state->dev_list, entry, next) {
|
||||||
|
if (xendev->pci_dev == pci_dev) {
|
||||||
|
QLIST_REMOVE(xendev, entry);
|
||||||
|
g_free(xendev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,7 +618,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
|
||||||
int rc, i, j;
|
int rc, i, j;
|
||||||
const XenPhysmap *physmap = NULL;
|
const XenPhysmap *physmap = NULL;
|
||||||
|
|
||||||
physmap = get_physmapping(state, start_addr, size);
|
physmap = get_physmapping(start_addr, size);
|
||||||
if (physmap == NULL) {
|
if (physmap == NULL) {
|
||||||
/* not handled */
|
/* not handled */
|
||||||
return;
|
return;
|
||||||
|
@ -904,6 +925,62 @@ static void cpu_ioreq_move(ioreq_t *req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cpu_ioreq_config(XenIOState *state, ioreq_t *req)
|
||||||
|
{
|
||||||
|
uint32_t sbdf = req->addr >> 32;
|
||||||
|
uint32_t reg = req->addr;
|
||||||
|
XenPciDevice *xendev;
|
||||||
|
|
||||||
|
if (req->size != sizeof(uint8_t) && req->size != sizeof(uint16_t) &&
|
||||||
|
req->size != sizeof(uint32_t)) {
|
||||||
|
hw_error("PCI config access: bad size (%u)", req->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->count != 1) {
|
||||||
|
hw_error("PCI config access: bad count (%u)", req->count);
|
||||||
|
}
|
||||||
|
|
||||||
|
QLIST_FOREACH(xendev, &state->dev_list, entry) {
|
||||||
|
if (xendev->sbdf != sbdf) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!req->data_is_ptr) {
|
||||||
|
if (req->dir == IOREQ_READ) {
|
||||||
|
req->data = pci_host_config_read_common(
|
||||||
|
xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
|
||||||
|
req->size);
|
||||||
|
trace_cpu_ioreq_config_read(req, xendev->sbdf, reg,
|
||||||
|
req->size, req->data);
|
||||||
|
} else if (req->dir == IOREQ_WRITE) {
|
||||||
|
trace_cpu_ioreq_config_write(req, xendev->sbdf, reg,
|
||||||
|
req->size, req->data);
|
||||||
|
pci_host_config_write_common(
|
||||||
|
xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
|
||||||
|
req->data, req->size);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
|
if (req->dir == IOREQ_READ) {
|
||||||
|
tmp = pci_host_config_read_common(
|
||||||
|
xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
|
||||||
|
req->size);
|
||||||
|
trace_cpu_ioreq_config_read(req, xendev->sbdf, reg,
|
||||||
|
req->size, tmp);
|
||||||
|
write_phys_req_item(req->data, req, 0, &tmp);
|
||||||
|
} else if (req->dir == IOREQ_WRITE) {
|
||||||
|
read_phys_req_item(req->data, req, 0, &tmp);
|
||||||
|
trace_cpu_ioreq_config_write(req, xendev->sbdf, reg,
|
||||||
|
req->size, tmp);
|
||||||
|
pci_host_config_write_common(
|
||||||
|
xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
|
||||||
|
tmp, req->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void regs_to_cpu(vmware_regs_t *vmport_regs, ioreq_t *req)
|
static void regs_to_cpu(vmware_regs_t *vmport_regs, ioreq_t *req)
|
||||||
{
|
{
|
||||||
X86CPU *cpu;
|
X86CPU *cpu;
|
||||||
|
@ -976,27 +1053,9 @@ static void handle_ioreq(XenIOState *state, ioreq_t *req)
|
||||||
case IOREQ_TYPE_INVALIDATE:
|
case IOREQ_TYPE_INVALIDATE:
|
||||||
xen_invalidate_map_cache();
|
xen_invalidate_map_cache();
|
||||||
break;
|
break;
|
||||||
case IOREQ_TYPE_PCI_CONFIG: {
|
case IOREQ_TYPE_PCI_CONFIG:
|
||||||
uint32_t sbdf = req->addr >> 32;
|
cpu_ioreq_config(state, req);
|
||||||
uint32_t val;
|
|
||||||
|
|
||||||
/* Fake a write to port 0xCF8 so that
|
|
||||||
* the config space access will target the
|
|
||||||
* correct device model.
|
|
||||||
*/
|
|
||||||
val = (1u << 31) |
|
|
||||||
((req->addr & 0x0f00) << 16) |
|
|
||||||
((sbdf & 0xffff) << 8) |
|
|
||||||
(req->addr & 0xfc);
|
|
||||||
do_outp(0xcf8, 4, val);
|
|
||||||
|
|
||||||
/* Now issue the config space access via
|
|
||||||
* port 0xCFC
|
|
||||||
*/
|
|
||||||
req->addr = 0xcfc | (req->addr & 0x03);
|
|
||||||
cpu_ioreq_pio(req);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
hw_error("Invalid ioreq type 0x%x\n", req->type);
|
hw_error("Invalid ioreq type 0x%x\n", req->type);
|
||||||
}
|
}
|
||||||
|
@ -1222,7 +1281,7 @@ static void xen_read_physmap(XenIOState *state)
|
||||||
xen_domid, entries[i]);
|
xen_domid, entries[i]);
|
||||||
physmap->name = xs_read(state->xenstore, 0, path, &len);
|
physmap->name = xs_read(state->xenstore, 0, path, &len);
|
||||||
|
|
||||||
QLIST_INSERT_HEAD(&state->physmap, physmap, list);
|
QLIST_INSERT_HEAD(&xen_physmap, physmap, list);
|
||||||
}
|
}
|
||||||
free(entries);
|
free(entries);
|
||||||
}
|
}
|
||||||
|
@ -1239,13 +1298,39 @@ static void xen_wakeup_notifier(Notifier *notifier, void *data)
|
||||||
|
|
||||||
static int xen_map_ioreq_server(XenIOState *state)
|
static int xen_map_ioreq_server(XenIOState *state)
|
||||||
{
|
{
|
||||||
|
void *addr = NULL;
|
||||||
|
xenforeignmemory_resource_handle *fres;
|
||||||
xen_pfn_t ioreq_pfn;
|
xen_pfn_t ioreq_pfn;
|
||||||
xen_pfn_t bufioreq_pfn;
|
xen_pfn_t bufioreq_pfn;
|
||||||
evtchn_port_t bufioreq_evtchn;
|
evtchn_port_t bufioreq_evtchn;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempt to map using the resource API and fall back to normal
|
||||||
|
* foreign mapping if this is not supported.
|
||||||
|
*/
|
||||||
|
QEMU_BUILD_BUG_ON(XENMEM_resource_ioreq_server_frame_bufioreq != 0);
|
||||||
|
QEMU_BUILD_BUG_ON(XENMEM_resource_ioreq_server_frame_ioreq(0) != 1);
|
||||||
|
fres = xenforeignmemory_map_resource(xen_fmem, xen_domid,
|
||||||
|
XENMEM_resource_ioreq_server,
|
||||||
|
state->ioservid, 0, 2,
|
||||||
|
&addr,
|
||||||
|
PROT_READ | PROT_WRITE, 0);
|
||||||
|
if (fres != NULL) {
|
||||||
|
trace_xen_map_resource_ioreq(state->ioservid, addr);
|
||||||
|
state->buffered_io_page = addr;
|
||||||
|
state->shared_page = addr + TARGET_PAGE_SIZE;
|
||||||
|
} else if (errno != EOPNOTSUPP) {
|
||||||
|
error_report("failed to map ioreq server resources: error %d handle=%p",
|
||||||
|
errno, xen_xc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
rc = xen_get_ioreq_server_info(xen_domid, state->ioservid,
|
rc = xen_get_ioreq_server_info(xen_domid, state->ioservid,
|
||||||
&ioreq_pfn, &bufioreq_pfn,
|
(state->shared_page == NULL) ?
|
||||||
|
&ioreq_pfn : NULL,
|
||||||
|
(state->buffered_io_page == NULL) ?
|
||||||
|
&bufioreq_pfn : NULL,
|
||||||
&bufioreq_evtchn);
|
&bufioreq_evtchn);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
error_report("failed to get ioreq server info: error %d handle=%p",
|
error_report("failed to get ioreq server info: error %d handle=%p",
|
||||||
|
@ -1253,26 +1338,36 @@ static int xen_map_ioreq_server(XenIOState *state)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF("shared page at pfn %lx\n", ioreq_pfn);
|
|
||||||
DPRINTF("buffered io page at pfn %lx\n", bufioreq_pfn);
|
|
||||||
DPRINTF("buffered io evtchn is %x\n", bufioreq_evtchn);
|
|
||||||
|
|
||||||
state->shared_page = xenforeignmemory_map(xen_fmem, xen_domid,
|
|
||||||
PROT_READ | PROT_WRITE,
|
|
||||||
1, &ioreq_pfn, NULL);
|
|
||||||
if (state->shared_page == NULL) {
|
if (state->shared_page == NULL) {
|
||||||
error_report("map shared IO page returned error %d handle=%p",
|
DPRINTF("shared page at pfn %lx\n", ioreq_pfn);
|
||||||
errno, xen_xc);
|
|
||||||
|
state->shared_page = xenforeignmemory_map(xen_fmem, xen_domid,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
1, &ioreq_pfn, NULL);
|
||||||
|
if (state->shared_page == NULL) {
|
||||||
|
error_report("map shared IO page returned error %d handle=%p",
|
||||||
|
errno, xen_xc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->buffered_io_page == NULL) {
|
||||||
|
DPRINTF("buffered io page at pfn %lx\n", bufioreq_pfn);
|
||||||
|
|
||||||
|
state->buffered_io_page = xenforeignmemory_map(xen_fmem, xen_domid,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
1, &bufioreq_pfn,
|
||||||
|
NULL);
|
||||||
|
if (state->buffered_io_page == NULL) {
|
||||||
|
error_report("map buffered IO page returned error %d", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->shared_page == NULL || state->buffered_io_page == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->buffered_io_page = xenforeignmemory_map(xen_fmem, xen_domid,
|
DPRINTF("buffered io evtchn is %x\n", bufioreq_evtchn);
|
||||||
PROT_READ | PROT_WRITE,
|
|
||||||
1, &bufioreq_pfn, NULL);
|
|
||||||
if (state->buffered_io_page == NULL) {
|
|
||||||
error_report("map buffered IO page returned error %d", errno);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
state->bufioreq_remote_port = bufioreq_evtchn;
|
state->bufioreq_remote_port = bufioreq_evtchn;
|
||||||
|
|
||||||
|
@ -1374,7 +1469,6 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
|
||||||
qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
|
qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
|
||||||
|
|
||||||
state->memory_listener = xen_memory_listener;
|
state->memory_listener = xen_memory_listener;
|
||||||
QLIST_INIT(&state->physmap);
|
|
||||||
memory_listener_register(&state->memory_listener, &address_space_memory);
|
memory_listener_register(&state->memory_listener, &address_space_memory);
|
||||||
state->log_for_dirtybit = NULL;
|
state->log_for_dirtybit = NULL;
|
||||||
|
|
||||||
|
@ -1382,6 +1476,7 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
|
||||||
memory_listener_register(&state->io_listener, &address_space_io);
|
memory_listener_register(&state->io_listener, &address_space_io);
|
||||||
|
|
||||||
state->device_listener = xen_device_listener;
|
state->device_listener = xen_device_listener;
|
||||||
|
QLIST_INIT(&state->dev_list);
|
||||||
device_listener_register(&state->device_listener);
|
device_listener_register(&state->device_listener);
|
||||||
|
|
||||||
/* Initialize backend core & drivers */
|
/* Initialize backend core & drivers */
|
||||||
|
@ -1390,6 +1485,8 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
xen_be_register_common();
|
xen_be_register_common();
|
||||||
|
|
||||||
|
QLIST_INIT(&xen_physmap);
|
||||||
xen_read_physmap(state);
|
xen_read_physmap(state);
|
||||||
|
|
||||||
/* Disable ACPI build because Xen handles it */
|
/* Disable ACPI build because Xen handles it */
|
||||||
|
@ -1461,6 +1558,8 @@ void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
|
||||||
int rc;
|
int rc;
|
||||||
ram_addr_t start_pfn, nb_pages;
|
ram_addr_t start_pfn, nb_pages;
|
||||||
|
|
||||||
|
start = xen_phys_offset_to_gaddr(start, length);
|
||||||
|
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
length = TARGET_PAGE_SIZE;
|
length = TARGET_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -319,7 +319,7 @@ tryagain:
|
||||||
mapcache->last_entry = NULL;
|
mapcache->last_entry = NULL;
|
||||||
#ifdef XEN_COMPAT_PHYSMAP
|
#ifdef XEN_COMPAT_PHYSMAP
|
||||||
if (!translated && mapcache->phys_offset_to_gaddr) {
|
if (!translated && mapcache->phys_offset_to_gaddr) {
|
||||||
phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size, mapcache->opaque);
|
phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size);
|
||||||
translated = true;
|
translated = true;
|
||||||
goto tryagain;
|
goto tryagain;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,22 @@ static inline int xendevicemodel_pin_memory_cacheattr(
|
||||||
return xc_domain_pin_memory_cacheattr(xen_xc, domid, start, end, type);
|
return xc_domain_pin_memory_cacheattr(xen_xc, domid, start, end, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef void xenforeignmemory_resource_handle;
|
||||||
|
|
||||||
|
#define XENMEM_resource_ioreq_server 0
|
||||||
|
|
||||||
|
#define XENMEM_resource_ioreq_server_frame_bufioreq 0
|
||||||
|
#define XENMEM_resource_ioreq_server_frame_ioreq(n) (1 + (n))
|
||||||
|
|
||||||
|
static inline xenforeignmemory_resource_handle *xenforeignmemory_map_resource(
|
||||||
|
xenforeignmemory_handle *fmem, domid_t domid, unsigned int type,
|
||||||
|
unsigned int id, unsigned long frame, unsigned long nr_frames,
|
||||||
|
void **paddr, int prot, int flags)
|
||||||
|
{
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_XEN_CTRL_INTERFACE_VERSION < 41100 */
|
#endif /* CONFIG_XEN_CTRL_INTERFACE_VERSION < 41100 */
|
||||||
|
|
||||||
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000
|
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000
|
||||||
|
|
|
@ -9,9 +9,8 @@
|
||||||
#ifndef XEN_MAPCACHE_H
|
#ifndef XEN_MAPCACHE_H
|
||||||
#define XEN_MAPCACHE_H
|
#define XEN_MAPCACHE_H
|
||||||
|
|
||||||
typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr start_addr,
|
typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
|
||||||
ram_addr_t size,
|
ram_addr_t size);
|
||||||
void *opaque);
|
|
||||||
#ifdef CONFIG_XEN
|
#ifdef CONFIG_XEN
|
||||||
|
|
||||||
void xen_map_cache_init(phys_offset_to_gaddr_t f,
|
void xen_map_cache_init(phys_offset_to_gaddr_t f,
|
||||||
|
|
Loading…
Reference in New Issue