diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-03 13:42:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-03 13:42:32 -0400 |
commit | 567cfea99af61ef19da42f8491da98cf94a4d166 (patch) | |
tree | 6986f1a2f0bf2f1f5508146a8cc2c369e6d2b962 | |
parent | ec2e76b4c73362231e7d6903e14fc9817d99f3ae (diff) | |
parent | f59df35fc28167886a0caf9f15db2f4a1f5932da (diff) |
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar:
"Misc fixes: a SYSRET single-stepping fix, a dmi-scan robustization
fix, a reboot quirk and a kgdb fixlet"
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
kgdb/x86: Fix reporting of 'si' in kgdb on x86_64
x86/asm/entry/64: Disable opportunistic SYSRET if regs->flags has TF set
x86/reboot: Add ASRock Q1900DC-ITX mainboard reboot quirk
MAINTAINERS: Change the x86 microcode loader maintainer
firmware: dmi_scan: Prevent dmi_num integer overflow
-rw-r--r-- | MAINTAINERS | 5 | ||||
-rw-r--r-- | arch/x86/kernel/entry_64.S | 16 | ||||
-rw-r--r-- | arch/x86/kernel/kgdb.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/reboot.c | 10 | ||||
-rw-r--r-- | drivers/firmware/dmi_scan.c | 22 |
5 files changed, 35 insertions, 20 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index ac976acd9841..efbcb50e4969 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -637,8 +637,7 @@ F: drivers/gpu/drm/radeon/radeon_kfd.h | |||
637 | F: include/uapi/linux/kfd_ioctl.h | 637 | F: include/uapi/linux/kfd_ioctl.h |
638 | 638 | ||
639 | AMD MICROCODE UPDATE SUPPORT | 639 | AMD MICROCODE UPDATE SUPPORT |
640 | M: Andreas Herrmann <herrmann.der.user@googlemail.com> | 640 | M: Borislav Petkov <bp@alien8.de> |
641 | L: amd64-microcode@amd64.org | ||
642 | S: Maintained | 641 | S: Maintained |
643 | F: arch/x86/kernel/cpu/microcode/amd* | 642 | F: arch/x86/kernel/cpu/microcode/amd* |
644 | 643 | ||
@@ -5095,7 +5094,7 @@ S: Supported | |||
5095 | F: drivers/platform/x86/intel_menlow.c | 5094 | F: drivers/platform/x86/intel_menlow.c |
5096 | 5095 | ||
5097 | INTEL IA32 MICROCODE UPDATE SUPPORT | 5096 | INTEL IA32 MICROCODE UPDATE SUPPORT |
5098 | M: Tigran Aivazian <tigran@aivazian.fsnet.co.uk> | 5097 | M: Borislav Petkov <bp@alien8.de> |
5099 | S: Maintained | 5098 | S: Maintained |
5100 | F: arch/x86/kernel/cpu/microcode/core* | 5099 | F: arch/x86/kernel/cpu/microcode/core* |
5101 | F: arch/x86/kernel/cpu/microcode/intel* | 5100 | F: arch/x86/kernel/cpu/microcode/intel* |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 2babb393915e..f0095a76c182 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -799,7 +799,21 @@ retint_swapgs: /* return to user-space */ | |||
799 | cmpq %r11,(EFLAGS-ARGOFFSET)(%rsp) /* R11 == RFLAGS */ | 799 | cmpq %r11,(EFLAGS-ARGOFFSET)(%rsp) /* R11 == RFLAGS */ |
800 | jne opportunistic_sysret_failed | 800 | jne opportunistic_sysret_failed |
801 | 801 | ||
802 | testq $X86_EFLAGS_RF,%r11 /* sysret can't restore RF */ | 802 | /* |
803 | * SYSRET can't restore RF. SYSRET can restore TF, but unlike IRET, | ||
804 | * restoring TF results in a trap from userspace immediately after | ||
805 | * SYSRET. This would cause an infinite loop whenever #DB happens | ||
806 | * with register state that satisfies the opportunistic SYSRET | ||
807 | * conditions. For example, single-stepping this user code: | ||
808 | * | ||
809 | * movq $stuck_here,%rcx | ||
810 | * pushfq | ||
811 | * popq %r11 | ||
812 | * stuck_here: | ||
813 | * | ||
814 | * would never get past 'stuck_here'. | ||
815 | */ | ||
816 | testq $(X86_EFLAGS_RF|X86_EFLAGS_TF), %r11 | ||
803 | jnz opportunistic_sysret_failed | 817 | jnz opportunistic_sysret_failed |
804 | 818 | ||
805 | /* nothing to check for RSP */ | 819 | /* nothing to check for RSP */ |
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 7ec1d5f8d283..25ecd56cefa8 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -72,7 +72,7 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = | |||
72 | { "bx", 8, offsetof(struct pt_regs, bx) }, | 72 | { "bx", 8, offsetof(struct pt_regs, bx) }, |
73 | { "cx", 8, offsetof(struct pt_regs, cx) }, | 73 | { "cx", 8, offsetof(struct pt_regs, cx) }, |
74 | { "dx", 8, offsetof(struct pt_regs, dx) }, | 74 | { "dx", 8, offsetof(struct pt_regs, dx) }, |
75 | { "si", 8, offsetof(struct pt_regs, dx) }, | 75 | { "si", 8, offsetof(struct pt_regs, si) }, |
76 | { "di", 8, offsetof(struct pt_regs, di) }, | 76 | { "di", 8, offsetof(struct pt_regs, di) }, |
77 | { "bp", 8, offsetof(struct pt_regs, bp) }, | 77 | { "bp", 8, offsetof(struct pt_regs, bp) }, |
78 | { "sp", 8, offsetof(struct pt_regs, sp) }, | 78 | { "sp", 8, offsetof(struct pt_regs, sp) }, |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index bae6c609888e..86db4bcd7ce5 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -183,6 +183,16 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
183 | }, | 183 | }, |
184 | }, | 184 | }, |
185 | 185 | ||
186 | /* ASRock */ | ||
187 | { /* Handle problems with rebooting on ASRock Q1900DC-ITX */ | ||
188 | .callback = set_pci_reboot, | ||
189 | .ident = "ASRock Q1900DC-ITX", | ||
190 | .matches = { | ||
191 | DMI_MATCH(DMI_BOARD_VENDOR, "ASRock"), | ||
192 | DMI_MATCH(DMI_BOARD_NAME, "Q1900DC-ITX"), | ||
193 | }, | ||
194 | }, | ||
195 | |||
186 | /* ASUS */ | 196 | /* ASUS */ |
187 | { /* Handle problems with rebooting on ASUS P4S800 */ | 197 | { /* Handle problems with rebooting on ASUS P4S800 */ |
188 | .callback = set_bios_reboot, | 198 | .callback = set_bios_reboot, |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 69fac068669f..2eebd28b4c40 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -86,10 +86,13 @@ static void dmi_table(u8 *buf, u32 len, int num, | |||
86 | int i = 0; | 86 | int i = 0; |
87 | 87 | ||
88 | /* | 88 | /* |
89 | * Stop when we see all the items the table claimed to have | 89 | * Stop when we have seen all the items the table claimed to have |
90 | * OR we run off the end of the table (also happens) | 90 | * (SMBIOS < 3.0 only) OR we reach an end-of-table marker OR we run |
91 | * off the end of the table (should never happen but sometimes does | ||
92 | * on bogus implementations.) | ||
91 | */ | 93 | */ |
92 | while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { | 94 | while ((!num || i < num) && |
95 | (data - buf + sizeof(struct dmi_header)) <= len) { | ||
93 | const struct dmi_header *dm = (const struct dmi_header *)data; | 96 | const struct dmi_header *dm = (const struct dmi_header *)data; |
94 | 97 | ||
95 | /* | 98 | /* |
@@ -529,21 +532,10 @@ static int __init dmi_smbios3_present(const u8 *buf) | |||
529 | if (memcmp(buf, "_SM3_", 5) == 0 && | 532 | if (memcmp(buf, "_SM3_", 5) == 0 && |
530 | buf[6] < 32 && dmi_checksum(buf, buf[6])) { | 533 | buf[6] < 32 && dmi_checksum(buf, buf[6])) { |
531 | dmi_ver = get_unaligned_be16(buf + 7); | 534 | dmi_ver = get_unaligned_be16(buf + 7); |
535 | dmi_num = 0; /* No longer specified */ | ||
532 | dmi_len = get_unaligned_le32(buf + 12); | 536 | dmi_len = get_unaligned_le32(buf + 12); |
533 | dmi_base = get_unaligned_le64(buf + 16); | 537 | dmi_base = get_unaligned_le64(buf + 16); |
534 | 538 | ||
535 | /* | ||
536 | * The 64-bit SMBIOS 3.0 entry point no longer has a field | ||
537 | * containing the number of structures present in the table. | ||
538 | * Instead, it defines the table size as a maximum size, and | ||
539 | * relies on the end-of-table structure type (#127) to be used | ||
540 | * to signal the end of the table. | ||
541 | * So let's define dmi_num as an upper bound as well: each | ||
542 | * structure has a 4 byte header, so dmi_len / 4 is an upper | ||
543 | * bound for the number of structures in the table. | ||
544 | */ | ||
545 | dmi_num = dmi_len / 4; | ||
546 | |||
547 | if (dmi_walk_early(dmi_decode) == 0) { | 539 | if (dmi_walk_early(dmi_decode) == 0) { |
548 | pr_info("SMBIOS %d.%d present.\n", | 540 | pr_info("SMBIOS %d.%d present.\n", |
549 | dmi_ver >> 8, dmi_ver & 0xFF); | 541 | dmi_ver >> 8, dmi_ver & 0xFF); |