diff options
Diffstat (limited to 'arch/x86/mm/pat.c')
-rw-r--r-- | arch/x86/mm/pat.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 8b08fb955274..7b61036427df 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -333,11 +333,23 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, | |||
333 | req_type & _PAGE_CACHE_MASK); | 333 | req_type & _PAGE_CACHE_MASK); |
334 | } | 334 | } |
335 | 335 | ||
336 | is_range_ram = pagerange_is_ram(start, end); | 336 | if (new_type) |
337 | if (is_range_ram == 1) | 337 | *new_type = actual_type; |
338 | return reserve_ram_pages_type(start, end, req_type, new_type); | 338 | |
339 | else if (is_range_ram < 0) | 339 | /* |
340 | return -EINVAL; | 340 | * For legacy reasons, some parts of the physical address range in the |
341 | * legacy 1MB region is treated as non-RAM (even when listed as RAM in | ||
342 | * the e820 tables). So we will track the memory attributes of this | ||
343 | * legacy 1MB region using the linear memtype_list always. | ||
344 | */ | ||
345 | if (end >= ISA_END_ADDRESS) { | ||
346 | is_range_ram = pagerange_is_ram(start, end); | ||
347 | if (is_range_ram == 1) | ||
348 | return reserve_ram_pages_type(start, end, req_type, | ||
349 | new_type); | ||
350 | else if (is_range_ram < 0) | ||
351 | return -EINVAL; | ||
352 | } | ||
341 | 353 | ||
342 | new = kmalloc(sizeof(struct memtype), GFP_KERNEL); | 354 | new = kmalloc(sizeof(struct memtype), GFP_KERNEL); |
343 | if (!new) | 355 | if (!new) |
@@ -347,9 +359,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, | |||
347 | new->end = end; | 359 | new->end = end; |
348 | new->type = actual_type; | 360 | new->type = actual_type; |
349 | 361 | ||
350 | if (new_type) | ||
351 | *new_type = actual_type; | ||
352 | |||
353 | spin_lock(&memtype_lock); | 362 | spin_lock(&memtype_lock); |
354 | 363 | ||
355 | if (cached_entry && start >= cached_start) | 364 | if (cached_entry && start >= cached_start) |
@@ -437,11 +446,19 @@ int free_memtype(u64 start, u64 end) | |||
437 | if (is_ISA_range(start, end - 1)) | 446 | if (is_ISA_range(start, end - 1)) |
438 | return 0; | 447 | return 0; |
439 | 448 | ||
440 | is_range_ram = pagerange_is_ram(start, end); | 449 | /* |
441 | if (is_range_ram == 1) | 450 | * For legacy reasons, some parts of the physical address range in the |
442 | return free_ram_pages_type(start, end); | 451 | * legacy 1MB region is treated as non-RAM (even when listed as RAM in |
443 | else if (is_range_ram < 0) | 452 | * the e820 tables). So we will track the memory attributes of this |
444 | return -EINVAL; | 453 | * legacy 1MB region using the linear memtype_list always. |
454 | */ | ||
455 | if (end >= ISA_END_ADDRESS) { | ||
456 | is_range_ram = pagerange_is_ram(start, end); | ||
457 | if (is_range_ram == 1) | ||
458 | return free_ram_pages_type(start, end); | ||
459 | else if (is_range_ram < 0) | ||
460 | return -EINVAL; | ||
461 | } | ||
445 | 462 | ||
446 | spin_lock(&memtype_lock); | 463 | spin_lock(&memtype_lock); |
447 | list_for_each_entry(entry, &memtype_list, nd) { | 464 | list_for_each_entry(entry, &memtype_list, nd) { |