[HVM] Allow HVM guest to request invalidation of foreign mappings via
authorkaf24@localhost.localdomain <kaf24@localhost.localdomain>
Sat, 27 Jan 2007 13:32:27 +0000 (13:32 +0000)
committerkaf24@localhost.localdomain <kaf24@localhost.localdomain>
Sat, 27 Jan 2007 13:32:27 +0000 (13:32 +0000)
an I/O port write.
Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
tools/ioemu/hw/xen_platform.c
tools/ioemu/target-i386-dm/exec-dm.c
tools/ioemu/vl.c
tools/ioemu/vl.h
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c

index a0e9f1e3975766ac99c183bee12f05bcd59ad2c5..cdff19c9d852fa93c69b061f2ab686c637ec2aca 100644 (file)
@@ -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)
index cfc82dd22179a8df7021adbccdea7a886d05bebc..35891ed0647667c3be33234827f311351ef6e7cb 100644 (file)
@@ -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
 
 
index f5a79ad7e51f6f60af15cebf5c52ffc9cbe5856c..ed29028d412619e9540215a366e4b3987a1e3715 100644 (file)
@@ -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)
index 9e4d92a17b2a9a145796a32a8743e678f3dcaa80..8535ba689ca24884ee624163e6a7d53b4b7a601d 100644 (file)
@@ -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;
index 7973f8682085c7e017929975865cc14ae3d66fb6..e6ff4107cb375182fa49f0d4dbabf2b18d6d698c 100644 (file)
@@ -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",