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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox