All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/14] xen: arm: 64-bit dom0 kernel support
@ 2013-03-12 14:53 Ian Campbell
  2013-03-12 15:03 ` Ian Campbell
                   ` (14 more replies)
  0 siblings, 15 replies; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 14:53 UTC (permalink / raw)
  To: xen-devel; +Cc: Tim Deegan, Stefano Stabellini

The following implements hypervisor support for booting an arm64 Linux
kernel as a dom0 onto of a 64-bit hypervisor. This works with both 32-
and 64-bit root filesystems (as you'd expect).

I'll post the kernel side too but note that it is very much WIP, I'm
just throwing this out there prior to going AFK for 3 weeks next week. 

I haven't yet tried a guest (even 32-bit) on top of this kernel, I know
for a fact that the kernel side of this work isn't up to it (mainly
because no sync bitops -> no event channels). For the same reason 64-bit
64-bit guests don't work yet.

The series is built on top of "arm: host SMP support" from last week.

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

* Re: [PATCH 00/14] xen: arm: 64-bit dom0 kernel support
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
@ 2013-03-12 15:03 ` Ian Campbell
  2013-03-12 15:48 ` [PATCH 01/14] xen: arm: define 64-bit guest hypercall calling convention Ian Campbell
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:03 UTC (permalink / raw)
  To: xen-devel; +Cc: Tim (Xen.org), Stefano Stabellini

On Tue, 2013-03-12 at 14:53 +0000, Ian Campbell wrote:
> 
> I haven't yet tried a guest (even 32-bit) on top of this kernel, I
> know for a fact that the kernel side of this work isn't up to it
> (mainly because no sync bitops -> no event channels). 

So here is that skanky patch. It is based on:
        commit d3fbfe7fbaa68ee918fd62c385b40d233d5c631d
        Author: Will Deacon <will.deacon@arm.com>
        Date:   Mon Jan 28 12:06:58 2013 +0000
        
            amba-clcd: separate ioremap framebuffer from DMA implementation
            
As well I hinted above evtchn stuff isn't expected to work due to lack
of asm optimised bitops on ARM causing a fallback to a spinlock based
thing which is no use for talking to the h/v.

I've also hacked around the arch/arm arch/arm64 in the worst possible
ways (where multiple worst options exist I have endeavoured to use both
possible techniques ;-)). We need to decide how to deal with this --
drivers/xen/arm or virt/xen/arm seem like contenders. Tricks based on
-I../../../ etc have been used elsewhere in the kernel but aren't
popular.

It should be pretty obvious this is just a dump, only reason I'm sending
it out is for reference since I'm going AFK for 3 weeks soon, perhaps
someone else will do the kernel side while I'm away, if not I'll pick it
up when I get back.

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ef14873..f1f3706 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1860,8 +1860,9 @@ config XEN_DOM0
 
 config XEN
 	bool "Xen guest support on ARM (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && ARM && OF
+	depends on EXPERIMENTAL && ARM && AEABI && OF
 	depends on CPU_V7 && !CPU_V6
+	depends on !GENERIC_ATOMIC64
 	help
 	  Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
 
diff --git a/arch/arm/include/asm/xen/events.h b/arch/arm/include/asm/xen/events.h
index e86a1b3..8b1f37b 100644
--- a/arch/arm/include/asm/xen/events.h
+++ b/arch/arm/include/asm/xen/events.h
@@ -16,6 +16,8 @@ static inline int xen_irqs_disabled(struct pt_regs *regs)
 	return raw_irqs_disabled_flags(regs->ARM_cpsr);
 }
 
-#define xchg_xen_ulong(ptr, val) atomic64_xchg((atomic64_t *)(ptr), (val))
+#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr),	\
+							    atomic64_t,	\
+							    counter), (val))
 
 #endif /* _ASM_ARM_XEN_EVENTS_H */
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 30cdacb..0ef7370 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -1,7 +1,7 @@
 #ifndef _ASM_ARM_XEN_PAGE_H
 #define _ASM_ARM_XEN_PAGE_H
 
-#include <asm/mach/map.h>
+//#include <asm/mach/map.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
@@ -88,6 +88,10 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 	return __set_phys_to_machine(pfn, mfn);
 }
 
+#ifdef CONFIG_ARM64
+#define xen_remap(cookie, size) __ioremap((cookie), (size), __pgprot(PROT_NORMAL_HACK))
+#else
 #define xen_remap(cookie, size) __arm_ioremap((cookie), (size), MT_MEMORY);
+#endif
 
 #endif /* _ASM_ARM_XEN_PAGE_H */
diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S
index 71f7239..cadf0c0 100644
--- a/arch/arm/xen/hypercall.S
+++ b/arch/arm/xen/hypercall.S
@@ -31,34 +31,52 @@
  */
 
 /*
- * The Xen hypercall calling convention is very similar to the ARM
- * procedure calling convention: the first paramter is passed in r0, the
- * second in r1, the third in r2 and the fourth in r3. Considering that
+ * The Xen hypercall calling convention is very similar to the ARM EABI
+ * procedure calling convention: the first paramter is passed in x0/r0, the
+ * second in x1/r1, the third in x2/r2 and the fourth in x3/r3. Considering that
  * Xen hypercalls have 5 arguments at most, the fifth paramter is passed
- * in r4, differently from the procedure calling convention of using the
+ * in x4/r4, differently from the procedure calling convention of using the
  * stack for that case.
  *
- * The hypercall number is passed in r12.
+ * The hypercall number is passed in r12 (arm) or x16 (arm64). In both cases the
+ * relevant ARM procedure calling convention specifies this is an
+ * inter-procedure-call scratch register (e.g. for use in linker
+ * stubs). This use does not conflict with use during a hypercall.
  *
- * The return value is in r0.
+ * The return value is in r0/x0.
  *
  * The hvc ISS is required to be 0xEA1, that is the Xen specific ARM
  * hypercall tag.
+ *
+ * Parameter structs passed to hypercalls are laid out according to
+	the ARM EABI standard.
  */
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <asm/opcodes-virt.h>
 #include <xen/interface/xen.h>
 
-
 #define XEN_IMM 0xEA1
 
+#ifdef CONFIG_ARM
+
+#include <asm/opcodes-virt.h>
+
+#define HYPERCALL_REG r12
+#define RET mov pc,lr
+	
+#else
+
+#define HYPERCALL_REG x16
+#define __HVC(x) hvc x
+#define RET ret
+#endif
+	
 #define HYPERCALL_SIMPLE(hypercall)		\
 ENTRY(HYPERVISOR_##hypercall)			\
-	mov r12, #__HYPERVISOR_##hypercall;	\
+	mov HYPERCALL_REG, #__HYPERVISOR_##hypercall;	\
 	__HVC(XEN_IMM);						\
-	mov pc, lr;							\
+	RET;							\
 ENDPROC(HYPERVISOR_##hypercall)
 
 #define HYPERCALL0 HYPERCALL_SIMPLE
@@ -67,6 +85,7 @@ ENDPROC(HYPERVISOR_##hypercall)
 #define HYPERCALL3 HYPERCALL_SIMPLE
 #define HYPERCALL4 HYPERCALL_SIMPLE
 
+#ifdef CONFIG_ARM
 #define HYPERCALL5(hypercall)			\
 ENTRY(HYPERVISOR_##hypercall)			\
 	stmdb sp!, {r4}						\
@@ -74,9 +93,12 @@ ENTRY(HYPERVISOR_##hypercall)			\
 	mov r12, #__HYPERVISOR_##hypercall;	\
 	__HVC(XEN_IMM);						\
 	ldm sp!, {r4}						\
-	mov pc, lr							\
+	RET							\
 ENDPROC(HYPERVISOR_##hypercall)
-
+#else
+	/*XXX*/
+#endif
+	
                 .text
 
 HYPERCALL2(xen_version);
@@ -88,6 +110,7 @@ HYPERCALL2(hvm_op);
 HYPERCALL2(memory_op);
 HYPERCALL2(physdev_op);
 
+#ifdef CONFIG_ARM
 ENTRY(privcmd_call)
 	stmdb sp!, {r4}
 	mov r12, r0
@@ -100,3 +123,17 @@ ENTRY(privcmd_call)
 	ldm sp!, {r4}
 	mov pc, lr
 ENDPROC(privcmd_call);
+#else
+ENTRY(privcmd_call)
+	push x4, xzr
+	mov x12, x0
+	mov x0, x1
+	mov x1, x2
+	mov x2, x3
+	ldr x3, [sp, #8]
+	ldr x4, [sp, #4]
+	__HVC(XEN_IMM)
+	pop x5, xzr
+	ret
+ENDPROC(privcmd_call);
+#endif
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f683721..d7d7b02 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -189,6 +189,25 @@ config HW_PERF_EVENTS
 
 source "mm/Kconfig"
 
+config XEN_DOM0
+        def_bool y
+        depends on XEN
+
+config XEN
+        bool "Xen guest support on ARM64 (EXPERIMENTAL)"
+        depends on EXPERIMENTAL && ARM64 && OF
+        #depends on CPU_V7 && !CPU_V6
+        help
+          Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
+
+
+          This option is EXPERIMENTAL because the hypervisor
+          interfaces which it uses are not yet considered stable
+          therefore backwards and forwards compatibility is not yet
+          guaranteed.
+
+          If unsure, say N.
+
 endmenu
 
 menu "Boot options"
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index c95c5cb..8084cb3 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -37,6 +37,7 @@ TEXT_OFFSET := 0x00080000
 export	TEXT_OFFSET GZFLAGS
 
 core-y		+= arch/arm64/kernel/ arch/arm64/mm/
+core-$(CONFIG_XEN)              += arch/arm/xen/
 libs-y		:= arch/arm64/lib/ $(libs-y)
 libs-y		+= $(LIBGCC)
 
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index c343448..eb31952 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -1,4 +1,5 @@
 dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb
+dtb-y += foundation-v8.dtb
 
 targets += dtbs
 targets += $(dtb-y)
diff --git a/arch/arm64/boot/dts/foundation-v8.dts b/arch/arm64/boot/dts/foundation-v8.dts
new file mode 100644
index 0000000..33dc3ff
--- /dev/null
+++ b/arch/arm64/boot/dts/foundation-v8.dts
@@ -0,0 +1,207 @@
+/*
+ * ARM Ltd.
+ *
+ * RTSM Foundation v8 platform (model)
+ *
+ * A very stripped down Versatile Express inspired platform
+ *
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <1>;
+	model = "V2P-AARCH64";
+	compatible = "arm,vexpress,v2p-aarch64", "arm,vexpress";
+	interrupt-parent = <&gic>;
+
+	chosen {
+		bootargs = "dom0_mem=128M dom0_max_vcpus=1 console=com1,vga";
+		xen,dom0-bootargs = "earlyprintk=xenboot console=ttyAMA1 root=/dev/mmcblk0 debug rw init=/root/init.sh";
+	};
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x0 0x8000fff8>;
+		};
+//		cpu@1 {
+//			device_type = "cpu";
+//			compatible = "arm,armv8";
+//			reg = <1>;
+//			enable-method = "spin-table";
+//			cpu-release-addr = <0x0 0x8000fff8>;
+//		};
+//		cpu@2 {
+//			device_type = "cpu";
+//			compatible = "arm,armv8";
+//			reg = <2>;
+//			enable-method = "spin-table";
+//			cpu-release-addr = <0x0 0x8000fff8>;
+//		};
+//		cpu@3 {
+//			device_type = "cpu";
+//			compatible = "arm,armv8";
+//			reg = <3>;
+//			enable-method = "spin-table";
+//			cpu-release-addr = <0x0 0x8000fff8>;
+//		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = < 0x00000000 0x80000000 0x80000000 >;
+//		        0x00000008 0x80000000 0x80000000 >;
+	};
+	 hypervisor {
+		 compatible = "xen,xen-4.2", "xen,xen";
+		 /* this field is going to be adjusted by the hypervisor */
+		 reg = <0 0xb0000000 0x20000>;
+		 /* this field is going to be adjusted by the hypervisor */
+		 interrupts = <1 15 0xf08>;
+	 };
+
+
+	gic: interrupt-controller@2c001000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0 0x2c001000 0x1000>,
+		      <0 0x2c002000 0x1000>,
+		      <0 0x2c004000 0x2000>,
+		      <0 0x2c006000 0x2000>;
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 60 4  0 61 4  0 62 4  0 63 4>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 14 0xff01>;
+		clock-frequency = <100000000>;
+	};
+
+	motherboard {
+		compatible = "simple-bus";
+		arm,v2m-memory-map = "rs1";
+		#address-cells = <2>; /* SMB chipselect number and offset */
+		#size-cells = <1>;
+		#interrupt-cells = <1>;
+
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0  0 4>,
+				<0 0  1 &gic 0  1 4>,
+				<0 0  2 &gic 0  2 4>,
+				<0 0  3 &gic 0  3 4>,
+				<0 0  4 &gic 0  4 4>,
+				<0 0  5 &gic 0  5 4>,
+				<0 0  6 &gic 0  6 4>,
+				<0 0  7 &gic 0  7 4>,
+				<0 0  8 &gic 0  8 4>,
+				<0 0  9 &gic 0  9 4>,
+				<0 0 10 &gic 0 10 4>,
+				<0 0 11 &gic 0 11 4>,
+				<0 0 12 &gic 0 12 4>,
+				<0 0 13 &gic 0 13 4>,
+				<0 0 14 &gic 0 14 4>,
+				<0 0 15 &gic 0 15 4>,
+				<0 0 16 &gic 0 16 4>,
+				<0 0 17 &gic 0 17 4>,
+				<0 0 18 &gic 0 18 4>,
+				<0 0 19 &gic 0 19 4>,
+				<0 0 20 &gic 0 20 4>,
+				<0 0 21 &gic 0 21 4>,
+				<0 0 22 &gic 0 22 4>,
+				<0 0 23 &gic 0 23 4>,
+				<0 0 24 &gic 0 24 4>,
+				<0 0 25 &gic 0 25 4>,
+				<0 0 26 &gic 0 26 4>,
+				<0 0 27 &gic 0 27 4>,
+				<0 0 28 &gic 0 28 4>,
+				<0 0 29 &gic 0 29 4>,
+				<0 0 30 &gic 0 30 4>,
+				<0 0 31 &gic 0 31 4>,
+				<0 0 32 &gic 0 32 4>,
+				<0 0 33 &gic 0 33 4>,
+				<0 0 34 &gic 0 34 4>,
+				<0 0 35 &gic 0 35 4>,
+				<0 0 36 &gic 0 36 4>,
+				<0 0 37 &gic 0 37 4>,
+				<0 0 38 &gic 0 38 4>,
+				<0 0 39 &gic 0 39 4>,
+				<0 0 40 &gic 0 40 4>,
+				<0 0 41 &gic 0 41 4>,
+				<0 0 42 &gic 0 42 4>;
+
+		ranges = <2 0 0x0 0x18000000 0x04000000>,
+			     <3 0 0x0 0x1c000000 0x04000000>;
+
+		ethernet@2,02000000 {
+			compatible = "smsc,lan91c111";
+			reg = <2 0x02000000 0x10000>;
+			interrupts = <15>;
+		};
+
+		iofpga@3,00000000 {
+			compatible = "arm,amba-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 3 0 0x200000>;
+
+			sysreg@010000 {
+				compatible = "arm,vexpress-sysreg";
+				reg = <0x010000 0x1000>;
+			};
+
+			v2m_serial0: uart@090000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x090000 0x1000>;
+				interrupts = <5>;
+			};
+
+			v2m_serial1: uart@0a0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0a0000 0x1000>;
+				interrupts = <6>;
+			};
+
+			v2m_serial2: uart@0b0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0b0000 0x1000>;
+				interrupts = <7>;
+			};
+
+			v2m_serial3: uart@0c0000 {
+				compatible = "arm,pl011", "arm,primecell";
+				reg = <0x0c0000 0x1000>;
+				interrupts = <8>;
+			};
+
+			virtio_block@0130000 {
+				compatible = "virtio,mmio";
+				reg = <0x130000 0x1000>;
+				interrupts = <42>;
+			};
+		};
+	};
+
+	/* chosen */
+};
+
diff --git a/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts b/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts
index 89c3065..d583ff8 100644
--- a/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts
+++ b/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts
@@ -21,7 +21,20 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	chosen { };
+	chosen {
+                 bootargs = "dom0_mem=128M dom0_max_vcpus=1 console=com1,vga";
+                 xen,dom0-bootargs = "earlyprintk=xenboot console=ttyAMA1 root=/dev/mmcblk0 debug rw init=/root/init.sh";
+//                 bootargs = "console=ttyAMA0 earlyprintk=pl011,0x1c090000 root=/dev/mmcblk0 debug rw init=/root/init.sh";
+                 /*xen,dom0-bootargs = "earlyprintk=xenboot console=hvc0 root=/dev/mmcblk0 debug rw init=/root/init.sh";*/
+	 };
+	hypervisor {
+		compatible = "xen,xen-4.2", "xen,xen";
+		/* this field is going to be adjusted by the hypervisor */
+		reg = <0 0xb0000000 0 0x20000>;
+		/* this field is going to be adjusted by the hypervisor */
+		interrupts = <1 15 0xf08>;
+	};
+
 
 	aliases {
 		serial0 = &v2m_serial0;
@@ -41,33 +54,11 @@
 			enable-method = "spin-table";
 			cpu-release-addr = <0x0 0x8000fff8>;
 		};
-		cpu@1 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <1>;
-			enable-method = "spin-table";
-			cpu-release-addr = <0x0 0x8000fff8>;
-		};
-		cpu@2 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <2>;
-			enable-method = "spin-table";
-			cpu-release-addr = <0x0 0x8000fff8>;
-		};
-		cpu@3 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <3>;
-			enable-method = "spin-table";
-			cpu-release-addr = <0x0 0x8000fff8>;
-		};
 	};
 
 	memory@80000000 {
 		device_type = "memory";
-		reg = <0x00000000 0x80000000 0 0x80000000>,
-		      <0x00000008 0x80000000 0 0x80000000>;
+		reg = <0x00000000 0x80000000 0 0x80000000>;
 	};
 
 	gic: interrupt-controller@2c001000 {
@@ -76,7 +67,9 @@
 		#address-cells = <0>;
 		interrupt-controller;
 		reg = <0 0x2c001000 0 0x1000>,
-		      <0 0x2c002000 0 0x100>;
+		      <0 0x2c002000 0 0x100>,
+		      <0 0x2c004000 0 0x2000>,
+		      <0 0x2c006000 0 0x2000>;
 	};
 
 	timer {
diff --git a/arch/arm64/include/asm/hypervisor.h b/arch/arm64/include/asm/hypervisor.h
new file mode 100644
index 0000000..b90d9e5
--- /dev/null
+++ b/arch/arm64/include/asm/hypervisor.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_ARM_HYPERVISOR_H
+#define _ASM_ARM_HYPERVISOR_H
+
+#include <asm/xen/hypervisor.h>
+
+#endif
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 57f12c9..fc95a8e 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -224,6 +224,7 @@ extern void __iounmap(volatile void __iomem *addr);
 #define PROT_DEFAULT		(PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY)
 #define PROT_DEVICE_nGnRE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
 #define PROT_NORMAL_NC		(PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC))
+#define PROT_NORMAL_HACK	(PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
 
 #define ioremap(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_nocache(addr, size)	__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
diff --git a/arch/arm64/include/asm/sync_bitops.h b/arch/arm64/include/asm/sync_bitops.h
new file mode 100644
index 0000000..fa323e6
--- /dev/null
+++ b/arch/arm64/include/asm/sync_bitops.h
@@ -0,0 +1,26 @@
+#ifndef __ASM_SYNC_BITOPS_H__
+#define __ASM_SYNC_BITOPS_H__
+
+#include <asm/bitops.h>
+#include <asm/cmpxchg.h>
+
+/* sync_bitops functions are equivalent to the SMP implementation of the
+ * original functions, independently from CONFIG_SMP being defined.
+ *
+ * We need them because _set_bit etc are not SMP safe if !CONFIG_SMP. But
+ * under Xen you might be communicating with a completely external entity
+ * who might be on another CPU (e.g. two uniprocessor guests communicating
+ * via event channels and grant tables). So we need a variant of the bit
+ * ops which are SMP safe even on a UP kernel.
+ */
+
+#define sync_set_bit(nr, p)		_set_bit(nr, p)
+#define sync_clear_bit(nr, p)		_clear_bit(nr, p)
+#define sync_change_bit(nr, p)		_change_bit(nr, p)
+#define sync_test_and_set_bit(nr, p)	_test_and_set_bit(nr, p)
+#define sync_test_and_clear_bit(nr, p)	_test_and_clear_bit(nr, p)
+#define sync_test_and_change_bit(nr, p)	_test_and_change_bit(nr, p)
+#define sync_test_bit(nr, addr)		test_bit(nr, addr)
+#define sync_cmpxchg			cmpxchg
+
+#endif
diff --git a/arch/arm64/include/asm/xen/events.h b/arch/arm64/include/asm/xen/events.h
new file mode 100644
index 0000000..4b4834f
--- /dev/null
+++ b/arch/arm64/include/asm/xen/events.h
@@ -0,0 +1,22 @@
+#ifndef _ASM_ARM_XEN_EVENTS_H
+#define _ASM_ARM_XEN_EVENTS_H
+
+#include <asm/ptrace.h>
+
+enum ipi_vector {
+	XEN_PLACEHOLDER_VECTOR,
+
+	/* Xen IPIs go here */
+	XEN_NR_IPIS,
+};
+
+static inline int xen_irqs_disabled(struct pt_regs *regs)
+{
+	return raw_irqs_disabled_flags(regs->pstate);
+}
+
+#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr),	\
+							    atomic64_t,	\
+							    counter), (val))
+
+#endif /* _ASM_ARM_XEN_EVENTS_H */
diff --git a/arch/arm64/include/asm/xen/hypercall.h b/arch/arm64/include/asm/xen/hypercall.h
new file mode 120000
index 0000000..3c2e6ce
--- /dev/null
+++ b/arch/arm64/include/asm/xen/hypercall.h
@@ -0,0 +1 @@
+../../../../arm/include/asm/xen/hypercall.h
\ No newline at end of file
diff --git a/arch/arm64/include/asm/xen/hypervisor.h b/arch/arm64/include/asm/xen/hypervisor.h
new file mode 120000
index 0000000..e7c8923
--- /dev/null
+++ b/arch/arm64/include/asm/xen/hypervisor.h
@@ -0,0 +1 @@
+../../../../arm/include/asm/xen/hypervisor.h
\ No newline at end of file
diff --git a/arch/arm64/include/asm/xen/interface.h b/arch/arm64/include/asm/xen/interface.h
new file mode 120000
index 0000000..3d12f53
--- /dev/null
+++ b/arch/arm64/include/asm/xen/interface.h
@@ -0,0 +1 @@
+../../../../arm/include/asm/xen/interface.h
\ No newline at end of file
diff --git a/arch/arm64/include/asm/xen/page.h b/arch/arm64/include/asm/xen/page.h
new file mode 120000
index 0000000..671b1d3
--- /dev/null
+++ b/arch/arm64/include/asm/xen/page.h
@@ -0,0 +1 @@
+../../../../arm/include/asm/xen/page.h
\ No newline at end of file
diff --git a/arch/arm64/xen b/arch/arm64/xen
new file mode 120000
index 0000000..2a99060
--- /dev/null
+++ b/arch/arm64/xen
@@ -0,0 +1 @@
+../arm/xen
\ No newline at end of file
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
index 8286f90..2846439 100644
--- a/drivers/mfd/vexpress-sysreg.c
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -260,10 +260,11 @@ static int vexpress_sysreg_config_func_exec(void *func, int offset,
 		/* Early execution, no timer available, have to spin */
 		u32 cfgstat;
 
-		do {
-			cpu_relax();
-			cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
-		} while (!cfgstat);
+		cpu_relax();
+//		do {
+//			cpu_relax();
+//			cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
+//		} while (!cfgstat);
 
 		if (!write && (cfgstat & SYS_CFGSTAT_COMPLETE))
 			*data = readl(vexpress_sysreg_base + SYS_CFGDATA);
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 651b576..36f0c91 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -355,20 +355,20 @@ static void init_evtchn_cpu_bindings(void)
 
 static inline void clear_evtchn(int port)
 {
-	struct shared_info *s = HYPERVISOR_shared_info;
-	sync_clear_bit(port, BM(&s->evtchn_pending[0]));
+	//struct shared_info *s = HYPERVISOR_shared_info;
+	//sync_clear_bit(port, &s->evtchn_pending[0]);
 }
 
 static inline void set_evtchn(int port)
 {
-	struct shared_info *s = HYPERVISOR_shared_info;
-	sync_set_bit(port, BM(&s->evtchn_pending[0]));
+	//struct shared_info *s = HYPERVISOR_shared_info;
+	//sync_set_bit(port, &s->evtchn_pending[0]);
 }
 
 static inline int test_evtchn(int port)
 {
-	struct shared_info *s = HYPERVISOR_shared_info;
-	return sync_test_bit(port, BM(&s->evtchn_pending[0]));
+	//struct shared_info *s = HYPERVISOR_shared_info;
+	return 0; //sync_test_bit(port, &s->evtchn_pending[0]);
 }
 
 
@@ -391,8 +391,8 @@ EXPORT_SYMBOL_GPL(notify_remote_via_irq);
 
 static void mask_evtchn(int port)
 {
-	struct shared_info *s = HYPERVISOR_shared_info;
-	sync_set_bit(port, BM(&s->evtchn_mask[0]));
+	//struct shared_info *s = HYPERVISOR_shared_info;
+	//sync_set_bit(port, &s->evtchn_mask[0]);
 }
 
 static void unmask_evtchn(int port)
@@ -418,6 +418,7 @@ static void unmask_evtchn(int port)
 		struct evtchn_unmask unmask = { .port = port };
 		(void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
 	} else {
+#if 0
 		struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
 
 		sync_clear_bit(port, BM(&s->evtchn_mask[0]));
@@ -431,6 +432,7 @@ static void unmask_evtchn(int port)
 		    !sync_test_and_set_bit(port / BITS_PER_EVTCHN_WORD,
 					   BM(&vcpu_info->evtchn_pending_sel)))
 			vcpu_info->evtchn_upcall_pending = 1;
+#endif
 	}
 
 	put_cpu();
