aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@localhost.localdomain <kaf24@localhost.localdomain>2007-01-27 13:32:27 +0000
committerkaf24@localhost.localdomain <kaf24@localhost.localdomain>2007-01-27 13:32:27 +0000
commit249c2a8ce6f2e8f193f73918dc1aeafe19b6a739 (patch)
tree38d12677f141c6cdf1ad53d08514f6ab4763ea79
parentf42eb8636f525fce8a8bec63dab14c24e3679641 (diff)
downloadxen-249c2a8ce6f2e8f193f73918dc1aeafe19b6a739.tar.gz
xen-249c2a8ce6f2e8f193f73918dc1aeafe19b6a739.tar.bz2
xen-249c2a8ce6f2e8f193f73918dc1aeafe19b6a739.zip
[HVM] Allow HVM guest to request invalidation of foreign mappings via
an I/O port write. Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
-rw-r--r--tools/ioemu/hw/xen_platform.c11
-rw-r--r--tools/ioemu/target-i386-dm/exec-dm.c12
-rw-r--r--tools/ioemu/vl.c38
-rw-r--r--tools/ioemu/vl.h17
-rw-r--r--unmodified_drivers/linux-2.6/platform-pci/platform-pci.c10
5 files changed, 64 insertions, 24 deletions
diff --git a/tools/ioemu/hw/xen_platform.c b/tools/ioemu/hw/xen_platform.c
index a0e9f1e397..cdff19c9d8 100644
--- a/tools/ioemu/hw/xen_platform.c
+++ b/tools/ioemu/hw/xen_platform.c
@@ -31,19 +31,14 @@ extern FILE *logfile;
static void platform_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
- return;
-}
-
-static uint32_t platform_ioport_read(void *opaque, uint32_t addr)
-{
- return 0;
+ if (val == 0)
+ qemu_invalidate_map_cache();
}
static void platform_ioport_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
- register_ioport_write(addr, 16, 4, platform_ioport_write, NULL);
- register_ioport_read(addr, 16, 1, platform_ioport_read, NULL);
+ register_ioport_write(addr, 1, 1, platform_ioport_write, NULL);
}
static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
diff --git a/tools/ioemu/target-i386-dm/exec-dm.c b/tools/ioemu/target-i386-dm/exec-dm.c
index cfc82dd221..35891ed064 100644
--- a/tools/ioemu/target-i386-dm/exec-dm.c
+++ b/tools/ioemu/target-i386-dm/exec-dm.c
@@ -129,18 +129,8 @@ FILE *logfile;
int loglevel;
-#if defined(__i386__) || defined(__x86_64__)
-#define MAPCACHE
-#endif
-
#ifdef MAPCACHE
-#include <pthread.h>
-static pthread_mutex_t mapcache_mutex;
-#define mapcache_lock() pthread_mutex_lock(&mapcache_mutex)
-#define mapcache_unlock() pthread_mutex_unlock(&mapcache_mutex)
-#else
-#define mapcache_lock() ( (void)0 )
-#define mapcache_unlock() ( (void)0 )
+pthread_mutex_t mapcache_mutex;
#endif
diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c
index f5a79ad7e5..ed29028d41 100644
--- a/tools/ioemu/vl.c
+++ b/tools/ioemu/vl.c
@@ -285,7 +285,7 @@ int register_ioport_write(int start, int length, int size,
for(i = start; i < start + length; i += size) {
ioport_write_table[bsize][i] = func;
if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
- hw_error("register_ioport_read: invalid opaque");
+ hw_error("register_ioport_write: invalid opaque");
ioport_opaque[i] = opaque;
}
return 0;
@@ -5826,6 +5826,10 @@ void suspend(int sig)
static struct map_cache *mapcache_entry;
static unsigned long nr_buckets;
+/* For most cases (>99.9%), the page address is the same. */
+static unsigned long last_address_index = ~0UL;
+static uint8_t *last_address_vaddr;
+
static int qemu_map_cache_init(unsigned long nr_pages)
{
unsigned long max_pages = MAX_MCACHE_SIZE >> PAGE_SHIFT;
@@ -5862,10 +5866,6 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr)
unsigned long address_index = phys_addr >> MCACHE_BUCKET_SHIFT;
unsigned long address_offset = phys_addr & (MCACHE_BUCKET_SIZE-1);
- /* For most cases (>99.9%), the page address is the same. */
- static unsigned long last_address_index = ~0UL;
- static uint8_t *last_address_vaddr;
-
if (address_index == last_address_index)
return last_address_vaddr + address_offset;
@@ -5905,6 +5905,34 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr)
return last_address_vaddr + address_offset;
}
+
+void qemu_invalidate_map_cache(void)
+{
+ unsigned long i;
+
+ mapcache_lock();
+
+ for (i = 0; i < nr_buckets; i++) {
+ struct map_cache *entry = &mapcache_entry[i];
+
+ if (entry->vaddr_base == NULL)
+ continue;
+
+ errno = munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE);
+ if (errno) {
+ fprintf(logfile, "unmap fails %d\n", errno);
+ exit(-1);
+ }
+
+ entry->paddr_index = 0;
+ entry->vaddr_base = NULL;
+ }
+
+ last_address_index = ~0UL;
+ last_address_vaddr = NULL;
+
+ mapcache_unlock();
+}
#endif
int main(int argc, char **argv)
diff --git a/tools/ioemu/vl.h b/tools/ioemu/vl.h
index 9e4d92a17b..8535ba689c 100644
--- a/tools/ioemu/vl.h
+++ b/tools/ioemu/vl.h
@@ -158,6 +158,9 @@ extern FILE *logfile;
#if defined(__i386__) || defined(__x86_64__)
+
+#define MAPCACHE
+
#if defined(__i386__)
#define MAX_MCACHE_SIZE 0x40000000 /* 1GB max for x86 */
#define MCACHE_BUCKET_SHIFT 16
@@ -174,6 +177,20 @@ struct map_cache {
};
uint8_t *qemu_map_cache(target_phys_addr_t phys_addr);
+void qemu_invalidate_map_cache(void);
+
+#include <pthread.h>
+extern pthread_mutex_t mapcache_mutex;
+#define mapcache_lock() pthread_mutex_lock(&mapcache_mutex)
+#define mapcache_unlock() pthread_mutex_unlock(&mapcache_mutex)
+
+#else
+
+#define qemu_invalidate_map_cache() ((void)0)
+
+#define mapcache_lock() ((void)0)
+#define mapcache_unlock() ((void)0)
+
#endif
extern int xc_handle;
diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
index 7973f86820..e6ff4107cb 100644
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
@@ -214,6 +214,14 @@ static uint64_t get_callback_via(struct pci_dev *pdev)
#endif
}
+/* Invalidate foreign mappings (e.g., in qemu-based device model). */
+static uint16_t invlmap_port;
+void xen_invalidate_foreign_mappings(void)
+{
+ outb(0, invlmap_port);
+}
+EXPORT_SYMBOL(xen_invalidate_foreign_mappings);
+
static int __devinit platform_pci_init(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -239,6 +247,8 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,
return -ENOENT;
}
+ invlmap_port = ioaddr;
+
if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL)
{
printk(KERN_ERR ":MEM I/O resource 0x%lx @ 0x%lx busy\n",