2018-02-26 23:26:59

by Tom Lendacky

[permalink] [raw]
Subject: [PATCH] x86/mm/sme: Disable stack protection for mem_encrypt_identity.c

Stack protection is not compatible with early boot code. All of the early
SME boot code is now isolated in a separate file, mem_encrypt_identity.c,
so arch/x86/mm/Makefile can be updated to turn off stack protection for
the entire file. This eliminates the need to worry about other functions
within the file being instrumented with stack protection (as was seen
when a newer version of GCC instrumented sme_encrypt_kernel() where an
older version hadn't). It also allows removal of the __nostackprotector
attribute from individual functions.

Signed-off-by: Tom Lendacky <[email protected]>
---
arch/x86/mm/Makefile | 1 +
arch/x86/mm/mem_encrypt_identity.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 03c6c85..4b101dd 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -19,6 +19,7 @@ obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
nostackp := $(call cc-option, -fno-stack-protector)
CFLAGS_physaddr.o := $(nostackp)
CFLAGS_setup_nx.o := $(nostackp)
+CFLAGS_mem_encrypt_identity.o := $(nostackp)

CFLAGS_fault.o := -I$(src)/../include/asm/trace

diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index b4139c5..1b2197d 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -266,7 +266,7 @@ static unsigned long __init sme_pgtable_calc(unsigned long len)
return entries + tables;
}

-void __init __nostackprotector sme_encrypt_kernel(struct boot_params *bp)
+void __init sme_encrypt_kernel(struct boot_params *bp)
{
unsigned long workarea_start, workarea_end, workarea_len;
unsigned long execute_start, execute_end, execute_len;
@@ -468,7 +468,7 @@ void __init __nostackprotector sme_encrypt_kernel(struct boot_params *bp)
native_write_cr3(__native_read_cr3());
}

-void __init __nostackprotector sme_enable(struct boot_params *bp)
+void __init sme_enable(struct boot_params *bp)
{
const char *cmdline_ptr, *cmdline_arg, *cmdline_on, *cmdline_off;
unsigned int eax, ebx, ecx, edx;



2018-02-27 09:29:30

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH] x86/mm/sme: Disable stack protection for mem_encrypt_identity.c

On Mon, Feb 26, 2018 at 05:25:54PM -0600, Tom Lendacky wrote:
> Stack protection is not compatible with early boot code. All of the early
> SME boot code is now isolated in a separate file, mem_encrypt_identity.c,
> so arch/x86/mm/Makefile can be updated to turn off stack protection for
> the entire file. This eliminates the need to worry about other functions
> within the file being instrumented with stack protection (as was seen
> when a newer version of GCC instrumented sme_encrypt_kernel() where an
> older version hadn't). It also allows removal of the __nostackprotector
> attribute from individual functions.
>
> Signed-off-by: Tom Lendacky <[email protected]>
> ---
> arch/x86/mm/Makefile | 1 +
> arch/x86/mm/mem_encrypt_identity.c | 4 ++--
> 2 files changed, 3 insertions(+), 2 deletions(-)

Reviewed-by: Borislav Petkov <[email protected]>

--
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

2018-02-27 15:44:39

by Kirill A. Shutemov

[permalink] [raw]
Subject: Re: [PATCH] x86/mm/sme: Disable stack protection for mem_encrypt_identity.c

On Mon, Feb 26, 2018 at 05:25:54PM -0600, Tom Lendacky wrote:
> Stack protection is not compatible with early boot code. All of the early
> SME boot code is now isolated in a separate file, mem_encrypt_identity.c,
> so arch/x86/mm/Makefile can be updated to turn off stack protection for
> the entire file. This eliminates the need to worry about other functions
> within the file being instrumented with stack protection (as was seen
> when a newer version of GCC instrumented sme_encrypt_kernel() where an
> older version hadn't). It also allows removal of the __nostackprotector
> attribute from individual functions.
>
> Signed-off-by: Tom Lendacky <[email protected]>

Looks good to me.

Acked-by: Kirill A. Shutemov <[email protected]>

--
Kirill A. Shutemov

Subject: [tip:x86/apic] x86/apic: Move pending intr check code into it's own function

Commit-ID: 0da89dfa7a6a85e2bab44462fe960ce41eecc4c9
Gitweb: https://git.kernel.org/tip/0da89dfa7a6a85e2bab44462fe960ce41eecc4c9
Author: Dou Liyang <[email protected]>
AuthorDate: Mon, 26 Feb 2018 10:39:56 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 28 Feb 2018 15:02:58 +0100

x86/apic: Move pending intr check code into it's own function

The pending interrupt check code is mixed with the local APIC setup code,
that looks messy.

Extract the related code, move it into a new function named
apic_pending_intr_clear().

Signed-off-by: Dou Liyang <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Reviewed-by: Andy Shevchenko <[email protected]>
Cc: [email protected]
Cc: [email protected]
Link: https://lkml.kernel.org/r/[email protected]

---
arch/x86/kernel/apic/apic.c | 98 ++++++++++++++++++++++++---------------------
1 file changed, 52 insertions(+), 46 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 2ceac9f6c5d7..3fda9734db25 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1408,6 +1408,56 @@ static void lapic_setup_esr(void)
oldvalue, value);
}

