mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.1159.250.1 (4208d729hvKh9E4GWJWvFDThd8OXyA)
More x86_64 fixes/cleanups. NB. update_va_mapping hypercalls now accept a virtual address, *not* a "virtual page number". Signed-off-by: keir.fraser@cl.cam.ac.uk
This commit is contained in:
1 parent
196c87d157
commit
f87f8a7110
17 files changed
+73
-76
No files matched your search
@@ -867,8 +867,8 @@
|
||||
3ddb79bcBit4xJXbwtX0kb1hh2uO1Q xen/arch/x86/idle0_task.c
|
||||
3ddb79bcKIkRR0kqWaJhe5VUDkMdxg xen/arch/x86/io_apic.c
|
||||
3ddb79bdqfIcjkz_h9Hvtp8Tk_19Zw xen/arch/x86/irq.c
|
||||
40ec29ffuOa1ZvmJHzFKyZn4k_RcXg xen/arch/x86/memory.c
|
||||
41d54a76qfpO0VnbL2tYs0Jgt3W3XA xen/arch/x86/microcode.c
|
||||
40ec29ffuOa1ZvmJHzFKyZn4k_RcXg xen/arch/x86/mm.c
|
||||
3ddb79bdS4UeWWXDH-FaBKqcpMFcnw xen/arch/x86/mpparse.c
|
||||
41aaf566Z4sTDgJ77eEg0TzzQ1ka6Q xen/arch/x86/mtrr/amd.c
|
||||
41aaf566TOpOBXT00wwQGUh20f1rlA xen/arch/x86/mtrr/centaur.c
|
||||
|
||||
@@ -915,7 +915,7 @@ static inline void establish_pte(struct vm_area_struct * vma, unsigned long addr
|
||||
#ifdef CONFIG_XEN
|
||||
if ( likely(vma->vm_mm == current->mm) ) {
|
||||
XEN_flush_page_update_queue();
|
||||
HYPERVISOR_update_va_mapping(address>>PAGE_SHIFT, entry, UVMF_INVLPG);
|
||||
HYPERVISOR_update_va_mapping(address, entry, UVMF_INVLPG);
|
||||
} else {
|
||||
set_pte(page_table, entry);
|
||||
flush_tlb_page(vma, address);
|
||||
@@ -1191,7 +1191,7 @@ static int do_swap_page(struct mm_struct * mm,
|
||||
#ifdef CONFIG_XEN
|
||||
if ( likely(vma->vm_mm == current->mm) ) {
|
||||
XEN_flush_page_update_queue();
|
||||
HYPERVISOR_update_va_mapping(address>>PAGE_SHIFT, pte, 0);
|
||||
HYPERVISOR_update_va_mapping(address, pte, 0);
|
||||
} else {
|
||||
set_pte(page_table, pte);
|
||||
XEN_flush_page_update_queue();
|
||||
@@ -1247,7 +1247,7 @@ static int do_anonymous_page(struct mm_struct * mm, struct vm_area_struct * vma,
|
||||
#ifdef CONFIG_XEN
|
||||
if ( likely(vma->vm_mm == current->mm) ) {
|
||||
XEN_flush_page_update_queue();
|
||||
HYPERVISOR_update_va_mapping(addr>>PAGE_SHIFT, entry, 0);
|
||||
HYPERVISOR_update_va_mapping(addr, entry, 0);
|
||||
} else {
|
||||
set_pte(page_table, entry);
|
||||
XEN_flush_page_update_queue();
|
||||
@@ -1333,7 +1333,7 @@ static int do_no_page(struct mm_struct * mm, struct vm_area_struct * vma,
|
||||
#ifdef CONFIG_XEN
|
||||
if ( likely(vma->vm_mm == current->mm) ) {
|
||||
XEN_flush_page_update_queue();
|
||||
HYPERVISOR_update_va_mapping(address>>PAGE_SHIFT, entry, 0);
|
||||
HYPERVISOR_update_va_mapping(address, entry, 0);
|
||||
} else {
|
||||
set_pte(page_table, entry);
|
||||
XEN_flush_page_update_queue();
|
||||
|
||||
@@ -95,7 +95,7 @@ static void fast_flush_area(int idx, int nr_pages)
|
||||
for ( i = 0; i < nr_pages; i++ )
|
||||
{
|
||||
mcl[i].op = __HYPERVISOR_update_va_mapping;
|
||||
mcl[i].args[0] = MMAP_VADDR(idx, i) >> PAGE_SHIFT;
|
||||
mcl[i].args[0] = MMAP_VADDR(idx, i);
|
||||
mcl[i].args[1] = 0;
|
||||
mcl[i].args[2] = 0;
|
||||
}
|
||||
@@ -343,14 +343,14 @@ static void dispatch_probe(blkif_t *blkif, blkif_request_t *req)
|
||||
|
||||
#ifdef CONFIG_XEN_BLKDEV_TAP_BE
|
||||
if ( HYPERVISOR_update_va_mapping_otherdomain(
|
||||
MMAP_VADDR(pending_idx, 0) >> PAGE_SHIFT,
|
||||
MMAP_VADDR(pending_idx, 0),
|
||||
(pte_t) { (req->frame_and_sects[0] & PAGE_MASK) | __PAGE_KERNEL },
|
||||
0, (blkif->is_blktap ? ID_TO_DOM(req->id) : blkif->domid) ) )
|
||||
|
||||
goto out;
|
||||
#else
|
||||
if ( HYPERVISOR_update_va_mapping_otherdomain(
|
||||
MMAP_VADDR(pending_idx, 0) >> PAGE_SHIFT,
|
||||
MMAP_VADDR(pending_idx, 0),
|
||||
(pte_t) { (req->frame_and_sects[0] & PAGE_MASK) | __PAGE_KERNEL },
|
||||
0, blkif->domid) )
|
||||
|
||||
@@ -436,7 +436,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
|
||||
for ( i = 0; i < nr_psegs; i++ )
|
||||
{
|
||||
mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain;
|
||||
mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT;
|
||||
mcl[i].args[0] = MMAP_VADDR(pending_idx, i);
|
||||
mcl[i].args[1] = (phys_seg[i].buffer & PAGE_MASK) | remap_prot;
|
||||
mcl[i].args[2] = 0;
|
||||
#ifdef CONFIG_XEN_BLKDEV_TAP_BE
|
||||
|
||||
@@ -234,7 +234,7 @@ static void net_rx_action(unsigned long unused)
|
||||
mmu[2].val = MMUEXT_REASSIGN_PAGE;
|
||||
|
||||
mcl[0].op = __HYPERVISOR_update_va_mapping;
|
||||
mcl[0].args[0] = vdata >> PAGE_SHIFT;
|
||||
mcl[0].args[0] = vdata;
|
||||
mcl[0].args[1] = (new_mfn << PAGE_SHIFT) | __PAGE_KERNEL;
|
||||
mcl[0].args[2] = 0;
|
||||
mcl[1].op = __HYPERVISOR_mmu_update;
|
||||
@@ -409,7 +409,7 @@ static void net_tx_action(unsigned long unused)
|
||||
{
|
||||
pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
|
||||
mcl[0].op = __HYPERVISOR_update_va_mapping;
|
||||
mcl[0].args[0] = MMAP_VADDR(pending_idx) >> PAGE_SHIFT;
|
||||
mcl[0].args[0] = MMAP_VADDR(pending_idx);
|
||||
mcl[0].args[1] = 0;
|
||||
mcl[0].args[2] = 0;
|
||||
mcl++;
|
||||
@@ -546,7 +546,7 @@ static void net_tx_action(unsigned long unused)
|
||||
skb_reserve(skb, 16);
|
||||
|
||||
mcl[0].op = __HYPERVISOR_update_va_mapping_otherdomain;
|
||||
mcl[0].args[0] = MMAP_VADDR(pending_idx) >> PAGE_SHIFT;
|
||||
mcl[0].args[0] = MMAP_VADDR(pending_idx);
|
||||
mcl[0].args[1] = (txreq.addr & PAGE_MASK) | __PAGE_KERNEL;
|
||||
mcl[0].args[2] = 0;
|
||||
mcl[0].args[3] = netif->domid;
|
||||
|
||||
@@ -392,7 +392,7 @@ static void network_alloc_rx_buffers(struct net_device *dev)
|
||||
= INVALID_P2M_ENTRY;
|
||||
|
||||
rx_mcl[i].op = __HYPERVISOR_update_va_mapping;
|
||||
rx_mcl[i].args[0] = (unsigned long)skb->head >> PAGE_SHIFT;
|
||||
rx_mcl[i].args[0] = (unsigned long)skb->head;
|
||||
rx_mcl[i].args[1] = 0;
|
||||
rx_mcl[i].args[2] = 0;
|
||||
}
|
||||
@@ -593,7 +593,7 @@ static int netif_poll(struct net_device *dev, int *pbudget)
|
||||
mmu->val = __pa(skb->head) >> PAGE_SHIFT;
|
||||
mmu++;
|
||||
mcl->op = __HYPERVISOR_update_va_mapping;
|
||||
mcl->args[0] = (unsigned long)skb->head >> PAGE_SHIFT;
|
||||
mcl->args[0] = (unsigned long)skb->head;
|
||||
mcl->args[1] = (rx->addr & PAGE_MASK) | __PAGE_KERNEL;
|
||||
mcl->args[2] = 0;
|
||||
mcl++;
|
||||
|
||||
@@ -191,7 +191,7 @@ static void fast_flush_area(int idx, int nr_pages)
|
||||
for ( i = 0; i < nr_pages; i++ )
|
||||
{
|
||||
mcl[i].op = __HYPERVISOR_update_va_mapping;
|
||||
mcl[i].args[0] = MMAP_VADDR(idx, i) >> PAGE_SHIFT;
|
||||
mcl[i].args[0] = MMAP_VADDR(idx, i);
|
||||
mcl[i].args[1] = 0;
|
||||
mcl[i].args[2] = 0;
|
||||
}
|
||||
@@ -630,7 +630,7 @@ static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req)
|
||||
i++, offset += PAGE_SIZE )
|
||||
{
|
||||
mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain;
|
||||
mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT;
|
||||
mcl[i].args[0] = MMAP_VADDR(pending_idx, i);
|
||||
mcl[i].args[1] = ((buffer_mach & PAGE_MASK) + offset) | remap_prot;
|
||||
mcl[i].args[2] = 0;
|
||||
mcl[i].args[3] = up->domid;
|
||||
@@ -646,7 +646,7 @@ static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req)
|
||||
{
|
||||
/* Map in ISO schedule, if necessary. */
|
||||
mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain;
|
||||
mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT;
|
||||
mcl[i].args[0] = MMAP_VADDR(pending_idx, i);
|
||||
mcl[i].args[1] = (req->iso_schedule & PAGE_MASK) | remap_prot;
|
||||
mcl[i].args[2] = 0;
|
||||
mcl[i].args[3] = up->domid;
|
||||
|
||||
@@ -426,7 +426,7 @@ extern pte_t *lookup_address(unsigned long address);
|
||||
if (__dirty) { \
|
||||
if ( likely((__vma)->vm_mm == current->mm) ) { \
|
||||
xen_flush_page_update_queue(); \
|
||||
HYPERVISOR_update_va_mapping((__address)>>PAGE_SHIFT, (__entry), UVMF_INVLPG); \
|
||||
HYPERVISOR_update_va_mapping((__address), (__entry), UVMF_INVLPG); \
|
||||
} else { \
|
||||
xen_l1_entry_update((__ptep), (__entry).pte_low); \
|
||||
flush_tlb_page((__vma), (__address)); \
|
||||
@@ -445,7 +445,7 @@ do { \
|
||||
do { \
|
||||
if (likely((__vma)->vm_mm == current->mm)) { \
|
||||
xen_flush_page_update_queue(); \
|
||||
HYPERVISOR_update_va_mapping((__address)>>PAGE_SHIFT, \
|
||||
HYPERVISOR_update_va_mapping((__address), \
|
||||
__entry, 0); \
|
||||
} else { \
|
||||
xen_l1_entry_update((__ptep), (__entry).pte_low); \
|
||||
|
||||
@@ -438,7 +438,7 @@ HYPERVISOR_multicall(
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_update_va_mapping(
|
||||
unsigned long page_nr, pte_t new_val, unsigned long flags)
|
||||
unsigned long nr, pte_t new_val, unsigned long flags)
|
||||
{
|
||||
int ret;
|
||||
unsigned long ign1, ign2, ign3;
|
||||
@@ -447,13 +447,13 @@ HYPERVISOR_update_va_mapping(
|
||||
TRAP_INSTR
|
||||
: "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
|
||||
: "0" (__HYPERVISOR_update_va_mapping),
|
||||
"1" (page_nr), "2" ((new_val).pte_low), "3" (flags)
|
||||
"1" (va), "2" ((new_val).pte_low), "3" (flags)
|
||||
: "memory" );
|
||||
|
||||
if ( unlikely(ret < 0) )
|
||||
{
|
||||
printk(KERN_ALERT "Failed update VA mapping: %08lx, %08lx, %08lx\n",
|
||||
page_nr, (new_val).pte_low, flags);
|
||||
va, (new_val).pte_low, flags);
|
||||
BUG();
|
||||
}
|
||||
|
||||
@@ -540,7 +540,7 @@ HYPERVISOR_grant_table_op(
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_update_va_mapping_otherdomain(
|
||||
unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid)
|
||||
unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
|
||||
{
|
||||
int ret;
|
||||
unsigned long ign1, ign2, ign3, ign4;
|
||||
@@ -549,7 +549,7 @@ HYPERVISOR_update_va_mapping_otherdomain(
|
||||
TRAP_INSTR
|
||||
: "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
|
||||
: "0" (__HYPERVISOR_update_va_mapping_otherdomain),
|
||||
"1" (page_nr), "2" ((new_val).pte_low), "3" (flags), "4" (domid) :
|
||||
"1" (va), "2" ((new_val).pte_low), "3" (flags), "4" (domid) :
|
||||
"memory" );
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -398,7 +398,7 @@ HYPERVISOR_multicall(void *call_list, int nr_calls)
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
|
||||
HYPERVISOR_update_va_mapping(unsigned long va, unsigned long new_val,
|
||||
unsigned long flags)
|
||||
{
|
||||
int ret;
|
||||
@@ -408,12 +408,12 @@ HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
|
||||
TRAP_INSTR
|
||||
: "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
|
||||
: "0" (__HYPERVISOR_update_va_mapping),
|
||||
"1" (page_nr), "2" (new_val), "3" (flags)
|
||||
"1" (va), "2" (new_val), "3" (flags)
|
||||
: "memory" );
|
||||
|
||||
if (__predict_false(ret < 0))
|
||||
panic("Failed update VA mapping: %08lx, %08lx, %08lx",
|
||||
page_nr, new_val, flags);
|
||||
va, new_val, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -494,7 +494,7 @@ HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
|
||||
HYPERVISOR_update_va_mapping_otherdomain(unsigned long va,
|
||||
unsigned long new_val, unsigned long flags, domid_t domid)
|
||||
{
|
||||
int ret;
|
||||
@@ -504,7 +504,7 @@ HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
|
||||
TRAP_INSTR
|
||||
: "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
|
||||
: "0" (__HYPERVISOR_update_va_mapping_otherdomain),
|
||||
"1" (page_nr), "2" (new_val), "3" (flags), "4" (domid) :
|
||||
"1" (va), "2" (new_val), "3" (flags), "4" (domid) :
|
||||
"memory" );
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -580,7 +580,7 @@ xennet_rx_push_buffer(struct xennet_softc *sc, int id)
|
||||
INVALID_P2M_ENTRY;
|
||||
|
||||
rx_mcl[nr_pfns].op = __HYPERVISOR_update_va_mapping;
|
||||
rx_mcl[nr_pfns].args[0] = sc->sc_rx_bufa[id].xb_rx.xbrx_va >> PAGE_SHIFT;
|
||||
rx_mcl[nr_pfns].args[0] = sc->sc_rx_bufa[id].xb_rx.xbrx_va;
|
||||
rx_mcl[nr_pfns].args[1] = 0;
|
||||
rx_mcl[nr_pfns].args[2] = 0;
|
||||
|
||||
@@ -679,7 +679,7 @@ xen_network_handler(void *arg)
|
||||
mmu->val = (pa - XPMAP_OFFSET) >> PAGE_SHIFT;
|
||||
mmu++;
|
||||
mcl->op = __HYPERVISOR_update_va_mapping;
|
||||
mcl->args[0] = sc->sc_rx_bufa[rx->id].xb_rx.xbrx_va >> PAGE_SHIFT;
|
||||
mcl->args[0] = sc->sc_rx_bufa[rx->id].xb_rx.xbrx_va;
|
||||
mcl->args[1] = (rx->addr & PG_FRAME) | PG_V|PG_KW;
|
||||
mcl->args[2] = UVMF_FLUSH_TLB; // 0;
|
||||
mcl++;
|
||||
@@ -872,7 +872,7 @@ network_alloc_rx_buffers(struct xennet_softc *sc)
|
||||
INVALID_P2M_ENTRY;
|
||||
|
||||
rx_mcl[nr_pfns].op = __HYPERVISOR_update_va_mapping;
|
||||
rx_mcl[nr_pfns].args[0] = va >> PAGE_SHIFT;
|
||||
rx_mcl[nr_pfns].args[0] = va;
|
||||
rx_mcl[nr_pfns].args[1] = 0;
|
||||
rx_mcl[nr_pfns].args[2] = 0;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
|
||||
/******************************************************************************
|
||||
* arch/x86/memory.c
|
||||
* arch/x86/mm.c
|
||||
*
|
||||
* Copyright (c) 2002-2004 K A Fraser
|
||||
* Copyright (c) 2002-2005 K A Fraser
|
||||
* Copyright (c) 2004 Christian Limpach
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -277,8 +277,8 @@ int map_ldt_shadow_page(unsigned int off)
|
||||
if ( unlikely(in_irq()) )
|
||||
BUG();
|
||||
|
||||
__get_user(l1e, (unsigned long *)&linear_pg_table[(ed->arch.ldt_base >>
|
||||
PAGE_SHIFT) + off]);
|
||||
__get_user(l1e, (unsigned long *)
|
||||
&linear_pg_table[l1_linear_offset(ed->arch.ldt_base) + off]);
|
||||
|
||||
if ( unlikely(!(l1e & _PAGE_PRESENT)) ||
|
||||
unlikely(!get_page_and_type(&frame_table[l1e >> PAGE_SHIFT],
|
||||
@@ -1552,7 +1552,7 @@ int do_mmu_update(
|
||||
}
|
||||
|
||||
|
||||
int do_update_va_mapping(unsigned long page_nr,
|
||||
int do_update_va_mapping(unsigned long va,
|
||||
unsigned long val,
|
||||
unsigned long flags)
|
||||
{
|
||||
@@ -1564,7 +1564,7 @@ int do_update_va_mapping(unsigned long page_nr,
|
||||
|
||||
perfc_incrc(calls_to_update_va);
|
||||
|
||||
if ( unlikely(page_nr >= (HYPERVISOR_VIRT_START >> PAGE_SHIFT)) )
|
||||
if ( unlikely(!__addr_ok(va)) )
|
||||
return -EINVAL;
|
||||
|
||||
LOCK_BIGLOCK(d);
|
||||
@@ -1576,7 +1576,7 @@ int do_update_va_mapping(unsigned long page_nr,
|
||||
* the case of updating L2 entries.
|
||||
*/
|
||||
|
||||
if ( unlikely(!mod_l1_entry(&linear_pg_table[page_nr],
|
||||
if ( unlikely(!mod_l1_entry(&linear_pg_table[l1_linear_offset(va)],
|
||||
mk_l1_pgentry(val))) )
|
||||
err = -EINVAL;
|
||||
|
||||
@@ -1587,7 +1587,7 @@ int do_update_va_mapping(unsigned long page_nr,
|
||||
l1pte_propagate_from_guest(d, &val, &sval);
|
||||
|
||||
if ( unlikely(__put_user(sval, ((unsigned long *)(
|
||||
&shadow_linear_pg_table[page_nr])))) )
|
||||
&shadow_linear_pg_table[l1_linear_offset(va)])))) )
|
||||
{
|
||||
/*
|
||||
* Since L2's are guranteed RW, failure indicates the page was not
|
||||
@@ -1602,7 +1602,7 @@ int do_update_va_mapping(unsigned long page_nr,
|
||||
* for this.
|
||||
*/
|
||||
if ( d->arch.shadow_mode == SHM_logdirty )
|
||||
mark_dirty(d, va_to_l1mfn(page_nr << PAGE_SHIFT));
|
||||
mark_dirty(d, va_to_l1mfn(va));
|
||||
|
||||
check_pagetable(d, ed->arch.pagetable, "va"); /* debug */
|
||||
}
|
||||
@@ -1614,7 +1614,7 @@ int do_update_va_mapping(unsigned long page_nr,
|
||||
unlikely(flags & UVMF_FLUSH_TLB) )
|
||||
local_flush_tlb();
|
||||
else if ( unlikely(flags & UVMF_INVLPG) )
|
||||
__flush_tlb_one(page_nr << PAGE_SHIFT);
|
||||
__flush_tlb_one(va);
|
||||
|
||||
if ( unlikely(deferred_ops & DOP_RELOAD_LDT) )
|
||||
(void)map_ldt_shadow_page(0);
|
||||
@@ -1624,7 +1624,7 @@ int do_update_va_mapping(unsigned long page_nr,
|
||||
return err;
|
||||
}
|
||||
|
||||
int do_update_va_mapping_otherdomain(unsigned long page_nr,
|
||||
int do_update_va_mapping_otherdomain(unsigned long va,
|
||||
unsigned long val,
|
||||
unsigned long flags,
|
||||
domid_t domid)
|
||||
@@ -1643,7 +1643,7 @@ int do_update_va_mapping_otherdomain(unsigned long page_nr,
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
rc = do_update_va_mapping(page_nr, val, flags);
|
||||
rc = do_update_va_mapping(va, val, flags);
|
||||
|
||||
put_domain(d);
|
||||
percpu_info[cpu].foreign = NULL;
|
||||
@@ -1994,6 +1994,10 @@ int ptwr_do_page_fault(unsigned long addr)
|
||||
int which, cpu = smp_processor_id();
|
||||
u32 l2_idx;
|
||||
|
||||
#ifdef __x86_64__
|
||||
return 0; /* Writable pagetables need fixing for x86_64. */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Attempt to read the PTE that maps the VA being accessed. By checking for
|
||||
* PDE validity in the L2 we avoid many expensive fixups in __get_user().
|
||||
@@ -522,7 +522,7 @@ asmlinkage int do_general_protection(struct xen_regs *regs)
|
||||
|
||||
/* Emulate some simple privileged instructions when exec'ed in ring 1. */
|
||||
if ( (regs->error_code == 0) &&
|
||||
RING_1(regs) &&
|
||||
GUESTOS_FAULT(regs) &&
|
||||
emulate_privileged_op(regs) )
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ free_dom_mem(struct domain *d,
|
||||
long
|
||||
do_dom_mem_op(unsigned long op,
|
||||
unsigned long *extent_list,
|
||||
unsigned long nr_extents,
|
||||
unsigned int nr_extents,
|
||||
unsigned int extent_order,
|
||||
domid_t domid)
|
||||
{
|
||||
@@ -133,8 +133,7 @@ do_dom_mem_op(unsigned long op,
|
||||
start_extent = op >> START_EXTENT_SHIFT;
|
||||
op &= (1 << START_EXTENT_SHIFT) - 1;
|
||||
|
||||
if ( unlikely(start_extent > nr_extents) ||
|
||||
unlikely(nr_extents > ~0U) ) /* can pack into a uint? */
|
||||
if ( unlikely(start_extent > nr_extents) )
|
||||
return -EINVAL;
|
||||
|
||||
if ( likely(domid == DOMID_SELF) )
|
||||
@@ -150,13 +149,11 @@ do_dom_mem_op(unsigned long op,
|
||||
{
|
||||
case MEMOP_increase_reservation:
|
||||
rc = alloc_dom_mem(
|
||||
d, extent_list, start_extent,
|
||||
(unsigned int)nr_extents, extent_order);
|
||||
d, extent_list, start_extent, nr_extents, extent_order);
|
||||
break;
|
||||
case MEMOP_decrease_reservation:
|
||||
rc = free_dom_mem(
|
||||
d, extent_list, start_extent,
|
||||
(unsigned int)nr_extents, extent_order);
|
||||
d, extent_list, start_extent, nr_extents, extent_order);
|
||||
break;
|
||||
default:
|
||||
rc = -ENOSYS;
|
||||
|
||||
@@ -99,6 +99,13 @@ typedef struct { unsigned long l4_lo; } l4_pgentry_t;
|
||||
(((_a) >> L4_PAGETABLE_SHIFT) & (ENTRIES_PER_L4_PAGETABLE - 1))
|
||||
#endif
|
||||
|
||||
/* Given a virtual address, get an entry offset into a linear page table. */
|
||||
#if defined(__i386__)
|
||||
#define l1_linear_offset(_a) ((_a) >> PAGE_SHIFT)
|
||||
#elif defined(__x86_64__)
|
||||
#define l1_linear_offset(_a) (((_a) & ((1UL << 48) - 1)) >> PAGE_SHIFT)
|
||||
#endif
|
||||
|
||||
#if defined(__i386__)
|
||||
#define pagetable_t l2_pgentry_t
|
||||
#define pagetable_val(_x) ((_x).l2_lo)
|
||||
|
||||
@@ -39,4 +39,6 @@ struct xen_regs
|
||||
#define RING_2(_r) (((_r)->cs & 3) == 2)
|
||||
#define RING_3(_r) (((_r)->cs & 3) == 3)
|
||||
|
||||
#define GUESTOS_FAULT(_r) (!VM86_MODE(_r) && RING_1(_r))
|
||||
|
||||
#endif
|
||||
@@ -36,4 +36,6 @@ struct xen_regs
|
||||
#define RING_2(_r) (((_r)->cs & 3) == 2)
|
||||
#define RING_3(_r) (((_r)->cs & 3) == 3)
|
||||
|
||||
#define GUESTOS_FAULT(_r) (!VM86_MODE(_r) && RING_3(_r))
|
||||
|
||||
#endif
|
||||
@@ -15,34 +15,19 @@
|
||||
#define VERIFY_READ 0
|
||||
#define VERIFY_WRITE 1
|
||||
|
||||
#define __addr_ok(addr) ((unsigned long)(addr) < HYPERVISOR_VIRT_START)
|
||||
|
||||
/*
|
||||
* Test whether a block of memory is a valid user space address.
|
||||
* Returns 0 if the range is valid, nonzero otherwise.
|
||||
*
|
||||
* This is equivalent to the following test:
|
||||
* ((u65)addr >= (u65)HYPERVISOR_VIRT_END) ?
|
||||
* (((u65)addr + (u65)size) >= ((u65)1 << 64)) :
|
||||
* (((u65)addr + (u65)size) >= ((u65)HYPERVISOR_VIRT_START))
|
||||
* Valid if in +ve half of 48-bit address space, or above Xen-reserved area.
|
||||
* This is also valid for range checks (addr, addr+size). As long as the
|
||||
* start address is outside the Xen-reserved area then we will access a
|
||||
* non-canonical address (and thus fault) before ever reaching VIRT_START.
|
||||
*/
|
||||
#define __range_not_ok(addr,size) ({ \
|
||||
unsigned long flag,sum; \
|
||||
if ((unsigned long)addr >= HYPERVISOR_VIRT_END) \
|
||||
asm("addq %3,%1 ; sbbq %0,%0" \
|
||||
:"=&r" (flag), "=r" (sum) \
|
||||
:"1" (addr),"g" ((long)(size))); \
|
||||
else \
|
||||
asm("addq %3,%1 ; sbbq %0,%0 ; cmpq %1,%4 ; sbbq $0,%0" \
|
||||
:"=&r" (flag), "=r" (sum) \
|
||||
:"1" (addr),"g" ((long)(size)),"r" (HYPERVISOR_VIRT_START)); \
|
||||
flag; })
|
||||
#define __addr_ok(addr) \
|
||||
(((unsigned long)(addr) < (1UL<<48)) || \
|
||||
((unsigned long)(addr) >= HYPERVISOR_VIRT_END))
|
||||
|
||||
#define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0)
|
||||
#define access_ok(type, addr, size) (__addr_ok(addr))
|
||||
|
||||
#define array_access_ok(type,addr,count,size) \
|
||||
(likely(sizeof(count) <= 4) /* disallow 64-bit counts */ && \
|
||||
access_ok(type,addr,(unsigned long)count*(unsigned long)size))
|
||||
#define array_access_ok(type,addr,count,size) (__addr_ok(addr))
|
||||
|
||||
extern long __get_user_bad(void);
|
||||
extern void __put_user_bad(void);
|
||||
|
||||