Skip to contentSkip to conversation

arm64: disable/enable d-cache support for

RFC PATCH Superseded Pratyush Anand 3 participants 11 messages May 4, 2015 – May 7, 2015

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover arm64: disable/enable d-cache support for

These patches add support for enable/disable d cache support. It reduces time for sha verification from more than 2 min to 3-4 sec on my platform.
There are some of the observation which I am unable to explain.
* It takes around 18 sec when I boot a kexec kernel and around 3-4 sec
* when I boot a crash kernel. In case of kexec kernel start of 1st
* segment is at 0000004000280000 and, end of last segment is at
* 00000040029c0000. In case of crash kernel start of 1st segment is at
* 00000041b9080000 and, end of last segment is at 00000041f9000000.

Pratyush Anand (3):
arm64: Add enable/disable d-cache support for purgatory
arm64: Pass RAM boundary to purgatory
arm64: Enable/disable D-cache before/after sha verification

 kexec/arch/arm64/include/types.h       |  16 +++
 kexec/arch/arm64/kexec-arm64.c         |  16 ++-
 purgatory/arch/arm64/Makefile          |   1 +
 purgatory/arch/arm64/cache.S           | 222 +++++++++++++++++++++++++++++++++
 purgatory/arch/arm64/cache.h           |  42 +++++++
 purgatory/arch/arm64/entry.S           |  10 ++
 purgatory/arch/arm64/purgatory-arm64.c |  12 ++
 7 files changed, 318 insertions(+), 1 deletion(-)
 create mode 100644 kexec/arch/arm64/include/types.h
 create mode 100644 purgatory/arch/arm64/cache.S
 create mode 100644 purgatory/arch/arm64/cache.h
Signature · 7 lines
2.1.0


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#1 lore raw

RFC PATCH 1/3 arm64: Add enable/disable d-cache support for purgatory

This patch adds support to enable/disable d-cache, which can be used for faster purgatory sha256 verification.

---
 purgatory/arch/arm64/Makefile |   1 +
 purgatory/arch/arm64/cache.S  | 222 ++++++++++++++++++++++++++++++++++++++++++
 purgatory/arch/arm64/cache.h  |  42 ++++++++
 3 files changed, 265 insertions(+)
 create mode 100644 purgatory/arch/arm64/cache.S
 create mode 100644 purgatory/arch/arm64/cache.h
purgatory/arch/arm64/Makefile +1 -0
index 5d35161fc5f4..04fef16476fb 100644
@@ -12,6 +12,7 @@ arm64_PURGATORY_EXTRA_CFLAGS = \
 
 arm64_PURGATORY_SRCS += \
 	purgatory/arch/arm64/entry.S \
+	purgatory/arch/arm64/cache.S \
 	purgatory/arch/arm64/purgatory-arm64.c
 
 dist += \
purgatory/arch/arm64/cache.S new file +222 -0

222 lines not on this page · raw message

purgatory/arch/arm64/cache.h new file +42 -0

42 lines not on this page · raw message

Signature · 7 lines
2.1.0


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#2 lore raw

RFC PATCH 2/3 arm64: Pass RAM boundary to purgatory

In reply to Pratyush Anand

RAM boundary which includes all the sections is needed for creating identity page mapping and to enable d-cache for those areas.

---
 kexec/arch/arm64/include/types.h | 16 ++++++++++++++++
 kexec/arch/arm64/kexec-arm64.c   | 16 +++++++++++++++-
 purgatory/arch/arm64/entry.S     | 10 ++++++++++
 3 files changed, 41 insertions(+), 1 deletion(-)
 create mode 100644 kexec/arch/arm64/include/types.h
kexec/arch/arm64/include/types.h new file +16 -0
new file mode 100644
index 000000000000..08f833a6d585
@@ -0,0 +1,16 @@
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+#define min(x,y) ({ \
+	typeof(x) _x = (x);	\
+	typeof(y) _y = (y);	\
+	(void) (&_x == &_y);	\
+	_x < _y ? _x : _y; })
+
+#define max(x,y) ({ \
+	typeof(x) _x = (x);	\
+	typeof(y) _y = (y);	\
+	(void) (&_x == &_y);	\
+	_x > _y ? _x : _y; })
+
+#endif /* _TYPES_H_ */
kexec/arch/arm64/kexec-arm64.c +15 -1
index 12c589f8001c..8ce4a61fc9c2 100644
@@ -28,6 +28,7 @@
 #include "fs2dt.h"
 #include "kexec-syscall.h"
 #include "arch/options.h"
+#include "types.h"
 
 /* Global varables the core kexec routines expect. */
 
@@ -588,9 +589,11 @@ static uint64_t read_sink(const char *command_line)
 int arm64_load_other_segments(struct kexec_info *info,
 	unsigned long kernel_entry, char *option)
 {
-	int result;
+	int result, i;
 	struct mem_ehdr ehdr;
 	unsigned long dtb_base;
+	unsigned long arm64_ram_start = -1;
+	unsigned long arm64_ram_end = 0;
 	unsigned long hole_min, hole_max;
 	char *initrd_buf = NULL;
 	uint64_t purgatory_sink;
@@ -720,6 +723,17 @@ int arm64_load_other_segments(struct kexec_info *info,
 
 		elf_rel_set_symbol(&info->rhdr, "arm64_dtb_addr", &dtb_base,
 				sizeof(dtb_base));
+		for (i = 0; i < info->nr_segments; i++) {
+			arm64_ram_start = min(arm64_ram_start,
+					(unsigned long)info->segment[i].mem);
+			arm64_ram_end = max(arm64_ram_end,
+				((unsigned long)info->segment[i].mem + 
+				info->segment[i].memsz));
+		}
+		elf_rel_set_symbol(&info->rhdr, "arm64_ram_start",
+				&arm64_ram_start, sizeof(arm64_ram_start));
+		elf_rel_set_symbol(&info->rhdr, "arm64_ram_end",
+				&arm64_ram_end, sizeof(arm64_ram_end));
 	}
 
 	return 0;
purgatory/arch/arm64/entry.S +10 -0
index 140e91d87ab1..0713ccdec4ad 100644
@@ -52,3 +52,13 @@ size arm64_kernel_entry
 arm64_dtb_addr:
 	.quad	0
 size arm64_dtb_addr
+
+.globl arm64_ram_start
+arm64_ram_start:
+	.quad	0
+size arm64_ram_start
+
+.globl arm64_ram_end
+arm64_ram_end:
+	.quad	0
+size arm64_ram_end
Signature · 7 lines
2.1.0


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#3 lore raw

RFC PATCH 3/3 arm64: Enable/disable D-cache before/after sha verification

In reply to Pratyush Anand

Enable D cache before SHA verification and disable it before switching to kernel.

Since we only map RAM area, therefore currently no printf is allowed between d-cache enable and disable events. Identity mapping for port area with device type memory attributes need to be created for printf to work.

---
 purgatory/arch/arm64/purgatory-arm64.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
purgatory/arch/arm64/purgatory-arm64.c +12 -0
index 3a1c9243bfa2..e045039039b6 100644
@@ -2,6 +2,7 @@
  * ARM64 purgatory.
  */
 
+#include "cache.h"
 #include <stdint.h>
 #include <purgatory.h>
 
@@ -10,6 +11,8 @@
 extern uint32_t *arm64_sink;
 extern void (*arm64_kernel_entry)(uint64_t);
 extern uint64_t arm64_dtb_addr;
+extern uint64_t arm64_ram_start;
+extern uint64_t arm64_ram_end;
 
 static void wait_for_xmit_complete(void)
 {
@@ -44,14 +47,23 @@ void putchar(int ch)
 	}
 }
 
+uint64_t page_table[PAGE_TABLE_SIZE / sizeof(uint64_t)] __attribute__ ((aligned (PAGE_TABLE_SIZE))) = { };
+extern void enable_dcache(uint64_t , uint64_t , uint64_t *);
+extern void disable_dcache(uint64_t , uint64_t);
+
 void setup_arch(void)
 {
 	printf("purgatory: kernel_entry: %lx\n",
 		(unsigned long)arm64_kernel_entry);
 	printf("purgatory: dtb:          %lx\n", arm64_dtb_addr);
+	printf("purgatory: RAM start: %lx\n", arm64_ram_start);
+	printf("purgatory: RAM end: %lx\n", arm64_ram_end);
+
+	enable_dcache(arm64_ram_start, arm64_ram_end, page_table);
 }
 
 void post_verification_setup_arch(void)
 {
+	disable_dcache(arm64_ram_start, arm64_ram_end);
 	arm64_kernel_entry(arm64_dtb_addr);
 }
Signature · 7 lines
2.1.0


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#4 lore raw
In reply to Pratyush Anand
Quoted 9 lines · Pratyush Anand

These patches add support for enable/disable d cache support. It reduces time for sha verification from more than 2 min to 3-4 sec on my platform.
There are some of the observation which I am unable to explain.
* It takes around 18 sec when I boot a kexec kernel and around 3-4 sec
* when I boot a crash kernel. In case of kexec kernel start of 1st
* segment is at 0000004000280000 and, end of last segment is at
* 00000040029c0000. In case of crash kernel start of 1st segment is at
* 00000041b9080000 and, end of last segment is at 00000041f9000000.

There is one more observation which is not explainable :(
While executing a secondary kernel using kexec -e, if sha256_process() function is aligned at offset 256, it takes 18 sec else it takes double ie 36 sec.

# objdump -d purgatory/purgatory.ro | grep sha256_process
0000000000001300 <sha256_process>:

-> takes 18 sec

If because of some changes in code, this function shifts a bit

# objdump -d purgatory/purgatory.ro | grep sha256_process
0000000000001310 <sha256_process>:

-> takes 36 sec.

So, "__attribute__ ((aligned (256))) void sha256_process( sha256_context *ctx, const uint8_t data[64] )" guarantees constant execution time, but how can this be justified?

~Pratyush

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#5 lore raw
In reply to Pratyush Anand

Hi,

I don't really like the idea of doing cache operations in purgatory. For fast reboot we have the --lite option to kexec, which will skip the digest calculations.

Your 2 minutes seems like a long time. Is this seen on other platforms?

-Geoff

Quoted 15 lines · Pratyush Anand

These patches add support for enable/disable d cache support. It reduces time for sha verification from more than 2 min to 3-4 sec on my platform.
There are some of the observation which I am unable to explain.
* It takes around 18 sec when I boot a kexec kernel and around 3-4 sec
* when I boot a crash kernel. In case of kexec kernel start of 1st
* segment is at 0000004000280000 and, end of last segment is at
* 00000040029c0000. In case of crash kernel start of 1st segment is at
* 00000041b9080000 and, end of last segment is at 00000041f9000000.

Pratyush Anand (3):
arm64: Add enable/disable d-cache support for purgatory
arm64: Pass RAM boundary to purgatory
arm64: Enable/disable D-cache before/after sha verification

Quoted 12 lines
 kexec/arch/arm64/include/types.h       |  16 +++
 kexec/arch/arm64/kexec-arm64.c         |  16 ++-
 purgatory/arch/arm64/Makefile          |   1 +
 purgatory/arch/arm64/cache.S           | 222 +++++++++++++++++++++++++++++++++
 purgatory/arch/arm64/cache.h           |  42 +++++++
 purgatory/arch/arm64/entry.S           |  10 ++
 purgatory/arch/arm64/purgatory-arm64.c |  12 ++
 7 files changed, 318 insertions(+), 1 deletion(-)
 create mode 100644 kexec/arch/arm64/include/types.h
 create mode 100644 purgatory/arch/arm64/cache.S
 create mode 100644 purgatory/arch/arm64/cache.h

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#6 lore raw

Hi Geoff,

Quoted 1 line · Geoff Levand

Your 2 minutes seems like a long time. Is this seen on other platforms?

At least it is seen on two different HW platforms I had tested with. I do not know about other.

It would be nice if somebody else who is using kexec on HW platform can report their execution time.

~Pratyush

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#7 lore raw

Geoff, Pratyush

Quoted 8 lines · Pratyush Anand

Hi Geoff,

Quoted 1 line · Geoff Levand

Your 2 minutes seems like a long time. Is this seen on other platforms?

At least it is seen on two different HW platforms I had tested with. I do not know about other.

It would be nice if somebody else who is using kexec on HW platform can report their execution time.

On my HW, it took about 42secs before showing extra boot messages after "I'm in purgatory."

-Takahiro AKASHI

Quoted 1 line

~Pratyush

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#8 lore raw
Quoted 8 lines · AKASHI Takahiro

Geoff, Pratyush

Quoted 5 lines · Pratyush Anand

Hi Geoff,

Quoted 1 line · Geoff Levand

Your 2 minutes seems like a long time. Is this seen on other platforms?

Quoted 9 lines
Quoted 5 lines

At least it is seen on two different HW platforms I had tested with. I do not know about other.

It would be nice if somebody else who is using kexec on HW platform can report their execution time.

On my HW, it took about 42secs before showing extra boot messages after "I'm in purgatory."

It would also depend on the size of different segments (mainly kernel and initrd) on which sha256 is calculated. What are the size of binaries in your case?

In my case:

segment[0].memsz = 0x10e0000 // kernel
segment[1].memsz = 0x1910000 // initrd

segment[2].memsz = 0x10000   // dtb
segment[3].memsz = 0x40000   // purgatory, not included in sha256
segment[4].memsz = 0x10000   // elf core hdr

@Geoff: Do you see any specific side effect for enabling D-cache in purgatory, other than the fact that it increases size of purgatory? May be we can keep an user option to select/not select d-cache enabling.

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#9 lore raw
Quoted 17 lines · Pratyush Anand
Quoted 14 lines · AKASHI Takahiro

Geoff, Pratyush

Quoted 10 lines · Pratyush Anand

Hi Geoff,

Quoted 1 line · Geoff Levand

Your 2 minutes seems like a long time. Is this seen on other platforms?

At least it is seen on two different HW platforms I had tested with. I do not know about other.

It would be nice if somebody else who is using kexec on HW platform can report their execution time.

Quoted 6 lines
Quoted 3 lines

On my HW, it took about 42secs before showing extra boot messages after "I'm in purgatory."

It would also depend on the size of different segments (mainly kernel and initrd) on which sha256 is calculated. What are the size of binaries in your case?

segment[0].memsz = 0x877000 // kernel
segment[1].memsz = 0x4000 // dtb
segment[2].memsz = 0x7000 // purgatory

no initrd under normal kexec.

Quoted 7 lines

In my case:

segment[0].memsz = 0x10e0000 // kernel
segment[1].memsz = 0x1910000 // initrd

segment[2].memsz = 0x10000   // dtb
segment[3].memsz = 0x40000   // purgatory, not included in sha256
segment[4].memsz = 0x10000   // elf core hdr

Your numbers have extra "0" :)

Quoted 2 lines

@Geoff: Do you see any specific side effect for enabling D-cache in purgatory, other than the fact that it increases size of purgatory? May be we can keep an user option to select/not select d-cache enabling.

The discussions should be Cc'd to linux-arm-kernel (or at least, arm64 maintainers).

-Takahiro AKASHI

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#10 lore raw
In reply to Pratyush Anand
Quoted 3 lines · Pratyush Anand

@Geoff: Do you see any specific side effect for enabling D-cache in purgatory, other than the fact that it increases size of purgatory? May be we can keep an user option to select/not select d-cache enabling.

The checks in purgatory are for kdump, which won't be a regularly used feature. I don't want to add the complexity to save one minute for someone who will likely spend several hours working on a problem that triggered a kdump.

-Geoff

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec