mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
bitkeeper revision 1.1159.39.1 (41237986oL9caNrlRwHT0c1soQ19YQ)
Clean up current support for foreign page mappings.
This commit is contained in:
1 parent
83e32915fb
commit
67f7d198ef
11 files changed
+129
-152
No files matched your search
@@ -117,10 +117,9 @@ int direct_remap_area_pages(struct mm_struct *mm,
|
||||
|
||||
if ( domid != 0 )
|
||||
{
|
||||
u[0].val = (unsigned long)(domid<<16) & ~0xFFFFUL;
|
||||
u[0].ptr = (unsigned long)(domid<< 0) & ~0xFFFFUL;
|
||||
u[0].ptr |= MMU_EXTENDED_COMMAND;
|
||||
u[0].val |= MMUEXT_SET_SUBJECTDOM;
|
||||
u[0].ptr = MMU_EXTENDED_COMMAND;
|
||||
u[0].val = MMUEXT_SET_FOREIGNDOM;
|
||||
u[0].val |= (unsigned long)domid << 16;
|
||||
v = w = &u[1];
|
||||
}
|
||||
else
|
||||
|
||||
@@ -417,10 +417,9 @@ int direct_remap_area_pages(struct mm_struct *mm,
|
||||
|
||||
if ( domid != 0 )
|
||||
{
|
||||
u[0].val = (unsigned long)(domid<<16) & ~0xFFFFUL;
|
||||
u[0].ptr = (unsigned long)(domid<< 0) & ~0xFFFFUL;
|
||||
u[0].ptr |= MMU_EXTENDED_COMMAND;
|
||||
u[0].val |= MMUEXT_SET_SUBJECTDOM;
|
||||
u[0].ptr = MMU_EXTENDED_COMMAND;
|
||||
u[0].val = MMUEXT_SET_FOREIGNDOM;
|
||||
u[0].val |= (unsigned long)domid << 16;
|
||||
v = w = &u[1];
|
||||
}
|
||||
else
|
||||
|
||||
@@ -205,11 +205,10 @@ static void net_rx_action(unsigned long unused)
|
||||
new_mfn = get_new_mfn();
|
||||
|
||||
mmu[0].ptr = (new_mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
|
||||
mmu[0].val = __pa(vdata) >> PAGE_SHIFT;
|
||||
mmu[1].val = (unsigned long)(netif->domid<<16) & ~0xFFFFUL;
|
||||
mmu[1].ptr = (unsigned long)(netif->domid<< 0) & ~0xFFFFUL;
|
||||
mmu[1].ptr |= MMU_EXTENDED_COMMAND;
|
||||
mmu[1].val |= MMUEXT_SET_SUBJECTDOM;
|
||||
mmu[0].val = __pa(vdata) >> PAGE_SHIFT;
|
||||
mmu[1].ptr = MMU_EXTENDED_COMMAND;
|
||||
mmu[1].val = MMUEXT_SET_FOREIGNDOM;
|
||||
mmu[1].val |= (unsigned long)netif->domid << 16;
|
||||
mmu[2].ptr = (mdata & PAGE_MASK) | MMU_EXTENDED_COMMAND;
|
||||
mmu[2].val = MMUEXT_REASSIGN_PAGE;
|
||||
|
||||
|
||||
@@ -140,10 +140,9 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
|
||||
|
||||
if ( m.dom != 0 )
|
||||
{
|
||||
u[0].val = (unsigned long)(m.dom<<16) & ~0xFFFFUL;
|
||||
u[0].ptr = (unsigned long)(m.dom<< 0) & ~0xFFFFUL;
|
||||
u[0].ptr |= MMU_EXTENDED_COMMAND;
|
||||
u[0].val |= MMUEXT_SET_SUBJECTDOM;
|
||||
u[0].ptr = MMU_EXTENDED_COMMAND;
|
||||
u[0].val = MMUEXT_SET_FOREIGNDOM;
|
||||
u[0].val |= (unsigned long)m.dom << 16;
|
||||
v = w = &u[1];
|
||||
}
|
||||
else
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@ int xc_rrobin_global_set(int xc_handle, u64 slice);
|
||||
|
||||
int xc_rrobin_global_get(int xc_handle, u64 *slice);
|
||||
|
||||
#define DOMID_SELF (0x7FFEU)
|
||||
#define DOMID_SELF (0x7FF0U)
|
||||
|
||||
typedef struct {
|
||||
#define EVTCHNSTAT_closed 0 /* Chennel is not in use. */
|
||||
|
||||
@@ -228,11 +228,9 @@ static int flush_mmu_updates(int xc_handle, mmu_t *mmu)
|
||||
if ( mmu->idx == FIRST_MMU_UPDATE )
|
||||
return 0;
|
||||
|
||||
/* The first two requests set the correct subject domain (PTS and GPS). */
|
||||
mmu->updates[0].val = (unsigned long)(mmu->subject<<16) & ~0xFFFFUL;
|
||||
mmu->updates[0].ptr = (unsigned long)(mmu->subject<< 0) & ~0xFFFFUL;
|
||||
mmu->updates[0].ptr |= MMU_EXTENDED_COMMAND;
|
||||
mmu->updates[0].val |= MMUEXT_SET_SUBJECTDOM | SET_PAGETABLE_SUBJECTDOM;
|
||||
mmu->updates[0].ptr = MMU_EXTENDED_COMMAND;
|
||||
mmu->updates[0].val = MMUEXT_SET_FOREIGNDOM;
|
||||
mmu->updates[0].val |= (unsigned long)mmu->subject << 16;
|
||||
|
||||
hypercall.op = __HYPERVISOR_mmu_update;
|
||||
hypercall.arg[0] = (unsigned long)mmu->updates;
|
||||
|
||||
+67
-74
@@ -127,14 +127,15 @@ static struct {
|
||||
#define DOP_RELOAD_LDT (1<<1) /* Reload the LDT shadow mapping. */
|
||||
unsigned long deferred_ops;
|
||||
unsigned long cr0;
|
||||
/* General-Purpose Subject, Page-Table Subject */
|
||||
struct domain *gps, *pts;
|
||||
/* If non-NULL, specifies a foreign subject domain for some operations. */
|
||||
struct domain *foreign;
|
||||
} percpu_info[NR_CPUS] __cacheline_aligned;
|
||||
|
||||
/* Determine the current General-Purpose Subject or Page-Table Subject. */
|
||||
#define PTS (percpu_info[smp_processor_id()].pts ? : current)
|
||||
#define GPS (percpu_info[smp_processor_id()].gps ? : current)
|
||||
|
||||
/*
|
||||
* Returns the current foreign domain; defaults to the currently-executing
|
||||
* domain if a foreign override hasn't been specified.
|
||||
*/
|
||||
#define FOREIGNDOM (percpu_info[smp_processor_id()].foreign ? : current)
|
||||
|
||||
void ptwr_init_backpointers(void);
|
||||
|
||||
@@ -283,7 +284,9 @@ static inline void set_l1_page_va(unsigned long pfn,
|
||||
* 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 get_linear_pagetable(l2_pgentry_t l2e, unsigned long pfn)
|
||||
static int
|
||||
get_linear_pagetable(
|
||||
l2_pgentry_t l2e, unsigned long pfn, struct domain *d)
|
||||
{
|
||||
u32 x, y;
|
||||
struct pfn_info *page;
|
||||
@@ -297,7 +300,7 @@ static int get_linear_pagetable(l2_pgentry_t l2e, unsigned long pfn)
|
||||
if ( (l2_pgentry_val(l2e) >> PAGE_SHIFT) != pfn )
|
||||
{
|
||||
/* Make sure the mapped frame belongs to the correct domain. */
|
||||
if ( unlikely(!get_page_from_pagenr(l2_pgentry_to_pagenr(l2e), PTS)) )
|
||||
if ( unlikely(!get_page_from_pagenr(l2_pgentry_to_pagenr(l2e), d)) )
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -323,7 +326,9 @@ static int get_linear_pagetable(l2_pgentry_t l2e, unsigned long pfn)
|
||||
}
|
||||
|
||||
|
||||
static int get_page_from_l1e(l1_pgentry_t l1e)
|
||||
static int
|
||||
get_page_from_l1e(
|
||||
l1_pgentry_t l1e, struct domain *d)
|
||||
{
|
||||
unsigned long l1v = l1_pgentry_val(l1e);
|
||||
unsigned long pfn = l1_pgentry_to_pagenr(l1e);
|
||||
@@ -353,19 +358,21 @@ static int get_page_from_l1e(l1_pgentry_t l1e)
|
||||
if ( l1v & _PAGE_RW )
|
||||
{
|
||||
if ( unlikely(!get_page_and_type_from_pagenr(
|
||||
pfn, PGT_writeable_page, GPS)) )
|
||||
pfn, PGT_writeable_page, d)) )
|
||||
return 0;
|
||||
set_bit(_PGC_tlb_flush_on_type_change,
|
||||
&frame_table[pfn].u.inuse.count_info);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return get_page_from_pagenr(pfn, GPS);
|
||||
return get_page_from_pagenr(pfn, d);
|
||||
}
|
||||
|
||||
|
||||
/* NB. Virtual address 'l2e' maps to a machine address within frame 'pfn'. */
|
||||
static int get_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn)
|
||||
static int
|
||||
get_page_from_l2e(
|
||||
l2_pgentry_t l2e, unsigned long pfn, struct domain *d)
|
||||
{
|
||||
if ( !(l2_pgentry_val(l2e) & _PAGE_PRESENT) )
|
||||
return 1;
|
||||
@@ -378,8 +385,8 @@ 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, PTS)) )
|
||||
return get_linear_pagetable(l2e, pfn);
|
||||
l2_pgentry_to_pagenr(l2e), PGT_l1_page_table, d)) )
|
||||
return get_linear_pagetable(l2e, pfn, d);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -423,14 +430,15 @@ static void put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn)
|
||||
|
||||
static int alloc_l2_table(struct pfn_info *page)
|
||||
{
|
||||
unsigned long page_nr = page - frame_table;
|
||||
l2_pgentry_t *pl2e;
|
||||
int i;
|
||||
struct domain *d = page->u.inuse.domain;
|
||||
unsigned long page_nr = page_to_pfn(page);
|
||||
l2_pgentry_t *pl2e;
|
||||
int i;
|
||||
|
||||
pl2e = map_domain_mem(page_nr << PAGE_SHIFT);
|
||||
|
||||
for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ ) {
|
||||
if ( unlikely(!get_page_from_l2e(pl2e[i], page_nr)) )
|
||||
if ( unlikely(!get_page_from_l2e(pl2e[i], page_nr, d)) )
|
||||
goto fail;
|
||||
set_l1_page_va(l2_pgentry_val(pl2e[i]) >> PAGE_SHIFT, i);
|
||||
}
|
||||
@@ -461,14 +469,15 @@ static int alloc_l2_table(struct pfn_info *page)
|
||||
|
||||
static int alloc_l1_table(struct pfn_info *page)
|
||||
{
|
||||
unsigned long page_nr = page - frame_table;
|
||||
l1_pgentry_t *pl1e;
|
||||
int i;
|
||||
struct domain *d = page->u.inuse.domain;
|
||||
unsigned long page_nr = page_to_pfn(page);
|
||||
l1_pgentry_t *pl1e;
|
||||
int i;
|
||||
|
||||
pl1e = map_domain_mem(page_nr << PAGE_SHIFT);
|
||||
|
||||
for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ )
|
||||
if ( unlikely(!get_page_from_l1e(pl1e[i])) )
|
||||
if ( unlikely(!get_page_from_l1e(pl1e[i], d)) )
|
||||
goto fail;
|
||||
|
||||
unmap_domain_mem(pl1e);
|
||||
@@ -552,7 +561,7 @@ static int mod_l2_entry(l2_pgentry_t *pl2e,
|
||||
if ( ((l2_pgentry_val(ol2e) ^ l2_pgentry_val(nl2e)) & ~0xffe) == 0 )
|
||||
return update_l2e(pl2e, ol2e, nl2e);
|
||||
|
||||
if ( unlikely(!get_page_from_l2e(nl2e, pfn)) )
|
||||
if ( unlikely(!get_page_from_l2e(nl2e, pfn, current)) )
|
||||
return 0;
|
||||
|
||||
set_l1_page_va(l2_pgentry_val(nl2e) >> PAGE_SHIFT,
|
||||
@@ -615,7 +624,7 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e)
|
||||
if ( ((l1_pgentry_val(ol1e) ^ l1_pgentry_val(nl1e)) & ~0xffc) == 0 )
|
||||
return update_l1e(pl1e, ol1e, nl1e);
|
||||
|
||||
if ( unlikely(!get_page_from_l1e(nl1e)) )
|
||||
if ( unlikely(!get_page_from_l1e(nl1e, FOREIGNDOM)) )
|
||||
return 0;
|
||||
|
||||
if ( unlikely(!update_l1e(pl1e, ol1e, nl1e)) )
|
||||
@@ -669,42 +678,28 @@ int alloc_page_type(struct pfn_info *page, unsigned int type)
|
||||
|
||||
void free_page_type(struct pfn_info *page, unsigned int type)
|
||||
{
|
||||
struct domain *d = page->u.inuse.domain;
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case PGT_l1_page_table:
|
||||
free_l1_table(page);
|
||||
if ( unlikely(current->mm.shadow_mode) &&
|
||||
(get_shadow_status(¤t->mm,
|
||||
page-frame_table) & PSH_shadowed) )
|
||||
{
|
||||
/*
|
||||
* Using 'current->mm' is safe and correct because page-table pages
|
||||
* are not shared across domains. Updates to such pages' types are
|
||||
* thus only done within the context of the owning domain. The one
|
||||
* exception is when destroying a domain; however, this is not a
|
||||
* problem as the currently-executing domain will not have this MFN
|
||||
* shadowed, and at domain end-of-day we explicitly unshadow
|
||||
* everything so that nothing will get left lying around.
|
||||
*/
|
||||
unshadow_table( page-frame_table, type );
|
||||
put_shadow_status(¤t->mm);
|
||||
}
|
||||
break;
|
||||
|
||||
case PGT_l2_page_table:
|
||||
free_l2_table(page);
|
||||
if ( unlikely(current->mm.shadow_mode) &&
|
||||
(get_shadow_status(¤t->mm,
|
||||
page-frame_table) & PSH_shadowed) )
|
||||
{
|
||||
unshadow_table( page-frame_table, type );
|
||||
put_shadow_status(¤t->mm);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
if ( unlikely(d->mm.shadow_mode) &&
|
||||
(get_shadow_status(&d->mm, page_to_pfn(page)) & PSH_shadowed) )
|
||||
{
|
||||
unshadow_table(page_to_pfn(page), type);
|
||||
put_shadow_status(&d->mm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -719,8 +714,6 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
u32 x, y;
|
||||
domid_t domid;
|
||||
|
||||
cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
|
||||
|
||||
switch ( cmd )
|
||||
{
|
||||
case MMUEXT_PIN_L1_TABLE:
|
||||
@@ -728,7 +721,7 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
okay = get_page_and_type_from_pagenr(
|
||||
pfn,
|
||||
(cmd==MMUEXT_PIN_L2_TABLE) ? PGT_l2_page_table : PGT_l1_page_table,
|
||||
PTS);
|
||||
FOREIGNDOM);
|
||||
if ( unlikely(!okay) )
|
||||
{
|
||||
MEM_LOG("Error while pinning pfn %08lx", pfn);
|
||||
@@ -748,7 +741,7 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
break;
|
||||
|
||||
case MMUEXT_UNPIN_TABLE:
|
||||
if ( unlikely(!(okay = get_page_from_pagenr(pfn, PTS))) )
|
||||
if ( unlikely(!(okay = get_page_from_pagenr(pfn, FOREIGNDOM))) )
|
||||
{
|
||||
MEM_LOG("Page %08lx bad domain (dom=%p)",
|
||||
ptr, page->u.inuse.domain);
|
||||
@@ -829,8 +822,8 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
break;
|
||||
}
|
||||
|
||||
case MMUEXT_SET_SUBJECTDOM:
|
||||
domid = ((domid_t)((ptr&~0xFFFF)|(val>>16)));
|
||||
case MMUEXT_SET_FOREIGNDOM:
|
||||
domid = (domid_t)(val >> 16);
|
||||
|
||||
if ( !IS_PRIV(d) )
|
||||
{
|
||||
@@ -840,12 +833,11 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( percpu_info[cpu].gps != NULL )
|
||||
put_domain(percpu_info[cpu].gps);
|
||||
percpu_info[cpu].gps = find_domain_by_id(domid);
|
||||
percpu_info[cpu].pts = (val & SET_PAGETABLE_SUBJECTDOM) ?
|
||||
percpu_info[cpu].gps : NULL;
|
||||
if ( percpu_info[cpu].gps == NULL )
|
||||
if ( (e = percpu_info[cpu].foreign) != NULL )
|
||||
put_domain(e);
|
||||
|
||||
percpu_info[cpu].foreign = e = find_domain_by_id(domid);
|
||||
if ( e == NULL )
|
||||
{
|
||||
MEM_LOG("Unknown domain '%u'", domid);
|
||||
okay = 0;
|
||||
@@ -861,9 +853,10 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
break;
|
||||
}
|
||||
|
||||
if ( unlikely((e = percpu_info[cpu].gps) == NULL) )
|
||||
e = percpu_info[cpu].foreign;
|
||||
if ( unlikely(e == NULL) )
|
||||
{
|
||||
MEM_LOG("No GPS to reassign pfn %08lx to", pfn);
|
||||
MEM_LOG("No FOREIGNDOM to reassign pfn %08lx to", pfn);
|
||||
okay = 0;
|
||||
break;
|
||||
}
|
||||
@@ -941,10 +934,10 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
spin_unlock(&e->page_alloc_lock);
|
||||
break;
|
||||
|
||||
case MMUEXT_RESET_SUBJECTDOM:
|
||||
if ( percpu_info[cpu].gps != NULL )
|
||||
put_domain(percpu_info[cpu].gps);
|
||||
percpu_info[cpu].gps = percpu_info[cpu].pts = NULL;
|
||||
case MMUEXT_CLEAR_FOREIGNDOM:
|
||||
if ( (e = percpu_info[cpu].foreign) != NULL )
|
||||
put_domain(e);
|
||||
percpu_info[cpu].foreign = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -992,7 +985,7 @@ int do_mmu_update(mmu_update_t *ureqs, int count, int *success_count)
|
||||
* MMU_NORMAL_PT_UPDATE: Normal update to any level of page table.
|
||||
*/
|
||||
case MMU_NORMAL_PT_UPDATE:
|
||||
if ( unlikely(!get_page_from_pagenr(pfn, PTS)) )
|
||||
if ( unlikely(!get_page_from_pagenr(pfn, current)) )
|
||||
{
|
||||
MEM_LOG("Could not get page for normal update");
|
||||
break;
|
||||
@@ -1064,7 +1057,7 @@ int do_mmu_update(mmu_update_t *ureqs, int count, int *success_count)
|
||||
break;
|
||||
|
||||
case MMU_MACHPHYS_UPDATE:
|
||||
if ( unlikely(!get_page_from_pagenr(pfn, GPS)) )
|
||||
if ( unlikely(!get_page_from_pagenr(pfn, FOREIGNDOM)) )
|
||||
{
|
||||
MEM_LOG("Could not get page for mach->phys update");
|
||||
break;
|
||||
@@ -1121,10 +1114,10 @@ int do_mmu_update(mmu_update_t *ureqs, int count, int *success_count)
|
||||
if ( deferred_ops & DOP_RELOAD_LDT )
|
||||
(void)map_ldt_shadow_page(0);
|
||||
|
||||
if ( unlikely(percpu_info[cpu].gps != NULL) )
|
||||
if ( unlikely(percpu_info[cpu].foreign != NULL) )
|
||||
{
|
||||
put_domain(percpu_info[cpu].gps);
|
||||
percpu_info[cpu].gps = percpu_info[cpu].pts = NULL;
|
||||
put_domain(percpu_info[cpu].foreign);
|
||||
percpu_info[cpu].foreign = NULL;
|
||||
}
|
||||
|
||||
if ( unlikely(success_count != NULL) )
|
||||
@@ -1215,7 +1208,7 @@ int do_update_va_mapping_otherdomain(unsigned long page_nr,
|
||||
|
||||
cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
|
||||
|
||||
percpu_info[cpu].gps = d = find_domain_by_id(domid);
|
||||
percpu_info[cpu].foreign = d = find_domain_by_id(domid);
|
||||
if ( unlikely(d == NULL) )
|
||||
{
|
||||
MEM_LOG("Unknown domain '%u'", domid);
|
||||
@@ -1225,7 +1218,7 @@ int do_update_va_mapping_otherdomain(unsigned long page_nr,
|
||||
rc = do_update_va_mapping(page_nr, val, flags);
|
||||
|
||||
put_domain(d);
|
||||
percpu_info[cpu].gps = NULL;
|
||||
percpu_info[cpu].foreign = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1314,7 +1307,7 @@ void ptwr_reconnect_disconnected(unsigned long addr)
|
||||
}
|
||||
if (unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT))
|
||||
put_page_from_l1e(ol1e);
|
||||
if (unlikely(!get_page_from_l1e(nl1e)))
|
||||
if (unlikely(!get_page_from_l1e(nl1e, current)))
|
||||
BUG();
|
||||
}
|
||||
unmap_domain_mem(pl1e);
|
||||
@@ -1381,7 +1374,7 @@ void ptwr_flush_inactive(void)
|
||||
continue;
|
||||
if (unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT))
|
||||
put_page_from_l1e(ol1e);
|
||||
if (unlikely(!get_page_from_l1e(nl1e)))
|
||||
if (unlikely(!get_page_from_l1e(nl1e, current)))
|
||||
BUG();
|
||||
}
|
||||
unmap_domain_mem(pl1e);
|
||||
|
||||
@@ -96,17 +96,13 @@ long do_dom_mem_op(unsigned int op,
|
||||
domid_t domid)
|
||||
{
|
||||
struct domain *d;
|
||||
long rc = -ENOSYS;
|
||||
long rc;
|
||||
|
||||
if (domid == DOMID_SELF)
|
||||
d = current;
|
||||
else
|
||||
d = find_domain_by_id(domid);
|
||||
|
||||
if (d==NULL)
|
||||
d = (domid == DOMID_SELF) ? current : find_domain_by_id(domid);
|
||||
if ( d == NULL )
|
||||
return -ESRCH;
|
||||
|
||||
switch( op )
|
||||
switch ( op )
|
||||
{
|
||||
case MEMOP_increase_reservation:
|
||||
rc = alloc_dom_mem(d, extent_list, nr_extents, extent_order);
|
||||
@@ -114,9 +110,12 @@ long do_dom_mem_op(unsigned int op,
|
||||
case MEMOP_decrease_reservation:
|
||||
rc = free_dom_mem(d, extent_list, nr_extents, extent_order);
|
||||
break;
|
||||
default:
|
||||
rc = -ENOSYS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (domid!=DOMID_SELF)
|
||||
if ( domid != DOMID_SELF )
|
||||
put_domain(d);
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -147,7 +147,7 @@ static inline int get_page(struct pfn_info *page,
|
||||
p = np;
|
||||
if ( unlikely((x & PGC_count_mask) == 0) || /* Not allocated? */
|
||||
unlikely((nx & PGC_count_mask) == 0) || /* Count overflow? */
|
||||
unlikely(!IS_PRIV(domain) && p != domain) ) /* Wrong owner? */
|
||||
unlikely(p != domain) ) /* Wrong owner? */
|
||||
{
|
||||
DPRINTK("Error pfn %08lx: ed=%p(%u), sd=%p(%u),"
|
||||
" caf=%08x, taf=%08x\n",
|
||||
@@ -249,7 +249,8 @@ static inline int get_page_type(struct pfn_info *page, u32 type)
|
||||
/* Try to validate page type; drop the new reference on failure. */
|
||||
if ( unlikely(!alloc_page_type(page, type)) )
|
||||
{
|
||||
DPRINTK("Error while validating pfn %08lx for type %08x. caf=%08x taf=%08x\n",
|
||||
DPRINTK("Error while validating pfn %08lx for type %08x."
|
||||
" caf=%08x taf=%08x\n",
|
||||
page_to_pfn(page), type,
|
||||
page->u.inuse.count_info,
|
||||
page->u.inuse.type_info);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* This makes sure that old versions of dom0 tools will stop working in a
|
||||
* well-defined way (rather than crashing the machine, for instance).
|
||||
*/
|
||||
#define DOM0_INTERFACE_VERSION 0xAAAA0011
|
||||
#define DOM0_INTERFACE_VERSION 0xAAAA0012
|
||||
|
||||
#define MAX_DOMAIN_NAME 16
|
||||
|
||||
|
||||
@@ -78,66 +78,56 @@
|
||||
* HYPERVISOR_mmu_update() accepts a list of (ptr, val) pairs.
|
||||
* ptr[1:0] specifies the appropriate MMU_* command.
|
||||
*
|
||||
* GPS (General-Purpose Subject)
|
||||
* -----------------------------
|
||||
* This domain that must own all non-page-table pages that are involved in
|
||||
* MMU updates. By default it is the domain that executes mmu_update(). If the
|
||||
* caller has sufficient privilege then it can be changed by executing
|
||||
* MMUEXT_SET_SUBJECTDOM.
|
||||
*
|
||||
* PTS (Page-Table Subject)
|
||||
* ------------------------
|
||||
* This domain must own all the page-table pages that are subject to MMU
|
||||
* updates. By default it is the domain that executes mmu_update(). If the
|
||||
* caller has sufficient privilege then it can be changed by executing
|
||||
* MMUEXT_SET_SUBJECTDOM with val[14] (SET_PAGETABLE_SUBJECTDOM) set.
|
||||
* FOREIGN DOMAIN (FD)
|
||||
* -------------------
|
||||
* Some commands recognise an explicitly-declared foreign domain,
|
||||
* in which case they will operate with respect to the foreigner rather than
|
||||
* the calling domain. Where the FD has some effect, it is described below.
|
||||
*
|
||||
* ptr[1:0] == MMU_NORMAL_PT_UPDATE:
|
||||
* Updates an entry in a page table.
|
||||
* ptr[:2] -- machine address of the page-table entry to modify [1]
|
||||
* val -- value to write [2]
|
||||
* Updates an entry in a page table. If updating an L1 table, and the new
|
||||
* table entry is valid/present, the mapped frame must belong to the FD, if
|
||||
* an FD has been specified. If attempting to map an I/O page, then the FD
|
||||
* is ignored, but the calling domain must have sufficient privilege.
|
||||
* ptr[:2] -- Machine address of the page-table entry to modify.
|
||||
* val -- Value to write.
|
||||
*
|
||||
* ptr[1:0] == MMU_MACHPHYS_UPDATE:
|
||||
* Updates an entry in the machine->pseudo-physical mapping table.
|
||||
* ptr[:2] -- machine address within the frame whose mapping to modify [3]
|
||||
* val -- value to write into the mapping entry
|
||||
* ptr[:2] -- Machine address within the frame whose mapping to modify.
|
||||
* The frame must belong to the FD, if one is specified.
|
||||
* val -- Value to write into the mapping entry.
|
||||
*
|
||||
* ptr[1:0] == MMU_EXTENDED_COMMAND:
|
||||
* val[7:0] -- MMUEXT_* command
|
||||
* val[7:0] -- MMUEXT_* command.
|
||||
*
|
||||
* val[7:0] == MMUEXT_(UN)PIN_*_TABLE:
|
||||
* ptr[:2] -- machine address of frame to be (un)pinned as a p.t. page [1]
|
||||
* ptr[:2] -- Machine address of frame to be (un)pinned as a p.t. page.
|
||||
* The frame must belong to the FD, if one is specified.
|
||||
*
|
||||
* val[7:0] == MMUEXT_NEW_BASEPTR:
|
||||
* ptr[:2] -- machine address of new page-table base to install in MMU [1]
|
||||
* ptr[:2] -- Machine address of new page-table base to install in MMU.
|
||||
*
|
||||
* val[7:0] == MMUEXT_TLB_FLUSH:
|
||||
* no additional arguments
|
||||
* No additional arguments.
|
||||
*
|
||||
* val[7:0] == MMUEXT_INVLPG:
|
||||
* ptr[:2] -- linear address to be flushed from the TLB
|
||||
* ptr[:2] -- Linear address to be flushed from the TLB.
|
||||
*
|
||||
* val[7:0] == MMUEXT_SET_LDT:
|
||||
* ptr[:2] -- linear address of LDT base (NB. must be page-aligned)
|
||||
* val[:8] -- number of entries in LDT
|
||||
* ptr[:2] -- Linear address of LDT base (NB. must be page-aligned).
|
||||
* val[:8] -- Number of entries in LDT.
|
||||
*
|
||||
* val[7:0] == MMUEXT_SET_SUBJECTDOM:
|
||||
* val[14] -- if TRUE then sets the PTS in addition to the GPS.
|
||||
* (ptr[31:15],val[31:15]) -- dom[31:0]
|
||||
* val[7:0] == MMUEXT_SET_FOREIGNDOM:
|
||||
* val[31:15] -- Domain to set as the Foreign Domain (FD).
|
||||
* (NB. DOMID_SELF is not recognised)
|
||||
*
|
||||
* val[7:0] == MMUEXT_REASSIGN_PAGE:
|
||||
* ptr[:2] -- machine address within page to be reassigned to the GPS.
|
||||
* ptr[:2] -- A machine address within the page to be reassigned to the FD.
|
||||
* (NB. page must currently belong to the calling domain).
|
||||
*
|
||||
* val[7:0] == MMUEXT_RESET_SUBJECTDOM:
|
||||
* Resets both the GPS and the PTS to their defaults (i.e., calling domain).
|
||||
*
|
||||
* Notes on constraints on the above arguments:
|
||||
* [1] The page frame containing the machine address must belong to the PTS.
|
||||
* [2] If the PTE is valid (i.e., bit 0 is set) then the specified page frame
|
||||
* must belong to:
|
||||
* (a) the PTS (if the PTE is part of a non-L1 table); or
|
||||
* (b) the GPS (if the PTE is part of an L1 table).
|
||||
* [3] The page frame containing the machine address must belong to the GPS.
|
||||
* val[7:0] == MMUEXT_CLEAR_FOREIGNDOM:
|
||||
* Clears the FD.
|
||||
*/
|
||||
#define MMU_NORMAL_PT_UPDATE 0 /* checked '*ptr = val'. ptr is MA. */
|
||||
#define MMU_MACHPHYS_UPDATE 2 /* ptr = MA of frame to modify entry for */
|
||||
@@ -151,10 +141,9 @@
|
||||
#define MMUEXT_TLB_FLUSH 6 /* ptr = NULL */
|
||||
#define MMUEXT_INVLPG 7 /* ptr = VA to invalidate */
|
||||
#define MMUEXT_SET_LDT 8 /* ptr = VA of table; val = # entries */
|
||||
#define MMUEXT_SET_SUBJECTDOM 9 /* (ptr[31:15],val[31:15]) = dom[31:0] */
|
||||
#define SET_PAGETABLE_SUBJECTDOM (1<<14) /* OR into 'val' arg of SUBJECTDOM */
|
||||
#define MMUEXT_SET_FOREIGNDOM 9 /* val[31:15] = dom */
|
||||
#define MMUEXT_REASSIGN_PAGE 10
|
||||
#define MMUEXT_RESET_SUBJECTDOM 11
|
||||
#define MMUEXT_CLEAR_FOREIGNDOM 11
|
||||
#define MMUEXT_CMD_MASK 255
|
||||
#define MMUEXT_CMD_SHIFT 8
|
||||
|
||||
@@ -198,7 +187,8 @@
|
||||
|
||||
typedef u16 domid_t;
|
||||
/* DOMID_SELF is used in certain contexts to refer to oneself. */
|
||||
#define DOMID_SELF (0x7FFEU)
|
||||
#define DOMID_SELF (0x7FF0U)
|
||||
/* NB. IDs >= 0x7FF1 are reserved for future use. */
|
||||
|
||||
/*
|
||||
* Send an array of these to HYPERVISOR_mmu_update().
|
||||
|
||||