Xen 2017/07/18
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJZbokoAAoJEIlPj0hw4a6QgloP/jc9tVFrPjTDezDyPmXR4ls8 U/kvz5RCn2bu4y8h6U+FHK4BZ7DR1Ccd3Uq1qqDbnlyfcvJeISqqkN2RrnwUQEgV XMCEr+okQyiQV4H/MLvmUWtPHpHt3gSEBdoRdGHnkzA2dC/YsJ1F/khKgCh8wqWS GTeACabyDTb9L/QFdh//o7GtcI6qv/APGJ/rVVFrrVktp+lZuIZCGZ3hbJ8lopoI FSXuM7caVgIlNzP/6RmCoP91ibREPfbfL/yqgv0cW7kiOWVXWwriz6Mi/J2AzmCo jqgDqRzkLZPAl1WdZM7MosQIiY7ZlAGhpS9ArK5P4Kv7H6TYV7mkbiSap8SmjnZH NvSRLxgT3JjTE5evSodfaaQpjiX0KGaZX0JmpqXYPqOBSYal2lDUNFSokbeucp7w y3dBZGY0/9om+G34QzZNvPisYJ2F4Yr5DvCtue8hmkvLSw+z3251555wKQvc6TNx wob2h8b8h+YsfhvnSrN1R8w3OL69kGFlMz9PWEgB4opVacZqph/XsMKLARXCg+FD 83kCuJnV/WAannHpvQA8k4HO6GiKGtrulh6vv1QOlCJQokcK1mZt7Atot+cPcGU2 UTyhSaOv4sy07lPYzvv0B4MUHNObN/v/OoDygrf7WjCDKigH+RpsVruwAqFakoCB 09+PtQ26X2Vup+YtW5bG =qPq6 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/sstabellini/tags/xen-20170718-tag' into staging Xen 2017/07/18 # gpg: Signature made Tue 18 Jul 2017 23:18:16 BST # gpg: using RSA key 0x894F8F4870E1AE90 # 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/tags/xen-20170718-tag: xen: don't use xenstore to save/restore physmap anymore xen/mapcache: introduce xen_replace_cache_entry() xen/mapcache: add an ability to create dummy mappings xen: move physmap saving into a separate function xen-platform: separate unplugging of NVMe disks xen_pt_msi.c: Check for xen_host_pci_get_* failures in xen_pt_msix_init() hw/xen: Set emu_mask for igd_opregion register Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
b3e46a8914
18
configure
vendored
18
configure
vendored
@ -2107,6 +2107,24 @@ EOF
|
||||
# Xen unstable
|
||||
elif
|
||||
cat > $TMPC <<EOF &&
|
||||
#undef XC_WANT_COMPAT_MAP_FOREIGN_API
|
||||
#include <xenforeignmemory.h>
|
||||
int main(void) {
|
||||
xenforeignmemory_handle *xfmem;
|
||||
|
||||
xfmem = xenforeignmemory_open(0, 0);
|
||||
xenforeignmemory_map2(xfmem, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
compile_prog "" "$xen_libs -lxendevicemodel $xen_stable_libs"
|
||||
then
|
||||
xen_stable_libs="-lxendevicemodel $xen_stable_libs"
|
||||
xen_ctrl_version=41000
|
||||
xen=yes
|
||||
elif
|
||||
cat > $TMPC <<EOF &&
|
||||
#undef XC_WANT_COMPAT_DEVICEMODEL_API
|
||||
#define __XEN_TOOLS__
|
||||
#include <xendevicemodel.h>
|
||||
|
@ -288,6 +288,7 @@ static XenPhysmap *get_physmapping(XenIOState *state,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef XEN_COMPAT_PHYSMAP
|
||||
static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
|
||||
ram_addr_t size, void *opaque)
|
||||
{
|
||||
@ -304,6 +305,42 @@ static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr,
|
||||
return start_addr;
|
||||
}
|
||||
|
||||
static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
|
||||
{
|
||||
char path[80], value[17];
|
||||
|
||||
snprintf(path, sizeof(path),
|
||||
"/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
|
||||
xen_domid, (uint64_t)physmap->phys_offset);
|
||||
snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->start_addr);
|
||||
if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
|
||||
return -1;
|
||||
}
|
||||
snprintf(path, sizeof(path),
|
||||
"/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
|
||||
xen_domid, (uint64_t)physmap->phys_offset);
|
||||
snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)physmap->size);
|
||||
if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
|
||||
return -1;
|
||||
}
|
||||
if (physmap->name) {
|
||||
snprintf(path, sizeof(path),
|
||||
"/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
|
||||
xen_domid, (uint64_t)physmap->phys_offset);
|
||||
if (!xs_write(state->xenstore, 0, path,
|
||||
physmap->name, strlen(physmap->name))) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int xen_add_to_physmap(XenIOState *state,
|
||||
hwaddr start_addr,
|
||||
ram_addr_t size,
|
||||
@ -315,7 +352,6 @@ static int xen_add_to_physmap(XenIOState *state,
|
||||
XenPhysmap *physmap = NULL;
|
||||
hwaddr pfn, start_gpfn;
|
||||
hwaddr phys_offset = memory_region_get_ram_addr(mr);
|
||||
char path[80], value[17];
|
||||
const char *mr_name;
|
||||
|
||||
if (get_physmapping(state, start_addr, size)) {
|
||||
@ -338,6 +374,26 @@ go_physmap:
|
||||
DPRINTF("mapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx"\n",
|
||||
start_addr, start_addr + size);
|
||||
|
||||
mr_name = memory_region_name(mr);
|
||||
|
||||
physmap = g_malloc(sizeof(XenPhysmap));
|
||||
|
||||
physmap->start_addr = start_addr;
|
||||
physmap->size = size;
|
||||
physmap->name = mr_name;
|
||||
physmap->phys_offset = phys_offset;
|
||||
|
||||
QLIST_INSERT_HEAD(&state->physmap, physmap, list);
|
||||
|
||||
if (runstate_check(RUN_STATE_INMIGRATE)) {
|
||||
/* Now when we have a physmap entry we can replace a dummy mapping with
|
||||
* a real one of guest foreign memory. */
|
||||
uint8_t *p = xen_replace_cache_entry(phys_offset, start_addr, size);
|
||||
assert(p && p == memory_region_get_ram_ptr(mr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pfn = phys_offset >> TARGET_PAGE_BITS;
|
||||
start_gpfn = start_addr >> TARGET_PAGE_BITS;
|
||||
for (i = 0; i < size >> TARGET_PAGE_BITS; i++) {
|
||||
@ -352,46 +408,11 @@ go_physmap:
|
||||
}
|
||||
}
|
||||
|
||||
mr_name = memory_region_name(mr);
|
||||
|
||||
physmap = g_malloc(sizeof (XenPhysmap));
|
||||
|
||||
physmap->start_addr = start_addr;
|
||||
physmap->size = size;
|
||||
physmap->name = mr_name;
|
||||
physmap->phys_offset = phys_offset;
|
||||
|
||||
QLIST_INSERT_HEAD(&state->physmap, physmap, list);
|
||||
|
||||
xc_domain_pin_memory_cacheattr(xen_xc, xen_domid,
|
||||
start_addr >> TARGET_PAGE_BITS,
|
||||
(start_addr + size - 1) >> TARGET_PAGE_BITS,
|
||||
XEN_DOMCTL_MEM_CACHEATTR_WB);
|
||||
|
||||
snprintf(path, sizeof(path),
|
||||
"/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
|
||||
xen_domid, (uint64_t)phys_offset);
|
||||
snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
|
||||
if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
|
||||
return -1;
|
||||
}
|
||||
snprintf(path, sizeof(path),
|
||||
"/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
|
||||
xen_domid, (uint64_t)phys_offset);
|
||||
snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
|
||||
if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
|
||||
return -1;
|
||||
}
|
||||
if (mr_name) {
|
||||
snprintf(path, sizeof(path),
|
||||
"/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
|
||||
xen_domid, (uint64_t)phys_offset);
|
||||
if (!xs_write(state->xenstore, 0, path, mr_name, strlen(mr_name))) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return xen_save_physmap(state, physmap);
|
||||
}
|
||||
|
||||
static int xen_remove_from_physmap(XenIOState *state,
|
||||
@ -1152,6 +1173,7 @@ static void xen_exit_notifier(Notifier *n, void *data)
|
||||
xs_daemon_close(state->xenstore);
|
||||
}
|
||||
|
||||
#ifdef XEN_COMPAT_PHYSMAP
|
||||
static void xen_read_physmap(XenIOState *state)
|
||||
{
|
||||
XenPhysmap *physmap = NULL;
|
||||
@ -1199,6 +1221,11 @@ static void xen_read_physmap(XenIOState *state)
|
||||
}
|
||||
free(entries);
|
||||
}
|
||||
#else
|
||||
static void xen_read_physmap(XenIOState *state)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void xen_wakeup_notifier(Notifier *notifier, void *data)
|
||||
{
|
||||
@ -1325,7 +1352,11 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
|
||||
state->bufioreq_local_port = rc;
|
||||
|
||||
/* Init RAM management */
|
||||
#ifdef XEN_COMPAT_PHYSMAP
|
||||
xen_map_cache_init(xen_phys_offset_to_gaddr, state);
|
||||
#else
|
||||
xen_map_cache_init(NULL, state);
|
||||
#endif
|
||||
xen_ram_init(pcms, ram_size, ram_memory);
|
||||
|
||||
qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
|
||||
|
@ -53,6 +53,8 @@ typedef struct MapCacheEntry {
|
||||
uint8_t *vaddr_base;
|
||||
unsigned long *valid_mapping;
|
||||
uint8_t lock;
|
||||
#define XEN_MAPCACHE_ENTRY_DUMMY (1 << 0)
|
||||
uint8_t flags;
|
||||
hwaddr size;
|
||||
struct MapCacheEntry *next;
|
||||
} MapCacheEntry;
|
||||
@ -149,8 +151,10 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
|
||||
}
|
||||
|
||||
static void xen_remap_bucket(MapCacheEntry *entry,
|
||||
void *vaddr,
|
||||
hwaddr size,
|
||||
hwaddr address_index)
|
||||
hwaddr address_index,
|
||||
bool dummy)
|
||||
{
|
||||
uint8_t *vaddr_base;
|
||||
xen_pfn_t *pfns;
|
||||
@ -164,7 +168,9 @@ static void xen_remap_bucket(MapCacheEntry *entry,
|
||||
err = g_malloc0(nb_pfn * sizeof (int));
|
||||
|
||||
if (entry->vaddr_base != NULL) {
|
||||
if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) {
|
||||
ram_block_notify_remove(entry->vaddr_base, entry->size);
|
||||
}
|
||||
if (munmap(entry->vaddr_base, entry->size) != 0) {
|
||||
perror("unmap fails");
|
||||
exit(-1);
|
||||
@ -177,12 +183,30 @@ static void xen_remap_bucket(MapCacheEntry *entry,
|
||||
pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
|
||||
}
|
||||
|
||||
vaddr_base = xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
|
||||
if (!dummy) {
|
||||
vaddr_base = xenforeignmemory_map2(xen_fmem, xen_domid, vaddr,
|
||||
PROT_READ | PROT_WRITE, 0,
|
||||
nb_pfn, pfns, err);
|
||||
if (vaddr_base == NULL) {
|
||||
perror("xenforeignmemory_map");
|
||||
perror("xenforeignmemory_map2");
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We create dummy mappings where we are unable to create a foreign
|
||||
* mapping immediately due to certain circumstances (i.e. on resume now)
|
||||
*/
|
||||
vaddr_base = mmap(vaddr, size, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_SHARED, -1, 0);
|
||||
if (vaddr_base == NULL) {
|
||||
perror("mmap");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) {
|
||||
ram_block_notify_add(vaddr_base, size);
|
||||
}
|
||||
|
||||
entry->vaddr_base = vaddr_base;
|
||||
entry->paddr_index = address_index;
|
||||
@ -190,7 +214,12 @@ static void xen_remap_bucket(MapCacheEntry *entry,
|
||||
entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long) *
|
||||
BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
|
||||
|
||||
ram_block_notify_add(entry->vaddr_base, entry->size);
|
||||
if (dummy) {
|
||||
entry->flags |= XEN_MAPCACHE_ENTRY_DUMMY;
|
||||
} else {
|
||||
entry->flags &= ~(XEN_MAPCACHE_ENTRY_DUMMY);
|
||||
}
|
||||
|
||||
bitmap_zero(entry->valid_mapping, nb_pfn);
|
||||
for (i = 0; i < nb_pfn; i++) {
|
||||
if (!err[i]) {
|
||||
@ -210,7 +239,8 @@ static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
|
||||
hwaddr address_offset;
|
||||
hwaddr cache_size = size;
|
||||
hwaddr test_bit_size;
|
||||
bool translated = false;
|
||||
bool translated G_GNUC_UNUSED = false;
|
||||
bool dummy = false;
|
||||
|
||||
tryagain:
|
||||
address_index = phys_addr >> MCACHE_BUCKET_SHIFT;
|
||||
@ -262,14 +292,14 @@ tryagain:
|
||||
if (!entry) {
|
||||
entry = g_malloc0(sizeof (MapCacheEntry));
|
||||
pentry->next = entry;
|
||||
xen_remap_bucket(entry, cache_size, address_index);
|
||||
xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
|
||||
} else if (!entry->lock) {
|
||||
if (!entry->vaddr_base || entry->paddr_index != address_index ||
|
||||
entry->size != cache_size ||
|
||||
!test_bits(address_offset >> XC_PAGE_SHIFT,
|
||||
test_bit_size >> XC_PAGE_SHIFT,
|
||||
entry->valid_mapping)) {
|
||||
xen_remap_bucket(entry, cache_size, address_index);
|
||||
xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
|
||||
}
|
||||
}
|
||||
|
||||
@ -277,11 +307,17 @@ tryagain:
|
||||
test_bit_size >> XC_PAGE_SHIFT,
|
||||
entry->valid_mapping)) {
|
||||
mapcache->last_entry = NULL;
|
||||
#ifdef XEN_COMPAT_PHYSMAP
|
||||
if (!translated && mapcache->phys_offset_to_gaddr) {
|
||||
phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size, mapcache->opaque);
|
||||
translated = true;
|
||||
goto tryagain;
|
||||
}
|
||||
#endif
|
||||
if (!dummy && runstate_check(RUN_STATE_INMIGRATE)) {
|
||||
dummy = true;
|
||||
goto tryagain;
|
||||
}
|
||||
trace_xen_map_cache_return(NULL);
|
||||
return NULL;
|
||||
}
|
||||
@ -462,3 +498,66 @@ void xen_invalidate_map_cache(void)
|
||||
|
||||
mapcache_unlock();
|
||||
}
|
||||
|
||||
static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
|
||||
hwaddr new_phys_addr,
|
||||
hwaddr size)
|
||||
{
|
||||
MapCacheEntry *entry;
|
||||
hwaddr address_index, address_offset;
|
||||
hwaddr test_bit_size, cache_size = size;
|
||||
|
||||
address_index = old_phys_addr >> MCACHE_BUCKET_SHIFT;
|
||||
address_offset = old_phys_addr & (MCACHE_BUCKET_SIZE - 1);
|
||||
|
||||
assert(size);
|
||||
/* test_bit_size is always a multiple of XC_PAGE_SIZE */
|
||||
test_bit_size = size + (old_phys_addr & (XC_PAGE_SIZE - 1));
|
||||
if (test_bit_size % XC_PAGE_SIZE) {
|
||||
test_bit_size += XC_PAGE_SIZE - (test_bit_size % XC_PAGE_SIZE);
|
||||
}
|
||||
cache_size = size + address_offset;
|
||||
if (cache_size % MCACHE_BUCKET_SIZE) {
|
||||
cache_size += MCACHE_BUCKET_SIZE - (cache_size % MCACHE_BUCKET_SIZE);
|
||||
}
|
||||
|
||||
entry = &mapcache->entry[address_index % mapcache->nr_buckets];
|
||||
while (entry && !(entry->paddr_index == address_index &&
|
||||
entry->size == cache_size)) {
|
||||
entry = entry->next;
|
||||
}
|
||||
if (!entry) {
|
||||
DPRINTF("Trying to update an entry for %lx " \
|
||||
"that is not in the mapcache!\n", old_phys_addr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
address_index = new_phys_addr >> MCACHE_BUCKET_SHIFT;
|
||||
address_offset = new_phys_addr & (MCACHE_BUCKET_SIZE - 1);
|
||||
|
||||
fprintf(stderr, "Replacing a dummy mapcache entry for %lx with %lx\n",
|
||||
old_phys_addr, new_phys_addr);
|
||||
|
||||
xen_remap_bucket(entry, entry->vaddr_base,
|
||||
cache_size, address_index, false);
|
||||
if (!test_bits(address_offset >> XC_PAGE_SHIFT,
|
||||
test_bit_size >> XC_PAGE_SHIFT,
|
||||
entry->valid_mapping)) {
|
||||
DPRINTF("Unable to update a mapcache entry for %lx!\n", old_phys_addr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return entry->vaddr_base + address_offset;
|
||||
}
|
||||
|
||||
uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
|
||||
hwaddr new_phys_addr,
|
||||
hwaddr size)
|
||||
{
|
||||
uint8_t *p;
|
||||
|
||||
mapcache_lock();
|
||||
p = xen_replace_cache_entry_unlocked(old_phys_addr, new_phys_addr, size);
|
||||
mapcache_unlock();
|
||||
return p;
|
||||
}
|
||||
|
@ -87,10 +87,30 @@ static void log_writeb(PCIXenPlatformState *s, char val)
|
||||
}
|
||||
}
|
||||
|
||||
/* Xen Platform, Fixed IOPort */
|
||||
#define UNPLUG_ALL_DISKS 1
|
||||
#define UNPLUG_ALL_NICS 2
|
||||
#define UNPLUG_AUX_IDE_DISKS 4
|
||||
/*
|
||||
* Unplug device flags.
|
||||
*
|
||||
* The logic got a little confused at some point in the past but this is
|
||||
* what they do now.
|
||||
*
|
||||
* bit 0: Unplug all IDE and SCSI disks.
|
||||
* bit 1: Unplug all NICs.
|
||||
* bit 2: Unplug IDE disks except primary master. This is overridden if
|
||||
* bit 0 is also present in the mask.
|
||||
* bit 3: Unplug all NVMe disks.
|
||||
*
|
||||
*/
|
||||
#define _UNPLUG_IDE_SCSI_DISKS 0
|
||||
#define UNPLUG_IDE_SCSI_DISKS (1u << _UNPLUG_IDE_SCSI_DISKS)
|
||||
|
||||
#define _UNPLUG_ALL_NICS 1
|
||||
#define UNPLUG_ALL_NICS (1u << _UNPLUG_ALL_NICS)
|
||||
|
||||
#define _UNPLUG_AUX_IDE_DISKS 2
|
||||
#define UNPLUG_AUX_IDE_DISKS (1u << _UNPLUG_AUX_IDE_DISKS)
|
||||
|
||||
#define _UNPLUG_NVME_DISKS 3
|
||||
#define UNPLUG_NVME_DISKS (1u << _UNPLUG_NVME_DISKS)
|
||||
|
||||
static void unplug_nic(PCIBus *b, PCIDevice *d, void *o)
|
||||
{
|
||||
@ -122,7 +142,7 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque)
|
||||
{
|
||||
uint32_t flags = *(uint32_t *)opaque;
|
||||
bool aux = (flags & UNPLUG_AUX_IDE_DISKS) &&
|
||||
!(flags & UNPLUG_ALL_DISKS);
|
||||
!(flags & UNPLUG_IDE_SCSI_DISKS);
|
||||
|
||||
/* We have to ignore passthrough devices */
|
||||
if (!strcmp(d->name, "xen-pci-passthrough")) {
|
||||
@ -135,12 +155,16 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque)
|
||||
break;
|
||||
|
||||
case PCI_CLASS_STORAGE_SCSI:
|
||||
case PCI_CLASS_STORAGE_EXPRESS:
|
||||
if (!aux) {
|
||||
object_unparent(OBJECT(d));
|
||||
}
|
||||
break;
|
||||
|
||||
case PCI_CLASS_STORAGE_EXPRESS:
|
||||
if (flags & UNPLUG_NVME_DISKS) {
|
||||
object_unparent(OBJECT(d));
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -158,10 +182,9 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v
|
||||
switch (addr) {
|
||||
case 0: {
|
||||
PCIDevice *pci_dev = PCI_DEVICE(s);
|
||||
/* Unplug devices. Value is a bitmask of which devices to
|
||||
unplug, with bit 0 the disk devices, bit 1 the network
|
||||
devices, and bit 2 the non-primary-master IDE devices. */
|
||||
if (val & (UNPLUG_ALL_DISKS | UNPLUG_AUX_IDE_DISKS)) {
|
||||
/* Unplug devices. See comment above flag definitions */
|
||||
if (val & (UNPLUG_IDE_SCSI_DISKS | UNPLUG_AUX_IDE_DISKS |
|
||||
UNPLUG_NVME_DISKS)) {
|
||||
DPRINTF("unplug disks\n");
|
||||
pci_unplug_disks(pci_dev->bus, val);
|
||||
}
|
||||
@ -349,14 +372,14 @@ static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
|
||||
* If VMDP was to control both disk and LAN it would use 4.
|
||||
* If it controlled just disk or just LAN, it would use 8 below.
|
||||
*/
|
||||
pci_unplug_disks(pci_dev->bus, UNPLUG_ALL_DISKS);
|
||||
pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
|
||||
pci_unplug_nics(pci_dev->bus);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
switch (val) {
|
||||
case 1:
|
||||
pci_unplug_disks(pci_dev->bus, UNPLUG_ALL_DISKS);
|
||||
pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
|
||||
break;
|
||||
case 2:
|
||||
pci_unplug_nics(pci_dev->bus);
|
||||
|
@ -1535,6 +1535,7 @@ static XenPTRegInfo xen_pt_emu_reg_igd_opregion[] = {
|
||||
.offset = 0x0,
|
||||
.size = 4,
|
||||
.init_val = 0,
|
||||
.emu_mask = 0xFFFFFFFF,
|
||||
.u.dw.read = xen_pt_intel_opregion_read,
|
||||
.u.dw.write = xen_pt_intel_opregion_write,
|
||||
},
|
||||
|
@ -535,7 +535,11 @@ int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base)
|
||||
return -1;
|
||||
}
|
||||
|
||||
xen_host_pci_get_word(hd, base + PCI_MSIX_FLAGS, &control);
|
||||
rc = xen_host_pci_get_word(hd, base + PCI_MSIX_FLAGS, &control);
|
||||
if (rc) {
|
||||
XEN_PT_ERR(d, "Failed to read PCI_MSIX_FLAGS field\n");
|
||||
return rc;
|
||||
}
|
||||
total_entries = control & PCI_MSIX_FLAGS_QSIZE;
|
||||
total_entries += 1;
|
||||
|
||||
@ -554,7 +558,11 @@ int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base)
|
||||
+ XC_PAGE_SIZE - 1)
|
||||
& XC_PAGE_MASK);
|
||||
|
||||
xen_host_pci_get_long(hd, base + PCI_MSIX_TABLE, &table_off);
|
||||
rc = xen_host_pci_get_long(hd, base + PCI_MSIX_TABLE, &table_off);
|
||||
if (rc) {
|
||||
XEN_PT_ERR(d, "Failed to read PCI_MSIX_TABLE field\n");
|
||||
goto error_out;
|
||||
}
|
||||
bar_index = msix->bar_index = table_off & PCI_MSIX_FLAGS_BIRMASK;
|
||||
table_off = table_off & ~PCI_MSIX_FLAGS_BIRMASK;
|
||||
msix->table_base = s->real_device.io_regions[bar_index].base_addr;
|
||||
|
@ -78,6 +78,21 @@ static inline void *xenforeignmemory_map(xc_interface *h, uint32_t dom,
|
||||
|
||||
extern xenforeignmemory_handle *xen_fmem;
|
||||
|
||||
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000
|
||||
|
||||
#define XEN_COMPAT_PHYSMAP
|
||||
static inline void *xenforeignmemory_map2(xenforeignmemory_handle *h,
|
||||
uint32_t dom, void *addr,
|
||||
int prot, int flags, size_t pages,
|
||||
const xen_pfn_t arr[/*pages*/],
|
||||
int err[/*pages*/])
|
||||
{
|
||||
assert(addr == NULL && flags == 0);
|
||||
return xenforeignmemory_map(h, dom, prot, pages, arr, err);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 40900
|
||||
|
||||
typedef xc_interface xendevicemodel_handle;
|
||||
|
@ -21,7 +21,9 @@ uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
|
||||
ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
|
||||
void xen_invalidate_map_cache_entry(uint8_t *buffer);
|
||||
void xen_invalidate_map_cache(void);
|
||||
|
||||
uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
|
||||
hwaddr new_phys_addr,
|
||||
hwaddr size);
|
||||
#else
|
||||
|
||||
static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
|
||||
@ -50,6 +52,13 @@ static inline void xen_invalidate_map_cache(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
|
||||
hwaddr new_phys_addr,
|
||||
hwaddr size)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* XEN_MAPCACHE_H */
|
||||
|
Loading…
Reference in New Issue
Block a user