Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 and EFI fixes from Peter Anvin:
"Half of these are EFI-related:

The by far biggest change is the change to hold off the deletion of a
sysfs entry while a backend scan is in progress. This is to avoid
calling kmemdup() while under a spinlock.

The other major change is for each entry in the EFI pstore backend to
get a unique identifier, as required by the pstore filesystem proper.

The other changes are:

A fix to the recent consolidation and optimization of using "asm goto"
with read-modify-write operation, which broke the bitops; specifically
in such a way that we could end up generating invalid code.

A build hack to make sure we compile with -mno-sse. icc, and most
likely future versions of gcc, can generate SSE instructions unless we
tell it not to.

A comment-only patch to a change the was due in part to an unpublished
erratum; now when the erratum is published we want to add a comment
explaining why"

* 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/apic, doc: Justification for disabling IO APIC before Local APIC
x86, bitops: Correct the assembly constraints to testing bitops
x86-64, build: Always pass in -mno-sse
efi-pstore: Make efi-pstore return a unique id
x86/efi: Fix earlyprintk off-by-one bug
efivars, efi-pstore: Hold off deletion of sysfs entry until the scan is completed

+201 -37
+7 -1
arch/x86/Makefile
··· 31 31 32 32 KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return 33 33 34 + # Don't autogenerate SSE instructions 35 + KBUILD_CFLAGS += -mno-sse 36 + 34 37 # Never want PIC in a 32-bit kernel, prevent breakage with GCC built 35 38 # with nonstandard options 36 39 KBUILD_CFLAGS += -fno-pic ··· 60 57 KBUILD_AFLAGS += -m64 61 58 KBUILD_CFLAGS += -m64 62 59 60 + # Don't autogenerate SSE instructions 61 + KBUILD_CFLAGS += -mno-sse 62 + 63 63 # Use -mpreferred-stack-boundary=3 if supported. 64 - KBUILD_CFLAGS += $(call cc-option,-mno-sse -mpreferred-stack-boundary=3) 64 + KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3) 65 65 66 66 # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu) 67 67 cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
+2 -2
arch/x86/include/asm/atomic.h
··· 77 77 */ 78 78 static inline int atomic_sub_and_test(int i, atomic_t *v) 79 79 { 80 - GEN_BINARY_RMWcc(LOCK_PREFIX "subl", v->counter, i, "%0", "e"); 80 + GEN_BINARY_RMWcc(LOCK_PREFIX "subl", v->counter, "er", i, "%0", "e"); 81 81 } 82 82 83 83 /** ··· 141 141 */ 142 142 static inline int atomic_add_negative(int i, atomic_t *v) 143 143 { 144 - GEN_BINARY_RMWcc(LOCK_PREFIX "addl", v->counter, i, "%0", "s"); 144 + GEN_BINARY_RMWcc(LOCK_PREFIX "addl", v->counter, "er", i, "%0", "s"); 145 145 } 146 146 147 147 /**
+2 -2
arch/x86/include/asm/atomic64_64.h
··· 72 72 */ 73 73 static inline int atomic64_sub_and_test(long i, atomic64_t *v) 74 74 { 75 - GEN_BINARY_RMWcc(LOCK_PREFIX "subq", v->counter, i, "%0", "e"); 75 + GEN_BINARY_RMWcc(LOCK_PREFIX "subq", v->counter, "er", i, "%0", "e"); 76 76 } 77 77 78 78 /** ··· 138 138 */ 139 139 static inline int atomic64_add_negative(long i, atomic64_t *v) 140 140 { 141 - GEN_BINARY_RMWcc(LOCK_PREFIX "addq", v->counter, i, "%0", "s"); 141 + GEN_BINARY_RMWcc(LOCK_PREFIX "addq", v->counter, "er", i, "%0", "s"); 142 142 } 143 143 144 144 /**
+3 -3
arch/x86/include/asm/bitops.h
··· 205 205 */ 206 206 static inline int test_and_set_bit(long nr, volatile unsigned long *addr) 207 207 { 208 - GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, nr, "%0", "c"); 208 + GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", "c"); 209 209 } 210 210 211 211 /** ··· 251 251 */ 252 252 static inline int test_and_clear_bit(long nr, volatile unsigned long *addr) 253 253 { 254 - GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, nr, "%0", "c"); 254 + GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, "Ir", nr, "%0", "c"); 255 255 } 256 256 257 257 /** ··· 304 304 */ 305 305 static inline int test_and_change_bit(long nr, volatile unsigned long *addr) 306 306 { 307 - GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, nr, "%0", "c"); 307 + GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, "Ir", nr, "%0", "c"); 308 308 } 309 309 310 310 static __always_inline int constant_test_bit(long nr, const volatile unsigned long *addr)
+2 -2
arch/x86/include/asm/local.h
··· 52 52 */ 53 53 static inline int local_sub_and_test(long i, local_t *l) 54 54 { 55 - GEN_BINARY_RMWcc(_ASM_SUB, l->a.counter, i, "%0", "e"); 55 + GEN_BINARY_RMWcc(_ASM_SUB, l->a.counter, "er", i, "%0", "e"); 56 56 } 57 57 58 58 /** ··· 92 92 */ 93 93 static inline int local_add_negative(long i, local_t *l) 94 94 { 95 - GEN_BINARY_RMWcc(_ASM_ADD, l->a.counter, i, "%0", "s"); 95 + GEN_BINARY_RMWcc(_ASM_ADD, l->a.counter, "er", i, "%0", "s"); 96 96 } 97 97 98 98 /**
+4 -4
arch/x86/include/asm/rmwcc.h
··· 16 16 #define GEN_UNARY_RMWcc(op, var, arg0, cc) \ 17 17 __GEN_RMWcc(op " " arg0, var, cc) 18 18 19 - #define GEN_BINARY_RMWcc(op, var, val, arg0, cc) \ 20 - __GEN_RMWcc(op " %1, " arg0, var, cc, "er" (val)) 19 + #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ 20 + __GEN_RMWcc(op " %1, " arg0, var, cc, vcon (val)) 21 21 22 22 #else /* !CC_HAVE_ASM_GOTO */ 23 23 ··· 33 33 #define GEN_UNARY_RMWcc(op, var, arg0, cc) \ 34 34 __GEN_RMWcc(op " " arg0, var, cc) 35 35 36 - #define GEN_BINARY_RMWcc(op, var, val, arg0, cc) \ 37 - __GEN_RMWcc(op " %2, " arg0, var, cc, "er" (val)) 36 + #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ 37 + __GEN_RMWcc(op " %2, " arg0, var, cc, vcon (val)) 38 38 39 39 #endif /* CC_HAVE_ASM_GOTO */ 40 40
+11
arch/x86/kernel/reboot.c
··· 558 558 { 559 559 /* Stop the cpus and apics */ 560 560 #ifdef CONFIG_X86_IO_APIC 561 + /* 562 + * Disabling IO APIC before local APIC is a workaround for 563 + * erratum AVR31 in "Intel Atom Processor C2000 Product Family 564 + * Specification Update". In this situation, interrupts that target 565 + * a Logical Processor whose Local APIC is either in the process of 566 + * being hardware disabled or software disabled are neither delivered 567 + * nor discarded. When this erratum occurs, the processor may hang. 568 + * 569 + * Even without the erratum, it still makes sense to quiet IO APIC 570 + * before disabling Local APIC. 571 + */ 561 572 disable_IO_APIC(); 562 573 #endif 563 574
+1 -1
arch/x86/platform/efi/early_printk.c
··· 142 142 efi_y += font->height; 143 143 } 144 144 145 - if (efi_y + font->height >= si->lfb_height) { 145 + if (efi_y + font->height > si->lfb_height) { 146 146 u32 i; 147 147 148 148 efi_y -= font->height;
+147 -16
drivers/firmware/efi/efi-pstore.c
··· 18 18 19 19 static int efi_pstore_open(struct pstore_info *psi) 20 20 { 21 - efivar_entry_iter_begin(); 22 21 psi->data = NULL; 23 22 return 0; 24 23 } 25 24 26 25 static int efi_pstore_close(struct pstore_info *psi) 27 26 { 28 - efivar_entry_iter_end(); 29 27 psi->data = NULL; 30 28 return 0; 31 29 } ··· 36 38 bool *compressed; 37 39 char **buf; 38 40 }; 41 + 42 + static inline u64 generic_id(unsigned long timestamp, 43 + unsigned int part, int count) 44 + { 45 + return (timestamp * 100 + part) * 1000 + count; 46 + } 39 47 40 48 static int efi_pstore_read_func(struct efivar_entry *entry, void *data) 41 49 { ··· 61 57 62 58 if (sscanf(name, "dump-type%u-%u-%d-%lu-%c", 63 59 cb_data->type, &part, &cnt, &time, &data_type) == 5) { 64 - *cb_data->id = part; 60 + *cb_data->id = generic_id(time, part, cnt); 65 61 *cb_data->count = cnt; 66 62 cb_data->timespec->tv_sec = time; 67 63 cb_data->timespec->tv_nsec = 0; ··· 71 67 *cb_data->compressed = false; 72 68 } else if (sscanf(name, "dump-type%u-%u-%d-%lu", 73 69 cb_data->type, &part, &cnt, &time) == 4) { 74 - *cb_data->id = part; 70 + *cb_data->id = generic_id(time, part, cnt); 75 71 *cb_data->count = cnt; 76 72 cb_data->timespec->tv_sec = time; 77 73 cb_data->timespec->tv_nsec = 0; ··· 83 79 * which doesn't support holding 84 80 * multiple logs, remains. 85 81 */ 86 - *cb_data->id = part; 82 + *cb_data->id = generic_id(time, part, 0); 87 83 *cb_data->count = 0; 88 84 cb_data->timespec->tv_sec = time; 89 85 cb_data->timespec->tv_nsec = 0; ··· 95 91 __efivar_entry_get(entry, &entry->var.Attributes, 96 92 &entry->var.DataSize, entry->var.Data); 97 93 size = entry->var.DataSize; 94 + memcpy(*cb_data->buf, entry->var.Data, 95 + (size_t)min_t(unsigned long, EFIVARS_DATA_SIZE_MAX, size)); 98 96 99 - *cb_data->buf = kmemdup(entry->var.Data, size, GFP_KERNEL); 100 - if (*cb_data->buf == NULL) 101 - return -ENOMEM; 102 97 return size; 103 98 } 104 99 100 + /** 101 + * efi_pstore_scan_sysfs_enter 102 + * @entry: scanning entry 103 + * @next: next entry 104 + * @head: list head 105 + */ 106 + static void efi_pstore_scan_sysfs_enter(struct efivar_entry *pos, 107 + struct efivar_entry *next, 108 + struct list_head *head) 109 + { 110 + pos->scanning = true; 111 + if (&next->list != head) 112 + next->scanning = true; 113 + } 114 + 115 + /** 116 + * __efi_pstore_scan_sysfs_exit 117 + * @entry: deleting entry 118 + * @turn_off_scanning: Check if a scanning flag should be turned off 119 + */ 120 + static inline void __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry, 121 + bool turn_off_scanning) 122 + { 123 + if (entry->deleting) { 124 + list_del(&entry->list); 125 + efivar_entry_iter_end(); 126 + efivar_unregister(entry); 127 + efivar_entry_iter_begin(); 128 + } else if (turn_off_scanning) 129 + entry->scanning = false; 130 + } 131 + 132 + /** 133 + * efi_pstore_scan_sysfs_exit 134 + * @pos: scanning entry 135 + * @next: next entry 136 + * @head: list head 137 + * @stop: a flag checking if scanning will stop 138 + */ 139 + static void efi_pstore_scan_sysfs_exit(struct efivar_entry *pos, 140 + struct efivar_entry *next, 141 + struct list_head *head, bool stop) 142 + { 143 + __efi_pstore_scan_sysfs_exit(pos, true); 144 + if (stop) 145 + __efi_pstore_scan_sysfs_exit(next, &next->list != head); 146 + } 147 + 148 + /** 149 + * efi_pstore_sysfs_entry_iter 150 + * 151 + * @data: function-specific data to pass to callback 152 + * @pos: entry to begin iterating from 153 + * 154 + * You MUST call efivar_enter_iter_begin() before this function, and 155 + * efivar_entry_iter_end() afterwards. 156 + * 157 + * It is possible to begin iteration from an arbitrary entry within 158 + * the list by passing @pos. @pos is updated on return to point to 159 + * the next entry of the last one passed to efi_pstore_read_func(). 160 + * To begin iterating from the beginning of the list @pos must be %NULL. 161 + */ 162 + static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos) 163 + { 164 + struct efivar_entry *entry, *n; 165 + struct list_head *head = &efivar_sysfs_list; 166 + int size = 0; 167 + 168 + if (!*pos) { 169 + list_for_each_entry_safe(entry, n, head, list) { 170 + efi_pstore_scan_sysfs_enter(entry, n, head); 171 + 172 + size = efi_pstore_read_func(entry, data); 173 + efi_pstore_scan_sysfs_exit(entry, n, head, size < 0); 174 + if (size) 175 + break; 176 + } 177 + *pos = n; 178 + return size; 179 + } 180 + 181 + list_for_each_entry_safe_from((*pos), n, head, list) { 182 + efi_pstore_scan_sysfs_enter((*pos), n, head); 183 + 184 + size = efi_pstore_read_func((*pos), data); 185 + efi_pstore_scan_sysfs_exit((*pos), n, head, size < 0); 186 + if (size) 187 + break; 188 + } 189 + *pos = n; 190 + return size; 191 + } 192 + 193 + /** 194 + * efi_pstore_read 195 + * 196 + * This function returns a size of NVRAM entry logged via efi_pstore_write(). 197 + * The meaning and behavior of efi_pstore/pstore are as below. 198 + * 199 + * size > 0: Got data of an entry logged via efi_pstore_write() successfully, 200 + * and pstore filesystem will continue reading subsequent entries. 201 + * size == 0: Entry was not logged via efi_pstore_write(), 202 + * and efi_pstore driver will continue reading subsequent entries. 203 + * size < 0: Failed to get data of entry logging via efi_pstore_write(), 204 + * and pstore will stop reading entry. 205 + */ 105 206 static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, 106 207 int *count, struct timespec *timespec, 107 208 char **buf, bool *compressed, 108 209 struct pstore_info *psi) 109 210 { 110 211 struct pstore_read_data data; 212 + ssize_t size; 111 213 112 214 data.id = id; 113 215 data.type = type; ··· 222 112 data.compressed = compressed; 223 113 data.buf = buf; 224 114 225 - return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data, 226 - (struct efivar_entry **)&psi->data); 115 + *data.buf = kzalloc(EFIVARS_DATA_SIZE_MAX, GFP_KERNEL); 116 + if (!*data.buf) 117 + return -ENOMEM; 118 + 119 + efivar_entry_iter_begin(); 120 + size = efi_pstore_sysfs_entry_iter(&data, 121 + (struct efivar_entry **)&psi->data); 122 + efivar_entry_iter_end(); 123 + if (size <= 0) 124 + kfree(*data.buf); 125 + return size; 227 126 } 228 127 229 128 static int efi_pstore_write(enum pstore_type_id type, ··· 303 184 return 0; 304 185 } 305 186 187 + if (entry->scanning) { 188 + /* 189 + * Skip deletion because this entry will be deleted 190 + * after scanning is completed. 191 + */ 192 + entry->deleting = true; 193 + } else 194 + list_del(&entry->list); 195 + 306 196 /* found */ 307 197 __efivar_entry_delete(entry); 308 - list_del(&entry->list); 309 198 310 199 return 1; 311 200 } ··· 326 199 char name[DUMP_NAME_LEN]; 327 200 efi_char16_t efi_name[DUMP_NAME_LEN]; 328 201 int found, i; 202 + unsigned int part; 329 203 330 - sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count, 331 - time.tv_sec); 204 + do_div(id, 1000); 205 + part = do_div(id, 100); 206 + sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count, time.tv_sec); 332 207 333 208 for (i = 0; i < DUMP_NAME_LEN; i++) 334 209 efi_name[i] = name[i]; 335 210 336 - edata.id = id; 211 + edata.id = part; 337 212 edata.type = type; 338 213 edata.count = count; 339 214 edata.time = time; ··· 343 214 344 215 efivar_entry_iter_begin(); 345 216 found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry); 346 - efivar_entry_iter_end(); 347 217 348 - if (found) 218 + if (found && !entry->scanning) { 219 + efivar_entry_iter_end(); 349 220 efivar_unregister(entry); 221 + } else 222 + efivar_entry_iter_end(); 350 223 351 224 return 0; 352 225 }
+8 -4
drivers/firmware/efi/efivars.c
··· 383 383 else if (__efivar_entry_delete(entry)) 384 384 err = -EIO; 385 385 386 - efivar_entry_iter_end(); 387 - 388 - if (err) 386 + if (err) { 387 + efivar_entry_iter_end(); 389 388 return err; 389 + } 390 390 391 - efivar_unregister(entry); 391 + if (!entry->scanning) { 392 + efivar_entry_iter_end(); 393 + efivar_unregister(entry); 394 + } else 395 + efivar_entry_iter_end(); 392 396 393 397 /* It's dead Jim.... */ 394 398 return count;
+10 -2
drivers/firmware/efi/vars.c
··· 683 683 if (!found) 684 684 return NULL; 685 685 686 - if (remove) 687 - list_del(&entry->list); 686 + if (remove) { 687 + if (entry->scanning) { 688 + /* 689 + * The entry will be deleted 690 + * after scanning is completed. 691 + */ 692 + entry->deleting = true; 693 + } else 694 + list_del(&entry->list); 695 + } 688 696 689 697 return entry; 690 698 }
+4
include/linux/efi.h
··· 801 801 struct efi_variable var; 802 802 struct list_head list; 803 803 struct kobject kobj; 804 + bool scanning; 805 + bool deleting; 804 806 }; 805 807 806 808 ··· 867 865 868 866 #if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE) 869 867 int efivars_sysfs_init(void); 868 + 869 + #define EFIVARS_DATA_SIZE_MAX 1024 870 870 871 871 #endif /* CONFIG_EFI_VARS */ 872 872