mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
bitkeeper revision 1.1155 (411350f1WPGKHyDE_nv5WX9LJBbaWg)
Add support for marking bad pages using the 'badpage=xxx' cmdline option when booting Xen.
This commit is contained in:
1 parent
82401cec24
commit
067b241269
6 files changed
+85
-48
No files matched your search
@@ -277,6 +277,13 @@ that may be able to help diagnose problems:
|
||||
|
||||
noht Disable Hyperthreading.
|
||||
|
||||
badpage=<page number>[,<page number>]*
|
||||
Specify a list of pages not to be allocated for use
|
||||
because they contain bad bytes. For example, if your
|
||||
memory tester says that byte 0x12345678 is bad, you would
|
||||
place 'badpage=0x12345' on Xen's command line (i.e., the
|
||||
last three digits of the byte address are not included!).
|
||||
|
||||
com1=<baud>,DPS[,<io_base>,<irq>]
|
||||
com2=<baud>,DPS[,<io_base>,<irq>]
|
||||
Xen supports up to two 16550-compatible serial ports.
|
||||
|
||||
@@ -223,6 +223,13 @@ The following is a list of command line arguments to pass to Xen:
|
||||
|
||||
noht Disable Hyperthreading.
|
||||
|
||||
badpage=<page number>[,<page number>]*
|
||||
Specify a list of pages not to be allocated for use
|
||||
because they contain bad bytes. For example, if your
|
||||
memory tester says that byte 0x12345678 is bad, you would
|
||||
place 'badpage=0x12345' on Xen's command line (i.e., the
|
||||
last three digits of the byte address are not included!).
|
||||
|
||||
com1=<baud>,DPS[,<io_base>,<irq>]
|
||||
com2=<baud>,DPS[,<io_base>,<irq>]
|
||||
Xen supports up to two 16550-compatible serial ports.
|
||||
|
||||
@@ -1140,6 +1140,14 @@ editting \path{grub.conf}.
|
||||
{\bf noht } \\
|
||||
Disable Hyperthreading. \\
|
||||
|
||||
{\bf badpage=$<$page number$>$[,$<$page number$>$] } \\
|
||||
Specify a list of pages not to be allocated for use
|
||||
because they contain bad bytes. For example, if your
|
||||
memory tester says that byte 0x12345678 is bad, you would
|
||||
place 'badpage=0x12345' on Xen's command line (i.e., the
|
||||
last three digits of the byte address are not
|
||||
included!). \\
|
||||
|
||||
{\bf com1=$<$baud$>$,DPS[,$<$io\_base$>$,$<$irq$>$] \\
|
||||
com2=$<$baud$>$,DPS[,$<$io\_base$>$,$<$irq$>$] } \\
|
||||
Xen supports up to two 16550-compatible serial ports.
|
||||
|
||||
+32
-21
@@ -91,32 +91,40 @@ char opt_nmi[10] = "dom0";
|
||||
#else
|
||||
char opt_nmi[10] = "fatal";
|
||||
#endif
|
||||
/*
|
||||
* Comma-separated list of hexadecimal page numbers containing bad bytes.
|
||||
* e.g. 'badpage=0x3f45,0x8a321'.
|
||||
*/
|
||||
char opt_badpage[100] = "";
|
||||
|
||||
static struct {
|
||||
unsigned char *name;
|
||||
enum { OPT_STR, OPT_UINT, OPT_BOOL } type;
|
||||
void *var;
|
||||
unsigned int len;
|
||||
} opts[] = {
|
||||
{ "console", OPT_STR, &opt_console },
|
||||
{ "conswitch", OPT_STR, &opt_conswitch },
|
||||
{ "com1", OPT_STR, &opt_com1 },
|
||||
{ "com2", OPT_STR, &opt_com2 },
|
||||
{ "dom0_mem", OPT_UINT, &opt_dom0_mem },
|
||||
{ "noht", OPT_BOOL, &opt_noht },
|
||||
{ "noacpi", OPT_BOOL, &opt_noacpi },
|
||||
{ "nosmp", OPT_BOOL, &opt_nosmp },
|
||||
{ "noreboot", OPT_BOOL, &opt_noreboot },
|
||||
{ "ignorebiostables", OPT_BOOL, &opt_ignorebiostables },
|
||||
{ "watchdog", OPT_BOOL, &opt_watchdog },
|
||||
{ "pdb", OPT_STR, &opt_pdb },
|
||||
{ "tbuf_size", OPT_UINT, &opt_tbuf_size },
|
||||
{ "sched", OPT_STR, &opt_sched },
|
||||
{ "physdev_dom0_hide", OPT_STR, &opt_physdev_dom0_hide },
|
||||
{ "leveltrigger", OPT_STR, &opt_leveltrigger },
|
||||
{ "edgetrigger", OPT_STR, &opt_edgetrigger },
|
||||
{ "xenheap_megabytes", OPT_UINT, &opt_xenheap_megabytes },
|
||||
{ "nmi", OPT_STR, &opt_nmi },
|
||||
{ NULL, 0, NULL }
|
||||
#define V(_x) &_x, sizeof(_x)
|
||||
{ "console", OPT_STR, V(opt_console) },
|
||||
{ "conswitch", OPT_STR, V(opt_conswitch) },
|
||||
{ "com1", OPT_STR, V(opt_com1) },
|
||||
{ "com2", OPT_STR, V(opt_com2) },
|
||||
{ "dom0_mem", OPT_UINT, V(opt_dom0_mem) },
|
||||
{ "noht", OPT_BOOL, V(opt_noht) },
|
||||
{ "noacpi", OPT_BOOL, V(opt_noacpi) },
|
||||
{ "nosmp", OPT_BOOL, V(opt_nosmp) },
|
||||
{ "noreboot", OPT_BOOL, V(opt_noreboot) },
|
||||
{ "ignorebiostables", OPT_BOOL, V(opt_ignorebiostables) },
|
||||
{ "watchdog", OPT_BOOL, V(opt_watchdog) },
|
||||
{ "pdb", OPT_STR, V(opt_pdb) },
|
||||
{ "tbuf_size", OPT_UINT, V(opt_tbuf_size) },
|
||||
{ "sched", OPT_STR, V(opt_sched) },
|
||||
{ "physdev_dom0_hide", OPT_STR, V(opt_physdev_dom0_hide) },
|
||||
{ "leveltrigger", OPT_STR, V(opt_leveltrigger) },
|
||||
{ "edgetrigger", OPT_STR, V(opt_edgetrigger) },
|
||||
{ "xenheap_megabytes", OPT_UINT, V(opt_xenheap_megabytes) },
|
||||
{ "nmi", OPT_STR, V(opt_nmi) },
|
||||
{ "badpage", OPT_STR, V(opt_badpage) },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -154,7 +162,10 @@ void cmain(multiboot_info_t *mbi)
|
||||
{
|
||||
case OPT_STR:
|
||||
if ( opt != NULL )
|
||||
strcpy(opts[i].var, opt);
|
||||
{
|
||||
strncpy(opts[i].var, opt, opts[i].len);
|
||||
((char *)opts[i].var)[opts[i].len-1] = '\0';
|
||||
}
|
||||
break;
|
||||
case OPT_UINT:
|
||||
if ( opt != NULL )
|
||||
|
||||
+30
-26
@@ -29,6 +29,7 @@
|
||||
#include <xen/slab.h>
|
||||
#include <xen/irq.h>
|
||||
|
||||
extern char opt_badpage[];
|
||||
|
||||
/*********************
|
||||
* ALLOCATION BITMAP
|
||||
@@ -137,7 +138,8 @@ unsigned long init_heap_allocator(
|
||||
unsigned long bitmap_start, unsigned long max_pages)
|
||||
{
|
||||
int i, j;
|
||||
unsigned long bitmap_size;
|
||||
unsigned long bitmap_size, bad_pfn;
|
||||
char *p;
|
||||
|
||||
memset(avail, 0, sizeof(avail));
|
||||
|
||||
@@ -155,40 +157,42 @@ unsigned long init_heap_allocator(
|
||||
/* All allocated by default. */
|
||||
memset(alloc_bitmap, ~0, bitmap_size);
|
||||
|
||||
/*
|
||||
* Process the bad-page list. Marking the page free in the bitmap will
|
||||
* indicate to init_heap_pages() that it should not be placed on the
|
||||
* buddy lists.
|
||||
*/
|
||||
p = opt_badpage;
|
||||
while ( *p != '\0' )
|
||||
{
|
||||
bad_pfn = simple_strtoul(p, &p, 0);
|
||||
|
||||
if ( *p == ',' )
|
||||
p++;
|
||||
else if ( *p != '\0' )
|
||||
break;
|
||||
|
||||
if ( (bad_pfn < max_pages) && allocated_in_map(bad_pfn) )
|
||||
{
|
||||
printk("Marking page %08lx as bad\n", bad_pfn);
|
||||
map_free(bad_pfn, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return bitmap_start + bitmap_size;
|
||||
}
|
||||
|
||||
/* Hand the specified arbitrary page range to the specified heap zone. */
|
||||
void init_heap_pages(int zone, struct pfn_info *pg, unsigned long nr_pages)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
unsigned long i, pfn = page_to_pfn(pg);
|
||||
|
||||
spin_lock_irqsave(&heap_lock, flags);
|
||||
|
||||
/* Free up the memory we've been given to play with. */
|
||||
map_free(page_to_pfn(pg), nr_pages);
|
||||
avail[zone] += nr_pages;
|
||||
|
||||
while ( nr_pages != 0 )
|
||||
/* Process each page in turn, skipping bad pages. */
|
||||
for ( i = 0; i < nr_pages; i++ )
|
||||
{
|
||||
/*
|
||||
* Next chunk is limited by alignment of pg, but also must not be
|
||||
* bigger than remaining bytes.
|
||||
*/
|
||||
for ( i = 0; i < MAX_ORDER; i++ )
|
||||
if ( ((page_to_pfn(pg) & (1 << i)) != 0) ||
|
||||
((1 << (i + 1)) > nr_pages) )
|
||||
break;
|
||||
|
||||
PFN_ORDER(pg) = i;
|
||||
list_add_tail(&pg->list, &heap[zone][i]);
|
||||
|
||||
pg += 1 << i;
|
||||
nr_pages -= 1 << i;
|
||||
if ( likely(allocated_in_map(pfn+i)) ) /* bad page? */
|
||||
free_heap_pages(zone, pg+i, 0);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&heap_lock, flags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <xen/string.h>
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define ASSERT(_p) if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , __LINE__, __FILE__); *(int*)0=0; }
|
||||
#define ASSERT(_p) if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s\n", #_p , __LINE__, __FILE__); *(int*)0=0; }
|
||||
#else
|
||||
#define ASSERT(_p) ((void)0)
|
||||
#endif
|
||||
|
||||