Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] swsusp: clean assembly parts

This patch fixes register saving so that each register is only saved once,
and adds missing saving of %cr8 on x86-64. Some reordering so that
save/restore is more logical/safer (segment registers should be restored
after gdt).

Signed-off-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Pavel Machek and committed by
Linus Torvalds
8d783b3e c61978b3

+17 -20
+7 -10
arch/i386/power/cpu.c
··· 44 44 */ 45 45 asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); 46 46 asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); 47 - asm volatile ("sldt %0" : "=m" (ctxt->ldt)); 48 47 asm volatile ("str %0" : "=m" (ctxt->tr)); 49 48 50 49 /* ··· 106 107 107 108 void __restore_processor_state(struct saved_context *ctxt) 108 109 { 109 - 110 110 /* 111 111 * control registers 112 112 */ ··· 115 117 asm volatile ("movl %0, %%cr0" :: "r" (ctxt->cr0)); 116 118 117 119 /* 120 + * now restore the descriptor tables to their proper values 121 + * ltr is done i fix_processor_context(). 122 + */ 123 + asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); 124 + asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); 125 + 126 + /* 118 127 * segment registers 119 128 */ 120 129 asm volatile ("movw %0, %%es" :: "r" (ctxt->es)); 121 130 asm volatile ("movw %0, %%fs" :: "r" (ctxt->fs)); 122 131 asm volatile ("movw %0, %%gs" :: "r" (ctxt->gs)); 123 132 asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss)); 124 - 125 - /* 126 - * now restore the descriptor tables to their proper values 127 - * ltr is done i fix_processor_context(). 128 - */ 129 - asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); 130 - asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); 131 - asm volatile ("lldt %0" :: "m" (ctxt->ldt)); 132 133 133 134 /* 134 135 * sysenter MSRs
+9 -9
arch/x86_64/kernel/suspend.c
··· 44 44 */ 45 45 asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); 46 46 asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); 47 - asm volatile ("sldt %0" : "=m" (ctxt->ldt)); 48 47 asm volatile ("str %0" : "=m" (ctxt->tr)); 49 48 50 49 /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */ ··· 68 69 asm volatile ("movq %%cr2, %0" : "=r" (ctxt->cr2)); 69 70 asm volatile ("movq %%cr3, %0" : "=r" (ctxt->cr3)); 70 71 asm volatile ("movq %%cr4, %0" : "=r" (ctxt->cr4)); 72 + asm volatile ("movq %%cr8, %0" : "=r" (ctxt->cr8)); 71 73 } 72 74 73 75 void save_processor_state(void) ··· 90 90 /* 91 91 * control registers 92 92 */ 93 + asm volatile ("movq %0, %%cr8" :: "r" (ctxt->cr8)); 93 94 asm volatile ("movq %0, %%cr4" :: "r" (ctxt->cr4)); 94 95 asm volatile ("movq %0, %%cr3" :: "r" (ctxt->cr3)); 95 96 asm volatile ("movq %0, %%cr2" :: "r" (ctxt->cr2)); 96 97 asm volatile ("movq %0, %%cr0" :: "r" (ctxt->cr0)); 98 + 99 + /* 100 + * now restore the descriptor tables to their proper values 101 + * ltr is done i fix_processor_context(). 102 + */ 103 + asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); 104 + asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); 97 105 98 106 /* 99 107 * segment registers ··· 115 107 wrmsrl(MSR_FS_BASE, ctxt->fs_base); 116 108 wrmsrl(MSR_GS_BASE, ctxt->gs_base); 117 109 wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); 118 - 119 - /* 120 - * now restore the descriptor tables to their proper values 121 - * ltr is done i fix_processor_context(). 122 - */ 123 - asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); 124 - asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); 125 - asm volatile ("lldt %0" :: "m" (ctxt->ldt)); 126 110 127 111 fix_processor_context(); 128 112
+1 -1
include/asm-x86_64/suspend.h
··· 16 16 struct saved_context { 17 17 u16 ds, es, fs, gs, ss; 18 18 unsigned long gs_base, gs_kernel_base, fs_base; 19 - unsigned long cr0, cr2, cr3, cr4; 19 + unsigned long cr0, cr2, cr3, cr4, cr8; 20 20 u16 gdt_pad; 21 21 u16 gdt_limit; 22 22 unsigned long gdt_base;