Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 2/2] arm64: Work around broken .inst when defective gas is detected
From: Marc Zyngier @ 2016-12-06 15:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481038065-32153-1-git-send-email-marc.zyngier@arm.com>

.inst being largely broken with older binutils, it'd be better not
to emit it altogether when detecting such configuration (as it
leads to all kind of horrors when using alternatives).

Generalize the __emit_inst macro and use it extensively in
asm/sysreg.h, and make it generate a .long when a broken gas is
detected. The disassembly will be crap, but at least we can write
semi-sane code.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/sysreg.h | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 9e16a18..98ae03f 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -35,12 +35,33 @@
 #define sys_reg(op0, op1, crn, crm, op2) \
 	((((op0)&3)<<19)|((op1)<<16)|((crn)<<12)|((crm)<<8)|((op2)<<5))
 
+#ifndef CONFIG_BROKEN_GAS_INST
+
 #ifdef __ASSEMBLY__
 #define __emit_inst(x)			.inst (x)
 #else
 #define __emit_inst(x)			".inst " __stringify((x)) "\n\t"
 #endif
 
+#else  /* CONFIG_BROKEN_GAS_INST */
+
+#ifndef CONFIG_CPU_BIG_ENDIAN
+#define __INSTR_BSWAP(x)		(x)
+#else  /* CONFIG_CPU_BIG_ENDIAN */
+#define __INSTR_BSWAP(x)		((((x) << 24) & 0xff000000)	| \
+					 (((x) <<  8) & 0x00ff0000)	| \
+					 (((x) >>  8) & 0x0000ff00)	| \
+					 (((x) >> 24) & 0x000000ff))
+#endif	/* CONFIG_CPU_BIG_ENDIAN */
+
+#ifdef __ASSEMBLY__
+#define __emit_inst(x)			.long __INSTR_BSWAP(x)
+#else  /* __ASSEMBLY__ */
+#define __emit_inst(x)			".long " __stringify(__INSTR_BSWAP(x)) "\n\t"
+#endif	/* __ASSEMBLY__ */
+
+#endif	/* CONFIG_BROKEN_GAS_INST */
+
 #define SYS_MIDR_EL1			sys_reg(3, 0, 0, 0, 0)
 #define SYS_MPIDR_EL1			sys_reg(3, 0, 0, 0, 5)
 #define SYS_REVIDR_EL1			sys_reg(3, 0, 0, 0, 6)
@@ -232,11 +253,11 @@
 	.equ	.L__reg_num_xzr, 31
 
 	.macro	mrs_s, rt, sreg
-	.inst	0xd5200000|(\sreg)|(.L__reg_num_\rt)
+	 __emit_inst(0xd5200000|(\sreg)|(.L__reg_num_\rt))
 	.endm
 
 	.macro	msr_s, sreg, rt
-	.inst	0xd5000000|(\sreg)|(.L__reg_num_\rt)
+	__emit_inst(0xd5000000|(\sreg)|(.L__reg_num_\rt))
 	.endm
 
 #else
@@ -250,11 +271,11 @@ asm(
 "	.equ	.L__reg_num_xzr, 31\n"
 "\n"
 "	.macro	mrs_s, rt, sreg\n"
-"	.inst	0xd5200000|(\\sreg)|(.L__reg_num_\\rt)\n"
+	__emit_inst(0xd5200000|(\\sreg)|(.L__reg_num_\\rt))
 "	.endm\n"
 "\n"
 "	.macro	msr_s, sreg, rt\n"
-"	.inst	0xd5000000|(\\sreg)|(.L__reg_num_\\rt)\n"
+	__emit_inst(0xd5000000|(\\sreg)|(.L__reg_num_\\rt))
 "	.endm\n"
 );
 
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2] arm/arm64: xen: Move shared architecture headers to include/xen/arm
From: Marc Zyngier @ 2016-12-06 15:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481038065-32153-1-git-send-email-marc.zyngier@arm.com>

ARM and arm64 Xen ports share a number of headers, leading to
packaging issues when these headers needs to be exported, as it
breaks the reasonable requirement that an architecture port
has self-contained headers.

Fix the issue by moving the 5 header files to include/xen/arm,
and keep local placeholders to include the relevant files.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
* From v1:
  - Move offending include files to include/xen/arm

 arch/arm/include/asm/xen/hypercall.h               |  88 +--------------
 arch/arm/include/asm/xen/hypervisor.h              |  40 +------
 arch/arm/include/asm/xen/interface.h               |  86 +-------------
 arch/arm/include/asm/xen/page-coherent.h           |  99 +----------------
 arch/arm/include/asm/xen/page.h                    | 123 +--------------------
 arch/arm64/include/asm/xen/hypercall.h             |   2 +-
 arch/arm64/include/asm/xen/hypervisor.h            |   2 +-
 arch/arm64/include/asm/xen/interface.h             |   2 +-
 arch/arm64/include/asm/xen/page-coherent.h         |   2 +-
 arch/arm64/include/asm/xen/page.h                  |   2 +-
 .../asm/xen => include/xen/arm}/hypercall.h        |   0
 .../asm/xen => include/xen/arm}/hypervisor.h       |   0
 .../asm/xen => include/xen/arm}/interface.h        |   0
 .../asm/xen => include/xen/arm}/page-coherent.h    |   0
 .../arm/include/asm/xen => include/xen/arm}/page.h |   0
 15 files changed, 10 insertions(+), 436 deletions(-)
 copy {arch/arm/include/asm/xen => include/xen/arm}/hypercall.h (100%)
 copy {arch/arm/include/asm/xen => include/xen/arm}/hypervisor.h (100%)
 copy {arch/arm/include/asm/xen => include/xen/arm}/interface.h (100%)
 copy {arch/arm/include/asm/xen => include/xen/arm}/page-coherent.h (100%)
 copy {arch/arm/include/asm/xen => include/xen/arm}/page.h (100%)

