diff options
author | Suresh Siddha <suresh.b.siddha@intel.com> | 2010-02-11 14:50:59 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-11 18:08:17 -0500 |
commit | 5b3efd500854d45d305b53c54c97db5970959980 (patch) | |
tree | 731629e22791d14b9661cada9c0c69eb38776c3b /arch/x86/kernel/ptrace.c | |
parent | 676ad585531e965416fd958747894541dabcec96 (diff) |
x86, ptrace: regset extensions to support xstate
Add the xstate regset support which helps extend the kernel ptrace and the
core-dump interfaces to support AVX state etc.
This regset interface is designed to support all the future state that gets
supported using xsave/xrstor infrastructure.
Looking at the memory layout saved by "xsave", one can't say which state
is represented in the memory layout. This is because if a particular state is
in init state, in the xsave hdr it can be represented by bit '0'. And hence
we can't really say by the xsave header wether a state is in init state or
the state is not saved in the memory layout.
And hence the xsave memory layout available through this regset
interface uses SW usable bytes [464..511] to convey what state is represented
in the memory layout.
First 8 bytes of the sw_usable_bytes[464..467] will be set to OS enabled xstate
mask(which is same as the 64bit mask returned by the xgetbv's xCR0).
The note NT_X86_XSTATE represents the extended state information in the
core file, using the above mentioned memory layout.
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
LKML-Reference: <20100211195614.802495327@sbs-t61.sc.intel.com>
Signed-off-by: Hongjiu Lu <hjl.tools@gmail.com>
Cc: Roland McGrath <roland@redhat.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/kernel/ptrace.c')
-rw-r--r-- | arch/x86/kernel/ptrace.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 017d937639fe..16433a59b396 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -48,6 +48,7 @@ enum x86_regset { | |||
48 | REGSET_FP, | 48 | REGSET_FP, |
49 | REGSET_XFP, | 49 | REGSET_XFP, |
50 | REGSET_IOPERM64 = REGSET_XFP, | 50 | REGSET_IOPERM64 = REGSET_XFP, |
51 | REGSET_XSTATE, | ||
51 | REGSET_TLS, | 52 | REGSET_TLS, |
52 | REGSET_IOPERM32, | 53 | REGSET_IOPERM32, |
53 | }; | 54 | }; |
@@ -1584,7 +1585,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | |||
1584 | 1585 | ||
1585 | #ifdef CONFIG_X86_64 | 1586 | #ifdef CONFIG_X86_64 |
1586 | 1587 | ||
1587 | static const struct user_regset x86_64_regsets[] = { | 1588 | static struct user_regset x86_64_regsets[] __read_mostly = { |
1588 | [REGSET_GENERAL] = { | 1589 | [REGSET_GENERAL] = { |
1589 | .core_note_type = NT_PRSTATUS, | 1590 | .core_note_type = NT_PRSTATUS, |
1590 | .n = sizeof(struct user_regs_struct) / sizeof(long), | 1591 | .n = sizeof(struct user_regs_struct) / sizeof(long), |
@@ -1597,6 +1598,12 @@ static const struct user_regset x86_64_regsets[] = { | |||
1597 | .size = sizeof(long), .align = sizeof(long), | 1598 | .size = sizeof(long), .align = sizeof(long), |
1598 | .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set | 1599 | .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set |
1599 | }, | 1600 | }, |
1601 | [REGSET_XSTATE] = { | ||
1602 | .core_note_type = NT_X86_XSTATE, | ||
1603 | .size = sizeof(u64), .align = sizeof(u64), | ||
1604 | .active = xstateregs_active, .get = xstateregs_get, | ||
1605 | .set = xstateregs_set | ||
1606 | }, | ||
1600 | [REGSET_IOPERM64] = { | 1607 | [REGSET_IOPERM64] = { |
1601 | .core_note_type = NT_386_IOPERM, | 1608 | .core_note_type = NT_386_IOPERM, |
1602 | .n = IO_BITMAP_LONGS, | 1609 | .n = IO_BITMAP_LONGS, |
@@ -1622,7 +1629,7 @@ static const struct user_regset_view user_x86_64_view = { | |||
1622 | #endif /* CONFIG_X86_64 */ | 1629 | #endif /* CONFIG_X86_64 */ |
1623 | 1630 | ||
1624 | #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION | 1631 | #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION |
1625 | static const struct user_regset x86_32_regsets[] = { | 1632 | static struct user_regset x86_32_regsets[] __read_mostly = { |
1626 | [REGSET_GENERAL] = { | 1633 | [REGSET_GENERAL] = { |
1627 | .core_note_type = NT_PRSTATUS, | 1634 | .core_note_type = NT_PRSTATUS, |
1628 | .n = sizeof(struct user_regs_struct32) / sizeof(u32), | 1635 | .n = sizeof(struct user_regs_struct32) / sizeof(u32), |
@@ -1641,6 +1648,12 @@ static const struct user_regset x86_32_regsets[] = { | |||
1641 | .size = sizeof(u32), .align = sizeof(u32), | 1648 | .size = sizeof(u32), .align = sizeof(u32), |
1642 | .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set | 1649 | .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set |
1643 | }, | 1650 | }, |
1651 | [REGSET_XSTATE] = { | ||
1652 | .core_note_type = NT_X86_XSTATE, | ||
1653 | .size = sizeof(u64), .align = sizeof(u64), | ||
1654 | .active = xstateregs_active, .get = xstateregs_get, | ||
1655 | .set = xstateregs_set | ||
1656 | }, | ||
1644 | [REGSET_TLS] = { | 1657 | [REGSET_TLS] = { |
1645 | .core_note_type = NT_386_TLS, | 1658 | .core_note_type = NT_386_TLS, |
1646 | .n = GDT_ENTRY_TLS_ENTRIES, .bias = GDT_ENTRY_TLS_MIN, | 1659 | .n = GDT_ENTRY_TLS_ENTRIES, .bias = GDT_ENTRY_TLS_MIN, |
@@ -1663,6 +1676,23 @@ static const struct user_regset_view user_x86_32_view = { | |||
1663 | }; | 1676 | }; |
1664 | #endif | 1677 | #endif |
1665 | 1678 | ||
1679 | /* | ||
1680 | * This represents bytes 464..511 in the memory layout exported through | ||
1681 | * the REGSET_XSTATE interface. | ||
1682 | */ | ||
1683 | u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS]; | ||
1684 | |||
1685 | void update_regset_xstate_info(unsigned int size, u64 xstate_mask) | ||
1686 | { | ||
1687 | #ifdef CONFIG_X86_64 | ||
1688 | x86_64_regsets[REGSET_XSTATE].n = size / sizeof(u64); | ||
1689 | #endif | ||
1690 | #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION | ||
1691 | x86_32_regsets[REGSET_XSTATE].n = size / sizeof(u64); | ||
1692 | #endif | ||
1693 | xstate_fx_sw_bytes[USER_XSTATE_XCR0_WORD] = xstate_mask; | ||
1694 | } | ||
1695 | |||
1666 | const struct user_regset_view *task_user_regset_view(struct task_struct *task) | 1696 | const struct user_regset_view *task_user_regset_view(struct task_struct *task) |
1667 | { | 1697 | { |
1668 | #ifdef CONFIG_IA32_EMULATION | 1698 | #ifdef CONFIG_IA32_EMULATION |