aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/xsave.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-12 15:04:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-12 15:05:14 -0400
commit807f4f8cdd5b65a8a5fcfda266c074f6a23818dd (patch)
tree395afdf45badd02d03871c827b8baa850cbe5841 /arch/x86/kernel/xsave.c
parent1a2217a9516b134e0a0e54cb4629e1e075d97b17 (diff)
parent8daf14cf56816303d64d1a705fcbc389211ba36e (diff)
Merge branch 'x86-core-v2-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
This merges in: x86/build, x86/microcode, x86/spinlocks, x86/memory-corruption-check, x86/early-printk, x86/xsave, x86/quirks, x86/setup, x86/signal, core/signal, x86/urgent, x86/xen * 'x86-core-v2-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (142 commits) x86: make processor type select depend on CONFIG_EMBEDDED x86: extend processor type select help text x86, amd-iommu: propagate PCI device enabling error warnings: fix arch/x86/kernel/io_apic_64.c warnings: fix arch/x86/kernel/early_printk.c x86, fpu: check __clear_user() return value x86: memory corruption check - cleanup x86: ioperm user_regset xen: do not reserve 2 pages of padding between hypervisor and fixmap. xen: use spin_lock_nest_lock when pinning a pagetable x86: xsave: set FP, SSE bits in the xsave header in the user sigcontext x86: xsave: fix error condition in save_i387_xstate() x86: SB450: deprioritize DMI quirks x86: SB450: skip IRQ0 override if it is not routed to INT2 of IOAPIC x86: replace a magic number with a named constant in the VESA boot code x86 setup: remove IMAGE_OFFSET x86 setup: remove DEF_INITSEG and DEF_SETUPSEG Revert "x86: fix ghost EDD devices in /sys again" x86 setup: fix ghost entries under /sys/firmware/edd take 3 x86: signal: remove indent in restore_sigcontext() ...
Diffstat (limited to 'arch/x86/kernel/xsave.c')
-rw-r--r--arch/x86/kernel/xsave.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index 07713d64debe..9abac8a9d823 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -95,7 +95,9 @@ int save_i387_xstate(void __user *buf)
95 * Start with clearing the user buffer. This will present a 95 * Start with clearing the user buffer. This will present a
96 * clean context for the bytes not touched by the fxsave/xsave. 96 * clean context for the bytes not touched by the fxsave/xsave.
97 */ 97 */
98 __clear_user(buf, sig_xstate_size); 98 err = __clear_user(buf, sig_xstate_size);
99 if (err)
100 return err;
99 101
100 if (task_thread_info(tsk)->status & TS_XSAVE) 102 if (task_thread_info(tsk)->status & TS_XSAVE)
101 err = xsave_user(buf); 103 err = xsave_user(buf);
@@ -114,6 +116,8 @@ int save_i387_xstate(void __user *buf)
114 116
115 if (task_thread_info(tsk)->status & TS_XSAVE) { 117 if (task_thread_info(tsk)->status & TS_XSAVE) {
116 struct _fpstate __user *fx = buf; 118 struct _fpstate __user *fx = buf;
119 struct _xstate __user *x = buf;
120 u64 xstate_bv;
117 121
118 err = __copy_to_user(&fx->sw_reserved, &fx_sw_reserved, 122 err = __copy_to_user(&fx->sw_reserved, &fx_sw_reserved,
119 sizeof(struct _fpx_sw_bytes)); 123 sizeof(struct _fpx_sw_bytes));
@@ -121,6 +125,31 @@ int save_i387_xstate(void __user *buf)
121 err |= __put_user(FP_XSTATE_MAGIC2, 125 err |= __put_user(FP_XSTATE_MAGIC2,
122 (__u32 __user *) (buf + sig_xstate_size 126 (__u32 __user *) (buf + sig_xstate_size
123 - FP_XSTATE_MAGIC2_SIZE)); 127 - FP_XSTATE_MAGIC2_SIZE));
128
129 /*
130 * Read the xstate_bv which we copied (directly from the cpu or
131 * from the state in task struct) to the user buffers and
132 * set the FP/SSE bits.
133 */
134 err |= __get_user(xstate_bv, &x->xstate_hdr.xstate_bv);
135
136 /*
137 * For legacy compatible, we always set FP/SSE bits in the bit
138 * vector while saving the state to the user context. This will
139 * enable us capturing any changes(during sigreturn) to
140 * the FP/SSE bits by the legacy applications which don't touch
141 * xstate_bv in the xsave header.
142 *
143 * xsave aware apps can change the xstate_bv in the xsave
144 * header as well as change any contents in the memory layout.
145 * xrestore as part of sigreturn will capture all the changes.
146 */
147 xstate_bv |= XSTATE_FPSSE;
148
149 err |= __put_user(xstate_bv, &x->xstate_hdr.xstate_bv);
150
151 if (err)
152 return err;
124 } 153 }
125 154
126 return 1; 155 return 1;
@@ -272,7 +301,7 @@ void __cpuinit xsave_init(void)
272/* 301/*
273 * setup the xstate image representing the init state 302 * setup the xstate image representing the init state
274 */ 303 */
275void setup_xstate_init(void) 304static void __init setup_xstate_init(void)
276{ 305{
277 init_xstate_buf = alloc_bootmem(xstate_size); 306 init_xstate_buf = alloc_bootmem(xstate_size);
278 init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT; 307 init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT;