Hi Inog, Today's linux-next merge of the sparseirq tree got a conflict in arch/x86/kernel/ptrace.c between commit 393084e9e8c20c63cef574a6466ec0e59c711727 ("x86: ioperm user_regset") from the x86 tree and commit 93fa7636dfdc059b25df148f230c0991096afdef ("x86, ptrace: PEBS support") from the sparseirq tree. Mostly overlapping additions/changes. I fixed it up (see below) and can carry the fix. -- Cheers, Stephen Rothwell sfr@xxxxxxxxxxxxxxxx http://www.canb.auug.org.au/~sfr/ diff --cc arch/x86/kernel/ptrace.c index 6b7ab0b,58ce4b5..0000000 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@@ -557,41 -554,87 +557,110 @@@ static int ptrace_set_debugreg(struct t return 0; } +/* + * These access the current or another (stopped) task's io permission + * bitmap for debugging or core dump. + */ +static int ioperm_active(struct task_struct *target, + const struct user_regset *regset) +{ + return target->thread.io_bitmap_max / regset->size; +} + +static int ioperm_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + if (!target->thread.io_bitmap_ptr) + return -ENXIO; + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + target->thread.io_bitmap_ptr, + 0, IO_BITMAP_BYTES); +} + - #ifdef X86_BTS + #ifdef CONFIG_X86_PTRACE_BTS + /* + * The configuration for a particular BTS hardware implementation. + */ + struct bts_configuration { + /* the size of a BTS record in bytes; at most BTS_MAX_RECORD_SIZE */ + unsigned char sizeof_bts; + /* the size of a field in the BTS record in bytes */ + unsigned char sizeof_field; + /* a bitmask to enable/disable BTS in DEBUGCTL MSR */ + unsigned long debugctl_mask; + }; + static struct bts_configuration bts_cfg; + + #define BTS_MAX_RECORD_SIZE (8 * 3) + + + /* + * Branch Trace Store (BTS) uses the following format. Different + * architectures vary in the size of those fields. + * - source linear address + * - destination linear address + * - flags + * + * Later architectures use 64bit pointers throughout, whereas earlier + * architectures use 32bit pointers in 32bit mode. + * + * We compute the base address for the first 8 fields based on: + * - the field size stored in the DS configuration + * - the relative field position + * + * In order to store additional information in the BTS buffer, we use + * a special source address to indicate that the record requires + * special interpretation. + * + * Netburst indicated via a bit in the flags field whether the branch + * was predicted; this is ignored. + */ - static int ptrace_bts_get_size(struct task_struct *child) + enum bts_field { + bts_from = 0, + bts_to, + bts_flags, + + bts_escape = (unsigned long)-1, + bts_qual = bts_to, + bts_jiffies = bts_flags + }; + + static inline unsigned long bts_get(const char *base, enum bts_field field) { - if (!child->thread.ds_area_msr) - return -ENXIO; + base += (bts_cfg.sizeof_field * field); + return *(unsigned long *)base; + } - return ds_get_bts_index((void *)child->thread.ds_area_msr); + static inline void bts_set(char *base, enum bts_field field, unsigned long val) + { + base += (bts_cfg.sizeof_field * field);; + (*(unsigned long *)base) = val; } - static int ptrace_bts_read_record(struct task_struct *child, - long index, + /* + * Translate a BTS record from the raw format into the bts_struct format + * + * out (out): bts_struct interpretation + * raw: raw BTS record + */ + static void ptrace_bts_translate_record(struct bts_struct *out, const void *raw) + { + memset(out, 0, sizeof(*out)); + if (bts_get(raw, bts_from) == bts_escape) { + out->qualifier = bts_get(raw, bts_qual); + out->variant.jiffies = bts_get(raw, bts_jiffies); + } else { + out->qualifier = BTS_BRANCH; + out->variant.lbr.from_ip = bts_get(raw, bts_from); + out->variant.lbr.to_ip = bts_get(raw, bts_to); + } + } + + static int ptrace_bts_read_record(struct task_struct *child, size_t index, struct bts_struct __user *out) { struct bts_struct ret;
Attachment:
pgpLHsgy4rnsQ.pgp
Description: PGP signature