All of lore.kernel.org
 help / color / mirror / Atom feed
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.