diff --git a/arch/arm/include/asm/xen/hypercall.h b/arch/arm/include/asm/xen/hypercall.h
index 9d874db..3522cba 100644
--- a/arch/arm/include/asm/xen/hypercall.h
+++ b/arch/arm/include/asm/xen/hypercall.h
@@ -1,87 +1 @@
-/******************************************************************************
- * hypercall.h
- *
- * Linux-specific hypervisor handling.
- *
- * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation; or, when distributed
- * separately from the Linux kernel or incorporated into other
- * software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef _ASM_ARM_XEN_HYPERCALL_H
-#define _ASM_ARM_XEN_HYPERCALL_H
-
-#include <linux/bug.h>
-
-#include <xen/interface/xen.h>
-#include <xen/interface/sched.h>
-#include <xen/interface/platform.h>
-
-long privcmd_call(unsigned call, unsigned long a1,
-		unsigned long a2, unsigned long a3,
-		unsigned long a4, unsigned long a5);
-int HYPERVISOR_xen_version(int cmd, void *arg);
-int HYPERVISOR_console_io(int cmd, int count, char *str);
-int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
-int HYPERVISOR_sched_op(int cmd, void *arg);
-int HYPERVISOR_event_channel_op(int cmd, void *arg);
-unsigned long HYPERVISOR_hvm_op(int op, void *arg);
-int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
-int HYPERVISOR_physdev_op(int cmd, void *arg);
-int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args);
-int HYPERVISOR_tmem_op(void *arg);
-int HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type);
-int HYPERVISOR_platform_op_raw(void *arg);
-static inline int HYPERVISOR_platform_op(struct xen_platform_op *op)
-{
-	op->interface_version = XENPF_INTERFACE_VERSION;
-	return HYPERVISOR_platform_op_raw(op);
-}
-int HYPERVISOR_multicall(struct multicall_entry *calls, uint32_t nr);
-
-static inline int
-HYPERVISOR_suspend(unsigned long start_info_mfn)
-{
-	struct sched_shutdown r = { .reason = SHUTDOWN_suspend };
-
-	/* start_info_mfn is unused on ARM */
-	return HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
-}
-
-static inline void
-MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
-			unsigned int new_val, unsigned long flags)
-{
-	BUG();
-}
-
-static inline void
-MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req,
-		 int count, int *success_count, domid_t domid)
-{
-	BUG();
-}
-
-#endif /* _ASM_ARM_XEN_HYPERCALL_H */
+#include <xen/arm/hypercall.h>
diff --git a/arch/arm/include/asm/xen/hypervisor.h b/arch/arm/include/asm/xen/hypervisor.h
index 9525151..d6e7709 100644
--- a/arch/arm/include/asm/xen/hypervisor.h
+++ b/arch/arm/include/asm/xen/hypervisor.h
@@ -1,39 +1 @@
-#ifndef _ASM_ARM_XEN_HYPERVISOR_H
-#define _ASM_ARM_XEN_HYPERVISOR_H
-
-#include <linux/init.h>
-
-extern struct shared_info *HYPERVISOR_shared_info;
-extern struct start_info *xen_start_info;
-
-/* Lazy mode for batching updates / context switch */
-enum paravirt_lazy_mode {
-	PARAVIRT_LAZY_NONE,
-	PARAVIRT_LAZY_MMU,
-	PARAVIRT_LAZY_CPU,
-};
-
-static inline enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
-{
-	return PARAVIRT_LAZY_NONE;
-}
-
-extern struct dma_map_ops *xen_dma_ops;
-
-#ifdef CONFIG_XEN
-void __init xen_early_init(void);
-#else
-static inline void xen_early_init(void) { return; }
-#endif
-
-#ifdef CONFIG_HOTPLUG_CPU
-static inline void xen_arch_register_cpu(int num)
-{
-}
-
-static inline void xen_arch_unregister_cpu(int num)
-{
-}
-#endif
-
-#endif /* _ASM_ARM_XEN_HYPERVISOR_H */
+#include <xen/arm/hypervisor.h>
diff --git a/arch/arm/include/asm/xen/interface.h b/arch/arm/include/asm/xen/interface.h
index 75d5968..88c0d75 100644
--- a/arch/arm/include/asm/xen/interface.h
+++ b/arch/arm/include/asm/xen/interface.h
@@ -1,85 +1 @@
-/******************************************************************************
- * Guest OS interface to ARM Xen.
- *
- * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
- */
-
-#ifndef _ASM_ARM_XEN_INTERFACE_H
-#define _ASM_ARM_XEN_INTERFACE_H
-
-#include <linux/types.h>
-
-#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
-
-#define __DEFINE_GUEST_HANDLE(name, type) \
-	typedef struct { union { type *p; uint64_aligned_t q; }; }  \
-        __guest_handle_ ## name
-
-#define DEFINE_GUEST_HANDLE_STRUCT(name) \
-	__DEFINE_GUEST_HANDLE(name, struct name)
-#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
-#define GUEST_HANDLE(name)        __guest_handle_ ## name
-
-#define set_xen_guest_handle(hnd, val)			\
-	do {						\
-		if (sizeof(hnd) == 8)			\
-			*(uint64_t *)&(hnd) = 0;	\
-		(hnd).p = val;				\
-	} while (0)
-
-#define __HYPERVISOR_platform_op_raw __HYPERVISOR_platform_op
-
-#ifndef __ASSEMBLY__
-/* Explicitly size integers that represent pfns in the interface with
- * Xen so that we can have one ABI that works for 32 and 64 bit guests.
- * Note that this means that the xen_pfn_t type may be capable of
- * representing pfn's which the guest cannot represent in its own pfn
- * type. However since pfn space is controlled by the guest this is
- * fine since it simply wouldn't be able to create any sure pfns in
- * the first place.
- */
-typedef uint64_t xen_pfn_t;
-#define PRI_xen_pfn "llx"
-typedef uint64_t xen_ulong_t;
-#define PRI_xen_ulong "llx"
-typedef int64_t xen_long_t;
-#define PRI_xen_long "llx"
-/* Guest handles for primitive C types. */
-__DEFINE_GUEST_HANDLE(uchar, unsigned char);
-__DEFINE_GUEST_HANDLE(uint,  unsigned int);
-DEFINE_GUEST_HANDLE(char);
-DEFINE_GUEST_HANDLE(int);
-DEFINE_GUEST_HANDLE(void);
-DEFINE_GUEST_HANDLE(uint64_t);
-DEFINE_GUEST_HANDLE(uint32_t);
-DEFINE_GUEST_HANDLE(xen_pfn_t);
-DEFINE_GUEST_HANDLE(xen_ulong_t);
-
-/* Maximum number of virtual CPUs in multi-processor guests. */
-#define MAX_VIRT_CPUS 1
-
-struct arch_vcpu_info { };
-struct arch_shared_info { };
-
-/* TODO: Move pvclock definitions some place arch independent */
-struct pvclock_vcpu_time_info {
-	u32   version;
-	u32   pad0;
-	u64   tsc_timestamp;
-	u64   system_time;
-	u32   tsc_to_system_mul;
-	s8    tsc_shift;
-	u8    flags;
-	u8    pad[2];
-} __attribute__((__packed__)); /* 32 bytes */
-
-/* It is OK to have a 12 bytes struct with no padding because it is packed */
-struct pvclock_wall_clock {
-	u32   version;
-	u32   sec;
-	u32   nsec;
-	u32   sec_hi;
-} __attribute__((__packed__));
-#endif
-
-#endif /* _ASM_ARM_XEN_INTERFACE_H */
+#include <xen/arm/interface.h>
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
index 95ce6ac..b3ef061 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -1,98 +1 @@
-#ifndef _ASM_ARM_XEN_PAGE_COHERENT_H
-#define _ASM_ARM_XEN_PAGE_COHERENT_H
-
-#include <asm/page.h>
-#include <linux/dma-mapping.h>
-
-void __xen_dma_map_page(struct device *hwdev, struct page *page,
-	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, unsigned long attrs);
-void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir,
-		unsigned long attrs);
-void __xen_dma_sync_single_for_cpu(struct device *hwdev,
-		dma_addr_t handle, size_t size, enum dma_data_direction dir);
-
-void __xen_dma_sync_single_for_device(struct device *hwdev,
-		dma_addr_t handle, size_t size, enum dma_data_direction dir);
-
-static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
-		dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
-{
-	return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
-}
-
-static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
-		void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
-{
-	__generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
-}
-
-static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
-	     dma_addr_t dev_addr, unsigned long offset, size_t size,
-	     enum dma_data_direction dir, unsigned long attrs)
-{
-	unsigned long page_pfn = page_to_xen_pfn(page);
-	unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
-	unsigned long compound_pages =
-		(1<<compound_order(page)) * XEN_PFN_PER_PAGE;
-	bool local = (page_pfn <= dev_pfn) &&
-		(dev_pfn - page_pfn < compound_pages);
-
-	/*
-	 * Dom0 is mapped 1:1, while the Linux page can span across
-	 * multiple Xen pages, it's not possible for it to contain a
-	 * mix of local and foreign Xen pages. So if the first xen_pfn
-	 * == mfn the page is local otherwise it's a foreign page
-	 * grant-mapped in dom0. If the page is local we can safely
-	 * call the native dma_ops function, otherwise we call the xen
-	 * specific function.
-	 */
-	if (local)
-		__generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
-	else
-		__xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
-}
-
-static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
-		size_t size, enum dma_data_direction dir, unsigned long attrs)
-{
-	unsigned long pfn = PFN_DOWN(handle);
-	/*
-	 * Dom0 is mapped 1:1, while the Linux page can be spanned accross
-	 * multiple Xen page, it's not possible to have a mix of local and
-	 * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a
-	 * foreign mfn will always return false. If the page is local we can
-	 * safely call the native dma_ops function, otherwise we call the xen
-	 * specific function.
-	 */
-	if (pfn_valid(pfn)) {
-		if (__generic_dma_ops(hwdev)->unmap_page)
-			__generic_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs);
-	} else
-		__xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
-}
-
-static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
-		dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
-	unsigned long pfn = PFN_DOWN(handle);
-	if (pfn_valid(pfn)) {
-		if (__generic_dma_ops(hwdev)->sync_single_for_cpu)
-			__generic_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir);
-	} else
-		__xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
-}
-
-static inline void xen_dma_sync_single_for_device(struct device *hwdev,
-		dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
-	unsigned long pfn = PFN_DOWN(handle);
-	if (pfn_valid(pfn)) {
-		if (__generic_dma_ops(hwdev)->sync_single_for_device)
-			__generic_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir);
-	} else
-		__xen_dma_sync_single_for_device(hwdev, handle, size, dir);
-}
-
-#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */
+#include <xen/arm/page-coherent.h>
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 415dbc6..31bbc80 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -1,122 +1 @@
-#ifndef _ASM_ARM_XEN_PAGE_H
-#define _ASM_ARM_XEN_PAGE_H
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-#include <linux/pfn.h>
-#include <linux/types.h>
-#include <linux/dma-mapping.h>
-
-#include <xen/xen.h>
-#include <xen/interface/grant_table.h>
-
-#define phys_to_machine_mapping_valid(pfn) (1)
-
-/* Xen machine address */
-typedef struct xmaddr {
-	phys_addr_t maddr;
-} xmaddr_t;
-
-/* Xen pseudo-physical address */
-typedef struct xpaddr {
-	phys_addr_t paddr;
-} xpaddr_t;
-
-#define XMADDR(x)	((xmaddr_t) { .maddr = (x) })
-#define XPADDR(x)	((xpaddr_t) { .paddr = (x) })
-
-#define INVALID_P2M_ENTRY      (~0UL)
-
-/*
- * The pseudo-physical frame (pfn) used in all the helpers is always based
- * on Xen page granularity (i.e 4KB).
- *
- * A Linux page may be split across multiple non-contiguous Xen page so we
- * have to keep track with frame based on 4KB page granularity.
- *
- * PV drivers should never make a direct usage of those helpers (particularly
- * pfn_to_gfn and gfn_to_pfn).
- */
-
-unsigned long __pfn_to_mfn(unsigned long pfn);
-extern struct rb_root phys_to_mach;
-
-/* Pseudo-physical <-> Guest conversion */
-static inline unsigned long pfn_to_gfn(unsigned long pfn)
-{
-	return pfn;
-}
-
-static inline unsigned long gfn_to_pfn(unsigned long gfn)
-{
-	return gfn;
-}
-
-/* Pseudo-physical <-> BUS conversion */
-static inline unsigned long pfn_to_bfn(unsigned long pfn)
-{
-	unsigned long mfn;
-
-	if (phys_to_mach.rb_node != NULL) {
-		mfn = __pfn_to_mfn(pfn);
-		if (mfn != INVALID_P2M_ENTRY)
-			return mfn;
-	}
-
-	return pfn;
-}
-
-static inline unsigned long bfn_to_pfn(unsigned long bfn)
-{
-	return bfn;
-}
-
-#define bfn_to_local_pfn(bfn)	bfn_to_pfn(bfn)
-
-/* VIRT <-> GUEST conversion */
-#define virt_to_gfn(v)		(pfn_to_gfn(virt_to_phys(v) >> XEN_PAGE_SHIFT))
-#define gfn_to_virt(m)		(__va(gfn_to_pfn(m) << XEN_PAGE_SHIFT))
-
-/* Only used in PV code. But ARM guests are always HVM. */
-static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
-{
-	BUG();
-}
-
-/* TODO: this shouldn't be here but it is because the frontend drivers
- * are using it (its rolled in headers) even though we won't hit the code path.
- * So for right now just punt with this.
- */
-static inline pte_t *lookup_address(unsigned long address, unsigned int *level)
-{
-	BUG();
-	return NULL;
-}
-
-extern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
-				   struct gnttab_map_grant_ref *kmap_ops,
-				   struct page **pages, unsigned int count);
-
-extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
-				     struct gnttab_unmap_grant_ref *kunmap_ops,
-				     struct page **pages, unsigned int count);
-
-bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
-bool __set_phys_to_machine_multi(unsigned long pfn, unsigned long mfn,
-		unsigned long nr_pages);
-
-static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
-{
-	return __set_phys_to_machine(pfn, mfn);
-}
-
-#define xen_remap(cookie, size) ioremap_cache((cookie), (size))
-#define xen_unmap(cookie) iounmap((cookie))
-
-bool xen_arch_need_swiotlb(struct device *dev,
-			   phys_addr_t phys,
-			   dma_addr_t dev_addr);
-unsigned long xen_get_swiotlb_free_pages(unsigned int order);
-
-#endif /* _ASM_ARM_XEN_PAGE_H */
+#include <xen/arm/page.h>
diff --git a/arch/arm64/include/asm/xen/hypercall.h b/arch/arm64/include/asm/xen/hypercall.h
index 74b0c42..3522cba 100644
--- a/arch/arm64/include/asm/xen/hypercall.h
+++ b/arch/arm64/include/asm/xen/hypercall.h
@@ -1 +1 @@
-#include <../../arm/include/asm/xen/hypercall.h>
+#include <xen/arm/hypercall.h>
diff --git a/arch/arm64/include/asm/xen/hypervisor.h b/arch/arm64/include/asm/xen/hypervisor.h
index f263da8..d6e7709 100644
--- a/arch/arm64/include/asm/xen/hypervisor.h
+++ b/arch/arm64/include/asm/xen/hypervisor.h
@@ -1 +1 @@
-#include <../../arm/include/asm/xen/hypervisor.h>
+#include <xen/arm/hypervisor.h>
diff --git a/arch/arm64/include/asm/xen/interface.h b/arch/arm64/include/asm/xen/interface.h
index 44457ae..88c0d75 100644
--- a/arch/arm64/include/asm/xen/interface.h
+++ b/arch/arm64/include/asm/xen/interface.h
@@ -1 +1 @@
-#include <../../arm/include/asm/xen/interface.h>
+#include <xen/arm/interface.h>
diff --git a/arch/arm64/include/asm/xen/page-coherent.h b/arch/arm64/include/asm/xen/page-coherent.h
index 2052102..b3ef061 100644
--- a/arch/arm64/include/asm/xen/page-coherent.h
+++ b/arch/arm64/include/asm/xen/page-coherent.h
@@ -1 +1 @@
-#include <../../arm/include/asm/xen/page-coherent.h>
+#include <xen/arm/page-coherent.h>
diff --git a/arch/arm64/include/asm/xen/page.h b/arch/arm64/include/asm/xen/page.h
index bed87ec..31bbc80 100644
--- a/arch/arm64/include/asm/xen/page.h
+++ b/arch/arm64/include/asm/xen/page.h
@@ -1 +1 @@
-#include <../../arm/include/asm/xen/page.h>
+#include <xen/arm/page.h>
diff --git a/arch/arm/include/asm/xen/hypercall.h b/include/xen/arm/hypercall.h
similarity index 100%
copy from arch/arm/include/asm/xen/hypercall.h
copy to include/xen/arm/hypercall.h
diff --git a/arch/arm/include/asm/xen/hypervisor.h b/include/xen/arm/hypervisor.h
similarity index 100%
copy from arch/arm/include/asm/xen/hypervisor.h
copy to include/xen/arm/hypervisor.h
diff --git a/arch/arm/include/asm/xen/interface.h b/include/xen/arm/interface.h
similarity index 100%
copy from arch/arm/include/asm/xen/interface.h
copy to include/xen/arm/interface.h
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/include/xen/arm/page-coherent.h
similarity index 100%
copy from arch/arm/include/asm/xen/page-coherent.h
copy to include/xen/arm/page-coherent.h
diff --git a/arch/arm/include/asm/xen/page.h b/include/xen/arm/page.h
similarity index 100%
copy from arch/arm/include/asm/xen/page.h
copy to include/xen/arm/page.h
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2 1/2] arm64: Add detection code for broken .inst support in binutils
From: Marc Zyngier @ 2016-12-06 15:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481038065-32153-1-git-send-email-marc.zyngier@arm.com>

Binutils version up to (and including) 2.25 have a pathological
behaviour when it comes to mixing .inst directive and arithmetic
involving labels. The assembler complains about non-constant
expressions and compilation stops pretty quickly.

In order to detect this and work around it, let's add a bit of
detection code that will set the CONFIG_BROKEN_GAS_INST option
should a broken gas be detected.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/Makefile | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 3635b86..b9a4a93 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -37,10 +37,16 @@ $(warning LSE atomics not supported by binutils)
   endif
 endif
 
-KBUILD_CFLAGS	+= -mgeneral-regs-only $(lseinstr)
+brokengasinst := $(call as-instr,1:\n.inst 0\n.rept . - 1b\n\nnop\n.endr\n,,-DCONFIG_BROKEN_GAS_INST=1)
+
+ifneq ($(brokengasinst),)
+$(warning Detected assembler with broken .inst; disassembly will be unreliable)
+endif
+
+KBUILD_CFLAGS	+= -mgeneral-regs-only $(lseinstr) $(brokengasinst)
 KBUILD_CFLAGS	+= -fno-asynchronous-unwind-tables
 KBUILD_CFLAGS	+= $(call cc-option, -mpc-relative-literal-loads)
-KBUILD_AFLAGS	+= $(lseinstr)
+KBUILD_AFLAGS	+= $(lseinstr) $(brokengasinst)
 
 ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
 KBUILD_CPPFLAGS	+= -mbig-endian
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2 0/2] arm64: Fix fallout of asm/opcodes.h removal
From: Marc Zyngier @ 2016-12-06 15:27 UTC (permalink / raw)
  To: linux-arm-kernel

As part of the asm/opcodes.h removal, the SET_PSTATE_{PAN,UAO} macros
have been switch to using the .inst directive instead of .long (as
this has the advantage of providing a correct disassembly). This
had the side effect of bringing back an ugly gas bug that shows up
when .inst is used within alternative sequences.

This series works around the problem by:
- adding detection code for the broken binutils,
- work around the issue by falling back to .long when using a buggy
  assembler.

This has been tested with both binutils 2.25 (broken) and 2.27
(fixed), with both LE and BE builds.

Marc Zyngier (2):
  arm64: Add detection code for broken .inst support in binutils
  arm64: Work around broken .inst when defective gas is detected

 arch/arm64/Makefile             | 10 ++++++++--
 arch/arm64/include/asm/sysreg.h | 29 +++++++++++++++++++++++++----
 2 files changed, 33 insertions(+), 6 deletions(-)

-- 
2.1.4

^ permalink raw reply

* [PATCH v2] arm64: KVM: pmu: Reset PMSELR_EL0.SEL to a sane value before entering the guest
From: Will Deacon @ 2016-12-06 15:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1481036210-31816-1-git-send-email-marc.zyngier@arm.com>

On Tue, Dec 06, 2016 at 02:56:50PM +0000, Marc Zyngier wrote:
> The ARMv8 architecture allows the cycle counter to be configured
> by setting PMSELR_EL0.SEL==0x1f and then accessing PMXEVTYPER_EL0,
> hence accessing PMCCFILTR_EL0. But it disallows the use of
> PMSELR_EL0.SEL==0x1f to access the cycle counter itself through
> PMXEVCNTR_EL0.
> 
> Linux itself doesn't violate this rule, but we may end up with
> PMSELR_EL0.SEL being set to 0x1f when we enter a guest. If that
> guest accesses PMXEVCNTR_EL0, the access may UNDEF at EL1,
> despite the guest not having done anything wrong.
> 
> In order to avoid this unfortunate course of events (haha!), let's
> sanitize PMSELR_EL0 on guest entry. This ensures that the guest
> won't explode unexpectedly.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
> This is another approach to fix this issue, this time nuking PMSELR_EL0
> on guest entry instead of relying on perf not to clobber the register.
> 
> Tested on v4.9-rc8 with a Rev A3 X-Gene.
> 
>  arch/arm64/kvm/hyp/switch.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index 83037cd..3b7cfbd 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -85,7 +85,13 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
>  	write_sysreg(val, hcr_el2);
>  	/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
>  	write_sysreg(1 << 15, hstr_el2);
> -	/* Make sure we trap PMU access from EL0 to EL2 */
> +	/*
> +	 * Make sure we trap PMU access from EL0 to EL2. Also sanitize
> +	 * PMSELR_EL0 to make sure it never contains the cycle
> +	 * counter, which could make a PMXEVCNTR_EL0 access UNDEF.

"UNDEF at EL1, as opposed to trapping to EL2" might be clearer, but up to
you.

> +	 */
> +	if (vcpu->arch.mdcr_el2 & MDCR_EL2_HPMN_MASK)
> +		write_sysreg(0, pmselr_el0);
>  	write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);

Curious, but why do you check MDCR.HPMN for PMSELR_EL0, but not for
PMUSERENR_EL0?

Anyway:

Acked-by: Will Deacon <will.deacon@arm.com>

Thanks,

Will

^ permalink raw reply

* [PATCH 1/1] arm64: Correcting format specifier for printing 64 bit addresses
From: Catalin Marinas @ 2016-12-06 15:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161205112421.GB14058@arm.com>

On Mon, Dec 05, 2016 at 11:24:21AM +0000, Will Deacon wrote:
> On Mon, Dec 05, 2016 at 01:39:53PM +0530, Maninder Singh wrote:
> > This patch corrects format specifier for printing 64 bit addresses.
> > 
> > Signed-off-by: Maninder Singh <maninder1.s@samsung.com>
> > Signed-off-by: Vaneet Narang <v.narang@samsung.com>
> > ---
> >  arch/arm64/kernel/signal.c |  2 +-
> >  arch/arm64/kvm/sys_regs.c  |  8 ++++++--
> >  arch/arm64/mm/fault.c      | 15 ++++++++++-----
> >  arch/arm64/mm/mmu.c        |  4 ++--
> >  4 files changed, 19 insertions(+), 10 deletions(-)
> 
> Any reason not to fix kvm/trace.h too?

If the KVM guys are ok, I can fold the hunk below into this patch:

diff --git a/arch/arm64/kvm/trace.h b/arch/arm64/kvm/trace.h
index 7fb0008c4fa3..e117123d414b 100644
--- a/arch/arm64/kvm/trace.h
+++ b/arch/arm64/kvm/trace.h
@@ -20,7 +20,7 @@ TRACE_EVENT(kvm_wfx_arm64,
 		__entry->is_wfe  = is_wfe;
 	),
 
-	TP_printk("guest executed wf%c at: 0x%08lx",
+	TP_printk("guest executed wf%c at: 0x%016lx",
 		  __entry->is_wfe ? 'e' : 'i', __entry->vcpu_pc)
 );
 
@@ -40,7 +40,7 @@ TRACE_EVENT(kvm_hvc_arm64,
 		__entry->imm = imm;
 	),
 
-	TP_printk("HVC at 0x%08lx (r0: 0x%08lx, imm: 0x%lx)",
+	TP_printk("HVC at 0x%016lx (r0: 0x%016lx, imm: 0x%lx)",
 		  __entry->vcpu_pc, __entry->r0, __entry->imm)
 );
 
@@ -131,7 +131,7 @@ TRACE_EVENT(trap_reg,
 		__entry->write_value = write_value;
 	),
 
-	TP_printk("%s %s reg %d (0x%08llx)", __entry->fn,  __entry->is_write?"write to":"read from", __entry->reg, __entry->write_value)
+	TP_printk("%s %s reg %d (0x%016llx)", __entry->fn,  __entry->is_write?"write to":"read from", __entry->reg, __entry->write_value)
 );
 
 TRACE_EVENT(kvm_handle_sys_reg,

-- 
Catalin

^ permalink raw reply related

* Tearing down DMA transfer setup after DMA client has finished
From: Mason @ 2016-12-06 15:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <yw1xwpfd2o9f.fsf@unicorn.mansr.com>

On 06/12/2016 14:14, M?ns Rullg?rd wrote:

> Mason wrote:
> 
>> On 06/12/2016 06:12, Vinod Koul wrote:
>>
>>> On Tue, Nov 29, 2016 at 07:25:02PM +0100, Mason wrote:
>>>
>>>> Is there a way to write a driver within the existing framework?
>>>
>>> I think so, looking back at comments from Russell, I do tend to agree with
>>> that. Is there a specific reason why sbox can't be tied to alloc and free
>>> channels?
>>
>> Here's a recap of the situation.
>>
>> The "SBOX+MBUS" HW is used in several iterations of the tango SoC:
>>
>> tango3
>>   2 memory channels available
>>   6 devices ("clients"?) may request an MBUS channel
>>
>> tango4 (one more channel)
>>   3 memory channels available
>>   7 devices may request an MBUS channel :
>>     NFC0, NFC1, SATA0, SATA1, memcpy, (IDE0, IDE1)
>>
>> Notes:
>> The current NFC driver supports only one controller.
> 
> I consider that a bug.

Meh. The two controller blocks share the I/O pins to the outside
world, so it's not possible to have two concurrent accesses.
Moreover, the current NAND framework does not currently support
such a setup. (I discussed this with the maintainer.)


>> IDE is mostly obsolete at this point.
>>
>> tango5 (SATA gets own dedicated MBUS channel pair)
>>   3 memory channels available
>>   5 devices may request an MBUS channel :
>>     NFC0, NFC1, memcpy, (IDE0, IDE1)
> 
> Some of the chip variants can also use this DMA engine for PCI devices.

Note: PCI support was dropped with tango4.


>> If I understand the current DMA driver (written by Mans), client
>> drivers are instructed to use a specific channel in the DT, and
>> the DMA driver muxes access to that channel.
> 
> Almost.  The DT indicates the sbox ID of each device.  The driver
> multiplexes requests from all devices across all channels.

Thanks for pointing that out. I misremembered the DT.
So a client's DT node specifies the client's SBOX port.
And the DMA node specifies all available MBUS channels.

So when an interrupt fires, the DMA driver (re)uses that
channel for the next transfer in line?


>> The DMA driver manages a per-channel queue of outstanding DMA transfer
>> requests, and a new transfer is started from within the DMA ISR
>> (modulo the fact that the interrupt does not signal completion of the
>> transfer, as explained else-thread).
> 
> We need to somehow let the device driver signal the dma driver when a
> transfer has been fully completed.  Currently the only post-transfer
> interaction between the dma engine and the device driver is through the
> descriptor callback, which is not suitable for this purpose.

The callback is called from vchan_complete() right?
Is that running from interrupt context?

What's the relationship between vchan_complete() and
tangox_dma_irq() -- does one call the other? Are they
asynchronous?


> This is starting to look like one of those situations where someone just
> needs to implement a solution, or we'll be forever bickering about
> hypotheticals.

I can give that a shot (if you're busy with real work).


>> What you're proposing, Vinod, is to make a channel exclusive
>> to a driver, as long as the driver has not explicitly released
>> the channel, via dma_release_channel(), right?
> 
> That's not going to work very well.  Device drivers typically request
> dma channels in their probe functions or when the device is opened.
> This means that reserving one of the few channels there will inevitably
> make some other device fail to operate.

This is true for tango3. Less so for tango4. And no longer
an issue for tango5.


> Doing a request/release per transfer really doesn't fit with the
> intended usage of the dmaengine api.  For starters, what should a driver
> do if all the channels are currently busy?

Why can't we queue channel requests the same way we queue
transfer requests?


> Since the hardware actually does support multiplexing the dma channels,
> I think it would be misguided to deliberately cripple the software
> support in order to shoehorn it into an incomplete model of how hardware
> ought to work.  While I agree it would be nicer if all hardware actually
> did work that way, this isn't the reality we're living in.

I agree with you that it would be nice to have a general solution,
since the HW supports it.

Regards.

^ permalink raw reply

* [PATCH v11 7/7] arm: pmu: Add PMU definitions for cores not initially online
From: Will Deacon @ 2016-12-06 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480704961-6910-8-git-send-email-jeremy.linton@arm.com>

On Fri, Dec 02, 2016 at 12:56:01PM -0600, Jeremy Linton wrote:
> ACPI CPUs aren't associated with a PMU until they have been put
> online. This means that we potentially have to update a PMU
> definition the first time a CPU is hot added to the machine.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
>  drivers/perf/arm_pmu.c       | 38 ++++++++++++++++++++++++++++++++++++--
>  include/linux/perf/arm_pmu.h |  4 ++++
>  2 files changed, 40 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index fa40294..4abb2fe 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -711,6 +711,30 @@ static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler)
>  	return 0;
>  }
>  
> +static DEFINE_SPINLOCK(arm_pmu_resource_lock);

Why do you need this spinlock? The hotplug notifiers are serialised afaik,
and you don't take it anywhere else.

Will

^ permalink raw reply

* [PATCH v4 6/7] IIO: add STM32 timer trigger driver
From: Benjamin Gaignard @ 2016-12-06 15:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206131635.GJ25385@dell.home>

[snip]
>> +
>> +static const char * const triggers0[] = {
>> +     TIM1_TRGO, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4, NULL,
>> +};
>> +
>> +static const char * const triggers1[] = {
>> +     TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4, NULL,
>> +};
>> +
>> +static const char * const triggers2[] = {
>> +     TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4, NULL,
>> +};
>> +
>> +static const char * const triggers3[] = {
>> +     TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4, NULL,
>> +};
>> +
>> +static const char * const triggers4[] = {
>> +     TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4, NULL,
>> +};
>> +
>> +static const char * const triggers5[] = {
>> +     TIM6_TRGO, NULL,
>> +};
>> +
>> +static const char * const triggers6[] = {
>> +     TIM7_TRGO, NULL,
>> +};
>> +
>> +static const char * const triggers7[] = {
>> +     TIM8_TRGO, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4, NULL,
>> +};
>> +
>> +static const char * const triggers8[] = {
>> +     TIM9_TRGO, TIM9_CH1, TIM9_CH2, NULL,
>> +};
>> +
>> +static const char * const triggers9[] = {
>> +     TIM12_TRGO, TIM12_CH1, TIM12_CH2, NULL,
>> +};
>> +
>> +static const void *triggers_table[] = {
>> +     triggers0,
>> +     triggers1,
>> +     triggers2,
>> +     triggers3,
>> +     triggers4,
>> +     triggers5,
>> +     triggers6,
>> +     triggers7,
>> +     triggers8,
>> +     triggers9,
>> +};
>
> What about:
>
> static const char * const triggers[][] = {
>         { TIM1_TRGO, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4, NULL },
>         { TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4, NULL },
>         { TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4, NULL },
>         { TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4, NULL },
>         { TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4, NULL },
>         { TIM6_TRGO, NULL },
>         { TIM7_TRGO, NULL },
>         { TIM8_TRGO, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4, NULL },
>         { TIM9_TRGO, TIM9_CH1, TIM9_CH2, NULL },
>         { TIM12_TRGO, TIM12_CH1, TIM12_CH2, NULL }
> };

I can't because the second dimension of the array isn't fix.
I could have between 2 and 6 elements per row... to create a dual dimension
array I would have to add NULL entries like that:

#define MAX_TRIGGERS 6

static const void *triggers_table[][MAX_TRIGGERS] = {
{ TIM1_TRGO, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4, NULL,},
{ TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4, NULL,},
{ TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4, NULL,},
{ TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4, NULL,},
{ TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4, NULL,},
{ TIM6_TRGO, NULL,     NULL,     NULL,     NULL,     NULL,},
{ TIM7_TRGO, NULL,     NULL,     NULL,     NULL,     NULL,},
{ TIM8_TRGO, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4, NULL,},
{ TIM9_TRGO, TIM9_CH1, TIM9_CH2, NULL,     NULL,     NULL,},
{ TIM12_TRGO, TIM12_CH1, TIM12_CH2, NULL,  NULL,     NULL,},
};

>> +static const char * const valids0[] = {
>> +     TIM5_TRGO, TIM2_TRGO, TIM4_TRGO, TIM3_TRGO, NULL,
>> +};
>> +
>> +static const char * const valids1[] = {
>> +     TIM1_TRGO, TIM8_TRGO, TIM3_TRGO, TIM4_TRGO, NULL,
>> +};
>> +
>> +static const char * const valids2[] = {
>> +     TIM1_TRGO, TIM8_TRGO, TIM5_TRGO, TIM4_TRGO, NULL,
>> +};
>> +
>> +static const char * const valids3[] = {
>> +     TIM1_TRGO, TIM2_TRGO, TIM3_TRGO, TIM8_TRGO, NULL,
>> +};
>> +
>> +static const char *const valids4[] = {
>> +     TIM2_TRGO, TIM3_TRGO, TIM4_TRGO, TIM8_TRGO, NULL,
>> +};
>> +
>> +static const char * const valids7[] = {
>> +     TIM1_TRGO, TIM2_TRGO, TIM4_TRGO, TIM5_TRGO, NULL,
>> +};
>> +
>> +static const char * const valids8[] = {
>> +     TIM2_TRGO, TIM3_TRGO, NULL,
>> +};
>> +
>> +static const char * const valids9[] = {
>> +     TIM4_TRGO, TIM5_TRGO, NULL,
>> +};
>> +
>> +static const void *valids_table[] = {
>> +     valids0,
>> +     valids1,
>> +     valids2,
>> +     valids3,
>> +     valids4,
>> +     NULL,
>> +     NULL,
>> +     valids7,
>> +     valids8,
>> +     valids9,
>> +};
>
> Same here.
>
> --
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org ? Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH] ACPI/IORT: Make dma masks set-up IORT specific
From: Lorenzo Pieralisi @ 2016-12-06 15:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206132448.GA17255@8bytes.org>

On Tue, Dec 06, 2016 at 02:24:48PM +0100, Joerg Roedel wrote:
> Hi Lorenzo,
> 
> On Tue, Dec 06, 2016 at 09:37:10AM +0000, Lorenzo Pieralisi wrote:
> > I can apply Rafael and Hanjun's tags and resend a v2 to you if you
> > prefer, it would be great if you could apply this patch to your arm/smmu
> > branch for v4.10 as per description above, please let me know.
> 
> Yes, please collect all the tags and send me a v2 please. I'll apply it
> the right away.

Thank you very much, I have just sent it.

Thanks !
Lorenzo

^ permalink raw reply

* [PATCH] arm: MAINTAINERS: transfer maintainership for the EZX platform
From: Harald Welte @ 2016-12-06 15:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <87pol51cx8.fsf@belgarion.home>

On Tue, Dec 06, 2016 at 01:04:35PM +0100, Robert Jarzmik wrote:
> Daniel and Harald, could we have your acks please for [1] ?

Acked-By: Harald Welte <laforge@gnumonks.org>
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply

* [PATCH v2 2/3] ARM: dts: sunxi: add support for Orange Pi Zero board
From: Icenowy Zheng @ 2016-12-06 15:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206080056.23jpd4e7eeuhuyiq@lukather>



06.12.2016, 16:01, "Maxime Ripard" <maxime.ripard@free-electrons.com>:
> On Mon, Dec 05, 2016 at 07:01:46PM +0800, Icenowy Zheng wrote:
>> ?05.12.2016, 17:40, "Maxime Ripard" <maxime.ripard@free-electrons.com>:
>> ?> On Mon, Dec 05, 2016 at 04:59:44PM +0800, Icenowy Zheng wrote:
>> ?>> ?2016?12?5? 16:52? Maxime Ripard <maxime.ripard@free-electrons.com>???
>> ?>> ?>
>> ?>> ?> On Fri, Dec 02, 2016 at 10:22:30PM +0800, Icenowy Zheng wrote:
>> ?>> ?> >
>> ?>> ?> >
>> ?>> ?> > 01.12.2016, 17:36, "Maxime Ripard" <maxime.ripard@free-electrons.com>:
>> ?>> ?> > > On Mon, Nov 28, 2016 at 12:29:07AM +0000, Andr? Przywara wrote:
>> ?>> ?> > >> ?> Something more interesting happened.
>> ?>> ?> > >> ?>
>> ?>> ?> > >> ?> Xunlong made a add-on board for Orange Pi Zero, which exposes the
>> ?>> ?> > >> ?> two USB Controllers exported at expansion bus as USB Type-A
>> ?>> ?> > >> ?> connectors.
>> ?>> ?> > >> ?>
>> ?>> ?> > >> ?> Also it exposes a analog A/V jack and a microphone.
>> ?>> ?> > >> ?>
>> ?>> ?> > >> ?> Should I enable {e,o}hci{2.3} in the device tree?
>> ?>> ?> > >>
>> ?>> ?> > >> ?Actually we should do this regardless of this extension board. The USB
>> ?>> ?> > >> ?pins are not multiplexed and are exposed on user accessible pins (just
>> ?>> ?> > >> ?not soldered, but that's a detail), so I think they qualify for DT
>> ?>> ?> > >> ?enablement. And even if a user can't use them, it doesn't hurt to have
>> ?>> ?> > >> ?them (since they are not multiplexed).
>> ?>> ?> > >
>> ?>> ?> > > My main concern about this is that we'll leave regulators enabled by
>> ?>> ?> > > default, for a minority of users. And that minority will prevent to do
>> ?>> ?> > > a proper power management when the times come since we'll have to keep
>> ?>> ?> > > that behaviour forever.
>> ?>> ?> >
>> ?>> ?> > I think these users can add a 'fdt set /xxx/xxx status "disabled" ' .
>> ?>> ?>
>> ?>> ?> You can't ask that from the majority of users. These users will take
>> ?>> ?> debian or fedora, install it, and expect everything to work
>> ?>> ?> properly. I would make the opposite argument actually. If someone is
>> ?>> ?> knowledgeable enough to solder the USB pins a connector, then (s)he'll
>> ?>> ?> be able to make that u-boot call.
>> ?>>
>> ?>> ?Now (s)he do not need soldering.
>> ?>>
>> ?>> ?(S)he needs only paying $1.99 more to Xunlong to get the expansion
>> ?>> ?board, and insert it on the OPi Zero.
>> ?>
>> ?> Which is going to require an overlay anyway, so we could have the USB
>> ?> bits in there too.
>>
>> ?If so, I think the [PATCH -next v3 2/2] is ready to be merged ;-)
>
> I meant enabling the USB in the overlay, you enabled it in the base DT.

I enabled only usb1 in the base DT.

The USBs on the expansion board is usb2/3, and usb1 is an onboard USB connector.

It should of course be enabled ;-)

And to mention: this usb's Vbus is also directly connected to DCIN.

(There's no regulator at 5.0V on orange pi Zero)

>
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

^ permalink raw reply

* [PATCH 1/2] misc: atmel-ssc: register as sound DAI if #sound-dai-cells is present
From: Rob Herring @ 2016-12-06 15:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480593549-6464-2-git-send-email-peda@axentia.se>

On Thu, Dec 01, 2016 at 12:59:08PM +0100, Peter Rosin wrote:
> The SSC is currently not usable with the ASoC simple-audio-card, as
> every SSC audio user has to build a platform driver that may do as
> little as calling atmel_ssc_set_audio/atmel_ssc_put_audio (which
> allocates the SSC and registers a DAI with the ASoC subsystem).
> 
> So, have that happen automatically, if the #sound-dai-cells property
> is present in devicetree, which it has to be anyway for simple audio
> card to work.
> 
> Signed-off-by: Peter Rosin <peda@axentia.se>
> ---
>  .../devicetree/bindings/misc/atmel-ssc.txt         |  2 +

Acked-by: Rob Herring <robh@kernel.org>

>  drivers/misc/atmel-ssc.c                           | 50 ++++++++++++++++++++++
>  include/linux/atmel-ssc.h                          |  1 +
>  3 files changed, 53 insertions(+)

^ permalink raw reply

* [PATCH v3 1/2] ARM: dts: da850-lcdk: add the dumb-vga-dac node
From: Bartosz Golaszewski @ 2016-12-06 15:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <e6d7870b-e9fd-242f-0e74-5bae2d2b27f1@ti.com>

2016-12-06 16:03 GMT+01:00 Sekhar Nori <nsekhar@ti.com>:
> On Tuesday 06 December 2016 06:32 PM, Bartosz Golaszewski wrote:
>> 2016-12-05 13:49 GMT+01:00 Tomi Valkeinen <tomi.valkeinen@ti.com>:
>>> On 29/11/16 13:57, Bartosz Golaszewski wrote:
>>>> Add the dumb-vga-dac node to the board DT together with corresponding
>>>> ports and vga connector. This allows to retrieve the edid info from
>>>> the display automatically.
>>>>
>>>
>>> It's a bit difficult to follow this as there's been so many patches
>>> going around. But I take the above is the LCDC node in the base da850
>>> dtsi file? In that case, what is the display_in supposed to present?
>>> It's the first node in the "display chain", so it has no input.
>>>
>>> Also, don't touch da850.dtsi here, just add the "ports" node in the
>>> da850-lcdk.dts file.
>>>
>>> If the da850.dtsi has not been merged yet, I'd change the name of the
>>> lcdc node to something else than "display". It's rather vague. If it's
>>> named "lcdc", reading da850-lcdk.dts becomes much easier, as you'll
>>> refer to "lcdc".
>>>
>>
>> The node is already in Sekhar's branch.
>
> The node name should be 'display' as thats the ePAPR 1.1 generic name
> recommendation. The label is also set to 'display' though and that can
> be changed to lcdc.
>
> A pre-patch to fix that before we modify the node further is welcome.
>
> Thanks,
> Sekhar

I'll include this in v5 together with the change requested by Laurent.

Thanks,
Bartosz

^ permalink raw reply

* [PATCH v3 1/2] ARM: dts: da850-lcdk: add the dumb-vga-dac node
From: Sekhar Nori @ 2016-12-06 15:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAMpxmJUDyZmokJsf=RdP1DwzA_4Xc+Oh3SuSg_OenQOO5mqLvw@mail.gmail.com>

On Tuesday 06 December 2016 06:32 PM, Bartosz Golaszewski wrote:
> 2016-12-05 13:49 GMT+01:00 Tomi Valkeinen <tomi.valkeinen@ti.com>:
>> On 29/11/16 13:57, Bartosz Golaszewski wrote:
>>> Add the dumb-vga-dac node to the board DT together with corresponding
>>> ports and vga connector. This allows to retrieve the edid info from
>>> the display automatically.
>>>
>>
>> It's a bit difficult to follow this as there's been so many patches
>> going around. But I take the above is the LCDC node in the base da850
>> dtsi file? In that case, what is the display_in supposed to present?
>> It's the first node in the "display chain", so it has no input.
>>
>> Also, don't touch da850.dtsi here, just add the "ports" node in the
>> da850-lcdk.dts file.
>>
>> If the da850.dtsi has not been merged yet, I'd change the name of the
>> lcdc node to something else than "display". It's rather vague. If it's
>> named "lcdc", reading da850-lcdk.dts becomes much easier, as you'll
>> refer to "lcdc".
>>
> 
> The node is already in Sekhar's branch.

The node name should be 'display' as thats the ePAPR 1.1 generic name
recommendation. The label is also set to 'display' though and that can
be changed to lcdc.

A pre-patch to fix that before we modify the node further is welcome.

Thanks,
Sekhar

^ permalink raw reply

* [PATCH] ipmi: bt-bmc: Use a regmap for register access
From: Cédric Le Goater @ 2016-12-06 15:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206025715.2002-1-andrew@aj.id.au>

[ this is a resend bc of some mailing list issues] 

On 12/06/2016 03:57 AM, Andrew Jeffery wrote:
> The registers for the bt-bmc device live under the Aspeed LPC
> controller. Devicetree bindings have recently been introduced for the
> LPC controller where the "host" portion of the LPC register space is
> described as a syscon device. Future devicetrees describing the bt-bmc
> device should nest its node under the appropriate "simple-mfd", "syscon"
> compatible node.
> 
> This change allows the bt-bmc driver to function with both syscon and
> non-syscon- based devicetree descriptions by always using a regmap for
> register access, either retrieved from the parent syscon device or
> instantiated if none exists.
> 
> The patch has been tested on an OpenPOWER Palmetto machine, successfully
> booting, rebooting and powering down the host.
> 
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>

It would be nice to have an example of the associated binding. 
I did not see it. A part from that :

Reviewed-by: C?dric Le Goater <clg@kaod.org>

Thanks,

C.

> ---
>  drivers/char/ipmi/Kconfig  |  1 +
>  drivers/char/ipmi/bt-bmc.c | 82 ++++++++++++++++++++++++++++++++++------------
>  2 files changed, 62 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
> index 7f816655cbbf..b5d48d9af124 100644
> --- a/drivers/char/ipmi/Kconfig
> +++ b/drivers/char/ipmi/Kconfig
> @@ -79,6 +79,7 @@ endif # IPMI_HANDLER
>  
>  config ASPEED_BT_IPMI_BMC
>  	depends on ARCH_ASPEED
> +        depends on REGMAP && REGMAP_MMIO && MFD_SYSCON
>  	tristate "BT IPMI bmc driver"
>  	help
>  	  Provides a driver for the BT (Block Transfer) IPMI interface
> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> index fc9e8891eae3..ca1e20f6c6c5 100644
> --- a/drivers/char/ipmi/bt-bmc.c
> +++ b/drivers/char/ipmi/bt-bmc.c
> @@ -12,10 +12,13 @@
>  #include <linux/errno.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
> +#include <linux/mfd/syscon.h>
>  #include <linux/miscdevice.h>
>  #include <linux/module.h>
> +#include <linux/of.h>
>  #include <linux/platform_device.h>
>  #include <linux/poll.h>
> +#include <linux/regmap.h>
>  #include <linux/sched.h>
>  #include <linux/timer.h>
>  
> @@ -60,7 +63,8 @@
>  struct bt_bmc {
>  	struct device		dev;
>  	struct miscdevice	miscdev;
> -	void __iomem		*base;
> +	struct regmap		*map;
> +	int			offset;
>  	int			irq;
>  	wait_queue_head_t	queue;
>  	struct timer_list	poll_timer;
> @@ -69,14 +73,31 @@ struct bt_bmc {
>  
>  static atomic_t open_count = ATOMIC_INIT(0);
>  
> +static struct regmap_config bt_regmap_cfg = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +};
> +
>  static u8 bt_inb(struct bt_bmc *bt_bmc, int reg)
>  {
> -	return ioread8(bt_bmc->base + reg);
> +	uint32_t val = 0;
> +	int rc;
> +
> +	rc = regmap_read(bt_bmc->map, bt_bmc->offset + reg, &val);
> +	WARN(rc != 0, "%s:%d: regmap_read() failed: %d\n",
> +			__FILE__, __LINE__, rc);
> +
> +	return rc == 0 ? (u8) val : 0;
>  }
>  
>  static void bt_outb(struct bt_bmc *bt_bmc, u8 data, int reg)
>  {
> -	iowrite8(data, bt_bmc->base + reg);
> +	int rc;
> +
> +	rc = regmap_write(bt_bmc->map, bt_bmc->offset + reg, data);
> +	WARN(rc != 0, "%s:%d: regmap_write() failed: %d\n",
> +			__FILE__, __LINE__, rc);
>  }
>  
>  static void clr_rd_ptr(struct bt_bmc *bt_bmc)
> @@ -367,14 +388,18 @@ static irqreturn_t bt_bmc_irq(int irq, void *arg)
>  {
>  	struct bt_bmc *bt_bmc = arg;
>  	u32 reg;
> +	int rc;
> +
> +	rc = regmap_read(bt_bmc->map, bt_bmc->offset + BT_CR2, &reg);
> +	if (rc)
> +		return IRQ_NONE;
>  
> -	reg = ioread32(bt_bmc->base + BT_CR2);
>  	reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY;
>  	if (!reg)
>  		return IRQ_NONE;
>  
>  	/* ack pending IRQs */
> -	iowrite32(reg, bt_bmc->base + BT_CR2);
> +	regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR2, reg);
>  
>  	wake_up(&bt_bmc->queue);
>  	return IRQ_HANDLED;
> @@ -384,7 +409,6 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
>  			     struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> -	u32 reg;
>  	int rc;
>  
>  	bt_bmc->irq = platform_get_irq(pdev, 0);
> @@ -405,18 +429,17 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
>  	 * will be cleared (along with B2H) when we can write the next
>  	 * message to the BT buffer
>  	 */
> -	reg = ioread32(bt_bmc->base + BT_CR1);
> -	reg |= BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY;
> -	iowrite32(reg, bt_bmc->base + BT_CR1);
> +	rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + BT_CR1,
> +				(BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY),
> +				(BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY));
>  
> -	return 0;
> +	return rc;
>  }
>  
>  static int bt_bmc_probe(struct platform_device *pdev)
>  {
>  	struct bt_bmc *bt_bmc;
>  	struct device *dev;
> -	struct resource *res;
>  	int rc;
>  
>  	if (!pdev || !pdev->dev.of_node)
> @@ -431,10 +454,27 @@ static int bt_bmc_probe(struct platform_device *pdev)
>  
>  	dev_set_drvdata(&pdev->dev, bt_bmc);
>  
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	bt_bmc->base = devm_ioremap_resource(&pdev->dev, res);
> -	if (IS_ERR(bt_bmc->base))
> -		return PTR_ERR(bt_bmc->base);
> +	bt_bmc->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
> +	if (IS_ERR(bt_bmc->map)) {
> +		struct resource *res;
> +		void __iomem *base;
> +
> +		/*
> +		 * Assume it's not the MFD-based devicetree description, in
> +		 * which case generate a regmap ourselves
> +		 */
> +		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +		base = devm_ioremap_resource(&pdev->dev, res);
> +		if (IS_ERR(base))
> +			return PTR_ERR(base);
> +
> +		bt_bmc->map = devm_regmap_init_mmio(dev, base, &bt_regmap_cfg);
> +		bt_bmc->offset = 0;
> +	} else {
> +		rc = of_property_read_u32(dev->of_node, "reg", &bt_bmc->offset);
> +		if (rc)
> +			return rc;
> +	}
>  
>  	mutex_init(&bt_bmc->mutex);
>  	init_waitqueue_head(&bt_bmc->queue);
> @@ -461,12 +501,12 @@ static int bt_bmc_probe(struct platform_device *pdev)
>  		add_timer(&bt_bmc->poll_timer);
>  	}
>  
> -	iowrite32((BT_IO_BASE << BT_CR0_IO_BASE) |
> -		  (BT_IRQ << BT_CR0_IRQ) |
> -		  BT_CR0_EN_CLR_SLV_RDP |
> -		  BT_CR0_EN_CLR_SLV_WRP |
> -		  BT_CR0_ENABLE_IBT,
> -		  bt_bmc->base + BT_CR0);
> +	regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR0,
> +		     (BT_IO_BASE << BT_CR0_IO_BASE) |
> +		     (BT_IRQ << BT_CR0_IRQ) |
> +		     BT_CR0_EN_CLR_SLV_RDP |
> +		     BT_CR0_EN_CLR_SLV_WRP |
> +		     BT_CR0_ENABLE_IBT);
>  
>  	clr_b_busy(bt_bmc);
>  
> 

