aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/x86_32/domain_page.c
diff options
context:
space:
mode:
Diffstat (limited to 'xen/arch/x86/x86_32/domain_page.c')
-rw-r--r--xen/arch/x86/x86_32/domain_page.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/xen/arch/x86/x86_32/domain_page.c b/xen/arch/x86/x86_32/domain_page.c
index db3237242c..8fe7b9b344 100644
--- a/xen/arch/x86/x86_32/domain_page.c
+++ b/xen/arch/x86/x86_32/domain_page.c
@@ -15,6 +15,7 @@
#include <asm/current.h>
#include <asm/flushtlb.h>
#include <asm/hardirq.h>
+#include <asm/hvm/support.h>
static inline struct vcpu *mapcache_current_vcpu(void)
{
@@ -58,10 +59,10 @@ void *map_domain_page(unsigned long pfn)
cache = &v->domain->arch.mapcache;
hashent = &cache->vcpu_maphash[vcpu].hash[MAPHASH_HASHFN(pfn)];
- if ( hashent->pfn == pfn )
+ if ( hashent->pfn == pfn && (idx = hashent->idx) != MAPHASHENT_NOTINUSE )
{
- idx = hashent->idx;
hashent->refcnt++;
+ ASSERT(idx < MAPCACHE_ENTRIES);
ASSERT(hashent->refcnt != 0);
ASSERT(l1e_get_pfn(cache->l1tab[idx]) == pfn);
goto out;
@@ -178,6 +179,30 @@ void mapcache_init(struct domain *d)
MAPHASHENT_NOTINUSE;
}
+paddr_t mapped_domain_page_to_maddr(void *va)
+/* Convert a pointer in a mapped domain page to a machine address.
+ * Takes any pointer that's valid for use in unmap_domain_page() */
+{
+ unsigned int idx;
+ struct vcpu *v;
+ struct mapcache *cache;
+ unsigned long pfn;
+
+ ASSERT(!in_irq());
+
+ ASSERT((void *)MAPCACHE_VIRT_START <= va);
+ ASSERT(va < (void *)MAPCACHE_VIRT_END);
+
+ v = mapcache_current_vcpu();
+
+ cache = &v->domain->arch.mapcache;
+
+ idx = ((unsigned long)va - MAPCACHE_VIRT_START) >> PAGE_SHIFT;
+ pfn = l1e_get_pfn(cache->l1tab[idx]);
+ return ((paddr_t) pfn << PAGE_SHIFT
+ | ((unsigned long) va & ~PAGE_MASK));
+}
+
#define GLOBALMAP_BITS (IOREMAP_MBYTES << (20 - PAGE_SHIFT))
static unsigned long inuse[BITS_TO_LONGS(GLOBALMAP_BITS)];
static unsigned long garbage[BITS_TO_LONGS(GLOBALMAP_BITS)];
@@ -233,6 +258,8 @@ void unmap_domain_page_global(void *va)
l1_pgentry_t *pl1e;
unsigned int idx;
+ ASSERT((__va >= IOREMAP_VIRT_START) && (__va <= (IOREMAP_VIRT_END - 1)));
+
/* /First/, we zap the PTE. */
pl2e = virt_to_xen_l2e(__va);
pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(__va);