[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH] xen/x86: Force removal of memory range when not covered by MTRRs



>>> On 14.02.13 at 18:11, Stefan Bader <stefan.bader@xxxxxxxxxxxxx> wrote:
> On a machine that could not cover all its RAM with MTRR ranges,
> a crash on boot as dom0 was caused by dom0 trying to create
> kernel mapping tables for the clipped range.
> 
> (XEN) WARNING: MTRRs do not cover all of memory.
> (XEN) Truncating RAM from 9109504kB to 9043968kB
> ...
> (XEN)  0000000228000000 - 000000022c000000 (unusable)
> ...
> [    0.000000] init_memory_mapping: 0000000228000000-000000022c000000
> [    0.000000]  0228000000 - 022c000000 page 4k
> [    0.000000] kernel direct mapping tables up to 22c000000 @
>                1e97d8000-1e97fa000
> (XEN) mm.c:825:d0 Non-privileged (0) attempt to map I/O space 00228000
> (XEN) mm.c:1222:d0 Failure in alloc_l1_table: entry 0
> (XEN) mm.c:2177:d0 Error while validating mfn 81de (pfn 1e97d8) for
>       type 1000000000000000: caf=8000000000000003 taf=1000000000000001
> (XEN) mm.c:2985:d0 Error while pinning mfn 81de
> 
> Setting the range in E820 to E280_UNUSABLE seems ambigous as
> this is the same type that gets used for memory to be used only
> as guest memory (using dom0_mem=).

Since when is E820_UNUSABLE memory being used as guest
memory? If that's indeed the case, that's the bug to fix. The
above data to me shows, however, that the range above
228000000 is considered invalid. So then the question is why the
kernel tries to map that memory in the first place (the hypervisor
rejecting the attempt, despite Dom0 being privileged, seems
correct to me, as the range is also known not to be MMIO).

> To avoid this, the clipped memory should be dropped completely
> from E820 (as it is done if setting the memory type fails).
> This is currently restricted to only the case of memory not
> coverable by MTRRs (which could be tested). Maybe it should
> be done in other cases, too.

No, that's wrong. When dropping the range completely, the
Dom0 kernel then could allocate MMIO resources in that address
range, and the devices using those MMIO resources then would
not work.

Bottom line - I think this needs to be fixed in the kernel.

Jan

> BugLink: http://bugs.launchpad.net/bugs/1111470 
> 
> Signed-off-by: Stefan Bader <stefan.bader@xxxxxxxxxxxxx>
> CC: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
> ---
>  xen/arch/x86/e820.c |   13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/xen/arch/x86/e820.c b/xen/arch/x86/e820.c
> index 55fe0d6..8dfe427 100644
> --- a/xen/arch/x86/e820.c
> +++ b/xen/arch/x86/e820.c
> @@ -372,7 +372,7 @@ static unsigned long __init find_max_pfn(void)
>      return max_pfn;
>  }
>  
> -static void __init clip_to_limit(uint64_t limit, char *warnmsg)
> +static void __init clip_to_limit(uint64_t limit, char *warnmsg, int drop)
>  {
>      int i;
>      char _warnmsg[160];
> @@ -394,7 +394,8 @@ static void __init clip_to_limit(uint64_t limit, char 
> *warnmsg)
>              uint64_t, old_limit, e820.map[i].addr + e820.map[i].size);
>  
>          /* We try to convert clipped RAM areas to E820_UNUSABLE. */
> -        if ( e820_change_range_type(&e820, max(e820.map[i].addr, limit),
> +        if ( !drop &&
> +             e820_change_range_type(&e820, max(e820.map[i].addr, limit),
>                                      e820.map[i].addr + e820.map[i].size,
>                                      E820_RAM, E820_UNUSABLE) )
>              continue;
> @@ -524,7 +525,7 @@ static void __init machine_specific_memory_setup(
>      (void)copy_e820_map(raw, nr);
>  
>      if ( opt_mem )
> -        clip_to_limit(opt_mem, NULL);
> +        clip_to_limit(opt_mem, NULL, 0);
>  
>      if ( opt_availmem )
>      {
> @@ -534,7 +535,7 @@ static void __init machine_specific_memory_setup(
>          if ( size > opt_availmem )
>              clip_to_limit(
>                  e820.map[i-1].addr + e820.map[i-1].size - 
> (size-opt_availmem),
> -                NULL);
> +                NULL, 0);
>      }
>  
>      mpt_limit = ((RDWR_MPT_VIRT_END - RDWR_MPT_VIRT_START)
> @@ -545,13 +546,13 @@ static void __init machine_specific_memory_setup(
>          mpt_limit = ro_mpt_limit;
>      clip_to_limit(mpt_limit,
>                    "Only the first %lu GB of the physical "
> -                  "memory map can be accessed by Xen.");
> +                  "memory map can be accessed by Xen.", 0);
>  
>      reserve_dmi_region();
>  
>      top_of_ram = mtrr_top_of_ram();
>      if ( top_of_ram )
> -        clip_to_limit(top_of_ram, "MTRRs do not cover all of memory.");
> +        clip_to_limit(top_of_ram, "MTRRs do not cover all of memory.", 1);
>  }
>  
>  /* This function relies on the passed in e820->map[] being sorted. */
> -- 
> 1.7.9.5
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx 
> http://lists.xen.org/xen-devel 



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.