^ permalink raw reply

* [PATCH 00/16] FSI device driver introduction
From: christopher.lee.bostic at gmail.com @ 2016-12-06 15:01 UTC (permalink / raw)
  To: linux-arm-kernel

From: Chris Bostic <cbostic@us.ibm.com>

Introduction of the IBM 'Flexible Support Interface' (FSI) bus device
driver. FSI is a high fan out serial bus consisting of a clock and a serial
data line capable of running at speeds up to 166 MHz.

This set provides the basic framework to add FSI extensions to the
Linux bus and device models. Master specific implementations are
defined to utilize the core FSI function.

In Linux, we have a core FSI "bus type", along with drivers for FSI
masters and engines.

The FSI master drivers expose a read/write interface to the bus address
space. The master drivers are under drivers/fsi/fsi-master-*.c.

The core handles probing and discovery of slaves and slave
engines, using those read/write interfaces. It is responsible for
creating the endpoint Linux devices corresponding to the discovered
engines on each slave.

Slave engines are identified by an 'engine' type, and an optional
version. Engine, a.k.a. client, drivers are matched and bound to these
engines during discovery.

This patch set does not include extended FSI function such as:
    *  Hub master support
    *  Cascaded master support
    *  Application layer hot plug notification
    *  Application layer FSI bus status interface

Common FSI terminology:

* Master
    Controller of the FSI bus.  Only the master is allowed to control the
    clock line and is the initiator of all transactions on a bus.

* Slave
    The receiver or target of a master initiated transaction.  The slave
    cannot initiate communications on a bus and must respond to any
    master requests for data.

* CFAM
    Stands for Common Field replaceable unit Access Macro.  A CFAM is an
    ASIC residing in any device requiring FSI communications. CFAMs
    consist of an array of hardware 'engines' used for various purposes.
    I2C masters, UARTs, General Purpose IO hardware are common types of
    these engines.

* Configuration Space / Table
    A table contained at the beginning of each CFAM address space.
    This table lists information such as the CFAM's ID, which engine types
    and versions it has available, as well as its addressing range.

* FSI Engine driver
    A device driver that registers with the FSI core so that it can access
    devices it owns on an FSI bus.


Chris Bostic (5):
  drivers/fsi: Set up links for slave communication
  drivers/fsi: Set slave SMODE to init communication
  drivers/fsi: Add master unscan
  drivers/fsi: Add documentation for GPIO bindings
  drivers/fsi: Add GPIO based FSI master

Jeremy Kerr (11):
  drivers/fsi: Add empty fsi bus definitions
  drivers/fsi: Add device & driver definitions
  drivers/fsi: add driver to device matches
  drivers/fsi: Add fsi master definition
  drivers/fsi: Add fake master driver
  drivers/fsi: Add slave definition
  drivers/fsi: Add empty master scan
  drivers/fsi: Add crc4 helpers
  drivers/fsi: Implement slave initialisation
  drivers/fsi: scan slaves & register devices
  drivers/fsi: Add device read/write/peek functions

 .../devicetree/bindings/fsi/fsi-master-gpio.txt    |  21 +
 drivers/Kconfig                                    |   2 +
 drivers/Makefile                                   |   1 +
 drivers/fsi/Kconfig                                |  29 ++
 drivers/fsi/Makefile                               |   4 +
 drivers/fsi/fsi-core.c                             | 514 +++++++++++++++++++
 drivers/fsi/fsi-master-fake.c                      |  95 ++++
 drivers/fsi/fsi-master-gpio.c                      | 552 +++++++++++++++++++++
 drivers/fsi/fsi-master.h                           |  62 +++
 include/linux/fsi.h                                |  60 +++
 10 files changed, 1340 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt
 create mode 100644 drivers/fsi/Kconfig
 create mode 100644 drivers/fsi/Makefile
 create mode 100644 drivers/fsi/fsi-core.c
 create mode 100644 drivers/fsi/fsi-master-fake.c
 create mode 100644 drivers/fsi/fsi-master-gpio.c
 create mode 100644 drivers/fsi/fsi-master.h
 create mode 100644 include/linux/fsi.h

-- 
1.8.2.2

^ permalink raw reply

* [PATCH v2] arm64: KVM: pmu: Reset PMSELR_EL0.SEL to a sane value before entering the guest
From: Marc Zyngier @ 2016-12-06 14:56 UTC (permalink / raw)
  To: linux-arm-kernel

The ARMv8 architecture allows the cycle counter to be configured
by setting PMSELR_EL0.SEL==0x1f and then accessing PMXEVTYPER_EL0,
hence accessing PMCCFILTR_EL0. But it disallows the use of
PMSELR_EL0.SEL==0x1f to access the cycle counter itself through
PMXEVCNTR_EL0.

Linux itself doesn't violate this rule, but we may end up with
PMSELR_EL0.SEL being set to 0x1f when we enter a guest. If that
guest accesses PMXEVCNTR_EL0, the access may UNDEF at EL1,
despite the guest not having done anything wrong.

In order to avoid this unfortunate course of events (haha!), let's
sanitize PMSELR_EL0 on guest entry. This ensures that the guest
won't explode unexpectedly.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
This is another approach to fix this issue, this time nuking PMSELR_EL0
on guest entry instead of relying on perf not to clobber the register.

Tested on v4.9-rc8 with a Rev A3 X-Gene.

 arch/arm64/kvm/hyp/switch.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 83037cd..3b7cfbd 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -85,7 +85,13 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
 	write_sysreg(val, hcr_el2);
 	/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
 	write_sysreg(1 << 15, hstr_el2);
-	/* Make sure we trap PMU access from EL0 to EL2 */
+	/*
+	 * Make sure we trap PMU access from EL0 to EL2. Also sanitize
+	 * PMSELR_EL0 to make sure it never contains the cycle
+	 * counter, which could make a PMXEVCNTR_EL0 access UNDEF.
+	 */
+	if (vcpu->arch.mdcr_el2 & MDCR_EL2_HPMN_MASK)
+		write_sysreg(0, pmselr_el0);
 	write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);
 	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
 	__activate_traps_arch()();
-- 
2.1.4

^ permalink raw reply related

* [RFC PATCH 00/29] arm64: Scalable Vector Extension core support
From: Dave Martin @ 2016-12-06 14:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480977739.14990.250.camel@redhat.com>

On Mon, Dec 05, 2016 at 11:42:19PM +0100, Torvald Riegel wrote:

Hi there,

> On Wed, 2016-11-30 at 12:06 +0000, Dave Martin wrote:
> > So, my key goal is to support _per-process_ vector length control.
> > 
> > From the kernel perspective, it is easiest to achieve this by providing
> > per-thread control since that is the unit that context switching acts
> > on.
> > 
> > How useful it really is to have threads with different VLs in the same
> > process is an open question.  It's theoretically useful for runtime
> > environments, which may want to dispatch code optimised for different
> > VLs
> 
> What would be the primary use case(s)?  Vectorization of short vectors
> (eg, if having an array of structs or sth like that)?

I'm not sure exactly what you're asking here.

SVE supports a regular SIMD-type computational model, along with
scalable vectors and features for speculative vectorisation of loops
whose iteration count is not statically known (or, possibly not known
even at loop entry at runtime).  It's intended as a compiler target, so
any algorithm that involves iterative computation may get some benefit
-- though the amount of benefit, and how the benefit scales with vector
length, will depend on the algorithm in question.

So some algorithms may get more benefit more from large VLs than others.
For jobs where performance tends to saturate at a shorter VL, it may
make sense to get the compiler to compile for the shorter VL -- this
may enable the same binary code to perform more optimally on a wider
range of hardware, but that may also mean you want to run that job with
the VL it was compiled for instead of what the hardware
supports.

In high-assurance scenarios, you might also want to restrict a
particular job to run at the VL that you validated for.

> > -- changing the VL on-the-fly within a single thread is not
> > something I want to encourage, due to overhead and ABI issues, but
> > switching between threads of different VLs would be more manageable.
> 
> So if on-the-fly switching is probably not useful, that would mean we
> need special threads for the use cases.  Is that a realistic assumption
> for the use cases?  Or do you primarily want to keep it possible to do
> this, regardless of whether there are real use cases now?
> I suppose allowing for a per-thread setting of VL could also be added as
> a feature in the future without breaking existing code.

Per-thread VL use cases are hypothetical for now.

It's easy to support per-thread VLs in the kernel, but we could deny it
initially and wait for someone to come along with a concrete use case.

> > For setcontext/setjmp, we don't save/restore any SVE state due to the
> > caller-save status of SVE, and I would not consider it necessary to
> > save/restore VL itself because of the no-change-on-the-fly policy for
> > this.
> 
> Thus, you would basically consider VL changes or per-thread VL as in the
> realm of compilation internals?  So, the specific size for a particular
> piece of code would not be part of an ABI?

Basically yes.  For most people, this would be hidden in libc/ld.so/some
framework.  This goes for most prctl()s -- random user code shouldn't
normally touch them unless it knows what it's doing.

> > I'm not familiar with resumable functions/executors -- are these in
> > the C++ standards yet (not that that would cause me to be familiar
> > with them... ;)  Any implementation of coroutines (i.e.,
> > cooperative switching) is likely to fall under the "setcontext"
> > argument above.
> 
> These are not part of the C++ standard yet, but will appear in TSes.
> There are various features for which implementations would be assumed to
> use one OS thread for several tasks, coroutines, etc.  Some of them
> switch between these tasks or coroutines while these are running,

Is the switching ever preemptive?  If not, that these features are
unlikely to be a concern for SVE.  It's preemptive switching that would
require the saving of extra SVE state (which is why we need to care for
signals).

> whereas the ones that will be in C++17 only run more than parallel task
> on the same OS thread but one after the other (like in a thread pool).

If jobs are only run to completion before yielding, that again isn't a
concern for SVE.

> However, if we are careful not to expose VL or make promises about it,
> this may just end up being a detail similar to, say, register
> allocation, which isn't exposed beyond the internals of a particular
> compiler either.
> Exposing it as a feature the user can set without messing with the
> implementation would introduce additional thread-specific state, as
> Florian said.  This might not be a show-stopper by itself, but the more
> thread-specific state we have the more an implementation has to take
> care of or switch, and the higher the runtime costs are.  C++17 already
> makes weaker promises for TLS for parallel tasks, so that
> implementations don't have to run TLS constructors or destructors just
> because a small parallel task was executed.

There's a difference between a feature that exposed by the kernel, and
a feature endorsed by the language / runtime.

For example, random code can enable seccomp via prctl(PR_SET_SECCOMP)
-- this may make most of libc unsafe to use, because under strict
seccomp most syscalls simply kill the thread.  libc doesn't pretend to
support this out of the box, but this feature is also not needlessly
denied to user code that knows what it's doing.

I tend to put setting the VL into this category: it is safe, and
useful or even necessary to change the VL in some situations, but
userspace is responsible for managing this for itself.  The kernel
doesn't have enough information to make these decisions unilaterally.

Cheers
---Dave

^ permalink raw reply

* [PATCH 1/2] arm64: PMU: Do not use PMSELR_EL0 to access PMCCFILTR_EL0
From: Marc Zyngier @ 2016-12-06 14:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206135020.GI2498@arm.com>

