bitkeeper revision 1.705 (40226014Y-RJhXC4XKyIIvcyJtSHuQ)

memory.c, domain.c:
  Extend support for linear page tables by allowing page directories to map one another.
This commit is contained in:
kaf24@scramble.cl.cam.ac.uk committed 2004-02-05 15:24:04 +00:00
1 parent 7517f0c0f2
commit ff9575f410
2 files changed
+59 -7

No files matched your search

+19
View File
@@ -343,6 +343,7 @@ void free_all_dom_mem(struct task_struct *p)
{
struct list_head *ent, zombies;
struct pfn_info *page;
unsigned long x, y;
INIT_LIST_HEAD(&zombies);
@@ -394,6 +395,24 @@ void free_all_dom_mem(struct task_struct *p)
if ( test_and_clear_bit(_PGC_allocated, &page->count_and_flags) )
put_page(page);
/*
* Forcibly invalidate L2 tables at this point to break circular
* 'linear page table' references. This is okay because MMU structures
* are not shared across domains and this domain is now dead. Thus L2
* tables are not in use so a non-zero count means circular reference.
*/
y = page->type_and_flags;
do {
x = y;
if ( likely((x & (PGT_type_mask|PGT_validated)) !=
(PGT_l2_page_table|PGT_validated)) )
break;
y = cmpxchg(&page->type_and_flags, x, x & ~PGT_validated);
if ( likely(y == x) )
free_page_type(page, PGT_l2_page_table);
}
while ( unlikely(y != x) );
put_page(page);
}
}
+40 -7
View File
@@ -346,11 +346,22 @@ static int get_page_and_type_from_pagenr(unsigned long page_nr,
/*
* We allow an L2 table to map itself, to achieve a linear p.t. Note that this
* does not raise any reference counts.
* We allow an L2 tables to map each other (a.k.a. linear page tables). It
* needs some special care with reference counst and access permissions:
* 1. The mapping entry must be read-only, or the guest may get write access
* to its own PTEs.
* 2. We must only bump the reference counts for an *already validated*
* L2 table, or we can end up in a deadlock in get_page_type() by waiting
* on a validation that is required to complete that validation.
* 3. We only need to increment the reference counts for the mapped page
* frame if it is mapped by a different L2 table. This is sufficient and
* also necessary to allow validation of an L2 table mapping itself.
*/
static int check_linear_pagetable(l2_pgentry_t l2e, unsigned long pfn)
static int get_linear_pagetable(l2_pgentry_t l2e, unsigned long pfn)
{
unsigned long x, y;
struct pfn_info *page;
if ( (l2_pgentry_val(l2e) & _PAGE_RW) )
{
MEM_LOG("Attempt to create linear p.t. with write perms");
@@ -359,8 +370,27 @@ static int check_linear_pagetable(l2_pgentry_t l2e, unsigned long pfn)
if ( (l2_pgentry_val(l2e) >> PAGE_SHIFT) != pfn )
{
MEM_LOG("L2 tables may not map _other_ L2 tables!\n");
return 0;
/* Make sure the mapped frame belongs to the correct domain. */
if ( unlikely(!get_page_from_pagenr(l2_pgentry_to_pagenr(l2e))) )
return 0;
/*
* Make sure that the mapped frame is an already-validated L2 table.
* If so, atomically increment the count (checking for overflow).
*/
page = &frame_table[l2_pgentry_to_pagenr(l2e)];
y = page->type_and_flags;
do {
x = y;
if ( unlikely((x & PGT_count_mask) == PGT_count_mask) ||
unlikely((x & (PGT_type_mask|PGT_validated)) !=
(PGT_l2_page_table|PGT_validated)) )
{
put_page(page);
return 0;
}
}
while ( (y = cmpxchg(&page->type_and_flags, x, x + 1)) != x );
}
return 1;
@@ -406,7 +436,7 @@ static int get_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn)
if ( unlikely(!get_page_and_type_from_pagenr(
l2_pgentry_to_pagenr(l2e), PGT_l1_page_table)) )
return check_linear_pagetable(l2e, pfn);
return get_linear_pagetable(l2e, pfn);
return 1;
}
@@ -434,7 +464,10 @@ static void put_page_from_l1e(l1_pgentry_t l1e)
}
/* NB. Virtual address 'l2e' maps to a machine address within frame 'pfn'. */
/*
* NB. Virtual address 'l2e' maps to a machine address within frame 'pfn'.
* Note also that this automatically deals correctly with linear p.t.'s.
*/
static void put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn)
{
ASSERT(l2_pgentry_val(l2e) & _PAGE_PRESENT);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.