mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86_32: [un]map_domain_page() is now IRQ safe.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
This commit is contained in:
1 parent
df57b09eb6
commit
a11b6c53f6
1 file changed
+12
-9
@@ -43,15 +43,13 @@ static inline struct vcpu *mapcache_current_vcpu(void)
|
||||
|
||||
void *map_domain_page(unsigned long mfn)
|
||||
{
|
||||
unsigned long va;
|
||||
unsigned int idx, i, flags;
|
||||
unsigned long va, flags;
|
||||
unsigned int idx, i;
|
||||
struct vcpu *v;
|
||||
struct mapcache_domain *dcache;
|
||||
struct mapcache_vcpu *vcache;
|
||||
struct vcpu_maphash_entry *hashent;
|
||||
|
||||
ASSERT(!in_irq());
|
||||
|
||||
perfc_incr(map_domain_page_count);
|
||||
|
||||
v = mapcache_current_vcpu();
|
||||
@@ -59,6 +57,8 @@ void *map_domain_page(unsigned long mfn)
|
||||
dcache = &v->domain->arch.mapcache;
|
||||
vcache = &v->arch.mapcache;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
hashent = &vcache->hash[MAPHASH_HASHFN(mfn)];
|
||||
if ( hashent->mfn == mfn )
|
||||
{
|
||||
@@ -70,7 +70,7 @@ void *map_domain_page(unsigned long mfn)
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&dcache->lock, flags);
|
||||
spin_lock(&dcache->lock);
|
||||
|
||||
/* Has some other CPU caused a wrap? We must flush if so. */
|
||||
if ( unlikely(dcache->epoch != vcache->shadow_epoch) )
|
||||
@@ -106,11 +106,12 @@ void *map_domain_page(unsigned long mfn)
|
||||
set_bit(idx, dcache->inuse);
|
||||
dcache->cursor = idx + 1;
|
||||
|
||||
spin_unlock_irqrestore(&dcache->lock, flags);
|
||||
spin_unlock(&dcache->lock);
|
||||
|
||||
l1e_write(&dcache->l1tab[idx], l1e_from_pfn(mfn, __PAGE_HYPERVISOR));
|
||||
|
||||
out:
|
||||
local_irq_restore(flags);
|
||||
va = MAPCACHE_VIRT_START + (idx << PAGE_SHIFT);
|
||||
return (void *)va;
|
||||
}
|
||||
@@ -120,11 +121,9 @@ void unmap_domain_page(const void *va)
|
||||
unsigned int idx;
|
||||
struct vcpu *v;
|
||||
struct mapcache_domain *dcache;
|
||||
unsigned long mfn;
|
||||
unsigned long mfn, flags;
|
||||
struct vcpu_maphash_entry *hashent;
|
||||
|
||||
ASSERT(!in_irq());
|
||||
|
||||
ASSERT((void *)MAPCACHE_VIRT_START <= va);
|
||||
ASSERT(va < (void *)MAPCACHE_VIRT_END);
|
||||
|
||||
@@ -136,6 +135,8 @@ void unmap_domain_page(const void *va)
|
||||
mfn = l1e_get_pfn(dcache->l1tab[idx]);
|
||||
hashent = &v->arch.mapcache.hash[MAPHASH_HASHFN(mfn)];
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
if ( hashent->idx == idx )
|
||||
{
|
||||
ASSERT(hashent->mfn == mfn);
|
||||
@@ -164,6 +165,8 @@ void unmap_domain_page(const void *va)
|
||||
/* /Second/, mark as garbage. */
|
||||
set_bit(idx, dcache->garbage);
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
void mapcache_domain_init(struct domain *d)
|
||||
|
||||