summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/setup.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-05 22:27:28 -0800
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 01:11:50 -0800
commit45fec05f805a113372c9a7ff4c653ac749f6921c (patch)
tree36fc99d10656775acb8e9442719447d64ac30a03 /arch/sparc64/kernel/setup.c
parent314981ac7177a933319e3c071a5cf0a579205e6e (diff)
[SPARC64]: Sanitize %pstate writes for sun4v.
If we're just switching between different alternate global sets, nop it out on sun4v. Also, get rid of all of the alternate global save/restore in the OBP CIF trampoline code. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/setup.c')
-rw-r--r--arch/sparc64/kernel/setup.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index aaab319ad88..e22bf5fc92c 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -547,19 +547,33 @@ static void __init per_cpu_patch(void)
static void __init gl_patch(void)
{
- struct gl_1insn_patch_entry *p;
+ struct gl_1insn_patch_entry *p1;
+ struct gl_2insn_patch_entry *p2;
if (tlb_type != hypervisor)
return;
- p = &__gl_1insn_patch;
- while (p < &__gl_1insn_patch_end) {
- unsigned long addr = p->addr;
+ p1 = &__gl_1insn_patch;
+ while (p1 < &__gl_1insn_patch_end) {
+ unsigned long addr = p1->addr;
- *(unsigned int *) (addr + 0) = p->insn;
+ *(unsigned int *) (addr + 0) = p1->insn;
__asm__ __volatile__("flush %0" : : "r" (addr + 0));
- p++;
+ p1++;
+ }
+
+ p2 = &__gl_2insn_patch;
+ while (p2 < &__gl_2insn_patch_end) {
+ unsigned long addr = p2->addr;
+
+ *(unsigned int *) (addr + 0) = p2->insns[0];
+ __asm__ __volatile__("flush %0" : : "r" (addr + 0));
+
+ *(unsigned int *) (addr + 3) = p2->insns[1];
+ __asm__ __volatile__("flush %0" : : "r" (addr + 4));
+
+ p2++;
}
}