lkml.org 
[lkml]   [2005]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: [PATCH 1/10] Cr4 is valid on some 486s
> Yep, extending alternatives is probably better than duplicating the 
> code. Maybe having some alternative_smp() macro which places both code
> versions into the .altinstr_replacement table? If that sounds ok I'll
> try to come up with a experimental patch.

i.e. something like this (as basic idea, patch is far away from doing
anything useful ...)?

Gerd
diff -pu -urp linux-2.6.14/arch/i386/kernel/setup.c work-2.6.14/arch/i386/kernel/setup.c
--- linux-2.6.14/arch/i386/kernel/setup.c 2005-10-28 02:02:08.000000000 +0200
+++ work-2.6.14/arch/i386/kernel/setup.c 2005-11-15 16:49:13.000000000 +0100
@@ -1435,9 +1435,9 @@ void apply_alternatives(void *start, voi
}
}
for (a = start; (void *)a < end; a++) {
+ BUG_ON(a->replacementlen > a->instrlen);
if (!boot_cpu_has(a->cpuid))
continue;
- BUG_ON(a->replacementlen > a->instrlen);
memcpy(a->instr, a->replacement, a->replacementlen);
diff = a->instrlen - a->replacementlen;
/* Pad the rest with nops */
@@ -1450,6 +1450,19 @@ void apply_alternatives(void *start, voi
}
}

+void apply_alternatives_smp(void *start, void *end)
+{
+ struct alt_instr *a;
+
+ for (a = start; (void *)a < end; a++) {
+ if (X86_FEATURE_UP != a->cpuid)
+ continue;
+ memcpy(a->instr,
+ a->replacement + a->replacementlen,
+ a->instrlen);
+ }
+}
+
void __init alternative_instructions(void)
{
extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
diff -pu -urp linux-2.6.14/include/asm-i386/cpufeature.h work-2.6.14/include/asm-i386/cpufeature.h
--- linux-2.6.14/include/asm-i386/cpufeature.h 2005-10-28 02:02:08.000000000 +0200
+++ work-2.6.14/include/asm-i386/cpufeature.h 2005-11-15 15:52:03.000000000 +0100
@@ -70,6 +70,8 @@
#define X86_FEATURE_P3 (3*32+ 6) /* P3 */
#define X86_FEATURE_P4 (3*32+ 7) /* P4 */

+#define X86_FEATURE_UP (3*32+ 8) /* smp kernel running on up */
+
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
#define X86_FEATURE_MWAIT (4*32+ 3) /* Monitor/Mwait support */
diff -pu -urp linux-2.6.14/include/asm-i386/system.h work-2.6.14/include/asm-i386/system.h
--- linux-2.6.14/include/asm-i386/system.h 2005-10-28 02:02:08.000000000 +0200
+++ work-2.6.14/include/asm-i386/system.h 2005-11-15 15:47:43.000000000 +0100
@@ -329,6 +329,25 @@ struct alt_instr {
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
".previous" :: "i" (feature) : "memory")

+#ifdef CONFIG_SMP
+#define alternative_smp(smpinstr, upinstr, input) \
+ asm volatile ("661:\n\t" smpinstr "\n662:\n" \
+ ".section .altinstructions,\"a\"\n" \
+ " .align 4\n" \
+ " .long 661b\n" /* label */ \
+ " .long 663f\n" /* new instruction */ \
+ " .byte %c0\n" /* feature bit */ \
+ " .byte 662b-661b\n" /* sourcelen */ \
+ " .byte 664f-663f\n" /* replacementlen */ \
+ ".previous\n" \
+ ".section .altinstr_replacement,\"ax\"\n" \
+ "663:\n\t" upinstr "\n" /* replacement */ \
+ "664:\n\t" smpinstr "\n" /* original again */ \
+ ".previous" :: "i" (X86_FEATURE_UP), ##input)
+#else
+#define alternative_smp(smpinstr, upinstr) asm(upinstr, ##input)
+#endif
+
/*
* Alternative inline assembly with input.
*
\
 
 \ /
  Last update: 2005-11-15 17:03    [W:0.133 / U:0.324 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site