debuggers.hg

changeset 21271:2b97855a629f

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>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Apr 22 17:43:56 2010 +0100 (2010-04-22)
parents a7947fd90328
children 7f3eff15050c
files xen/drivers/char/console.c
line diff
     1.1 --- a/xen/drivers/char/console.c	Thu Apr 22 09:44:29 2010 +0100
     1.2 +++ b/xen/drivers/char/console.c	Thu Apr 22 17:43:56 2010 +0100
     1.3 @@ -66,11 +66,7 @@ size_param("conring_size", opt_conring_s
     1.4  
     1.5  #define _CONRING_SIZE 16384
     1.6  #define CONRING_IDX_MASK(i) ((i)&(conring_size-1))
     1.7 -static char
     1.8 -#if _CONRING_SIZE >= PAGE_SIZE
     1.9 -    __attribute__((__section__(".bss.page_aligned"), __aligned__(PAGE_SIZE)))
    1.10 -#endif
    1.11 -    _conring[_CONRING_SIZE];
    1.12 +static char __initdata _conring[_CONRING_SIZE];
    1.13  static char *__read_mostly conring = _conring;
    1.14  static uint32_t __read_mostly conring_size = _CONRING_SIZE;
    1.15  static uint32_t conringc, conringp;
    1.16 @@ -597,25 +593,20 @@ void __init console_init_preirq(void)
    1.17  void __init console_init_postirq(void)
    1.18  {
    1.19      char *ring;
    1.20 -    unsigned int i;
    1.21 +    unsigned int i, order;
    1.22  
    1.23      serial_init_postirq();
    1.24  
    1.25      if ( !opt_conring_size )
    1.26          opt_conring_size = num_present_cpus() << (9 + xenlog_lower_thresh);
    1.27 -    /* Round size down to a power of two. */
    1.28 -    while ( opt_conring_size & (opt_conring_size - 1) )
    1.29 -        opt_conring_size &= opt_conring_size - 1;
    1.30 -    if ( opt_conring_size < conring_size )
    1.31 -        return;
    1.32 -    
    1.33 -    ring = alloc_xenheap_pages(get_order_from_bytes(opt_conring_size), 0);
    1.34 -    if ( ring == NULL )
    1.35 +
    1.36 +    order = get_order_from_bytes(max(opt_conring_size, conring_size));
    1.37 +    while ( (ring = alloc_xenheap_pages(order, 0)) == NULL )
    1.38      {
    1.39 -        printk("Unable to allocate console ring of %u bytes.\n",
    1.40 -               opt_conring_size);
    1.41 -        return;
    1.42 +        BUG_ON(order == 0);
    1.43 +        order--;
    1.44      }
    1.45 +    opt_conring_size = PAGE_SIZE << order;
    1.46  
    1.47      spin_lock_irq(&console_lock);
    1.48      for ( i = conringc ; i != conringp; i++ )
    1.49 @@ -626,8 +617,6 @@ void __init console_init_postirq(void)
    1.50      spin_unlock_irq(&console_lock);
    1.51  
    1.52      printk("Allocated console ring of %u KiB.\n", opt_conring_size >> 10);
    1.53 -
    1.54 -    init_xenheap_pages(__pa(_conring), __pa(_conring + _CONRING_SIZE));
    1.55  }
    1.56  
    1.57  void __init console_endboot(void)