+static void apic_pending_intr_clear(void)
+{
+ long long max_loops = cpu_khz ? cpu_khz : 1000000;
+ unsigned long long tsc = 0, ntsc;
+ unsigned int value, queued;
+ int i, j, acked = 0;
+
+ if (boot_cpu_has(X86_FEATURE_TSC))
+ tsc = rdtsc();
+ /*
+ * After a crash, we no longer service the interrupts and a pending
+ * interrupt from previous kernel might still have ISR bit set.
+ *
+ * Most probably by now CPU has serviced that pending interrupt and
+ * it might not have done the ack_APIC_irq() because it thought,
+ * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
+ * does not clear the ISR bit and cpu thinks it has already serivced
+ * the interrupt. Hence a vector might get locked. It was noticed
+ * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
+ */
+ do {
+ queued = 0;
+ for (i = APIC_ISR_NR - 1; i >= 0; i--)
+ queued |= apic_read(APIC_IRR + i*0x10);
+
+ for (i = APIC_ISR_NR - 1; i >= 0; i--) {
+ value = apic_read(APIC_ISR + i*0x10);
+ for (j = 31; j >= 0; j--) {
+ if (value & (1<<j)) {
+ ack_APIC_irq();
+ acked++;
+ }
+ }
+ }
+ if (acked > 256) {
+ printk(KERN_ERR "LAPIC pending interrupts after %d EOI\n",
+ acked);
+ break;
+ }
+ if (queued) {
+ if (boot_cpu_has(X86_FEATURE_TSC) && cpu_khz) {
+ ntsc = rdtsc();
+ max_loops = (cpu_khz << 10) - (ntsc - tsc);
+ } else
+ max_loops--;
+ }
+ } while (queued && max_loops > 0);
+ WARN_ON(max_loops <= 0);
+}
+
/**
* setup_local_APIC - setup the local APIC
*
@@ -1417,13 +1467,7 @@ static void lapic_setup_esr(void)
static void setup_local_APIC(void)
{
int cpu = smp_processor_id();
- unsigned int value, queued;
- int i, j, acked = 0;
- unsigned long long tsc = 0, ntsc;
- long long max_loops = cpu_khz ? cpu_khz : 1000000;
-
- if (boot_cpu_has(X86_FEATURE_TSC))
- tsc = rdtsc();
+ unsigned int value;

if (disable_apic) {
disable_ioapic_support();
@@ -1475,45 +1519,7 @@ static void setup_local_APIC(void)
value &= ~APIC_TPRI_MASK;
apic_write(APIC_TASKPRI, value);

- /*
- * After a crash, we no longer service the interrupts and a pending
- * interrupt from previous kernel might still have ISR bit set.
- *
- * Most probably by now CPU has serviced that pending interrupt and
- * it might not have done the ack_APIC_irq() because it thought,
- * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
- * does not clear the ISR bit and cpu thinks it has already serivced
- * the interrupt. Hence a vector might get locked. It was noticed
- * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
- */
- do {
- queued = 0;
- for (i = APIC_ISR_NR - 1; i >= 0; i--)
- queued |= apic_read(APIC_IRR + i*0x10);
-
- for (i = APIC_ISR_NR - 1; i >= 0; i--) {
- value = apic_read(APIC_ISR + i*0x10);
- for (j = 31; j >= 0; j--) {
- if (value & (1<<j)) {
- ack_APIC_irq();
- acked++;
- }
- }
- }
- if (acked > 256) {
- printk(KERN_ERR "LAPIC pending interrupts after %d EOI\n",
- acked);
- break;
- }
- if (queued) {
- if (boot_cpu_has(X86_FEATURE_TSC) && cpu_khz) {
- ntsc = rdtsc();
- max_loops = (cpu_khz << 10) - (ntsc - tsc);
- } else
- max_loops--;
- }
- } while (queued && max_loops > 0);
- WARN_ON(max_loops <= 0);
+ apic_pending_intr_clear();

