+6
-2
drivers/firmware/efi/efi.c
+6
-2
drivers/firmware/efi/efi.c
···
273
273
if (status == EFI_NOT_FOUND) {
274
274
break;
275
275
} else if (status == EFI_BUFFER_TOO_SMALL) {
276
-
name = krealloc(name, name_size, GFP_KERNEL);
277
-
if (!name)
276
+
efi_char16_t *name_tmp =
277
+
krealloc(name, name_size, GFP_KERNEL);
278
+
if (!name_tmp) {
279
+
kfree(name);
278
280
return -ENOMEM;
281
+
}
282
+
name = name_tmp;
279
283
continue;
280
284
}
281
285
+3
-4
drivers/firmware/efi/libstub/x86-stub.c
+3
-4
drivers/firmware/efi/libstub/x86-stub.c
···
605
605
break;
606
606
607
607
case EFI_UNACCEPTED_MEMORY:
608
-
if (!IS_ENABLED(CONFIG_UNACCEPTED_MEMORY)) {
609
-
efi_warn_once(
610
-
"The system has unaccepted memory, but kernel does not support it\nConsider enabling CONFIG_UNACCEPTED_MEMORY\n");
608
+
if (!IS_ENABLED(CONFIG_UNACCEPTED_MEMORY))
611
609
continue;
612
-
}
613
610
e820_type = E820_TYPE_RAM;
614
611
process_unaccepted_memory(d->phys_addr,
615
612
d->phys_addr + PAGE_SIZE * d->num_pages);
···
848
851
const struct linux_efi_initrd *initrd = NULL;
849
852
unsigned long kernel_entry;
850
853
efi_status_t status;
854
+
855
+
boot_params_pointer = boot_params;
851
856
852
857
efi_system_table = sys_table_arg;
853
858
/* Check if we were booted by the EFI firmware */
+2
drivers/firmware/efi/libstub/x86-stub.h
+2
drivers/firmware/efi/libstub/x86-stub.h
+60
-4
drivers/firmware/efi/unaccepted_memory.c
+60
-4
drivers/firmware/efi/unaccepted_memory.c
···
5
5
#include <linux/spinlock.h>
6
6
#include <asm/unaccepted_memory.h>
7
7
8
-
/* Protects unaccepted memory bitmap */
8
+
/* Protects unaccepted memory bitmap and accepting_list */
9
9
static DEFINE_SPINLOCK(unaccepted_memory_lock);
10
+
11
+
struct accept_range {
12
+
struct list_head list;
13
+
unsigned long start;
14
+
unsigned long end;
15
+
};
16
+
17
+
static LIST_HEAD(accepting_list);
10
18
11
19
/*
12
20
* accept_memory() -- Consult bitmap and accept the memory if needed.
···
32
24
{
33
25
struct efi_unaccepted_memory *unaccepted;
34
26
unsigned long range_start, range_end;
27
+
struct accept_range range, *entry;
35
28
unsigned long flags;
36
29
u64 unit_size;
37
30
···
87
78
if (end > unaccepted->size * unit_size * BITS_PER_BYTE)
88
79
end = unaccepted->size * unit_size * BITS_PER_BYTE;
89
80
90
-
range_start = start / unit_size;
91
-
81
+
range.start = start / unit_size;
82
+
range.end = DIV_ROUND_UP(end, unit_size);
83
+
retry:
92
84
spin_lock_irqsave(&unaccepted_memory_lock, flags);
85
+
86
+
/*
87
+
* Check if anybody works on accepting the same range of the memory.
88
+
*
89
+
* The check is done with unit_size granularity. It is crucial to catch
90
+
* all accept requests to the same unit_size block, even if they don't
91
+
* overlap on physical address level.
92
+
*/
93
+
list_for_each_entry(entry, &accepting_list, list) {
94
+
if (entry->end < range.start)
95
+
continue;
96
+
if (entry->start >= range.end)
97
+
continue;
98
+
99
+
/*
100
+
* Somebody else accepting the range. Or at least part of it.
101
+
*
102
+
* Drop the lock and retry until it is complete.
103
+
*/
104
+
spin_unlock_irqrestore(&unaccepted_memory_lock, flags);
105
+
goto retry;
106
+
}
107
+
108
+
/*
109
+
* Register that the range is about to be accepted.
110
+
* Make sure nobody else will accept it.
111
+
*/
112
+
list_add(&range.list, &accepting_list);
113
+
114
+
range_start = range.start;
93
115
for_each_set_bitrange_from(range_start, range_end, unaccepted->bitmap,
94
-
DIV_ROUND_UP(end, unit_size)) {
116
+
range.end) {
95
117
unsigned long phys_start, phys_end;
96
118
unsigned long len = range_end - range_start;
97
119
98
120
phys_start = range_start * unit_size + unaccepted->phys_base;
99
121
phys_end = range_end * unit_size + unaccepted->phys_base;
100
122
123
+
/*
124
+
* Keep interrupts disabled until the accept operation is
125
+
* complete in order to prevent deadlocks.
126
+
*
127
+
* Enabling interrupts before calling arch_accept_memory()
128
+
* creates an opportunity for an interrupt handler to request
129
+
* acceptance for the same memory. The handler will continuously
130
+
* spin with interrupts disabled, preventing other task from
131
+
* making progress with the acceptance process.
132
+
*/
133
+
spin_unlock(&unaccepted_memory_lock);
134
+
101
135
arch_accept_memory(phys_start, phys_end);
136
+
137
+
spin_lock(&unaccepted_memory_lock);
102
138
bitmap_clear(unaccepted->bitmap, range_start, len);
103
139
}
140
+
141
+
list_del(&range.list);
104
142
spin_unlock_irqrestore(&unaccepted_memory_lock, flags);
105
143
}
106
144