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

x86/xen: Fix 32-bit PV guests's usage of kernel_stack

Commit 198d208df4371734ac4728f69cb585c284d20a15 ("x86: Keep
thread_info on thread stack in x86_32") made 32-bit kernels use
kernel_stack to point to thread_info. That change missed a couple of
updates needed by Xen's 32-bit PV guests:

1. kernel_stack needs to be initialized for secondary CPUs

2. GET_THREAD_INFO() now uses %fs register which may not be the
kernel's version when executing xen_iret().

With respect to the second issue, we don't need GET_THREAD_INFO()
anymore: we used it as an intermediate step to get to per_cpu xen_vcpu
and avoid referencing %fs. Now that we are going to use %fs anyway we
may as well go directly to xen_vcpu.

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>

authored by

Boris Ostrovsky and committed by
David Vrabel
4461bbc0 d06eb3ee

+19 -9
+2 -1
arch/x86/xen/smp.c
··· 441 441 irq_ctx_init(cpu); 442 442 #else 443 443 clear_tsk_thread_flag(idle, TIF_FORK); 444 + #endif 444 445 per_cpu(kernel_stack, cpu) = 445 446 (unsigned long)task_stack_page(idle) - 446 447 KERNEL_STACK_OFFSET + THREAD_SIZE; 447 - #endif 448 + 448 449 xen_setup_runstate_info(cpu); 449 450 xen_setup_timer(cpu); 450 451 xen_init_lock_cpu(cpu);
+17 -8
arch/x86/xen/xen-asm_32.S
··· 75 75 * stack state in whatever form its in, we keep things simple by only 76 76 * using a single register which is pushed/popped on the stack. 77 77 */ 78 + 79 + .macro POP_FS 80 + 1: 81 + popw %fs 82 + .pushsection .fixup, "ax" 83 + 2: movw $0, (%esp) 84 + jmp 1b 85 + .popsection 86 + _ASM_EXTABLE(1b,2b) 87 + .endm 88 + 78 89 ENTRY(xen_iret) 79 90 /* test eflags for special cases */ 80 91 testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp) ··· 94 83 push %eax 95 84 ESP_OFFSET=4 # bytes pushed onto stack 96 85 97 - /* 98 - * Store vcpu_info pointer for easy access. Do it this way to 99 - * avoid having to reload %fs 100 - */ 86 + /* Store vcpu_info pointer for easy access */ 101 87 #ifdef CONFIG_SMP 102 - GET_THREAD_INFO(%eax) 103 - movl %ss:TI_cpu(%eax), %eax 104 - movl %ss:__per_cpu_offset(,%eax,4), %eax 105 - mov %ss:xen_vcpu(%eax), %eax 88 + pushw %fs 89 + movl $(__KERNEL_PERCPU), %eax 90 + movl %eax, %fs 91 + movl %fs:xen_vcpu, %eax 92 + POP_FS 106 93 #else 107 94 movl %ss:xen_vcpu, %eax 108 95 #endif