@@ -1523,16 +1525,16 @@ static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest,
 
 int resend_irq_on_evtchn(unsigned int irq)
 {
-	int masked, evtchn = evtchn_from_irq(irq);
-	struct shared_info *s = HYPERVISOR_shared_info;
+//	int masked, evtchn = evtchn_from_irq(irq);
+//	struct shared_info *s = HYPERVISOR_shared_info;
 
-	if (!VALID_EVTCHN(evtchn))
-		return 1;
+//	if (!VALID_EVTCHN(evtchn))
+//		return 1;
 
-	masked = sync_test_and_set_bit(evtchn, BM(s->evtchn_mask));
-	sync_set_bit(evtchn, BM(s->evtchn_pending));
-	if (!masked)
-		unmask_evtchn(evtchn);
+//	masked = sync_test_and_set_bit(evtchn, s->evtchn_mask);
+//	sync_set_bit(evtchn, s->evtchn_pending);
+//	if (!masked)
+//		unmask_evtchn(evtchn);
 
 	return 1;
 }
@@ -1576,12 +1578,12 @@ static int retrigger_dynirq(struct irq_data *data)
 	int ret = 0;
 
 	if (VALID_EVTCHN(evtchn)) {
-		int masked;
+//		int masked;
 
-		masked = sync_test_and_set_bit(evtchn, BM(sh->evtchn_mask));
-		sync_set_bit(evtchn, BM(sh->evtchn_pending));
-		if (!masked)
-			unmask_evtchn(evtchn);
+//		masked = sync_test_and_set_bit(evtchn, sh->evtchn_mask);
+//		sync_set_bit(evtchn, sh->evtchn_pending);
+//		if (!masked)
+//			unmask_evtchn(evtchn);
 		ret = 1;
 	}
 
diff --git a/include/xen/interface/io/protocols.h b/include/xen/interface/io/protocols.h
index 0eafaf2..056744b 100644
--- a/include/xen/interface/io/protocols.h
+++ b/include/xen/interface/io/protocols.h
@@ -15,7 +15,7 @@
 # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_IA64
 #elif defined(__powerpc64__)
 # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_POWERPC64
-#elif defined(__arm__)
+#elif defined(__arm__) || defined(__aarch64__)
 # define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_ARM
 #else
 # error arch fixup needed here
diff --git a/kernel/printk.c b/kernel/printk.c
index 587404d..f4ad381 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1542,7 +1542,6 @@ asmlinkage int vprintk_emit(int facility, int level,
 	 * prefix which might be passed-in as a parameter.
 	 */
 	text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
-	xen_raw_console_write(text);
 
 	/* mark and strip a trailing newline */
 	if (text_len && text[text_len-1] == '\n') {

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

* [PATCH 01/14] xen: arm: define 64-bit guest hypercall calling convention.
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
  2013-03-12 15:03 ` Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-04-08 11:17   ` Stefano Stabellini
  2013-03-12 15:48 ` [PATCH 02/14] xen: arm: tweak arm64 stack frame layout Ian Campbell
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

As well as using x<N> rather than r<N> registers for passing arguments/results
as mandate the use of x16 as the hypercall number.

Add some pedantry about struct alignment layout referencing the ARM Procedure
Calling Standard to avoid confusion with the previous "OABI" convention. While
at it also mandate that hypercall argument structs are always little endian.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/include/public/arch-arm.h |   27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index 3333399..e44e90f 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -33,20 +33,31 @@
  * A hypercall is issued using the ARM HVC instruction.
  *
  * A hypercall can take up to 5 arguments. These are passed in
- * registers, the first argument in r0, the second argument in r1, the
- * third in r2, the forth in r3 and the fifth in r4.
+ * registers, the first argument in x0/r0 (for arm64/arm32 guests
+ * respectively irrespective of whether the underlying hypervisor is
+ * 32- or 64-bit), the second argument in x1/r1, the third in x2/r2,
+ * the forth in x3/r3 and the fifth in x4/r4.
  *
- * The hypercall number is passed in r12.
+ * The hypercall number is passed in r12 (arm) or x16 (arm64). In both
+ * cases the relevant ARM procedure calling convention specifies this
+ * is an inter-procedure-call scratch register (e.g. for use in linker
+ * stubs). This use does not conflict with use during a hypercall.
  *
  * The HVC ISS must contain a Xen specific TAG: XEN_HYPERCALL_TAG.
  *
- * The return value is in r0.
+ * The return value is in x0/r0.
  *
- * The hypercall will clobber r12 and the argument registers used by
- * that hypercall (except r0 which is the return value) i.e. a 2
- * argument hypercall will clobber r1 and a 4 argument hypercall will
- * clobber r1, r2 and r3.
+ * The hypercall will clobber x16/r12 and the argument registers used
+ * by that hypercall (except r0 which is the return value) i.e. in
+ * addition to x16/r12 a 2 argument hypercall will clobber x1/r1 and a
+ * 4 argument hypercall will clobber x1/r1, x2/r2 and x3/r3.
  *
+ * Parameter structs passed to hypercalls are laid out according to
+ * the Procedure Call Standard for the ARM Architecture (AAPCS, AKA
+ * EABI) and Procedure Call Standard for the ARM 64-bit Architecture
+ * (AAPCS64). Where there is a conflict the 64-bit standard should be
+ * used regardless of guest type. Structures which are passed as
+ * hypercall arguments are always little endian.
  */
 
 #define XEN_HYPERCALL_TAG   0XEA1
-- 
1.7.10.4

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

* [PATCH 02/14] xen: arm: tweak arm64 stack frame layout
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
  2013-03-12 15:03 ` Ian Campbell
  2013-03-12 15:48 ` [PATCH 01/14] xen: arm: define 64-bit guest hypercall calling convention Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-04-08 13:31   ` Stefano Stabellini
  2013-03-12 15:48 ` [PATCH 03/14] xen: arm: rename 32-bit specific zImage field offset constants Ian Campbell
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

Correct definition of UREGS_kernel_sizeof and use it.

Correct adjustment of stack on entry and exit.

Add 64-bit versions of the build time checks for stack pointer alignment
correctness when pushing the stack frames.

Lastly, correct the padding in the stack frames to properly align the inner and
outer frames and also avoid an unnecessary 64bit padding field.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/arm64/asm-offsets.c      |    2 +-
 xen/arch/arm/arm64/entry.S            |    9 +++++----
 xen/arch/arm/domain.c                 |    2 ++
 xen/arch/arm/traps.c                  |    7 +++++++
 xen/include/asm-arm/arm64/processor.h |    7 +++----
 5 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/xen/arch/arm/arm64/asm-offsets.c b/xen/arch/arm/arm64/asm-offsets.c
index 7949e3e..7544082 100644
--- a/xen/arch/arm/arm64/asm-offsets.c
+++ b/xen/arch/arm/arm64/asm-offsets.c
@@ -39,7 +39,7 @@ void __dummy__(void)
    OFFSET(UREGS_SP_el1, struct cpu_user_regs, sp_el1);
    OFFSET(UREGS_ELR_el1, struct cpu_user_regs, elr_el1);
 
-   OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, cpsr);
+   OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, spsr_el1);
    DEFINE(UREGS_user_sizeof, sizeof(struct cpu_user_regs));
    BLANK();
 
diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
index 9d38088..a5fd608 100644
--- a/xen/arch/arm/arm64/entry.S
+++ b/xen/arch/arm/arm64/entry.S
@@ -34,7 +34,7 @@ lr      .req    x30             // link register
         mrs     x22, SP_el0
         str     x22, [x21]
 
-        add     x21, sp, #UREGS_ELR_el1
+        add     x21, sp, #UREGS_SP_el1
         mrs     x22, SP_el1
         mrs     x23, ELR_el1
         stp     x22, x23, [x21]
@@ -59,7 +59,7 @@ lr      .req    x30             // link register
  * Save state on entry to hypervisor
  */
         .macro  entry, hyp, compat
-        sub     sp, sp, #(UREGS_SPSR_el1 - UREGS_SP)
+        sub     sp, sp, #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */
         push    x28, x29
         push    x26, x27
         push    x24, x25
@@ -78,7 +78,7 @@ lr      .req    x30             // link register
 
         .if \hyp == 1        /* Hypervisor mode */
 
-        add     x21, sp, #(UREGS_X0 - UREGS_SP)
+        add     x21, sp, #UREGS_kernel_sizeof
 
         .else                /* Guest mode */
 
@@ -213,7 +213,8 @@ ENTRY(return_to_hypervisor)
         pop     x26, x27
         pop     x28, x29
 
-        ldr     lr, [sp], #(UREGS_SPSR_el1 - UREGS_SP)
+        ldr     lr, [sp], #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */
+
         eret
 
 /*
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index f369871..08bb132 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -419,6 +419,8 @@ int vcpu_initialise(struct vcpu *v)
 {
     int rc = 0;
 
+    BUILD_BUG_ON( sizeof(struct cpu_info) > STACK_SIZE );
+
     v->arch.stack = alloc_xenheap_pages(STACK_ORDER, MEMF_node(vcpu_to_node(v)));
     if ( v->arch.stack == NULL )
         return -ENOMEM;
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index a98a45e..6b19bc5 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -43,9 +43,16 @@
  * entry.S) and struct cpu_info (which lives at the bottom of a Xen
  * stack) must be doubleword-aligned in size.  */
 static inline void check_stack_alignment_constraints(void) {
+#ifdef CONFIG_ARM_64
+    BUILD_BUG_ON((sizeof (struct cpu_user_regs)) & 0xf);
+    BUILD_BUG_ON((offsetof(struct cpu_user_regs, spsr_el1)) & 0xf);
+    BUILD_BUG_ON((offsetof(struct cpu_user_regs, lr)) & 0xf);
+    BUILD_BUG_ON((sizeof (struct cpu_info)) & 0xf);
+#else
     BUILD_BUG_ON((sizeof (struct cpu_user_regs)) & 0x7);
     BUILD_BUG_ON((offsetof(struct cpu_user_regs, sp_usr)) & 0x7);
     BUILD_BUG_ON((sizeof (struct cpu_info)) & 0x7);
+#endif
 }
 
 static int debug_stack_lines = 20;
diff --git a/xen/include/asm-arm/arm64/processor.h b/xen/include/asm-arm/arm64/processor.h
index b4602fa..bf436c8 100644
--- a/xen/include/asm-arm/arm64/processor.h
+++ b/xen/include/asm-arm/arm64/processor.h
@@ -51,6 +51,7 @@ struct cpu_user_regs
     __DECL_REG(x27,          r11_fiq);
     __DECL_REG(x28,          r12_fiq);
     __DECL_REG(/* x29 */ fp, /* r13_fiq */ sp_fiq);
+
     __DECL_REG(/* x30 */ lr, /* r14_fiq */ lr_fiq);
 
     register_t sp; /* Valid for hypervisor frames */
@@ -59,7 +60,7 @@ struct cpu_user_regs
     __DECL_REG(pc,           pc32);             /* ELR_EL2 */
     uint32_t cpsr;                              /* SPSR_EL2 */
 
-    uint64_t pad0;
+    uint32_t pad0; /* Align end of kernel frame. */
 
     /* Outer guest frame only from here on... */
 
@@ -68,7 +69,7 @@ struct cpu_user_regs
         uint32_t spsr_svc;       /* AArch32 */
     };
 
-    uint32_t pad1; /* Align */
+    uint32_t pad1; /* Doubleword-align the user half of the frame */
 
     /* AArch32 guests only */
     uint32_t spsr_fiq, spsr_irq, spsr_und, spsr_abt;
@@ -76,8 +77,6 @@ struct cpu_user_regs
     /* AArch64 guests only */
     uint64_t sp_el0;
     uint64_t sp_el1, elr_el1;
-
-    uint64_t pad2; /* Doubleword-align the user half of the frame */
 };
 
 #undef __DECL_REG
-- 
1.7.10.4

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

* [PATCH 03/14] xen: arm: rename 32-bit specific zImage field offset constants
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (2 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 02/14] xen: arm: tweak arm64 stack frame layout Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-03-12 15:48 ` [PATCH 04/14] xen: arm: support for loading 64-bit zImage dom0 Ian Campbell
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

This will help avoid confusion when 64-bit Image support is added.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/kernel.c |   28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c
index 8f4a60d..e7f34a4 100644
--- a/xen/arch/arm/kernel.c
+++ b/xen/arch/arm/kernel.c
@@ -19,12 +19,12 @@
 #define KERNEL_FLASH_ADDRESS 0x00000000UL
 #define KERNEL_FLASH_SIZE    0x00800000UL
 
-#define ZIMAGE_MAGIC_OFFSET 0x24
-#define ZIMAGE_START_OFFSET 0x28
-#define ZIMAGE_END_OFFSET   0x2c
-#define ZIMAGE_HEADER_LEN   0x30
+#define ZIMAGE32_MAGIC_OFFSET 0x24
+#define ZIMAGE32_START_OFFSET 0x28
+#define ZIMAGE32_END_OFFSET   0x2c
+#define ZIMAGE32_HEADER_LEN   0x30
 
-#define ZIMAGE_MAGIC 0x016f2818
+#define ZIMAGE32_MAGIC 0x016f2818
 
 struct minimal_dtb_header {
     uint32_t magic;
@@ -99,26 +99,26 @@ static void kernel_zimage_load(struct kernel_info *info)
     }
 }
 
-/**
- * Check the image is a zImage and return the load address and length
+/*
+ * Check if the image is a 32-bit zImage and setup kernel_info
  */
-static int kernel_try_zimage_prepare(struct kernel_info *info,
+static int kernel_try_zimage32_prepare(struct kernel_info *info,
                                      paddr_t addr, paddr_t size)
 {
-    uint32_t zimage[ZIMAGE_HEADER_LEN/4];
+    uint32_t zimage[ZIMAGE32_HEADER_LEN/4];
     uint32_t start, end;
     struct minimal_dtb_header dtb_hdr;
 
-    if ( size < ZIMAGE_HEADER_LEN )
+    if ( size < ZIMAGE32_HEADER_LEN )
         return -EINVAL;
 
     copy_from_paddr(zimage, addr, sizeof(zimage), DEV_SHARED);
 
-    if (zimage[ZIMAGE_MAGIC_OFFSET/4] != ZIMAGE_MAGIC)
+    if (zimage[ZIMAGE32_MAGIC_OFFSET/4] != ZIMAGE32_MAGIC)
         return -EINVAL;
 
-    start = zimage[ZIMAGE_START_OFFSET/4];
-    end = zimage[ZIMAGE_END_OFFSET/4];
+    start = zimage[ZIMAGE32_START_OFFSET/4];
+    end = zimage[ZIMAGE32_END_OFFSET/4];
 
     if ( (end - start) > size )
         return -EINVAL;
@@ -224,7 +224,7 @@ int kernel_prepare(struct kernel_info *info)
         info->load_attr = BUFFERABLE;
     }
 
-    rc = kernel_try_zimage_prepare(info, start, size);
+    rc = kernel_try_zimage32_prepare(info, start, size);
     if (rc < 0)
         rc = kernel_try_elf_prepare(info, start, size);
 
-- 
1.7.10.4

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

* [PATCH 04/14] xen: arm: support for loading 64-bit zImage dom0
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (3 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 03/14] xen: arm: rename 32-bit specific zImage field offset constants Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-04-08 11:24   ` Stefano Stabellini
  2013-03-12 15:48 ` [PATCH 05/14] xen: arm: support building a 64-bit dom0 domain Ian Campbell
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

This is defined in linux/Documentation/arm64/booting.txt.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/kernel.c |   80 +++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 75 insertions(+), 5 deletions(-)

diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c
index e7f34a4..59844b0 100644
--- a/xen/arch/arm/kernel.c
+++ b/xen/arch/arm/kernel.c
@@ -26,6 +26,8 @@
 
 #define ZIMAGE32_MAGIC 0x016f2818
 
+#define ZIMAGE64_MAGIC 0x14000008
+
 struct minimal_dtb_header {
     uint32_t magic;
     uint32_t total_size;
@@ -99,6 +101,57 @@ static void kernel_zimage_load(struct kernel_info *info)
     }
 }
 
+#ifdef CONFIG_ARM_64
+/*
+ * Check if the image is a 64-bit zImage and setup kernel_info
+ */
+static int kernel_try_zimage64_prepare(struct kernel_info *info,
+                                     paddr_t addr, paddr_t size)
+{
+    /* linux/Documentation/arm64/booting.txt */
+    struct {
+        uint32_t magic;
+        uint32_t res0;
+        uint64_t text_offset;  /* Image load offset */
+        uint64_t res1;
+        uint64_t res2;
+    } zimage;
+    uint64_t start, end;
+
+    if ( size < sizeof(zimage) )
+        return -EINVAL;
+
+    copy_from_paddr(&zimage, addr, sizeof(zimage), DEV_SHARED);
+
+    if (zimage.magic != ZIMAGE64_MAGIC)
+        return -EINVAL;
+
+    /* Currently there is no length in the header, so just use the size */
+    start = 0;
+    end = size;
+
+    /*
+     * Given the above this check is a bit pointless, but leave it
+     * here in case someone adds a length field in the future.
+     */
+    if ( (end - start) > size )
+        return -EINVAL;
+
+    info->zimage.kernel_addr = addr;
+
+    info->zimage.load_addr = info->mem.bank[0].start
+        + zimage.text_offset;
+    info->zimage.len = end - start;
+
+    info->entry = info->zimage.load_addr;
+    info->load = kernel_zimage_load;
+
+    info->type = DOMAIN_PV64;
+
+    return 0;
+}
+#endif
+
 /*
  * Check if the image is a 32-bit zImage and setup kernel_info
  */
@@ -153,6 +206,10 @@ static int kernel_try_zimage32_prepare(struct kernel_info *info,
     info->entry = info->zimage.load_addr;
     info->load = kernel_zimage_load;
 
+#ifdef CONFIG_ARM_64
+    info->type = DOMAIN_PV32;
+#endif
+
     return 0;
 }
 
@@ -187,6 +244,19 @@ static int kernel_try_elf_prepare(struct kernel_info *info,
     if ( (rc = elf_xen_parse(&info->elf.elf, &info->elf.parms)) != 0 )
         goto err;
 
+#ifdef CONFIG_ARM_64
+    if ( elf_32bit(&info->elf.elf) )
+        info->type = DOMAIN_PV32;
+    else if ( elf_64bit(&info->elf.elf) )
+        info->type = DOMAIN_PV64;
+    else
+    {
+        printk("Unknown ELF class\n");
+        rc = -EINVAL;
+        goto err;
+    }
+#endif
+
     /*
      * TODO: can the ELF header be used to find the physical address
      * to load the image to?  Instead of assuming virt == phys.
@@ -224,13 +294,13 @@ int kernel_prepare(struct kernel_info *info)
         info->load_attr = BUFFERABLE;
     }
 
-    rc = kernel_try_zimage32_prepare(info, start, size);
-    if (rc < 0)
-        rc = kernel_try_elf_prepare(info, start, size);
-
 #ifdef CONFIG_ARM_64
-    info->type = DOMAIN_PV32; /* No 64-bit guest support yet */
+    rc = kernel_try_zimage64_prepare(info, start, size);
+    if (rc < 0)
 #endif
+        rc = kernel_try_zimage32_prepare(info, start, size);
+    if (rc < 0)
+        rc = kernel_try_elf_prepare(info, start, size);
 
     return rc;
 }
-- 
1.7.10.4

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

* [PATCH 05/14] xen: arm: support building a 64-bit dom0 domain
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (4 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 04/14] xen: arm: support for loading 64-bit zImage dom0 Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-04-08 11:25   ` Stefano Stabellini
  2013-03-12 15:48 ` [PATCH 06/14] xen: arm: precalculate VTTBR_EL2 for a domain when setting up its p2m Ian Campbell
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/domain_build.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index f161845..b1402d5 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -334,9 +334,8 @@ int construct_dom0(struct domain *d)
 
     memset(regs, 0, sizeof(*regs));
 
-    regs->pc = (uint32_t)kinfo.entry;
+    regs->pc = (register_t)kinfo.entry;
 
-    regs->cpsr = PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC;
 
 #ifdef CONFIG_ARM_64
     d->arch.type = kinfo.type;
@@ -344,6 +343,11 @@ int construct_dom0(struct domain *d)
 
     if ( is_pv32_domain(d) )
     {
+        regs->cpsr = PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC;
+
+        /* Pretend to be a Cortex A15 */
+        d->arch.vpidr = 0x410fc0f0;
+
         /* FROM LINUX head.S
          *
          * Kernel startup entry point.
@@ -361,6 +365,8 @@ int construct_dom0(struct domain *d)
 #ifdef CONFIG_ARM_64
     else
     {
+        regs->cpsr = PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h;
+
         /* From linux/Documentation/arm64/booting.txt */
         regs->x0 = kinfo.dtb_paddr;
         regs->x1 = 0; /* Reserved for future use */
-- 
1.7.10.4

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

* [PATCH 06/14] xen: arm: precalculate VTTBR_EL2 for a domain when setting up its p2m
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (5 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 05/14] xen: arm: support building a 64-bit dom0 domain Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-04-08 11:27   ` Stefano Stabellini
  2013-03-12 15:48 ` [PATCH 07/14] xen: arm: improve register dump output for 64-bit guest (and more generally too) Ian Campbell
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

Mostly just to help with upcoming vcpu_show_registers changes.

Signed-off-by: Ian Campbell <ijc@hellion.org.uk>
---
 xen/arch/arm/p2m.c           |   16 +++++++++-------
 xen/include/asm-arm/domain.h |    3 +++
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 1e8c8b4..175216c 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -23,13 +23,10 @@ void dump_p2m_lookup(struct domain *d, paddr_t addr)
 
 void p2m_load_VTTBR(struct domain *d)
 {
-    struct p2m_domain *p2m = &d->arch.p2m;
-    paddr_t maddr = page_to_maddr(p2m->first_level);
-    uint64_t vttbr = maddr;
-
-    vttbr |= ((uint64_t)p2m->vmid&0xff)<<48;
-
-    WRITE_SYSREG64(vttbr, VTTBR_EL2);
+    if ( is_idle_domain(d) )
+        return;
+    BUG_ON(!d->arch.vttbr);
+    WRITE_SYSREG64(d->arch.vttbr, VTTBR_EL2);
     isb(); /* Ensure update is visible */
 }
 
@@ -300,6 +297,9 @@ int p2m_alloc_table(struct domain *d)
 
     p2m->first_level = page;
 
+    d->arch.vttbr = page_to_maddr(p2m->first_level)
+        | ((uint64_t)p2m->vmid&0xff)<<48;
+
     spin_unlock(&p2m->lock);
 
     return 0;
@@ -331,6 +331,8 @@ int p2m_init(struct domain *d)
     /* Zero is reserved */
     p2m->vmid = d->domain_id + 1;
 
+    d->arch.vttbr = 0;
+
     p2m->first_level = NULL;
 
     return 0;
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index bf9caff..3da9163 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -53,7 +53,10 @@ struct arch_domain
     enum domain_type type;
 #endif
 
+    /* Virtual MMU */
     struct p2m_domain p2m;
+    uint64_t vttbr;
+
     struct hvm_domain hvm_domain;
     xen_pfn_t *grant_table_gpfn;
 
-- 
1.7.10.4

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

* [PATCH 07/14] xen: arm: improve register dump output for 64-bit guest (and more generally too)
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (6 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 06/14] xen: arm: precalculate VTTBR_EL2 for a domain when setting up its p2m Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-03-12 15:48 ` [PATCH 08/14] xen: arm: support dumping 64-bit guest stack Ian Campbell
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c         |  171 +++++++++++++++++++++++++++---------------
 xen/include/asm-arm/cpregs.h |    1 +
 2 files changed, 113 insertions(+), 59 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 6b19bc5..2f4e157 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -238,7 +238,7 @@ void panic_PAR(uint64_t par)
 
     msg = decode_fsc( (par&PAR_FSC_MASK) >> PAR_FSC_SHIFT, &level);
 
-    printk("PAR: %010"PRIx64": %s stage %d%s%s\n",
+    printk("PAR: %016"PRIx64": %s stage %d%s%s\n",
            par, msg,
            stage,
            second_in_first ? " during second stage lookup" : "",
@@ -248,33 +248,60 @@ void panic_PAR(uint64_t par)
 }
 
 struct reg_ctxt {
-    uint32_t sctlr, tcr;
-    uint64_t ttbr0, ttbr1;
+    /* Guest-side state */
+    uint32_t sctlr_el1, tcr_el1;
+    uint64_t ttbr0_el1, ttbr1_el1;
 #ifdef CONFIG_ARM_32
+    uint32_t dfsr, ifsr;
     uint32_t dfar, ifar;
 #else
+    uint32_t esr_el1;
     uint64_t far;
+    uint32_t ifsr32_el2;
 #endif
+
+    /* Hypervisor-side state */
+    uint64_t vttbr_el2;
 };
 
+static const char *mode_string(uint32_t cpsr)
+{
+    uint32_t mode;
+    static const char *mode_strings[] = {
+       [PSR_MODE_USR] = "32-bit Guest USR",
+       [PSR_MODE_FIQ] = "32-bit Guest FIQ",
+       [PSR_MODE_IRQ] = "32-bit Guest IRQ",
+       [PSR_MODE_SVC] = "32-bit Guest SVC",
+       [PSR_MODE_MON] = "32-bit Monitor",
+       [PSR_MODE_ABT] = "32-bit Guest ABT",
+       [PSR_MODE_HYP] = "Hypervisor",
+       [PSR_MODE_UND] = "32-bit Guest UND",
+       [PSR_MODE_SYS] = "32-bit Guest SYS",
+#ifdef CONFIG_ARM_64
+       [PSR_MODE_EL3h] = "64-bit EL3h (Monitor, handler)",
+       [PSR_MODE_EL3t] = "64-bit EL3t (Monitor, thread)",
+       [PSR_MODE_EL2h] = "64-bit EL2h (Hypervisor, handler)",
+       [PSR_MODE_EL2t] = "64-bit EL2t (Hypervisor, thread)",
+       [PSR_MODE_EL1h] = "64-bit EL1h (Guest Kernel, handler)",
+       [PSR_MODE_EL1t] = "64-bit EL1t (Guest Kernel, thread)",
+       [PSR_MODE_EL0t] = "64-bit EL0t (Guest User)",
+#endif
+    };
+    mode = cpsr & PSR_MODE_MASK;
+
+    if ( mode > ARRAY_SIZE(mode_strings) )
+        return "Unknown";
+    return mode_strings[mode] ? : "Unknown";
+}
+
 static void show_registers_32(struct cpu_user_regs *regs,
                               struct reg_ctxt *ctxt,
                               int guest_mode,
                               const struct vcpu *v)
 {
-    static const char *mode_strings[] = {
-       [PSR_MODE_USR] = "USR",
-       [PSR_MODE_FIQ] = "FIQ",
-       [PSR_MODE_IRQ] = "IRQ",
-       [PSR_MODE_SVC] = "SVC",
-       [PSR_MODE_MON] = "MON",
-       [PSR_MODE_ABT] = "ABT",
-       [PSR_MODE_HYP] = "HYP",
-       [PSR_MODE_UND] = "UND",
-       [PSR_MODE_SYS] = "SYS"
-    };
 
 #ifdef CONFIG_ARM_64
+    BUG_ON( ! (regs->cpsr & PSR_MODE_BIT) );
     printk("PC:     %08"PRIx32"\n", regs->pc32);
 #else
     printk("PC:     %08"PRIx32, regs->pc);
@@ -282,9 +309,8 @@ static void show_registers_32(struct cpu_user_regs *regs,
         print_symbol(" %s", regs->pc);
     printk("\n");
 #endif
-    printk("CPSR:   %08"PRIx32" MODE:%s%s\n", regs->cpsr,
-           guest_mode ? "32-bit Guest " : "Hypervisor",
-           guest_mode ? mode_strings[regs->cpsr & PSR_MODE_MASK] : "");
+    printk("CPSR:   %08"PRIx32" MODE:%s\n", regs->cpsr,
+           mode_string(regs->cpsr));
     printk("     R0: %08"PRIx32" R1: %08"PRIx32" R2: %08"PRIx32" R3: %08"PRIx32"\n",
            regs->r0, regs->r1, regs->r2, regs->r3);
     printk("     R4: %08"PRIx32" R5: %08"PRIx32" R6: %08"PRIx32" R7: %08"PRIx32"\n",
@@ -325,15 +351,19 @@ static void show_registers_32(struct cpu_user_regs *regs,
 
     if ( guest_mode )
     {
-        printk("TTBR0 %010"PRIx64" TTBR1 %010"PRIx64" TCR %08"PRIx32"\n",
-               ctxt->ttbr0, ctxt->ttbr1, ctxt->tcr);
-        printk("SCTLR %08"PRIx32"\n", ctxt->sctlr);
-        printk("IFAR %08"PRIx32" DFAR %08"PRIx32"\n",
+        printk("     SCTLR: %08"PRIx32"\n", ctxt->sctlr_el1);
+        printk("       TCR: %08"PRIx32"\n", ctxt->tcr_el1);
+        printk("     TTBR0: %016"PRIx64"\n", ctxt->ttbr0_el1);
+        printk("     TTBR1: %016"PRIx64"\n", ctxt->ttbr1_el1);
+        printk("      IFAR: %08"PRIx32", IFSR: %08"PRIx32"\n"
+               "      DFAR: %08"PRIx32", DFSR: %08"PRIx32"\n",
 #ifdef CONFIG_ARM_64
                (uint32_t)(ctxt->far >> 32),
-               (uint32_t)(ctxt->far & 0xffffffff)
+               ctxt->ifsr32_el2,
+               (uint32_t)(ctxt->far & 0xffffffff),
+               ctxt->esr_el1
 #else
-               ctxt->ifar, ctxt->dfar
+               ctxt->ifar, ctxt->ifsr, ctxt->dfar, ctxt->dfsr
 #endif
             );
         printk("\n");
@@ -346,13 +376,25 @@ static void show_registers_64(struct cpu_user_regs *regs,
                               int guest_mode,
                               const struct vcpu *v)
 {
+
+    BUG_ON( (regs->cpsr & PSR_MODE_BIT) );
+
     printk("PC:     %016"PRIx64, regs->pc);
     if ( !guest_mode )
         print_symbol(" %s", regs->pc);
     printk("\n");
-    printk("SP:     %08"PRIx64"\n", regs->sp);
+    printk("LR:     %016"PRIx64"\n", regs->lr);
+    if ( guest_mode )
+    {
+        printk("SP_EL0: %016"PRIx64"\n", regs->sp_el0);
+        printk("SP_EL1: %016"PRIx64"\n", regs->sp_el1);
+    }
+    else
+    {
+        printk("SP:     %016"PRIx64"\n", regs->sp);
+    }
     printk("CPSR:   %08"PRIx32" MODE:%s\n", regs->cpsr,
-           guest_mode ? "64-bit Guest" : "Hypervisor");
+           mode_string(regs->cpsr));
     printk("     X0: %016"PRIx64"  X1: %016"PRIx64"  X2: %016"PRIx64"\n",
            regs->x0, regs->x1, regs->x2);
     printk("     X3: %016"PRIx64"  X4: %016"PRIx64"  X5: %016"PRIx64"\n",
@@ -371,17 +413,20 @@ static void show_registers_64(struct cpu_user_regs *regs,
            regs->x21, regs->x22, regs->x23);
     printk("    X24: %016"PRIx64" X25: %016"PRIx64" X26: %016"PRIx64"\n",
            regs->x24, regs->x25, regs->x26);
-    printk("    X27: %016"PRIx64" X28: %016"PRIx64" X29: %016"PRIx64"\n",
-           regs->x27, regs->x28, regs->lr);
+    printk("    X27: %016"PRIx64" X28: %016"PRIx64"  FP: %016"PRIx64"\n",
+           regs->x27, regs->x28, regs->fp);
     printk("\n");
 
     if ( guest_mode )
     {
-        printk("SCTLR_EL1: %08"PRIx32"\n", ctxt->sctlr);
-        printk("  TCR_EL1: %08"PRIx32"\n", ctxt->tcr);
-        printk("TTBR0_EL1: %010"PRIx64"\n", ctxt->ttbr0);
-        printk("TTBR1_EL1: %010"PRIx64"\n", ctxt->ttbr1);
-        printk("  FAR_EL1: %010"PRIx64"\n", ctxt->far);
+        printk("   ELR_EL1: %016"PRIx64"\n", regs->elr_el1);
+        printk("   ESR_EL1: %08"PRIx32"\n", ctxt->esr_el1);
+        printk("   FAR_EL1: %016"PRIx64"\n", ctxt->far);
+        printk("\n");
+        printk(" SCTLR_EL1: %08"PRIx32"\n", ctxt->sctlr_el1);
+        printk("   TCR_EL1: %08"PRIx32"\n", ctxt->tcr_el1);
+        printk(" TTBR0_EL1: %016"PRIx64"\n", ctxt->ttbr0_el1);
+        printk(" TTBR1_EL1: %016"PRIx64"\n", ctxt->ttbr1_el1);
         printk("\n");
     }
 }
@@ -413,60 +458,68 @@ static void _show_registers(struct cpu_user_regs *regs,
         show_registers_32(regs, ctxt, guest_mode, v);
 #endif
     }
-
-#ifdef CONFIG_ARM_32
-    printk("HTTBR %"PRIx64"\n", READ_CP64(HTTBR));
-    printk("HDFAR %"PRIx32"\n", READ_CP32(HDFAR));
-    printk("HIFAR %"PRIx32"\n", READ_CP32(HIFAR));
-    printk("HPFAR %"PRIx32"\n", READ_CP32(HPFAR));
-    printk("HCR %08"PRIx32"\n", READ_CP32(HCR));
-    printk("HSR   %"PRIx32"\n", READ_CP32(HSR));
-    printk("VTTBR %010"PRIx64"\n", READ_CP64(VTTBR));
+    printk("  VTCR_EL2: %08"PRIx32"\n", READ_SYSREG32(VTCR_EL2));
+    printk(" VTTBR_EL2: %016"PRIx64"\n", ctxt->vttbr_el2);
     printk("\n");
 
-    printk("DFSR %"PRIx32" DFAR %"PRIx32"\n", READ_CP32(DFSR), READ_CP32(DFAR));
-    printk("IFSR %"PRIx32" IFAR %"PRIx32"\n", READ_CP32(IFSR), READ_CP32(IFAR));
+    printk(" SCTLR_EL2: %08"PRIx32"\n", READ_SYSREG32(SCTLR_EL2));
+    printk("   HCR_EL2: %016"PRIregister"\n", READ_SYSREG(HCR_EL2));
+    printk(" TTBR0_EL2: %016"PRIx64"\n", READ_SYSREG64(TTBR0_EL2));
     printk("\n");
+    printk("   ESR_EL2: %08"PRIx32"\n", READ_SYSREG32(ESR_EL2));
+    printk(" HPFAR_EL2: %016"PRIregister"\n", READ_SYSREG(HPFAR_EL2));
+
+#ifdef CONFIG_ARM_32
+    printk("     HDFAR: %08"PRIx32"\n", READ_CP32(HDFAR));
+    printk("     HIFAR: %08"PRIx32"\n", READ_CP32(HIFAR));
 #else
-    printk("TTBR0_EL2: %"PRIx64"\n", READ_SYSREG64(TTBR0_EL2));
-    printk("  FAR_EL2: %"PRIx64"\n", READ_SYSREG64(FAR_EL2));
-    printk("HPFAR_EL2: %"PRIx64"\n", READ_SYSREG64(HPFAR_EL2));
-    printk("  HCR_EL2: %"PRIx64"\n", READ_SYSREG64(HCR_EL2));
-    printk("  ESR_EL2: %"PRIx64"\n", READ_SYSREG64(ESR_EL2));
-    printk("VTTBR_EL2: %"PRIx64"\n", READ_SYSREG64(VTTBR_EL2));
-    printk("\n");
+    printk("   FAR_EL2: %016"PRIx64"\n", READ_SYSREG64(FAR_EL2));
 #endif
+    printk("\n");
 }
 
 void show_registers(struct cpu_user_regs *regs)
 {
     struct reg_ctxt ctxt;
-    ctxt.sctlr = READ_SYSREG(SCTLR_EL1);
-    ctxt.tcr = READ_SYSREG(TCR_EL1);
-    ctxt.ttbr0 = READ_SYSREG64(TTBR0_EL1);
-    ctxt.ttbr1 = READ_SYSREG64(TTBR1_EL1);
+    ctxt.sctlr_el1 = READ_SYSREG(SCTLR_EL1);
+    ctxt.tcr_el1 = READ_SYSREG(TCR_EL1);
+    ctxt.ttbr0_el1 = READ_SYSREG64(TTBR0_EL1);
+    ctxt.ttbr1_el1 = READ_SYSREG64(TTBR1_EL1);
 #ifdef CONFIG_ARM_32
     ctxt.dfar = READ_CP32(DFAR);
     ctxt.ifar = READ_CP32(IFAR);
+    ctxt.dfsr = READ_CP32(DFSR);
+    ctxt.ifsr = READ_CP32(IFSR);
 #else
     ctxt.far = READ_SYSREG(FAR_EL1);
+    ctxt.esr_el1 = READ_SYSREG(ESR_EL1);
+    ctxt.ifsr32_el2 = READ_SYSREG(IFSR32_EL2);
 #endif
+    ctxt.vttbr_el2 = READ_SYSREG64(VTTBR_EL2);
+
     _show_registers(regs, &ctxt, guest_mode(regs), current);
 }
 
 void vcpu_show_registers(const struct vcpu *v)
 {
     struct reg_ctxt ctxt;
-    ctxt.sctlr = v->arch.sctlr;
-    ctxt.tcr = v->arch.ttbcr;
-    ctxt.ttbr0 = v->arch.ttbr0;
-    ctxt.ttbr1 = v->arch.ttbr1;
+    ctxt.sctlr_el1 = v->arch.sctlr;
+    ctxt.tcr_el1 = v->arch.ttbcr;
+    ctxt.ttbr0_el1 = v->arch.ttbr0;
+    ctxt.ttbr1_el1 = v->arch.ttbr1;
 #ifdef CONFIG_ARM_32
     ctxt.dfar = v->arch.dfar;
     ctxt.ifar = v->arch.ifar;
+    ctxt.dfsr = v->arch.dfsr;
+    ctxt.ifsr = v->arch.ifsr;
 #else
     ctxt.far = v->arch.far;
+    ctxt.esr_el1 = v->arch.esr;
+    ctxt.ifsr32_el2 = v->arch.ifsr;
 #endif
+
+    ctxt.vttbr_el2 = v->domain->arch.vttbr;
+
     _show_registers(&v->arch.cpu_info->guest_cpu_user_regs, &ctxt, 1, v);
 }
 
@@ -834,7 +887,7 @@ void dump_guest_s1_walk(struct domain *d, vaddr_t addr)
 
     printk("dom%d VA 0x%08"PRIvaddr"\n", d->domain_id, addr);
     printk("    TTBCR: 0x%08"PRIx32"\n", ttbcr);
-    printk("    TTBR0: 0x%010"PRIx64" = 0x%"PRIpaddr"\n",
+    printk("    TTBR0: 0x%016"PRIx64" = 0x%"PRIpaddr"\n",
            ttbr0, p2m_lookup(d, ttbr0 & PAGE_MASK));
 
     if ( ttbcr & TTBCR_EAE )
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index f08d59a..71daafa 100644
--- a/xen/include/asm-arm/cpregs.h
+++ b/xen/include/asm-arm/cpregs.h
@@ -250,6 +250,7 @@
 #define DACR32_EL2              DACR
 #define ESR_EL2                 HSR
 #define HCR_EL2                 HCR
+#define HPFAR_EL2               HPFAR
 #define ID_AFR0_EL1             ID_AFR0
 #define ID_DFR0_EL1             ID_DFR0
 #define ID_ISAR0_EL1            ID_ISAR0
-- 
1.7.10.4

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

* [PATCH 08/14] xen: arm: support dumping 64-bit guest stack
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (7 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 07/14] xen: arm: improve register dump output for 64-bit guest (and more generally too) Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-04-08 17:29   ` Stefano Stabellini
  2013-03-12 15:48 ` [PATCH 09/14] xen: arm: show less words in a line of a stack trace in 64-bit builds Ian Campbell
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c |   80 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 76 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 2f4e157..2671eba 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -523,9 +523,81 @@ void vcpu_show_registers(const struct vcpu *v)
     _show_registers(&v->arch.cpu_info->guest_cpu_user_regs, &ctxt, 1, v);
 }
 
-static void show_guest_stack(struct cpu_user_regs *regs)
+static void show_guest_stack(struct vcpu *v, struct cpu_user_regs *regs)
 {
-    printk("GUEST STACK GOES HERE\n");
+    int i;
+    vaddr_t sp;
+    paddr_t stack_phys;
+    void *mapped;
+    unsigned long *stack, addr;
+
+    switch ( regs->cpsr & PSR_MODE_MASK )
+    {
+    case PSR_MODE_USR:
+    case PSR_MODE_SYS:
+#ifdef CONFIG_ARM_64
+    case PSR_MODE_EL0t:
+#endif
+        printk("No stack trace for guest user-mode\n");
+        return;
+
+    case PSR_MODE_FIQ:
+    case PSR_MODE_IRQ:
+    case PSR_MODE_SVC:
+    case PSR_MODE_ABT:
+    case PSR_MODE_UND:
+        printk("No stack trace for 32-bit guest kernel-mode\n");
+        return;
+
+#ifdef CONFIG_ARM_64
+    case PSR_MODE_EL1t:
+        sp = regs->sp_el0;
+        break;
+    case PSR_MODE_EL1h:
+        sp = regs->sp_el1;
+        break;
+#endif
+
+    case PSR_MODE_HYP:
+    case PSR_MODE_MON:
+#ifdef CONFIG_ARM_64
+    case PSR_MODE_EL3h:
+    case PSR_MODE_EL3t:
+    case PSR_MODE_EL2h:
+    case PSR_MODE_EL2t:
+#endif
+    default:
+        BUG();
+        return;
+    }
+
+    printk("Guest stack trace from sp=%"PRIvaddr":\n  ", sp);
+
+    if ( gvirt_to_maddr(sp, &stack_phys) )
+    {
+        printk("Failed to convert stack to physical address\n");
+        return;
+    }
+
+    mapped = map_domain_page(stack_phys >> PAGE_SHIFT);
+
+    stack = mapped + (sp & ~PAGE_MASK);
+
+    for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
+    {
+        if ( (((long)stack - 1) ^ ((long)(stack + 1) - 1)) & PAGE_SIZE )
+            break;
+        addr = *stack;
+        if ( (i != 0) && ((i % stack_words_per_line) == 0) )
+            printk("\n  ");
+        printk(" %p", _p(addr));
+        stack++;
+    }
+    if ( i == 0 )
+        printk("Stack empty.");
+    printk("\n");
+    unmap_domain_page(mapped);
+
 }
 
 #define STACK_BEFORE_EXCEPTION(regs) ((register_t*)(regs)->sp)
@@ -589,7 +661,7 @@ void show_stack(struct cpu_user_regs *regs)
     int i;
 
     if ( guest_mode(regs) )
-        return show_guest_stack(regs);
+        return show_guest_stack(current, regs);
 
     printk("Xen stack trace from sp=%p:\n  ", stack);
 
@@ -631,7 +703,7 @@ void vcpu_show_execution_state(struct vcpu *v)
 
     vcpu_show_registers(v);
     if ( !usr_mode(&v->arch.cpu_info->guest_cpu_user_regs) )
-        show_guest_stack(&v->arch.cpu_info->guest_cpu_user_regs);
+        show_guest_stack(v, &v->arch.cpu_info->guest_cpu_user_regs);
 
     vcpu_unpause(v);
 }
-- 
1.7.10.4

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

* [PATCH 09/14] xen: arm: show less words in a line of a stack trace in 64-bit builds
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (8 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 08/14] xen: arm: support dumping 64-bit guest stack Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-04-08 13:46   ` Stefano Stabellini
  2013-03-12 15:48 ` [PATCH 10/14] xen: arm: Set EL1 register width in HCR_EL2 during context switch Ian Campbell
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

Words are twice as wide so this ensures that a line is still <80 characters.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 2671eba..f1dd557 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -55,10 +55,15 @@ static inline void check_stack_alignment_constraints(void) {
 #endif
 }
 
+#ifdef CONFIG_ARM_32
 static int debug_stack_lines = 20;
-integer_param("debug_stack_lines", debug_stack_lines);
-
 #define stack_words_per_line 8
+#else
+static int debug_stack_lines = 40;
+#define stack_words_per_line 4
+#endif
+
+integer_param("debug_stack_lines", debug_stack_lines);
 
 
 void __cpuinit init_traps(void)
-- 
1.7.10.4

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

* [PATCH 10/14] xen: arm: Set EL1 register width in HCR_EL2 during context switch.
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (9 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 09/14] xen: arm: show less words in a line of a stack trace in 64-bit builds Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-03-12 15:48 ` [PATCH 11/14] xen: arm: handle traps from 64-bit guests Ian Campbell
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/domain.c           |    7 +++++++
 xen/include/asm-arm/processor.h |    3 +++
 2 files changed, 10 insertions(+)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 08bb132..20bb6c7 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -203,6 +203,13 @@ static void ctxt_switch_to(struct vcpu *n)
 
     isb();
 
+#ifdef CONFIG_ARM_64
+    if ( is_pv32_domain(n->domain) )
+        hcr &= ~HCR_RW;
+    else
+        hcr |= HCR_RW;
+#endif
+
     WRITE_SYSREG(hcr, HCR_EL2);
     isb();
 
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 1681ebf..32c441b 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -41,6 +41,9 @@
 #define HSCTLR_BASE       0x30c51878
 
 /* HCR Hyp Configuration Register */
+#ifdef CONFIG_ARM_64
+#define HCR_RW          (1<<31)
+#endif
 #define HCR_TGE         (1<<27)
 #define HCR_TVM         (1<<26)
 #define HCR_TTLB        (1<<25)
-- 
1.7.10.4

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

* [PATCH 11/14] xen: arm: handle traps from 64-bit guests
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (10 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 10/14] xen: arm: Set EL1 register width in HCR_EL2 during context switch Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-04-08 13:45   ` Stefano Stabellini
  2013-03-12 15:48 ` [PATCH 12/14] xen: arm: handle hypercalls " Ian Campbell
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/arm64/entry.S |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
index a5fd608..7799751 100644
--- a/xen/arch/arm/arm64/entry.S
+++ b/xen/arch/arm/arm64/entry.S
@@ -142,11 +142,16 @@ hyp_irq:
 
 guest_sync:
         entry   hyp=0, compat=0
-        invalid BAD_SYNC /* No AArch64 guest support yet */
+        msr     daifclr, #2
+        mov     x0, sp
+        bl      do_trap_hypervisor
+        b       return_to_guest
 
 guest_irq:
         entry   hyp=0, compat=0
-        invalid BAD_IRQ /* No AArch64 guest support yet */
+        mov     x0, sp
+        bl      do_trap_irq
+        b       return_to_guest
 
 guest_fiq_invalid:
         entry   hyp=0, compat=0
-- 
1.7.10.4

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

* [PATCH 12/14] xen: arm: handle hypercalls from 64-bit guests
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (11 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 11/14] xen: arm: handle traps from 64-bit guests Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-04-08 11:43   ` Stefano Stabellini
  2013-03-12 15:48 ` [PATCH 13/14] xen: arm: handle 64-bit system register access traps Ian Campbell
  2013-03-12 15:48 ` [PATCH 14/14] xen: arm: align some comments Ian Campbell
  14 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c            |   67 ++++++++++++++++++++++++++++-----------
 xen/include/asm-arm/processor.h |    7 ++--
 2 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index f1dd557..190d1e8 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -726,8 +726,8 @@ unsigned long do_arch_0(unsigned int cmd, unsigned long long value)
         return 0;
 }
 
-typedef unsigned long (*arm_hypercall_fn_t)(
-    unsigned int, unsigned int, unsigned int, unsigned int, unsigned int);
+typedef register_t (*arm_hypercall_fn_t)(
+    register_t, register_t, register_t, register_t, register_t);
 
 typedef struct {
     arm_hypercall_fn_t fn;
@@ -783,30 +783,49 @@ static void do_debug_trap(struct cpu_user_regs *regs, unsigned int code)
     }
 }
 
-static void do_trap_hypercall(struct cpu_user_regs *regs, unsigned long iss)
+#ifdef CONFIG_ARM_64
+#define HYPERCALL_RESULT_REG(r) (r)->x0
+#define HYPERCALL_ARG1(r) (r)->x0
+#define HYPERCALL_ARG2(r) (r)->x1
+#define HYPERCALL_ARG3(r) (r)->x2
+#define HYPERCALL_ARG4(r) (r)->x3
+#define HYPERCALL_ARG5(r) (r)->x4
+#define HYPERCALL_ARGS(r) (r)->x0, (r)->x1, (r)->x2, (r)->x3, (r)->x4
+#else
+#define HYPERCALL_RESULT_REG(r) (r)->r0
+#define HYPERCALL_ARG1(r) (r)->r0
+#define HYPERCALL_ARG2(r) (r)->r1
+#define HYPERCALL_ARG3(r) (r)->r2
+#define HYPERCALL_ARG4(r) (r)->r3
+#define HYPERCALL_ARG5(r) (r)->r4
+#define HYPERCALL_ARGS(r) (r)->r0, (r)->r1, (r)->r2, (r)->r3, (r)->r4
+#endif
+
+static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
+                              unsigned long iss)
 {
     arm_hypercall_fn_t call = NULL;
 #ifndef NDEBUG
-    uint32_t orig_pc = regs->pc;
+    register_t orig_pc = regs->pc;
 #endif
 
     if ( iss != XEN_HYPERCALL_TAG )
         domain_crash_synchronous();
 
-    if ( regs->r12 >= ARRAY_SIZE(arm_hypercall_table) )
+    if ( *nr >= ARRAY_SIZE(arm_hypercall_table) )
     {
-        regs->r0 = -ENOSYS;
+        HYPERCALL_RESULT_REG(regs) = -ENOSYS;
         return;
     }
 
-    call = arm_hypercall_table[regs->r12].fn;
+    call = arm_hypercall_table[*nr].fn;
     if ( call == NULL )
     {
-        regs->r0 = -ENOSYS;
+        HYPERCALL_RESULT_REG(regs) = -ENOSYS;
         return;
     }
 
-    regs->r0 = call(regs->r0, regs->r1, regs->r2, regs->r3, regs->r4);
+    HYPERCALL_RESULT_REG(regs) = call(HYPERCALL_ARGS(regs));
 
 #ifndef NDEBUG
     /*
@@ -815,16 +834,16 @@ static void do_trap_hypercall(struct cpu_user_regs *regs, unsigned long iss)
      */
     if ( orig_pc == regs->pc )
     {
-        switch ( arm_hypercall_table[regs->r12].nr_args ) {
-        case 5: regs->r4 = 0xDEADBEEF;
-        case 4: regs->r3 = 0xDEADBEEF;
-        case 3: regs->r2 = 0xDEADBEEF;
-        case 2: regs->r1 = 0xDEADBEEF;
-        case 1: /* Don't clobber r0 -- it's the return value */
+        switch ( arm_hypercall_table[*nr].nr_args ) {
+        case 5: HYPERCALL_ARG5(regs) = 0xDEADBEEF;
+        case 4: HYPERCALL_ARG4(regs) = 0xDEADBEEF;
+        case 3: HYPERCALL_ARG3(regs) = 0xDEADBEEF;
+        case 2: HYPERCALL_ARG2(regs) = 0xDEADBEEF;
+        case 1: /* Don't clobber x0/r0 -- it's the return value */
             break;
         default: BUG();
         }
-        regs->r12 = 0xDEADBEEF;
+        *nr = 0xDEADBEEF;
     }
 #endif
 }
@@ -1079,11 +1098,23 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs)
             goto bad_trap;
         do_cp15_64(regs, hsr);
         break;
-    case HSR_EC_HVC:
+    case HSR_EC_HVC32:
+#ifndef NDEBUG
+        if ( (hsr.iss & 0xff00) == 0xff00 )
+            return do_debug_trap(regs, hsr.iss & 0x00ff);
+#endif
+        do_trap_hypercall(regs, (register_t *)&regs->r12, hsr.iss);
+        break;
+
+#ifdef CONFIG_ARM_64
+    case HSR_EC_HVC64:
+#ifndef NDEBUG
         if ( (hsr.iss & 0xff00) == 0xff00 )
             return do_debug_trap(regs, hsr.iss & 0x00ff);
-        do_trap_hypercall(regs, hsr.iss);
+#endif
+        do_trap_hypercall(regs, &regs->x16, hsr.iss);
         break;
+#endif
     case HSR_EC_DATA_ABORT_GUEST:
         do_trap_data_abort_guest(regs, hsr.dabt);
         break;
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 32c441b..17f5465 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -86,8 +86,11 @@
 #define HSR_EC_JAZELLE              0x09
 #define HSR_EC_BXJ                  0x0a
 #define HSR_EC_CP14_64              0x0c
-#define HSR_EC_SVC                  0x11
-#define HSR_EC_HVC                  0x12
+#define HSR_EC_SVC32                0x11
+#define HSR_EC_HVC32                0x12
+#ifdef CONFIG_ARM_64
+#define HSR_EC_HVC64                0x16
+#endif
 #define HSR_EC_INSTR_ABORT_GUEST    0x20
 #define HSR_EC_INSTR_ABORT_HYP      0x21
 #define HSR_EC_DATA_ABORT_GUEST     0x24
-- 
1.7.10.4

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

* [PATCH 13/14] xen: arm: handle 64-bit system register access traps.
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (12 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 12/14] xen: arm: handle hypercalls " Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-04-08 13:11   ` Stefano Stabellini
  2013-03-12 15:48 ` [PATCH 14/14] xen: arm: align some comments Ian Campbell
  14 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

Wire up the vtimer handling to it.

Use a simplified version of the 32-bit cp-register macros to have convenient
decoding of HSR register values. (simplified because we don't need them for
passing to the assembler on 64-bit)

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/traps.c            |   39 +++++++++++++
 xen/arch/arm/vtimer.c           |  119 ++++++++++++++++++++++++++-------------
 xen/include/asm-arm/processor.h |   32 +++++++++++
 xen/include/asm-arm/sysregs.h   |   56 ++++++++++++++++++
 4 files changed, 208 insertions(+), 38 deletions(-)
 create mode 100644 xen/include/asm-arm/sysregs.h

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 190d1e8..67d9072 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -973,6 +973,39 @@ static void do_cp15_64(struct cpu_user_regs *regs,
 
 }
 
+#ifdef CONFIG_ARM_64
+static void do_sysreg(struct cpu_user_regs *regs,
+                      union hsr hsr)
+{
+    struct hsr_sysreg sysreg = hsr.sysreg;
+
+    switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
+    {
+    case CNTP_CTL_EL0:
+    case CNTP_TVAL_EL0:
+        if ( !vtimer_emulate(regs, hsr) )
+        {
+            dprintk(XENLOG_ERR,
+                    "failed emulation of 64-bit vtimer sysreg access\n");
+            domain_crash_synchronous();
+        }
+        break;
+    default:
+        printk("%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
+               sysreg.read ? "mrs" : "msr",
+               sysreg.op0, sysreg.op1,
+               sysreg.crn, sysreg.crm,
+               sysreg.op2,
+               sysreg.read ? "=>" : "<=",
+               sysreg.reg, regs->pc);
+        panic("unhandled 64-bit sysreg access %#x\n",
+              hsr.bits & HSR_SYSREG_REGS_MASK);
+    }
+
+    regs->pc += 4;
+}
+#endif
+
 void dump_guest_s1_walk(struct domain *d, vaddr_t addr)
 {
     uint32_t ttbcr = READ_SYSREG32(TCR_EL1);
@@ -1114,7 +1147,13 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs)
 #endif
         do_trap_hypercall(regs, &regs->x16, hsr.iss);
         break;
+    case HSR_EC_SYSREG:
+        if ( is_pv32_domain(current->domain) )
+            goto bad_trap;
+        do_sysreg(regs, hsr);
+        break;
 #endif
+
     case HSR_EC_DATA_ABORT_GUEST:
         do_trap_data_abort_guest(regs, hsr.dabt);
         break;
diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
index a68f662..f9fc045 100644
--- a/xen/arch/arm/vtimer.c
+++ b/xen/arch/arm/vtimer.c
@@ -102,51 +102,62 @@ int virt_timer_restore(struct vcpu *v)
     return 0;
 }
 
-static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr)
+static void vtimer_cntp_ctl(struct cpu_user_regs *regs, uint32_t *r, int read)
 {
     struct vcpu *v = current;
-    struct hsr_cp32 cp32 = hsr.cp32;
-    uint32_t *r = (uint32_t *)select_user_reg(regs, cp32.reg);
-    s_time_t now;
-
-    switch ( hsr.bits & HSR_CP32_REGS_MASK )
+    if ( read )
     {
-    case HSR_CPREG32(CNTP_CTL):
-        if ( cp32.read )
+        *r = v->arch.phys_timer.ctl;
+    }
+    else
+    {
+        v->arch.phys_timer.ctl = *r;
+
+        if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
         {
-            *r = v->arch.phys_timer.ctl;
+            set_timer(&v->arch.phys_timer.timer,
+                      v->arch.phys_timer.cval + v->arch.phys_timer.offset);
         }
         else
+            stop_timer(&v->arch.phys_timer.timer);
+    }
+}
+
+static void vtimer_cntp_tval(struct cpu_user_regs *regs, uint32_t *r, int read)
+{
+    struct vcpu *v = current;
+    s_time_t now;
+
+    now = NOW() - v->arch.phys_timer.offset;
+
+    if ( read )
+    {
+        *r = (uint32_t)(ns_to_ticks(v->arch.phys_timer.cval - now) & 0xffffffffull);
+    }
+    else
+    {
+        v->arch.phys_timer.cval = now + ticks_to_ns(*r);
+        if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
         {
-            v->arch.phys_timer.ctl = *r;
-
-            if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
-            {
-                set_timer(&v->arch.phys_timer.timer,
-                          v->arch.phys_timer.cval + v->arch.phys_timer.offset);
-            }
-            else
-                stop_timer(&v->arch.phys_timer.timer);
+            set_timer(&v->arch.phys_timer.timer,
+                      v->arch.phys_timer.cval + v->arch.phys_timer.offset);
         }
+    }
+}
 
+static int vtimer_emulate_cp32(struct cpu_user_regs *regs, union hsr hsr)
+{
+    struct hsr_cp32 cp32 = hsr.cp32;
+    uint32_t *r = (uint32_t *)select_user_reg(regs, cp32.reg);
+
+    switch ( hsr.bits & HSR_CP32_REGS_MASK )
+    {
+    case HSR_CPREG32(CNTP_CTL):
+        vtimer_cntp_ctl(regs, r, cp32.read);
         return 1;
 
     case HSR_CPREG32(CNTP_TVAL):
-        now = NOW() - v->arch.phys_timer.offset;
-        if ( cp32.read )
-        {
-            *r = (uint32_t)(ns_to_ticks(v->arch.phys_timer.cval - now) & 0xffffffffull);
-        }
-        else
-        {
-            v->arch.phys_timer.cval = now + ticks_to_ns(*r);
-            if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
-            {
-                set_timer(&v->arch.phys_timer.timer,
-                          v->arch.phys_timer.cval + v->arch.phys_timer.offset);
-            }
-        }
-
+        vtimer_cntp_tval(regs, r, cp32.read);
         return 1;
 
     default:
@@ -154,7 +165,7 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr)
     }
 }
 
-static int vtimer_emulate_64(struct cpu_user_regs *regs, union hsr hsr)
+static int vtimer_emulate_cp64(struct cpu_user_regs *regs, union hsr hsr)
 {
     struct vcpu *v = current;
     struct hsr_cp64 cp64 = hsr.cp64;
@@ -185,16 +196,48 @@ static int vtimer_emulate_64(struct cpu_user_regs *regs, union hsr hsr)
     }
 }
 
+#ifdef CONFIG_ARM_64
+static int vtimer_emulate_sysreg(struct cpu_user_regs *regs, union hsr hsr)
+{
+    struct hsr_sysreg sysreg = hsr.sysreg;
+    register_t *x = select_user_reg(regs, sysreg.reg);
+    uint32_t r = (uint32_t)*x;
+
+    switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
+    {
+    case CNTP_CTL_EL0:
+        vtimer_cntp_ctl(regs, &r, sysreg.read);
+        *x = r;
+        return 1;
+    case CNTP_TVAL_EL0:
+        vtimer_cntp_tval(regs, &r, sysreg.read);
+        *x = r;
+        return 1;
+    default:
+        return 0;
+    }
+
+}
+#endif
+
 int vtimer_emulate(struct cpu_user_regs *regs, union hsr hsr)
 {
-    if ( !is_pv32_domain(current->domain) )
-        return -EINVAL;
 
     switch (hsr.ec) {
     case HSR_EC_CP15_32:
-        return vtimer_emulate_32(regs, hsr);
+        if ( !is_pv32_domain(current->domain) )
+            return 0;
+        return vtimer_emulate_cp32(regs, hsr);
     case HSR_EC_CP15_64:
-        return vtimer_emulate_64(regs, hsr);
+        if ( !is_pv32_domain(current->domain) )
+            return 0;
+        return vtimer_emulate_cp64(regs, hsr);
+#ifdef CONFIG_ARM_64
+    case HSR_EC_SYSREG:
+        if ( is_pv32_domain(current->domain) )
+            return 0;
+        return vtimer_emulate_sysreg(regs, hsr);
+#endif
     default:
         return 0;
     }
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 17f5465..d75530d 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -2,6 +2,7 @@
 #define __ASM_ARM_PROCESSOR_H
 
 #include <asm/cpregs.h>
+#include <asm/sysregs.h>
 
 /* MIDR Main ID Register */
 #define MIDR_MASK    0xff0ffff0
@@ -90,6 +91,7 @@
 #define HSR_EC_HVC32                0x12
 #ifdef CONFIG_ARM_64
 #define HSR_EC_HVC64                0x16
+#define HSR_EC_SYSREG               0x18
 #endif
 #define HSR_EC_INSTR_ABORT_GUEST    0x20
 #define HSR_EC_INSTR_ABORT_HYP      0x21
@@ -249,6 +251,21 @@ union hsr {
         unsigned long ec:6;    /* Exception Class */
     } cp64; /* HSR_EC_CP15_64, HSR_EC_CP14_64 */
 
+#ifdef CONFIG_ARM_64
+    struct hsr_sysreg {
+        unsigned long read:1;   /* Direction */
+        unsigned long crm:4;    /* CRm */
+        unsigned long reg:5;    /* Rt */
+        unsigned long crn:4;    /* CRn */
+        unsigned long op1:3;    /* Op1 */
+        unsigned long op2:3;    /* Op2 */
+        unsigned long op0:2;    /* Op0 */
+        unsigned long res0:3;
+        unsigned long len:1;    /* Instruction length */
+        unsigned long ec:6;
+    } sysreg; /* HSR_EC_SYSREG */
+#endif
+
     struct hsr_dabt {
         unsigned long dfsc:6;  /* Data Fault Status Code */
         unsigned long write:1; /* Write / not Read */
@@ -291,6 +308,21 @@ union hsr {
 #define HSR_CP64_CRM_SHIFT (1)
 #define HSR_CP64_REGS_MASK (HSR_CP64_OP1_MASK|HSR_CP64_CRM_MASK)
 
+/* HSR.EC == HSR_SYSREG */
+#define HSR_SYSREG_OP0_MASK (0x00300000)
+#define HSR_SYSREG_OP0_SHIFT (20)
+#define HSR_SYSREG_OP1_MASK (0x0001c000)
+#define HSR_SYSREG_OP1_SHIFT (14)
+#define HSR_SYSREG_CRN_MASK (0x00003800)
+#define HSR_SYSREG_CRN_SHIFT (10)
+#define HSR_SYSREG_CRM_MASK (0x0000001e)
+#define HSR_SYSREG_CRM_SHIFT (1)
+#define HSR_SYSREG_OP2_MASK (0x000e0000)
+#define HSR_SYSREG_OP2_SHIFT (17)
+#define HSR_SYSREG_REGS_MASK (HSR_SYSREG_OP0_MASK|HSR_SYSREG_OP1_MASK|\
+                              HSR_SYSREG_CRN_MASK|HSR_SYSREG_CRM_MASK|\
+                              HSR_SYSREG_OP2_MASK)
+
 /* Physical Address Register */
 #define PAR_F           (1<<0)
 
diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h
new file mode 100644
index 0000000..9c64777
--- /dev/null
+++ b/xen/include/asm-arm/sysregs.h
@@ -0,0 +1,56 @@
+#ifndef __ASM_ARM_SYSREGS_H
+#define __ASM_ARM_SYSREGS_H
+
+#ifdef CONFIG_ARM_64
+
+#include <xen/stringify.h>
+
+/* AArch 64 System Register Encodings */
+#define __HSR_SYSREG_c0  0
+#define __HSR_SYSREG_c1  1
+#define __HSR_SYSREG_c2  2
+#define __HSR_SYSREG_c3  3
+#define __HSR_SYSREG_c4  4
+#define __HSR_SYSREG_c5  5
+#define __HSR_SYSREG_c6  6
+#define __HSR_SYSREG_c7  7
+#define __HSR_SYSREG_c8  8
+#define __HSR_SYSREG_c9  9
+#define __HSR_SYSREG_c10 10
+#define __HSR_SYSREG_c11 11
+#define __HSR_SYSREG_c12 12
+#define __HSR_SYSREG_c13 13
+#define __HSR_SYSREG_c14 14
+#define __HSR_SYSREG_c15 15
+
+#define __HSR_SYSREG_0   0
+#define __HSR_SYSREG_1   1
+#define __HSR_SYSREG_2   2
+#define __HSR_SYSREG_3   3
+#define __HSR_SYSREG_4   4
+#define __HSR_SYSREG_5   5
+#define __HSR_SYSREG_6   6
+#define __HSR_SYSREG_7   7
+
+/* These are used to decode traps with HSR.EC==HSR_EC_SYSREG */
+#define HSR_SYSREG(op0,op1,crn,crm,op2) \
+    ((__HSR_SYSREG_##op0) << HSR_SYSREG_OP0_SHIFT) | \
+    ((__HSR_SYSREG_##op1) << HSR_SYSREG_OP1_SHIFT) | \
+    ((__HSR_SYSREG_##crn) << HSR_SYSREG_CRN_SHIFT) | \
+    ((__HSR_SYSREG_##crm) << HSR_SYSREG_CRM_SHIFT) | \
+    ((__HSR_SYSREG_##op2) << HSR_SYSREG_OP2_SHIFT)
+
+#define CNTP_CTL_EL0  HSR_SYSREG(3,3,c14,c2,1)
+#define CNTP_TVAL_EL0 HSR_SYSREG(3,3,c14,c2,0)
+#endif
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
1.7.10.4

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

* [PATCH 14/14] xen: arm: align some comments
  2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
                   ` (13 preceding siblings ...)
  2013-03-12 15:48 ` [PATCH 13/14] xen: arm: handle 64-bit system register access traps Ian Campbell
@ 2013-03-12 15:48 ` Ian Campbell
  2013-04-08 11:44   ` Stefano Stabellini
  14 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-03-12 15:48 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, tim, Ian Campbell

From: Ian Campbell <ian.campbell@citrix.com>

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/include/asm-arm/processor.h |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index d75530d..53ffce2 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -244,11 +244,11 @@ union hsr {
         unsigned long reg1:5;   /* Rt1 */
         unsigned long reg2:5;   /* Rt2 */
         unsigned long sbzp2:1;
-        unsigned long op1:4;   /* Op1 */
-        unsigned long cc:4;    /* Condition Code */
+        unsigned long op1:4;    /* Op1 */
+        unsigned long cc:4;     /* Condition Code */
         unsigned long ccvalid:1;/* CC Valid */
-        unsigned long len:1;   /* Instruction length */
-        unsigned long ec:6;    /* Exception Class */
+        unsigned long len:1;    /* Instruction length */
+        unsigned long ec:6;     /* Exception Class */
     } cp64; /* HSR_EC_CP15_64, HSR_EC_CP14_64 */
 
 #ifdef CONFIG_ARM_64
-- 
1.7.10.4

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

* Re: [PATCH 01/14] xen: arm: define 64-bit guest hypercall calling convention.
  2013-03-12 15:48 ` [PATCH 01/14] xen: arm: define 64-bit guest hypercall calling convention Ian Campbell
@ 2013-04-08 11:17   ` Stefano Stabellini
  2013-04-11  9:35     ` Ian Campbell
  0 siblings, 1 reply; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-08 11:17 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), Ian Campbell, xen-devel

On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> 
> As well as using x<N> rather than r<N> registers for passing arguments/results
> as mandate the use of x16 as the hypercall number.
> 
> Add some pedantry about struct alignment layout referencing the ARM Procedure
> Calling Standard to avoid confusion with the previous "OABI" convention. While
> at it also mandate that hypercall argument structs are always little endian.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>  xen/include/public/arch-arm.h |   27 +++++++++++++++++++--------
>  1 file changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
> index 3333399..e44e90f 100644
> --- a/xen/include/public/arch-arm.h
> +++ b/xen/include/public/arch-arm.h
> @@ -33,20 +33,31 @@
>   * A hypercall is issued using the ARM HVC instruction.
>   *
>   * A hypercall can take up to 5 arguments. These are passed in
> - * registers, the first argument in r0, the second argument in r1, the
> - * third in r2, the forth in r3 and the fifth in r4.
> + * registers, the first argument in x0/r0 (for arm64/arm32 guests
> + * respectively irrespective of whether the underlying hypervisor is
> + * 32- or 64-bit), the second argument in x1/r1, the third in x2/r2,
> + * the forth in x3/r3 and the fifth in x4/r4.
>   *
> - * The hypercall number is passed in r12.
> + * The hypercall number is passed in r12 (arm) or x16 (arm64). In both
> + * cases the relevant ARM procedure calling convention specifies this
> + * is an inter-procedure-call scratch register (e.g. for use in linker
> + * stubs). This use does not conflict with use during a hypercall.
>   *
>   * The HVC ISS must contain a Xen specific TAG: XEN_HYPERCALL_TAG.
>   *
> - * The return value is in r0.
> + * The return value is in x0/r0.
>   *
> - * The hypercall will clobber r12 and the argument registers used by
> - * that hypercall (except r0 which is the return value) i.e. a 2
> - * argument hypercall will clobber r1 and a 4 argument hypercall will
> - * clobber r1, r2 and r3.
> + * The hypercall will clobber x16/r12 and the argument registers used
> + * by that hypercall (except r0 which is the return value) i.e. in
> + * addition to x16/r12 a 2 argument hypercall will clobber x1/r1 and a
> + * 4 argument hypercall will clobber x1/r1, x2/r2 and x3/r3.
>   *
> + * Parameter structs passed to hypercalls are laid out according to
> + * the Procedure Call Standard for the ARM Architecture (AAPCS, AKA
> + * EABI) and Procedure Call Standard for the ARM 64-bit Architecture
> + * (AAPCS64). Where there is a conflict the 64-bit standard should be
> + * used regardless of guest type. Structures which are passed as
> + * hypercall arguments are always little endian.
>   */
>  
>  #define XEN_HYPERCALL_TAG   0XEA1
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 04/14] xen: arm: support for loading 64-bit zImage dom0
  2013-03-12 15:48 ` [PATCH 04/14] xen: arm: support for loading 64-bit zImage dom0 Ian Campbell
@ 2013-04-08 11:24   ` Stefano Stabellini
  2013-04-10 11:52     ` Ian Campbell
  0 siblings, 1 reply; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-08 11:24 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), Ian Campbell, xen-devel

On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> 
> This is defined in linux/Documentation/arm64/booting.txt.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> ---
>  xen/arch/arm/kernel.c |   80 +++++++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 75 insertions(+), 5 deletions(-)
> 
> diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c
> index e7f34a4..59844b0 100644
> --- a/xen/arch/arm/kernel.c
> +++ b/xen/arch/arm/kernel.c
> @@ -26,6 +26,8 @@
>  
>  #define ZIMAGE32_MAGIC 0x016f2818
>  
> +#define ZIMAGE64_MAGIC 0x14000008
> +
>  struct minimal_dtb_header {
>      uint32_t magic;
>      uint32_t total_size;
> @@ -99,6 +101,57 @@ static void kernel_zimage_load(struct kernel_info *info)
>      }
>  }
>  
> +#ifdef CONFIG_ARM_64
> +/*
> + * Check if the image is a 64-bit zImage and setup kernel_info
> + */
> +static int kernel_try_zimage64_prepare(struct kernel_info *info,
> +                                     paddr_t addr, paddr_t size)
> +{
> +    /* linux/Documentation/arm64/booting.txt */
> +    struct {
> +        uint32_t magic;
> +        uint32_t res0;
> +        uint64_t text_offset;  /* Image load offset */
> +        uint64_t res1;
> +        uint64_t res2;
> +    } zimage;
> +    uint64_t start, end;
> +
> +    if ( size < sizeof(zimage) )
> +        return -EINVAL;
> +
> +    copy_from_paddr(&zimage, addr, sizeof(zimage), DEV_SHARED);
> +
> +    if (zimage.magic != ZIMAGE64_MAGIC)
> +        return -EINVAL;
> +
> +    /* Currently there is no length in the header, so just use the size */
> +    start = 0;
> +    end = size;
> +
> +    /*
> +     * Given the above this check is a bit pointless, but leave it
> +     * here in case someone adds a length field in the future.
> +     */
> +    if ( (end - start) > size )
> +        return -EINVAL;
> +
> +    info->zimage.kernel_addr = addr;
> +
> +    info->zimage.load_addr = info->mem.bank[0].start
> +        + zimage.text_offset;
> +    info->zimage.len = end - start;
> +
> +    info->entry = info->zimage.load_addr;
> +    info->load = kernel_zimage_load;
> +
> +    info->type = DOMAIN_PV64;
> +
> +    return 0;
> +}
> +#endif

this function doesn't seem very different from kernel_try_elf_prepare:
do we really need two of them?

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

* Re: [PATCH 05/14] xen: arm: support building a 64-bit dom0 domain
  2013-03-12 15:48 ` [PATCH 05/14] xen: arm: support building a 64-bit dom0 domain Ian Campbell
