aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers/char/console.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-04-22 17:43:56 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-04-22 17:43:56 +0100
commitb5e0c9e2a3036937647f2f3e47275fde00415087 (patch)
treebe5735975e2394f7af0bfe1df15e3bedcd286746 /xen/drivers/char/console.c
parent3dc27ee3852c9803ee87ff93224f0f33a49096ab (diff)
downloadxen-b5e0c9e2a3036937647f2f3e47275fde00415087.tar.gz
xen-b5e0c9e2a3036937647f2f3e47275fde00415087.tar.bz2
xen-b5e0c9e2a3036937647f2f3e47275fde00415087.zip
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 <keir.fraser@citrix.com>
Diffstat (limited to 'xen/drivers/char/console.c')
-rw-r--r--xen/drivers/char/console.c27
1 files changed, 8 insertions, 19 deletions
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)