All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] xen/arm64: Use __flush_dcache_area instead of __flush_dcache_all
@ 2014-10-06 15:49 suravee.suthikulpanit
  2014-10-06 16:28 ` Mark Rutland
  0 siblings, 1 reply; 23+ messages in thread
From: suravee.suthikulpanit @ 2014-10-06 15:49 UTC (permalink / raw)
  To: roy.franz, ian.campbell, mark.rutland
  Cc: julien.grall, xen-devel, Suravee Suthikulpanit,
	stefano.stabellini

From: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

when booting with EFI, __flush_dcache_all does not correctly flush data.

According to Mark Rutland, __flush_dcache_all does not guaranteed to push
data to the PoC if there is a system-level cache as it uses Set/Way
operations.

Therefore, this patch switchs to use the "__flush_dcache_area"
mechanism, which is coppied from Linux.

Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
---

NOTE: I still have not fully boot into Dom0 with this patch.
      However, it seems that the data is flushed out to physical
      memory now.

 xen/arch/arm/arm64/cache.S | 32 ++++++++++++++++++++++++++++++++
 xen/arch/arm/arm64/head.S  | 24 +++++++++++++++++++-----
 2 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/xen/arch/arm/arm64/cache.S b/xen/arch/arm/arm64/cache.S
index a445cbf..38f96c2 100644
--- a/xen/arch/arm/arm64/cache.S
+++ b/xen/arch/arm/arm64/cache.S
@@ -97,3 +97,35 @@ finished:
 	isb
 	ret
 ENDPROC(__flush_dcache_all)
+
+/*
+ * dcache_line_size - get the minimum D-cache line size from the CTR register.
+ */
+	.macro	dcache_line_size, reg, tmp
+	mrs	\tmp, ctr_el0			// read CTR
+	ubfm	\tmp, \tmp, #16, #19		// cache line size encoding
+	mov	\reg, #4			// bytes per word
+	lsl	\reg, \reg, \tmp		// actual cache line size
+	.endm
+
+/*
+ *	__flush_dcache_area(kaddr, size)
+ *
+ *	Ensure that the data held in the page kaddr is written back to the
+ *	page in question.
+ *
+ *	- kaddr   - kernel address
+ *	- size    - size in question
+ */
+ENTRY(__flush_dcache_area)
+	dcache_line_size x2, x3
+	add	x1, x0, x1
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+1:	dc	civac, x0			// clean & invalidate D line / unified line
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo	1b
+	dsb	sy
+	ret
+ENDPROC(__flush_dcache_area)
diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index 7650abe..704f39d 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -740,16 +740,30 @@ ENTRY(lookup_processor_type)
  */
 ENTRY(efi_xen_start)
         /*
+         * Preserve x0 (fdf pointer) across call to __flush_dcache_area,
+         * restore for entry into Xen.
+         */
+        mov   x20, x0
+
+        /*
+         * Flush dcache covering current runtime addresses
+         * of xen text/data. Then flush all of icache.
+         */
+        adrp  x1, _start
+        add   x1, x1, #:lo12:_start
+        adrp  x2, _end
+        add   x2, x2, #:lo12:_end
+        sub   x1, x2, x1
+
+        bl    __flush_dcache_area
+        ic    ialluis
+
+        /*
          * Turn off cache and MMU as Xen expects. EFI enables them, but also
          * mandates a 1:1 (unity) VA->PA mapping, so we can turn off the
          * MMU while executing EFI code before entering Xen.
          * The EFI loader calls this to start Xen.
-         * Preserve x0 (fdf pointer) across call to __flush_dcache_all,
-         * restore for entry into Xen.
          */
-        mov   x20, x0
-        bl    __flush_dcache_all
-        ic    ialluis
 
         /* Turn off Dcache and MMU */
         mrs   x0, sctlr_el2
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 23+ messages in thread
* [PATCH] xen/arm64: Use __flush_dcache_area instead of __flush_dcache_all
@ 2014-10-21  3:55 Roy Franz
  2014-10-21  3:57 ` Roy Franz
  2014-10-21  8:17 ` Ian Campbell
  0 siblings, 2 replies; 23+ messages in thread
From: Roy Franz @ 2014-10-21  3:55 UTC (permalink / raw)
  To: xen-devel, ian.campbell, stefano.stabellini, tim
  Cc: Roy Franz, Suravee Suthikulpanit, fu.wei

From: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

When booting with EFI, __flush_dcache_all does not correctly flush data.
According to Mark Rutland, __flush_dcache_all is not guaranteed to push
data to the PoC if there is a system-level cache as it uses Set/Way
operations.  Therefore, this patch switchs to use the "__flush_dcache_area"
mechanism, which is coppied from Linux.
Add flushing of FDT in addition to Xen text/data.
Remove now unused __flush_dcache_all and related helper functions.
Invalidate the instruction tlb before turning on paging
later on when starting Xen in EL2.

Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Signed-off-by: Roy Franz <roy.franz@linaro.org>
---
Changes since v2:
* Pass FDT size to efi_xen_start, flush exact FDT size rather than
  max FDT size.  (Max size could extend past end of DRAM.)

Changes since v1:
* Added flushing of FDT memory region
* Remove used __flush_dcache_all function, and related helper functions
* Fix typo in comment
* Properly set base address in __flush_dcache_area call.
* Add flush of instruction TLB

 xen/arch/arm/arm64/cache.S  | 89 +++++++++++----------------------------------
 xen/arch/arm/arm64/head.S   | 31 +++++++++++++---
 xen/arch/arm/efi/efi-boot.h |  4 +-
 3 files changed, 48 insertions(+), 76 deletions(-)

diff --git a/xen/arch/arm/arm64/cache.S b/xen/arch/arm/arm64/cache.S
index a445cbf..eff4e16 100644
--- a/xen/arch/arm/arm64/cache.S
+++ b/xen/arch/arm/arm64/cache.S
@@ -20,80 +20,33 @@
  */
 
 /*
- * Enable and disable interrupts.
+ * dcache_line_size - get the minimum D-cache line size from the CTR register.
  */
-	.macro	disable_irq
-	msr	daifset, #2
-	.endm
-
-	.macro	enable_irq
-	msr	daifclr, #2
-	.endm
-
-/*
- * Save/disable and restore interrupts.
- */
-	.macro	save_and_disable_irqs, olddaif
-	mrs	\olddaif, daif
-	disable_irq
-	.endm
-
-	.macro	restore_irqs, olddaif
-	msr	daif, \olddaif
+	.macro	dcache_line_size, reg, tmp
+	mrs	\tmp, ctr_el0			// read CTR
+	ubfm	\tmp, \tmp, #16, #19		// cache line size encoding
+	mov	\reg, #4			// bytes per word
+	lsl	\reg, \reg, \tmp		// actual cache line size
 	.endm
 
 /*
- *	__flush_dcache_all()
+ *	__flush_dcache_area(kaddr, size)
  *
- *	Flush the whole D-cache.
+ *	Ensure that the data held in the page kaddr is written back to the
+ *	page in question.
  *
- *	Corrupted registers: x0-x7, x9-x11
+ *	- kaddr   - kernel address
+ *	- size    - size in question
  */
-ENTRY(__flush_dcache_all)
-	dmb	sy				// ensure ordering with previous memory accesses
-	mrs	x0, clidr_el1			// read clidr
-	and	x3, x0, #0x7000000		// extract loc from clidr
-	lsr	x3, x3, #23			// left align loc bit field
-	cbz	x3, finished			// if loc is 0, then no need to clean
-	mov	x10, #0				// start clean at cache level 0
-loop1:
-	add	x2, x10, x10, lsr #1		// work out 3x current cache level
-	lsr	x1, x0, x2			// extract cache type bits from clidr
-	and	x1, x1, #7			// mask of the bits for current cache only
-	cmp	x1, #2				// see what cache we have at this level
-	b.lt	skip				// skip if no cache, or just i-cache
-	save_and_disable_irqs x9		// make CSSELR and CCSIDR access atomic
-	msr	csselr_el1, x10			// select current cache level in csselr
-	isb					// isb to sych the new cssr&csidr
-	mrs	x1, ccsidr_el1			// read the new ccsidr
-	restore_irqs x9
-	and	x2, x1, #7			// extract the length of the cache lines
-	add	x2, x2, #4			// add 4 (line length offset)
-	mov	x4, #0x3ff
-	and	x4, x4, x1, lsr #3		// find maximum number on the way size
-	clz	w5, w4				// find bit position of way size increment
-	mov	x7, #0x7fff
-	and	x7, x7, x1, lsr #13		// extract max number of the index size
-loop2:
-	mov	x9, x4				// create working copy of max way size
-loop3:
-	lsl	x6, x9, x5
-	orr	x11, x10, x6			// factor way and cache number into x11
-	lsl	x6, x7, x2
-	orr	x11, x11, x6			// factor index number into x11
-	dc	cisw, x11			// clean & invalidate by set/way
-	subs	x9, x9, #1			// decrement the way
-	b.ge	loop3
-	subs	x7, x7, #1			// decrement the index
-	b.ge	loop2
-skip:
-	add	x10, x10, #2			// increment cache number
-	cmp	x3, x10
-	b.gt	loop1
-finished:
-	mov	x10, #0				// swith back to cache level 0
-	msr	csselr_el1, x10			// select current cache level in csselr
+ENTRY(__flush_dcache_area)
+	dcache_line_size x2, x3
+	add	x1, x0, x1
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+1:	dc	civac, x0			// clean & invalidate D line / unified line
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo	1b
 	dsb	sy
-	isb
 	ret
-ENDPROC(__flush_dcache_all)
+ENDPROC(__flush_dcache_area)
diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index 7650abe..9379dd1 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -736,20 +736,39 @@ ENTRY(lookup_processor_type)
         ret
 /*
  *  Function to transition from EFI loader in C, to Xen entry point.
- *  void noreturn efi_xen_start(void *fdt_ptr);
+ *  void noreturn efi_xen_start(void *fdt_ptr, uint32_t fdt_size);
  */
 ENTRY(efi_xen_start)
         /*
+         * Preserve x0 (fdt pointer) across call to __flush_dcache_area,
+         * restore for entry into Xen.
+         */
+        mov   x20, x0
+
+        /* flush dcache covering the FDT updated by EFI boot code */
+        bl    __flush_dcache_area
+
+        /*
+         * Flush dcache covering current runtime addresses
+         * of xen text/data. Then flush all of icache.
+         */
+        adrp  x1, _start
+        add   x1, x1, #:lo12:_start
+        mov   x0, x1
+        adrp  x2, _end
+        add   x2, x2, #:lo12:_end
+        sub   x1, x2, x1
+
+        bl    __flush_dcache_area
+        ic    ialluis
+        tlbi alle2
+
+        /*
          * Turn off cache and MMU as Xen expects. EFI enables them, but also
          * mandates a 1:1 (unity) VA->PA mapping, so we can turn off the
          * MMU while executing EFI code before entering Xen.
          * The EFI loader calls this to start Xen.
-         * Preserve x0 (fdf pointer) across call to __flush_dcache_all,
-         * restore for entry into Xen.
          */
-        mov   x20, x0
-        bl    __flush_dcache_all
-        ic    ialluis
 
         /* Turn off Dcache and MMU */
         mrs   x0, sctlr_el2
diff --git a/xen/arch/arm/efi/efi-boot.h b/xen/arch/arm/efi/efi-boot.h
index 7abc059..d40d8b2 100644
--- a/xen/arch/arm/efi/efi-boot.h
+++ b/xen/arch/arm/efi/efi-boot.h
@@ -7,7 +7,7 @@
 #include <xen/libfdt/libfdt.h>
 #include <asm/setup.h>
 
-void noreturn efi_xen_start(void *fdt_ptr);
+void noreturn efi_xen_start(void *fdt_ptr, uint32_t fdt_size);
 
 #define DEVICE_TREE_GUID \
 {0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0}}
@@ -343,7 +343,7 @@ static void __init efi_arch_pre_exit_boot(void)
 
 static void __init efi_arch_post_exit_boot(void)
 {
-    efi_xen_start(fdt);
+    efi_xen_start(fdt, fdt_totalsize(fdt));
 }
 
 static void __init efi_arch_cfg_file_early(EFI_FILE_HANDLE dir_handle, char *section)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2014-10-21  8:17 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-06 15:49 [PATCH] xen/arm64: Use __flush_dcache_area instead of __flush_dcache_all suravee.suthikulpanit
2014-10-06 16:28 ` Mark Rutland
2014-10-07  4:15   ` Roy Franz
2014-10-07  9:32     ` Ian Campbell
2014-10-07 10:40     ` Mark Rutland
2014-10-14  3:48       ` Roy Franz
2014-10-14  9:21         ` Mark Rutland
2014-10-14  9:35           ` Ian Campbell
2014-10-14 10:32             ` Mark Rutland
2014-10-14 10:39               ` Ian Campbell
2014-10-14 11:23                 ` Mark Rutland
2014-10-14 12:54                   ` Ian Campbell
2014-10-14 14:30                     ` Mark Rutland
2014-10-14 16:26                       ` Roy Franz
2014-10-14 17:07                         ` Mark Rutland
2014-10-14 17:19                           ` Roy Franz
2014-10-15  8:02                           ` Ian Campbell
2014-10-15 15:02                           ` Stefano Stabellini
2014-10-07  9:27   ` Ian Campbell
2014-10-07 10:52     ` Mark Rutland
  -- strict thread matches above, loose matches on Subject: below --
2014-10-21  3:55 Roy Franz
2014-10-21  3:57 ` Roy Franz
2014-10-21  8:17 ` Ian Campbell

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.