@ 2013-04-08 11:25   ` Stefano Stabellini
  0 siblings, 0 replies; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-08 11:25 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), Ian Campbell, xen-devel

On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>


Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>  xen/arch/arm/domain_build.c |   10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index f161845..b1402d5 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -334,9 +334,8 @@ int construct_dom0(struct domain *d)
>  
>      memset(regs, 0, sizeof(*regs));
>  
> -    regs->pc = (uint32_t)kinfo.entry;
> +    regs->pc = (register_t)kinfo.entry;
>  
> -    regs->cpsr = PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC;
>  
>  #ifdef CONFIG_ARM_64
>      d->arch.type = kinfo.type;
> @@ -344,6 +343,11 @@ int construct_dom0(struct domain *d)
>  
>      if ( is_pv32_domain(d) )
>      {
> +        regs->cpsr = PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC;
> +
> +        /* Pretend to be a Cortex A15 */
> +        d->arch.vpidr = 0x410fc0f0;
> +
>          /* FROM LINUX head.S
>           *
>           * Kernel startup entry point.
> @@ -361,6 +365,8 @@ int construct_dom0(struct domain *d)
>  #ifdef CONFIG_ARM_64
>      else
>      {
> +        regs->cpsr = PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h;
> +
>          /* From linux/Documentation/arm64/booting.txt */
>          regs->x0 = kinfo.dtb_paddr;
>          regs->x1 = 0; /* Reserved for future use */
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 06/14] xen: arm: precalculate VTTBR_EL2 for a domain when setting up its p2m
  2013-03-12 15:48 ` [PATCH 06/14] xen: arm: precalculate VTTBR_EL2 for a domain when setting up its p2m Ian Campbell
@ 2013-04-08 11:27   ` Stefano Stabellini
  0 siblings, 0 replies; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-08 11:27 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), Ian Campbell, xen-devel

On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Mostly just to help with upcoming vcpu_show_registers changes.
> 
> Signed-off-by: Ian Campbell <ijc@hellion.org.uk>

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>  xen/arch/arm/p2m.c           |   16 +++++++++-------
>  xen/include/asm-arm/domain.h |    3 +++
>  2 files changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 1e8c8b4..175216c 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -23,13 +23,10 @@ void dump_p2m_lookup(struct domain *d, paddr_t addr)
>  
>  void p2m_load_VTTBR(struct domain *d)
>  {
> -    struct p2m_domain *p2m = &d->arch.p2m;
> -    paddr_t maddr = page_to_maddr(p2m->first_level);
> -    uint64_t vttbr = maddr;
> -
> -    vttbr |= ((uint64_t)p2m->vmid&0xff)<<48;
> -
> -    WRITE_SYSREG64(vttbr, VTTBR_EL2);
> +    if ( is_idle_domain(d) )
> +        return;
> +    BUG_ON(!d->arch.vttbr);
> +    WRITE_SYSREG64(d->arch.vttbr, VTTBR_EL2);
>      isb(); /* Ensure update is visible */
>  }
>  
> @@ -300,6 +297,9 @@ int p2m_alloc_table(struct domain *d)
>  
>      p2m->first_level = page;
>  
> +    d->arch.vttbr = page_to_maddr(p2m->first_level)
> +        | ((uint64_t)p2m->vmid&0xff)<<48;
> +
>      spin_unlock(&p2m->lock);
>  
>      return 0;
> @@ -331,6 +331,8 @@ int p2m_init(struct domain *d)
>      /* Zero is reserved */
>      p2m->vmid = d->domain_id + 1;
>  
> +    d->arch.vttbr = 0;
> +
>      p2m->first_level = NULL;
>  
>      return 0;
> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index bf9caff..3da9163 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -53,7 +53,10 @@ struct arch_domain
>      enum domain_type type;
>  #endif
>  
> +    /* Virtual MMU */
>      struct p2m_domain p2m;
> +    uint64_t vttbr;
> +
>      struct hvm_domain hvm_domain;
>      xen_pfn_t *grant_table_gpfn;
>  
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 12/14] xen: arm: handle hypercalls from 64-bit guests
  2013-03-12 15:48 ` [PATCH 12/14] xen: arm: handle hypercalls " Ian Campbell
@ 2013-04-08 11:43   ` Stefano Stabellini
  0 siblings, 0 replies; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-08 11:43 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), Ian Campbell, xen-devel

On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>  xen/arch/arm/traps.c            |   67 ++++++++++++++++++++++++++++-----------
>  xen/include/asm-arm/processor.h |    7 ++--
>  2 files changed, 54 insertions(+), 20 deletions(-)
> 
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index f1dd557..190d1e8 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -726,8 +726,8 @@ unsigned long do_arch_0(unsigned int cmd, unsigned long long value)
>          return 0;
>  }
>  
> -typedef unsigned long (*arm_hypercall_fn_t)(
> -    unsigned int, unsigned int, unsigned int, unsigned int, unsigned int);
> +typedef register_t (*arm_hypercall_fn_t)(
> +    register_t, register_t, register_t, register_t, register_t);
>  
>  typedef struct {
>      arm_hypercall_fn_t fn;
> @@ -783,30 +783,49 @@ static void do_debug_trap(struct cpu_user_regs *regs, unsigned int code)
>      }
>  }
>  
> -static void do_trap_hypercall(struct cpu_user_regs *regs, unsigned long iss)
> +#ifdef CONFIG_ARM_64
> +#define HYPERCALL_RESULT_REG(r) (r)->x0
> +#define HYPERCALL_ARG1(r) (r)->x0
> +#define HYPERCALL_ARG2(r) (r)->x1
> +#define HYPERCALL_ARG3(r) (r)->x2
> +#define HYPERCALL_ARG4(r) (r)->x3
> +#define HYPERCALL_ARG5(r) (r)->x4
> +#define HYPERCALL_ARGS(r) (r)->x0, (r)->x1, (r)->x2, (r)->x3, (r)->x4
> +#else
> +#define HYPERCALL_RESULT_REG(r) (r)->r0
> +#define HYPERCALL_ARG1(r) (r)->r0
> +#define HYPERCALL_ARG2(r) (r)->r1
> +#define HYPERCALL_ARG3(r) (r)->r2
> +#define HYPERCALL_ARG4(r) (r)->r3
> +#define HYPERCALL_ARG5(r) (r)->r4
> +#define HYPERCALL_ARGS(r) (r)->r0, (r)->r1, (r)->r2, (r)->r3, (r)->r4
> +#endif
> +
> +static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
> +                              unsigned long iss)
>  {
>      arm_hypercall_fn_t call = NULL;
>  #ifndef NDEBUG
> -    uint32_t orig_pc = regs->pc;
> +    register_t orig_pc = regs->pc;
>  #endif
>  
>      if ( iss != XEN_HYPERCALL_TAG )
>          domain_crash_synchronous();
>  
> -    if ( regs->r12 >= ARRAY_SIZE(arm_hypercall_table) )
> +    if ( *nr >= ARRAY_SIZE(arm_hypercall_table) )
>      {
> -        regs->r0 = -ENOSYS;
> +        HYPERCALL_RESULT_REG(regs) = -ENOSYS;
>          return;
>      }
>  
> -    call = arm_hypercall_table[regs->r12].fn;
> +    call = arm_hypercall_table[*nr].fn;
>      if ( call == NULL )
>      {
> -        regs->r0 = -ENOSYS;
> +        HYPERCALL_RESULT_REG(regs) = -ENOSYS;
>          return;
>      }
>  
> -    regs->r0 = call(regs->r0, regs->r1, regs->r2, regs->r3, regs->r4);
> +    HYPERCALL_RESULT_REG(regs) = call(HYPERCALL_ARGS(regs));
>  
>  #ifndef NDEBUG
>      /*
> @@ -815,16 +834,16 @@ static void do_trap_hypercall(struct cpu_user_regs *regs, unsigned long iss)
>       */
>      if ( orig_pc == regs->pc )
>      {
> -        switch ( arm_hypercall_table[regs->r12].nr_args ) {
> -        case 5: regs->r4 = 0xDEADBEEF;
> -        case 4: regs->r3 = 0xDEADBEEF;
> -        case 3: regs->r2 = 0xDEADBEEF;
> -        case 2: regs->r1 = 0xDEADBEEF;
> -        case 1: /* Don't clobber r0 -- it's the return value */
> +        switch ( arm_hypercall_table[*nr].nr_args ) {
> +        case 5: HYPERCALL_ARG5(regs) = 0xDEADBEEF;
> +        case 4: HYPERCALL_ARG4(regs) = 0xDEADBEEF;
> +        case 3: HYPERCALL_ARG3(regs) = 0xDEADBEEF;
> +        case 2: HYPERCALL_ARG2(regs) = 0xDEADBEEF;
> +        case 1: /* Don't clobber x0/r0 -- it's the return value */
>              break;
>          default: BUG();
>          }
> -        regs->r12 = 0xDEADBEEF;
> +        *nr = 0xDEADBEEF;
>      }
>  #endif
>  }
> @@ -1079,11 +1098,23 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs)
>              goto bad_trap;
>          do_cp15_64(regs, hsr);
>          break;
> -    case HSR_EC_HVC:
> +    case HSR_EC_HVC32:
> +#ifndef NDEBUG
> +        if ( (hsr.iss & 0xff00) == 0xff00 )
> +            return do_debug_trap(regs, hsr.iss & 0x00ff);
> +#endif
> +        do_trap_hypercall(regs, (register_t *)&regs->r12, hsr.iss);
> +        break;
> +
> +#ifdef CONFIG_ARM_64
> +    case HSR_EC_HVC64:
> +#ifndef NDEBUG
>          if ( (hsr.iss & 0xff00) == 0xff00 )
>              return do_debug_trap(regs, hsr.iss & 0x00ff);
> -        do_trap_hypercall(regs, hsr.iss);
> +#endif
> +        do_trap_hypercall(regs, &regs->x16, hsr.iss);
>          break;
> +#endif
>      case HSR_EC_DATA_ABORT_GUEST:
>          do_trap_data_abort_guest(regs, hsr.dabt);
>          break;
> diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
> index 32c441b..17f5465 100644
> --- a/xen/include/asm-arm/processor.h
> +++ b/xen/include/asm-arm/processor.h
> @@ -86,8 +86,11 @@
>  #define HSR_EC_JAZELLE              0x09
>  #define HSR_EC_BXJ                  0x0a
>  #define HSR_EC_CP14_64              0x0c
> -#define HSR_EC_SVC                  0x11
> -#define HSR_EC_HVC                  0x12
> +#define HSR_EC_SVC32                0x11
> +#define HSR_EC_HVC32                0x12
> +#ifdef CONFIG_ARM_64
> +#define HSR_EC_HVC64                0x16
> +#endif
>  #define HSR_EC_INSTR_ABORT_GUEST    0x20
>  #define HSR_EC_INSTR_ABORT_HYP      0x21
>  #define HSR_EC_DATA_ABORT_GUEST     0x24
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 14/14] xen: arm: align some comments
  2013-03-12 15:48 ` [PATCH 14/14] xen: arm: align some comments Ian Campbell
@ 2013-04-08 11:44   ` Stefano Stabellini
  0 siblings, 0 replies; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-08 11:44 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), Ian Campbell, xen-devel

On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>  xen/include/asm-arm/processor.h |    8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
> index d75530d..53ffce2 100644
> --- a/xen/include/asm-arm/processor.h
> +++ b/xen/include/asm-arm/processor.h
> @@ -244,11 +244,11 @@ union hsr {
>          unsigned long reg1:5;   /* Rt1 */
>          unsigned long reg2:5;   /* Rt2 */
>          unsigned long sbzp2:1;
> -        unsigned long op1:4;   /* Op1 */
> -        unsigned long cc:4;    /* Condition Code */
> +        unsigned long op1:4;    /* Op1 */
> +        unsigned long cc:4;     /* Condition Code */
>          unsigned long ccvalid:1;/* CC Valid */
> -        unsigned long len:1;   /* Instruction length */
> -        unsigned long ec:6;    /* Exception Class */
> +        unsigned long len:1;    /* Instruction length */
> +        unsigned long ec:6;     /* Exception Class */
>      } cp64; /* HSR_EC_CP15_64, HSR_EC_CP14_64 */
>  
>  #ifdef CONFIG_ARM_64
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 13/14] xen: arm: handle 64-bit system register access traps.
  2013-03-12 15:48 ` [PATCH 13/14] xen: arm: handle 64-bit system register access traps Ian Campbell
@ 2013-04-08 13:11   ` Stefano Stabellini
  2013-04-10 11:52     ` Ian Campbell
  0 siblings, 1 reply; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-08 13:11 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), Ian Campbell, xen-devel

On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Wire up the vtimer handling to it.
> 
> Use a simplified version of the 32-bit cp-register macros to have convenient
> decoding of HSR register values. (simplified because we don't need them for
> passing to the assembler on 64-bit)
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>


Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

assuming that you didn't make any mistakes in writing down thw new
SYSREG #define


>  xen/arch/arm/traps.c            |   39 +++++++++++++
>  xen/arch/arm/vtimer.c           |  119 ++++++++++++++++++++++++++-------------
>  xen/include/asm-arm/processor.h |   32 +++++++++++
>  xen/include/asm-arm/sysregs.h   |   56 ++++++++++++++++++
>  4 files changed, 208 insertions(+), 38 deletions(-)
>  create mode 100644 xen/include/asm-arm/sysregs.h
> 
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index 190d1e8..67d9072 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -973,6 +973,39 @@ static void do_cp15_64(struct cpu_user_regs *regs,
>  
>  }
>  
> +#ifdef CONFIG_ARM_64
> +static void do_sysreg(struct cpu_user_regs *regs,
> +                      union hsr hsr)
> +{
> +    struct hsr_sysreg sysreg = hsr.sysreg;
> +
> +    switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
> +    {
> +    case CNTP_CTL_EL0:
> +    case CNTP_TVAL_EL0:
> +        if ( !vtimer_emulate(regs, hsr) )
> +        {
> +            dprintk(XENLOG_ERR,
> +                    "failed emulation of 64-bit vtimer sysreg access\n");
> +            domain_crash_synchronous();
> +        }
> +        break;
> +    default:
> +        printk("%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
> +               sysreg.read ? "mrs" : "msr",
> +               sysreg.op0, sysreg.op1,
> +               sysreg.crn, sysreg.crm,
> +               sysreg.op2,
> +               sysreg.read ? "=>" : "<=",
> +               sysreg.reg, regs->pc);
> +        panic("unhandled 64-bit sysreg access %#x\n",
> +              hsr.bits & HSR_SYSREG_REGS_MASK);
> +    }
> +
> +    regs->pc += 4;
> +}
> +#endif
> +
>  void dump_guest_s1_walk(struct domain *d, vaddr_t addr)
>  {
>      uint32_t ttbcr = READ_SYSREG32(TCR_EL1);
> @@ -1114,7 +1147,13 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs)
>  #endif
>          do_trap_hypercall(regs, &regs->x16, hsr.iss);
>          break;
> +    case HSR_EC_SYSREG:
> +        if ( is_pv32_domain(current->domain) )
> +            goto bad_trap;
> +        do_sysreg(regs, hsr);
> +        break;
>  #endif
> +
>      case HSR_EC_DATA_ABORT_GUEST:
>          do_trap_data_abort_guest(regs, hsr.dabt);
>          break;
> diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
> index a68f662..f9fc045 100644
> --- a/xen/arch/arm/vtimer.c
> +++ b/xen/arch/arm/vtimer.c
> @@ -102,51 +102,62 @@ int virt_timer_restore(struct vcpu *v)
>      return 0;
>  }
>  
> -static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr)
> +static void vtimer_cntp_ctl(struct cpu_user_regs *regs, uint32_t *r, int read)
>  {
>      struct vcpu *v = current;
> -    struct hsr_cp32 cp32 = hsr.cp32;
> -    uint32_t *r = (uint32_t *)select_user_reg(regs, cp32.reg);
> -    s_time_t now;
> -
> -    switch ( hsr.bits & HSR_CP32_REGS_MASK )
> +    if ( read )
>      {
> -    case HSR_CPREG32(CNTP_CTL):
> -        if ( cp32.read )
> +        *r = v->arch.phys_timer.ctl;
> +    }
> +    else
> +    {
> +        v->arch.phys_timer.ctl = *r;
> +
> +        if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
>          {
> -            *r = v->arch.phys_timer.ctl;
> +            set_timer(&v->arch.phys_timer.timer,
> +                      v->arch.phys_timer.cval + v->arch.phys_timer.offset);
>          }
>          else
> +            stop_timer(&v->arch.phys_timer.timer);
> +    }
> +}
> +
> +static void vtimer_cntp_tval(struct cpu_user_regs *regs, uint32_t *r, int read)
> +{
> +    struct vcpu *v = current;
> +    s_time_t now;
> +
> +    now = NOW() - v->arch.phys_timer.offset;
> +
> +    if ( read )
> +    {
> +        *r = (uint32_t)(ns_to_ticks(v->arch.phys_timer.cval - now) & 0xffffffffull);
> +    }
> +    else
> +    {
> +        v->arch.phys_timer.cval = now + ticks_to_ns(*r);
> +        if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
>          {
> -            v->arch.phys_timer.ctl = *r;
> -
> -            if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
> -            {
> -                set_timer(&v->arch.phys_timer.timer,
> -                          v->arch.phys_timer.cval + v->arch.phys_timer.offset);
> -            }
> -            else
> -                stop_timer(&v->arch.phys_timer.timer);
> +            set_timer(&v->arch.phys_timer.timer,
> +                      v->arch.phys_timer.cval + v->arch.phys_timer.offset);
>          }
> +    }
> +}
>  
> +static int vtimer_emulate_cp32(struct cpu_user_regs *regs, union hsr hsr)
> +{
> +    struct hsr_cp32 cp32 = hsr.cp32;
> +    uint32_t *r = (uint32_t *)select_user_reg(regs, cp32.reg);
> +
> +    switch ( hsr.bits & HSR_CP32_REGS_MASK )
> +    {
> +    case HSR_CPREG32(CNTP_CTL):
> +        vtimer_cntp_ctl(regs, r, cp32.read);
>          return 1;
>  
>      case HSR_CPREG32(CNTP_TVAL):
> -        now = NOW() - v->arch.phys_timer.offset;
> -        if ( cp32.read )
> -        {
> -            *r = (uint32_t)(ns_to_ticks(v->arch.phys_timer.cval - now) & 0xffffffffull);
> -        }
> -        else
> -        {
> -            v->arch.phys_timer.cval = now + ticks_to_ns(*r);
> -            if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
> -            {
> -                set_timer(&v->arch.phys_timer.timer,
> -                          v->arch.phys_timer.cval + v->arch.phys_timer.offset);
> -            }
> -        }
> -
> +        vtimer_cntp_tval(regs, r, cp32.read);
>          return 1;
>  
>      default:
> @@ -154,7 +165,7 @@ static int vtimer_emulate_32(struct cpu_user_regs *regs, union hsr hsr)
>      }
>  }
>  
> -static int vtimer_emulate_64(struct cpu_user_regs *regs, union hsr hsr)
> +static int vtimer_emulate_cp64(struct cpu_user_regs *regs, union hsr hsr)
>  {
>      struct vcpu *v = current;
>      struct hsr_cp64 cp64 = hsr.cp64;
> @@ -185,16 +196,48 @@ static int vtimer_emulate_64(struct cpu_user_regs *regs, union hsr hsr)
>      }
>  }
>  
> +#ifdef CONFIG_ARM_64
> +static int vtimer_emulate_sysreg(struct cpu_user_regs *regs, union hsr hsr)
> +{
> +    struct hsr_sysreg sysreg = hsr.sysreg;
> +    register_t *x = select_user_reg(regs, sysreg.reg);
> +    uint32_t r = (uint32_t)*x;
> +
> +    switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
> +    {
> +    case CNTP_CTL_EL0:
> +        vtimer_cntp_ctl(regs, &r, sysreg.read);
> +        *x = r;
> +        return 1;
> +    case CNTP_TVAL_EL0:
> +        vtimer_cntp_tval(regs, &r, sysreg.read);
> +        *x = r;
> +        return 1;
> +    default:
> +        return 0;
> +    }
> +
> +}
> +#endif
> +
>  int vtimer_emulate(struct cpu_user_regs *regs, union hsr hsr)
>  {
> -    if ( !is_pv32_domain(current->domain) )
> -        return -EINVAL;
>  
>      switch (hsr.ec) {
>      case HSR_EC_CP15_32:
> -        return vtimer_emulate_32(regs, hsr);
> +        if ( !is_pv32_domain(current->domain) )
> +            return 0;
> +        return vtimer_emulate_cp32(regs, hsr);
>      case HSR_EC_CP15_64:
> -        return vtimer_emulate_64(regs, hsr);
> +        if ( !is_pv32_domain(current->domain) )
> +            return 0;
> +        return vtimer_emulate_cp64(regs, hsr);
> +#ifdef CONFIG_ARM_64
> +    case HSR_EC_SYSREG:
> +        if ( is_pv32_domain(current->domain) )
> +            return 0;
> +        return vtimer_emulate_sysreg(regs, hsr);
> +#endif
>      default:
>          return 0;
>      }
> diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
> index 17f5465..d75530d 100644
> --- a/xen/include/asm-arm/processor.h
> +++ b/xen/include/asm-arm/processor.h
> @@ -2,6 +2,7 @@
>  #define __ASM_ARM_PROCESSOR_H
>  
>  #include <asm/cpregs.h>
> +#include <asm/sysregs.h>
>  
>  /* MIDR Main ID Register */
>  #define MIDR_MASK    0xff0ffff0
> @@ -90,6 +91,7 @@
>  #define HSR_EC_HVC32                0x12
>  #ifdef CONFIG_ARM_64
>  #define HSR_EC_HVC64                0x16
> +#define HSR_EC_SYSREG               0x18
>  #endif
>  #define HSR_EC_INSTR_ABORT_GUEST    0x20
>  #define HSR_EC_INSTR_ABORT_HYP      0x21
> @@ -249,6 +251,21 @@ union hsr {
>          unsigned long ec:6;    /* Exception Class */
>      } cp64; /* HSR_EC_CP15_64, HSR_EC_CP14_64 */
>  
> +#ifdef CONFIG_ARM_64
> +    struct hsr_sysreg {
> +        unsigned long read:1;   /* Direction */
> +        unsigned long crm:4;    /* CRm */
> +        unsigned long reg:5;    /* Rt */
> +        unsigned long crn:4;    /* CRn */
> +        unsigned long op1:3;    /* Op1 */
> +        unsigned long op2:3;    /* Op2 */
> +        unsigned long op0:2;    /* Op0 */
> +        unsigned long res0:3;
> +        unsigned long len:1;    /* Instruction length */
> +        unsigned long ec:6;
> +    } sysreg; /* HSR_EC_SYSREG */
> +#endif
> +
>      struct hsr_dabt {
>          unsigned long dfsc:6;  /* Data Fault Status Code */
>          unsigned long write:1; /* Write / not Read */
> @@ -291,6 +308,21 @@ union hsr {
>  #define HSR_CP64_CRM_SHIFT (1)
>  #define HSR_CP64_REGS_MASK (HSR_CP64_OP1_MASK|HSR_CP64_CRM_MASK)
>  
> +/* HSR.EC == HSR_SYSREG */
> +#define HSR_SYSREG_OP0_MASK (0x00300000)
> +#define HSR_SYSREG_OP0_SHIFT (20)
> +#define HSR_SYSREG_OP1_MASK (0x0001c000)
> +#define HSR_SYSREG_OP1_SHIFT (14)
> +#define HSR_SYSREG_CRN_MASK (0x00003800)
> +#define HSR_SYSREG_CRN_SHIFT (10)
> +#define HSR_SYSREG_CRM_MASK (0x0000001e)
> +#define HSR_SYSREG_CRM_SHIFT (1)
> +#define HSR_SYSREG_OP2_MASK (0x000e0000)
> +#define HSR_SYSREG_OP2_SHIFT (17)
> +#define HSR_SYSREG_REGS_MASK (HSR_SYSREG_OP0_MASK|HSR_SYSREG_OP1_MASK|\
> +                              HSR_SYSREG_CRN_MASK|HSR_SYSREG_CRM_MASK|\
> +                              HSR_SYSREG_OP2_MASK)
> +
>  /* Physical Address Register */
>  #define PAR_F           (1<<0)
>  
> diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h
> new file mode 100644
> index 0000000..9c64777
> --- /dev/null
> +++ b/xen/include/asm-arm/sysregs.h
> @@ -0,0 +1,56 @@
> +#ifndef __ASM_ARM_SYSREGS_H
> +#define __ASM_ARM_SYSREGS_H
> +
> +#ifdef CONFIG_ARM_64
> +
> +#include <xen/stringify.h>
> +
> +/* AArch 64 System Register Encodings */
> +#define __HSR_SYSREG_c0  0
> +#define __HSR_SYSREG_c1  1
> +#define __HSR_SYSREG_c2  2
> +#define __HSR_SYSREG_c3  3
> +#define __HSR_SYSREG_c4  4
> +#define __HSR_SYSREG_c5  5
> +#define __HSR_SYSREG_c6  6
> +#define __HSR_SYSREG_c7  7
> +#define __HSR_SYSREG_c8  8
> +#define __HSR_SYSREG_c9  9
> +#define __HSR_SYSREG_c10 10
> +#define __HSR_SYSREG_c11 11
> +#define __HSR_SYSREG_c12 12
> +#define __HSR_SYSREG_c13 13
> +#define __HSR_SYSREG_c14 14
> +#define __HSR_SYSREG_c15 15
> +
> +#define __HSR_SYSREG_0   0
> +#define __HSR_SYSREG_1   1
> +#define __HSR_SYSREG_2   2
> +#define __HSR_SYSREG_3   3
> +#define __HSR_SYSREG_4   4
> +#define __HSR_SYSREG_5   5
> +#define __HSR_SYSREG_6   6
> +#define __HSR_SYSREG_7   7
> +
> +/* These are used to decode traps with HSR.EC==HSR_EC_SYSREG */
> +#define HSR_SYSREG(op0,op1,crn,crm,op2) \
> +    ((__HSR_SYSREG_##op0) << HSR_SYSREG_OP0_SHIFT) | \
> +    ((__HSR_SYSREG_##op1) << HSR_SYSREG_OP1_SHIFT) | \
> +    ((__HSR_SYSREG_##crn) << HSR_SYSREG_CRN_SHIFT) | \
> +    ((__HSR_SYSREG_##crm) << HSR_SYSREG_CRM_SHIFT) | \
> +    ((__HSR_SYSREG_##op2) << HSR_SYSREG_OP2_SHIFT)
> +
> +#define CNTP_CTL_EL0  HSR_SYSREG(3,3,c14,c2,1)
> +#define CNTP_TVAL_EL0 HSR_SYSREG(3,3,c14,c2,0)
> +#endif
> +
> +#endif
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-set-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 02/14] xen: arm: tweak arm64 stack frame layout
  2013-03-12 15:48 ` [PATCH 02/14] xen: arm: tweak arm64 stack frame layout Ian Campbell
@ 2013-04-08 13:31   ` Stefano Stabellini
  2013-04-10 11:57     ` Ian Campbell
  0 siblings, 1 reply; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-08 13:31 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), Ian Campbell, xen-devel

On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Correct definition of UREGS_kernel_sizeof and use it.
> 
> Correct adjustment of stack on entry and exit.
> 
> Add 64-bit versions of the build time checks for stack pointer alignment
> correctness when pushing the stack frames.
> 
> Lastly, correct the padding in the stack frames to properly align the inner and
> outer frames and also avoid an unnecessary 64bit padding field.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> ---
>  xen/arch/arm/arm64/asm-offsets.c      |    2 +-
>  xen/arch/arm/arm64/entry.S            |    9 +++++----
>  xen/arch/arm/domain.c                 |    2 ++
>  xen/arch/arm/traps.c                  |    7 +++++++
>  xen/include/asm-arm/arm64/processor.h |    7 +++----
>  5 files changed, 18 insertions(+), 9 deletions(-)
> 
> diff --git a/xen/arch/arm/arm64/asm-offsets.c b/xen/arch/arm/arm64/asm-offsets.c
> index 7949e3e..7544082 100644
> --- a/xen/arch/arm/arm64/asm-offsets.c
> +++ b/xen/arch/arm/arm64/asm-offsets.c
> @@ -39,7 +39,7 @@ void __dummy__(void)
>     OFFSET(UREGS_SP_el1, struct cpu_user_regs, sp_el1);
>     OFFSET(UREGS_ELR_el1, struct cpu_user_regs, elr_el1);
>  
> -   OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, cpsr);
> +   OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, spsr_el1);
>     DEFINE(UREGS_user_sizeof, sizeof(struct cpu_user_regs));
>     BLANK();
>  
> diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
> index 9d38088..a5fd608 100644
> --- a/xen/arch/arm/arm64/entry.S
> +++ b/xen/arch/arm/arm64/entry.S
> @@ -34,7 +34,7 @@ lr      .req    x30             // link register
>          mrs     x22, SP_el0
>          str     x22, [x21]
>  
> -        add     x21, sp, #UREGS_ELR_el1
> +        add     x21, sp, #UREGS_SP_el1
>          mrs     x22, SP_el1
>          mrs     x23, ELR_el1
>          stp     x22, x23, [x21]

Honestly I think it would be much cleaner and easier to read if we saved
sp_el1 and elr_el1 separately.


> @@ -59,7 +59,7 @@ lr      .req    x30             // link register
>   * Save state on entry to hypervisor
>   */
>          .macro  entry, hyp, compat
> -        sub     sp, sp, #(UREGS_SPSR_el1 - UREGS_SP)
> +        sub     sp, sp, #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */
>          push    x28, x29
>          push    x26, x27
>          push    x24, x25
> @@ -78,7 +78,7 @@ lr      .req    x30             // link register
>  
>          .if \hyp == 1        /* Hypervisor mode */
>  
> -        add     x21, sp, #(UREGS_X0 - UREGS_SP)
> +        add     x21, sp, #UREGS_kernel_sizeof
>  
>          .else                /* Guest mode */
>  
> @@ -213,7 +213,8 @@ ENTRY(return_to_hypervisor)
>          pop     x26, x27
>          pop     x28, x29
>  
> -        ldr     lr, [sp], #(UREGS_SPSR_el1 - UREGS_SP)
> +        ldr     lr, [sp], #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */
> +
>          eret
>  
>  /*
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index f369871..08bb132 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -419,6 +419,8 @@ int vcpu_initialise(struct vcpu *v)
>  {
>      int rc = 0;
>  
> +    BUILD_BUG_ON( sizeof(struct cpu_info) > STACK_SIZE );
> +
>      v->arch.stack = alloc_xenheap_pages(STACK_ORDER, MEMF_node(vcpu_to_node(v)));
>      if ( v->arch.stack == NULL )
>          return -ENOMEM;
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index a98a45e..6b19bc5 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -43,9 +43,16 @@
>   * entry.S) and struct cpu_info (which lives at the bottom of a Xen
>   * stack) must be doubleword-aligned in size.  */
>  static inline void check_stack_alignment_constraints(void) {
> +#ifdef CONFIG_ARM_64
> +    BUILD_BUG_ON((sizeof (struct cpu_user_regs)) & 0xf);
> +    BUILD_BUG_ON((offsetof(struct cpu_user_regs, spsr_el1)) & 0xf);
> +    BUILD_BUG_ON((offsetof(struct cpu_user_regs, lr)) & 0xf);
> +    BUILD_BUG_ON((sizeof (struct cpu_info)) & 0xf);

Why both spsr_el1 and lr?
>From the comment on top of check_stack_alignment_constraints I would
think that only spsr_el1 is needed?


> +#else
>      BUILD_BUG_ON((sizeof (struct cpu_user_regs)) & 0x7);
>      BUILD_BUG_ON((offsetof(struct cpu_user_regs, sp_usr)) & 0x7);
>      BUILD_BUG_ON((sizeof (struct cpu_info)) & 0x7);
> +#endif
>  }
>  
>  static int debug_stack_lines = 20;
> diff --git a/xen/include/asm-arm/arm64/processor.h b/xen/include/asm-arm/arm64/processor.h
> index b4602fa..bf436c8 100644
> --- a/xen/include/asm-arm/arm64/processor.h
> +++ b/xen/include/asm-arm/arm64/processor.h
> @@ -51,6 +51,7 @@ struct cpu_user_regs
>      __DECL_REG(x27,          r11_fiq);
>      __DECL_REG(x28,          r12_fiq);
>      __DECL_REG(/* x29 */ fp, /* r13_fiq */ sp_fiq);
> +
>      __DECL_REG(/* x30 */ lr, /* r14_fiq */ lr_fiq);
>  
>      register_t sp; /* Valid for hypervisor frames */
> @@ -59,7 +60,7 @@ struct cpu_user_regs
>      __DECL_REG(pc,           pc32);             /* ELR_EL2 */
>      uint32_t cpsr;                              /* SPSR_EL2 */
>  
> -    uint64_t pad0;
> +    uint32_t pad0; /* Align end of kernel frame. */

That would be because cpsr is a uint32_t, right?


>      /* Outer guest frame only from here on... */
>  
> @@ -68,7 +69,7 @@ struct cpu_user_regs
>          uint32_t spsr_svc;       /* AArch32 */
>      };
>  
> -    uint32_t pad1; /* Align */
> +    uint32_t pad1; /* Doubleword-align the user half of the frame */

This one is because of the preceding union of two uint32_t


>      /* AArch32 guests only */
>      uint32_t spsr_fiq, spsr_irq, spsr_und, spsr_abt;
> @@ -76,8 +77,6 @@ struct cpu_user_regs
>      /* AArch64 guests only */
>      uint64_t sp_el0;
>      uint64_t sp_el1, elr_el1;
> -
> -    uint64_t pad2; /* Doubleword-align the user half of the frame */
>  };

of course padding with uint64_t is useless on arm (32 and 64)

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

* Re: [PATCH 11/14] xen: arm: handle traps from 64-bit guests
  2013-03-12 15:48 ` [PATCH 11/14] xen: arm: handle traps from 64-bit guests Ian Campbell
@ 2013-04-08 13:45   ` Stefano Stabellini
  0 siblings, 0 replies; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-08 13:45 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), Ian Campbell, xen-devel

On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>


Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

>  xen/arch/arm/arm64/entry.S |    9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
> index a5fd608..7799751 100644
> --- a/xen/arch/arm/arm64/entry.S
> +++ b/xen/arch/arm/arm64/entry.S
> @@ -142,11 +142,16 @@ hyp_irq:
>  
>  guest_sync:
>          entry   hyp=0, compat=0
> -        invalid BAD_SYNC /* No AArch64 guest support yet */
> +        msr     daifclr, #2
> +        mov     x0, sp
> +        bl      do_trap_hypervisor
> +        b       return_to_guest
>  
>  guest_irq:
>          entry   hyp=0, compat=0
> -        invalid BAD_IRQ /* No AArch64 guest support yet */
> +        mov     x0, sp
> +        bl      do_trap_irq
> +        b       return_to_guest
>  
>  guest_fiq_invalid:
>          entry   hyp=0, compat=0
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 09/14] xen: arm: show less words in a line of a stack trace in 64-bit builds
  2013-03-12 15:48 ` [PATCH 09/14] xen: arm: show less words in a line of a stack trace in 64-bit builds Ian Campbell
@ 2013-04-08 13:46   ` Stefano Stabellini
  0 siblings, 0 replies; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-08 13:46 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), Ian Campbell, xen-devel

On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Words are twice as wide so this ensures that a line is still <80 characters.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>  xen/arch/arm/traps.c |    9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index 2671eba..f1dd557 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -55,10 +55,15 @@ static inline void check_stack_alignment_constraints(void) {
>  #endif
>  }
>  
> +#ifdef CONFIG_ARM_32
>  static int debug_stack_lines = 20;
> -integer_param("debug_stack_lines", debug_stack_lines);
> -
>  #define stack_words_per_line 8
> +#else
> +static int debug_stack_lines = 40;
> +#define stack_words_per_line 4
> +#endif
> +
> +integer_param("debug_stack_lines", debug_stack_lines);
>  
>  
>  void __cpuinit init_traps(void)
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 08/14] xen: arm: support dumping 64-bit guest stack
  2013-03-12 15:48 ` [PATCH 08/14] xen: arm: support dumping 64-bit guest stack Ian Campbell
@ 2013-04-08 17:29   ` Stefano Stabellini
  2013-04-10 11:59     ` Ian Campbell
  0 siblings, 1 reply; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-08 17:29 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Tim (Xen.org), Ian Campbell, xen-devel

On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@citrix.com>
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

it would be nice to support more guest modes but this is undoubtedly an improvement.

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>  xen/arch/arm/traps.c |   80 +++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 76 insertions(+), 4 deletions(-)
> 
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index 2f4e157..2671eba 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -523,9 +523,81 @@ void vcpu_show_registers(const struct vcpu *v)
>      _show_registers(&v->arch.cpu_info->guest_cpu_user_regs, &ctxt, 1, v);
>  }
>  
> -static void show_guest_stack(struct cpu_user_regs *regs)
> +static void show_guest_stack(struct vcpu *v, struct cpu_user_regs *regs)
>  {
> -    printk("GUEST STACK GOES HERE\n");
> +    int i;
> +    vaddr_t sp;
> +    paddr_t stack_phys;
> +    void *mapped;
> +    unsigned long *stack, addr;
> +
> +    switch ( regs->cpsr & PSR_MODE_MASK )
> +    {
> +    case PSR_MODE_USR:
> +    case PSR_MODE_SYS:
> +#ifdef CONFIG_ARM_64
> +    case PSR_MODE_EL0t:
> +#endif
> +        printk("No stack trace for guest user-mode\n");
> +        return;
> +
> +    case PSR_MODE_FIQ:
> +    case PSR_MODE_IRQ:
> +    case PSR_MODE_SVC:
> +    case PSR_MODE_ABT:
> +    case PSR_MODE_UND:
> +        printk("No stack trace for 32-bit guest kernel-mode\n");
> +        return;
> +
> +#ifdef CONFIG_ARM_64
> +    case PSR_MODE_EL1t:
> +        sp = regs->sp_el0;
> +        break;
> +    case PSR_MODE_EL1h:
> +        sp = regs->sp_el1;
> +        break;
> +#endif
> +
> +    case PSR_MODE_HYP:
> +    case PSR_MODE_MON:
> +#ifdef CONFIG_ARM_64
> +    case PSR_MODE_EL3h:
> +    case PSR_MODE_EL3t:
> +    case PSR_MODE_EL2h:
> +    case PSR_MODE_EL2t:
> +#endif
> +    default:
> +        BUG();
> +        return;
> +    }
> +
> +    printk("Guest stack trace from sp=%"PRIvaddr":\n  ", sp);
> +
> +    if ( gvirt_to_maddr(sp, &stack_phys) )
> +    {
> +        printk("Failed to convert stack to physical address\n");
> +        return;
> +    }
> +
> +    mapped = map_domain_page(stack_phys >> PAGE_SHIFT);
> +
> +    stack = mapped + (sp & ~PAGE_MASK);
> +
> +    for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
> +    {
> +        if ( (((long)stack - 1) ^ ((long)(stack + 1) - 1)) & PAGE_SIZE )
> +            break;
> +        addr = *stack;
> +        if ( (i != 0) && ((i % stack_words_per_line) == 0) )
> +            printk("\n  ");
> +        printk(" %p", _p(addr));
> +        stack++;
> +    }
> +    if ( i == 0 )
> +        printk("Stack empty.");
> +    printk("\n");
> +    unmap_domain_page(mapped);
> +
>  }
>  
>  #define STACK_BEFORE_EXCEPTION(regs) ((register_t*)(regs)->sp)
> @@ -589,7 +661,7 @@ void show_stack(struct cpu_user_regs *regs)
>      int i;
>  
>      if ( guest_mode(regs) )
> -        return show_guest_stack(regs);
> +        return show_guest_stack(current, regs);
>  
>      printk("Xen stack trace from sp=%p:\n  ", stack);
>  
> @@ -631,7 +703,7 @@ void vcpu_show_execution_state(struct vcpu *v)
>  
>      vcpu_show_registers(v);
>      if ( !usr_mode(&v->arch.cpu_info->guest_cpu_user_regs) )
> -        show_guest_stack(&v->arch.cpu_info->guest_cpu_user_regs);
> +        show_guest_stack(v, &v->arch.cpu_info->guest_cpu_user_regs);
>  
>      vcpu_unpause(v);
>  }
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 04/14] xen: arm: support for loading 64-bit zImage dom0
  2013-04-08 11:24   ` Stefano Stabellini
@ 2013-04-10 11:52     ` Ian Campbell
  2013-04-18 13:30       ` Stefano Stabellini
  0 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-04-10 11:52 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: Tim (Xen.org), xen-devel

On Mon, 2013-04-08 at 12:24 +0100, Stefano Stabellini wrote:
> On Tue, 12 Mar 2013, Ian Campbell wrote:
> > +static int kernel_try_zimage64_prepare(struct kernel_info *info,
> > +                                     paddr_t addr, paddr_t size)
> > +{

> this function doesn't seem very different from kernel_try_elf_prepare:
> do we really need two of them?

The 32- and 64-bit zImage formats are completely different, different
header fields/offsets different magic numbers etc. I thnk two functions
is the way to go.

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

* Re: [PATCH 13/14] xen: arm: handle 64-bit system register access traps.
  2013-04-08 13:11   ` Stefano Stabellini
@ 2013-04-10 11:52     ` Ian Campbell
  0 siblings, 0 replies; 34+ messages in thread
From: Ian Campbell @ 2013-04-10 11:52 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: Tim (Xen.org), xen-devel

On Mon, 2013-04-08 at 14:11 +0100, Stefano Stabellini wrote:
> On Tue, 12 Mar 2013, Ian Campbell wrote:
> > From: Ian Campbell <ian.campbell@citrix.com>
> > 
> > Wire up the vtimer handling to it.
> > 
> > Use a simplified version of the 32-bit cp-register macros to have convenient
> > decoding of HSR register values. (simplified because we don't need them for
> > passing to the assembler on 64-bit)
> > 
> > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> 
> 
> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> 
> assuming that you didn't make any mistakes in writing down thw new
> SYSREG #define

Yeah, lets assume that ;-)

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

* Re: [PATCH 02/14] xen: arm: tweak arm64 stack frame layout
  2013-04-08 13:31   ` Stefano Stabellini
@ 2013-04-10 11:57     ` Ian Campbell
  2013-04-11 16:50       ` Ian Campbell
  0 siblings, 1 reply; 34+ messages in thread
From: Ian Campbell @ 2013-04-10 11:57 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: Tim (Xen.org), xen-devel

On Mon, 2013-04-08 at 14:31 +0100, Stefano Stabellini wrote:
> On Tue, 12 Mar 2013, Ian Campbell wrote:
> > From: Ian Campbell <ian.campbell@citrix.com>
> > 
> > Correct definition of UREGS_kernel_sizeof and use it.
> > 
> > Correct adjustment of stack on entry and exit.
> > 
> > Add 64-bit versions of the build time checks for stack pointer alignment
> > correctness when pushing the stack frames.
> > 
> > Lastly, correct the padding in the stack frames to properly align the inner and
> > outer frames and also avoid an unnecessary 64bit padding field.
> > 
> > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> > ---
> >  xen/arch/arm/arm64/asm-offsets.c      |    2 +-
> >  xen/arch/arm/arm64/entry.S            |    9 +++++----
> >  xen/arch/arm/domain.c                 |    2 ++
> >  xen/arch/arm/traps.c                  |    7 +++++++
> >  xen/include/asm-arm/arm64/processor.h |    7 +++----
> >  5 files changed, 18 insertions(+), 9 deletions(-)
> > 
> > diff --git a/xen/arch/arm/arm64/asm-offsets.c b/xen/arch/arm/arm64/asm-offsets.c
> > index 7949e3e..7544082 100644
> > --- a/xen/arch/arm/arm64/asm-offsets.c
> > +++ b/xen/arch/arm/arm64/asm-offsets.c
> > @@ -39,7 +39,7 @@ void __dummy__(void)
> >     OFFSET(UREGS_SP_el1, struct cpu_user_regs, sp_el1);
> >     OFFSET(UREGS_ELR_el1, struct cpu_user_regs, elr_el1);
> >  
> > -   OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, cpsr);
> > +   OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, spsr_el1);
> >     DEFINE(UREGS_user_sizeof, sizeof(struct cpu_user_regs));
> >     BLANK();
> >  
> > diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
> > index 9d38088..a5fd608 100644
> > --- a/xen/arch/arm/arm64/entry.S
> > +++ b/xen/arch/arm/arm64/entry.S
> > @@ -34,7 +34,7 @@ lr      .req    x30             // link register
> >          mrs     x22, SP_el0
> >          str     x22, [x21]
> >  
> > -        add     x21, sp, #UREGS_ELR_el1
> > +        add     x21, sp, #UREGS_SP_el1
> >          mrs     x22, SP_el1
> >          mrs     x23, ELR_el1
> >          stp     x22, x23, [x21]
> 
> Honestly I think it would be much cleaner and easier to read if we saved
> sp_el1 and elr_el1 separately.

I think stp is supposed to be faster, but I'm running on a model so I'm
not sure. Also there are weird quadword alignment constraints on the
stack and stp is atomic from that PoV.

> 
> 
> > @@ -59,7 +59,7 @@ lr      .req    x30             // link register
> >   * Save state on entry to hypervisor
> >   */
> >          .macro  entry, hyp, compat
> > -        sub     sp, sp, #(UREGS_SPSR_el1 - UREGS_SP)
> > +        sub     sp, sp, #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */
> >          push    x28, x29
> >          push    x26, x27
> >          push    x24, x25
> > @@ -78,7 +78,7 @@ lr      .req    x30             // link register
> >  
> >          .if \hyp == 1        /* Hypervisor mode */
> >  
> > -        add     x21, sp, #(UREGS_X0 - UREGS_SP)
> > +        add     x21, sp, #UREGS_kernel_sizeof
> >  
> >          .else                /* Guest mode */
> >  
> > @@ -213,7 +213,8 @@ ENTRY(return_to_hypervisor)
> >          pop     x26, x27
> >          pop     x28, x29
> >  
> > -        ldr     lr, [sp], #(UREGS_SPSR_el1 - UREGS_SP)
> > +        ldr     lr, [sp], #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */
> > +
> >          eret
> >  
> >  /*
> > diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> > index f369871..08bb132 100644
> > --- a/xen/arch/arm/domain.c
> > +++ b/xen/arch/arm/domain.c
> > @@ -419,6 +419,8 @@ int vcpu_initialise(struct vcpu *v)
> >  {
> >      int rc = 0;
> >  
> > +    BUILD_BUG_ON( sizeof(struct cpu_info) > STACK_SIZE );
> > +
> >      v->arch.stack = alloc_xenheap_pages(STACK_ORDER, MEMF_node(vcpu_to_node(v)));
> >      if ( v->arch.stack == NULL )
> >          return -ENOMEM;
> > diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> > index a98a45e..6b19bc5 100644
> > --- a/xen/arch/arm/traps.c
> > +++ b/xen/arch/arm/traps.c
> > @@ -43,9 +43,16 @@
> >   * entry.S) and struct cpu_info (which lives at the bottom of a Xen
> >   * stack) must be doubleword-aligned in size.  */
> >  static inline void check_stack_alignment_constraints(void) {
> > +#ifdef CONFIG_ARM_64
> > +    BUILD_BUG_ON((sizeof (struct cpu_user_regs)) & 0xf);
> > +    BUILD_BUG_ON((offsetof(struct cpu_user_regs, spsr_el1)) & 0xf);
> > +    BUILD_BUG_ON((offsetof(struct cpu_user_regs, lr)) & 0xf);
> > +    BUILD_BUG_ON((sizeof (struct cpu_info)) & 0xf);
> 
> Why both spsr_el1 and lr?
> From the comment on top of check_stack_alignment_constraints I would
> think that only spsr_el1 is needed?

You are right spsr_el1 is needed to check the alignments of the
inner/outer frames.

The lr check is because I had a few problems getting the inner code
pushing working correctly, IIRC it relates to the use of stp (since you
need to make sure the pair are correctly aligned)

> 
> 
> > +#else
> >      BUILD_BUG_ON((sizeof (struct cpu_user_regs)) & 0x7);
> >      BUILD_BUG_ON((offsetof(struct cpu_user_regs, sp_usr)) & 0x7);
> >      BUILD_BUG_ON((sizeof (struct cpu_info)) & 0x7);
> > +#endif
> >  }
> >  
> >  static int debug_stack_lines = 20;
> > diff --git a/xen/include/asm-arm/arm64/processor.h b/xen/include/asm-arm/arm64/processor.h
> > index b4602fa..bf436c8 100644
> > --- a/xen/include/asm-arm/arm64/processor.h
> > +++ b/xen/include/asm-arm/arm64/processor.h
> > @@ -51,6 +51,7 @@ struct cpu_user_regs
> >      __DECL_REG(x27,          r11_fiq);
> >      __DECL_REG(x28,          r12_fiq);
> >      __DECL_REG(/* x29 */ fp, /* r13_fiq */ sp_fiq);
> > +
> >      __DECL_REG(/* x30 */ lr, /* r14_fiq */ lr_fiq);
> >  
> >      register_t sp; /* Valid for hypervisor frames */
> > @@ -59,7 +60,7 @@ struct cpu_user_regs
> >      __DECL_REG(pc,           pc32);             /* ELR_EL2 */
> >      uint32_t cpsr;                              /* SPSR_EL2 */
> >  
> > -    uint64_t pad0;
> > +    uint32_t pad0; /* Align end of kernel frame. */
> 
> That would be because cpsr is a uint32_t, right?

Right, I think.
> 
> 
> >      /* Outer guest frame only from here on... */
> >  
> > @@ -68,7 +69,7 @@ struct cpu_user_regs
> >          uint32_t spsr_svc;       /* AArch32 */
> >      };
> >  
> > -    uint32_t pad1; /* Align */
> > +    uint32_t pad1; /* Doubleword-align the user half of the frame */
> 
> This one is because of the preceding union of two uint32_t

Yup.

> 
> >      /* AArch32 guests only */
> >      uint32_t spsr_fiq, spsr_irq, spsr_und, spsr_abt;
> > @@ -76,8 +77,6 @@ struct cpu_user_regs
> >      /* AArch64 guests only */
> >      uint64_t sp_el0;
> >      uint64_t sp_el1, elr_el1;
> > -
> > -    uint64_t pad2; /* Doubleword-align the user half of the frame */
> >  };
> 
> of course padding with uint64_t is useless on arm (32 and 64)

Right.

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

* Re: [PATCH 08/14] xen: arm: support dumping 64-bit guest stack
  2013-04-08 17:29   ` Stefano Stabellini
@ 2013-04-10 11:59     ` Ian Campbell
  0 siblings, 0 replies; 34+ messages in thread
From: Ian Campbell @ 2013-04-10 11:59 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: Tim (Xen.org), xen-devel

On Mon, 2013-04-08 at 18:29 +0100, Stefano Stabellini wrote:
> On Tue, 12 Mar 2013, Ian Campbell wrote:
> > From: Ian Campbell <ian.campbell@citrix.com>
> > 
> > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> 
> it would be nice to support more guest modes but this is undoubtedly an improvement.

I implemented the one I needed to debug the issue I was facing at the
time ;-) Hopefully others will do the same...
> 
> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> 
> 
> >  xen/arch/arm/traps.c |   80 +++++++++++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 76 insertions(+), 4 deletions(-)
> > 
> > diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> > index 2f4e157..2671eba 100644
> > --- a/xen/arch/arm/traps.c
> > +++ b/xen/arch/arm/traps.c
> > @@ -523,9 +523,81 @@ void vcpu_show_registers(const struct vcpu *v)
> >      _show_registers(&v->arch.cpu_info->guest_cpu_user_regs, &ctxt, 1, v);
> >  }
> >  
> > -static void show_guest_stack(struct cpu_user_regs *regs)
> > +static void show_guest_stack(struct vcpu *v, struct cpu_user_regs *regs)
> >  {
> > -    printk("GUEST STACK GOES HERE\n");
> > +    int i;
> > +    vaddr_t sp;
> > +    paddr_t stack_phys;
> > +    void *mapped;
> > +    unsigned long *stack, addr;
> > +
> > +    switch ( regs->cpsr & PSR_MODE_MASK )
> > +    {
> > +    case PSR_MODE_USR:
> > +    case PSR_MODE_SYS:
> > +#ifdef CONFIG_ARM_64
> > +    case PSR_MODE_EL0t:
> > +#endif
> > +        printk("No stack trace for guest user-mode\n");
> > +        return;
> > +
> > +    case PSR_MODE_FIQ:
> > +    case PSR_MODE_IRQ:
> > +    case PSR_MODE_SVC:
> > +    case PSR_MODE_ABT:
> > +    case PSR_MODE_UND:
> > +        printk("No stack trace for 32-bit guest kernel-mode\n");
> > +        return;
> > +
> > +#ifdef CONFIG_ARM_64
> > +    case PSR_MODE_EL1t:
> > +        sp = regs->sp_el0;
> > +        break;
> > +    case PSR_MODE_EL1h:
> > +        sp = regs->sp_el1;
> > +        break;
> > +#endif
> > +
> > +    case PSR_MODE_HYP:
> > +    case PSR_MODE_MON:
> > +#ifdef CONFIG_ARM_64
> > +    case PSR_MODE_EL3h:
> > +    case PSR_MODE_EL3t:
> > +    case PSR_MODE_EL2h:
> > +    case PSR_MODE_EL2t:
> > +#endif
> > +    default:
> > +        BUG();
> > +        return;
> > +    }
> > +
> > +    printk("Guest stack trace from sp=%"PRIvaddr":\n  ", sp);
> > +
> > +    if ( gvirt_to_maddr(sp, &stack_phys) )
> > +    {
> > +        printk("Failed to convert stack to physical address\n");
> > +        return;
> > +    }
> > +
> > +    mapped = map_domain_page(stack_phys >> PAGE_SHIFT);
> > +
> > +    stack = mapped + (sp & ~PAGE_MASK);
> > +
> > +    for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
> > +    {
> > +        if ( (((long)stack - 1) ^ ((long)(stack + 1) - 1)) & PAGE_SIZE )
> > +            break;
> > +        addr = *stack;
> > +        if ( (i != 0) && ((i % stack_words_per_line) == 0) )
> > +            printk("\n  ");
> > +        printk(" %p", _p(addr));
> > +        stack++;
> > +    }
> > +    if ( i == 0 )
> > +        printk("Stack empty.");
> > +    printk("\n");
> > +    unmap_domain_page(mapped);
> > +
> >  }
> >  
> >  #define STACK_BEFORE_EXCEPTION(regs) ((register_t*)(regs)->sp)
> > @@ -589,7 +661,7 @@ void show_stack(struct cpu_user_regs *regs)
> >      int i;
> >  
> >      if ( guest_mode(regs) )
> > -        return show_guest_stack(regs);
> > +        return show_guest_stack(current, regs);
> >  
> >      printk("Xen stack trace from sp=%p:\n  ", stack);
> >  
> > @@ -631,7 +703,7 @@ void vcpu_show_execution_state(struct vcpu *v)
> >  
> >      vcpu_show_registers(v);
> >      if ( !usr_mode(&v->arch.cpu_info->guest_cpu_user_regs) )
> > -        show_guest_stack(&v->arch.cpu_info->guest_cpu_user_regs);
> > +        show_guest_stack(v, &v->arch.cpu_info->guest_cpu_user_regs);
> >  
> >      vcpu_unpause(v);
> >  }
> > -- 
> > 1.7.10.4
> > 

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

* Re: [PATCH 01/14] xen: arm: define 64-bit guest hypercall calling convention.
  2013-04-08 11:17   ` Stefano Stabellini
@ 2013-04-11  9:35     ` Ian Campbell
  0 siblings, 0 replies; 34+ messages in thread
From: Ian Campbell @ 2013-04-11  9:35 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: Tim (Xen.org), xen-devel

On Mon, 2013-04-08 at 12:17 +0100, Stefano Stabellini wrote:
> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Thanks, applied.

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

* Re: [PATCH 02/14] xen: arm: tweak arm64 stack frame layout
  2013-04-10 11:57     ` Ian Campbell
@ 2013-04-11 16:50       ` Ian Campbell
  0 siblings, 0 replies; 34+ messages in thread
From: Ian Campbell @ 2013-04-11 16:50 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: Tim (Xen.org), xen-devel

On Wed, 2013-04-10 at 12:57 +0100, Ian Campbell wrote:
> On Mon, 2013-04-08 at 14:31 +0100, Stefano Stabellini wrote:
> > On Tue, 12 Mar 2013, Ian Campbell wrote:
> > > From: Ian Campbell <ian.campbell@citrix.com>
> > > 
> > > Correct definition of UREGS_kernel_sizeof and use it.
> > > 
> > > Correct adjustment of stack on entry and exit.
> > > 
> > > Add 64-bit versions of the build time checks for stack pointer alignment
> > > correctness when pushing the stack frames.
> > > 
> > > Lastly, correct the padding in the stack frames to properly align the inner and
> > > outer frames and also avoid an unnecessary 64bit padding field.
> > > 
> > > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> > > ---
> > >  xen/arch/arm/arm64/asm-offsets.c      |    2 +-
> > >  xen/arch/arm/arm64/entry.S            |    9 +++++----
> > >  xen/arch/arm/domain.c                 |    2 ++
> > >  xen/arch/arm/traps.c                  |    7 +++++++
> > >  xen/include/asm-arm/arm64/processor.h |    7 +++----
> > >  5 files changed, 18 insertions(+), 9 deletions(-)
> > > 
> > > diff --git a/xen/arch/arm/arm64/asm-offsets.c b/xen/arch/arm/arm64/asm-offsets.c
> > > index 7949e3e..7544082 100644
> > > --- a/xen/arch/arm/arm64/asm-offsets.c
> > > +++ b/xen/arch/arm/arm64/asm-offsets.c
> > > @@ -39,7 +39,7 @@ void __dummy__(void)
> > >     OFFSET(UREGS_SP_el1, struct cpu_user_regs, sp_el1);
> > >     OFFSET(UREGS_ELR_el1, struct cpu_user_regs, elr_el1);
> > >  
> > > -   OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, cpsr);
> > > +   OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, spsr_el1);
> > >     DEFINE(UREGS_user_sizeof, sizeof(struct cpu_user_regs));
> > >     BLANK();
> > >  
> > > diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
> > > index 9d38088..a5fd608 100644
> > > --- a/xen/arch/arm/arm64/entry.S
> > > +++ b/xen/arch/arm/arm64/entry.S
> > > @@ -34,7 +34,7 @@ lr      .req    x30             // link register
> > >          mrs     x22, SP_el0
> > >          str     x22, [x21]
> > >  
> > > -        add     x21, sp, #UREGS_ELR_el1
> > > +        add     x21, sp, #UREGS_SP_el1
> > >          mrs     x22, SP_el1
> > >          mrs     x23, ELR_el1
> > >          stp     x22, x23, [x21]
> > 
> > Honestly I think it would be much cleaner and easier to read if we saved
> > sp_el1 and elr_el1 separately.
> 
> I think stp is supposed to be faster, but I'm running on a model so I'm
> not sure. Also there are weird quadword alignment constraints on the

By "weird" I really mean "double", i.e. sp must always be 16 byte
aligned.

> stack and stp is atomic from that PoV.

Actually we aren't actually changing sp in this particular code so that
doesn't really matter.

But because the UREGS_* constants here are too large for the immediate
of a str or stp we need to precalculate the offset, the choices are smth
like:
	add x21, sp, #UREGS_ELR_el1
	mrs x22, ELR_el1
	str x22, [x21]
	add x21, sp, #UREGS_SP_el1
	mrs x22, SP_el1
	str x22, [x21]
which is certainly clearer but does two adds (an extra arith
instruction) and an extra str for two extra instructions on a hot path.
So its worse even if stp had no actual benefit from doing a 16 byte
store instead of 2*8 bytes, and I'm pretty sure stp will turn out to
have such benefits. (yes, we could use different registers for the two
sets of adds+stores and arrange for better pipelining etc, but still).

The other option is:
	add	x21, sp, #UREGS_SP_el1
        mrs     x22, SP_el1
        mrs     x23, ELR_el1
        str     x22, [x21]
 	str	x23, [x21,#8]
which avoids the extra add but still has the extra str and the #8 offset
on the second one is about as opaque as the stp thing IMHO, so it's
slower for no gain in readability.

I think what we have now (the store pair) is the best option.

Ian.

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

* Re: [PATCH 04/14] xen: arm: support for loading 64-bit zImage dom0
  2013-04-10 11:52     ` Ian Campbell
@ 2013-04-18 13:30       ` Stefano Stabellini
  0 siblings, 0 replies; 34+ messages in thread
From: Stefano Stabellini @ 2013-04-18 13:30 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, Tim (Xen.org), Stefano Stabellini

On Wed, 10 Apr 2013, Ian Campbell wrote:
> On Mon, 2013-04-08 at 12:24 +0100, Stefano Stabellini wrote:
> > On Tue, 12 Mar 2013, Ian Campbell wrote:
> > > +static int kernel_try_zimage64_prepare(struct kernel_info *info,
> > > +                                     paddr_t addr, paddr_t size)
> > > +{
> 
> > this function doesn't seem very different from kernel_try_elf_prepare:
> > do we really need two of them?
> 
> The 32- and 64-bit zImage formats are completely different, different
> header fields/offsets different magic numbers etc. I thnk two functions
> is the way to go.

OK

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

end of thread, other threads:[~2013-04-18 13:30 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-12 14:53 [PATCH 00/14] xen: arm: 64-bit dom0 kernel support Ian Campbell
2013-03-12 15:03 ` Ian Campbell
2013-03-12 15:48 ` [PATCH 01/14] xen: arm: define 64-bit guest hypercall calling convention Ian Campbell
2013-04-08 11:17   ` Stefano Stabellini
2013-04-11  9:35     ` Ian Campbell
2013-03-12 15:48 ` [PATCH 02/14] xen: arm: tweak arm64 stack frame layout Ian Campbell
2013-04-08 13:31   ` Stefano Stabellini
2013-04-10 11:57     ` Ian Campbell
2013-04-11 16:50       ` Ian Campbell
2013-03-12 15:48 ` [PATCH 03/14] xen: arm: rename 32-bit specific zImage field offset constants Ian Campbell
2013-03-12 15:48 ` [PATCH 04/14] xen: arm: support for loading 64-bit zImage dom0 Ian Campbell
2013-04-08 11:24   ` Stefano Stabellini
2013-04-10 11:52     ` Ian Campbell
2013-04-18 13:30       ` Stefano Stabellini
2013-03-12 15:48 ` [PATCH 05/14] xen: arm: support building a 64-bit dom0 domain Ian Campbell
2013-04-08 11:25   ` Stefano Stabellini
2013-03-12 15:48 ` [PATCH 06/14] xen: arm: precalculate VTTBR_EL2 for a domain when setting up its p2m Ian Campbell
2013-04-08 11:27   ` Stefano Stabellini
2013-03-12 15:48 ` [PATCH 07/14] xen: arm: improve register dump output for 64-bit guest (and more generally too) Ian Campbell
2013-03-12 15:48 ` [PATCH 08/14] xen: arm: support dumping 64-bit guest stack Ian Campbell
2013-04-08 17:29   ` Stefano Stabellini
2013-04-10 11:59     ` Ian Campbell
2013-03-12 15:48 ` [PATCH 09/14] xen: arm: show less words in a line of a stack trace in 64-bit builds Ian Campbell
2013-04-08 13:46   ` Stefano Stabellini
2013-03-12 15:48 ` [PATCH 10/14] xen: arm: Set EL1 register width in HCR_EL2 during context switch Ian Campbell
2013-03-12 15:48 ` [PATCH 11/14] xen: arm: handle traps from 64-bit guests Ian Campbell
2013-04-08 13:45   ` Stefano Stabellini
2013-03-12 15:48 ` [PATCH 12/14] xen: arm: handle hypercalls " Ian Campbell
2013-04-08 11:43   ` Stefano Stabellini
2013-03-12 15:48 ` [PATCH 13/14] xen: arm: handle 64-bit system register access traps Ian Campbell
2013-04-08 13:11   ` Stefano Stabellini
2013-04-10 11:52     ` Ian Campbell
2013-03-12 15:48 ` [PATCH 14/14] xen: arm: align some comments Ian Campbell
2013-04-08 11:44   ` Stefano Stabellini

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.