Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 230855
b: refs/heads/master
c: 87f1d40
h: refs/heads/master
i:
  230853: 7a051a5
  230851: 37907eb
  230847: cfd36f9
v: v3
  • Loading branch information
Jeremy Fitzhardinge authored and Konrad Rzeszutek Wilk committed Jan 11, 2011
1 parent 6c0bf9a commit 24c3131
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a12b4eb34bb1ea16046c5b61e7a887e252cc1cce
refs/heads/master: 87f1d40a706bdebdc8f959b9ac291d0d8fdfcc7e
4 changes: 2 additions & 2 deletions trunk/arch/x86/include/asm/xen/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ extern unsigned int machine_to_phys_order;
extern unsigned long get_phys_to_machine(unsigned long pfn);
extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);

extern void m2p_add_override(unsigned long mfn, struct page *page);
extern void m2p_remove_override(struct page *page);
extern int m2p_add_override(unsigned long mfn, struct page *page);
extern int m2p_remove_override(struct page *page);
extern struct page *m2p_find_override(unsigned long mfn);
extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);

Expand Down
49 changes: 45 additions & 4 deletions trunk/arch/x86/xen/p2m.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/list.h>
#include <linux/hash.h>
#include <linux/sched.h>

#include <asm/cache.h>
#include <asm/setup.h>
Expand Down Expand Up @@ -404,34 +405,74 @@ static unsigned long mfn_hash(unsigned long mfn)
}

/* Add an MFN override for a particular page */
void m2p_add_override(unsigned long mfn, struct page *page)
int m2p_add_override(unsigned long mfn, struct page *page)
{
unsigned long flags;
unsigned long pfn = page_to_pfn(page);
unsigned long pfn;
unsigned long address;
unsigned level;
pte_t *ptep = NULL;

pfn = page_to_pfn(page);
if (!PageHighMem(page)) {
address = (unsigned long)__va(pfn << PAGE_SHIFT);
ptep = lookup_address(address, &level);

if (WARN(ptep == NULL || level != PG_LEVEL_4K,
"m2p_add_override: pfn %lx not mapped", pfn))
return -EINVAL;
}

page->private = mfn;
page->index = pfn_to_mfn(pfn);

__set_phys_to_machine(pfn, FOREIGN_FRAME(mfn));
if (!PageHighMem(page))
/* Just zap old mapping for now */
pte_clear(&init_mm, address, ptep);

spin_lock_irqsave(&m2p_override_lock, flags);
list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]);
spin_unlock_irqrestore(&m2p_override_lock, flags);

return 0;
}

void m2p_remove_override(struct page *page)
int m2p_remove_override(struct page *page)
{
unsigned long flags;
unsigned long mfn;
unsigned long pfn;
unsigned long address;
unsigned level;
pte_t *ptep = NULL;

pfn = page_to_pfn(page);
mfn = get_phys_to_machine(pfn);
if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT))
return;
return -EINVAL;

if (!PageHighMem(page)) {
address = (unsigned long)__va(pfn << PAGE_SHIFT);
ptep = lookup_address(address, &level);

if (WARN(ptep == NULL || level != PG_LEVEL_4K,
"m2p_remove_override: pfn %lx not mapped", pfn))
return -EINVAL;
}

spin_lock_irqsave(&m2p_override_lock, flags);
list_del(&page->lru);
spin_unlock_irqrestore(&m2p_override_lock, flags);
__set_phys_to_machine(pfn, page->index);

if (!PageHighMem(page))
set_pte_at(&init_mm, address, ptep,
pfn_pte(pfn, PAGE_KERNEL));
/* No tlb flush necessary because the caller already
* left the pte unmapped. */

return 0;
}

struct page *m2p_find_override(unsigned long mfn)
Expand Down
16 changes: 13 additions & 3 deletions trunk/drivers/xen/grant-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
unsigned long mfn;

ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count);
if (ret)
return ret;

for (i = 0; i < count; i++) {
/* m2p override only supported for GNTMAP_contains_pte mappings */
Expand All @@ -463,7 +465,9 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
pte = (pte_t *) (mfn_to_virt(PFN_DOWN(map_ops[i].host_addr)) +
(map_ops[i].host_addr & ~PAGE_MASK));
mfn = pte_mfn(*pte);
m2p_add_override(mfn, pages[i]);
ret = m2p_add_override(mfn, pages[i]);
if (ret)
return ret;
}

return ret;
Expand All @@ -476,8 +480,14 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
int i, ret;

ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count);
for (i = 0; i < count; i++)
m2p_remove_override(pages[i]);
if (ret)
return ret;

for (i = 0; i < count; i++) {
ret = m2p_remove_override(pages[i]);
if (ret)
return ret;
}

return ret;
}
Expand Down

0 comments on commit 24c3131

Please sign in to comment.