From: Helge Deller <deller@gmx.de>
To: linux-parisc@vger.kernel.org
Subject: [PATCH] parisc: Reduce kernel size by packing alternative tables - variant 2
Date: Tue, 11 Oct 2022 11:54:53 +0200 [thread overview]
Message-ID: <Y0U9bXkZk4Pfab12@p100> (raw)
This is the second variant to reduce the size of the alternative tables.
Basically it halves the size by reducing length, condition and replacement
fields.
bloat-o-meter shows a reduction of -0.01% by this change:
Total: Before=10254498, After=10253654, chg -0.01%
Since this patch introduces more changes without benefit, I won't
apply it for now, but want it to show up in patchwork.
Signed-off-by: Helge Deller <deller@gmx.de>
diff --git a/arch/parisc/include/asm/alternative.h b/arch/parisc/include/asm/alternative.h
index 0ec54f43d6d2..1705abd97f5f 100644
--- a/arch/parisc/include/asm/alternative.h
+++ b/arch/parisc/include/asm/alternative.h
@@ -10,7 +10,9 @@
#define ALT_COND_NO_IOC_FDC 0x10 /* if I/O cache does not need flushes */
#define ALT_COND_RUN_ON_QEMU 0x20 /* if running on QEMU */
-#define INSN_PxTLB 0x02 /* modify pdtlb, pitlb */
+#define ALTCODE_PxTLB 0x01 /* add local flag to pdtlb & pitlb */
+#define ALTCODE_NOP 0x02 /* insert nops */
+
#define INSN_NOP 0x08000240 /* nop */
#ifndef __ASSEMBLY__
@@ -22,10 +24,10 @@
struct alt_instr {
s32 orig_offset; /* offset to original instructions */
- s32 len; /* end of original instructions */
- u32 cond; /* see ALT_COND_XXX */
- u32 replacement; /* replacement instruction or code */
-};
+ u16 len; /* number of instructions */
+ u8 cond; /* see ALT_COND_XXX condition */
+ u8 replacement; /* see ALTCODE_XXX replacement instruction */
+} __packed;
void set_kernel_text_rw(int enable_read_write);
void apply_alternatives_all(void);
@@ -34,9 +36,11 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end,
/* Alternative SMP implementation. */
#define ALTERNATIVE(cond, replacement) "!0:" \
- ".section .altinstructions, \"aw\" !" \
- ".word (0b-4-.), 1, " __stringify(cond) "," \
- __stringify(replacement) " !" \
+ ".section .altinstructions, \"aw\" !" \
+ ".word (0b-4) - . !" \
+ ".hword 1 !" \
+ ".byte " __stringify(cond) "!" \
+ ".byte " __stringify(replacement) "!" \
".previous"
#else
@@ -44,15 +48,9 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end,
/* to replace one single instructions by a new instruction */
#define ALTERNATIVE(from, to, cond, replacement)\
.section .altinstructions, "aw" ! \
- .word (from - .), (to - from)/4 ! \
- .word cond, replacement ! \
- .previous
-
-/* to replace multiple instructions by new code */
-#define ALTERNATIVE_CODE(from, num_instructions, cond, new_instr_ptr)\
- .section .altinstructions, "aw" ! \
- .word (from - .), -num_instructions ! \
- .word cond, (new_instr_ptr - .) ! \
+ .word from - . ! \
+ .hword (to - from)/4 ! \
+ .byte cond, replacement ! \
.previous
#endif /* __ASSEMBLY__ */
diff --git a/arch/parisc/include/asm/barrier.h b/arch/parisc/include/asm/barrier.h
index c705decf2bed..f99bb8feff78 100644
--- a/arch/parisc/include/asm/barrier.h
+++ b/arch/parisc/include/asm/barrier.h
@@ -9,7 +9,7 @@
/* The synchronize caches instruction executes as a nop on systems in
which all memory references are performed in order. */
#define synchronize_caches() asm volatile("sync" \
- ALTERNATIVE(ALT_COND_NO_SMP, INSN_NOP) \
+ ALTERNATIVE(ALT_COND_NO_SMP, ALTCODE_NOP) \
: : : "memory")
#if defined(CONFIG_SMP)
diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
index e23d06b51a20..41fa03e7efa1 100644
--- a/arch/parisc/include/asm/cache.h
+++ b/arch/parisc/include/asm/cache.h
@@ -40,20 +40,20 @@ extern struct pdc_cache_info cache_info;
void parisc_setup_cache_timing(void);
#define pdtlb(sr, addr) asm volatile("pdtlb 0(%%sr%0,%1)" \
- ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \
+ ALTERNATIVE(ALT_COND_NO_SMP, ALTCODE_PxTLB) \
: : "i"(sr), "r" (addr) : "memory")
#define pitlb(sr, addr) asm volatile("pitlb 0(%%sr%0,%1)" \
- ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \
- ALTERNATIVE(ALT_COND_NO_SPLIT_TLB, INSN_NOP) \
+ ALTERNATIVE(ALT_COND_NO_SMP, ALTCODE_PxTLB) \
+ ALTERNATIVE(ALT_COND_NO_SPLIT_TLB, ALTCODE_NOP) \
: : "i"(sr), "r" (addr) : "memory")
#define asm_io_fdc(addr) asm volatile("fdc %%r0(%0)" \
- ALTERNATIVE(ALT_COND_NO_DCACHE, INSN_NOP) \
- ALTERNATIVE(ALT_COND_NO_IOC_FDC, INSN_NOP) \
+ ALTERNATIVE(ALT_COND_NO_DCACHE, ALTCODE_NOP) \
+ ALTERNATIVE(ALT_COND_NO_IOC_FDC, ALTCODE_NOP) \
: : "r" (addr) : "memory")
#define asm_io_sync() asm volatile("sync" \
- ALTERNATIVE(ALT_COND_NO_DCACHE, INSN_NOP) \
- ALTERNATIVE(ALT_COND_NO_IOC_FDC, INSN_NOP) :::"memory")
+ ALTERNATIVE(ALT_COND_NO_DCACHE, ALTCODE_NOP) \
+ ALTERNATIVE(ALT_COND_NO_IOC_FDC, ALTCODE_NOP) :::"memory")
#define asm_syncdma() asm volatile("syncdma" :::"memory")
#endif /* ! __ASSEMBLY__ */
diff --git a/arch/parisc/kernel/alternative.c b/arch/parisc/kernel/alternative.c
index daa1e9047275..0c455ae13150 100644
--- a/arch/parisc/kernel/alternative.c
+++ b/arch/parisc/kernel/alternative.c
@@ -26,7 +26,7 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
struct alt_instr *entry;
int index = 0, applied = 0;
int num_cpus = num_online_cpus();
- u32 cond_check;
+ u8 cond_check;
cond_check = ALT_COND_ALWAYS |
((num_cpus == 1) ? ALT_COND_NO_SMP : 0) |
@@ -45,15 +45,19 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
for (entry = start; entry < end; entry++, index++) {
- u32 *from, cond, replacement;
- s32 len;
+ u32 *from, replacement;
+ u8 cond;
+ u16 len;
from = (u32 *)((ulong)&entry->orig_offset + entry->orig_offset);
len = entry->len;
cond = entry->cond;
replacement = entry->replacement;
- WARN_ON(!cond);
+ if (WARN_ON(!cond || !len))
+ continue;
+ if (WARN_ON(replacement != ALTCODE_PxTLB && replacement != ALTCODE_NOP))
+ continue;
if ((cond & ALT_COND_ALWAYS) == 0 && no_alternatives)
continue;
@@ -66,7 +70,7 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
continue;
/* Want to replace pdtlb by a pdtlb,l instruction? */
- if (replacement == INSN_PxTLB) {
+ if (replacement == ALTCODE_PxTLB) {
replacement = *from;
if (boot_cpu_data.cpu_type >= pcxu) /* >= pa2.0 ? */
replacement |= (1 << 10); /* set el bit */
@@ -76,21 +80,20 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
* Replace instruction with NOPs?
* For long distance insert a branch instruction instead.
*/
- if (replacement == INSN_NOP && len > 1)
- replacement = 0xe8000002 + (len-2)*8; /* "b,n .+8" */
+ if (replacement == ALTCODE_NOP) {
+ if (len > 1)
+ replacement = 0xe8000002 + (len-2)*8; /* "b,n .+8" */
+ else
+ replacement = INSN_NOP;
+ len = 1;
+ }
pr_debug("ALTERNATIVE %3d: Cond %2x, Replace %2d instructions to 0x%08x @ 0x%px (%pS)\n",
index, cond, len, replacement, from, from);
- if (len < 0) {
- /* Replace multiple instruction by new code */
- u32 *source;
- len = -len;
- source = (u32 *)((ulong)&entry->replacement + entry->replacement);
- memcpy(from, source, 4 * len);
- } else {
+ while (len--) {
/* Replace by one instruction */
- *from = replacement;
+ *from++ = replacement;
}
applied++;
}
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index df8102fb435f..32167b276c26 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -407,7 +407,7 @@
bb,<,n \pte,_PAGE_PRESENT_BIT,3f
b \fault
stw \spc,0(\tmp)
-99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
+99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, ALTCODE_NOP)
#endif
2: LDREG 0(\ptp),\pte
bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault
@@ -424,7 +424,7 @@
#ifdef CONFIG_TLB_PTLOCK
98: or,COND(=) %r0,\spc,%r0
stw,ma \spc,0(\tmp)
-99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
+99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, ALTCODE_NOP)
#endif
.endm
@@ -433,7 +433,7 @@
#ifdef CONFIG_TLB_PTLOCK
98: get_ptl \tmp
ptl_unlock0 \spc,\tmp
-99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
+99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, ALTCODE_NOP)
#endif
.endm
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 9a0018f1f42c..038d876b0a92 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -103,7 +103,7 @@ fitonemiddle: /* Loop if LOOP = 1 */
add %r21, %r20, %r20 /* increment space */
fitdone:
- ALTERNATIVE(88b, fitdone, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
+ ALTERNATIVE(88b, fitdone, ALT_COND_NO_SPLIT_TLB, ALTCODE_NOP)
/* Flush Data Tlb */
@@ -172,17 +172,16 @@ fdtdone:
rfi
nop
-2: bv %r0(%r2)
- nop
+ bv,n %r0(%r2)
/*
* When running in qemu, drop whole flush_tlb_all_local function and
* replace by one pdtlbe instruction, for which QEMU will drop all
* local TLB entries.
*/
-3: pdtlbe %r0(%sr1,%r0)
- bv,n %r0(%r2)
- ALTERNATIVE_CODE(flush_tlb_all_local, 2, ALT_COND_RUN_ON_QEMU, 3b)
+3: ALTERNATIVE(flush_tlb_all_local, 3b, ALT_COND_RUN_ON_QEMU, ALTCODE_NOP)
+ bv %r0(%r2)
+ pdtlbe %r0(%sr1,%r0)
ENDPROC_CFI(flush_tlb_all_local)
.import cache_info,data
@@ -241,7 +240,7 @@ fioneloop2:
fisync:
sync
mtsm %r22 /* restore I-bit */
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, ALTCODE_NOP)
bv %r0(%r2)
nop
ENDPROC_CFI(flush_instruction_cache_local)
@@ -302,7 +301,7 @@ fdoneloop2:
fdsync:
sync
mtsm %r22 /* restore I-bit */
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
bv %r0(%r2)
nop
ENDPROC_CFI(flush_data_cache_local)
@@ -545,8 +544,8 @@ ENTRY_CFI(copy_user_page_asm)
#else
0: pdtlb %r0(%r28)
1: pdtlb %r0(%r29)
- ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
- ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB)
+ ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
+ ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
#endif
#ifdef CONFIG_64BIT
@@ -674,7 +673,7 @@ ENTRY_CFI(clear_user_page_asm)
pdtlb,l %r0(%r28)
#else
0: pdtlb %r0(%r28)
- ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
+ ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
#endif
#ifdef CONFIG_64BIT
@@ -740,7 +739,7 @@ ENTRY_CFI(flush_dcache_page_asm)
pdtlb,l %r0(%r28)
#else
0: pdtlb %r0(%r28)
- ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
+ ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
#endif
88: ldil L%dcache_stride, %r1
@@ -772,7 +771,7 @@ ENTRY_CFI(flush_dcache_page_asm)
cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
fdc,m r31(%r28)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
sync
bv %r0(%r2)
nop
@@ -789,7 +788,7 @@ ENTRY_CFI(purge_dcache_page_asm)
pdtlb,l %r0(%r28)
#else
0: pdtlb %r0(%r28)
- ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
+ ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
#endif
88: ldil L%dcache_stride, %r1
@@ -821,7 +820,7 @@ ENTRY_CFI(purge_dcache_page_asm)
cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
pdc,m r31(%r28)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
sync
bv %r0(%r2)
nop
@@ -840,13 +839,13 @@ ENTRY_CFI(flush_icache_page_asm)
#ifdef CONFIG_PA20
pdtlb,l %r0(%r28)
1: pitlb,l %r0(%sr4,%r28)
- ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
+ ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, ALTCODE_NOP)
#else
0: pdtlb %r0(%r28)
1: pitlb %r0(%sr4,%r28)
- ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
- ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB)
- ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
+ ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
+ ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
+ ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, ALTCODE_NOP)
#endif
88: ldil L%icache_stride, %r1
@@ -880,7 +879,7 @@ ENTRY_CFI(flush_icache_page_asm)
cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
fic,m %r31(%sr4,%r28)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, ALTCODE_NOP)
sync
bv %r0(%r2)
nop
@@ -916,7 +915,7 @@ ENTRY_CFI(flush_kernel_dcache_page_asm)
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
fdc,m %r23(%r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
sync
bv %r0(%r2)
nop
@@ -952,7 +951,7 @@ ENTRY_CFI(purge_kernel_dcache_page_asm)
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
pdc,m %r23(%r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
sync
bv %r0(%r2)
nop
@@ -993,7 +992,7 @@ ENTRY_CFI(flush_user_dcache_range_asm)
2: cmpb,COND(>>),n %r25, %r26, 2b
fdc,m %r23(%sr3, %r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
sync
bv %r0(%r2)
nop
@@ -1035,7 +1034,7 @@ ENTRY_CFI(flush_kernel_dcache_range_asm)
fdc,m %r23(%r26)
sync
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
bv %r0(%r2)
nop
ENDPROC_CFI(flush_kernel_dcache_range_asm)
@@ -1076,7 +1075,7 @@ ENTRY_CFI(purge_kernel_dcache_range_asm)
pdc,m %r23(%r26)
sync
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
bv %r0(%r2)
nop
ENDPROC_CFI(purge_kernel_dcache_range_asm)
@@ -1116,7 +1115,7 @@ ENTRY_CFI(flush_user_icache_range_asm)
2: cmpb,COND(>>),n %r25, %r26, 2b
fic,m %r23(%sr3, %r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, ALTCODE_NOP)
sync
bv %r0(%r2)
nop
@@ -1153,7 +1152,7 @@ ENTRY_CFI(flush_kernel_icache_page)
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
fic,m %r23(%sr4, %r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, ALTCODE_NOP)
sync
bv %r0(%r2)
nop
@@ -1194,7 +1193,7 @@ ENTRY_CFI(flush_kernel_icache_range_asm)
2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
fic,m %r23(%sr4, %r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
+89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, ALTCODE_NOP)
sync
bv %r0(%r2)
nop
reply other threads:[~2022-10-11 9:55 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Y0U9bXkZk4Pfab12@p100 \
--to=deller@gmx.de \
--cc=linux-parisc@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.