On 06/12/16 13:50, Will Deacon wrote:
> On Fri, Dec 02, 2016 at 03:50:58PM +0000, Marc Zyngier wrote:
>> The ARMv8 architecture allows the cycle counter to be configured
>> by setting PMSELR_EL0.SEL==0x1f and then accessing PMXEVTYPER_EL0,
>> hence accessing PMCCFILTR_EL0. But it disallows the use of
>> PMSELR_EL0.SEL==0x1f to access the cycle counter itself through
>> PMXEVCNTR_EL0.
>>
>> Linux itself doesn't violate this rule, but we may end up with
>> PMSELR_EL0.SEL being set to 0x1f when we enter a guest. If that
>> guest accesses PMXEVCNTR_EL0, the access may UNDEF at EL1,
>> despite the guest not having done anything wrong.
>>
>> In order to avoid this unfortunate course of events (haha!), let's
>> apply the same method armv8pmu_write_counter and co are using,
>> explicitely checking for the cycle counter and writing to
>> PMCCFILTR_EL0 directly. This prevents writing 0x1f to PMSELR_EL0,
>> and saves a Linux guest an extra trap.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/kernel/perf_event.c | 5 ++++-
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>> index 57ae9d9..a65b757 100644
>> --- a/arch/arm64/kernel/perf_event.c
>> +++ b/arch/arm64/kernel/perf_event.c
>> @@ -632,7 +632,10 @@ static inline void armv8pmu_write_counter(struct perf_event *event, u32 value)
>>  
>>  static inline void armv8pmu_write_evtype(int idx, u32 val)
>>  {
>> -	if (armv8pmu_select_counter(idx) == idx) {
>> +	if (idx == ARMV8_IDX_CYCLE_COUNTER) {
>> +		val &= ARMV8_PMU_EVTYPE_MASK & ~ARMV8_PMU_EVTYPE_EVENT;
>> +		write_sysreg(val, pmccfiltr_el0);
>> +	} else if (armv8pmu_select_counter(idx) == idx) {
> 
> If we go down this route, then we also have to "fix" the 32-bit code,
> which uses PMSELR in a similar way. However, neither of the perf drivers
> are actually doing anything wrong here -- the problem comes about because
> the architecture doesn't guarantee that PMU accesses trap to EL2 unless
> both MDCR.TPM=1 *and* PMSELR_EL0 is valid. So I think that this should
> be handled together, in the KVM code that enables PMU traps.
> 
> Given that the perf callbacks tend to run with preemption disabled, I
> think you should be fine nuking PMSELR_EL0 to zero (i.e. no need to
> save/restore).

Fair enough. I'll respin another patch in a bit.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH] dts: sun8i-h3: correct UART3 pin definitions
From: Maxime Ripard @ 2016-12-06 14:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206142710.6450-1-jorik@kippendief.biz>

Hi Arnd, Olof,

On Tue, Dec 06, 2016 at 03:27:10PM +0100, jorik at kippendief.biz wrote:
> From: Jorik Jonker <jorik@kippendief.biz>
> 
> In a previous commit, I made a copy/paste error in the pinmux
> definitions of UART3: PG{13,14} instead of PA{13,14}. This commit takes
> care of that. I have tested this commit on Orange Pi PC and Orange Pi
> Plus, and it works for these boards.
> 
> Fixes: e3d11d3c45c5 ("dts: sun8i-h3: add pinmux definitions for
> UART2-3")
> 
> Signed-off-by: Jorik Jonker <jorik@kippendief.biz>

Could you please queue that patch for 4.9, with
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161206/3bdb1410/attachment-0001.sig>

^ permalink raw reply

* [PATCH v9 01/11] arm/arm64: vgic: Implement support for userspace access
From: Christoffer Dall @ 2016-12-06 14:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20c63256-48f7-692c-1c6c-c4fcdb82f401@redhat.com>

On Tue, Dec 06, 2016 at 12:42:09PM +0100, Auger Eric wrote:
> Hi,
> 
> On 28/11/2016 14:05, Christoffer Dall wrote:
> > On Wed, Nov 23, 2016 at 06:31:48PM +0530, vijay.kilari at gmail.com wrote:
> >> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> >>
> >> Read and write of some registers like ISPENDR and ICPENDR
> >> from userspace requires special handling when compared to
> >> guest access for these registers.
> >>
> >> Refer to Documentation/virtual/kvm/devices/arm-vgic-v3.txt
> >> for handling of ISPENDR, ICPENDR registers handling.
> >>
> >> Add infrastructure to support guest and userspace read
> >> and write for the required registers
> >> Also moved vgic_uaccess from vgic-mmio-v2.c to vgic-mmio.c
> >>
> >> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> >> ---
> >>  virt/kvm/arm/vgic/vgic-mmio-v2.c |  25 ----------
> >>  virt/kvm/arm/vgic/vgic-mmio-v3.c | 102 ++++++++++++++++++++++++++++++++-------
> >>  virt/kvm/arm/vgic/vgic-mmio.c    |  78 +++++++++++++++++++++++++++---
> >>  virt/kvm/arm/vgic/vgic-mmio.h    |  19 ++++++++
> >>  4 files changed, 175 insertions(+), 49 deletions(-)
> >>
> >> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c
> >> index b44b359..0b32f40 100644
> >> --- a/virt/kvm/arm/vgic/vgic-mmio-v2.c
> >> +++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c
> >> @@ -406,31 +406,6 @@ int vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
> >>  	return -ENXIO;
> >>  }
> >>  
> >> -/*
> >> - * When userland tries to access the VGIC register handlers, we need to
> >> - * create a usable struct vgic_io_device to be passed to the handlers and we
> >> - * have to set up a buffer similar to what would have happened if a guest MMIO
> >> - * access occurred, including doing endian conversions on BE systems.
> >> - */
> >> -static int vgic_uaccess(struct kvm_vcpu *vcpu, struct vgic_io_device *dev,
> >> -			bool is_write, int offset, u32 *val)
> >> -{
> >> -	unsigned int len = 4;
> >> -	u8 buf[4];
> >> -	int ret;
> >> -
> >> -	if (is_write) {
> >> -		vgic_data_host_to_mmio_bus(buf, len, *val);
> >> -		ret = kvm_io_gic_ops.write(vcpu, &dev->dev, offset, len, buf);
> >> -	} else {
> >> -		ret = kvm_io_gic_ops.read(vcpu, &dev->dev, offset, len, buf);
> >> -		if (!ret)
> >> -			*val = vgic_data_mmio_bus_to_host(buf, len);
> >> -	}
> >> -
> >> -	return ret;
> >> -}
> >> -
> >>  int vgic_v2_cpuif_uaccess(struct kvm_vcpu *vcpu, bool is_write,
> >>  			  int offset, u32 *val)
> >>  {
> >> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> >> index 50f42f0..8e76d04 100644
> >> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
> >> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> >> @@ -207,6 +207,66 @@ static unsigned long vgic_mmio_read_v3_idregs(struct kvm_vcpu *vcpu,
> >>  	return 0;
> >>  }
> >>  
> >> +static unsigned long vgic_v3_uaccess_read_pending(struct kvm_vcpu *vcpu,
> >> +						  gpa_t addr, unsigned int len)
> >> +{
> >> +	u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
> >> +	u32 value = 0;
> >> +	int i;
> >> +
> >> +	/*
> >> +	 * A level triggerred interrupt pending state is latched in both
> >> +	 * "soft_pending" and "line_level" variables. Userspace will save
> >> +	 * and restore soft_pending and line_level separately.
> >> +	 * Refer to Documentation/virtual/kvm/devices/arm-vgic-v3.txt
> >> +	 * handling of ISPENDR and ICPENDR.
> >> +	 */
> >> +	for (i = 0; i < len * 8; i++) {
> >> +		struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
> >> +
> >> +		if (irq->config == VGIC_CONFIG_LEVEL && irq->soft_pending)
> >> +			value |= (1U << i);
> >> +		if (irq->config == VGIC_CONFIG_EDGE && irq->pending)
> >> +			value |= (1U << i);
> >> +
> >> +		vgic_put_irq(vcpu->kvm, irq);
> >> +	}
> >> +
> >> +	return value;
> >> +}
> >> +
> >> +static void vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu,
> >> +					  gpa_t addr, unsigned int len,
> >> +					  unsigned long val)
> >> +{
> >> +	u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
> >> +	int i;
> >> +
> >> +	for (i = 0; i < len * 8; i++) {
> >> +		struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
> >> +
> >> +		spin_lock(&irq->irq_lock);
> >> +		if (test_bit(i, &val)) {
> >> +			/* soft_pending is set irrespective of irq type
> >> +			 * (level or edge) to avoid dependency that VM should
> >> +			 * restore irq config before pending info.
> >> +			 */
> > 
> > nit: kernel commenting style
> > 
> >> +			irq->pending = true;
> >> +			irq->soft_pending = true;
> >> +			vgic_queue_irq_unlock(vcpu->kvm, irq);
> >> +		} else {
> >> +			irq->soft_pending = false;
> >> +			if (irq->config == VGIC_CONFIG_EDGE ||
> >> +			    (irq->config == VGIC_CONFIG_LEVEL &&
> >> +			    !irq->line_level))
> >> +				irq->pending = false;
> I am confused by the comment above. Since we test the irq config here
> don't we assume the config was restored before the pending state?

THe idea here was that if you're setting the value, then if you later
set the config to level, then the soft_pending state has already been
set properly, and if the irq stays an edge, then it doesn't matter what
that field is.

If you read the value, the assumption is that you're reading a
consistently configured GIC, if not, then all bets are off anyhow.

Does that make sense?

Perhaps only the comment should be adjusted or do you think the logic is
flawed?

Thanks,
-Christoffer

^ permalink raw reply

* [PATCH 1/2] ARM: dts: sun8i: Specify memblock for Nano Pi M1
From: Milo Kim @ 2016-12-06 14:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161206140025.hnlhnsouvohxweou@lukather>

On 12/06/2016 11:00 PM, Maxime Ripard wrote:
> No, we need a recent U-Boot in order to boot, and such a uboot will
> setup the memory node anyway.

Got it. Thanks! Please just ignore my patches.

Best regards,
Milo

^ permalink raw reply

* [PATCH] dts: sun8i-h3: correct UART3 pin definitions
From: jorik at kippendief.biz @ 2016-12-06 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jorik Jonker <jorik@kippendief.biz>

In a previous commit, I made a copy/paste error in the pinmux
definitions of UART3: PG{13,14} instead of PA{13,14}. This commit takes
care of that. I have tested this commit on Orange Pi PC and Orange Pi
Plus, and it works for these boards.

Fixes: e3d11d3c45c5 ("dts: sun8i-h3: add pinmux definitions for
UART2-3")

Signed-off-by: Jorik Jonker <jorik@kippendief.biz>
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index 75a8654..f4ba088 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -410,7 +410,7 @@
 			};
 
 			uart3_pins: uart3 {
-				allwinner,pins = "PG13", "PG14";
+				allwinner,pins = "PA13", "PA14";
 				allwinner,function = "uart3";
 				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-- 
2.9.3

^ permalink raw reply related

* [PATCH v3] KVM: arm/arm64: Access CNTHCTL_EL2 bit fields correctly
From: Christoffer Dall @ 2016-12-06 14:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <b2623eed-fd63-c8c6-fd66-428bd87759d9@arm.com>

On Tue, Dec 06, 2016 at 01:09:26PM +0000, Marc Zyngier wrote:
> On 06/12/16 12:16, Christoffer Dall wrote:
> > On Tue, Dec 06, 2016 at 01:12:21PM +0100, Christoffer Dall wrote:
> >> On Tue, Dec 06, 2016 at 11:17:40AM +0000, Marc Zyngier wrote:
> >>> On 01/12/16 19:32, Jintack Lim wrote:
> >>>> Current KVM world switch code is unintentionally setting wrong bits to
> >>>> CNTHCTL_EL2 when E2H == 1, which may allow guest OS to access physical
> >>>> timer.  Bit positions of CNTHCTL_EL2 are changing depending on
> >>>> HCR_EL2.E2H bit.  EL1PCEN and EL1PCTEN are 1st and 0th bits when E2H is
> >>>> not set, but they are 11th and 10th bits respectively when E2H is set.
> >>>>
> >>>> In fact, on VHE we only need to set those bits once, not for every world
> >>>> switch. This is because the host kernel runs in EL2 with HCR_EL2.TGE ==
> >>>> 1, which makes those bits have no effect for the host kernel execution.
> >>>> So we just set those bits once for guests, and that's it.
> >>>>
> >>>> Signed-off-by: Jintack Lim <jintack@cs.columbia.edu>
> >>>> ---
> >>>> v2->v3: 
> >>>> - Perform the initialization including CPU hotplug case.
> >>>> - Move has_vhe() to asm/virt.h
> >>>>
> >>>> v1->v2: 
> >>>> - Skip configuring cnthctl_el2 in world switch path on VHE system.
> >>>> - Write patch based on linux-next.
> >>>> ---
> >>>>  arch/arm/include/asm/virt.h   |  5 +++++
> >>>>  arch/arm/kvm/arm.c            |  3 +++
> >>>>  arch/arm64/include/asm/virt.h | 10 ++++++++++
> >>>>  include/kvm/arm_arch_timer.h  |  1 +
> >>>>  virt/kvm/arm/arch_timer.c     | 23 +++++++++++++++++++++++
> >>>>  virt/kvm/arm/hyp/timer-sr.c   | 33 +++++++++++++++++++++------------
> >>>>  6 files changed, 63 insertions(+), 12 deletions(-)
> >>>>
> >>>> diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
> >>>> index a2e75b8..6dae195 100644
> >>>> --- a/arch/arm/include/asm/virt.h
> >>>> +++ b/arch/arm/include/asm/virt.h
> >>>> @@ -80,6 +80,11 @@ static inline bool is_kernel_in_hyp_mode(void)
> >>>>  	return false;
> >>>>  }
> >>>>  
> >>>> +static inline bool has_vhe(void)
> >>>> +{
> >>>> +	return false;
> >>>> +}
> >>>> +
> >>>>  /* The section containing the hypervisor idmap text */
> >>>>  extern char __hyp_idmap_text_start[];
> >>>>  extern char __hyp_idmap_text_end[];
> >>>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> >>>> index 8f92efa..13e54e8 100644
> >>>> --- a/arch/arm/kvm/arm.c
> >>>> +++ b/arch/arm/kvm/arm.c
> >>>> @@ -1099,6 +1099,9 @@ static void cpu_init_hyp_mode(void *dummy)
> >>>>  	__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr);
> >>>>  	__cpu_init_stage2();
> >>>>  
> >>>> +	if (is_kernel_in_hyp_mode())
> >>>> +		kvm_timer_init_vhe();
> >>>> +
> >>>>  	kvm_arm_init_debug();
> >>>>  }
> >>>>  
> >>>> diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
> >>>> index fea1073..b043cfd 100644
> >>>> --- a/arch/arm64/include/asm/virt.h
> >>>> +++ b/arch/arm64/include/asm/virt.h
> >>>> @@ -47,6 +47,7 @@
> >>>>  #include <asm/ptrace.h>
> >>>>  #include <asm/sections.h>
> >>>>  #include <asm/sysreg.h>
> >>>> +#include <asm/cpufeature.h>
> >>>>  
> >>>>  /*
> >>>>   * __boot_cpu_mode records what mode CPUs were booted in.
> >>>> @@ -80,6 +81,15 @@ static inline bool is_kernel_in_hyp_mode(void)
> >>>>  	return read_sysreg(CurrentEL) == CurrentEL_EL2;
> >>>>  }
> >>>>  
> >>>> +static inline bool has_vhe(void)
> >>>> +{
> >>>> +#ifdef CONFIG_ARM64_VHE
> >>>
> >>> Is there a particular reason why this should be guarded by a #ifdef? All
> >>> the symbols should always be available, and since this is a static key,
> >>> the overhead should be really insignificant (provided that you use a
> >>> non-prehistoric compiler...).
> >>>
> >>
> >> Isn't this code called from a file shared between 32-bit arm and arm64?
> >> Does the cpus_have_const_cap work on ARM64?
> > 
> > Duh, I meant on 32-bit arm of course.
> 
> Well, this is a pure 64bit file - 32bit has the canonical implementation
> that always returns false. So I can't really see how this can ever break
> 32bit. Unless my lack of sleep is really showing, and I'm missing
> something terribly obvious?
> 
No, I'm being an idiot, too many things at once and a lack of coffee.

-Christoffer

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox