aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorEduardo Habkost <ehabkost@redhat.com>2008-07-08 18:07:10 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-16 05:04:55 -0400
commit8a95408e183b3e4aaf3b6a66fa34bff4db53011b (patch)
treeaf3d69d791d65fe324d4883fbe6a2e3d5f065fd0 /arch/x86
parent4a5c3e77f70b3ea8b361d7fa9eb2e4dad18f70ae (diff)
xen64: Clear %fs on xen_load_tls()
We need to do this, otherwise we can get a GPF on hypercall return after TLS descriptor is cleared but %fs is still pointing to it. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Cc: Stephen Tweedie <sct@redhat.com> Cc: Eduardo Habkost <ehabkost@redhat.com> Cc: Mark McLoughlin <markmc@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/xen/enlighten.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 0172ba774523..c13698faae54 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -364,14 +364,6 @@ static void load_TLS_descriptor(struct thread_struct *t,
364 364
365static void xen_load_tls(struct thread_struct *t, unsigned int cpu) 365static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
366{ 366{
367 xen_mc_batch();
368
369 load_TLS_descriptor(t, cpu, 0);
370 load_TLS_descriptor(t, cpu, 1);
371 load_TLS_descriptor(t, cpu, 2);
372
373 xen_mc_issue(PARAVIRT_LAZY_CPU);
374
375 /* 367 /*
376 * XXX sleazy hack: If we're being called in a lazy-cpu zone, 368 * XXX sleazy hack: If we're being called in a lazy-cpu zone,
377 * it means we're in a context switch, and %gs has just been 369 * it means we're in a context switch, and %gs has just been
@@ -380,9 +372,30 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
380 * Either way, it has been saved, and the new value will get 372 * Either way, it has been saved, and the new value will get
381 * loaded properly. This will go away as soon as Xen has been 373 * loaded properly. This will go away as soon as Xen has been
382 * modified to not save/restore %gs for normal hypercalls. 374 * modified to not save/restore %gs for normal hypercalls.
375 *
376 * On x86_64, this hack is not used for %gs, because gs points
377 * to KERNEL_GS_BASE (and uses it for PDA references), so we
378 * must not zero %gs on x86_64
379 *
380 * For x86_64, we need to zero %fs, otherwise we may get an
381 * exception between the new %fs descriptor being loaded and
382 * %fs being effectively cleared at __switch_to().
383 */ 383 */
384 if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) 384 if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) {
385#ifdef CONFIG_X86_32
385 loadsegment(gs, 0); 386 loadsegment(gs, 0);
387#else
388 loadsegment(fs, 0);
389#endif
390 }
391
392 xen_mc_batch();
393
394 load_TLS_descriptor(t, cpu, 0);
395 load_TLS_descriptor(t, cpu, 1);
396 load_TLS_descriptor(t, cpu, 2);
397
398 xen_mc_issue(PARAVIRT_LAZY_CPU);
386} 399}
387 400
388#ifdef CONFIG_X86_64 401#ifdef CONFIG_X86_64