From: Vineet Gupta <vgu...@kernel.org>

- Entry code (interrupts/exceptions) need not save/restore ZOL regs
- Any userspace ZOL references (ptrace, signal frame, process start)
  reworked such that ZOL regs are Zero-on-read, Ingore-on-write since
  the ptrace ABI need not change

Signed-off-by: Vineet Gupta <vgu...@kernel.org>
---
 arch/arc/include/asm/entry-arcv2.h |  4 ++++
 arch/arc/include/asm/ptrace.h      |  4 +++-
 arch/arc/kernel/asm-offsets.c      |  2 ++
 arch/arc/kernel/disasm.c           |  2 ++
 arch/arc/kernel/intc-arcv2.c       |  2 ++
 arch/arc/kernel/kgdb.c             |  4 ++++
 arch/arc/kernel/process.c          |  2 ++
 arch/arc/kernel/ptrace.c           | 12 ++++++++++++
 arch/arc/kernel/signal.c           |  8 ++++++++
 arch/arc/kernel/troubleshoot.c     |  3 +++
 arch/arc/kernel/unaligned.c        |  2 ++
 11 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/arch/arc/include/asm/entry-arcv2.h 
b/arch/arc/include/asm/entry-arcv2.h
index 0ff4c0610561..e40a98d2ec29 100644
--- a/arch/arc/include/asm/entry-arcv2.h
+++ b/arch/arc/include/asm/entry-arcv2.h
@@ -117,11 +117,13 @@
 
        st      blink, [sp, PT_blink]
 
+#ifndef CONFIG_ARC_LACKS_ZOL
        lr      r10, [lp_end]
        lr      r11, [lp_start]
        ST2     r10, r11, PT_lpe
 
        st      lp_count, [sp, PT_lpc]
+#endif
 
        ; skip JLI, LDI, EI for now
 .endm
@@ -205,12 +207,14 @@
 
        ld      blink, [sp, PT_blink]
 
+#ifndef CONFIG_ARC_LACKS_ZOL
        LD2     r10, r11, PT_lpe
        sr      r10, [lp_end]
        sr      r11, [lp_start]
 
        ld      r10, [sp, PT_lpc]       ; lp_count can't be target of LD
        mov     lp_count, r10
+#endif
 
        LD2     r0,  r1,  PT_r0
        LD2     r2,  r3,  PT_r2
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h
index cca8d6583e31..9d2b1e7ba6a3 100644
--- a/arch/arc/include/asm/ptrace.h
+++ b/arch/arc/include/asm/ptrace.h
@@ -94,8 +94,10 @@ struct pt_regs {
        unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11;
 
        unsigned long blink;
-       unsigned long lp_end, lp_start, lp_count;
 
+#ifndef CONFIG_ARC_LACKS_ZOL
+       unsigned long lp_end, lp_start, lp_count;
+#endif
        unsigned long ei, ldi, jli;
 
        unsigned long ret;
diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c
index 0e884036ab74..e388d3420b3d 100644
--- a/arch/arc/kernel/asm-offsets.c
+++ b/arch/arc/kernel/asm-offsets.c
@@ -61,8 +61,10 @@ int main(void)
        DEFINE(PT_r26, offsetof(struct pt_regs, r26));
        DEFINE(PT_ret, offsetof(struct pt_regs, ret));
        DEFINE(PT_blink, offsetof(struct pt_regs, blink));
+#ifndef CONFIG_ARC_LACKS_ZOL
        DEFINE(PT_lpe, offsetof(struct pt_regs, lp_end));
        DEFINE(PT_lpc, offsetof(struct pt_regs, lp_count));
+#endif
        DEFINE(PT_user_r25, offsetof(struct pt_regs, user_r25));
 
        DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs));
diff --git a/arch/arc/kernel/disasm.c b/arch/arc/kernel/disasm.c
index 03f8b1be0c3a..c23d3829aef6 100644
--- a/arch/arc/kernel/disasm.c
+++ b/arch/arc/kernel/disasm.c
@@ -523,11 +523,13 @@ int __kprobes disasm_next_pc(unsigned long pc, struct 
pt_regs *regs,
                *next_pc += instr_d.instr_len;
         }
 
