Selaa lähdekoodia

[PATCH] x86_64: Save original IST values for checking stack addresses

The values in init_tss.ist[] can change when an IST event occurs.  Save
the original IST values for checking stack addresses when debugging or
doing stack traces.

Signed-off-by: Keith Owens <kaos@ocs.com.au>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Keith Owens 19 vuotta sitten
vanhempi
commit
01ebb77b31

+ 5 - 0
arch/x86_64/kernel/init_task.c

@@ -46,4 +46,9 @@ EXPORT_SYMBOL(init_task);
  */ 
  */ 
 DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
 DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
 
 
+/* Copies of the original ist values from the tss are only accessed during
+ * debugging, no special alignment required.
+ */
+DEFINE_PER_CPU(struct orig_ist, orig_ist);
+
 #define ALIGN_TO_4K __attribute__((section(".data.init_task")))
 #define ALIGN_TO_4K __attribute__((section(".data.init_task")))

+ 2 - 1
arch/x86_64/kernel/setup64.c

@@ -189,6 +189,7 @@ void __cpuinit cpu_init (void)
 {
 {
 	int cpu = stack_smp_processor_id();
 	int cpu = stack_smp_processor_id();
 	struct tss_struct *t = &per_cpu(init_tss, cpu);
 	struct tss_struct *t = &per_cpu(init_tss, cpu);
+	struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
 	unsigned long v; 
 	unsigned long v; 
 	char *estacks = NULL; 
 	char *estacks = NULL; 
 	struct task_struct *me;
 	struct task_struct *me;
@@ -256,7 +257,7 @@ void __cpuinit cpu_init (void)
 			estacks += EXCEPTION_STKSZ;
 			estacks += EXCEPTION_STKSZ;
 			break;
 			break;
 		}
 		}
-		t->ist[v] = (unsigned long)estacks;
+		orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks;
 	}
 	}
 
 
 	t->io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
 	t->io_bitmap_base = offsetof(struct tss_struct, io_bitmap);

+ 1 - 1
arch/x86_64/kernel/traps.c

@@ -178,7 +178,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
 			break;
 			break;
 #endif
 #endif
 		default:
 		default:
-			end = per_cpu(init_tss, cpu).ist[k];
+			end = per_cpu(orig_ist, cpu).ist[k];
 			break;
 			break;
 		}
 		}
 		/*
 		/*

+ 6 - 0
include/asm-x86_64/processor.h

@@ -232,8 +232,14 @@ struct tss_struct {
 	unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
 	unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
 } __attribute__((packed)) ____cacheline_aligned;
 } __attribute__((packed)) ____cacheline_aligned;
 
 
+
 extern struct cpuinfo_x86 boot_cpu_data;
 extern struct cpuinfo_x86 boot_cpu_data;
 DECLARE_PER_CPU(struct tss_struct,init_tss);
 DECLARE_PER_CPU(struct tss_struct,init_tss);
+/* Save the original ist values for checking stack pointers during debugging */
+struct orig_ist {
+	unsigned long ist[7];
+};
+DECLARE_PER_CPU(struct orig_ist, orig_ist);
 
 
 #ifdef CONFIG_X86_VSMP
 #ifdef CONFIG_X86_VSMP
 #define ARCH_MIN_TASKALIGN	(1 << INTERNODE_CACHE_SHIFT)
 #define ARCH_MIN_TASKALIGN	(1 << INTERNODE_CACHE_SHIFT)