Skip to content

Commit 75ebedf

Browse files
committed
parisc: Add HAVE_REGS_AND_STACK_ACCESS_API feature
Some parts of the HAVE_REGS_AND_STACK_ACCESS_API feature is needed for the rseq syscall. This patch adds the most important parts, and as long as we don't support kprobes, we should be fine. Signed-off-by: Helge Deller <deller@gmx.de>
1 parent 93cb8e2 commit 75ebedf

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

arch/parisc/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ config PARISC
4545
select HAVE_ARCH_HASH
4646
select HAVE_ARCH_SECCOMP_FILTER
4747
select HAVE_ARCH_TRACEHOOK
48+
select HAVE_REGS_AND_STACK_ACCESS_API
4849
select GENERIC_SCHED_CLOCK
4950
select HAVE_UNSTABLE_SCHED_CLOCK if SMP
5051
select GENERIC_CLOCKEVENTS

arch/parisc/include/asm/ptrace.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,15 @@ static inline unsigned long regs_return_value(struct pt_regs *regs)
2525
return regs->gr[20];
2626
}
2727

28+
static inline void instruction_pointer_set(struct pt_regs *regs,
29+
unsigned long val)
30+
{
31+
regs->iaoq[0] = val;
32+
}
33+
34+
/* Query offset/name of register from its name/offset */
35+
extern int regs_query_register_offset(const char *name);
36+
extern const char *regs_query_register_name(unsigned int offset);
37+
#define MAX_REG_OFFSET (offsetof(struct pt_regs, ipsw))
38+
2839
#endif

arch/parisc/kernel/ptrace.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,3 +676,103 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
676676
#endif
677677
return &user_parisc_native_view;
678678
}
679+
680+
681+
/* HAVE_REGS_AND_STACK_ACCESS_API feature */
682+
683+
struct pt_regs_offset {
684+
const char *name;
685+
int offset;
686+
};
687+
688+
#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
689+
#define REG_OFFSET_INDEX(r,i) {.name = #r#i, .offset = offsetof(struct pt_regs, r[i])}
690+
#define REG_OFFSET_END {.name = NULL, .offset = 0}
691+
692+
static const struct pt_regs_offset regoffset_table[] = {
693+
REG_OFFSET_INDEX(gr,0),
694+
REG_OFFSET_INDEX(gr,1),
695+
REG_OFFSET_INDEX(gr,2),
696+
REG_OFFSET_INDEX(gr,3),
697+
REG_OFFSET_INDEX(gr,4),
698+
REG_OFFSET_INDEX(gr,5),
699+
REG_OFFSET_INDEX(gr,6),
700+
REG_OFFSET_INDEX(gr,7),
701+
REG_OFFSET_INDEX(gr,8),
702+
REG_OFFSET_INDEX(gr,9),
703+
REG_OFFSET_INDEX(gr,10),
704+
REG_OFFSET_INDEX(gr,11),
705+
REG_OFFSET_INDEX(gr,12),
706+
REG_OFFSET_INDEX(gr,13),
707+
REG_OFFSET_INDEX(gr,14),
708+
REG_OFFSET_INDEX(gr,15),
709+
REG_OFFSET_INDEX(gr,16),
710+
REG_OFFSET_INDEX(gr,17),
711+
REG_OFFSET_INDEX(gr,18),
712+
REG_OFFSET_INDEX(gr,19),
713+
REG_OFFSET_INDEX(gr,20),
714+
REG_OFFSET_INDEX(gr,21),
715+
REG_OFFSET_INDEX(gr,22),
716+
REG_OFFSET_INDEX(gr,23),
717+
REG_OFFSET_INDEX(gr,24),
718+
REG_OFFSET_INDEX(gr,25),
719+
REG_OFFSET_INDEX(gr,26),
720+
REG_OFFSET_INDEX(gr,27),
721+
REG_OFFSET_INDEX(gr,28),
722+
REG_OFFSET_INDEX(gr,29),
723+
REG_OFFSET_INDEX(gr,30),
724+
REG_OFFSET_INDEX(gr,31),
725+
REG_OFFSET_INDEX(sr,0),
726+
REG_OFFSET_INDEX(sr,1),
727+
REG_OFFSET_INDEX(sr,2),
728+
REG_OFFSET_INDEX(sr,3),
729+
REG_OFFSET_INDEX(sr,4),
730+
REG_OFFSET_INDEX(sr,5),
731+
REG_OFFSET_INDEX(sr,6),
732+
REG_OFFSET_INDEX(sr,7),
733+
REG_OFFSET_INDEX(iasq,0),
734+
REG_OFFSET_INDEX(iasq,1),
735+
REG_OFFSET_INDEX(iaoq,0),
736+
REG_OFFSET_INDEX(iaoq,1),
737+
REG_OFFSET_NAME(cr27),
738+
REG_OFFSET_NAME(ksp),
739+
REG_OFFSET_NAME(kpc),
740+
REG_OFFSET_NAME(sar),
741+
REG_OFFSET_NAME(iir),
742+
REG_OFFSET_NAME(isr),
743+
REG_OFFSET_NAME(ior),
744+
REG_OFFSET_NAME(ipsw),
745+
REG_OFFSET_END,
746+
};
747+
748+
/**
749+
* regs_query_register_offset() - query register offset from its name
750+
* @name: the name of a register
751+
*
752+
* regs_query_register_offset() returns the offset of a register in struct
753+
* pt_regs from its name. If the name is invalid, this returns -EINVAL;
754+
*/
755+
int regs_query_register_offset(const char *name)
756+
{
757+
const struct pt_regs_offset *roff;
758+
for (roff = regoffset_table; roff->name != NULL; roff++)
759+
if (!strcmp(roff->name, name))
760+
return roff->offset;
761+
return -EINVAL;
762+
}
763+
764+
/**
765+
* regs_query_register_name() - query register name from its offset
766+
* @offset: the offset of a register in struct pt_regs.
767+
*
768+
* regs_query_register_name() returns the name of a register from its
769+
* offset in struct pt_regs. If the @offset is invalid, this returns NULL;
770+
*/
771+
const char *regs_query_register_name(unsigned int offset)
772+
{
773+
const struct pt_regs_offset *roff;
774+
for (roff = regoffset_table; roff->name != NULL; roff++)
775+
if (roff->offset == offset)
776+
return roff->name;
777+
return NULL;
778+
}

0 commit comments

Comments
 (0)