x86: Load __USER_DS into DS/ES after resume
authorIngo Molnar <mingo@kernel.org>
Mon, 22 Jun 2015 12:40:03 +0000 (14:40 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 22 Jun 2015 12:40:03 +0000 (14:40 +0200)
Srinivas Pandruvada reported a problem with system resume from
suspend-to-RAM on 32-bit x86 systems where the DS register of
the CPU is set to __KERNEL_DS instead of __USER_DS on return
to user space which cases a General Protection Fault to occur.

The issue is that DS is set to __KERNEL_DS by the ACPI resume code
path while the SYSEXIT path never reloads DS/ES.  It assumes they
are still __USER_DS set at the SYSENTER time (Brian Gerst), so if
the return to user space happens to be through SYSEXIT, it will lead
to the reported GPF.

Fix the problem by setting the DS and ES registers to __USER_DS
as expected by the SYSEXIT path.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=61781
Link: http://marc.info/?l=linux-pm&m=143406648920385&w=2
Acked-by: Pavel Machek <pavel@ucw.cz>
Tested-by: Pavel Machek <pavel@ucw.cz>
Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
arch/x86/kernel/acpi/wakeup_32.S

index 665c6b7d2ea93c25740a4b18043d5602d33d9711..0c26b1b44e51aeffb72a6daa151049880f52892f 100644 (file)
@@ -12,11 +12,13 @@ ENTRY(wakeup_pmode_return)
 wakeup_pmode_return:
        movw    $__KERNEL_DS, %ax
        movw    %ax, %ss
-       movw    %ax, %ds
-       movw    %ax, %es
        movw    %ax, %fs
        movw    %ax, %gs
 
+       movw    $__USER_DS, %ax
+       movw    %ax, %ds
+       movw    %ax, %es
+
        # reload the gdt, as we need the full 32 bit address
        lidt    saved_idt
        lldt    saved_ldt