/*
* Now that we are all set up, enable the APIC

Subject: [tip:x86/apic] x86/apic: Replace common tools with new ones

Commit-ID: eb088bc5133167ca7790bae351761f5448a8941d
Gitweb: https://git.kernel.org/tip/eb088bc5133167ca7790bae351761f5448a8941d
Author: Dou Liyang <[email protected]>
AuthorDate: Mon, 26 Feb 2018 10:39:57 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 28 Feb 2018 15:02:58 +0100

x86/apic: Replace common tools with new ones

The pending interrupt check code is old, update the following.

-Replace for-if pair with for_each_set_bit()
-Replace printk() with pr_err()

Also merge the printk's code in one line and make curly braces balanced

Signed-off-by: Dou Liyang <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Reviewed-by: Andy Shevchenko <[email protected]>
Cc: [email protected]
Cc: [email protected]
Link: https://lkml.kernel.org/r/[email protected]

---
arch/x86/kernel/apic/apic.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 3fda9734db25..4704a3541b11 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1412,7 +1412,8 @@ static void apic_pending_intr_clear(void)
{
long long max_loops = cpu_khz ? cpu_khz : 1000000;
unsigned long long tsc = 0, ntsc;
- unsigned int value, queued;
+ unsigned int queued;
+ unsigned long value;
int i, j, acked = 0;

if (boot_cpu_has(X86_FEATURE_TSC))
@@ -1435,24 +1436,22 @@ static void apic_pending_intr_clear(void)

for (i = APIC_ISR_NR - 1; i >= 0; i--) {
value = apic_read(APIC_ISR + i*0x10);
- for (j = 31; j >= 0; j--) {
- if (value & (1<<j)) {
- ack_APIC_irq();
- acked++;
- }
+ for_each_set_bit(j, &value, 32) {
+ ack_APIC_irq();
+ acked++;
}
}
if (acked > 256) {
- printk(KERN_ERR "LAPIC pending interrupts after %d EOI\n",
- acked);
+ pr_err("LAPIC pending interrupts after %d EOI\n", acked);
break;
}
if (queued) {
if (boot_cpu_has(X86_FEATURE_TSC) && cpu_khz) {
ntsc = rdtsc();
max_loops = (cpu_khz << 10) - (ntsc - tsc);
- } else
+ } else {
max_loops--;
+ }
}
} while (queued && max_loops > 0);
WARN_ON(max_loops <= 0);

Subject: [tip:x86/mm] x86/mm/sme: Disable stack protection for mem_encrypt_identity.c

Commit-ID: ae8d1d0061ad7996c2c5e769e809a593544fa145
Gitweb: https://git.kernel.org/tip/ae8d1d0061ad7996c2c5e769e809a593544fa145
Author: Tom Lendacky <[email protected]>
AuthorDate: Mon, 26 Feb 2018 17:25:54 -0600
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 28 Feb 2018 15:24:12 +0100

x86/mm/sme: Disable stack protection for mem_encrypt_identity.c

Stack protection is not compatible with early boot code. All of the early
SME boot code is now isolated in a separate file, mem_encrypt_identity.c,
so arch/x86/mm/Makefile can be updated to turn off stack protection for
the entire file. This eliminates the need to worry about other functions
within the file being instrumented with stack protection (as was seen
when a newer version of GCC instrumented sme_encrypt_kernel() where an
older version hadn't). It also allows removal of the __nostackprotector
attribute from individual functions.

Signed-off-by: Tom Lendacky <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Reviewed-by: Borislav Petkov <[email protected]>
Acked-by: Kirill A. Shutemov <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Borislav Petkov <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]

---
arch/x86/mm/Makefile | 1 +
arch/x86/mm/mem_encrypt_identity.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 03c6c8561623..4b101dd6e52f 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -19,6 +19,7 @@ obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
nostackp := $(call cc-option, -fno-stack-protector)
CFLAGS_physaddr.o := $(nostackp)
CFLAGS_setup_nx.o := $(nostackp)
+CFLAGS_mem_encrypt_identity.o := $(nostackp)

CFLAGS_fault.o := -I$(src)/../include/asm/trace

diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index b4139c5ab972..1b2197d13832 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -266,7 +266,7 @@ static unsigned long __init sme_pgtable_calc(unsigned long len)
return entries + tables;
}

-void __init __nostackprotector sme_encrypt_kernel(struct boot_params *bp)
+void __init sme_encrypt_kernel(struct boot_params *bp)
{
unsigned long workarea_start, workarea_end, workarea_len;
unsigned long execute_start, execute_end, execute_len;
@@ -468,7 +468,7 @@ void __init __nostackprotector sme_encrypt_kernel(struct boot_params *bp)
native_write_cr3(__native_read_cr3());
}

-void __init __nostackprotector sme_enable(struct boot_params *bp)
+void __init sme_enable(struct boot_params *bp)
{
const char *cmdline_ptr, *cmdline_arg, *cmdline_on, *cmdline_off;
unsigned int eax, ebx, ecx, edx;