diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-12 15:04:59 -0400 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-12 15:05:14 -0400 | 
| commit | 807f4f8cdd5b65a8a5fcfda266c074f6a23818dd (patch) | |
| tree | 395afdf45badd02d03871c827b8baa850cbe5841 /arch/x86/kernel/xsave.c | |
| parent | 1a2217a9516b134e0a0e54cb4629e1e075d97b17 (diff) | |
| parent | 8daf14cf56816303d64d1a705fcbc389211ba36e (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.c | 33 | 
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 | */ | 
| 275 | void setup_xstate_init(void) | 304 | static 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; | 
