[GIT pull] x86/pti updates for 4.17
Linus, please pull the latest x86-pti-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-pti-for-linus Two fixes for the SSBD mitigation code: - Expose SSBD properly to guests. This got broken when the CPU feature flags got reshuffled. - Simplify the CPU detection logic to avoid duplicate entries in the tables. Thanks, tglx --> Dominik Brodowski (1): x86/speculation: Simplify the CPU bug detection logic Konrad Rzeszutek Wilk (1): KVM/VMX: Expose SSBD properly to guests arch/x86/kernel/cpu/common.c | 22 +++--- arch/x86/kvm/cpuid.c | 4 ++-- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 78decc3e3067..38276f58d3bf 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -942,12 +942,8 @@ static const __initconst struct x86_cpu_id cpu_no_meltdown[] = { {} }; +/* Only list CPUs which speculate but are non susceptible to SSB */ static const __initconst struct x86_cpu_id cpu_no_spec_store_bypass[] = { - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_PINEVIEW}, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_LINCROFT}, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_PENWELL }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_CLOVERVIEW }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_CEDARVIEW }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT1 }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT2 }, @@ -955,14 +951,10 @@ static const __initconst struct x86_cpu_id cpu_no_spec_store_bypass[] = { { X86_VENDOR_INTEL, 6, INTEL_FAM6_CORE_YONAH }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNL }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNM }, - { X86_VENDOR_CENTAUR, 5, }, - { X86_VENDOR_INTEL, 5, }, - { X86_VENDOR_NSC, 5, }, { X86_VENDOR_AMD, 0x12, }, { X86_VENDOR_AMD, 0x11, }, { X86_VENDOR_AMD, 0x10, }, { X86_VENDOR_AMD, 0xf,}, - { X86_VENDOR_ANY, 4, }, {} }; @@ -970,6 +962,12 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) { u64 ia32_cap = 0; + if (x86_match_cpu(cpu_no_speculation)) + return; + + setup_force_cpu_bug(X86_BUG_SPECTRE_V1); + setup_force_cpu_bug(X86_BUG_SPECTRE_V2); + if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES)) rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); @@ -977,12 +975,6 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) !(ia32_cap & ARCH_CAP_SSB_NO)) setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS); - if (x86_match_cpu(cpu_no_speculation)) - return; - - setup_force_cpu_bug(X86_BUG_SPECTRE_V1); - setup_force_cpu_bug(X86_BUG_SPECTRE_V2); - if (x86_match_cpu(cpu_no_meltdown)) return; diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index ced851169730..598461e24be3 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -407,8 +407,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, /* cpuid 7.0.edx*/ const u32 kvm_cpuid_7_0_edx_x86_features = - F(AVX512_4VNNIW) | F(AVX512_4FMAPS) | F(SPEC_CTRL) | F(SSBD) | - F(ARCH_CAPABILITIES); + F(AVX512_4VNNIW) | F(AVX512_4FMAPS) | F(SPEC_CTRL) | + F(SPEC_CTRL_SSBD) | F(ARCH_CAPABILITIES); /* all calls to cpuid_count() should be made on the same cpu */ get_cpu();
[GIT pull] x86/pti updates for 4.17
Linus, please pull the latest x86-pti-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-pti-for-linus Two fixes for the SSBD mitigation code: - Expose SSBD properly to guests. This got broken when the CPU feature flags got reshuffled. - Simplify the CPU detection logic to avoid duplicate entries in the tables. Thanks, tglx --> Dominik Brodowski (1): x86/speculation: Simplify the CPU bug detection logic Konrad Rzeszutek Wilk (1): KVM/VMX: Expose SSBD properly to guests arch/x86/kernel/cpu/common.c | 22 +++--- arch/x86/kvm/cpuid.c | 4 ++-- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 78decc3e3067..38276f58d3bf 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -942,12 +942,8 @@ static const __initconst struct x86_cpu_id cpu_no_meltdown[] = { {} }; +/* Only list CPUs which speculate but are non susceptible to SSB */ static const __initconst struct x86_cpu_id cpu_no_spec_store_bypass[] = { - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_PINEVIEW}, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_LINCROFT}, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_PENWELL }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_CLOVERVIEW }, - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_CEDARVIEW }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT1 }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT2 }, @@ -955,14 +951,10 @@ static const __initconst struct x86_cpu_id cpu_no_spec_store_bypass[] = { { X86_VENDOR_INTEL, 6, INTEL_FAM6_CORE_YONAH }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNL }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNM }, - { X86_VENDOR_CENTAUR, 5, }, - { X86_VENDOR_INTEL, 5, }, - { X86_VENDOR_NSC, 5, }, { X86_VENDOR_AMD, 0x12, }, { X86_VENDOR_AMD, 0x11, }, { X86_VENDOR_AMD, 0x10, }, { X86_VENDOR_AMD, 0xf,}, - { X86_VENDOR_ANY, 4, }, {} }; @@ -970,6 +962,12 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) { u64 ia32_cap = 0; + if (x86_match_cpu(cpu_no_speculation)) + return; + + setup_force_cpu_bug(X86_BUG_SPECTRE_V1); + setup_force_cpu_bug(X86_BUG_SPECTRE_V2); + if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES)) rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); @@ -977,12 +975,6 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) !(ia32_cap & ARCH_CAP_SSB_NO)) setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS); - if (x86_match_cpu(cpu_no_speculation)) - return; - - setup_force_cpu_bug(X86_BUG_SPECTRE_V1); - setup_force_cpu_bug(X86_BUG_SPECTRE_V2); - if (x86_match_cpu(cpu_no_meltdown)) return; diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index ced851169730..598461e24be3 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -407,8 +407,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, /* cpuid 7.0.edx*/ const u32 kvm_cpuid_7_0_edx_x86_features = - F(AVX512_4VNNIW) | F(AVX512_4FMAPS) | F(SPEC_CTRL) | F(SSBD) | - F(ARCH_CAPABILITIES); + F(AVX512_4VNNIW) | F(AVX512_4FMAPS) | F(SPEC_CTRL) | + F(SPEC_CTRL_SSBD) | F(ARCH_CAPABILITIES); /* all calls to cpuid_count() should be made on the same cpu */ get_cpu();
[GIT pull] x86/pti updates for 4.17
Linus, please pull the latest x86-pti-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-pti-for-linus A mixed bag of fixes and updates for the ghosts which are hunting us. The scheduler fixes have been pulled into that branch to avoid conflicts. - A set of fixes to address a khread_parkme() race which caused lost wakeups and loss of state. - A deadlock fix for stop_machine() solved by moving the wakeups outside of the stopper_lock held region. - A set of Spectre V1 array access restrictions. The possible problematic spots were discuvered by Dan Carpenters new checks in smatch. - Removal of an unused file which was forgotten when the rest of that functionality was removed. Thanks, tglx --> Jann Horn (1): x86/vdso: Remove unused file Peter Zijlstra (11): stop_machine, sched: Fix migrate_swap() vs. active_balance() deadlock kthread, sched/wait: Fix kthread_parkme() wait-loop kthread, sched/wait: Fix kthread_parkme() completion issue sched/core: Introduce set_special_state() sched/core: Fix possible Spectre-v1 indexing for sched_prio_to_weight[] sched/autogroup: Fix possible Spectre-v1 indexing for sched_prio_to_weight[] perf/core: Fix possible Spectre-v1 indexing for ->aux_pages[] perf/x86: Fix possible Spectre-v1 indexing for hw_perf_event cache_* perf/x86: Fix possible Spectre-v1 indexing for x86_pmu::event_map() perf/x86/msr: Fix possible Spectre-v1 indexing in the MSR driver perf/x86/cstate: Fix possible Spectre-v1 indexing for pkg_msr Vincent Guittot (1): sched/fair: Fix the update of blocked load when newly idle arch/x86/entry/vdso/vdso32/vdso-fakesections.c | 1 - arch/x86/events/core.c | 8 +++- arch/x86/events/intel/cstate.c | 2 + arch/x86/events/msr.c | 9 +++-- include/linux/kthread.h| 1 + include/linux/sched.h | 50 --- include/linux/sched/signal.h | 2 +- kernel/events/ring_buffer.c| 7 +++- kernel/kthread.c | 50 +++ kernel/sched/autogroup.c | 7 +++- kernel/sched/core.c| 56 +- kernel/sched/fair.c| 2 +- kernel/signal.c| 17 +++- kernel/stop_machine.c | 19 ++--- 14 files changed, 153 insertions(+), 78 deletions(-) delete mode 100644 arch/x86/entry/vdso/vdso32/vdso-fakesections.c diff --git a/arch/x86/entry/vdso/vdso32/vdso-fakesections.c b/arch/x86/entry/vdso/vdso32/vdso-fakesections.c deleted file mode 100644 index 541468e25265.. --- a/arch/x86/entry/vdso/vdso32/vdso-fakesections.c +++ /dev/null @@ -1 +0,0 @@ -#include "../vdso-fakesections.c" diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index a6006e7bb729..45b2b1c93d04 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -304,17 +305,20 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event *event) config = attr->config; - cache_type = (config >> 0) & 0xff; + cache_type = (config >> 0) & 0xff; if (cache_type >= PERF_COUNT_HW_CACHE_MAX) return -EINVAL; + cache_type = array_index_nospec(cache_type, PERF_COUNT_HW_CACHE_MAX); cache_op = (config >> 8) & 0xff; if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) return -EINVAL; + cache_op = array_index_nospec(cache_op, PERF_COUNT_HW_CACHE_OP_MAX); cache_result = (config >> 16) & 0xff; if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) return -EINVAL; + cache_result = array_index_nospec(cache_result, PERF_COUNT_HW_CACHE_RESULT_MAX); val = hw_cache_event_ids[cache_type][cache_op][cache_result]; @@ -421,6 +425,8 @@ int x86_setup_perfctr(struct perf_event *event) if (attr->config >= x86_pmu.max_events) return -EINVAL; + attr->config = array_index_nospec((unsigned long)attr->config, x86_pmu.max_events); + /* * The generic map: */ diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 9aca448bb8e6..9f8084f18d58 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include #include "../perf_event.h" @@ -302,6 +303,7 @@ static int cstate_pmu_event_init(struct perf_event *event) } else if (event->pmu == _pkg_pmu) { if (cfg >= PERF_CSTATE_PKG_EVENT_MAX) return -EINVAL; + cfg = array_index_nospec((unsigned
[GIT pull] x86/pti updates for 4.17
Linus, please pull the latest x86-pti-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-pti-for-linus A mixed bag of fixes and updates for the ghosts which are hunting us. The scheduler fixes have been pulled into that branch to avoid conflicts. - A set of fixes to address a khread_parkme() race which caused lost wakeups and loss of state. - A deadlock fix for stop_machine() solved by moving the wakeups outside of the stopper_lock held region. - A set of Spectre V1 array access restrictions. The possible problematic spots were discuvered by Dan Carpenters new checks in smatch. - Removal of an unused file which was forgotten when the rest of that functionality was removed. Thanks, tglx --> Jann Horn (1): x86/vdso: Remove unused file Peter Zijlstra (11): stop_machine, sched: Fix migrate_swap() vs. active_balance() deadlock kthread, sched/wait: Fix kthread_parkme() wait-loop kthread, sched/wait: Fix kthread_parkme() completion issue sched/core: Introduce set_special_state() sched/core: Fix possible Spectre-v1 indexing for sched_prio_to_weight[] sched/autogroup: Fix possible Spectre-v1 indexing for sched_prio_to_weight[] perf/core: Fix possible Spectre-v1 indexing for ->aux_pages[] perf/x86: Fix possible Spectre-v1 indexing for hw_perf_event cache_* perf/x86: Fix possible Spectre-v1 indexing for x86_pmu::event_map() perf/x86/msr: Fix possible Spectre-v1 indexing in the MSR driver perf/x86/cstate: Fix possible Spectre-v1 indexing for pkg_msr Vincent Guittot (1): sched/fair: Fix the update of blocked load when newly idle arch/x86/entry/vdso/vdso32/vdso-fakesections.c | 1 - arch/x86/events/core.c | 8 +++- arch/x86/events/intel/cstate.c | 2 + arch/x86/events/msr.c | 9 +++-- include/linux/kthread.h| 1 + include/linux/sched.h | 50 --- include/linux/sched/signal.h | 2 +- kernel/events/ring_buffer.c| 7 +++- kernel/kthread.c | 50 +++ kernel/sched/autogroup.c | 7 +++- kernel/sched/core.c| 56 +- kernel/sched/fair.c| 2 +- kernel/signal.c| 17 +++- kernel/stop_machine.c | 19 ++--- 14 files changed, 153 insertions(+), 78 deletions(-) delete mode 100644 arch/x86/entry/vdso/vdso32/vdso-fakesections.c diff --git a/arch/x86/entry/vdso/vdso32/vdso-fakesections.c b/arch/x86/entry/vdso/vdso32/vdso-fakesections.c deleted file mode 100644 index 541468e25265.. --- a/arch/x86/entry/vdso/vdso32/vdso-fakesections.c +++ /dev/null @@ -1 +0,0 @@ -#include "../vdso-fakesections.c" diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index a6006e7bb729..45b2b1c93d04 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -304,17 +305,20 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event *event) config = attr->config; - cache_type = (config >> 0) & 0xff; + cache_type = (config >> 0) & 0xff; if (cache_type >= PERF_COUNT_HW_CACHE_MAX) return -EINVAL; + cache_type = array_index_nospec(cache_type, PERF_COUNT_HW_CACHE_MAX); cache_op = (config >> 8) & 0xff; if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) return -EINVAL; + cache_op = array_index_nospec(cache_op, PERF_COUNT_HW_CACHE_OP_MAX); cache_result = (config >> 16) & 0xff; if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) return -EINVAL; + cache_result = array_index_nospec(cache_result, PERF_COUNT_HW_CACHE_RESULT_MAX); val = hw_cache_event_ids[cache_type][cache_op][cache_result]; @@ -421,6 +425,8 @@ int x86_setup_perfctr(struct perf_event *event) if (attr->config >= x86_pmu.max_events) return -EINVAL; + attr->config = array_index_nospec((unsigned long)attr->config, x86_pmu.max_events); + /* * The generic map: */ diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 9aca448bb8e6..9f8084f18d58 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include #include "../perf_event.h" @@ -302,6 +303,7 @@ static int cstate_pmu_event_init(struct perf_event *event) } else if (event->pmu == _pkg_pmu) { if (cfg >= PERF_CSTATE_PKG_EVENT_MAX) return -EINVAL; + cfg = array_index_nospec((unsigned
[GIT pull] x86/pti updates for 4.17
Linus, please pull the latest x86-pti-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-pti-for-linus A set of updates for the x86/pti related code: - Preserve r8-r11 in int $0x80. r8-r11 need to be preserved, but the $int80 entry code removed that quite some time ago. Make it correct again. - A set of fixes for the Global Bit work which went into 4.17 and caused a bunch of interesting regressions: - Triggering a BUG in the page attribute code due to a missing check for early boot stage - Warnings in the page attribute code about holes in the kernel text mapping which are caused by the freeing of the init code. Handle such holes gracefully. - Reduce the amount of kernel memory which is set global to the actual text and do not incidentally overlap with data. - Disable the global bit when RANDSTRUCT is enabled as it partially defeats the hardening. - Make the page protection setup correct for vma->page_prot population again. The adjustment of the protections fell through the crack during the Global bit rework and triggers warnings on machines which do not support certain features, e.g. NX Thanks, tglx --> Andy Lutomirski (1): x86/entry/64/compat: Preserve r8-r11 in int $0x80 Dave Hansen (5): x86/pti: Fix boot problems from Global-bit setting x86/pti: Fix boot warning from Global-bit setting x86/pti: Reduce amount of kernel text allowed to be Global x86/pti: Disallow global kernel text with RANDSTRUCT x86/pti: Filter at vma->vm_page_prot population arch/x86/Kconfig| 4 +++ arch/x86/entry/entry_64_compat.S| 8 ++--- arch/x86/include/asm/pgtable.h | 5 +++ arch/x86/mm/pageattr.c | 44 ++--- arch/x86/mm/pti.c | 26 +-- mm/mmap.c | 11 ++- tools/testing/selftests/x86/test_syscall_vdso.c | 35 7 files changed, 99 insertions(+), 34 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 00fcf81f2c56..c07f492b871a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -52,6 +52,7 @@ config X86 select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_FAST_MULTIPLIER + select ARCH_HAS_FILTER_PGPROT select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_KCOVif X86_64 @@ -273,6 +274,9 @@ config ARCH_HAS_CPU_RELAX config ARCH_HAS_CACHE_LINE_SIZE def_bool y +config ARCH_HAS_FILTER_PGPROT + def_bool y + config HAVE_SETUP_PER_CPU_AREA def_bool y diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index 9af927e59d49..9de7f1e1dede 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -84,13 +84,13 @@ ENTRY(entry_SYSENTER_compat) pushq %rdx/* pt_regs->dx */ pushq %rcx/* pt_regs->cx */ pushq $-ENOSYS/* pt_regs->ax */ - pushq $0 /* pt_regs->r8 = 0 */ + pushq %r8 /* pt_regs->r8 */ xorl%r8d, %r8d /* nospec r8 */ - pushq $0 /* pt_regs->r9 = 0 */ + pushq %r9 /* pt_regs->r9 */ xorl%r9d, %r9d /* nospec r9 */ - pushq $0 /* pt_regs->r10 = 0 */ + pushq %r10/* pt_regs->r10 */ xorl%r10d, %r10d/* nospec r10 */ - pushq $0 /* pt_regs->r11 = 0 */ + pushq %r11/* pt_regs->r11 */ xorl%r11d, %r11d/* nospec r11 */ pushq %rbx/* pt_regs->rbx */ xorl%ebx, %ebx /* nospec rbx */ diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 5f49b4ff0c24..f1633de5a675 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -601,6 +601,11 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) #define canon_pgprot(p) __pgprot(massage_pgprot(p)) +static inline pgprot_t arch_filter_pgprot(pgprot_t prot) +{ + return canon_pgprot(prot); +} + static inline int is_new_memtype_allowed(u64 paddr, unsigned long size, enum page_cache_mode pcm, enum page_cache_mode new_pcm) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 0f3d50f4c48c..3bded76e8d5c 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file *m) static
[GIT pull] x86/pti updates for 4.17
Linus, please pull the latest x86-pti-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-pti-for-linus A set of updates for the x86/pti related code: - Preserve r8-r11 in int $0x80. r8-r11 need to be preserved, but the $int80 entry code removed that quite some time ago. Make it correct again. - A set of fixes for the Global Bit work which went into 4.17 and caused a bunch of interesting regressions: - Triggering a BUG in the page attribute code due to a missing check for early boot stage - Warnings in the page attribute code about holes in the kernel text mapping which are caused by the freeing of the init code. Handle such holes gracefully. - Reduce the amount of kernel memory which is set global to the actual text and do not incidentally overlap with data. - Disable the global bit when RANDSTRUCT is enabled as it partially defeats the hardening. - Make the page protection setup correct for vma->page_prot population again. The adjustment of the protections fell through the crack during the Global bit rework and triggers warnings on machines which do not support certain features, e.g. NX Thanks, tglx --> Andy Lutomirski (1): x86/entry/64/compat: Preserve r8-r11 in int $0x80 Dave Hansen (5): x86/pti: Fix boot problems from Global-bit setting x86/pti: Fix boot warning from Global-bit setting x86/pti: Reduce amount of kernel text allowed to be Global x86/pti: Disallow global kernel text with RANDSTRUCT x86/pti: Filter at vma->vm_page_prot population arch/x86/Kconfig| 4 +++ arch/x86/entry/entry_64_compat.S| 8 ++--- arch/x86/include/asm/pgtable.h | 5 +++ arch/x86/mm/pageattr.c | 44 ++--- arch/x86/mm/pti.c | 26 +-- mm/mmap.c | 11 ++- tools/testing/selftests/x86/test_syscall_vdso.c | 35 7 files changed, 99 insertions(+), 34 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 00fcf81f2c56..c07f492b871a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -52,6 +52,7 @@ config X86 select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_FAST_MULTIPLIER + select ARCH_HAS_FILTER_PGPROT select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_KCOVif X86_64 @@ -273,6 +274,9 @@ config ARCH_HAS_CPU_RELAX config ARCH_HAS_CACHE_LINE_SIZE def_bool y +config ARCH_HAS_FILTER_PGPROT + def_bool y + config HAVE_SETUP_PER_CPU_AREA def_bool y diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index 9af927e59d49..9de7f1e1dede 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -84,13 +84,13 @@ ENTRY(entry_SYSENTER_compat) pushq %rdx/* pt_regs->dx */ pushq %rcx/* pt_regs->cx */ pushq $-ENOSYS/* pt_regs->ax */ - pushq $0 /* pt_regs->r8 = 0 */ + pushq %r8 /* pt_regs->r8 */ xorl%r8d, %r8d /* nospec r8 */ - pushq $0 /* pt_regs->r9 = 0 */ + pushq %r9 /* pt_regs->r9 */ xorl%r9d, %r9d /* nospec r9 */ - pushq $0 /* pt_regs->r10 = 0 */ + pushq %r10/* pt_regs->r10 */ xorl%r10d, %r10d/* nospec r10 */ - pushq $0 /* pt_regs->r11 = 0 */ + pushq %r11/* pt_regs->r11 */ xorl%r11d, %r11d/* nospec r11 */ pushq %rbx/* pt_regs->rbx */ xorl%ebx, %ebx /* nospec rbx */ diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 5f49b4ff0c24..f1633de5a675 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -601,6 +601,11 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) #define canon_pgprot(p) __pgprot(massage_pgprot(p)) +static inline pgprot_t arch_filter_pgprot(pgprot_t prot) +{ + return canon_pgprot(prot); +} + static inline int is_new_memtype_allowed(u64 paddr, unsigned long size, enum page_cache_mode pcm, enum page_cache_mode new_pcm) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 0f3d50f4c48c..3bded76e8d5c 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file *m) static
[GIT pull] x86/pti updates for 4.17
Linus, please pull the latest x86-pti-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-pti-for-linus Another series of PTI related changes: - Remove the manual stack switch for user entries from the idtentry code. This debloats entry by 5k+ bytes of text. - Use the proper types for the asm/bootparam.h defines to prevent user space compile errors. - Use PAGE_GLOBAL for !PCID systems to gain back performance - Prevent setting of huge PUD/PMD entries when the entries are not leaf entries otherwise the entries to which the PUD/PMD points to and are populated get lost. Thanks, tglx --> Andy Lutomirski (1): x86/entry/64: Drop idtentry's manual stack switch for user entries Dave Hansen (11): x86/mm: Factor out pageattr _PAGE_GLOBAL setting x86/mm: Undo double _PAGE_PSE clearing x86/mm: Introduce "default" kernel PTE mask x86/espfix: Document use of _PAGE_GLOBAL x86/mm: Do not auto-massage page protections x86/mm: Remove extra filtering in pageattr code x86/mm: Comment _PAGE_GLOBAL mystery x86/mm: Do not forbid _PAGE_RW before init for __ro_after_init x86/pti: Enable global pages for shared areas x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image x86/pti: Leave kernel text global for !PCID Dmitry V. Levin (1): x86/uapi: Fix asm/bootparam.h userspace compilation errors Joerg Roedel (1): x86/pgtable: Don't set huge PUD/PMD on non-leaf entries arch/x86/boot/compressed/kaslr.c | 3 + arch/x86/entry/entry_64.S | 4 +- arch/x86/include/asm/pgtable.h| 27 ++-- arch/x86/include/asm/pgtable_types.h | 29 arch/x86/include/asm/pti.h| 2 + arch/x86/include/uapi/asm/bootparam.h | 18 ++--- arch/x86/kernel/espfix_64.c | 4 ++ arch/x86/kernel/head64.c | 2 + arch/x86/kernel/head_64.S | 11 ++- arch/x86/kernel/ldt.c | 6 +- arch/x86/mm/cpu_entry_area.c | 14 +++- arch/x86/mm/ident_map.c | 3 + arch/x86/mm/init.c| 14 ++-- arch/x86/mm/init_32.c | 8 ++- arch/x86/mm/init_64.c | 11 +++ arch/x86/mm/iomap_32.c| 6 ++ arch/x86/mm/ioremap.c | 3 + arch/x86/mm/kasan_init_64.c | 14 +++- arch/x86/mm/pageattr.c| 97 -- arch/x86/mm/pgtable.c | 12 arch/x86/mm/pti.c | 126 -- arch/x86/power/hibernate_64.c | 20 -- 22 files changed, 329 insertions(+), 105 deletions(-) diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index 66e42a098d70..a0a50b91ecef 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -54,6 +54,9 @@ unsigned int ptrs_per_p4d __ro_after_init = 1; extern unsigned long get_cmd_line_ptr(void); +/* Used by PAGE_KERN* macros: */ +pteval_t __default_kernel_pte_mask __read_mostly = ~0; + /* Simplified build-specific string for starting entropy. */ static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION; diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 936e19642eab..cb1d8a3b870b 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -913,7 +913,7 @@ ENTRY(\sym) pushq $-1 /* ORIG_RAX: no syscall to restart */ .endif - .if \paranoid < 2 + .if \paranoid == 1 testb $3, CS-ORIG_RAX(%rsp) /* If coming from userspace, switch stacks */ jnz .Lfrom_usermode_switch_stack_\@ .endif @@ -960,7 +960,7 @@ ENTRY(\sym) jmp error_exit .endif - .if \paranoid < 2 + .if \paranoid == 1 /* * Entry from userspace. Switch stacks and treat it * as a normal entry. This means that paranoid handlers diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 89d5c8886c85..5f49b4ff0c24 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -526,22 +526,39 @@ static inline pgprotval_t massage_pgprot(pgprot_t pgprot) return protval; } +static inline pgprotval_t check_pgprot(pgprot_t pgprot) +{ + pgprotval_t massaged_val = massage_pgprot(pgprot); + + /* mmdebug.h can not be included here because of dependencies */ +#ifdef CONFIG_DEBUG_VM + WARN_ONCE(pgprot_val(pgprot) != massaged_val, + "attempted to set unsupported pgprot: %016llx " + "bits: %016llx supported: %016llx\n", + (u64)pgprot_val(pgprot), + (u64)pgprot_val(pgprot) ^ massaged_val, + (u64)__supported_pte_mask); +#endif + +
[GIT pull] x86/pti updates for 4.17
Linus, please pull the latest x86-pti-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-pti-for-linus Another series of PTI related changes: - Remove the manual stack switch for user entries from the idtentry code. This debloats entry by 5k+ bytes of text. - Use the proper types for the asm/bootparam.h defines to prevent user space compile errors. - Use PAGE_GLOBAL for !PCID systems to gain back performance - Prevent setting of huge PUD/PMD entries when the entries are not leaf entries otherwise the entries to which the PUD/PMD points to and are populated get lost. Thanks, tglx --> Andy Lutomirski (1): x86/entry/64: Drop idtentry's manual stack switch for user entries Dave Hansen (11): x86/mm: Factor out pageattr _PAGE_GLOBAL setting x86/mm: Undo double _PAGE_PSE clearing x86/mm: Introduce "default" kernel PTE mask x86/espfix: Document use of _PAGE_GLOBAL x86/mm: Do not auto-massage page protections x86/mm: Remove extra filtering in pageattr code x86/mm: Comment _PAGE_GLOBAL mystery x86/mm: Do not forbid _PAGE_RW before init for __ro_after_init x86/pti: Enable global pages for shared areas x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image x86/pti: Leave kernel text global for !PCID Dmitry V. Levin (1): x86/uapi: Fix asm/bootparam.h userspace compilation errors Joerg Roedel (1): x86/pgtable: Don't set huge PUD/PMD on non-leaf entries arch/x86/boot/compressed/kaslr.c | 3 + arch/x86/entry/entry_64.S | 4 +- arch/x86/include/asm/pgtable.h| 27 ++-- arch/x86/include/asm/pgtable_types.h | 29 arch/x86/include/asm/pti.h| 2 + arch/x86/include/uapi/asm/bootparam.h | 18 ++--- arch/x86/kernel/espfix_64.c | 4 ++ arch/x86/kernel/head64.c | 2 + arch/x86/kernel/head_64.S | 11 ++- arch/x86/kernel/ldt.c | 6 +- arch/x86/mm/cpu_entry_area.c | 14 +++- arch/x86/mm/ident_map.c | 3 + arch/x86/mm/init.c| 14 ++-- arch/x86/mm/init_32.c | 8 ++- arch/x86/mm/init_64.c | 11 +++ arch/x86/mm/iomap_32.c| 6 ++ arch/x86/mm/ioremap.c | 3 + arch/x86/mm/kasan_init_64.c | 14 +++- arch/x86/mm/pageattr.c| 97 -- arch/x86/mm/pgtable.c | 12 arch/x86/mm/pti.c | 126 -- arch/x86/power/hibernate_64.c | 20 -- 22 files changed, 329 insertions(+), 105 deletions(-) diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index 66e42a098d70..a0a50b91ecef 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -54,6 +54,9 @@ unsigned int ptrs_per_p4d __ro_after_init = 1; extern unsigned long get_cmd_line_ptr(void); +/* Used by PAGE_KERN* macros: */ +pteval_t __default_kernel_pte_mask __read_mostly = ~0; + /* Simplified build-specific string for starting entropy. */ static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION; diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 936e19642eab..cb1d8a3b870b 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -913,7 +913,7 @@ ENTRY(\sym) pushq $-1 /* ORIG_RAX: no syscall to restart */ .endif - .if \paranoid < 2 + .if \paranoid == 1 testb $3, CS-ORIG_RAX(%rsp) /* If coming from userspace, switch stacks */ jnz .Lfrom_usermode_switch_stack_\@ .endif @@ -960,7 +960,7 @@ ENTRY(\sym) jmp error_exit .endif - .if \paranoid < 2 + .if \paranoid == 1 /* * Entry from userspace. Switch stacks and treat it * as a normal entry. This means that paranoid handlers diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 89d5c8886c85..5f49b4ff0c24 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -526,22 +526,39 @@ static inline pgprotval_t massage_pgprot(pgprot_t pgprot) return protval; } +static inline pgprotval_t check_pgprot(pgprot_t pgprot) +{ + pgprotval_t massaged_val = massage_pgprot(pgprot); + + /* mmdebug.h can not be included here because of dependencies */ +#ifdef CONFIG_DEBUG_VM + WARN_ONCE(pgprot_val(pgprot) != massaged_val, + "attempted to set unsupported pgprot: %016llx " + "bits: %016llx supported: %016llx\n", + (u64)pgprot_val(pgprot), + (u64)pgprot_val(pgprot) ^ massaged_val, + (u64)__supported_pte_mask); +#endif + +