From: Keir Fraser Date: Thu, 22 Apr 2010 16:43:56 +0000 (+0100) Subject: console: Make initial static console buffer __initdata. X-Git-Tag: 4.1.0-rc1~1391 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=b5e0c9e2a3036937647f2f3e47275fde00415087;p=xen.git console: Make initial static console buffer __initdata. The previous scheme --- freeing an area of BSS --- did not interact nicely with device passthrough as IOMMU will not have any Xen BSS area in guest device pagetables. Hence if the freed BSS space gets allocated to a guest, DMAs to guest's own memory can fail. The simple solution here is to always free the static buffer at end of boot (initmem is specially handled for IOMMUs) and require a dynamically-allocated buffer always to be created. Signed-off-by: Keir Fraser --- diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 354ff86b73..993532c9e8 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -66,11 +66,7 @@ size_param("conring_size", opt_conring_size); #define _CONRING_SIZE 16384 #define CONRING_IDX_MASK(i) ((i)&(conring_size-1)) -static char -#if _CONRING_SIZE >= PAGE_SIZE - __attribute__((__section__(".bss.page_aligned"), __aligned__(PAGE_SIZE))) -#endif - _conring[_CONRING_SIZE]; +static char __initdata _conring[_CONRING_SIZE]; static char *__read_mostly conring = _conring; static uint32_t __read_mostly conring_size = _CONRING_SIZE; static uint32_t conringc, conringp; @@ -597,25 +593,20 @@ void __init console_init_preirq(void) void __init console_init_postirq(void) { char *ring; - unsigned int i; + unsigned int i, order; serial_init_postirq(); if ( !opt_conring_size ) opt_conring_size = num_present_cpus() << (9 + xenlog_lower_thresh); - /* Round size down to a power of two. */ - while ( opt_conring_size & (opt_conring_size - 1) ) - opt_conring_size &= opt_conring_size - 1; - if ( opt_conring_size < conring_size ) - return; - - ring = alloc_xenheap_pages(get_order_from_bytes(opt_conring_size), 0); - if ( ring == NULL ) + + order = get_order_from_bytes(max(opt_conring_size, conring_size)); + while ( (ring = alloc_xenheap_pages(order, 0)) == NULL ) { - printk("Unable to allocate console ring of %u bytes.\n", - opt_conring_size); - return; + BUG_ON(order == 0); + order--; } + opt_conring_size = PAGE_SIZE << order; spin_lock_irq(&console_lock); for ( i = conringc ; i != conringp; i++ ) @@ -626,8 +617,6 @@ void __init console_init_postirq(void) spin_unlock_irq(&console_lock); printk("Allocated console ring of %u KiB.\n", opt_conring_size >> 10); - - init_xenheap_pages(__pa(_conring), __pa(_conring + _CONRING_SIZE)); } void __init console_endboot(void)