From 1511aa3b38f7a01e47f7eb70225ffe2aeb461b21 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Fri, 19 Aug 2005 17:38:07 +0000 Subject: [PATCH 01/29] Improve error paths and cleanup code. Signed-off-by: Christian Limpach --- .../drivers/xen/blkback/xenbus.c | 24 +++-- .../drivers/xen/blkfront/blkfront.c | 98 +++++++++---------- linux-2.6-xen-sparse/include/asm-xen/xenbus.h | 10 ++ 3 files changed, 71 insertions(+), 61 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c index 416832c87b..175b10f6b1 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c @@ -182,16 +182,20 @@ static void backend_changed(struct xenbus_watch *watch, const char *node) "frontend-id", "%li", &be->frontend_id, "frontend", NULL, &frontend, NULL); - if (err == -ENOENT || err == -ERANGE || + if (XENBUS_EXIST_ERR(err) || strlen(frontend) == 0 || !xenbus_exists(frontend, "")) { - if (frontend) - kfree(frontend); /* If we can't get a frontend path and a frontend-id, * then our bus-id is no longer valid and we need to * destroy the backend device. */ goto device_fail; } + if (err < 0) { + xenbus_dev_error(dev, err, + "reading %s/frontend or frontend-id", + dev->nodename); + goto device_fail; + } if (!be->frontpath || strcmp(frontend, be->frontpath)) { if (be->watch.node) @@ -199,6 +203,7 @@ static void backend_changed(struct xenbus_watch *watch, const char *node) if (be->frontpath) kfree(be->frontpath); be->frontpath = frontend; + frontend = NULL; be->watch.node = be->frontpath; be->watch.callback = frontend_changed; err = register_xenbus_watch(&be->watch); @@ -206,14 +211,13 @@ static void backend_changed(struct xenbus_watch *watch, const char *node) be->watch.node = NULL; goto device_fail; } - } else - kfree(frontend); + } err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev); - if (err == -ENOENT || err == -ERANGE) + if (XENBUS_EXIST_ERR(err)) goto out; if (err < 0) { - xenbus_dev_error(dev, err, "Reading physical-device"); + xenbus_dev_error(dev, err, "reading physical-device"); goto device_fail; } if (be->pdev && be->pdev != pdev) { @@ -253,12 +257,14 @@ static void backend_changed(struct xenbus_watch *watch, const char *node) frontend_changed(&be->watch, be->frontpath); } + out: + if (frontend) + kfree(frontend); return; device_fail: device_unregister(&be->dev->dev); - out: - return; + goto out; } static int blkback_probe(struct xenbus_device *dev, diff --git a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c index 0e3d172aed..d7afebf094 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -1134,25 +1134,24 @@ static void watch_for_status(struct xenbus_watch *watch, const char *node) "info", "%u", &binfo, "sector-size", "%lu", §or_size, NULL); - - if (err) + if (err) { xenbus_dev_error(info->dev, err, "reading backend fields"); - else { - xlvbd_add(sectors, info->vdevice, info->handle, binfo, - sector_size); - info->connected = 1; - - /* First to connect? blkif is now connected. */ - if (blkif_vbds_connected++ == 0) - blkif_state = BLKIF_STATE_CONNECTED; - - xenbus_dev_ok(info->dev); - - /* Kick pending requests. */ - spin_lock_irq(&blkif_io_lock); - kick_pending_request_queues(); - spin_unlock_irq(&blkif_io_lock); + return; } + + xlvbd_add(sectors, info->vdevice, info->handle, binfo, sector_size); + info->connected = 1; + + /* First to connect? blkif is now connected. */ + if (blkif_vbds_connected++ == 0) + blkif_state = BLKIF_STATE_CONNECTED; + + xenbus_dev_ok(info->dev); + + /* Kick pending requests. */ + spin_lock_irq(&blkif_io_lock); + kick_pending_request_queues(); + spin_unlock_irq(&blkif_io_lock); } static int setup_blkring(struct xenbus_device *dev, unsigned int backend_id) @@ -1199,36 +1198,28 @@ static int talk_to_backend(struct xenbus_device *dev, const char *message; int err, backend_id; - backend = xenbus_read(dev->nodename, "backend", NULL); - if (IS_ERR(backend)) { - err = PTR_ERR(backend); - if (err == -ENOENT) - goto out; - xenbus_dev_error(dev, err, "reading %s/backend", + backend = NULL; + err = xenbus_gather(dev->nodename, + "backend-id", "%i", &backend_id, + "backend", NULL, &backend, + NULL); + if (XENBUS_EXIST_ERR(err)) + goto out; + if (backend && strlen(backend) == 0) { + err = -ENOENT; + goto out; + } + if (err < 0) { + xenbus_dev_error(dev, err, "reading %s/backend or backend-id", dev->nodename); goto out; } - if (strlen(backend) == 0) { - err = -ENOENT; - goto free_backend; - } - - /* FIXME: This driver can't handle backends on different - * domains. Check and fail gracefully. */ - err = xenbus_scanf(dev->nodename, "backend-id", "%i", &backend_id); - if (err == -ENOENT) - goto free_backend; - if (err < 0) { - xenbus_dev_error(dev, err, "reading %s/backend-id", - dev->nodename); - goto free_backend; - } /* First device? We create shared ring, alloc event channel. */ if (blkif_vbds == 0) { err = setup_blkring(dev, backend_id); if (err) - goto free_backend; + goto out; } err = xenbus_transaction_start(dev->nodename); @@ -1258,9 +1249,11 @@ static int talk_to_backend(struct xenbus_device *dev, goto abort_transaction; } - info->watch.node = info->backend = backend; - info->watch.callback = watch_for_status; + info->backend = backend; + backend = NULL; + info->watch.node = info->backend; + info->watch.callback = watch_for_status; err = register_xenbus_watch(&info->watch); if (err) { message = "registering watch on backend"; @@ -1272,20 +1265,20 @@ static int talk_to_backend(struct xenbus_device *dev, xenbus_dev_error(dev, err, "completing transaction"); goto destroy_blkring; } - return 0; -abort_transaction: + out: + if (backend) + kfree(backend); + return err; + + abort_transaction: xenbus_transaction_end(1); /* Have to do this *outside* transaction. */ xenbus_dev_error(dev, err, "%s", message); -destroy_blkring: + destroy_blkring: if (blkif_vbds == 0) blkif_free(); -free_backend: - kfree(backend); -out: - printk("%s:%u = %i\n", __FILE__, __LINE__, err); - return err; + goto out; } /* Setup supplies the backend dir, virtual device. @@ -1301,7 +1294,7 @@ static int blkfront_probe(struct xenbus_device *dev, /* FIXME: Use dynamic device id if this is not set. */ err = xenbus_scanf(dev->nodename, "virtual-device", "%i", &vdevice); - if (err == -ENOENT) + if (XENBUS_EXIST_ERR(err)) return err; if (err < 0) { xenbus_dev_error(dev, err, "reading virtual-device"); @@ -1316,6 +1309,7 @@ static int blkfront_probe(struct xenbus_device *dev, info->dev = dev; info->vdevice = vdevice; info->connected = 0; + /* Front end dir is a number, which is used as the id. */ info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0); dev->data = info; @@ -1427,8 +1421,8 @@ static int __init xlblk_init(void) #ifdef CONFIG_XEN_BLKDEV_GRANT /* A grant for every ring slot, plus one for the ring itself. */ - if ( 0 > gnttab_alloc_grant_references(MAXIMUM_OUTSTANDING_BLOCK_REQS + 1, - &gref_head, &gref_terminal) ) + if (gnttab_alloc_grant_references(MAXIMUM_OUTSTANDING_BLOCK_REQS + 1, + &gref_head, &gref_terminal) < 0) return 1; printk(KERN_ALERT "Blkif frontend is using grant tables.\n"); #endif diff --git a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h index d119b78ad4..acdf931acc 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h +++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h @@ -128,4 +128,14 @@ void reregister_xenbus_watches(void); void xenbus_suspend(void); void xenbus_resume(void); +#define XENBUS_IS_ERR_READ(str) ({ \ + if (!IS_ERR(str) && strlen(str) == 0) { \ + kfree(str); \ + str = ERR_PTR(-ERANGE); \ + } \ + IS_ERR(str); \ +}) + +#define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE) + #endif /* _ASM_XEN_XENBUS_H */ From 6328b7e119a0b13ac7123500d3e4d415490410dc Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 19 Aug 2005 17:51:37 +0000 Subject: [PATCH 02/29] Six the SWIOTLB. The bus range does need to be contiguous after all as a range comparsion is used to determine if a given dma address is within the swiotlb aperture. Maybe we can do better sometime in the future (fast address range comparison yet not require bus-contiguous aperture). But reverting this morning's patch is fine for now. Signed-off-by: Keir Fraser --- .../arch/xen/i386/kernel/swiotlb.c | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c index db3881c840..8d8fe38bf5 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c @@ -43,20 +43,18 @@ #define IO_TLB_SHIFT 11 int swiotlb_force; +static char *iotlb_virt_start; +static unsigned long iotlb_nslabs; /* * Used to do a quick range check in swiotlb_unmap_single and * swiotlb_sync_single_*, to see if the memory was in fact allocated by this * API. */ -static char *iotlb_virt_start, *iotlb_virt_end; -static dma_addr_t iotlb_bus_start, iotlb_bus_end; +static dma_addr_t iotlb_bus_start, iotlb_bus_mask; -/* - * The number of IO TLB blocks (in groups of 64) betweeen iotlb_virt_start and - * iotlb_virt_end. This is command line adjustable via setup_io_tlb_npages. - */ -static unsigned long iotlb_nslabs; +/* Does the given dma address reside within the swiotlb aperture? */ +#define in_swiotlb_aperture(a) (!(((a) ^ iotlb_bus_start) & iotlb_bus_mask)) /* * When the IOMMU overflows we return a fallback buffer. This sets the size. @@ -94,6 +92,9 @@ setup_io_tlb_npages(char *str) iotlb_nslabs = simple_strtoul(str, &str, 0) << (20 - IO_TLB_SHIFT); iotlb_nslabs = ALIGN(iotlb_nslabs, IO_TLB_SEGSIZE); + /* Round up to power of two (xen_create_contiguous_region). */ + while (iotlb_nslabs & (iotlb_nslabs-1)) + iotlb_nslabs += iotlb_nslabs & ~(iotlb_nslabs-1); } if (*str == ',') ++str; @@ -120,6 +121,9 @@ swiotlb_init_with_default_size (size_t default_size) if (!iotlb_nslabs) { iotlb_nslabs = (default_size >> IO_TLB_SHIFT); iotlb_nslabs = ALIGN(iotlb_nslabs, IO_TLB_SEGSIZE); + /* Round up to power of two (xen_create_contiguous_region). */ + while (iotlb_nslabs & (iotlb_nslabs-1)) + iotlb_nslabs += iotlb_nslabs & ~(iotlb_nslabs-1); } bytes = iotlb_nslabs * (1UL << IO_TLB_SHIFT); @@ -133,17 +137,12 @@ swiotlb_init_with_default_size (size_t default_size) "Use dom0_mem Xen boot parameter to reserve\n" "some DMA memory (e.g., dom0_mem=-128M).\n"); - for (i = 0; i < iotlb_nslabs; i += IO_TLB_SEGSIZE) - xen_create_contiguous_region( - (unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT), - get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT)); - - iotlb_virt_end = iotlb_virt_start + bytes; + xen_create_contiguous_region( + (unsigned long)iotlb_virt_start, get_order(bytes)); /* * Allocate and initialize the free list array. This array is used - * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE - * between iotlb_virt_start and iotlb_virt_end. + * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE. */ io_tlb_list = alloc_bootmem(iotlb_nslabs * sizeof(int)); for (i = 0; i < iotlb_nslabs; i++) @@ -156,15 +155,19 @@ swiotlb_init_with_default_size (size_t default_size) * Get the overflow emergency buffer */ io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow); + iotlb_bus_start = virt_to_bus(iotlb_virt_start); - iotlb_bus_end = iotlb_bus_start + bytes; + iotlb_bus_mask = ~(dma_addr_t)(bytes - 1); + printk(KERN_INFO "Software IO TLB enabled: \n" " Aperture: %lu megabytes\n" " Bus range: 0x%016lx - 0x%016lx\n" " Kernel range: 0x%016lx - 0x%016lx\n", bytes >> 20, - (unsigned long)iotlb_bus_start, (unsigned long)iotlb_bus_end, - (unsigned long)iotlb_virt_start, (unsigned long)iotlb_virt_end); + (unsigned long)iotlb_bus_start, + (unsigned long)iotlb_bus_start + bytes, + (unsigned long)iotlb_virt_start, + (unsigned long)iotlb_virt_start + bytes); } void @@ -444,7 +447,7 @@ swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir) { BUG_ON(dir == DMA_NONE); - if ((dev_addr >= iotlb_bus_start) && (dev_addr < iotlb_bus_end)) + if (in_swiotlb_aperture(dev_addr)) unmap_single(hwdev, bus_to_virt(dev_addr), size, dir); } @@ -463,7 +466,7 @@ swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir) { BUG_ON(dir == DMA_NONE); - if ((dev_addr >= iotlb_bus_start) && (dev_addr < iotlb_bus_end)) + if (in_swiotlb_aperture(dev_addr)) sync_single(hwdev, bus_to_virt(dev_addr), size, dir); } @@ -472,7 +475,7 @@ swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir) { BUG_ON(dir == DMA_NONE); - if ((dev_addr >= iotlb_bus_start) && (dev_addr < iotlb_bus_end)) + if (in_swiotlb_aperture(dev_addr)) sync_single(hwdev, bus_to_virt(dev_addr), size, dir); } @@ -610,7 +613,7 @@ swiotlb_unmap_page(struct device *hwdev, dma_addr_t dma_address, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); - if ((dma_address >= iotlb_bus_start) && (dma_address < iotlb_bus_end)) + if (in_swiotlb_aperture(dma_address)) unmap_single(hwdev, bus_to_virt(dma_address), size, direction); } From 4fa9c861ef36fed24f9ef6ea05e8e0b82c732560 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 19 Aug 2005 17:56:20 +0000 Subject: [PATCH 03/29] Fix x86/64 build by defining correct vcpu_pickle(). --- .../include/asm-xen/asm-x86_64/hypercall.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h index b382e66182..d382b16abb 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h @@ -507,14 +507,14 @@ HYPERVISOR_vcpu_pickle( int vcpu, vcpu_guest_context_t *ctxt) { int ret; - unsigned long ign1, ign2; + __asm__ __volatile__ ( TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2) - : "0" (__HYPERVISOR_sched_op), - "1" (SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)), - "2" (ctxt) - : __syscall_clobber ); + : "=a" (ret) + : "0" ((unsigned long)__HYPERVISOR_sched_op), + "D" ((unsigned long)SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)), + "S" ((unsigned long)ctxt) + : __syscall_clobber ); return ret; } From b25e5aa958e7b4ff032c05d32dfc3de90cb2c4e4 Mon Sep 17 00:00:00 2001 From: "sd386@font.cl.cam.ac.uk" Date: Fri, 19 Aug 2005 18:08:29 +0000 Subject: [PATCH 04/29] Fix broken 'xm sedf', fixed by Ross Mcilroy Signed-off by: Stephan.Diestelhorst@{cl.cam.ac.uk, inf.tu-dresden.de} --- tools/python/xen/xm/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index e195196a5e..d711ef9d69 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -434,7 +434,7 @@ def xm_sedf(args): arg_check(args, 6, "sedf") dom = args[0] - v = map(int, args[1:5]) + v = map(int, args[1:6]) from xen.xend.XendClient import server server.xend_domain_cpu_sedf_set(dom, *v) From 2bf204d13a9d2ab4611a5095bf6b7c74363c40b2 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Fri, 19 Aug 2005 20:02:01 +0000 Subject: [PATCH 05/29] Hopefully fix build with SLES9 compiler. Signed-off-by: ian@xensource.com --- xen/include/public/physdev.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/include/public/physdev.h b/xen/include/public/physdev.h index b61432c899..4a324ac470 100644 --- a/xen/include/public/physdev.h +++ b/xen/include/public/physdev.h @@ -27,8 +27,8 @@ typedef struct physdevop_set_iopl { typedef struct physdevop_set_iobitmap { /* IN */ - char *bitmap; - u32 nr_ports; + u8 *bitmap; + u32 nr_ports; } physdevop_set_iobitmap_t; typedef struct physdevop_apic { From a1b473eb0619b33601cf95260ddc581a7f1979be Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 20 Aug 2005 09:35:38 +0000 Subject: [PATCH 06/29] Mini-os updated to use the new time interface. Signed-off-by: Grzegorz Milos --- extras/mini-os/include/time.h | 10 +- extras/mini-os/kernel.c | 14 -- extras/mini-os/time.c | 232 ++++++++++++++++++---------------- 3 files changed, 132 insertions(+), 124 deletions(-) diff --git a/extras/mini-os/include/time.h b/extras/mini-os/include/time.h index 40b4c212fa..067b8b36a1 100644 --- a/extras/mini-os/include/time.h +++ b/extras/mini-os/include/time.h @@ -28,7 +28,7 @@ * of real time into system time */ typedef s64 s_time_t; -#define NOW() ((s_time_t)get_s_time()) +#define NOW() ((s_time_t)monotonic_clock()) #define SECONDS(_s) (((s_time_t)(_s)) * 1000000000UL ) #define TENTHS(_ts) (((s_time_t)(_ts)) * 100000000UL ) #define HUNDREDTHS(_hs) (((s_time_t)(_hs)) * 10000000UL ) @@ -36,7 +36,8 @@ typedef s64 s_time_t; #define MICROSECS(_us) (((s_time_t)(_us)) * 1000UL ) #define Time_Max ((s_time_t) 0x7fffffffffffffffLL) #define FOREVER Time_Max - +#define NSEC_TO_USEC(_nsec) (_nsec / 1000UL) +#define NSEC_TO_SEC(_nsec) (_nsec / 1000000000ULL) /* wall clock time */ typedef long time_t; @@ -46,6 +47,11 @@ struct timeval { suseconds_t tv_usec; /* microseconds */ }; +struct timespec { + time_t ts_sec; + long ts_nsec; +}; + /* prototypes */ void init_time(void); diff --git a/extras/mini-os/kernel.c b/extras/mini-os/kernel.c index 85b55f1ab0..b275dd371f 100644 --- a/extras/mini-os/kernel.c +++ b/extras/mini-os/kernel.c @@ -132,20 +132,6 @@ void start_kernel(start_info_t *si) i = 0; for ( ; ; ) { - if(i >= 1000) - { - { - unsigned long saved; - __asm__ ("movl %%esp, %0" - :"=r"(saved) /* y is output operand */ - /* x is input operand */); -// :"a"); /* %eax is clobbered register */ - printk("ESP=0x%lx\n", saved); - } - - printk("1000 bloks\n"); - i=0; - } // HYPERVISOR_yield(); block(1); i++; diff --git a/extras/mini-os/time.c b/extras/mini-os/time.c index ca48a6ae1d..c03c86df35 100644 --- a/extras/mini-os/time.c +++ b/extras/mini-os/time.c @@ -43,19 +43,20 @@ * Time functions *************************************************************************/ -/* Cached *multiplier* to convert TSC counts to microseconds. - * (see the equation below). - * Equal to 2^32 * (1 / (clocks per usec) ). - * Initialized in time_init. - */ -static unsigned long fast_gettimeoffset_quotient; - - /* These are peridically updated in shared_info, and then copied here. */ -static u32 shadow_tsc_stamp; -static s64 shadow_system_time; -static u32 shadow_time_version; -static struct timeval shadow_tv; +struct shadow_time_info { + u64 tsc_timestamp; /* TSC at last update of time vals. */ + u64 system_timestamp; /* Time, in nanosecs, since boot. */ + u32 tsc_to_nsec_mul; + u32 tsc_to_usec_mul; + int tsc_shift; + u32 version; +}; +static struct timespec shadow_ts; +static u32 shadow_ts_version; + +static struct shadow_time_info shadow; + #ifndef rmb #define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") @@ -63,116 +64,150 @@ static struct timeval shadow_tv; #define HANDLE_USEC_OVERFLOW(_tv) \ do { \ - while ( (_tv).tv_usec >= 1000000 ) \ + while ( (_tv)->tv_usec >= 1000000 ) \ { \ - (_tv).tv_usec -= 1000000; \ - (_tv).tv_sec++; \ + (_tv)->tv_usec -= 1000000; \ + (_tv)->tv_sec++; \ } \ } while ( 0 ) +static inline int time_values_up_to_date(void) +{ + struct vcpu_time_info *src = &HYPERVISOR_shared_info->vcpu_time[0]; + + return (shadow.version == src->version); +} + + +/* + * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, + * yielding a 64-bit result. + */ +static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift) +{ + u64 product; +#ifdef __i386__ + u32 tmp1, tmp2; +#endif + + if ( shift < 0 ) + delta >>= -shift; + else + delta <<= shift; + +#ifdef __i386__ + __asm__ ( + "mul %5 ; " + "mov %4,%%eax ; " + "mov %%edx,%4 ; " + "mul %5 ; " + "add %4,%%eax ; " + "xor %5,%5 ; " + "adc %5,%%edx ; " + : "=A" (product), "=r" (tmp1), "=r" (tmp2) + : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); +#else + __asm__ ( + "mul %%rdx ; shrd $32,%%rdx,%%rax" + : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) ); +#endif + + return product; +} + + +static unsigned long get_nsec_offset(void) +{ + u64 now, delta; + rdtscll(now); + delta = now - shadow.tsc_timestamp; + return scale_delta(delta, shadow.tsc_to_nsec_mul, shadow.tsc_shift); +} + + static void get_time_values_from_xen(void) { - do { - shadow_time_version = HYPERVISOR_shared_info->time_version2; - rmb(); - shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec; - shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec; - shadow_tsc_stamp = (u32)HYPERVISOR_shared_info->tsc_timestamp; - shadow_system_time = HYPERVISOR_shared_info->system_time; - rmb(); - } - while ( shadow_time_version != HYPERVISOR_shared_info->time_version1 ); + struct vcpu_time_info *src = &HYPERVISOR_shared_info->vcpu_time[0]; + + do { + shadow.version = src->version; + rmb(); + shadow.tsc_timestamp = src->tsc_timestamp; + shadow.system_timestamp = src->system_time; + shadow.tsc_to_nsec_mul = src->tsc_to_system_mul; + shadow.tsc_shift = src->tsc_shift; + rmb(); + } + while ((src->version & 1) | (shadow.version ^ src->version)); + + shadow.tsc_to_usec_mul = shadow.tsc_to_nsec_mul / 1000; } -#define TIME_VALUES_UP_TO_DATE \ - (shadow_time_version == HYPERVISOR_shared_info->time_version2) -static u32 get_time_delta_usecs(void) + +/* monotonic_clock(): returns # of nanoseconds passed since time_init() + * Note: This function is required to return accurate + * time even in the absence of multiple timer ticks. + */ +u64 monotonic_clock(void) { - register unsigned long eax, edx; + u64 time; + u32 local_time_version; - /* Read the Time Stamp Counter */ + do { + local_time_version = shadow.version; + rmb(); + time = shadow.system_timestamp + get_nsec_offset(); + if (!time_values_up_to_date()) + get_time_values_from_xen(); + rmb(); + } while (local_time_version != shadow.version); - rdtsc(eax,edx); - - /* .. relative to previous jiffy (32 bits is enough) */ - eax -= shadow_tsc_stamp; - - /* - * Time offset = (tsc_low delta) * fast_gettimeoffset_quotient - * = (tsc_low delta) * (usecs_per_clock) - * = (tsc_low delta) * (usecs_per_jiffy / clocks_per_jiffy) - * - * Using a mull instead of a divl saves up to 31 clock cycles - * in the critical path. - */ - - __asm__("mull %2" - :"=a" (eax), "=d" (edx) - :"rm" (fast_gettimeoffset_quotient), - "0" (eax)); - - /* our adjusted time offset in microseconds */ - return edx; + return time; } -s64 get_s_time (void) +static void update_wallclock(void) { - u64 u_delta; - s64 ret; + shared_info_t *s = HYPERVISOR_shared_info; - again: - - u_delta = get_time_delta_usecs(); - ret = shadow_system_time + (1000 * u_delta); - - if ( unlikely(!TIME_VALUES_UP_TO_DATE) ) - { - /* - * We may have blocked for a long time, rendering our calculations - * invalid (e.g. the time delta may have overflowed). Detect that - * and recalculate with fresh values. - */ - get_time_values_from_xen(); - goto again; - } - - return ret; + do { + shadow_ts_version = s->wc_version; + rmb(); + shadow_ts.ts_sec = s->wc_sec; + shadow_ts.ts_nsec = s->wc_nsec; + rmb(); + } + while ((s->wc_version & 1) | (shadow_ts_version ^ s->wc_version)); } + void gettimeofday(struct timeval *tv) { - struct timeval _tv; - - do { - get_time_values_from_xen(); - _tv.tv_usec = get_time_delta_usecs(); - _tv.tv_sec = shadow_tv.tv_sec; - _tv.tv_usec += shadow_tv.tv_usec; - } - while ( unlikely(!TIME_VALUES_UP_TO_DATE) ); - - HANDLE_USEC_OVERFLOW(_tv); - *tv = _tv; + u64 nsec = monotonic_clock(); + nsec += shadow_ts.ts_nsec; + + + tv->tv_sec = shadow_ts.ts_sec; + tv->tv_sec += NSEC_TO_SEC(nsec); + tv->tv_usec = NSEC_TO_USEC(nsec % 1000000000UL); } + static void print_current_time(void) { - struct timeval tv; - - get_time_values_from_xen(); + struct timeval tv; gettimeofday(&tv); printk("T(s=%ld us=%ld)\n", tv.tv_sec, tv.tv_usec); } + void block(u32 millisecs) { struct timeval tv; gettimeofday(&tv); - //printk("tv.tv_sec=%ld, tv.tv_usec=%ld, shadow_system_time=%lld\n", tv.tv_sec, tv.tv_usec, shadow_system_time ); - HYPERVISOR_set_timer_op(get_s_time() + 1000000LL * (s64) millisecs); + HYPERVISOR_set_timer_op(monotonic_clock() + 1000000LL * (s64) millisecs); HYPERVISOR_block(); } @@ -185,7 +220,7 @@ static void timer_handler(int ev, struct pt_regs *regs) static int i; get_time_values_from_xen(); - + update_wallclock(); i++; if (i >= 1000) { print_current_time(); @@ -197,24 +232,5 @@ static void timer_handler(int ev, struct pt_regs *regs) void init_time(void) { - u64 __cpu_khz; - unsigned long cpu_khz; - - __cpu_khz = HYPERVISOR_shared_info->cpu_freq; - - cpu_khz = (u32) (__cpu_khz/1000); - - printk("Xen reported: %lu.%03lu MHz processor.\n", - cpu_khz / 1000, cpu_khz % 1000); - /* (10^6 * 2^32) / cpu_hz = (10^3 * 2^32) / cpu_khz = - (2^32 * 1 / (clocks/us)) */ - { - unsigned long eax=0, edx=1000; - __asm__("divl %2" - :"=a" (fast_gettimeoffset_quotient), "=d" (edx) - :"r" (cpu_khz), - "0" (eax), "1" (edx)); - } - bind_virq(VIRQ_TIMER, &timer_handler); } From bd56a310711c3800e1dba9046bd29b7dc8bebe91 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 20 Aug 2005 09:36:15 +0000 Subject: [PATCH 07/29] We need to detect ioemu handled devices earlier and ignore them. Testing in blkif.py is too late. The check should be in createDevices. Signed-off-by: Arun Sharma --- tools/python/xen/xend/XendDomainInfo.py | 6 ++++-- tools/python/xen/xend/server/blkif.py | 11 +---------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 0dcfb5e462..74b8b6cc1d 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -23,7 +23,7 @@ Author: Mike Wray """ -import string +import string, re import os import time import threading @@ -383,7 +383,9 @@ class XendDomainInfo: def createDevice(self, type, devconfig, change=False): if type == 'vbd': - + typedev = sxp.child_value(devconfig, 'dev') + if re.match('^ioemu:', typedev): + return; backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0')) devnum = blkdev_name_to_number(sxp.child_value(devconfig, 'dev')) diff --git a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py index 49d1fc5f9e..5bd89e8353 100755 --- a/tools/python/xen/xend/server/blkif.py +++ b/tools/python/xen/xend/server/blkif.py @@ -18,7 +18,6 @@ """Support for virtual block devices. """ import string -import re from xen.util import blkif from xen.xend.XendError import XendError, VmError @@ -200,7 +199,6 @@ class BlkDev(Dev): self.vdev = None self.mode = None self.type = None - self.emtype = None self.params = None self.node = None self.device = None @@ -239,12 +237,7 @@ class BlkDev(Dev): # Split into type and type-specific params (which are passed to the # type-specific control script). (self.type, self.params) = string.split(self.uname, ':', 1) - typedev = sxp.child_value(config, 'dev') - if re.match( '^ioemu:', typedev): - (self.emtype, self.dev) = string.split(typedev, ':', 1) - else: - self.emtype = 'vbd' - self.dev = typedev + self.dev = sxp.child_value(config, 'dev') if not self.dev: raise VmError('vbd: Missing dev') self.mode = sxp.child_value(config, 'mode', 'r') @@ -265,8 +258,6 @@ class BlkDev(Dev): if recreate: pass else: - if self.emtype == 'ioemu': - return node = Blkctl.block('bind', self.type, self.params) self.setNode(node) self.attachBackend() From 7cd753585f1b58f476daa5e2d8d40581c4c88587 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 20 Aug 2005 09:38:32 +0000 Subject: [PATCH 08/29] I find at present "make uninstall" won't remove all installed files, for example: /usr/libexec/xen/xc_restore. This may cause potential unclean environment. This patch add more lines in uninstall to remove all installed files by "make uninstall". Signed-off-by: Yongkang You --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index 4a9c283319..804db56f32 100644 --- a/Makefile +++ b/Makefile @@ -172,6 +172,12 @@ uninstall: rm -rf $(D)/usr/bin/xen* $(D)/usr/bin/miniterm rm -rf $(D)/boot/*xen* rm -rf $(D)/lib/modules/*xen* + rm -rf $(D)/usr/bin/cpuperf-perfcntr $(D)/usr/bin/cpuperf-xen + rm -rf $(D)/usr/bin/xc_shadow + rm -rf $(D)/usr/share/xen $(D)/usr/libexec/xen + rm -rf $(D)/usr/share/man/man1/xen* + rm -rf $(D)/usr/share/man/man8/xen* + rm -rf $(D)/usr/lib/xen # Legacy targets for compatibility linux24: From e5ca22d4abe420523406b576a4f249614faea6f9 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 20 Aug 2005 10:01:20 +0000 Subject: [PATCH 09/29] Fix PAE boot. Signed-off-by: Keir Fraser --- Config.mk | 2 +- linux-2.6-xen-sparse/arch/xen/i386/mm/init.c | 18 ------------------ 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/Config.mk b/Config.mk index 76180e6b26..2f2183e20e 100644 --- a/Config.mk +++ b/Config.mk @@ -3,7 +3,7 @@ # Currently supported architectures: x86_32, x86_64 XEN_COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) XEN_TARGET_ARCH ?= $(XEN_COMPILE_ARCH) -XEN_TARGET_X86_PAE ?= n +XEN_TARGET_X86_PAE ?= y # Tools to run on system hosting the build HOSTCC = gcc diff --git a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c index 5016b86a86..78d5058f92 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c @@ -352,13 +352,6 @@ static void __init pagetable_init (void) swapper_pg_dir = pgd_base; init_mm.pgd = pgd_base; -#ifdef CONFIG_X86_PAE - int i; - /* Init entries of the first-level page table to the zero page */ - for (i = 0; i < PTRS_PER_PGD; i++) - set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT)); -#endif - /* Enable PSE if available */ if (cpu_has_pse) { set_in_cr4(X86_CR4_PSE); @@ -383,17 +376,6 @@ static void __init pagetable_init (void) page_table_range_init(vaddr, 0, pgd_base); permanent_kmaps_init(pgd_base); - -#if 0 /* def CONFIG_X86_PAE */ - /* - * Add low memory identity-mappings - SMP needs it when - * starting up on an AP from real-mode. In the non-PAE - * case we already have these mappings through head.S. - * All user-space mappings are explicitly cleared after - * SMP startup. - */ - set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]); -#endif } #if defined(CONFIG_PM_DISK) || defined(CONFIG_SOFTWARE_SUSPEND) From 4f61ba1e84f3f2f37c642b8316cd22b8fb9449d3 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 20 Aug 2005 10:03:40 +0000 Subject: [PATCH 10/29] Not ready for pae by default just yet. ;-) --- Config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config.mk b/Config.mk index 2f2183e20e..76180e6b26 100644 --- a/Config.mk +++ b/Config.mk @@ -3,7 +3,7 @@ # Currently supported architectures: x86_32, x86_64 XEN_COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) XEN_TARGET_ARCH ?= $(XEN_COMPILE_ARCH) -XEN_TARGET_X86_PAE ?= y +XEN_TARGET_X86_PAE ?= n # Tools to run on system hosting the build HOSTCC = gcc From 7cca45f4478e8287adf927fe6e007b40997e4e27 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 20 Aug 2005 11:14:28 +0000 Subject: [PATCH 11/29] Fix put_pte_flags() for Xen PAE. Signed-off-by: Keir Fraser --- xen/include/asm-x86/page.h | 4 ---- xen/include/asm-x86/x86_32/page-3level.h | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h index 71edad1530..c242722888 100644 --- a/xen/include/asm-x86/page.h +++ b/xen/include/asm-x86/page.h @@ -6,11 +6,7 @@ * It is important that the masks are signed quantities. This ensures that * the compiler sign-extends a 32-bit mask to 64 bits if that is required. */ -#ifndef __ASSEMBLY__ -#define PAGE_SIZE (1L << PAGE_SHIFT) -#else #define PAGE_SIZE (1 << PAGE_SHIFT) -#endif #define PAGE_MASK (~(PAGE_SIZE-1)) #define PAGE_FLAG_MASK (~0) diff --git a/xen/include/asm-x86/x86_32/page-3level.h b/xen/include/asm-x86/x86_32/page-3level.h index 79b14169e9..46234c43d9 100644 --- a/xen/include/asm-x86/x86_32/page-3level.h +++ b/xen/include/asm-x86/x86_32/page-3level.h @@ -63,7 +63,7 @@ typedef l3_pgentry_t root_pgentry_t; /* Extract flags into 32-bit integer, or turn 32-bit flags into a pte mask. */ #define get_pte_flags(x) (((int)((x) >> 32) & ~0xFFF) | ((int)(x) & 0xFFF)) -#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 40) | ((x) & 0xFFF)) +#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 32) | ((x) & 0xFFF)) #define L1_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PAT/GLOBAL */ #define L2_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PSE/GLOBAL */ From afb777e9394505e299d6bdedf5906eddf647f1c1 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 20 Aug 2005 11:51:50 +0000 Subject: [PATCH 12/29] Defining PAGE_SIZE as int broke x86/64. Revert that change. --- xen/include/asm-x86/page.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h index c242722888..71edad1530 100644 --- a/xen/include/asm-x86/page.h +++ b/xen/include/asm-x86/page.h @@ -6,7 +6,11 @@ * It is important that the masks are signed quantities. This ensures that * the compiler sign-extends a 32-bit mask to 64 bits if that is required. */ +#ifndef __ASSEMBLY__ +#define PAGE_SIZE (1L << PAGE_SHIFT) +#else #define PAGE_SIZE (1 << PAGE_SHIFT) +#endif #define PAGE_MASK (~(PAGE_SIZE-1)) #define PAGE_FLAG_MASK (~0) From 1d595a775e04a59b462f82bf033c63ab8655ad01 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 20 Aug 2005 20:05:21 +0000 Subject: [PATCH 13/29] Fix NORMAL_PT_UPDATE for PAE when page is not pinned. Signed-off-by: Keir Fraser --- xen/arch/x86/mm.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 62c0a06d5f..070c195a1c 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -2176,7 +2176,7 @@ int do_mmu_update( } } - *(unsigned long *)va = req.val; + *(intpte_t *)va = req.val; okay = 1; if ( shadow_mode_enabled(d) ) @@ -2386,7 +2386,7 @@ int clear_grant_pte_mapping( } /* Delete pagetable entry. */ - if ( unlikely(__put_user(0, (unsigned long *)va))) + if ( unlikely(__put_user(0, (intpte_t *)va))) { DPRINTK("Cannot delete PTE entry at %p.\n", va); put_page_type(page); @@ -2446,12 +2446,11 @@ int update_grant_va_mapping( int clear_grant_va_mapping(unsigned long addr, unsigned long frame) { - l1_pgentry_t *pl1e; - unsigned long _ol1e; + l1_pgentry_t *pl1e, ol1e; pl1e = &linear_pg_table[l1_linear_offset(addr)]; - if ( unlikely(__get_user(_ol1e, (unsigned long *)pl1e) != 0) ) + if ( unlikely(__get_user(ol1e.l1, &pl1e->l1) != 0) ) { DPRINTK("Could not find PTE entry for address %lx\n", addr); return GNTST_general_error; @@ -2461,15 +2460,15 @@ int clear_grant_va_mapping(unsigned long addr, unsigned long frame) * Check that the virtual address supplied is actually mapped to * frame. */ - if ( unlikely((_ol1e >> PAGE_SHIFT) != frame )) + if ( unlikely(l1e_get_pfn(ol1e) != frame) ) { DPRINTK("PTE entry %lx for address %lx doesn't match frame %lx\n", - _ol1e, addr, frame); + l1e_get_pfn(ol1e), addr, frame); return GNTST_general_error; } /* Delete pagetable entry. */ - if ( unlikely(__put_user(0, (unsigned long *)pl1e))) + if ( unlikely(__put_user(0, &pl1e->l1)) ) { DPRINTK("Cannot delete PTE entry at %p.\n", (unsigned long *)pl1e); return GNTST_general_error; From 5a3294e5348b76e8a657e7c03e05111d2aab58d8 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Sun, 21 Aug 2005 00:10:30 +0000 Subject: [PATCH 14/29] PAE fix to allow dom0 to be >4GB. PAE has made huge progress this week. I now kn ow of no PAE specific outstanding issues. Go find some :-) Signed-off-by: ian@xensource.com --- xen/arch/x86/domain_build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index bde7d8ef31..939aaf9992 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -72,7 +72,7 @@ boolean_param("dom0_translate", opt_dom0_translate); static struct pfn_info *alloc_largest(struct domain *d, unsigned long max) { struct pfn_info *page; - unsigned int order = get_order(max * PAGE_SIZE); + unsigned int order = get_order(max)+PAGE_SHIFT-1; if ( (max & (max-1)) != 0 ) order--; while ( (page = alloc_domheap_pages(d, order, 0)) == NULL ) From b3fc0bbf71d4c4df546c3a65bb97fae000511b9c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 21 Aug 2005 08:14:36 +0000 Subject: [PATCH 15/29] Fix dom0 memory allocation. Signed-off-by: Keir Fraser --- xen/arch/x86/domain_build.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 939aaf9992..1b77371141 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -69,11 +69,21 @@ boolean_param("dom0_translate", opt_dom0_translate); #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) #define round_pgdown(_p) ((_p)&PAGE_MASK) -static struct pfn_info *alloc_largest(struct domain *d, unsigned long max) +static struct pfn_info *alloc_chunk(struct domain *d, unsigned long max_pages) { struct pfn_info *page; - unsigned int order = get_order(max)+PAGE_SHIFT-1; - if ( (max & (max-1)) != 0 ) + unsigned int order; + /* + * Allocate up to 2MB at a time: + * 1. This prevents overflow of get_order() when allocating more than + * 4GB to domain 0 on a PAE machine. + * 2. It prevents allocating very large chunks from DMA pools before + * the >4GB pool is fully depleted. + */ + if ( max_pages > (2UL << (20 - PAGE_SHIFT)) ) + max_pages = 2UL << (20 - PAGE_SHIFT); + order = get_order(max_pages << PAGE_SHIFT); + if ( (max_pages & (max_pages-1)) != 0 ) order--; while ( (page = alloc_domheap_pages(d, order, 0)) == NULL ) if ( order-- == 0 ) @@ -608,7 +618,7 @@ int construct_dom0(struct domain *d, } while ( pfn < nr_pages ) { - if ( (page = alloc_largest(d, nr_pages - d->tot_pages)) == NULL ) + if ( (page = alloc_chunk(d, nr_pages - d->tot_pages)) == NULL ) panic("Not enough RAM for DOM0 reservation.\n"); while ( pfn < d->tot_pages ) { From dbf6d3dd6e3c4f6e383f06c4ed69d6fd95a14921 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Sun, 21 Aug 2005 11:02:00 +0000 Subject: [PATCH 16/29] merge? From 3ce6c98f6229c9d2b03a26c24c0b87ed96c7f91c Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Sun, 21 Aug 2005 11:40:39 +0000 Subject: [PATCH 17/29] Fix fallout from "Get rid of memory_t." checkin. {get,put}_user of u64 items has to use u64 variables. Signed-off-by: Christian Limpach --- xen/common/grant_table.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index b3bbc7e0db..15c824d3c4 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -75,8 +75,8 @@ __gnttab_activate_grant_ref( struct domain *granting_d, grant_ref_t ref, u16 dev_hst_ro_flags, - unsigned long addr, - unsigned long *pframe ) /* OUT */ + u64 addr, + u64 *pframe ) /* OUT */ { domid_t sdom; u16 sflags; @@ -342,7 +342,7 @@ __gnttab_map_grant_ref( struct vcpu *led; u16 dev_hst_ro_flags; int handle; - unsigned long frame = 0, addr; + u64 frame = 0, addr; int rc; led = current; @@ -363,7 +363,7 @@ __gnttab_map_grant_ref( (!(dev_hst_ro_flags & GNTMAP_contains_pte) && unlikely(!__addr_ok(addr))) ) ) { - DPRINTK("Bad virtual address (%lx) or flags (%x).\n", + DPRINTK("Bad virtual address (%llx) or flags (%x).\n", addr, dev_hst_ro_flags); (void)__put_user(GNTST_bad_virt_addr, &uop->handle); return GNTST_bad_gntref; @@ -502,7 +502,7 @@ __gnttab_unmap_grant_ref( grant_mapping_t *map; u16 flags; s16 rc = 1; - unsigned long frame, addr; + u64 frame, addr; ld = current->domain; From e5c0d3be0d16ec4ccbb45d53db72aaed30b53abd Mon Sep 17 00:00:00 2001 From: "akw27@arcadians.cl.cam.ac.uk" Date: Sun, 21 Aug 2005 12:24:21 +0000 Subject: [PATCH 18/29] Remove dead code from blkback. Signed-off-by: Andrew Warfield --- .../drivers/xen/blkback/common.h | 2 +- .../drivers/xen/blkback/interface.c | 47 ------------------- 2 files changed, 1 insertion(+), 48 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h index ffb44a78d6..dd56fdeb25 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h @@ -53,7 +53,7 @@ typedef struct blkif_st { rb_root_t vbd_rb; /* Mapping from 16-bit vdevices to VBDs.*/ spinlock_t vbd_lock; /* Protects VBD mapping. */ /* Private fields. */ - enum { DISCONNECTED, DISCONNECTING, CONNECTED } status; + enum { DISCONNECTED, CONNECTED } status; /* * DISCONNECT response is deferred until pending requests are ack'ed. * We therefore need to store the id from the original request. 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 a29fe2d6ee..259b65c39c 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c @@ -7,7 +7,6 @@ */ #include "common.h" -#include #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) @@ -138,52 +137,6 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) return 0; } -static void __blkif_disconnect_complete(void *arg) -{ - blkif_t *blkif = (blkif_t *)arg; - ctrl_msg_t cmsg; - blkif_be_disconnect_t disc; - - /* - * These can't be done in blkif_disconnect() because at that point there - * may be outstanding requests at the disc whose asynchronous responses - * must still be notified to the remote driver. - */ - unmap_frontend_page(blkif); - vfree(blkif->blk_ring.sring); - - /* Construct the deferred response message. */ - cmsg.type = CMSG_BLKIF_BE; - cmsg.subtype = CMSG_BLKIF_BE_DISCONNECT; - cmsg.id = blkif->disconnect_rspid; - cmsg.length = sizeof(blkif_be_disconnect_t); - disc.domid = blkif->domid; - disc.blkif_handle = blkif->handle; - disc.status = BLKIF_BE_STATUS_OKAY; - memcpy(cmsg.msg, &disc, sizeof(disc)); - - /* - * Make sure message is constructed /before/ status change, because - * after the status change the 'blkif' structure could be deallocated at - * any time. Also make sure we send the response /after/ status change, - * as otherwise a subsequent CONNECT request could spuriously fail if - * another CPU doesn't see the status change yet. - */ - mb(); - BUG_ON(blkif->status != DISCONNECTING); - blkif->status = DISCONNECTED; - mb(); - - /* Send the successful response. */ - ctrl_if_send_response(&cmsg); -} - -void blkif_disconnect_complete(blkif_t *blkif) -{ - INIT_WORK(&blkif->work, __blkif_disconnect_complete, (void *)blkif); - schedule_work(&blkif->work); -} - void free_blkif(blkif_t *blkif) { blkif_t **pblkif; From 23998ec9899300f94c2b44dc2025a384f6ccbc60 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 21 Aug 2005 16:24:23 +0000 Subject: [PATCH 19/29] Fix debug build. --- xen/common/grant_table.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 15c824d3c4..09edee02c5 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -70,13 +70,13 @@ put_maptrack_handle( static int __gnttab_activate_grant_ref( - struct domain *mapping_d, /* IN */ + struct domain *mapping_d, /* IN */ struct vcpu *mapping_ed, - struct domain *granting_d, - grant_ref_t ref, - u16 dev_hst_ro_flags, - u64 addr, - u64 *pframe ) /* OUT */ + struct domain *granting_d, + grant_ref_t ref, + u16 dev_hst_ro_flags, + u64 addr, + u64 *pframe ) /* OUT */ { domid_t sdom; u16 sflags; @@ -342,7 +342,7 @@ __gnttab_map_grant_ref( struct vcpu *led; u16 dev_hst_ro_flags; int handle; - u64 frame = 0, addr; + u64 frame = 0, addr; int rc; led = current; @@ -363,7 +363,7 @@ __gnttab_map_grant_ref( (!(dev_hst_ro_flags & GNTMAP_contains_pte) && unlikely(!__addr_ok(addr))) ) ) { - DPRINTK("Bad virtual address (%llx) or flags (%x).\n", + DPRINTK("Bad virtual address (%"PRIx64") or flags (%"PRIx16").\n", addr, dev_hst_ro_flags); (void)__put_user(GNTST_bad_virt_addr, &uop->handle); return GNTST_bad_gntref; @@ -496,13 +496,12 @@ __gnttab_unmap_grant_ref( grant_ref_t ref; u16 handle; struct domain *ld, *rd; - active_grant_entry_t *act; grant_entry_t *sha; grant_mapping_t *map; u16 flags; s16 rc = 1; - u64 frame, addr; + u64 frame, addr; ld = current->domain; From 86c29e15439c044b828e87c816c9d13b348546ad Mon Sep 17 00:00:00 2001 From: "vh249@arcadians.cl.cam.ac.uk" Date: Sun, 21 Aug 2005 16:49:54 +0000 Subject: [PATCH 20/29] fix logic of ballooning out to handle the dom0_min_mem parameter correctly add an error message when having not enough memory Signed-off-by: Vincent Hanquez --- tools/python/xen/xm/create.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 3770609df6..ec4ab49c12 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -688,7 +688,9 @@ def balloon_out(dom0_min_mem, opts): dom0_cur_alloc = get_dom0_alloc() dom0_new_alloc = dom0_cur_alloc - (domU_need_mem - free_mem) - if free_mem < domU_need_mem and dom0_new_alloc >= dom0_min_mem: + if free_mem < domU_need_mem and dom0_new_alloc < dom0_min_mem: + ret = 1 + if free_mem < domU_need_mem and ret == 0: server.xend_domain_mem_target_set(0, dom0_new_alloc) @@ -734,7 +736,8 @@ def main(argv): dom0_min_mem = xroot.get_dom0_min_mem() if dom0_min_mem != 0: if balloon_out(dom0_min_mem, opts): - return + print >>sys.stderr, "error: cannot allocate enough memory for domain" + sys.exit(1) dom = make_domain(opts, config) if opts.vals.console_autoconnect: From 0ab9c07764ee37185d8e805bc3c7b6de65f6534f Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 21 Aug 2005 17:06:08 +0000 Subject: [PATCH 21/29] Make grant-table dev_bus_addr really be an address, not a frame number. Also get rid of GNTUNMAP_DEV_FROM_VIRT -- it makes little sense and noone uses it. Signed-off-by: Keir Fraser --- .../drivers/xen/blkback/blkback.c | 5 +- .../drivers/xen/blktap/blktap_userdev.c | 5 +- .../drivers/xen/netback/netback.c | 2 +- xen/arch/ia64/grant_table.c | 18 ------ xen/common/grant_table.c | 60 +++++++------------ xen/include/public/dom0_ops.h | 2 +- xen/include/public/grant_table.h | 2 - 7 files changed, 29 insertions(+), 65 deletions(-) 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 9e918fe6de..97c7865abe 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c @@ -431,7 +431,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) } phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] = - FOREIGN_FRAME(map[i].dev_bus_addr); + FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT); pending_handle(pending_idx, i) = map[i].handle; } @@ -441,8 +441,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) { fas = req->frame_and_sects[i]; #ifdef CONFIG_XEN_BLKDEV_GRANT - seg[i].buf = (map[i].dev_bus_addr << PAGE_SHIFT) | - (blkif_first_sect(fas) << 9); + seg[i].buf = map[i].dev_bus_addr | (blkif_first_sect(fas) << 9); #else seg[i].buf = (fas & PAGE_MASK) | (blkif_first_sect(fas) << 9); seg[i].nsec = blkif_last_sect(fas) - blkif_first_sect(fas) + 1; diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c index 3dce2cfdf2..3b9089228d 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c @@ -5,7 +5,6 @@ * Control interface between the driver and a character device. * * Copyright (c) 2004, Andrew Warfield - * */ #include @@ -535,8 +534,8 @@ int blktap_write_fe_ring(blkif_request_t *req) /* Set the necessary mappings in p2m and in the VM_FOREIGN * vm_area_struct to allow user vaddr -> struct page lookups * to work. This is needed for direct IO to foreign pages. */ - phys_to_machine_mapping[__pa(kvaddr)>>PAGE_SHIFT] = - FOREIGN_FRAME(map[i].dev_bus_addr); + phys_to_machine_mapping[__pa(kvaddr) >> PAGE_SHIFT] = + FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT); offset = (uvaddr - blktap_vma->vm_start) >> PAGE_SHIFT; ((struct page **)blktap_vma->vm_private_data)[offset] = 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 a0b61167aa..fdd174c8cb 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c @@ -768,7 +768,7 @@ static void net_tx_action(unsigned long unused) continue; } phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] = - FOREIGN_FRAME(mop->dev_bus_addr); + FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT); grant_tx_ref[pending_idx] = mop->handle; #else if ( unlikely(mcl[0].result != 0) ) diff --git a/xen/arch/ia64/grant_table.c b/xen/arch/ia64/grant_table.c index 7e25dda2f4..43d2a7ccb5 100644 --- a/xen/arch/ia64/grant_table.c +++ b/xen/arch/ia64/grant_table.c @@ -546,15 +546,6 @@ __gnttab_unmap_grant_ref( { frame = act->frame; } - else if ( frame == GNTUNMAP_DEV_FROM_VIRT ) - { - if ( !( flags & GNTMAP_device_map ) ) - PIN_FAIL(unmap_out, GNTST_bad_dev_addr, - "Bad frame number: frame not mapped for dev access.\n"); - frame = act->frame; - - /* Frame will be unmapped for device access below if virt addr okay. */ - } else { if ( unlikely(frame != act->frame) ) @@ -616,15 +607,6 @@ __gnttab_unmap_grant_ref( act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_hstr_inc : GNTPIN_hstw_inc; - if ( frame == GNTUNMAP_DEV_FROM_VIRT ) - { - act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_devr_inc - : GNTPIN_devw_inc; - - map->ref_and_flags &= ~GNTMAP_device_map; - (void)__put_user(0, &uop->dev_bus_addr); - } - rc = 0; *va = virt; } diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 09edee02c5..7ff75aab4d 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -76,7 +76,7 @@ __gnttab_activate_grant_ref( grant_ref_t ref, u16 dev_hst_ro_flags, u64 addr, - u64 *pframe ) /* OUT */ + unsigned long *pframe ) /* OUT */ { domid_t sdom; u16 sflags; @@ -336,14 +336,15 @@ __gnttab_map_grant_ref( gnttab_map_grant_ref_t *uop, unsigned long *va) { - domid_t dom; - grant_ref_t ref; - struct domain *ld, *rd; - struct vcpu *led; - u16 dev_hst_ro_flags; - int handle; - u64 frame = 0, addr; - int rc; + domid_t dom; + grant_ref_t ref; + struct domain *ld, *rd; + struct vcpu *led; + u16 dev_hst_ro_flags; + int handle; + u64 addr; + unsigned long frame = 0; + int rc; led = current; ld = led->domain; @@ -450,7 +451,7 @@ __gnttab_map_grant_ref( = (ref << MAPTRACK_REF_SHIFT) | (dev_hst_ro_flags & MAPTRACK_GNTMAP_MASK); - (void)__put_user(frame, &uop->dev_bus_addr); + (void)__put_user((u64)frame << PAGE_SHIFT, &uop->dev_bus_addr); if ( ( dev_hst_ro_flags & GNTMAP_host_map ) && !( dev_hst_ro_flags & GNTMAP_contains_pte) ) @@ -492,28 +493,31 @@ __gnttab_unmap_grant_ref( gnttab_unmap_grant_ref_t *uop, unsigned long *va) { - domid_t dom; - grant_ref_t ref; - u16 handle; - struct domain *ld, *rd; + domid_t dom; + grant_ref_t ref; + u16 handle; + struct domain *ld, *rd; active_grant_entry_t *act; - grant_entry_t *sha; + grant_entry_t *sha; grant_mapping_t *map; - u16 flags; - s16 rc = 1; - u64 frame, addr; + u16 flags; + s16 rc = 1; + u64 addr, dev_bus_addr; + unsigned long frame; ld = current->domain; /* Bitwise-OR avoids short-circuiting which screws control flow. */ if ( unlikely(__get_user(addr, &uop->host_addr) | - __get_user(frame, &uop->dev_bus_addr) | + __get_user(dev_bus_addr, &uop->dev_bus_addr) | __get_user(handle, &uop->handle)) ) { DPRINTK("Fault while reading gnttab_unmap_grant_ref_t.\n"); return -EFAULT; /* don't set status */ } + frame = (unsigned long)(dev_bus_addr >> PAGE_SHIFT); + map = &ld->grant_table->maptrack[handle]; if ( unlikely(handle >= ld->grant_table->maptrack_limit) || @@ -552,15 +556,6 @@ __gnttab_unmap_grant_ref( { frame = act->frame; } - else if ( frame == GNTUNMAP_DEV_FROM_VIRT ) - { - if ( !( flags & GNTMAP_device_map ) ) - PIN_FAIL(unmap_out, GNTST_bad_dev_addr, - "Bad frame number: frame not mapped for dev access.\n"); - frame = act->frame; - - /* Frame will be unmapped for device access below if virt addr okay. */ - } else { if ( unlikely(frame != act->frame) ) @@ -596,15 +591,6 @@ __gnttab_unmap_grant_ref( act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_hstr_inc : GNTPIN_hstw_inc; - if ( frame == GNTUNMAP_DEV_FROM_VIRT ) - { - act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_devr_inc - : GNTPIN_devw_inc; - - map->ref_and_flags &= ~GNTMAP_device_map; - (void)__put_user(0, &uop->dev_bus_addr); - } - rc = 0; if ( !( flags & GNTMAP_contains_pte) ) *va = addr; diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index b5b027726c..b8928b0f68 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -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 0xAAAA100F +#define DOM0_INTERFACE_VERSION 0xAAAA1010 /************************************************************************/ diff --git a/xen/include/public/grant_table.h b/xen/include/public/grant_table.h index 54bbc45eeb..c642e975d9 100644 --- a/xen/include/public/grant_table.h +++ b/xen/include/public/grant_table.h @@ -183,8 +183,6 @@ typedef struct gnttab_unmap_grant_ref { s16 status; /* GNTST_* */ } gnttab_unmap_grant_ref_t; -#define GNTUNMAP_DEV_FROM_VIRT (~0U) - /* * GNTTABOP_setup_table: Set up a grant table for comprising at least * pages. The frame addresses are written to the . From bb519d6c5cf6221aa70953c31b6ec90af4f02fa0 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 22 Aug 2005 08:36:21 +0000 Subject: [PATCH 22/29] When building in a tree with (the sparse trees and) the patches stripped, a warning is issued by make, which the below patch eliminates. Signed-off-by: Jan Beulich --- buildconfigs/Rules.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/buildconfigs/Rules.mk b/buildconfigs/Rules.mk index f259822b5f..615a21085c 100644 --- a/buildconfigs/Rules.mk +++ b/buildconfigs/Rules.mk @@ -66,6 +66,7 @@ pristine-%/.valid-pristine: %.tar.bz2 PATCHDIRS := $(wildcard patches/*-*) +ifneq ($(PATCHDIRS),) -include $(patsubst %,%/.makedep,$(PATCHDIRS)) $(patsubst patches/%,patches/%/.makedep,$(PATCHDIRS)): patches/%/.makedep: @@ -80,6 +81,7 @@ ref-%/.valid-ref: pristine-%/.valid-pristine ([ -d patches/$* ] && \ for i in patches/$*/*.patch ; do ( cd $(@D) ; patch -p1 <../$$i || exit 1 ) ; done) || true touch $@ # update timestamp to avoid rebuild +endif %-build: $(MAKE) -f buildconfigs/mk.$* build From a1a7a3e42fbdde8dcf396314d5ccb017362c93a1 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 22 Aug 2005 08:51:04 +0000 Subject: [PATCH 23/29] Ordering was broken in the course of separating XEN-overridden sources from those getting used through symlink creation. Signed-off-by: Jan Beulich --- linux-2.6-xen-sparse/arch/xen/i386/pci/Makefile | 5 +++-- linux-2.6-xen-sparse/arch/xen/x86_64/pci/Makefile | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/pci/Makefile b/linux-2.6-xen-sparse/arch/xen/i386/pci/Makefile index 76c024abfd..898fbd428a 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/pci/Makefile +++ b/linux-2.6-xen-sparse/arch/xen/i386/pci/Makefile @@ -17,7 +17,7 @@ l-pci-y += irq.o c-pci-$(CONFIG_X86_VISWS) := visws.o fixup.o pci-$(CONFIG_X86_VISWS) := c-pci-$(CONFIG_X86_NUMAQ) := numa.o -pci-$(CONFIG_X86_NUMAQ) := irq.o +l-pci-$(CONFIG_X86_NUMAQ) := irq.o obj-y += $(pci-y) c-obj-y += $(c-pci-y) common.o @@ -27,6 +27,7 @@ c-link := $(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-link)): @ln -fsn $(srctree)/arch/i386/pci/$(notdir $@) $@ -obj-y += $(c-obj-y) $(l-pci-y) +# Make sure irq.o gets linked in before common.o +obj-y += $(patsubst common.o,$(l-pci-y) common.o,$(c-obj-y)) clean-files += $(patsubst %.o,%.c,$(c-obj-y) $(c-obj-) $(c-link)) diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/pci/Makefile b/linux-2.6-xen-sparse/arch/xen/x86_64/pci/Makefile index 811fa0f200..25b13a3b4a 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/pci/Makefile +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/pci/Makefile @@ -30,8 +30,9 @@ $(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-link)): $(patsubst %.o,$(obj)/%.c,$(c-i386-obj-y)): @ln -fsn $(srctree)/arch/i386/pci/$(notdir $@) $@ -obj-y += $(c-i386-obj-y) $(c-obj-y) -obj-y += $(c-xen-obj-y) +# Make sure irq.o gets linked in before common.o +obj-y += $(patsubst common.o,$(c-xen-obj-y) common.o,$(c-i386-obj-y)) +obj-y += $(c-obj-y) clean-files += $(patsubst %.o,%.c,$(c-obj-y) $(c-obj-) $(c-link)) clean-files += $(patsubst %.o,%.c,$(c-i386-obj-y) $(c-i386-obj-)) From 3b742fc66ace9cbeb3b16578ee6ca140b17b98fe Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 22 Aug 2005 09:37:27 +0000 Subject: [PATCH 24/29] I noticed that an old problem is back (see below). The time command is not showing the correct time (it's 3 sec in real time). The patch attached restores the dropped line at the time of upgrading to 2.6.12. Jun Nakajima --- linux-2.6-xen-sparse/arch/xen/x86_64/kernel/vsyscall.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/vsyscall.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/vsyscall.c index 737ffeb6d0..d96b83e683 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/vsyscall.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/vsyscall.c @@ -210,15 +210,16 @@ static void __init map_vsyscall(void) __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL); } -extern void __set_fixmap_user (enum fixed_addresses, unsigned long, pgprot_t); - +#ifdef CONFIG_XEN static void __init map_vsyscall_user(void) { + extern void __set_fixmap_user(enum fixed_addresses, unsigned long, pgprot_t); extern char __vsyscall_0; unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0); __set_fixmap_user(VSYSCALL_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL); } +#endif static int __init vsyscall_init(void) { @@ -227,7 +228,10 @@ static int __init vsyscall_init(void) BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime)); BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE))); map_vsyscall(); - map_vsyscall_user(); /* establish tranlation for user address space */ +#ifdef CONFIG_XEN + map_vsyscall_user(); + sysctl_vsyscall = 0; /* disable vgettimeofay() */ +#endif #ifdef CONFIG_SYSCTL register_sysctl_table(kernel_root_table2, 0); #endif From 559ea02f610e54837db67a0ecc5dbdb66cc724de Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 22 Aug 2005 09:43:58 +0000 Subject: [PATCH 25/29] Fix out-of-source-tree build problem. Signed-off-by: Jan Beulich --- linux-2.6-xen-sparse/arch/xen/x86_64/ia32/Makefile | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/ia32/Makefile b/linux-2.6-xen-sparse/arch/xen/x86_64/ia32/Makefile index fe88b369a1..6ba237b682 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/ia32/Makefile +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/ia32/Makefile @@ -36,8 +36,8 @@ $(obj)/vsyscall-%.so: $(obj)/vsyscall.lds $(obj)/vsyscall-%.o FORCE $(call if_changed,syscall) AFLAGS_vsyscall-int80.o = -m32 -I$(obj) -AFLAGS_vsyscall-sysenter.o = -m32 -AFLAGS_vsyscall-syscall.o = -m32 +AFLAGS_vsyscall-sysenter.o = -m32 -I$(obj) +AFLAGS_vsyscall-syscall.o = -m32 -I$(obj) CFLAGS_ia32_ioctl.o += -Ifs/ s-link := vsyscall-syscall.o vsyscall-sysenter.o vsyscall-sigreturn.o @@ -48,13 +48,11 @@ $(obj)/vsyscall.lds: $(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-link)) $(patsubst %.o,$(obj)/%.S,$(s-obj-y) $(s-link)): @ln -fsn $(srctree)/arch/x86_64/ia32/$(notdir $@) $@ -$(obj)/vsyscall-int80.S: $(obj)/vsyscall-sigreturn.S ../../i386/kernel/vsyscall-note.S -$(obj)/vsyscall-sysenter.S: $(obj)/vsyscall-sigreturn.S -$(obj)/vsyscall-syscall.S: $(obj)/vsyscall-sigreturn.S +$(obj)/vsyscall-int80.o $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-syscall.o: \ + $(obj)/vsyscall-sigreturn.S $(obj)/../../i386/kernel/vsyscall-note.S -../../i386/kernel/vsyscall-note.S: - @ln -fsn $(srctree)/arch/i386/kernel/$(notdir $@) $(srctree)/arch/xen/i386/kernel/$(notdir $@) - make -C arch/xen/i386/kernel vsyscall-note.S +$(obj)/../../i386/kernel/vsyscall-note.S: + @ln -fsn $(srctree)/arch/i386/kernel/$(notdir $@) $@ obj-y += $(c-obj-y) $(s-obj-y) From aa82c3b80739646e75e50920b4a05c2ef55b49f6 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 22 Aug 2005 09:52:06 +0000 Subject: [PATCH 26/29] Ensure that 64-bit get_user/put_user only transfer to a 64-bit local variable. Some gcc versions have bugs if this restriction isn't observed. Signed-off-by: Keir Fraser --- xen/include/asm-x86/x86_32/uaccess.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xen/include/asm-x86/x86_32/uaccess.h b/xen/include/asm-x86/x86_32/uaccess.h index 176c8401fe..1ea7f86cae 100644 --- a/xen/include/asm-x86/x86_32/uaccess.h +++ b/xen/include/asm-x86/x86_32/uaccess.h @@ -22,7 +22,11 @@ #define array_access_ok(addr,count,size) \ (likely(count < (~0UL/size)) && access_ok(addr,count*size)) +/* Undefined function to catch size mismatches on 64-bit get_user/put_user. */ +extern void __uaccess_var_not_u64(void); + #define __put_user_u64(x, addr, retval, errret) \ + if (sizeof(x) != 8) __uaccess_var_not_u64(); \ __asm__ __volatile__( \ "1: movl %%eax,0(%2)\n" \ "2: movl %%edx,4(%2)\n" \ @@ -52,6 +56,7 @@ do { \ } while (0) #define __get_user_u64(x, addr, retval, errret) \ + if (sizeof(x) != 8) __uaccess_var_not_u64(); \ __asm__ __volatile__( \ "1: movl 0(%2),%%eax\n" \ "2: movl 4(%2),%%edx\n" \ From 46f1e56137e374e3485c6db20e9c566c7fb0f3be Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 22 Aug 2005 10:18:14 +0000 Subject: [PATCH 27/29] No 'boot error' message if booting secondary vcpu succeeds. --- linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c index b879cf5a8d..45787ddf5b 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c @@ -923,7 +923,8 @@ static int __init do_boot_cpu(int apicid) ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT; boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt); - printk("boot error: %ld\n", boot_error); + if (boot_error) + printk("boot error: %ld\n", boot_error); if (!boot_error) { /* From 09b3e8204213e06d255ec4db7aa6ac9d54023ad4 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Mon, 22 Aug 2005 10:20:58 +0000 Subject: [PATCH 28/29] Remove option for running block devices without grant-tables. Signed-off-by: Christian Limpach --- linux-2.6-xen-sparse/arch/xen/Kconfig | 9 --- .../arch/xen/configs/xen0_defconfig_x86_32 | 1 - .../arch/xen/configs/xen0_defconfig_x86_64 | 1 - .../arch/xen/configs/xenU_defconfig_x86_32 | 1 - .../arch/xen/configs/xenU_defconfig_x86_64 | 1 - .../arch/xen/configs/xen_defconfig_x86_32 | 1 - .../arch/xen/configs/xen_defconfig_x86_64 | 1 - linux-2.6-xen-sparse/arch/xen/kernel/reboot.c | 5 -- .../drivers/xen/blkback/blkback.c | 70 ------------------ .../drivers/xen/blkback/common.h | 4 -- .../drivers/xen/blkback/interface.c | 14 ---- .../drivers/xen/blkback/xenbus.c | 11 --- .../drivers/xen/blkfront/blkfront.c | 72 ------------------- xen/include/public/io/blkif.h | 6 -- 14 files changed, 197 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/Kconfig b/linux-2.6-xen-sparse/arch/xen/Kconfig index f3f6162df6..a66ebffe00 100644 --- a/linux-2.6-xen-sparse/arch/xen/Kconfig +++ b/linux-2.6-xen-sparse/arch/xen/Kconfig @@ -61,15 +61,6 @@ config XEN_BLKDEV_TAP_BE with the blktap. This option will be removed as the block drivers are modified to use grant tables. -config XEN_BLKDEV_GRANT - bool "Grant table substrate for block drivers" - depends on !XEN_BLKDEV_TAP_BE - default y - help - This introduces the use of grant tables as a data exhange mechanism - between the frontend and backend block drivers. This currently - conflicts with the block tap. - config XEN_NETDEV_BACKEND bool "Network-device backend driver" depends on XEN_PHYSDEV_ACCESS diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 index 418a2db5b4..162739efb3 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 @@ -14,7 +14,6 @@ CONFIG_XEN_PRIVILEGED_GUEST=y CONFIG_XEN_PHYSDEV_ACCESS=y CONFIG_XEN_BLKDEV_BACKEND=y # CONFIG_XEN_BLKDEV_TAP_BE is not set -CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 index ae756242ce..a918dc9c96 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 @@ -14,7 +14,6 @@ CONFIG_XEN_PRIVILEGED_GUEST=y CONFIG_XEN_PHYSDEV_ACCESS=y CONFIG_XEN_BLKDEV_BACKEND=y # CONFIG_XEN_BLKDEV_TAP_BE is not set -CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 index 18a5217794..e8d4ac4242 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 @@ -12,7 +12,6 @@ CONFIG_NO_IDLE_HZ=y # # CONFIG_XEN_PRIVILEGED_GUEST is not set # CONFIG_XEN_PHYSDEV_ACCESS is not set -CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y CONFIG_XEN_NETDEV_GRANT_TX=y diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 index 37934aa796..eea8b9462e 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 @@ -12,7 +12,6 @@ CONFIG_NO_IDLE_HZ=y # # CONFIG_XEN_PRIVILEGED_GUEST is not set # CONFIG_XEN_PHYSDEV_ACCESS is not set -CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y CONFIG_XEN_NETDEV_GRANT_TX=y diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 index 51307cfbe0..5e64881232 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 @@ -14,7 +14,6 @@ CONFIG_XEN_PRIVILEGED_GUEST=y CONFIG_XEN_PHYSDEV_ACCESS=y CONFIG_XEN_BLKDEV_BACKEND=y # CONFIG_XEN_BLKDEV_TAP_BE is not set -CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 index f7619599e3..2a01472dd5 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 @@ -14,7 +14,6 @@ CONFIG_XEN_PRIVILEGED_GUEST=y CONFIG_XEN_PHYSDEV_ACCESS=y CONFIG_XEN_BLKDEV_BACKEND=y # CONFIG_XEN_BLKDEV_TAP_BE is not set -CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c index 937292776e..f1a773a7e8 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c @@ -143,13 +143,8 @@ static int __do_suspend(void *ignore) #define usbif_resume() do{}while(0) #endif -#ifdef CONFIG_XEN_BLKDEV_GRANT extern int gnttab_suspend(void); extern int gnttab_resume(void); -#else -#define gnttab_suspend() do{}while(0) -#define gnttab_resume() do{}while(0) -#endif #ifdef CONFIG_SMP extern void smp_suspend(void); 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 97c7865abe..d8378bd3f0 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c @@ -80,7 +80,6 @@ static inline void flush_plugged_queue(void) } #endif -#ifdef CONFIG_XEN_BLKDEV_GRANT /* When using grant tables to map a frame for device access then the * handle returned must be used to unmap the frame. This is needed to * drop the ref count on the frame. @@ -89,7 +88,6 @@ static u16 pending_grant_handles[MMAP_PAGES]; #define pending_handle(_idx, _i) \ (pending_grant_handles[((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) + (_i)]) #define BLKBACK_INVALID_HANDLE (0xFFFF) -#endif #ifdef CONFIG_XEN_BLKDEV_TAP_BE /* @@ -110,7 +108,6 @@ static void make_response(blkif_t *blkif, unsigned long id, static void fast_flush_area(int idx, int nr_pages) { -#ifdef CONFIG_XEN_BLKDEV_GRANT struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int i, invcount = 0; u16 handle; @@ -129,21 +126,6 @@ static void fast_flush_area(int idx, int nr_pages) if ( unlikely(HYPERVISOR_grant_table_op( GNTTABOP_unmap_grant_ref, unmap, invcount))) BUG(); -#else - - multicall_entry_t mcl[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - int i; - - for ( i = 0; i < nr_pages; i++ ) - { - MULTI_update_va_mapping(mcl+i, MMAP_VADDR(idx, i), - __pte(0), 0); - } - - mcl[nr_pages-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; - if ( unlikely(HYPERVISOR_multicall(mcl, nr_pages) != 0) ) - BUG(); -#endif } @@ -367,12 +349,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) unsigned long fas = 0; int i, pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; pending_req_t *pending_req; -#ifdef CONFIG_XEN_BLKDEV_GRANT struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST]; -#else - unsigned long remap_prot; - multicall_entry_t mcl[BLKIF_MAX_SEGMENTS_PER_REQUEST]; -#endif struct phys_req preq; struct { unsigned long buf; unsigned int nsec; @@ -399,7 +376,6 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) preq.sector_number = req->sector_number; preq.nr_sects = 0; -#ifdef CONFIG_XEN_BLKDEV_GRANT for ( i = 0; i < nseg; i++ ) { fas = req->frame_and_sects[i]; @@ -435,20 +411,11 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) pending_handle(pending_idx, i) = map[i].handle; } -#endif for ( i = 0; i < nseg; i++ ) { fas = req->frame_and_sects[i]; -#ifdef CONFIG_XEN_BLKDEV_GRANT seg[i].buf = map[i].dev_bus_addr | (blkif_first_sect(fas) << 9); -#else - seg[i].buf = (fas & PAGE_MASK) | (blkif_first_sect(fas) << 9); - seg[i].nsec = blkif_last_sect(fas) - blkif_first_sect(fas) + 1; - if ( seg[i].nsec <= 0 ) - goto bad_descriptor; - preq.nr_sects += seg[i].nsec; -#endif } if ( vbd_translate(&preq, blkif, operation) != 0 ) @@ -459,40 +426,6 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) goto bad_descriptor; } -#ifndef CONFIG_XEN_BLKDEV_GRANT - if ( operation == READ ) - remap_prot = _PAGE_PRESENT|_PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_RW; - else - remap_prot = _PAGE_PRESENT|_PAGE_DIRTY|_PAGE_ACCESSED; - - - for ( i = 0; i < nseg; i++ ) - { - MULTI_update_va_mapping_otherdomain( - mcl+i, MMAP_VADDR(pending_idx, i), - pfn_pte_ma(seg[i].buf >> PAGE_SHIFT, __pgprot(remap_prot)), - 0, blkif->domid); -#ifdef CONFIG_XEN_BLKDEV_TAP_BE - if ( blkif->is_blktap ) - mcl[i].args[MULTI_UVMDOMID_INDEX] = ID_TO_DOM(req->id); -#endif - phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] = - FOREIGN_FRAME(seg[i].buf >> PAGE_SHIFT); - } - - BUG_ON(HYPERVISOR_multicall(mcl, nseg) != 0); - - for ( i = 0; i < nseg; i++ ) - { - if ( unlikely(mcl[i].result != 0) ) - { - DPRINTK("invalid buffer -- could not remap it\n"); - fast_flush_area(pending_idx, nseg); - goto bad_descriptor; - } - } -#endif /* end ifndef CONFIG_XEN_BLKDEV_GRANT */ - pending_req = &pending_reqs[pending_idx]; pending_req->blkif = blkif; pending_req->id = req->id; @@ -666,10 +599,7 @@ static int __init blkif_init(void) blkif_xenbus_init(); -#ifdef CONFIG_XEN_BLKDEV_GRANT memset( pending_grant_handles, BLKBACK_INVALID_HANDLE, MMAP_PAGES ); - printk(KERN_ALERT "Blkif backend is using grant tables.\n"); -#endif #ifdef CONFIG_XEN_BLKDEV_TAP_BE printk(KERN_ALERT "NOTE: Blkif backend is running with tap support on!\n"); diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h index dd56fdeb25..3d83383142 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h @@ -17,9 +17,7 @@ #include #include #include -#ifdef CONFIG_XEN_BLKDEV_GRANT #include -#endif #if 0 #define ASSERT(_p) \ @@ -69,11 +67,9 @@ typedef struct blkif_st { atomic_t refcnt; struct work_struct work; -#ifdef CONFIG_XEN_BLKDEV_GRANT u16 shmem_handle; unsigned long shmem_vaddr; grant_ref_t shmem_ref; -#endif } blkif_t; void blkif_create(blkif_be_create_t *create); 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 259b65c39c..633dab8e26 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c @@ -47,19 +47,6 @@ blkif_t *blkif_find(domid_t domid) return blkif; } -#ifndef CONFIG_XEN_BLKDEV_GRANT -static int map_frontend_page(blkif_t *blkif, unsigned long localaddr, - unsigned long shared_page) -{ - return direct_remap_area_pages(&init_mm, localaddr, - shared_page<domid); -} - -static void unmap_frontend_page(blkif_t *blkif) -{ -} -#else static int map_frontend_page(blkif_t *blkif, unsigned long localaddr, unsigned long shared_page) { @@ -91,7 +78,6 @@ static void unmap_frontend_page(blkif_t *blkif) op.dev_bus_addr = 0; BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); } -#endif /* CONFIG_XEN_BLKDEV_GRANT */ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) { diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c index 175b10f6b1..39e901de6d 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c @@ -75,16 +75,6 @@ static void frontend_changed(struct xenbus_watch *watch, const char *node) if (vbd_is_active(be->vbd)) return; -#ifndef CONFIG_XEN_BLKDEV_GRANT - err = xenbus_gather(be->frontpath, "shared-frame", "%lu", &sharedmfn, - "event-channel", "%u", &evtchn, NULL); - if (err) { - xenbus_dev_error(be->dev, err, - "reading %s/shared-frame and event-channel", - be->frontpath); - return; - } -#else err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn, "event-channel", "%u", &evtchn, NULL); if (err) { @@ -93,7 +83,6 @@ static void frontend_changed(struct xenbus_watch *watch, const char *node) be->frontpath); return; } -#endif /* Domains must use same shared frame for all vbds. */ if (be->blkif->status == CONNECTED && diff --git a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c index d7afebf094..d4e60ace2b 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -55,10 +55,8 @@ #include #include #include -#ifdef CONFIG_XEN_BLKDEV_GRANT #include #include -#endif typedef unsigned char byte; /* from linux/ide.h */ @@ -78,14 +76,12 @@ static blkif_front_ring_t blk_ring; #define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE) -#ifdef CONFIG_XEN_BLKDEV_GRANT static domid_t rdomid = 0; static grant_ref_t gref_head, gref_terminal; #define MAXIMUM_OUTSTANDING_BLOCK_REQS \ (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE) #define GRANTREF_INVALID (1<<15) static int shmem_ref; -#endif static struct blk_shadow { blkif_request_t req; @@ -131,30 +127,14 @@ static int sg_operation = -1; static inline void pickle_request(struct blk_shadow *s, blkif_request_t *r) { -#ifndef CONFIG_XEN_BLKDEV_GRANT - int i; -#endif s->req = *r; - -#ifndef CONFIG_XEN_BLKDEV_GRANT - for ( i = 0; i < r->nr_segments; i++ ) - s->req.frame_and_sects[i] = machine_to_phys(r->frame_and_sects[i]); -#endif } static inline void unpickle_request(blkif_request_t *r, struct blk_shadow *s) { -#ifndef CONFIG_XEN_BLKDEV_GRANT - int i; -#endif *r = s->req; - -#ifndef CONFIG_XEN_BLKDEV_GRANT - for ( i = 0; i < s->req.nr_segments; i++ ) - r->frame_and_sects[i] = phys_to_machine(s->req.frame_and_sects[i]); -#endif } @@ -256,9 +236,7 @@ static int blkif_queue_request(struct request *req) int idx; unsigned long id; unsigned int fsect, lsect; -#ifdef CONFIG_XEN_BLKDEV_GRANT int ref; -#endif if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) ) return 1; @@ -284,7 +262,6 @@ static int blkif_queue_request(struct request *req) buffer_ma = page_to_phys(bvec->bv_page); fsect = bvec->bv_offset >> 9; lsect = fsect + (bvec->bv_len >> 9) - 1; -#ifdef CONFIG_XEN_BLKDEV_GRANT /* install a grant reference. */ ref = gnttab_claim_grant_reference(&gref_head, gref_terminal); ASSERT( ref != -ENOSPC ); @@ -300,11 +277,6 @@ static int blkif_queue_request(struct request *req) ring_req->frame_and_sects[ring_req->nr_segments++] = blkif_fas_from_gref(ref, fsect, lsect); - -#else - ring_req->frame_and_sects[ring_req->nr_segments++] = - blkif_fas(buffer_ma, fsect, lsect); -#endif } } @@ -711,9 +683,7 @@ static int blkif_queue_request(unsigned long id, blkif_request_t *req; struct buffer_head *bh; unsigned int fsect, lsect; -#ifdef CONFIG_XEN_BLKDEV_GRANT int ref; -#endif fsect = (buffer_ma & ~PAGE_MASK) >> 9; lsect = fsect + nr_sectors - 1; @@ -762,7 +732,6 @@ static int blkif_queue_request(unsigned long id, bh->b_reqnext = (struct buffer_head *)blk_shadow[req->id].request; blk_shadow[req->id].request = (unsigned long)id; -#ifdef CONFIG_XEN_BLKDEV_GRANT /* install a grant reference. */ ref = gnttab_claim_grant_reference(&gref_head, gref_terminal); ASSERT( ref != -ENOSPC ); @@ -778,10 +747,6 @@ static int blkif_queue_request(unsigned long id, req->frame_and_sects[req->nr_segments] = blkif_fas_from_gref(ref, fsect, lsect); -#else - req->frame_and_sects[req->nr_segments] = - blkif_fas(buffer_ma, fsect, lsect); -#endif if ( ++req->nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST ) sg_next_sect += nr_sectors; else @@ -819,7 +784,6 @@ static int blkif_queue_request(unsigned long id, req->sector_number = (blkif_sector_t)sector_number; req->handle = handle; req->nr_segments = 1; -#ifdef CONFIG_XEN_BLKDEV_GRANT /* install a grant reference. */ ref = gnttab_claim_grant_reference(&gref_head, gref_terminal); ASSERT( ref != -ENOSPC ); @@ -833,9 +797,6 @@ static int blkif_queue_request(unsigned long id, blk_shadow[xid].frame[0] = buffer_ma >> PAGE_SHIFT; req->frame_and_sects[0] = blkif_fas_from_gref(ref, fsect, lsect); -#else - req->frame_and_sects[0] = blkif_fas(buffer_ma, fsect, lsect); -#endif /* Keep a private copy so we can reissue requests when recovering. */ pickle_request(&blk_shadow[xid], req); @@ -1015,9 +976,7 @@ static void blkif_recover(void) int i; blkif_request_t *req; struct blk_shadow *copy; -#ifdef CONFIG_XEN_BLKDEV_GRANT int j; -#endif /* Stage 1: Make a safe copy of the shadow state. */ copy = (struct blk_shadow *)kmalloc(sizeof(blk_shadow), GFP_KERNEL); @@ -1047,7 +1006,6 @@ static void blkif_recover(void) req->id = GET_ID_FROM_FREELIST(); memcpy(&blk_shadow[req->id], ©[i], sizeof(copy[i])); -#ifdef CONFIG_XEN_BLKDEV_GRANT /* Rewrite any grant references invalidated by suspend/resume. */ for ( j = 0; j < req->nr_segments; j++ ) { @@ -1061,7 +1019,6 @@ static void blkif_recover(void) req->frame_and_sects[j] &= ~GRANTREF_INVALID; } blk_shadow[req->id].req = *req; -#endif blk_ring.req_prod_pvt++; } @@ -1085,9 +1042,7 @@ static void blkif_connect(u16 evtchn, domid_t domid) int err = 0; blkif_evtchn = evtchn; -#ifdef CONFIG_XEN_BLKDEV_GRANT rdomid = domid; -#endif err = bind_evtchn_to_irqhandler( blkif_evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", NULL); @@ -1168,7 +1123,6 @@ static int setup_blkring(struct xenbus_device *dev, unsigned int backend_id) SHARED_RING_INIT(sring); FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE); -#ifdef CONFIG_XEN_BLKDEV_GRANT shmem_ref = gnttab_claim_grant_reference(&gref_head, gref_terminal); ASSERT(shmem_ref != -ENOSPC); @@ -1176,7 +1130,6 @@ static int setup_blkring(struct xenbus_device *dev, unsigned int backend_id) backend_id, virt_to_mfn(blk_ring.sring), 0); -#endif op.u.alloc_unbound.dom = backend_id; err = HYPERVISOR_event_channel_op(&op); @@ -1228,20 +1181,11 @@ static int talk_to_backend(struct xenbus_device *dev, goto destroy_blkring; } -#ifdef CONFIG_XEN_BLKDEV_GRANT err = xenbus_printf(dev->nodename, "grant-id","%u", shmem_ref); if (err) { message = "writing grant-id"; goto abort_transaction; } -#else - err = xenbus_printf(dev->nodename, "shared-frame", "%lu", - virt_to_mfn(blk_ring.sring)); - if (err) { - message = "writing shared-frame"; - goto abort_transaction; - } -#endif err = xenbus_printf(dev->nodename, "event-channel", "%u", blkif_evtchn); if (err) { @@ -1419,13 +1363,10 @@ static int __init xlblk_init(void) { int i; -#ifdef CONFIG_XEN_BLKDEV_GRANT /* A grant for every ring slot, plus one for the ring itself. */ if (gnttab_alloc_grant_references(MAXIMUM_OUTSTANDING_BLOCK_REQS + 1, &gref_head, &gref_terminal) < 0) return 1; - printk(KERN_ALERT "Blkif frontend is using grant tables.\n"); -#endif if ( (xen_start_info.flags & SIF_INITDOMAIN) || (xen_start_info.flags & SIF_BLK_BE_DOMAIN) ) @@ -1449,20 +1390,7 @@ static int __init xlblk_init(void) static void blkif_completion(struct blk_shadow *s) { int i; -#ifdef CONFIG_XEN_BLKDEV_GRANT for ( i = 0; i < s->req.nr_segments; i++ ) gnttab_release_grant_reference( &gref_head, blkif_gref_from_fas(s->req.frame_and_sects[i])); -#else - /* This is a hack to get the dirty logging bits set */ - if ( s->req.operation == BLKIF_OP_READ ) - { - for ( i = 0; i < s->req.nr_segments; i++ ) - { - unsigned long pfn = s->req.frame_and_sects[i] >> PAGE_SHIFT; - unsigned long mfn = phys_to_machine_mapping[pfn]; - xen_machphys_update(mfn, pfn); - } - } -#endif } diff --git a/xen/include/public/io/blkif.h b/xen/include/public/io/blkif.h index d0e2a60732..26a33a448c 100644 --- a/xen/include/public/io/blkif.h +++ b/xen/include/public/io/blkif.h @@ -36,11 +36,7 @@ typedef struct blkif_request { unsigned long id; /* private guest value, echoed in resp */ blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ /* @f_a_s[4:0]=last_sect ; @f_a_s[9:5]=first_sect */ -#ifdef CONFIG_XEN_BLKDEV_GRANT /* @f_a_s[:16]= grant reference (16 bits) */ -#else - /* @f_a_s[:12]=@frame: machine page frame number. */ -#endif /* @first_sect: first sector in frame to transfer (inclusive). */ /* @last_sect: last sector in frame to transfer (inclusive). */ unsigned long frame_and_sects[BLKIF_MAX_SEGMENTS_PER_REQUEST]; @@ -50,10 +46,8 @@ typedef struct blkif_request { #define blkif_first_sect(_fas) (((_fas)>>5)&31) #define blkif_last_sect(_fas) ((_fas)&31) -#ifdef CONFIG_XEN_BLKDEV_GRANT #define blkif_fas_from_gref(_gref, _fs, _ls) (((_gref)<<16)|((_fs)<<5)|(_ls)) #define blkif_gref_from_fas(_fas) ((_fas)>>16) -#endif typedef struct blkif_response { unsigned long id; /* copied from request */ From f84addf44986b34be13ae81892809fd583303a64 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 22 Aug 2005 16:38:13 +0000 Subject: [PATCH 29/29] Apply Ross Mcilroy's balloon_dealloc_empty_page_range patch and generally clean up the ballon driver a bunch. Signed-off-by: Keir Fraser --- .../arch/xen/i386/mm/hypervisor.c | 48 -- .../drivers/xen/balloon/balloon.c | 500 ++++++++++-------- .../drivers/xen/blkback/blkback.c | 6 +- .../drivers/xen/blktap/blktap_userdev.c | 6 +- .../drivers/xen/netback/netback.c | 5 +- .../drivers/xen/usbback/usbback.c | 8 +- .../include/asm-xen/balloon.h | 15 +- .../include/asm-xen/hypervisor.h | 3 - 8 files changed, 293 insertions(+), 298 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c index 26433a2b67..1d7b4b1fab 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c @@ -405,54 +405,6 @@ void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order) balloon_unlock(flags); } - -unsigned long allocate_empty_lowmem_region(unsigned long pages) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - unsigned long *pfn_array; - unsigned long vstart; - unsigned long i; - unsigned int order = get_order(pages*PAGE_SIZE); - - vstart = __get_free_pages(GFP_KERNEL, order); - if (vstart == 0) - return 0UL; - - scrub_pages(vstart, 1 << order); - - pfn_array = vmalloc((1<>PAGE_SHIFT)+i] = - INVALID_P2M_ENTRY; - } - - flush_tlb_all(); - - balloon_put_pages(pfn_array, 1 << order); - - vfree(pfn_array); - - return vstart; -} - -EXPORT_SYMBOL(allocate_empty_lowmem_region); - /* * Local variables: * c-file-style: "linux" diff --git a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c index ed4822932f..090a19be4d 100644 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c @@ -83,12 +83,15 @@ static struct timer_list balloon_timer; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) /* Use the private and mapping fields of struct page as a list. */ -#define PAGE_TO_LIST(p) ( (struct list_head *)&p->private ) -#define LIST_TO_PAGE(l) ( list_entry( ((unsigned long *)l), \ - struct page, private ) ) -#define UNLIST_PAGE(p) do { list_del(PAGE_TO_LIST(p)); \ - p->mapping = NULL; \ - p->private = 0; } while(0) +#define PAGE_TO_LIST(p) ((struct list_head *)&p->private) +#define LIST_TO_PAGE(l) \ + (list_entry(((unsigned long *)l), struct page, private)) +#define UNLIST_PAGE(p) \ + do { \ + list_del(PAGE_TO_LIST(p)); \ + p->mapping = NULL; \ + p->private = 0; \ + } while(0) #else /* There's a dedicated list field in struct page we can use. */ #define PAGE_TO_LIST(p) ( &p->list ) @@ -104,56 +107,53 @@ static struct timer_list balloon_timer; #endif #define IPRINTK(fmt, args...) \ - printk(KERN_INFO "xen_mem: " fmt, ##args) + printk(KERN_INFO "xen_mem: " fmt, ##args) #define WPRINTK(fmt, args...) \ - printk(KERN_WARNING "xen_mem: " fmt, ##args) + printk(KERN_WARNING "xen_mem: " fmt, ##args) /* balloon_append: add the given page to the balloon. */ static void balloon_append(struct page *page) { - /* Low memory is re-populated first, so highmem pages go at list tail. */ - if ( PageHighMem(page) ) - { - list_add_tail(PAGE_TO_LIST(page), &ballooned_pages); - balloon_high++; - } - else - { - list_add(PAGE_TO_LIST(page), &ballooned_pages); - balloon_low++; - } + /* Lowmem is re-populated first, so highmem pages go at list tail. */ + if (PageHighMem(page)) { + list_add_tail(PAGE_TO_LIST(page), &ballooned_pages); + balloon_high++; + } else { + list_add(PAGE_TO_LIST(page), &ballooned_pages); + balloon_low++; + } } /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */ static struct page *balloon_retrieve(void) { - struct page *page; + struct page *page; - if ( list_empty(&ballooned_pages) ) - return NULL; + if (list_empty(&ballooned_pages)) + return NULL; - page = LIST_TO_PAGE(ballooned_pages.next); - UNLIST_PAGE(page); + page = LIST_TO_PAGE(ballooned_pages.next); + UNLIST_PAGE(page); - if ( PageHighMem(page) ) - balloon_high--; - else - balloon_low--; + if (PageHighMem(page)) + balloon_high--; + else + balloon_low--; - return page; + return page; } static void balloon_alarm(unsigned long unused) { - schedule_work(&balloon_worker); + schedule_work(&balloon_worker); } static unsigned long current_target(void) { - unsigned long target = min(target_pages, hard_limit); - if ( target > (current_pages + balloon_low + balloon_high) ) - target = current_pages + balloon_low + balloon_high; - return target; + unsigned long target = min(target_pages, hard_limit); + if (target > (current_pages + balloon_low + balloon_high)) + target = current_pages + balloon_low + balloon_high; + return target; } /* @@ -164,161 +164,147 @@ static unsigned long current_target(void) */ static void balloon_process(void *unused) { - unsigned long *mfn_list, pfn, i, flags; - struct page *page; - long credit, debt, rc; - void *v; + unsigned long *mfn_list, pfn, i, flags; + struct page *page; + long credit, debt, rc; + void *v; - down(&balloon_mutex); + down(&balloon_mutex); retry: - mfn_list = NULL; + mfn_list = NULL; - if ( (credit = current_target() - current_pages) > 0 ) - { - mfn_list = (unsigned long *)vmalloc(credit * sizeof(*mfn_list)); - if ( mfn_list == NULL ) - goto out; + if ((credit = current_target() - current_pages) > 0) { + mfn_list = vmalloc(credit * sizeof(*mfn_list)); + if (mfn_list == NULL) + goto out; - balloon_lock(flags); - rc = HYPERVISOR_dom_mem_op( - MEMOP_increase_reservation, mfn_list, credit, 0); - balloon_unlock(flags); - if ( rc < credit ) - { - /* We hit the Xen hard limit: reprobe. */ - if ( HYPERVISOR_dom_mem_op( - MEMOP_decrease_reservation, mfn_list, rc, 0) != rc ) - BUG(); - hard_limit = current_pages + rc - driver_pages; - vfree(mfn_list); - goto retry; - } + balloon_lock(flags); + rc = HYPERVISOR_dom_mem_op( + MEMOP_increase_reservation, mfn_list, credit, 0); + balloon_unlock(flags); + if (rc < credit) { + /* We hit the Xen hard limit: reprobe. */ + BUG_ON(HYPERVISOR_dom_mem_op( + MEMOP_decrease_reservation, + mfn_list, rc, 0) != rc); + hard_limit = current_pages + rc - driver_pages; + vfree(mfn_list); + goto retry; + } - for ( i = 0; i < credit; i++ ) - { - if ( (page = balloon_retrieve()) == NULL ) - BUG(); + for (i = 0; i < credit; i++) { + page = balloon_retrieve(); + BUG_ON(page == NULL); - pfn = page - mem_map; - if ( phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY ) - BUG(); + pfn = page - mem_map; + if (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY) + BUG(); - /* Update P->M and M->P tables. */ - phys_to_machine_mapping[pfn] = mfn_list[i]; - xen_machphys_update(mfn_list[i], pfn); + /* Update P->M and M->P tables. */ + phys_to_machine_mapping[pfn] = mfn_list[i]; + xen_machphys_update(mfn_list[i], pfn); - /* Link back into the page tables if it's not a highmem page. */ - if ( pfn < max_low_pfn ) - { - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)__va(pfn << PAGE_SHIFT), - pfn_pte_ma(mfn_list[i], PAGE_KERNEL), 0)); - } + /* Link back into the page tables if not highmem. */ + if (pfn < max_low_pfn) + BUG_ON(HYPERVISOR_update_va_mapping( + (unsigned long)__va(pfn << PAGE_SHIFT), + pfn_pte_ma(mfn_list[i], PAGE_KERNEL), + 0)); - /* Finally, relinquish the memory back to the system allocator. */ - ClearPageReserved(page); - set_page_count(page, 1); - __free_page(page); - } + /* Relinquish the page back to the allocator. */ + ClearPageReserved(page); + set_page_count(page, 1); + __free_page(page); + } - current_pages += credit; - } - else if ( credit < 0 ) - { - debt = -credit; + current_pages += credit; + } else if (credit < 0) { + debt = -credit; - mfn_list = (unsigned long *)vmalloc(debt * sizeof(*mfn_list)); - if ( mfn_list == NULL ) - goto out; + mfn_list = vmalloc(debt * sizeof(*mfn_list)); + if (mfn_list == NULL) + goto out; - for ( i = 0; i < debt; i++ ) - { - if ( (page = alloc_page(GFP_HIGHUSER)) == NULL ) - { - debt = i; - break; - } + for (i = 0; i < debt; i++) { + if ((page = alloc_page(GFP_HIGHUSER)) == NULL) { + debt = i; + break; + } - pfn = page - mem_map; - mfn_list[i] = phys_to_machine_mapping[pfn]; + pfn = page - mem_map; + mfn_list[i] = phys_to_machine_mapping[pfn]; - if ( !PageHighMem(page) ) - { - v = phys_to_virt(pfn << PAGE_SHIFT); - scrub_pages(v, 1); - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)v, __pte_ma(0), 0)); - } + if (!PageHighMem(page)) { + v = phys_to_virt(pfn << PAGE_SHIFT); + scrub_pages(v, 1); + BUG_ON(HYPERVISOR_update_va_mapping( + (unsigned long)v, __pte_ma(0), 0)); + } #ifdef CONFIG_XEN_SCRUB_PAGES - else - { - v = kmap(page); - scrub_pages(v, 1); - kunmap(page); - } + else { + v = kmap(page); + scrub_pages(v, 1); + kunmap(page); + } #endif - } + } - /* Ensure that ballooned highmem pages don't have cached mappings. */ - kmap_flush_unused(); - flush_tlb_all(); + /* Ensure that ballooned highmem pages don't have kmaps. */ + kmap_flush_unused(); + flush_tlb_all(); - /* No more mappings: invalidate pages in P2M and add to balloon. */ - for ( i = 0; i < debt; i++ ) - { - pfn = mfn_to_pfn(mfn_list[i]); - phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY; - balloon_append(pfn_to_page(pfn)); - } + /* No more mappings: invalidate P2M and add to balloon. */ + for (i = 0; i < debt; i++) { + pfn = mfn_to_pfn(mfn_list[i]); + phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY; + balloon_append(pfn_to_page(pfn)); + } - if ( HYPERVISOR_dom_mem_op( - MEMOP_decrease_reservation, mfn_list, debt, 0) != debt ) - BUG(); + BUG_ON(HYPERVISOR_dom_mem_op( + MEMOP_decrease_reservation,mfn_list, debt, 0) != debt); - current_pages -= debt; - } + current_pages -= debt; + } out: - if ( mfn_list != NULL ) - vfree(mfn_list); + if (mfn_list != NULL) + vfree(mfn_list); - /* Schedule more work if there is some still to be done. */ - if ( current_target() != current_pages ) - mod_timer(&balloon_timer, jiffies + HZ); + /* Schedule more work if there is some still to be done. */ + if (current_target() != current_pages) + mod_timer(&balloon_timer, jiffies + HZ); - up(&balloon_mutex); + up(&balloon_mutex); } /* Resets the Xen limit, sets new target, and kicks off processing. */ static void set_new_target(unsigned long target) { - /* No need for lock. Not read-modify-write updates. */ - hard_limit = ~0UL; - target_pages = target; - schedule_work(&balloon_worker); + /* No need for lock. Not read-modify-write updates. */ + hard_limit = ~0UL; + target_pages = target; + schedule_work(&balloon_worker); } static struct xenbus_watch target_watch = { - .node = "memory/target" + .node = "memory/target" }; /* React to a change in the target key */ static void watch_target(struct xenbus_watch *watch, const char *node) { - unsigned long new_target; - int err; + unsigned long new_target; + int err; - err = xenbus_scanf("memory", "target", "%lu", &new_target); + err = xenbus_scanf("memory", "target", "%lu", &new_target); + if (err != 1) { + printk(KERN_ERR "Unable to read memory/target\n"); + return; + } - if(err != 1) - { - printk(KERN_ERR "Unable to read memory/target\n"); - return; - } - - set_new_target(new_target >> PAGE_SHIFT); + set_new_target(new_target >> PAGE_SHIFT); } @@ -329,141 +315,185 @@ int balloon_init_watcher(struct notifier_block *notifier, unsigned long event, void *data) { - int err; + int err; - BUG_ON(down_trylock(&xenbus_lock) == 0); + BUG_ON(down_trylock(&xenbus_lock) == 0); - err = register_xenbus_watch(&target_watch); + err = register_xenbus_watch(&target_watch); + if (err) + printk(KERN_ERR "Failed to set balloon watcher\n"); - if (err) { - printk(KERN_ERR "Failed to set balloon watcher\n"); - } - - return NOTIFY_DONE; + return NOTIFY_DONE; } static int balloon_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { - char memstring[64], *endchar; - unsigned long long target_bytes; + char memstring[64], *endchar; + unsigned long long target_bytes; - if ( !capable(CAP_SYS_ADMIN) ) - return -EPERM; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; - if ( count <= 1 ) - return -EBADMSG; /* runt */ - if ( count > sizeof(memstring) ) - return -EFBIG; /* too long */ + if (count <= 1) + return -EBADMSG; /* runt */ + if (count > sizeof(memstring)) + return -EFBIG; /* too long */ - if ( copy_from_user(memstring, buffer, count) ) - return -EFAULT; - memstring[sizeof(memstring)-1] = '\0'; + if (copy_from_user(memstring, buffer, count)) + return -EFAULT; + memstring[sizeof(memstring)-1] = '\0'; - target_bytes = memparse(memstring, &endchar); - set_new_target(target_bytes >> PAGE_SHIFT); + target_bytes = memparse(memstring, &endchar); + set_new_target(target_bytes >> PAGE_SHIFT); - return count; + return count; } static int balloon_read(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len; + int len; - len = sprintf( - page, - "Current allocation: %8lu kB\n" - "Requested target: %8lu kB\n" - "Low-mem balloon: %8lu kB\n" - "High-mem balloon: %8lu kB\n" - "Xen hard limit: ", - PAGES2KB(current_pages), PAGES2KB(target_pages), - PAGES2KB(balloon_low), PAGES2KB(balloon_high)); + len = sprintf( + page, + "Current allocation: %8lu kB\n" + "Requested target: %8lu kB\n" + "Low-mem balloon: %8lu kB\n" + "High-mem balloon: %8lu kB\n" + "Xen hard limit: ", + PAGES2KB(current_pages), PAGES2KB(target_pages), + PAGES2KB(balloon_low), PAGES2KB(balloon_high)); - if ( hard_limit != ~0UL ) - len += sprintf( - page + len, - "%8lu kB (inc. %8lu kB driver headroom)\n", - PAGES2KB(hard_limit), PAGES2KB(driver_pages)); - else - len += sprintf( - page + len, - " ??? kB\n"); + if (hard_limit != ~0UL) { + len += sprintf( + page + len, + "%8lu kB (inc. %8lu kB driver headroom)\n", + PAGES2KB(hard_limit), PAGES2KB(driver_pages)); + } else { + len += sprintf( + page + len, + " ??? kB\n"); + } - *eof = 1; - return len; + *eof = 1; + return len; } static struct notifier_block xenstore_notifier; static int __init balloon_init(void) { - unsigned long pfn; - struct page *page; + unsigned long pfn; + struct page *page; - IPRINTK("Initialising balloon driver.\n"); + IPRINTK("Initialising balloon driver.\n"); - current_pages = min(xen_start_info.nr_pages, max_pfn); - target_pages = current_pages; - balloon_low = 0; - balloon_high = 0; - driver_pages = 0UL; - hard_limit = ~0UL; + current_pages = min(xen_start_info.nr_pages, max_pfn); + target_pages = current_pages; + balloon_low = 0; + balloon_high = 0; + driver_pages = 0UL; + hard_limit = ~0UL; - init_timer(&balloon_timer); - balloon_timer.data = 0; - balloon_timer.function = balloon_alarm; + init_timer(&balloon_timer); + balloon_timer.data = 0; + balloon_timer.function = balloon_alarm; - if ( (balloon_pde = create_xen_proc_entry("balloon", 0644)) == NULL ) - { - WPRINTK("Unable to create /proc/xen/balloon.\n"); - return -1; - } + if ((balloon_pde = create_xen_proc_entry("balloon", 0644)) == NULL) { + WPRINTK("Unable to create /proc/xen/balloon.\n"); + return -1; + } - balloon_pde->read_proc = balloon_read; - balloon_pde->write_proc = balloon_write; + balloon_pde->read_proc = balloon_read; + balloon_pde->write_proc = balloon_write; - /* Initialise the balloon with excess memory space. */ - for ( pfn = xen_start_info.nr_pages; pfn < max_pfn; pfn++ ) - { - page = &mem_map[pfn]; - if ( !PageReserved(page) ) - balloon_append(page); - } + /* Initialise the balloon with excess memory space. */ + for (pfn = xen_start_info.nr_pages; pfn < max_pfn; pfn++) { + page = &mem_map[pfn]; + if (!PageReserved(page)) + balloon_append(page); + } - target_watch.callback = watch_target; - xenstore_notifier.notifier_call = balloon_init_watcher; + target_watch.callback = watch_target; + xenstore_notifier.notifier_call = balloon_init_watcher; - register_xenstore_notifier(&xenstore_notifier); + register_xenstore_notifier(&xenstore_notifier); - return 0; + return 0; } subsys_initcall(balloon_init); void balloon_update_driver_allowance(long delta) { - unsigned long flags; - balloon_lock(flags); - driver_pages += delta; /* non-atomic update */ - balloon_unlock(flags); + unsigned long flags; + balloon_lock(flags); + driver_pages += delta; /* non-atomic update */ + balloon_unlock(flags); } -void balloon_put_pages(unsigned long *mfn_list, unsigned long nr_mfns) +struct page *balloon_alloc_empty_page_range(unsigned long nr_pages) { - unsigned long flags; + int f(pte_t *pte, struct page *pte_page, + unsigned long addr, void *data) + { + unsigned long mfn = pte_mfn(*pte); + set_pte(pte, __pte_ma(0)); + phys_to_machine_mapping[__pa(addr) >> PAGE_SHIFT] = + INVALID_P2M_ENTRY; + BUG_ON(HYPERVISOR_dom_mem_op( + MEMOP_decrease_reservation, &mfn, 1, 0) != 1); + return 0; + } - balloon_lock(flags); - if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, - mfn_list, nr_mfns, 0) != nr_mfns ) - BUG(); - current_pages -= nr_mfns; /* non-atomic update */ - balloon_unlock(flags); + unsigned long vstart, flags; + unsigned int order = get_order(nr_pages * PAGE_SIZE); - schedule_work(&balloon_worker); + vstart = __get_free_pages(GFP_KERNEL, order); + if (vstart == 0) + return NULL; + + scrub_pages(vstart, 1 << order); + + balloon_lock(flags); + BUG_ON(generic_page_range( + &init_mm, vstart, PAGE_SIZE << order, f, NULL) != 0); + current_pages -= 1UL << order; + balloon_unlock(flags); + + schedule_work(&balloon_worker); + + flush_tlb_all(); + + return virt_to_page(vstart); +} + +void balloon_dealloc_empty_page_range( + struct page *page, unsigned long nr_pages) +{ + unsigned long i, flags; + unsigned int order = get_order(nr_pages * PAGE_SIZE); + + balloon_lock(flags); + for (i = 0; i < (1UL << order); i++) + balloon_append(page + i); + balloon_unlock(flags); + + schedule_work(&balloon_worker); } EXPORT_SYMBOL(balloon_update_driver_allowance); -EXPORT_SYMBOL(balloon_put_pages); +EXPORT_SYMBOL(balloon_alloc_empty_page_range); +EXPORT_SYMBOL(balloon_dealloc_empty_page_range); + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ 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 d8378bd3f0..40155615c1 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c @@ -569,6 +569,7 @@ void blkif_deschedule(blkif_t *blkif) static int __init blkif_init(void) { int i; + struct page *page; if ( !(xen_start_info.flags & SIF_INITDOMAIN) && !(xen_start_info.flags & SIF_BLK_BE_DOMAIN) ) @@ -576,8 +577,9 @@ static int __init blkif_init(void) blkif_interface_init(); - if ( (mmap_vstart = allocate_empty_lowmem_region(MMAP_PAGES)) == 0 ) - BUG(); + page = balloon_alloc_empty_page_range(MMAP_PAGES); + BUG_ON(page == NULL); + mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); pending_cons = 0; pending_prod = MAX_PENDING_REQS; diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c index 3b9089228d..4c06b3e6c4 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap_userdev.c @@ -775,9 +775,11 @@ static struct miscdevice blktap_miscdev = { int blktap_init(void) { int err, i, j; + struct page *page; - if ( (mmap_vstart = allocate_empty_lowmem_region(MMAP_PAGES)) == 0 ) - BUG(); + page = balloon_alloc_empty_page_range(MMAP_PAGES); + BUG_ON(page == NULL); + mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); #ifdef CONFIG_XEN_BLKDEV_GRANT for (i=0; i #if defined(CONFIG_X86_64)