aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt14
-rw-r--r--arch/x86/kernel/setup.c21
-rw-r--r--include/linux/swiotlb.h1
-rw-r--r--lib/swiotlb.c19
4 files changed, 45 insertions, 10 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 4609e81dbc37..cff672da2486 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -596,9 +596,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
596 is selected automatically. Check 596 is selected automatically. Check
597 Documentation/kdump/kdump.txt for further details. 597 Documentation/kdump/kdump.txt for further details.
598 598
599 crashkernel_low=size[KMG]
600 [KNL, x86] parts under 4G.
601
602 crashkernel=range1:size1[,range2:size2,...][@offset] 599 crashkernel=range1:size1[,range2:size2,...][@offset]
603 [KNL] Same as above, but depends on the memory 600 [KNL] Same as above, but depends on the memory
604 in the running system. The syntax of range is 601 in the running system. The syntax of range is
@@ -606,6 +603,17 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
606 a memory unit (amount[KMG]). See also 603 a memory unit (amount[KMG]). See also
607 Documentation/kdump/kdump.txt for an example. 604 Documentation/kdump/kdump.txt for an example.
608 605
606 crashkernel_low=size[KMG]
607 [KNL, x86_64] range under 4G. When crashkernel= is
608 passed, kernel allocate physical memory region
609 above 4G, that cause second kernel crash on system
610 that require some amount of low memory, e.g. swiotlb
611 requires at least 64M+32K low memory. Kernel would
612 try to allocate 72M below 4G automatically.
613 This one let user to specify own low range under 4G
614 for second kernel instead.
615 0: to disable low allocation.
616
609 cs89x0_dma= [HW,NET] 617 cs89x0_dma= [HW,NET]
610 Format: <dma> 618 Format: <dma>
611 619
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 90d8cc930f5e..12349202cae7 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -521,19 +521,34 @@ static void __init reserve_crashkernel_low(void)
521 unsigned long long low_base = 0, low_size = 0; 521 unsigned long long low_base = 0, low_size = 0;
522 unsigned long total_low_mem; 522 unsigned long total_low_mem;
523 unsigned long long base; 523 unsigned long long base;
524 bool auto_set = false;
524 int ret; 525 int ret;
525 526
526 total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT)); 527 total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT));
527 ret = parse_crashkernel_low(boot_command_line, total_low_mem, 528 ret = parse_crashkernel_low(boot_command_line, total_low_mem,
528 &low_size, &base); 529 &low_size, &base);
529 if (ret != 0 || low_size <= 0) 530 if (ret != 0) {
530 return; 531 /*
532 * two parts from lib/swiotlb.c:
533 * swiotlb size: user specified with swiotlb= or default.
534 * swiotlb overflow buffer: now is hardcoded to 32k.
535 * We round it to 8M for other buffers that
536 * may need to stay low too.
537 */
538 low_size = swiotlb_size_or_default() + (8UL<<20);
539 auto_set = true;
540 } else {
541 /* passed with crashkernel_low=0 ? */
542 if (!low_size)
543 return;
544 }
531 545
532 low_base = memblock_find_in_range(low_size, (1ULL<<32), 546 low_base = memblock_find_in_range(low_size, (1ULL<<32),
533 low_size, alignment); 547 low_size, alignment);
534 548
535 if (!low_base) { 549 if (!low_base) {
536 pr_info("crashkernel low reservation failed - No suitable area found.\n"); 550 if (!auto_set)
551 pr_info("crashkernel low reservation failed - No suitable area found.\n");
537 552
538 return; 553 return;
539 } 554 }
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 2de42f9401d2..a5ffd32642fd 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -25,6 +25,7 @@ extern int swiotlb_force;
25extern void swiotlb_init(int verbose); 25extern void swiotlb_init(int verbose);
26int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose); 26int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose);
27extern unsigned long swiotlb_nr_tbl(void); 27extern unsigned long swiotlb_nr_tbl(void);
28unsigned long swiotlb_size_or_default(void);
28extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs); 29extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs);
29 30
30/* 31/*
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index bfe02b8fc55b..d23762e6652c 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -105,9 +105,9 @@ setup_io_tlb_npages(char *str)
105 if (!strcmp(str, "force")) 105 if (!strcmp(str, "force"))
106 swiotlb_force = 1; 106 swiotlb_force = 1;
107 107
108 return 1; 108 return 0;
109} 109}
110__setup("swiotlb=", setup_io_tlb_npages); 110early_param("swiotlb", setup_io_tlb_npages);
111/* make io_tlb_overflow tunable too? */ 111/* make io_tlb_overflow tunable too? */
112 112
113unsigned long swiotlb_nr_tbl(void) 113unsigned long swiotlb_nr_tbl(void)
@@ -115,6 +115,18 @@ unsigned long swiotlb_nr_tbl(void)
115 return io_tlb_nslabs; 115 return io_tlb_nslabs;
116} 116}
117EXPORT_SYMBOL_GPL(swiotlb_nr_tbl); 117EXPORT_SYMBOL_GPL(swiotlb_nr_tbl);
118
119/* default to 64MB */
120#define IO_TLB_DEFAULT_SIZE (64UL<<20)
121unsigned long swiotlb_size_or_default(void)
122{
123 unsigned long size;
124
125 size = io_tlb_nslabs << IO_TLB_SHIFT;
126
127 return size ? size : (IO_TLB_DEFAULT_SIZE);
128}
129
118/* Note that this doesn't work with highmem page */ 130/* Note that this doesn't work with highmem page */
119static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, 131static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev,
120 volatile void *address) 132 volatile void *address)
@@ -188,8 +200,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
188void __init 200void __init
189swiotlb_init(int verbose) 201swiotlb_init(int verbose)
190{ 202{
191 /* default to 64MB */ 203 size_t default_size = IO_TLB_DEFAULT_SIZE;
192 size_t default_size = 64UL<<20;
193 unsigned char *vstart; 204 unsigned char *vstart;
194 unsigned long bytes; 205 unsigned long bytes;
195 206