summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2003-03-09 02:49:41 -0800
committerLinus Torvalds <torvalds@home.transmeta.com>2003-03-09 02:49:41 -0800
commit36f0619922472bf8e5ecf83ac420114952a87bf3 (patch)
tree65effd9c155da6774b45ddb3ab23e9f23add6098 /include
parentd1537fd1c7a1fa9303467825eb5a764cb229df10 (diff)
Cache the MSR_IA32_SYSENTER_CS value in the per-CPU TSS (using
the otherwise unused cpl1 entry for SS), so that we can avoid re-loading it on task switches if it doesn't change.
Diffstat (limited to 'include')
-rw-r--r--include/asm-i386/processor.h13
1 files changed, 9 insertions, 4 deletions
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 5ed85117e7ef..00014406c6ac 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -347,7 +347,7 @@ struct tss_struct {
unsigned long esp0;
unsigned short ss0,__ss0h;
unsigned long esp1;
- unsigned short ss1,__ss1h;
+ unsigned short ss1,__ss1h; /* ss1 is used to cache MSR_IA32_SYSENTER_CS */
unsigned long esp2;
unsigned short ss2,__ss2h;
unsigned long __cr3;
@@ -413,15 +413,20 @@ static inline void load_esp0(struct tss_struct *tss, unsigned long esp0)
{
tss->esp0 = esp0;
if (cpu_has_sep) {
- wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
+ if (tss->ss1 != __KERNEL_CS) {
+ tss->ss1 = __KERNEL_CS;
+ wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
+ }
wrmsr(MSR_IA32_SYSENTER_ESP, esp0, 0);
}
}
-static inline void disable_sysenter(void)
+static inline void disable_sysenter(struct tss_struct *tss)
{
- if (cpu_has_sep)
+ if (cpu_has_sep) {
+ tss->ss1 = 0;
wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);
+ }
}
#define start_thread(regs, new_eip, new_esp) do { \