bitkeeper revision 1.913 (40ab4ea8vu84ako0LR_rQN0fDuznVw)

Fix the mmu_update hypercall interface.
This commit is contained in:
kaf24@scramble.cl.cam.ac.uk committed 2004-05-19 12:10:16 +00:00
1 parent c9cfbb3322
commit 74a3bae43b
11 files changed
+62 -80

No files matched your search

+4 -2
View File
@@ -50,13 +50,15 @@ static __inline__ int HYPERVISOR_set_trap_table(trap_info_t *table)
return ret;
}
static __inline__ int HYPERVISOR_mmu_update(mmu_update_t *req, int count)
static __inline__ int HYPERVISOR_mmu_update(mmu_update_t *req,
int count,
int *success_count)
{
int ret;
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_mmu_update),
"b" (req), "c" (count) : "memory" );
"b" (req), "c" (count), "d" (success_count) : "memory" );
return ret;
}
+2 -1
View File
@@ -323,7 +323,8 @@ static int flush_mmu_updates(int xc_handle, mmu_t *mmu)
hypercall.op = __HYPERVISOR_mmu_update;
hypercall.arg[0] = (unsigned long)mmu->updates;
hypercall.arg[1] = (unsigned long)&(mmu->idx);
hypercall.arg[1] = (unsigned long)mmu->idx;
hypercall.arg[2] = 0;
if ( mlock(mmu->updates, sizeof(mmu->updates)) != 0 )
{
+3 -9
View File
@@ -988,9 +988,8 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
}
int do_mmu_update(mmu_update_t *ureqs, int * p_count)
int do_mmu_update(mmu_update_t *ureqs, int count, int *success_count)
{
int count;
mmu_update_t req;
unsigned long va = 0, deferred_ops, pfn, prev_pfn = 0;
struct pfn_info *page;
@@ -999,11 +998,6 @@ int do_mmu_update(mmu_update_t *ureqs, int * p_count)
unsigned long prev_spfn = 0;
l1_pgentry_t *prev_spl1e = 0;
if ( unlikely( get_user(count, p_count) ) )
{
return -EFAULT;
}
perfc_incrc(calls_to_mmu_update);
perfc_addc(num_page_updates, count);
@@ -1160,8 +1154,8 @@ int do_mmu_update(mmu_update_t *ureqs, int * p_count)
percpu_info[cpu].gps = percpu_info[cpu].pts = NULL;
}
if ( unlikely(rc) )
put_user( count, p_count );
if ( unlikely(success_count != NULL) )
put_user(count, success_count);
return rc;
}
+1 -1
View File
@@ -314,7 +314,7 @@ int check_descriptor(unsigned long a, unsigned long b);
#define machine_to_phys_mapping ((unsigned long *)RDWR_MPT_VIRT_START)
/* Part of the domain API. */
int do_mmu_update(mmu_update_t *updates, int *count);
int do_mmu_update(mmu_update_t *updates, int count, int *success_count);
#define DEFAULT_GDT_ENTRIES ((LAST_RESERVED_GDT_ENTRY*8)+7)
#define DEFAULT_GDT_ADDRESS ((unsigned long)gdt_table)
@@ -89,18 +89,18 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
if ( copy_from_user(&msg, p, n*sizeof(privcmd_mmap_entry_t)) )
return -EFAULT;
for (j=0;j<n;j++)
for ( j = 0; j < n; j++ )
{
struct vm_area_struct *vma =
find_vma( current->mm, msg[j].va );
if (!vma)
if ( !vma )
return -EINVAL;
if (msg[j].va > PAGE_OFFSET)
if ( msg[j].va > PAGE_OFFSET )
return -EINVAL;
if (msg[j].va + (msg[j].npages<<PAGE_SHIFT) > vma->vm_end)
if ( (msg[j].va + (msg[j].npages<<PAGE_SHIFT)) > vma->vm_end )
return -EINVAL;
if ( (rc = direct_remap_area_pages(vma->vm_mm,
@@ -108,7 +108,7 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
msg[j].mfn<<PAGE_SHIFT,
msg[j].npages<<PAGE_SHIFT,
vma->vm_page_prot,
mmapcmd.dom)) <0)
mmapcmd.dom)) < 0 )
return rc;
}
}
@@ -131,21 +131,15 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
vma = find_vma( current->mm, m.addr );
if (!vma)
if ( !vma )
{ ret = -EINVAL; goto batch_err; }
if (m.addr > PAGE_OFFSET)
if ( m.addr > PAGE_OFFSET )
{ ret = -EFAULT; goto batch_err; }
if (m.addr + (m.num<<PAGE_SHIFT) > vma->vm_end)
if ( (m.addr + (m.num<<PAGE_SHIFT)) > vma->vm_end )
{ ret = -EFAULT; goto batch_err; }
// everything fits inside the vma
//printk("direct_r_a_p sx=%ld address=%lx macaddr=%lx dom=%lld\n",size,address,machine_addr,domid);
// memset( u, 0, sizeof(mmu_update_t)*MAX_DIRECTMAP_MMU_QUEUE );// XXX
if ( m.dom != 0 )
{
u[0].val = (unsigned long)(m.dom<<16) & ~0xFFFFUL;
@@ -165,35 +159,28 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
p = m.arr;
addr = m.addr;
//printk("BATCH: arr=%p addr=%lx num=%d u=%p,w=%p\n",p,addr,m.num,u,w);
for (i=0; i<m.num; i++, addr+=PAGE_SIZE, p++)
for ( i = 0; i < m.num; i++, addr += PAGE_SIZE, p++ )
{
unsigned int count;
if ( get_user(mfn, p) ) return -EFAULT;
v->val = (mfn << PAGE_SHIFT) | pgprot_val(vma->vm_page_prot) |
_PAGE_IO;
__direct_remap_area_pages( vma->vm_mm,
addr,
PAGE_SIZE,
v);
v++;
count = v-u;
//printk("Q i=%d mfn=%x co=%d v=%p : %lx %lx\n",i,mfn,count,v, w->val,w->ptr);
__direct_remap_area_pages(vma->vm_mm,
addr,
PAGE_SIZE,
v);
if ( HYPERVISOR_mmu_update(u, &count) < 0 )
{
//printk("Fail %d->%d mfn=%lx\n",v-u,count, w->val);
if ( unlikely(HYPERVISOR_mmu_update(u, v - u + 1, NULL) < 0) )
put_user( 0xe0000000 | mfn, p );
}
v=w;
v = w;
}
ret = 0;
break;
batch_err:
printk("batch_err ret=%d vma=%p addr=%lx num=%d arr=%lx %lx-%lx\n",
printk("batch_err ret=%d vma=%p addr=%lx num=%d arr=%p %lx-%lx\n",
ret, vma, m.addr, m.num, m.arr, vma->vm_start, vma->vm_end);
break;
}
@@ -231,6 +231,7 @@ static void net_rx_action(unsigned long unused)
mcl[1].op = __HYPERVISOR_mmu_update;
mcl[1].args[0] = (unsigned long)mmu;
mcl[1].args[1] = 4;
mcl[1].args[2] = 0;
mmu += 4;
mcl += 2;
@@ -384,6 +384,7 @@ static int netif_poll(struct net_device *dev, int *pbudget)
mcl->op = __HYPERVISOR_mmu_update;
mcl->args[0] = (unsigned long)rx_mmu;
mcl->args[1] = mmu - rx_mmu;
mcl->args[2] = 0;
mcl++;
(void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
}
@@ -317,12 +317,11 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
__asm__ __volatile__ ( "sldt %0" : "=r" (ldt) );
if ( ldt == 0 )
{
int count = 1;
mmu_update_t u;
u.ptr = MMU_EXTENDED_COMMAND;
u.ptr |= (unsigned long)&default_ldt[0];
u.val = MMUEXT_SET_LDT | (5 << MMUEXT_CMD_SHIFT);
if ( unlikely(HYPERVISOR_mmu_update(&u, &count) < 0) )
if ( unlikely(HYPERVISOR_mmu_update(&u, 1, NULL) < 0) )
{
show_trace(NULL);
panic("Failed to install default LDT");
@@ -644,7 +643,7 @@ void __init trap_init(void)
* don't set them to safe values on entry to the kernel). At *any* point Xen
* may be entered due to a hardware interrupt --- on exit from Xen an invalid
* FS/GS will cause our failsafe_callback to be executed. This could occur,
* for example, while the mmmu_update_queue is in an inconsistent state. This
* for example, while the mmu_update_queue is in an inconsistent state. This
* is disastrous because the normal page-fault handler touches the update
* queue!
*
@@ -40,13 +40,12 @@ static void DEBUG_allow_pt_reads(void)
int i;
for ( i = idx-1; i >= 0; i-- )
{
int count = 1;
pte = update_debug_queue[i].ptep;
if ( pte == NULL ) continue;
update_debug_queue[i].ptep = NULL;
update.ptr = virt_to_machine(pte);
update.val = update_debug_queue[i].pteval;
HYPERVISOR_mmu_update(&update, &count);
HYPERVISOR_mmu_update(&update, 1, NULL);
}
}
static void DEBUG_disallow_pt_read(unsigned long va)
@@ -55,7 +54,6 @@ static void DEBUG_disallow_pt_read(unsigned long va)
pmd_t *pmd;
pgd_t *pgd;
unsigned long pteval;
int count = 1;
/*
* We may fault because of an already outstanding update.
* That's okay -- it'll get fixed up in the fault handler.
@@ -67,7 +65,7 @@ static void DEBUG_disallow_pt_read(unsigned long va)
update.ptr = virt_to_machine(pte);
pteval = *(unsigned long *)pte;
update.val = pteval & ~_PAGE_PRESENT;
HYPERVISOR_mmu_update(&update, &count);
HYPERVISOR_mmu_update(&update, 1, NULL);
update_debug_queue[idx].ptep = pte;
update_debug_queue[idx].pteval = pteval;
}
@@ -103,9 +101,10 @@ void MULTICALL_flush_page_update_queue(void)
#endif
idx = 0;
wmb(); /* Make sure index is cleared first to avoid double updates. */
queue_multicall2(__HYPERVISOR_mmu_update,
queue_multicall3(__HYPERVISOR_mmu_update,
(unsigned long)update_queue,
&_idx);
(unsigned long)_idx,
(unsigned long)NULL);
}
spin_unlock_irqrestore(&update_lock, flags);
}
@@ -121,7 +120,7 @@ static inline void __flush_page_update_queue(void)
#endif
idx = 0;
wmb(); /* Make sure index is cleared first to avoid double updates. */
if ( unlikely(HYPERVISOR_mmu_update(update_queue, &_idx) < 0) )
if ( unlikely(HYPERVISOR_mmu_update(update_queue, _idx, NULL) < 0) )
panic("Failed to execute MMU updates");
}
+21 -25
View File
@@ -42,18 +42,11 @@ static inline void direct_remap_area_pte(pte_t *pte,
BUG();
do {
#if 0 // XXX
if (!pte_none(*pte)) {
printk("direct_remap_area_pte: page already exists\n");
BUG();
}
#endif
(*v)->ptr = virt_to_machine(pte);
(*v)++;
address += PAGE_SIZE;
pte++;
} while (address && (address < end));
return ;
}
static inline int direct_remap_area_pmd(struct mm_struct *mm,
@@ -71,7 +64,7 @@ static inline int direct_remap_area_pmd(struct mm_struct *mm,
if (address >= end)
BUG();
do {
pte_t * pte = pte_alloc(mm, pmd, address);
pte_t *pte = pte_alloc(mm, pmd, address);
if (!pte)
return -ENOMEM;
direct_remap_area_pte(pte, address, end - address, v);
@@ -117,7 +110,7 @@ int direct_remap_area_pages(struct mm_struct *mm,
pgprot_t prot,
domid_t domid)
{
int i, count;
int i;
unsigned long start_address;
#define MAX_DIRECTMAP_MMU_QUEUE 130
mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *w, *v;
@@ -141,39 +134,42 @@ int direct_remap_area_pages(struct mm_struct *mm,
start_address = address;
for(i=0; i<size;
i+=PAGE_SIZE, machine_addr+=PAGE_SIZE, address+=PAGE_SIZE, v++)
for( i = 0; i < size; i += PAGE_SIZE )
{
if( (v-u) == MAX_DIRECTMAP_MMU_QUEUE )
if ( (v - u) == MAX_DIRECTMAP_MMU_QUEUE )
{
/* get the ptep's filled in */
/* Fill in the PTE pointers. */
__direct_remap_area_pages( mm,
start_address,
address-start_address,
w);
count = v-u;
if ( HYPERVISOR_mmu_update(u, &count) < 0 )
if ( HYPERVISOR_mmu_update(u, v - u, NULL) < 0 )
return -EFAULT;
v=w;
v = w;
start_address = address;
}
/* fill in the machine addresses */
/*
* Fill in the machine address: PTE ptr is done later by
* __direct_remap_area_pages().
*/
v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot) | _PAGE_IO;
machine_addr += PAGE_SIZE;
address += PAGE_SIZE;
v++;
}
if(v!=w)
if ( v != w )
{
/* get the ptep's filled in */
__direct_remap_area_pages( mm,
start_address,
address-start_address,
w);
count = v-u;
if ( HYPERVISOR_mmu_update(u, &count) < 0 )
__direct_remap_area_pages(mm,
start_address,
address-start_address,
w);
if ( unlikely(HYPERVISOR_mmu_update(u, v - u, NULL) < 0) )
return -EFAULT;
}
return 0;
@@ -160,13 +160,15 @@ static inline int HYPERVISOR_set_trap_table(trap_info_t *table)
return ret;
}
static inline int HYPERVISOR_mmu_update(mmu_update_t *req, int *count)
static inline int HYPERVISOR_mmu_update(mmu_update_t *req,
int count,
int *success_count)
{
int ret;
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_mmu_update),
"b" (req), "c" (count) : "memory" );
"b" (req), "c" (count), "d" (success_count) : "memory" );
return ret;
}
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.