+#ifndef CONFIG_ARC_LACKS_ZOL
         /* Zero Overhead Loop - end of the loop */
        if (!(regs->status32 & STATUS32_L) && (*next_pc == regs->lp_end)
                && (regs->lp_count > 1)) {
                *next_pc = regs->lp_start;
        }
+#endif
 
        return instr.is_branch;
 }
diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c
index 5cda19d0aa91..7c1d8b2c4dce 100644
--- a/arch/arc/kernel/intc-arcv2.c
+++ b/arch/arc/kernel/intc-arcv2.c
@@ -48,7 +48,9 @@ void arc_init_IRQ(void)
 #ifndef CONFIG_ARC_IRQ_NO_AUTOSAVE
        ictrl.save_nr_gpr_pairs = 6;    /* r0 to r11 (r12 saved manually) */
        ictrl.save_blink = 1;
+#ifndef CONFIG_ARC_LACKS_ZOL
        ictrl.save_lp_regs = 1;         /* LP_COUNT, LP_START, LP_END */
+#endif
        ictrl.save_u_to_u = 0;          /* user ctxt saved on kernel stack */
        ictrl.save_idx_regs = 1;        /* JLI, LDI, EI */
 #endif
diff --git a/arch/arc/kernel/kgdb.c b/arch/arc/kernel/kgdb.c
index 345a0000554c..6f237fdc6e54 100644
--- a/arch/arc/kernel/kgdb.c
+++ b/arch/arc/kernel/kgdb.c
@@ -27,9 +27,11 @@ static void to_gdb_regs(unsigned long *gdb_regs, struct 
pt_regs *kernel_regs,
        gdb_regs[_BLINK]        = kernel_regs->blink;
        gdb_regs[_RET]          = kernel_regs->ret;
        gdb_regs[_STATUS32]     = kernel_regs->status32;
+#ifndef CONFIG_ARC_LACKS_ZOL
        gdb_regs[_LP_COUNT]     = kernel_regs->lp_count;
        gdb_regs[_LP_END]       = kernel_regs->lp_end;
        gdb_regs[_LP_START]     = kernel_regs->lp_start;
+#endif
        gdb_regs[_BTA]          = kernel_regs->bta;
        gdb_regs[_STOP_PC]      = kernel_regs->ret;
 }
@@ -47,9 +49,11 @@ static void from_gdb_regs(unsigned long *gdb_regs, struct 
pt_regs *kernel_regs,
        kernel_regs->blink      = gdb_regs[_BLINK];
        kernel_regs->ret        = gdb_regs[_RET];
        kernel_regs->status32   = gdb_regs[_STATUS32];
+#ifndef CONFIG_ARC_LACKS_ZOL
        kernel_regs->lp_count   = gdb_regs[_LP_COUNT];
        kernel_regs->lp_end     = gdb_regs[_LP_END];
        kernel_regs->lp_start   = gdb_regs[_LP_START];
+#endif
        kernel_regs->bta        = gdb_regs[_BTA];
 }
 
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c
index 8e90052f6f05..2de60b74d462 100644
--- a/arch/arc/kernel/process.c
+++ b/arch/arc/kernel/process.c
@@ -269,9 +269,11 @@ void start_thread(struct pt_regs *regs, unsigned long pc, 
unsigned long usp)
 
        fpu_init_task(regs);
 
+#ifndef CONFIG_ARC_LACKS_ZOL
        /* bogus seed values for debugging */
        regs->lp_start = 0x10;
        regs->lp_end = 0x80;
