diff options
Diffstat (limited to 'arch/x86/xen/setup.c')
-rw-r--r-- | arch/x86/xen/setup.c | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index dfd77dec8e2b..865e56cea7a0 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -140,7 +140,7 @@ static void __init xen_del_extra_mem(u64 start, u64 size) | |||
140 | unsigned long __ref xen_chk_extra_mem(unsigned long pfn) | 140 | unsigned long __ref xen_chk_extra_mem(unsigned long pfn) |
141 | { | 141 | { |
142 | int i; | 142 | int i; |
143 | unsigned long addr = PFN_PHYS(pfn); | 143 | phys_addr_t addr = PFN_PHYS(pfn); |
144 | 144 | ||
145 | for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { | 145 | for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { |
146 | if (addr >= xen_extra_mem[i].start && | 146 | if (addr >= xen_extra_mem[i].start && |
@@ -160,6 +160,8 @@ void __init xen_inv_extra_mem(void) | |||
160 | int i; | 160 | int i; |
161 | 161 | ||
162 | for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { | 162 | for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { |
163 | if (!xen_extra_mem[i].size) | ||
164 | continue; | ||
163 | pfn_s = PFN_DOWN(xen_extra_mem[i].start); | 165 | pfn_s = PFN_DOWN(xen_extra_mem[i].start); |
164 | pfn_e = PFN_UP(xen_extra_mem[i].start + xen_extra_mem[i].size); | 166 | pfn_e = PFN_UP(xen_extra_mem[i].start + xen_extra_mem[i].size); |
165 | for (pfn = pfn_s; pfn < pfn_e; pfn++) | 167 | for (pfn = pfn_s; pfn < pfn_e; pfn++) |
@@ -229,15 +231,14 @@ static int __init xen_free_mfn(unsigned long mfn) | |||
229 | * as a fallback if the remapping fails. | 231 | * as a fallback if the remapping fails. |
230 | */ | 232 | */ |
231 | static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn, | 233 | static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn, |
232 | unsigned long end_pfn, unsigned long nr_pages, unsigned long *identity, | 234 | unsigned long end_pfn, unsigned long nr_pages, unsigned long *released) |
233 | unsigned long *released) | ||
234 | { | 235 | { |
235 | unsigned long len = 0; | ||
236 | unsigned long pfn, end; | 236 | unsigned long pfn, end; |
237 | int ret; | 237 | int ret; |
238 | 238 | ||
239 | WARN_ON(start_pfn > end_pfn); | 239 | WARN_ON(start_pfn > end_pfn); |
240 | 240 | ||
241 | /* Release pages first. */ | ||
241 | end = min(end_pfn, nr_pages); | 242 | end = min(end_pfn, nr_pages); |
242 | for (pfn = start_pfn; pfn < end; pfn++) { | 243 | for (pfn = start_pfn; pfn < end; pfn++) { |
243 | unsigned long mfn = pfn_to_mfn(pfn); | 244 | unsigned long mfn = pfn_to_mfn(pfn); |
@@ -250,16 +251,14 @@ static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn, | |||
250 | WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret); | 251 | WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret); |
251 | 252 | ||
252 | if (ret == 1) { | 253 | if (ret == 1) { |
254 | (*released)++; | ||
253 | if (!__set_phys_to_machine(pfn, INVALID_P2M_ENTRY)) | 255 | if (!__set_phys_to_machine(pfn, INVALID_P2M_ENTRY)) |
254 | break; | 256 | break; |
255 | len++; | ||
256 | } else | 257 | } else |
257 | break; | 258 | break; |
258 | } | 259 | } |
259 | 260 | ||
260 | /* Need to release pages first */ | 261 | set_phys_range_identity(start_pfn, end_pfn); |
261 | *released += len; | ||
262 | *identity += set_phys_range_identity(start_pfn, end_pfn); | ||
263 | } | 262 | } |
264 | 263 | ||
265 | /* | 264 | /* |
@@ -287,7 +286,7 @@ static void __init xen_update_mem_tables(unsigned long pfn, unsigned long mfn) | |||
287 | } | 286 | } |
288 | 287 | ||
289 | /* Update kernel mapping, but not for highmem. */ | 288 | /* Update kernel mapping, but not for highmem. */ |
290 | if ((pfn << PAGE_SHIFT) >= __pa(high_memory)) | 289 | if (pfn >= PFN_UP(__pa(high_memory - 1))) |
291 | return; | 290 | return; |
292 | 291 | ||
293 | if (HYPERVISOR_update_va_mapping((unsigned long)__va(pfn << PAGE_SHIFT), | 292 | if (HYPERVISOR_update_va_mapping((unsigned long)__va(pfn << PAGE_SHIFT), |
@@ -318,7 +317,6 @@ static void __init xen_do_set_identity_and_remap_chunk( | |||
318 | unsigned long ident_pfn_iter, remap_pfn_iter; | 317 | unsigned long ident_pfn_iter, remap_pfn_iter; |
319 | unsigned long ident_end_pfn = start_pfn + size; | 318 | unsigned long ident_end_pfn = start_pfn + size; |
320 | unsigned long left = size; | 319 | unsigned long left = size; |
321 | unsigned long ident_cnt = 0; | ||
322 | unsigned int i, chunk; | 320 | unsigned int i, chunk; |
323 | 321 | ||
324 | WARN_ON(size == 0); | 322 | WARN_ON(size == 0); |
@@ -347,8 +345,7 @@ static void __init xen_do_set_identity_and_remap_chunk( | |||
347 | xen_remap_mfn = mfn; | 345 | xen_remap_mfn = mfn; |
348 | 346 | ||
349 | /* Set identity map */ | 347 | /* Set identity map */ |
350 | ident_cnt += set_phys_range_identity(ident_pfn_iter, | 348 | set_phys_range_identity(ident_pfn_iter, ident_pfn_iter + chunk); |
351 | ident_pfn_iter + chunk); | ||
352 | 349 | ||
353 | left -= chunk; | 350 | left -= chunk; |
354 | } | 351 | } |
@@ -371,7 +368,7 @@ static void __init xen_do_set_identity_and_remap_chunk( | |||
371 | static unsigned long __init xen_set_identity_and_remap_chunk( | 368 | static unsigned long __init xen_set_identity_and_remap_chunk( |
372 | const struct e820entry *list, size_t map_size, unsigned long start_pfn, | 369 | const struct e820entry *list, size_t map_size, unsigned long start_pfn, |
373 | unsigned long end_pfn, unsigned long nr_pages, unsigned long remap_pfn, | 370 | unsigned long end_pfn, unsigned long nr_pages, unsigned long remap_pfn, |
374 | unsigned long *identity, unsigned long *released) | 371 | unsigned long *released, unsigned long *remapped) |
375 | { | 372 | { |
376 | unsigned long pfn; | 373 | unsigned long pfn; |
377 | unsigned long i = 0; | 374 | unsigned long i = 0; |
@@ -386,8 +383,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk( | |||
386 | /* Do not remap pages beyond the current allocation */ | 383 | /* Do not remap pages beyond the current allocation */ |
387 | if (cur_pfn >= nr_pages) { | 384 | if (cur_pfn >= nr_pages) { |
388 | /* Identity map remaining pages */ | 385 | /* Identity map remaining pages */ |
389 | *identity += set_phys_range_identity(cur_pfn, | 386 | set_phys_range_identity(cur_pfn, cur_pfn + size); |
390 | cur_pfn + size); | ||
391 | break; | 387 | break; |
392 | } | 388 | } |
393 | if (cur_pfn + size > nr_pages) | 389 | if (cur_pfn + size > nr_pages) |
@@ -398,7 +394,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk( | |||
398 | if (!remap_range_size) { | 394 | if (!remap_range_size) { |
399 | pr_warning("Unable to find available pfn range, not remapping identity pages\n"); | 395 | pr_warning("Unable to find available pfn range, not remapping identity pages\n"); |
400 | xen_set_identity_and_release_chunk(cur_pfn, | 396 | xen_set_identity_and_release_chunk(cur_pfn, |
401 | cur_pfn + left, nr_pages, identity, released); | 397 | cur_pfn + left, nr_pages, released); |
402 | break; | 398 | break; |
403 | } | 399 | } |
404 | /* Adjust size to fit in current e820 RAM region */ | 400 | /* Adjust size to fit in current e820 RAM region */ |
@@ -410,7 +406,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk( | |||
410 | /* Update variables to reflect new mappings. */ | 406 | /* Update variables to reflect new mappings. */ |
411 | i += size; | 407 | i += size; |
412 | remap_pfn += size; | 408 | remap_pfn += size; |
413 | *identity += size; | 409 | *remapped += size; |
414 | } | 410 | } |
415 | 411 | ||
416 | /* | 412 | /* |
@@ -427,13 +423,13 @@ static unsigned long __init xen_set_identity_and_remap_chunk( | |||
427 | 423 | ||
428 | static void __init xen_set_identity_and_remap( | 424 | static void __init xen_set_identity_and_remap( |
429 | const struct e820entry *list, size_t map_size, unsigned long nr_pages, | 425 | const struct e820entry *list, size_t map_size, unsigned long nr_pages, |
430 | unsigned long *released) | 426 | unsigned long *released, unsigned long *remapped) |
431 | { | 427 | { |
432 | phys_addr_t start = 0; | 428 | phys_addr_t start = 0; |
433 | unsigned long identity = 0; | ||
434 | unsigned long last_pfn = nr_pages; | 429 | unsigned long last_pfn = nr_pages; |
435 | const struct e820entry *entry; | 430 | const struct e820entry *entry; |
436 | unsigned long num_released = 0; | 431 | unsigned long num_released = 0; |
432 | unsigned long num_remapped = 0; | ||
437 | int i; | 433 | int i; |
438 | 434 | ||
439 | /* | 435 | /* |
@@ -460,14 +456,14 @@ static void __init xen_set_identity_and_remap( | |||
460 | last_pfn = xen_set_identity_and_remap_chunk( | 456 | last_pfn = xen_set_identity_and_remap_chunk( |
461 | list, map_size, start_pfn, | 457 | list, map_size, start_pfn, |
462 | end_pfn, nr_pages, last_pfn, | 458 | end_pfn, nr_pages, last_pfn, |
463 | &identity, &num_released); | 459 | &num_released, &num_remapped); |
464 | start = end; | 460 | start = end; |
465 | } | 461 | } |
466 | } | 462 | } |
467 | 463 | ||
468 | *released = num_released; | 464 | *released = num_released; |
465 | *remapped = num_remapped; | ||
469 | 466 | ||
470 | pr_info("Set %ld page(s) to 1-1 mapping\n", identity); | ||
471 | pr_info("Released %ld page(s)\n", num_released); | 467 | pr_info("Released %ld page(s)\n", num_released); |
472 | } | 468 | } |
473 | 469 | ||
@@ -586,6 +582,7 @@ char * __init xen_memory_setup(void) | |||
586 | struct xen_memory_map memmap; | 582 | struct xen_memory_map memmap; |
587 | unsigned long max_pages; | 583 | unsigned long max_pages; |
588 | unsigned long extra_pages = 0; | 584 | unsigned long extra_pages = 0; |
585 | unsigned long remapped_pages; | ||
589 | int i; | 586 | int i; |
590 | int op; | 587 | int op; |
591 | 588 | ||
@@ -635,9 +632,10 @@ char * __init xen_memory_setup(void) | |||
635 | * underlying RAM. | 632 | * underlying RAM. |
636 | */ | 633 | */ |
637 | xen_set_identity_and_remap(map, memmap.nr_entries, max_pfn, | 634 | xen_set_identity_and_remap(map, memmap.nr_entries, max_pfn, |
638 | &xen_released_pages); | 635 | &xen_released_pages, &remapped_pages); |
639 | 636 | ||
640 | extra_pages += xen_released_pages; | 637 | extra_pages += xen_released_pages; |
638 | extra_pages += remapped_pages; | ||
641 | 639 | ||
642 | /* | 640 | /* |
643 | * Clamp the amount of extra memory to a EXTRA_MEM_RATIO | 641 | * Clamp the amount of extra memory to a EXTRA_MEM_RATIO |