|
@@ -650,7 +650,7 @@ static unsigned long mfn_hash(unsigned long mfn)
|
|
}
|
|
}
|
|
|
|
|
|
/* Add an MFN override for a particular page */
|
|
/* Add an MFN override for a particular page */
|
|
-int m2p_add_override(unsigned long mfn, struct page *page)
|
|
|
|
|
|
+int m2p_add_override(unsigned long mfn, struct page *page, bool clear_pte)
|
|
{
|
|
{
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
unsigned long pfn;
|
|
unsigned long pfn;
|
|
@@ -662,7 +662,6 @@ int m2p_add_override(unsigned long mfn, struct page *page)
|
|
if (!PageHighMem(page)) {
|
|
if (!PageHighMem(page)) {
|
|
address = (unsigned long)__va(pfn << PAGE_SHIFT);
|
|
address = (unsigned long)__va(pfn << PAGE_SHIFT);
|
|
ptep = lookup_address(address, &level);
|
|
ptep = lookup_address(address, &level);
|
|
-
|
|
|
|
if (WARN(ptep == NULL || level != PG_LEVEL_4K,
|
|
if (WARN(ptep == NULL || level != PG_LEVEL_4K,
|
|
"m2p_add_override: pfn %lx not mapped", pfn))
|
|
"m2p_add_override: pfn %lx not mapped", pfn))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
@@ -674,10 +673,9 @@ int m2p_add_override(unsigned long mfn, struct page *page)
|
|
if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn))))
|
|
if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn))))
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
- if (!PageHighMem(page))
|
|
|
|
|
|
+ if (clear_pte && !PageHighMem(page))
|
|
/* Just zap old mapping for now */
|
|
/* Just zap old mapping for now */
|
|
pte_clear(&init_mm, address, ptep);
|
|
pte_clear(&init_mm, address, ptep);
|
|
-
|
|
|
|
spin_lock_irqsave(&m2p_override_lock, flags);
|
|
spin_lock_irqsave(&m2p_override_lock, flags);
|
|
list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]);
|
|
list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]);
|
|
spin_unlock_irqrestore(&m2p_override_lock, flags);
|
|
spin_unlock_irqrestore(&m2p_override_lock, flags);
|
|
@@ -685,7 +683,7 @@ int m2p_add_override(unsigned long mfn, struct page *page)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-int m2p_remove_override(struct page *page)
|
|
|
|
|
|
+int m2p_remove_override(struct page *page, bool clear_pte)
|
|
{
|
|
{
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
unsigned long mfn;
|
|
unsigned long mfn;
|
|
@@ -713,7 +711,7 @@ int m2p_remove_override(struct page *page)
|
|
spin_unlock_irqrestore(&m2p_override_lock, flags);
|
|
spin_unlock_irqrestore(&m2p_override_lock, flags);
|
|
set_phys_to_machine(pfn, page->index);
|
|
set_phys_to_machine(pfn, page->index);
|
|
|
|
|
|
- if (!PageHighMem(page))
|
|
|
|
|
|
+ if (clear_pte && !PageHighMem(page))
|
|
set_pte_at(&init_mm, address, ptep,
|
|
set_pte_at(&init_mm, address, ptep,
|
|
pfn_pte(pfn, PAGE_KERNEL));
|
|
pfn_pte(pfn, PAGE_KERNEL));
|
|
/* No tlb flush necessary because the caller already
|
|
/* No tlb flush necessary because the caller already
|