+#endif
 }
 
 /*
diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c
index 883391977fdf..d3b98c9749e4 100644
--- a/arch/arc/kernel/ptrace.c
+++ b/arch/arc/kernel/ptrace.c
@@ -26,9 +26,15 @@ static int genregs_get(struct task_struct *target,
 
        membuf_zero(&to, 4);    // pad
        membuf_store(&to, ptregs->bta);
+#ifndef CONFIG_ARC_LACKS_ZOL
        membuf_store(&to, ptregs->lp_start);
        membuf_store(&to, ptregs->lp_end);
        membuf_store(&to, ptregs->lp_count);
+#else
+       membuf_zero(&to, 4);    // ptregs->lp_start
+       membuf_zero(&to, 4);    // ptregs->lp_end
+       membuf_zero(&to, 4);    // ptregs->lp_count
+#endif
        membuf_store(&to, ptregs->status32);
        membuf_store(&to, ptregs->ret);
        membuf_store(&to, ptregs->blink);
@@ -107,9 +113,15 @@ static int genregs_set(struct task_struct *target,
        REG_IGNORE_ONE(pad);
 
        REG_IN_ONE(scratch.bta, &ptregs->bta);
+#ifndef CONFIG_ARC_LACKS_ZOL
        REG_IN_ONE(scratch.lp_start, &ptregs->lp_start);
        REG_IN_ONE(scratch.lp_end, &ptregs->lp_end);
        REG_IN_ONE(scratch.lp_count, &ptregs->lp_count);
+#else
+       REG_IGNORE_ONE(scratch.lp_start);
+       REG_IGNORE_ONE(scratch.lp_end);
+       REG_IGNORE_ONE(scratch.lp_count);
+#endif
 
        REG_IGNORE_ONE(scratch.status32);
 
diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c
index cb2f88502baf..449a4b0c6453 100644
--- a/arch/arc/kernel/signal.c
+++ b/arch/arc/kernel/signal.c
@@ -104,9 +104,15 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct 
pt_regs *regs,
        struct user_regs_struct uregs;
 
        uregs.scratch.bta       = regs->bta;
+#ifndef CONFIG_ARC_LACKS_ZOL
        uregs.scratch.lp_start  = regs->lp_start;
        uregs.scratch.lp_end    = regs->lp_end;
        uregs.scratch.lp_count  = regs->lp_count;
+#else
+       uregs.scratch.lp_start  = 0;
+       uregs.scratch.lp_end    = 0;
+       uregs.scratch.lp_count  = 0;
+#endif
        uregs.scratch.status32  = regs->status32;
        uregs.scratch.ret       = regs->ret;
        uregs.scratch.blink     = regs->blink;
@@ -157,9 +163,11 @@ static int restore_usr_regs(struct pt_regs *regs, struct 
rt_sigframe __user *sf)
 
        set_current_blocked(&set);
        regs->bta       = uregs.scratch.bta;
+#ifndef CONFIG_ARC_LACKS_ZOL
        regs->lp_start  = uregs.scratch.lp_start;
        regs->lp_end    = uregs.scratch.lp_end;
        regs->lp_count  = uregs.scratch.lp_count;
+#endif
        regs->status32  = uregs.scratch.status32;
        regs->ret       = uregs.scratch.ret;
        regs->blink     = uregs.scratch.blink;
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c
index 7654c2e42dc0..acb7ee6c024d 100644
--- a/arch/arc/kernel/troubleshoot.c
+++ b/arch/arc/kernel/troubleshoot.c
@@ -22,8 +22,11 @@ static noinline void print_regs_scratch(struct pt_regs *regs)
 {
        pr_cont("BTA: 0x%08lx\n SP: 0x%08lx  FP: 0x%08lx BLK: %pS\n",
                regs->bta, regs->sp, regs->fp, (void *)regs->blink);
+
+#ifndef CONFIG_ARC_LACKS_ZOL
        pr_cont("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n",
                regs->lp_start, regs->lp_end, regs->lp_count);
+#endif
 
        pr_info("r00: 0x%08lx\tr01: 0x%08lx\tr02: 0x%08lx\n"    \
                "r03: 0x%08lx\tr04: 0x%08lx\tr05: 0x%08lx\n"    \
diff --git a/arch/arc/kernel/unaligned.c b/arch/arc/kernel/unaligned.c
index d63ebd81f1c6..0937441bce04 100644
--- a/arch/arc/kernel/unaligned.c
+++ b/arch/arc/kernel/unaligned.c
@@ -244,11 +244,13 @@ int misaligned_fixup(unsigned long address, struct 
pt_regs *regs,
        } else {
                regs->ret += state.instr_len;
 
+#ifndef CONFIG_ARC_LACKS_ZOL
                /* handle zero-overhead-loop */
                if ((regs->ret == regs->lp_end) && (regs->lp_count)) {
                        regs->ret = regs->lp_start;
                        regs->lp_count--;
                }
+#endif
        }
 
        perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, address);
-- 
2.25.1


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

Reply via email to