aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.hgignore20
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c8
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/blkback/interface.c4
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/netback/netback.c6
-rw-r--r--tools/libxc/xc_core.c7
-rw-r--r--tools/libxc/xc_gnttab.c4
-rw-r--r--tools/libxc/xc_linux_build.c15
-rw-r--r--tools/libxc/xc_linux_restore.c11
-rw-r--r--tools/libxc/xc_linux_save.c27
-rw-r--r--tools/libxc/xc_load_elf.c3
-rw-r--r--tools/libxc/xc_ptrace.c2
-rw-r--r--tools/libxc/xc_vmx_build.c14
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py4
-rwxr-xr-xtools/python/xen/xend/server/controller.py8
-rw-r--r--tools/xenstore/xenstored_core.c7
-rw-r--r--xen/arch/ia64/grant_table.c4
-rw-r--r--xen/arch/x86/mm.c231
-rw-r--r--xen/arch/x86/setup.c25
-rw-r--r--xen/common/grant_table.c133
-rw-r--r--xen/include/asm-x86/mm.h9
-rw-r--r--xen/include/public/grant_table.h23
-rw-r--r--xen/include/xen/grant_table.h7
22 files changed, 402 insertions, 170 deletions
diff --git a/.hgignore b/.hgignore
index 9cfb00dcaf..1e003873c0 100644
--- a/.hgignore
+++ b/.hgignore
@@ -69,19 +69,19 @@
^tools/blktap/blkdump$
^tools/blktap/blkgnbd$
^tools/blktap/blkimg$
-^tools/blktap/blockstore\.dat$
-^tools/blktap/blockstored$
^tools/blktap/bstest$
-^tools/blktap/parallax$
^tools/blktap/vdi\.dot$
^tools/blktap/vdi\.ps$
-^tools/blktap/vdi_create$
-^tools/blktap/vdi_fill$
-^tools/blktap/vdi_list$
-^tools/blktap/vdi_snap$
-^tools/blktap/vdi_snap_list$
-^tools/blktap/vdi_tree$
-^tools/blktap/vdi_validate$
+^tools/blktap/parallax/vdi_create$
+^tools/blktap/parallax/vdi_fill$
+^tools/blktap/parallax/vdi_list$
+^tools/blktap/parallax/vdi_snap$
+^tools/blktap/parallax/vdi_snap_list$
+^tools/blktap/parallax/vdi_snap_delete$
+^tools/blktap/parallax/vdi_tree$
+^tools/blktap/parallax/vdi_validate$
+^tools/blktap/parallax/parallax$
+^tools/blktap/parallax/blockstored$
^tools/blktap/xen/.*$
^tools/check/\..*$
^tools/cmdline/.*$
diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
index 1121aeb56b..eb26470286 100644
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
@@ -120,10 +120,10 @@ static void fast_flush_area(int idx, int nr_pages)
{
if ( BLKBACK_INVALID_HANDLE != ( handle = pending_handle(idx, i) ) )
{
- unmap[i].host_virt_addr = MMAP_VADDR(idx, i);
+ unmap[i].host_addr = MMAP_VADDR(idx, i);
unmap[i].dev_bus_addr = 0;
unmap[i].handle = handle;
- pending_handle(idx, i) = BLKBACK_INVALID_HANDLE;
+ pending_handle(idx, i) = BLKBACK_INVALID_HANDLE;
invcount++;
}
}
@@ -383,7 +383,7 @@ static void dispatch_probe(blkif_t *blkif, blkif_request_t *req)
{
struct gnttab_map_grant_ref map;
- map.host_virt_addr = MMAP_VADDR(pending_idx, 0);
+ map.host_addr = MMAP_VADDR(pending_idx, 0);
map.flags = GNTMAP_host_map;
map.ref = blkif_gref_from_fas(req->frame_and_sects[0]);
map.dom = blkif->domid;
@@ -480,7 +480,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
goto bad_descriptor;
preq.nr_sects += seg[i].nsec;
- map[i].host_virt_addr = MMAP_VADDR(pending_idx, i);
+ map[i].host_addr = MMAP_VADDR(pending_idx, i);
map[i].dom = blkif->domid;
map[i].ref = blkif_gref_from_fas(fas);
map[i].flags = GNTMAP_host_map;
diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
index b62c2d345d..14de83c92f 100644
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
@@ -42,7 +42,7 @@ static void __blkif_disconnect_complete(void *arg)
* must still be notified to the remote driver.
*/
#ifdef CONFIG_XEN_BLKDEV_GRANT
- op.host_virt_addr = blkif->shmem_vaddr;
+ op.host_addr = blkif->shmem_vaddr;
op.handle = blkif->shmem_handle;
op.dev_bus_addr = 0;
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
@@ -204,7 +204,7 @@ void blkif_connect(blkif_be_connect_t *connect)
#else
{ /* Map: Use the Grant table reference */
struct gnttab_map_grant_ref op;
- op.host_virt_addr = VMALLOC_VMADDR(vma->addr);
+ op.host_addr = VMALLOC_VMADDR(vma->addr);
op.flags = GNTMAP_host_map;
op.ref = ref;
op.dom = domid;
diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c
index edc6c67d1f..8be345edea 100644
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c
@@ -511,9 +511,9 @@ inline static void net_tx_action_dealloc(void)
gop = unmap_ops;
while (dc != dp) {
pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
- gop->host_virt_addr = MMAP_VADDR(pending_idx);
+ gop->host_addr = MMAP_VADDR(pending_idx);
gop->dev_bus_addr = 0;
- gop->handle = grant_tx_ref[pending_idx];
+ gop->handle = grant_tx_ref[pending_idx];
grant_tx_ref[pending_idx] = GRANT_INVALID_REF;
gop++;
}
@@ -699,7 +699,7 @@ static void net_tx_action(unsigned long unused)
/* Packets passed to netif_rx() must have some headroom. */
skb_reserve(skb, 16);
#ifdef CONFIG_XEN_NETDEV_GRANT_TX
- mop->host_virt_addr = MMAP_VADDR(pending_idx);
+ mop->host_addr = MMAP_VADDR(pending_idx);
mop->dom = netif->domid;
mop->ref = txreq.addr >> PAGE_SHIFT;
mop->flags = GNTMAP_host_map | GNTMAP_readonly;
diff --git a/tools/libxc/xc_core.c b/tools/libxc/xc_core.c
index 653512ab92..df4352de1c 100644
--- a/tools/libxc/xc_core.c
+++ b/tools/libxc/xc_core.c
@@ -43,7 +43,7 @@ xc_domain_dumpcore(int xc_handle,
goto error_out;
}
- if ((dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == 0) {
+ if ((dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL) {
PERROR("Could not allocate dump_mem");
goto error_out;
}
@@ -108,9 +108,8 @@ xc_domain_dumpcore(int xc_handle,
free(dump_mem_start);
return 0;
error_out:
- if (dump_fd)
+ if (dump_fd != -1)
close(dump_fd);
- if (dump_mem_start)
- free(dump_mem_start);
+ free(dump_mem_start);
return -1;
}
diff --git a/tools/libxc/xc_gnttab.c b/tools/libxc/xc_gnttab.c
index 4101ca74dd..83fcf9218c 100644
--- a/tools/libxc/xc_gnttab.c
+++ b/tools/libxc/xc_gnttab.c
@@ -50,7 +50,7 @@ int xc_gnttab_map_grant_ref(int xc_handle,
struct gnttab_map_grant_ref op;
int rc;
- op.host_virt_addr = host_virt_addr;
+ op.host_addr = host_virt_addr;
op.dom = (domid_t)dom;
op.ref = ref;
op.flags = flags;
@@ -75,7 +75,7 @@ int xc_gnttab_unmap_grant_ref(int xc_handle,
struct gnttab_unmap_grant_ref op;
int rc;
- op.host_virt_addr = host_virt_addr;
+ op.host_addr = host_virt_addr;
op.dev_bus_addr = dev_bus_addr;
op.handle = handle;
diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c
index 48cace5647..45044c0735 100644
--- a/tools/libxc/xc_linux_build.c
+++ b/tools/libxc/xc_linux_build.c
@@ -318,8 +318,7 @@ static int setup_guest(int xc_handle,
return 0;
error_out:
- if ( page_array != NULL )
- free(page_array);
+ free(page_array);
return -1;
}
#else /* x86 */
@@ -616,10 +615,8 @@ static int setup_guest(int xc_handle,
return 0;
error_out:
- if ( mmu != NULL )
- free(mmu);
- if ( page_array != NULL )
- free(page_array);
+ free(mmu);
+ free(page_array);
return -1;
}
#endif
@@ -719,8 +716,7 @@ int xc_linux_build(int xc_handle,
close(initrd_fd);
if ( initrd_gfd )
gzclose(initrd_gfd);
- if ( image != NULL )
- free(image);
+ free(image);
#ifdef __ia64__
/* based on new_thread in xen/arch/ia64/domain.c */
@@ -806,8 +802,7 @@ int xc_linux_build(int xc_handle,
gzclose(initrd_gfd);
else if ( initrd_fd >= 0 )
close(initrd_fd);
- if ( image != NULL )
- free(image);
+ free(image);
return -1;
}
diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c
index c2bce43910..67d5607e77 100644
--- a/tools/libxc/xc_linux_restore.c
+++ b/tools/libxc/xc_linux_restore.c
@@ -32,7 +32,7 @@
#define PPRINTF(_f, _a...)
#endif
-ssize_t
+static ssize_t
read_exact(int fd, void *buf, size_t count)
{
int r = 0, s;
@@ -607,12 +607,9 @@ int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
out:
if ( (rc != 0) && (dom != 0) )
xc_domain_destroy(xc_handle, dom);
- if ( mmu != NULL )
- free(mmu);
- if ( pfn_to_mfn_table != NULL )
- free(pfn_to_mfn_table);
- if ( pfn_type != NULL )
- free(pfn_type);
+ free(mmu);
+ free(pfn_to_mfn_table);
+ free(pfn_type);
DPRINTF("Restore exit with rc=%d\n", rc);
return rc;
diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c
index c2a6af5f13..77349c88a3 100644
--- a/tools/libxc/xc_linux_save.c
+++ b/tools/libxc/xc_linux_save.c
@@ -136,7 +136,7 @@ static long long tv_to_us( struct timeval *new )
return (new->tv_sec * 1000000) + new->tv_usec;
}
-static long long llgettimeofday()
+static long long llgettimeofday( void )
{
struct timeval now;
gettimeofday(&now, NULL);
@@ -312,9 +312,9 @@ static int analysis_phase( int xc_handle, u32 domid,
}
-int suspend_and_state(int xc_handle, int io_fd, int dom,
- xc_dominfo_t *info,
- vcpu_guest_context_t *ctxt)
+static int suspend_and_state(int xc_handle, int io_fd, int dom,
+ xc_dominfo_t *info,
+ vcpu_guest_context_t *ctxt)
{
int i=0;
char ans[30];
@@ -1051,20 +1051,11 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom)
if(live_mfn_to_pfn_table)
munmap(live_mfn_to_pfn_table, PAGE_SIZE*1024);
- if (pfn_type != NULL)
- free(pfn_type);
-
- if (pfn_batch != NULL)
- free(pfn_batch);
-
- if (to_send != NULL)
- free(to_send);
-
- if (to_fix != NULL)
- free(to_fix);
-
- if (to_skip != NULL)
- free(to_skip);
+ free(pfn_type);
+ free(pfn_batch);
+ free(to_send);
+ free(to_fix);
+ free(to_skip);
DPRINTF("Save exit rc=%d\n",rc);
return !!rc;
diff --git a/tools/libxc/xc_load_elf.c b/tools/libxc/xc_load_elf.c
index 926db3a964..90417fb2ca 100644
--- a/tools/libxc/xc_load_elf.c
+++ b/tools/libxc/xc_load_elf.c
@@ -309,8 +309,7 @@ loadelfsymtab(
dsi->v_end = round_pgup(maxva);
out:
- if ( p != NULL )
- free(p);
+ free(p);
return 0;
}
diff --git a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c
index 2b53f460cf..fdeca60e2e 100644
--- a/tools/libxc/xc_ptrace.c
+++ b/tools/libxc/xc_ptrace.c
@@ -221,7 +221,7 @@ map_domain_va(unsigned long domid, int cpu, void * guest_va, int perm)
return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
error_out:
- return 0;
+ return NULL;
}
int
diff --git a/tools/libxc/xc_vmx_build.c b/tools/libxc/xc_vmx_build.c
index 9836746919..f10cc8391c 100644
--- a/tools/libxc/xc_vmx_build.c
+++ b/tools/libxc/xc_vmx_build.c
@@ -616,17 +616,15 @@ static int setup_guest(int xc_handle,
return 0;
error_out:
- if ( mmu != NULL )
- free(mmu);
- if ( page_array != NULL )
- free(page_array);
+ free(mmu);
+ free(page_array);
return -1;
}
#define VMX_FEATURE_FLAG 0x20
-int vmx_identify(void)
+static int vmx_identify(void)
{
int eax, ecx;
@@ -745,8 +743,7 @@ int xc_vmx_build(int xc_handle,
close(initrd_fd);
if ( initrd_gfd )
gzclose(initrd_gfd);
- if ( image != NULL )
- free(image);
+ free(image);
ctxt->flags = VGCF_VMX_GUEST;
/* FPU is set up to default initial state. */
@@ -801,8 +798,7 @@ int xc_vmx_build(int xc_handle,
gzclose(initrd_gfd);
else if ( initrd_fd >= 0 )
close(initrd_fd);
- if ( image != NULL )
- free(image);
+ free(image);
return -1;
}
diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index 4e01041342..029021f13e 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -138,7 +138,7 @@ def dom_get(dom):
if domlist and dom == domlist[0]['dom']:
return domlist[0]
return None
-
+
class XendDomainInfo:
"""Virtual machine object."""
@@ -754,7 +754,7 @@ class XendDomainInfo:
@param dev_config: device configuration
"""
dev_type = sxp.name(dev_config)
- dev = self.createDevice(self, dev_config, change=True)
+ dev = self.createDevice(dev_type, dev_config, change=True)
self.config.append(['device', dev.getConfig()])
return dev.sxpr()
diff --git a/tools/python/xen/xend/server/controller.py b/tools/python/xen/xend/server/controller.py
index f399503d7f..973398f090 100755
--- a/tools/python/xen/xend/server/controller.py
+++ b/tools/python/xen/xend/server/controller.py
@@ -142,7 +142,7 @@ class DevControllerTable:
def createDevController(self, type, vm, recreate=False):
cls = self.getDevControllerClass(type)
if not cls:
- raise XendError("unknown device type: " + type)
+ raise XendError("unknown device type: " + str(type))
return cls.createDevController(vm, recreate=recreate)
def getDevControllerTable():
@@ -283,6 +283,8 @@ class DevController:
dev.attach(recreate=recreate, change=change)
dev.exportToDB()
+ return dev
+
def configureDevice(self, id, config, change=False):
"""Reconfigure an existing device.
May be defined in subclass."""
@@ -323,9 +325,9 @@ class DevController:
return self.destroyed
def getDevice(self, id, error=False):
- dev = self.devices.get(id)
+ dev = self.devices.get(int(id))
if error and not dev:
- raise XendError("invalid device id: " + id)
+ raise XendError("invalid device id: " + str(id))
return dev
def getDeviceIds(self):
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index c91021876b..02f480e220 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1587,7 +1587,7 @@ static struct option options[] = { { "no-fork", 0, NULL, 'N' },
int main(int argc, char *argv[])
{
- int opt, *sock, *ro_sock, event_fd, max, tmpout;
+ int opt, *sock, *ro_sock, event_fd, max;
struct sockaddr_un addr;
fd_set inset, outset;
bool dofork = true;
@@ -1673,9 +1673,8 @@ int main(int argc, char *argv[])
restore_existing_connections();
if (outputpid) {
- char buffer[20];
- sprintf(buffer, "%i\n", getpid());
- write(tmpout, buffer, strlen(buffer));
+ printf("%i\n", getpid());
+ fflush(stdout);
}
/* close stdin/stdout now we're ready to accept connections */
diff --git a/xen/arch/ia64/grant_table.c b/xen/arch/ia64/grant_table.c
index 9436347779..7e25dda2f4 100644
--- a/xen/arch/ia64/grant_table.c
+++ b/xen/arch/ia64/grant_table.c
@@ -355,7 +355,7 @@ __gnttab_map_grant_ref(
/* Bitwise-OR avoids short-circuiting which screws control flow. */
if ( unlikely(__get_user(dom, &uop->dom) |
__get_user(ref, &uop->ref) |
- __get_user(host_virt_addr, &uop->host_virt_addr) |
+ __get_user(host_virt_addr, &uop->host_addr) |
__get_user(dev_hst_ro_flags, &uop->flags)) )
{
DPRINTK("Fault while reading gnttab_map_grant_ref_t.\n");
@@ -500,7 +500,7 @@ __gnttab_unmap_grant_ref(
ld = current->domain;
/* Bitwise-OR avoids short-circuiting which screws control flow. */
- if ( unlikely(__get_user(virt, &uop->host_virt_addr) |
+ if ( unlikely(__get_user(virt, &uop->host_addr) |
__get_user(frame, &uop->dev_bus_addr) |
__get_user(handle, &uop->handle)) )
{
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 8cbb7cb2d1..4cf33a594f 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -2268,6 +2268,197 @@ int do_mmu_update(
return rc;
}
+
+int update_grant_va_mapping_pte(unsigned long pte_addr,
+ l1_pgentry_t _nl1e,
+ struct domain *d,
+ struct vcpu *v)
+{
+ /* Caller must:
+ * . own d's BIGLOCK
+ * . already have 'get_page' correctly on the to-be-installed nl1e
+ * . be responsible for flushing the TLB
+ * . check PTE being installed isn't DISALLOWED
+ */
+
+ int rc = GNTST_okay;
+ void *va;
+ unsigned long gpfn, mfn;
+ struct pfn_info *page;
+ struct domain_mmap_cache mapcache, sh_mapcache;
+ u32 type_info;
+ l1_pgentry_t ol1e;
+
+ /* Grant tables and shadow mode don't currently work together. */
+ ASSERT( !shadow_mode_refcounts(d) );
+
+ /* There shouldn't be any strange bits set on the PTE. */
+ ASSERT( (l1e_get_flags(_nl1e) & L1_DISALLOW_MASK) == 0);
+
+ cleanup_writable_pagetable(d);
+
+ domain_mmap_cache_init(&mapcache);
+ domain_mmap_cache_init(&sh_mapcache);
+
+ gpfn = pte_addr >> PAGE_SHIFT;
+ mfn = __gpfn_to_mfn(d, gpfn);
+
+ if ( unlikely(!get_page_from_pagenr(mfn, current->domain)) )
+ {
+ MEM_LOG("Could not get page for normal update");
+ rc = -EINVAL;
+ goto failed_norefs;
+ }
+
+ va = map_domain_page_with_cache(mfn, &mapcache);
+ va = (void *)((unsigned long)va +
+ (unsigned long)(pte_addr & ~PAGE_MASK));
+ page = &frame_table[mfn];
+
+ type_info = page->u.inuse.type_info;
+ if ( (type_info & PGT_type_mask) != PGT_l1_page_table) {
+ DPRINTK("Grant map attempted to update a non-L1 page\n");
+ rc = -EINVAL;
+ goto failed;
+ }
+
+ if ( likely(get_page_type(page, type_info & (PGT_type_mask|PGT_va_mask))) )
+ {
+
+ if ( unlikely(__copy_from_user(&ol1e, (l1_pgentry_t *)va,
+ sizeof(ol1e)) != 0) ) {
+ put_page_type(page);
+ rc = -EINVAL;
+ goto failed;
+ }
+
+ if ( update_l1e(va, ol1e, _nl1e) )
+ {
+ put_page_from_l1e(ol1e, d);
+
+ if ( l1e_get_flags(ol1e) & _PAGE_PRESENT )
+ rc = GNTST_flush_all; /* We don't know what vaddr to flush */
+ else
+ rc = GNTST_okay; /* Caller need not invalidate TLB entry */
+
+ if ( unlikely(shadow_mode_enabled(d)) )
+ shadow_l1_normal_pt_update(d, pte_addr, _nl1e, &sh_mapcache);
+ }
+ else
+ rc = -EINVAL;
+
+ put_page_type(page);
+ }
+
+ failed:
+ unmap_domain_page_with_cache(va, &mapcache);
+ put_page(page);
+
+ failed_norefs:
+ domain_mmap_cache_destroy(&mapcache);
+ domain_mmap_cache_destroy(&sh_mapcache);
+
+ return rc;
+}
+
+
+
+int clear_grant_va_mapping_pte(unsigned long addr, unsigned long frame,
+ struct domain *d)
+{
+ /* Caller must:
+ * . own d's BIGLOCK
+ * . already have 'get_page' correctly on the to-be-installed nl1e
+ * . be responsible for flushing the TLB
+ * . check PTE being installed isn't DISALLOWED
+ */
+
+ int rc = GNTST_okay;
+ void *va;
+ unsigned long gpfn, mfn;
+ struct pfn_info *page;
+ struct domain_mmap_cache mapcache, sh_mapcache;
+ u32 type_info;
+ l1_pgentry_t ol1e;
+
+ /* Grant tables and shadow mode don't work together. */
+ ASSERT( !shadow_mode_refcounts(d) );
+
+ cleanup_writable_pagetable(d);
+
+ domain_mmap_cache_init(&mapcache);
+ domain_mmap_cache_init(&sh_mapcache);
+
+ gpfn = addr >> PAGE_SHIFT;
+ mfn = __gpfn_to_mfn(d, gpfn);
+
+ if ( unlikely(!get_page_from_pagenr(mfn, current->domain)) )
+ {
+ MEM_LOG("Could not get page for normal update");
+ rc = -EINVAL;
+ goto failed_norefs;
+ }
+
+ va = map_domain_page_with_cache(mfn, &mapcache);
+ va = (void *)((unsigned long)va +
+ (unsigned long)(addr & ~PAGE_MASK));
+ page = &frame_table[mfn];
+
+ type_info = page->u.inuse.type_info;
+ if ( (type_info & PGT_type_mask) != PGT_l1_page_table) {
+ DPRINTK("Grant map attempted to update a non-L1 page\n");
+ rc = -EINVAL;
+ goto failed;
+ }
+
+ if ( likely(get_page_type(page, type_info & (PGT_type_mask|PGT_va_mask))) )
+ {
+ if ( unlikely(__copy_from_user(&ol1e, (l1_pgentry_t *)va,
+ sizeof(ol1e)) != 0) )
+ {
+ rc = -EINVAL;
+ put_page_type(page);
+ goto failed;
+ }
+
+ /*
+ * Check that the virtual address supplied is actually mapped to frame.
+ */
+ if ( unlikely((l1e_get_intpte(ol1e) >> PAGE_SHIFT) != frame ))
+ {
+ DPRINTK("PTE entry %lx for address %lx doesn't match frame %lx\n",
+ (unsigned long)l1e_get_intpte(ol1e), addr, frame);
+ rc = -EINVAL;
+ put_page_type(page);
+ goto failed;
+ }
+
+ /* Delete pagetable entry. */
+ if ( unlikely(__put_user(0, (unsigned long *)va)))
+ {
+ DPRINTK("Cannot delete PTE entry at %p.\n", va);
+ rc = -EINVAL;
+ } else {
+ if ( unlikely(shadow_mode_enabled(d)) )
+ shadow_l1_normal_pt_update(d, addr, l1e_empty(),
+ &sh_mapcache);
+ }
+ put_page_type(page);
+ }
+
+ failed:
+ unmap_domain_page_with_cache(va, &mapcache);
+ put_page(page);
+
+ failed_norefs:
+ domain_mmap_cache_destroy(&mapcache);
+ domain_mmap_cache_destroy(&sh_mapcache);
+
+ return rc;
+}
+
+
+
/* This function assumes the caller is holding the domain's BIGLOCK
* and is running in a shadow mode
*/
@@ -2283,7 +2474,7 @@ int update_grant_va_mapping(unsigned long va,
* . check PTE being installed isn't DISALLOWED
*/
- int rc = 0;
+ int rc = GNTST_okay;
l1_pgentry_t *pl1e;
l1_pgentry_t ol1e;
@@ -2305,9 +2496,9 @@ int update_grant_va_mapping(unsigned long va,
{
put_page_from_l1e(ol1e, d);
if ( l1e_get_flags(ol1e) & _PAGE_PRESENT )
- rc = 0; /* Caller needs to invalidate TLB entry */
+ rc = GNTST_flush_one;
else
- rc = 1; /* Caller need not invalidate TLB entry */
+ rc = GNTST_okay; /* Caller need not invalidate TLB entry */
}
else
rc = -EINVAL;
@@ -2324,6 +2515,40 @@ int update_grant_va_mapping(unsigned long va,
return rc;
}
+int clear_grant_va_mapping(unsigned long addr, unsigned long frame)
+{
+ l1_pgentry_t *pl1e;
+ unsigned long _ol1e;
+
+ pl1e = &linear_pg_table[l1_linear_offset(addr)];
+
+ if ( unlikely(__get_user(_ol1e, (unsigned long *)pl1e) != 0) )
+ {
+ DPRINTK("Could not find PTE entry for address %lx\n", addr);
+ return -EINVAL;
+ }
+
+ /*
+ * Check that the virtual address supplied is actually mapped to
+ * frame.
+ */
+ if ( unlikely((_ol1e >> PAGE_SHIFT) != frame ))
+ {
+ DPRINTK("PTE entry %lx for address %lx doesn't match frame %lx\n",
+ _ol1e, addr, frame);
+ return -EINVAL;
+ }
+
+ /* Delete pagetable entry. */
+ if ( unlikely(__put_user(0, (unsigned long *)pl1e)))
+ {
+ DPRINTK("Cannot delete PTE entry at %p.\n", (unsigned long *)pl1e);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
int do_update_va_mapping(unsigned long va, u64 val64,
unsigned long flags)
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index fcf7f522b8..070a9127b2 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -336,26 +336,25 @@ void __init __start_xen(multiboot_info_t *mbi)
/* Find a large enough RAM extent to stash the DOM0 modules. */
for ( i = 0; ; i++ )
{
- if ( (e820.map[i].type == E820_RAM) &&
- (e820.map[i].size >= modules_length) &&
- ((e820.map[i].addr + e820.map[i].size) >=
- (xenheap_phys_end + modules_length)) )
- {
- /* Stash as near as possible to the beginning of the RAM extent. */
- initial_images_start = e820.map[i].addr;
- if ( initial_images_start < xenheap_phys_end )
- initial_images_start = xenheap_phys_end;
- initial_images_end = initial_images_start + modules_length;
- break;
- }
-
if ( i == e820.nr_map )
{
printk("Not enough memory to stash the DOM0 kernel image.\n");
for ( ; ; ) ;
}
+
+ if ( (e820.map[i].type == E820_RAM) &&
+ (e820.map[i].size >= modules_length) &&
+ ((e820.map[i].addr + e820.map[i].size) >=
+ (xenheap_phys_end + modules_length)) )
+ break;
}
+ /* Stash as near as possible to the beginning of the RAM extent. */
+ initial_images_start = e820.map[i].addr;
+ if ( initial_images_start < xenheap_phys_end )
+ initial_images_start = xenheap_phys_end;
+ initial_images_end = initial_images_start + modules_length;
+
#if defined(CONFIG_X86_32)
memmove((void *)initial_images_start, /* use low mapping */
(void *)mod[0].mod_start, /* use low mapping */
diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index 03f9c8dd6a..b5bec9e229 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -6,6 +6,8 @@
*
* Copyright (c) 2005 Christopher Clark
* Copyright (c) 2004 K A Fraser
+ * Copyright (c) 2005 Andrew Warfield
+ * Modifications by Geoffrey Lefebvre are (c) Intel Research Cambridge
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -50,7 +52,7 @@ get_maptrack_handle(
grant_table_t *t)
{
unsigned int h;
- if ( unlikely((h = t->maptrack_head) == t->maptrack_limit) )
+ if ( unlikely((h = t->maptrack_head) == (t->maptrack_limit - 1)) )
return -1;
t->maptrack_head = t->maptrack[h].ref_and_flags >> MAPTRACK_REF_SHIFT;
t->map_count++;
@@ -73,7 +75,7 @@ __gnttab_activate_grant_ref(
struct domain *granting_d,
grant_ref_t ref,
u16 dev_hst_ro_flags,
- unsigned long host_virt_addr,
+ unsigned long addr,
unsigned long *pframe ) /* OUT */
{
domid_t sdom;
@@ -95,7 +97,7 @@ __gnttab_activate_grant_ref(
* Returns:
* . -ve: error
* . 1: ok
- * . 0: ok and TLB invalidate of host_virt_addr needed.
+ * . 0: ok and TLB invalidate of host_addr needed.
*
* On success, *pframe contains mfn.
*/
@@ -121,6 +123,10 @@ __gnttab_activate_grant_ref(
sflags = sha->flags;
sdom = sha->domid;
+ /* This loop attempts to set the access (reading/writing) flags
+ * in the grant table entry. It tries a cmpxchg on the field
+ * up to five times, and then fails under the assumption that
+ * the guest is misbehaving. */
for ( ; ; )
{
u32 scombo, prev_scombo, new_scombo;
@@ -253,28 +259,37 @@ __gnttab_activate_grant_ref(
/*
* At this point:
- * act->pin updated to reflect mapping.
+ * act->pin updated to reference count mappings.
* sha->flags updated to indicate to granting domain mapping done.
* frame contains the mfn.
*/
spin_unlock(&granting_d->grant_table->lock);
- if ( (host_virt_addr != 0) && (dev_hst_ro_flags & GNTMAP_host_map) )
+
+ if ( (addr != 0) && (dev_hst_ro_flags & GNTMAP_host_map) )
{
/* Write update into the pagetable. */
l1_pgentry_t pte;
pte = l1e_from_pfn(frame, GRANT_PTE_FLAGS);
+
+ if ( (dev_hst_ro_flags & GNTMAP_application_map) )
+ l1e_add_flags(pte,_PAGE_USER);
if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
l1e_add_flags(pte,_PAGE_RW);
- rc = update_grant_va_mapping( host_virt_addr, pte,
- mapping_d, mapping_ed );
- /*
- * IMPORTANT: (rc == 0) => must flush / invalidate entry in TLB.
- * This is done in the outer gnttab_map_grant_ref.
- */
+ if (!(dev_hst_ro_flags & GNTMAP_contains_pte))
+ {
+ rc = update_grant_va_mapping( addr, pte,
+ mapping_d, mapping_ed );
+ } else {
+ rc = update_grant_va_mapping_pte( addr, pte,
+ mapping_d, mapping_ed );
+ }
+ /* IMPORTANT: rc indicates the degree of TLB flush that is required.
+ * GNTST_flush_one (1) or GNTST_flush_all (2). This is done in the
+ * outer gnttab_map_grant_ref. */
if ( rc < 0 )
{
/* Failure: undo and abort. */
@@ -317,6 +332,9 @@ __gnttab_activate_grant_ref(
/*
* Returns 0 if TLB flush / invalidate required by caller.
* va will indicate the address to be invalidated.
+ *
+ * addr is _either_ a host virtual address, or the address of the pte to
+ * update, as indicated by the GNTMAP_contains_pte flag.
*/
static int
__gnttab_map_grant_ref(
@@ -326,10 +344,10 @@ __gnttab_map_grant_ref(
domid_t dom;
grant_ref_t ref;
struct domain *ld, *rd;
- struct vcpu *led;
+ struct vcpu *led;
u16 dev_hst_ro_flags;
int handle;
- unsigned long frame = 0, host_virt_addr;
+ unsigned long frame = 0, addr;
int rc;
led = current;
@@ -338,19 +356,20 @@ __gnttab_map_grant_ref(
/* Bitwise-OR avoids short-circuiting which screws control flow. */
if ( unlikely(__get_user(dom, &uop->dom) |
__get_user(ref, &uop->ref) |
- __get_user(host_virt_addr, &uop->host_virt_addr) |
+ __get_user(addr, &uop->host_addr) |
__get_user(dev_hst_ro_flags, &uop->flags)) )
{
DPRINTK("Fault while reading gnttab_map_grant_ref_t.\n");
return -EFAULT; /* don't set status */
}
-
- if ( ((host_virt_addr != 0) || (dev_hst_ro_flags & GNTMAP_host_map)) &&
- unlikely(!__addr_ok(host_virt_addr)))
+ if ( (dev_hst_ro_flags & GNTMAP_host_map) &&
+ ( (addr == 0) ||
+ (!(dev_hst_ro_flags & GNTMAP_contains_pte) &&
+ unlikely(!__addr_ok(addr))) ) )
{
DPRINTK("Bad virtual address (%lx) or flags (%x).\n",
- host_virt_addr, dev_hst_ro_flags);
+ addr, dev_hst_ro_flags);
(void)__put_user(GNTST_bad_virt_addr, &uop->handle);
return GNTST_bad_gntref;
}
@@ -386,12 +405,20 @@ __gnttab_map_grant_ref(
grant_mapping_t *new_mt;
grant_table_t *lgt = ld->grant_table;
+ if ( (lgt->maptrack_limit << 1) > MAPTRACK_MAX_ENTRIES )
+ {
+ put_domain(rd);
+ DPRINTK("Maptrack table is at maximum size.\n");
+ (void)__put_user(GNTST_no_device_space, &uop->handle);
+ return GNTST_no_device_space;
+ }
+
/* Grow the maptrack table. */
new_mt = alloc_xenheap_pages(lgt->maptrack_order + 1);
if ( new_mt == NULL )
{
put_domain(rd);
- DPRINTK("No more map handles available\n");
+ DPRINTK("No more map handles available.\n");
(void)__put_user(GNTST_no_device_space, &uop->handle);
return GNTST_no_device_space;
}
@@ -405,7 +432,7 @@ __gnttab_map_grant_ref(
lgt->maptrack_order += 1;
lgt->maptrack_limit <<= 1;
- printk("Doubled maptrack size\n");
+ DPRINTK("Doubled maptrack size\n");
handle = get_maptrack_handle(ld->grant_table);
}
@@ -416,7 +443,7 @@ __gnttab_map_grant_ref(
if ( 0 <= ( rc = __gnttab_activate_grant_ref( ld, led, rd, ref,
dev_hst_ro_flags,
- host_virt_addr, &frame)))
+ addr, &frame)))
{
/*
* Only make the maptrack live _after_ writing the pte, in case we
@@ -430,8 +457,9 @@ __gnttab_map_grant_ref(
(void)__put_user(frame, &uop->dev_bus_addr);
- if ( dev_hst_ro_flags & GNTMAP_host_map )
- *va = host_virt_addr;
+ if ( ( dev_hst_ro_flags & GNTMAP_host_map ) &&
+ !( dev_hst_ro_flags & GNTMAP_contains_pte) )
+ *va = addr;
(void)__put_user(handle, &uop->handle);
}
@@ -449,12 +477,12 @@ static long
gnttab_map_grant_ref(
gnttab_map_grant_ref_t *uop, unsigned int count)
{
- int i, flush = 0;
+ int i, rc, flush = 0;
unsigned long va = 0;
for ( i = 0; i < count; i++ )
- if ( __gnttab_map_grant_ref(&uop[i], &va) == 0 )
- flush++;
+ if ( (rc =__gnttab_map_grant_ref(&uop[i], &va)) >= 0 )
+ flush += rc;
if ( flush == 1 )
flush_tlb_one_mask(current->domain->cpumask, va);
@@ -479,12 +507,12 @@ __gnttab_unmap_grant_ref(
grant_mapping_t *map;
u16 flags;
s16 rc = 1;
- unsigned long frame, virt;
+ unsigned long frame, addr;
ld = current->domain;
/* Bitwise-OR avoids short-circuiting which screws control flow. */
- if ( unlikely(__get_user(virt, &uop->host_virt_addr) |
+ if ( unlikely(__get_user(addr, &uop->host_addr) |
__get_user(frame, &uop->dev_bus_addr) |
__get_user(handle, &uop->handle)) )
{
@@ -554,41 +582,17 @@ __gnttab_unmap_grant_ref(
/* Frame is now unmapped for device access. */
}
- if ( (virt != 0) &&
+ if ( (addr != 0) &&
(flags & GNTMAP_host_map) &&
((act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) > 0))
{
- l1_pgentry_t *pl1e;
- unsigned long _ol1e;
-
- pl1e = &linear_pg_table[l1_linear_offset(virt)];
-
- if ( unlikely(__get_user(_ol1e, (unsigned long *)pl1e) != 0) )
- {
- DPRINTK("Could not find PTE entry for address %lx\n", virt);
- rc = -EINVAL;
- goto unmap_out;
- }
-
- /*
- * Check that the virtual address supplied is actually mapped to
- * act->frame.
- */
- if ( unlikely((_ol1e >> PAGE_SHIFT) != frame ))
- {
- DPRINTK("PTE entry %lx for address %lx doesn't match frame %lx\n",
- _ol1e, virt, frame);
- rc = -EINVAL;
- goto unmap_out;
- }
-
- /* Delete pagetable entry. */
- if ( unlikely(__put_user(0, (unsigned long *)pl1e)))
+ if (flags & GNTMAP_contains_pte)
{
- DPRINTK("Cannot delete PTE entry at %p for virtual address %lx\n",
- pl1e, virt);
- rc = -EINVAL;
- goto unmap_out;
+ if ( (rc = clear_grant_va_mapping_pte(addr, frame, ld)) < 0 )
+ goto unmap_out;
+ } else {
+ if ( (rc = clear_grant_va_mapping(addr, frame)) < 0 )
+ goto unmap_out;
}
map->ref_and_flags &= ~GNTMAP_host_map;
@@ -606,7 +610,8 @@ __gnttab_unmap_grant_ref(
}
rc = 0;
- *va = virt;
+ if ( !( flags & GNTMAP_contains_pte) )
+ *va = addr;
}
if ( (map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0)
@@ -630,6 +635,7 @@ __gnttab_unmap_grant_ref(
if ( act->pin == 0 )
{
+ act->frame = 0xdeadbeef;
clear_bit(_GTF_reading, &sha->flags);
put_page(&frame_table[frame]);
}
@@ -769,7 +775,8 @@ gnttab_dump_table(gnttab_dump_table_t *uop)
{
DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) "
"dom:(%hu) frame:(%lx)\n",
- op.dom, i, sha_copy.flags, sha_copy.domid, sha_copy.frame);
+ op.dom, i, sha_copy.flags, sha_copy.domid,
+ (unsigned long) sha_copy.frame);
}
}
@@ -823,7 +830,7 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count)
gnttab_donate_t *gop = &uop[i];
#if GRANT_DEBUG
printk("gnttab_donate: i=%d mfn=%08x domid=%d gref=%08x\n",
- i, gop->mfn, gop->domid, gop->handle);
+ i, (unsigned int)gop->mfn, gop->domid, gop->handle);
#endif
page = &frame_table[gop->mfn];
@@ -1027,7 +1034,7 @@ gnttab_check_unmap(
if ( ld->domain_id != 0 )
{
DPRINTK("Foreign unref rd(%d) ld(%d) frm(%x) flgs(%x).\n",
- rd->domain_id, ld->domain_id, frame, readonly);
+ rd->domain_id, ld->domain_id, (unsigned int)frame, readonly);
}
#endif
diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h
index 505481253e..b0389df3dd 100644
--- a/xen/include/asm-x86/mm.h
+++ b/xen/include/asm-x86/mm.h
@@ -381,4 +381,13 @@ int update_grant_va_mapping(unsigned long va,
l1_pgentry_t _nl1e,
struct domain *d,
struct vcpu *v);
+int update_grant_va_mapping_pte(unsigned long pte_addr,
+ l1_pgentry_t _nl1e,
+ struct domain *d,
+ struct vcpu *v);
+
+int clear_grant_va_mapping(unsigned long addr, unsigned long frame);
+int clear_grant_va_mapping_pte(unsigned long addr, unsigned long frame,
+ struct domain *d);
+
#endif /* __ASM_X86_MM_H__ */
diff --git a/xen/include/public/grant_table.h b/xen/include/public/grant_table.h
index 4522d52571..b70bb65856 100644
--- a/xen/include/public/grant_table.h
+++ b/xen/include/public/grant_table.h
@@ -142,7 +142,10 @@ typedef u16 grant_ref_t;
* 1. If GNTPIN_map_for_dev is specified then <dev_bus_addr> is the address
* via which I/O devices may access the granted frame.
* 2. If GNTPIN_map_for_host is specified then a mapping will be added at
- * virtual address <host_virt_addr> in the current address space.
+ * either a host virtual address in the current address space, or at
+ * a PTE at the specified machine address. The type of mapping to
+ * perform is selected through the GNTMAP_contains_pte flag, and the
+ * address is specified in <host_addr>.
* 3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a
* host mapping is destroyed by other means then it is *NOT* guaranteed
* to be accounted to the correct grant reference!
@@ -150,7 +153,7 @@ typedef u16 grant_ref_t;
#define GNTTABOP_map_grant_ref 0
typedef struct gnttab_map_grant_ref {
/* IN parameters. */
- memory_t host_virt_addr;
+ memory_t host_addr;
domid_t dom;
grant_ref_t ref;
u16 flags; /* GNTMAP_* */
@@ -161,7 +164,7 @@ typedef struct gnttab_map_grant_ref {
/*
* GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings
- * tracked by <handle>. If <host_virt_addr> or <dev_bus_addr> is zero, that
+ * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that
* field is ignored. If non-zero, they must refer to a device/host mapping
* that is tracked by <handle>
* NOTES:
@@ -173,7 +176,7 @@ typedef struct gnttab_map_grant_ref {
#define GNTTABOP_unmap_grant_ref 1
typedef struct gnttab_unmap_grant_ref {
/* IN parameters. */
- memory_t host_virt_addr;
+ memory_t host_addr;
memory_t dev_bus_addr;
u16 handle;
/* OUT parameters. */
@@ -247,10 +250,20 @@ typedef struct {
#define _GNTMAP_application_map (3)
#define GNTMAP_application_map (1<<_GNTMAP_application_map)
+ /*
+ * GNTMAP_contains_pte subflag:
+ * 0 => This map request contains a host virtual address.
+ * 1 => This map request contains the machine addess of the PTE to update.
+ */
+#define _GNTMAP_contains_pte (4)
+#define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte)
+
/*
* Values for error status returns. All errors are -ve.
*/
-#define GNTST_okay (0)
+#define GNTST_flush_all (2) /* Success, need to flush entire TLB. */
+#define GNTST_flush_one (1) /* Success, need to flush a vaddr. */
+#define GNTST_okay (0) /* Normal return. */
#define GNTST_general_error (-1) /* General undefined error. */
#define GNTST_bad_domain (-2) /* Unrecognsed domain id. */
#define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntref. */
diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h
index c273eacada..1250c5abaf 100644
--- a/xen/include/xen/grant_table.h
+++ b/xen/include/xen/grant_table.h
@@ -61,11 +61,12 @@ typedef struct {
* table of these, indexes into which are returned as a 'mapping handle'.
*/
typedef struct {
- u16 ref_and_flags; /* 0-2: GNTMAP_* ; 3-15: grant ref */
+ u16 ref_and_flags; /* 0-4: GNTMAP_* ; 5-15: grant ref */
domid_t domid; /* granting domain */
} grant_mapping_t;
-#define MAPTRACK_GNTMAP_MASK 7
-#define MAPTRACK_REF_SHIFT 3
+#define MAPTRACK_GNTMAP_MASK 0x1f
+#define MAPTRACK_REF_SHIFT 5
+#define MAPTRACK_MAX_ENTRIES ( 1 << (16 - MAPTRACK_REF_SHIFT) )
/* Per-domain grant information. */
typedef struct {