]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - arch/x86/kernel/ptrace.c
x86, ptrace: regset extensions to support xstate
[net-next-2.6.git] / arch / x86 / kernel / ptrace.c
index 017d937639fef87694eea7cd3cbbf95efb163d37..16433a59b396ada7c947fb8d76a5c8a19d4139e2 100644 (file)
@@ -48,6 +48,7 @@ enum x86_regset {
        REGSET_FP,
        REGSET_XFP,
        REGSET_IOPERM64 = REGSET_XFP,
+       REGSET_XSTATE,
        REGSET_TLS,
        REGSET_IOPERM32,
 };
@@ -1584,7 +1585,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 #ifdef CONFIG_X86_64
 
-static const struct user_regset x86_64_regsets[] = {
+static struct user_regset x86_64_regsets[] __read_mostly = {
        [REGSET_GENERAL] = {
                .core_note_type = NT_PRSTATUS,
                .n = sizeof(struct user_regs_struct) / sizeof(long),
@@ -1597,6 +1598,12 @@ static const struct user_regset x86_64_regsets[] = {
                .size = sizeof(long), .align = sizeof(long),
                .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set
        },
+       [REGSET_XSTATE] = {
+               .core_note_type = NT_X86_XSTATE,
+               .size = sizeof(u64), .align = sizeof(u64),
+               .active = xstateregs_active, .get = xstateregs_get,
+               .set = xstateregs_set
+       },
        [REGSET_IOPERM64] = {
                .core_note_type = NT_386_IOPERM,
                .n = IO_BITMAP_LONGS,
@@ -1622,7 +1629,7 @@ static const struct user_regset_view user_x86_64_view = {
 #endif /* CONFIG_X86_64 */
 
 #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
-static const struct user_regset x86_32_regsets[] = {
+static struct user_regset x86_32_regsets[] __read_mostly = {
        [REGSET_GENERAL] = {
                .core_note_type = NT_PRSTATUS,
                .n = sizeof(struct user_regs_struct32) / sizeof(u32),
@@ -1641,6 +1648,12 @@ static const struct user_regset x86_32_regsets[] = {
                .size = sizeof(u32), .align = sizeof(u32),
                .active = xfpregs_active, .get = xfpregs_get, .set = xfpregs_set
        },
+       [REGSET_XSTATE] = {
+               .core_note_type = NT_X86_XSTATE,
+               .size = sizeof(u64), .align = sizeof(u64),
+               .active = xstateregs_active, .get = xstateregs_get,
+               .set = xstateregs_set
+       },
        [REGSET_TLS] = {
                .core_note_type = NT_386_TLS,
                .n = GDT_ENTRY_TLS_ENTRIES, .bias = GDT_ENTRY_TLS_MIN,
@@ -1663,6 +1676,23 @@ static const struct user_regset_view user_x86_32_view = {
 };
 #endif
 
+/*
+ * This represents bytes 464..511 in the memory layout exported through
+ * the REGSET_XSTATE interface.
+ */
+u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
+
+void update_regset_xstate_info(unsigned int size, u64 xstate_mask)
+{
+#ifdef CONFIG_X86_64
+       x86_64_regsets[REGSET_XSTATE].n = size / sizeof(u64);
+#endif
+#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
+       x86_32_regsets[REGSET_XSTATE].n = size / sizeof(u64);
+#endif
+       xstate_fx_sw_bytes[USER_XSTATE_XCR0_WORD] = xstate_mask;
+}
+
 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 {
 #ifdef CONFIG_IA32_EMULATION