Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 03/14] KVM: arm/arm64: Introduce kvm_arch_vcpu_run_pid_change
From: Marc Zyngier @ 2018-05-08  8:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525449935-31424-4-git-send-email-Dave.Martin@arm.com>

On 04/05/18 17:05, Dave Martin wrote:
> From: Christoffer Dall <christoffer.dall@linaro.org>
> 
> KVM/ARM differs from other architectures in having to maintain an
> additional virtual address space from that of the host and the
> guest, because we split the execution of KVM across both EL1 and
> EL2.
> 
> This results in a need to explicitly map data structures into EL2
> (hyp) which are accessed from the hyp code.  As we are about to be
> more clever with our FPSIMD handling on arm64, which stores data in
> the task struct and uses thread_info flags, we will have to map
> parts of the currently executing task struct into the EL2 virtual
> address space.
> 
> However, we don't want to do this on every KVM_RUN, because it is a
> fairly expensive operation to walk the page tables, and the common
> execution mode is to map a single thread to a VCPU.  By introducing
> a hook that architectures can select with
> HAVE_KVM_VCPU_RUN_PID_CHANGE, we do not introduce overhead for
> other architectures, but have a simple way to only map the data we
> need when required for arm64.
> 
> This patch introduces the framework only, and wires it up in the
> arm/arm64 KVM common code.
> 
> No functional change.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
> Signed-off-by: Dave Martin <Dave.Martin@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

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

^ permalink raw reply

* [PATCH v2 26/26] drm/bridge: establish a link between the bridge supplier and consumer
From: Andrzej Hajda @ 2018-05-08  9:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <9751c1c5-f2fa-f24e-64f3-71019f253332@axentia.se>

On 07.05.2018 15:43, Peter Rosin wrote:
> On 2018-05-07 14:59, Andrzej Hajda wrote:
>> On 04.05.2018 15:52, Peter Rosin wrote:
>>> If the bridge supplier is unbound, this will bring the bridge consumer
>>> down along with the bridge. Thus, there will no longer linger any
>>> dangling pointers from the bridge consumer (the drm_device) to some
>>> non-existent bridge supplier.
>> I understand rationales behind this patch, but it is another step into
>> making drm_dev one big driver with subcomponents, where drm will work
>> only if every subcomponent is working/loaded.
> The step is very small IMHO. Just a device-link, which is very easy to
> remove once whatever other solution is ready.
>
>>                                               Do we need to go this way?
> If the drivers expect the parts to be there, and there is no other safety
> net in place if they are not, what is the (short-term) alternative?
>
>> In case of many platforms such approach results in display turned on
>> very late on boot for example due to late initialization of some
>> regulator exposed by some i2c device, which is used by hdmi bridge. And
>> this hdmi bridge is just to provide alternative(rarely used) display
>> path, the main display path would work anyway.
> This patch does not contribute to any late init and any such delay is not
> affected by this. At all.
>
>> So the main question to drm maintainers is about evolution of bridges,
>> if drm_bridges should become mandatory components of drm device or they
>> could be added/removed dynamically?
> That is a much bigger question than this patch/series. Conflating the
> two is not fair IMHO. You could run this very same argument for every
> driver that gets added, since any additional driver will just make it
> harder to make everything dynamic. Should we stop development right
> away?
>
> Besides, as long as the drm devices are in fact acting as big static
> drivers (built from smaller parts), 

not true

> this should be considered a bug-fix
> that will prevent dereference of stale pointers.
>
> Or will some other solution appear and magically make all bridges and
> drm drivers capable of dynamic reconfiguration in the next few weeks?
> Yeah, right...

You are not changing single driver, you are changing framework and it
affects all the drivers using it, being more cautious about such patches
seems quite natural.

Anyway, I have realized that since drm_bridge_detach will remove the
link, so with properly written dynamic bridge removal, your patch should
not be a blocker.

Regards
Andrzej

>
> Cheers,
> Peter
>
>> Regards
>> Andrzej
>>
>>
>>> Signed-off-by: Peter Rosin <peda@axentia.se>
>>> ---
>>>  drivers/gpu/drm/drm_bridge.c | 18 ++++++++++++++++++
>>>  include/drm/drm_bridge.h     |  2 ++
>>>  2 files changed, 20 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
>>> index 78d186b6831b..0259f0a3ff27 100644
>>> --- a/drivers/gpu/drm/drm_bridge.c
>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>> @@ -26,6 +26,7 @@
>>>  #include <linux/mutex.h>
>>>  
>>>  #include <drm/drm_bridge.h>
>>> +#include <drm/drm_device.h>
>>>  #include <drm/drm_encoder.h>
>>>  
>>>  #include "drm_crtc_internal.h"
>>> @@ -127,12 +128,25 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
>>>  	if (bridge->dev)
>>>  		return -EBUSY;
>>>  
>>> +	if (encoder->dev->dev != bridge->odev) {
>>> +		bridge->link = device_link_add(encoder->dev->dev,
>>> +					       bridge->odev, 0);
>>> +		if (!bridge->link) {
>>> +			dev_err(bridge->odev, "failed to link bridge to %s\n",
>>> +				dev_name(encoder->dev->dev));
>>> +			return -EINVAL;
>>> +		}
>>> +	}
>>> +
>>>  	bridge->dev = encoder->dev;
>>>  	bridge->encoder = encoder;
>>>  
>>>  	if (bridge->funcs->attach) {
>>>  		ret = bridge->funcs->attach(bridge);
>>>  		if (ret < 0) {
>>> +			if (bridge->link)
>>> +				device_link_del(bridge->link);
>>> +			bridge->link = NULL;
>>>  			bridge->dev = NULL;
>>>  			bridge->encoder = NULL;
>>>  			return ret;
>>> @@ -159,6 +173,10 @@ void drm_bridge_detach(struct drm_bridge *bridge)
>>>  	if (bridge->funcs->detach)
>>>  		bridge->funcs->detach(bridge);
>>>  
>>> +	if (bridge->link)
>>> +		device_link_del(bridge->link);
>>> +	bridge->link = NULL;
>>> +
>>>  	bridge->dev = NULL;
>>>  }
>>>  
>>> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
>>> index b656e505d11e..804189c63a4c 100644
>>> --- a/include/drm/drm_bridge.h
>>> +++ b/include/drm/drm_bridge.h
>>> @@ -261,6 +261,7 @@ struct drm_bridge_timings {
>>>   * @list: to keep track of all added bridges
>>>   * @timings: the timing specification for the bridge, if any (may
>>>   * be NULL)
>>> + * @link: drm consumer <-> bridge supplier
>>>   * @funcs: control functions
>>>   * @driver_private: pointer to the bridge driver's internal context
>>>   */
>>> @@ -271,6 +272,7 @@ struct drm_bridge {
>>>  	struct drm_bridge *next;
>>>  	struct list_head list;
>>>  	const struct drm_bridge_timings *timings;
>>> +	struct device_link *link;
>>>  
>>>  	const struct drm_bridge_funcs *funcs;
>>>  	void *driver_private;
>>
>
>
>

^ permalink raw reply

* [PATCH v5 04/14] KVM: arm64: Convert lazy FPSIMD context switch trap to C
From: Marc Zyngier @ 2018-05-08  9:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525449935-31424-5-git-send-email-Dave.Martin@arm.com>

On 04/05/18 17:05, Dave Martin wrote:
> To make the lazy FPSIMD context switch trap code easier to hack on,
> this patch converts it to C.
> 
> This is not amazingly efficient, but the trap should typically only
> be taken once per host context switch.
> 
> Signed-off-by: Dave Martin <Dave.Martin@arm.com>

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

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

^ permalink raw reply

* [PATCH v5 05/14] arm64: fpsimd: Generalise context saving for non-task contexts
From: Marc Zyngier @ 2018-05-08  9:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525449935-31424-6-git-send-email-Dave.Martin@arm.com>

On 04/05/18 17:05, Dave Martin wrote:
> In preparation for allowing non-task (i.e., KVM vcpu) FPSIMD
> contexts to be handled by the fpsimd common code, this patch adapts
> task_fpsimd_save() to save back the currently loaded context,
> removing the explicit dependency on current.
> 
> The relevant storage to write back to in memory is now found by
> examining the fpsimd_last_state percpu struct.
> 
> fpsimd_save() does nothing unless TIF_FOREIGN_FPSTATE is clear, and
> fpsimd_last_state is updated under local_bh_disable() or
> local_irq_disable() everywhere that TIF_FOREIGN_FPSTATE is cleared:
> thus, fpsimd_save() will write back to the correct storage for the
> loaded context.
> 
> No functional change.
> 
> Signed-off-by: Dave Martin <Dave.Martin@arm.com>

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

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

^ permalink raw reply

* [PATCH] hwmon: (aspeed-pwm-tacho) Use 24MHz clock
From: Lei YU @ 2018-05-08  9:39 UTC (permalink / raw)
  To: linux-arm-kernel

The clock source for aspeed pwm is set to 24MHz, so use the hard-coded
clock frequency instead of the one in device tree.

Otherwise, in case of the clock specified in device tree is not 24MHz,
the fan speed will be incorrect.

Signed-off-by: Lei YU <mine260309@gmail.com>
---
 drivers/hwmon/aspeed-pwm-tacho.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/hwmon/aspeed-pwm-tacho.c b/drivers/hwmon/aspeed-pwm-tacho.c
index 693a3d5..e83b8df 100644
--- a/drivers/hwmon/aspeed-pwm-tacho.c
+++ b/drivers/hwmon/aspeed-pwm-tacho.c
@@ -922,7 +922,6 @@ static int aspeed_pwm_tacho_probe(struct platform_device *pdev)
 	void __iomem *regs;
 	struct resource *res;
 	struct device *hwmon;
-	struct clk *clk;
 	int ret;
 
 	np = dev->of_node;
@@ -956,12 +955,10 @@ static int aspeed_pwm_tacho_probe(struct platform_device *pdev)
 	regmap_write(priv->regmap, ASPEED_PTCR_TACH_SOURCE, 0);
 	regmap_write(priv->regmap, ASPEED_PTCR_TACH_SOURCE_EXT, 0);
 
-	clk = devm_clk_get(dev, NULL);
-	if (IS_ERR(clk))
-		return -ENODEV;
-	priv->clk_freq = clk_get_rate(clk);
 	aspeed_set_clock_enable(priv->regmap, true);
+	// The clock source is set to 24MHz
 	aspeed_set_clock_source(priv->regmap, 0);
+	priv->clk_freq = 24000000;
 
 	aspeed_create_type(priv);
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH 1/3] dma-debug: move initialization to common code
From: Robin Murphy @ 2018-05-08  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180424140235.9125-2-hch@lst.de>

On 24/04/18 15:02, Christoph Hellwig wrote:
> Most mainstream architectures are using 65536 entries, so lets stick to
> that.  If someone is really desperate to override it that can still be
> done through <asm/dma-mapping.h>, but I'd rather see a really good
> rationale for that.
> 
> dma_debug_init is now called as a core_initcall, which for many
> architectures means much earlier, and provides dma-debug functionality
> earlier in the boot process.  This should be safe as it only relies
> on the memory allocator already being available.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   arch/arm/mm/dma-mapping-nommu.c |  9 ---------
>   arch/arm/mm/dma-mapping.c       |  9 ---------
>   arch/arm64/mm/dma-mapping.c     | 10 ----------
>   arch/c6x/kernel/dma.c           | 11 -----------
>   arch/ia64/kernel/dma-mapping.c  | 10 ----------
>   arch/microblaze/kernel/dma.c    | 11 -----------
>   arch/mips/mm/dma-default.c      | 10 ----------
>   arch/openrisc/kernel/dma.c      | 11 -----------
>   arch/powerpc/kernel/dma.c       |  3 ---
>   arch/s390/pci/pci_dma.c         |  9 ---------
>   arch/sh/mm/consistent.c         |  9 ---------
>   arch/sparc/kernel/Makefile      |  2 --
>   arch/sparc/kernel/dma.c         | 13 -------------
>   arch/x86/kernel/pci-dma.c       |  4 ----
>   arch/xtensa/kernel/pci-dma.c    |  9 ---------
>   include/linux/dma-debug.h       |  6 ------
>   lib/dma-debug.c                 | 21 ++++++++++++++-------
>   17 files changed, 14 insertions(+), 143 deletions(-)
>   delete mode 100644 arch/sparc/kernel/dma.c
> 
> diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
> index 619f24a42d09..f448a0663b10 100644
> --- a/arch/arm/mm/dma-mapping-nommu.c
> +++ b/arch/arm/mm/dma-mapping-nommu.c
> @@ -241,12 +241,3 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>   void arch_teardown_dma_ops(struct device *dev)
>   {
>   }
> -
> -#define PREALLOC_DMA_DEBUG_ENTRIES	4096
> -
> -static int __init dma_debug_do_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -core_initcall(dma_debug_do_init);
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 8c398fedbbb6..c26bf83f44ca 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1165,15 +1165,6 @@ int arm_dma_supported(struct device *dev, u64 mask)
>   	return __dma_supported(dev, mask, false);
>   }
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES	4096
> -
> -static int __init dma_debug_do_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -core_initcall(dma_debug_do_init);
> -
>   #ifdef CONFIG_ARM_DMA_USE_IOMMU
>   
>   static int __dma_info_to_prot(enum dma_data_direction dir, unsigned long attrs)
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index a96ec0181818..db01f2709842 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -508,16 +508,6 @@ static int __init arm64_dma_init(void)
>   }
>   arch_initcall(arm64_dma_init);
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES	4096
> -
> -static int __init dma_debug_do_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -fs_initcall(dma_debug_do_init);
> -
> -
>   #ifdef CONFIG_IOMMU_DMA
>   #include <linux/dma-iommu.h>
>   #include <linux/platform_device.h>
> diff --git a/arch/c6x/kernel/dma.c b/arch/c6x/kernel/dma.c
> index 9fff8be75f58..31e1a9ec3a9c 100644
> --- a/arch/c6x/kernel/dma.c
> +++ b/arch/c6x/kernel/dma.c
> @@ -136,14 +136,3 @@ const struct dma_map_ops c6x_dma_ops = {
>   	.sync_sg_for_cpu	= c6x_dma_sync_sg_for_cpu,
>   };
>   EXPORT_SYMBOL(c6x_dma_ops);
> -
> -/* Number of entries preallocated for DMA-API debugging */
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -
> -	return 0;
> -}
> -fs_initcall(dma_init);
> diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c
> index f2d57e66fd86..7a471d8d67d4 100644
> --- a/arch/ia64/kernel/dma-mapping.c
> +++ b/arch/ia64/kernel/dma-mapping.c
> @@ -9,16 +9,6 @@ int iommu_detected __read_mostly;
>   const struct dma_map_ops *dma_ops;
>   EXPORT_SYMBOL(dma_ops);
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -
> -	return 0;
> -}
> -fs_initcall(dma_init);
> -
>   const struct dma_map_ops *dma_get_ops(struct device *dev)
>   {
>   	return dma_ops;
> diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
> index c91e8cef98dd..3145e7dc8ab1 100644
> --- a/arch/microblaze/kernel/dma.c
> +++ b/arch/microblaze/kernel/dma.c
> @@ -184,14 +184,3 @@ const struct dma_map_ops dma_nommu_ops = {
>   	.sync_sg_for_device	= dma_nommu_sync_sg_for_device,
>   };
>   EXPORT_SYMBOL(dma_nommu_ops);
> -
> -/* Number of entries preallocated for DMA-API debugging */
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -
> -	return 0;
> -}
> -fs_initcall(dma_init);
> diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
> index dcafa43613b6..f9fef0028ca2 100644
> --- a/arch/mips/mm/dma-default.c
> +++ b/arch/mips/mm/dma-default.c
> @@ -402,13 +402,3 @@ static const struct dma_map_ops mips_default_dma_map_ops = {
>   
>   const struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops;
>   EXPORT_SYMBOL(mips_dma_map_ops);
> -
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init mips_dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -
> -	return 0;
> -}
> -fs_initcall(mips_dma_init);
> diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
> index a945f00011b4..ec7fd45704d2 100644
> --- a/arch/openrisc/kernel/dma.c
> +++ b/arch/openrisc/kernel/dma.c
> @@ -247,14 +247,3 @@ const struct dma_map_ops or1k_dma_map_ops = {
>   	.sync_single_for_device = or1k_sync_single_for_device,
>   };
>   EXPORT_SYMBOL(or1k_dma_map_ops);
> -
> -/* Number of entries preallocated for DMA-API debugging */
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -
> -	return 0;
> -}
> -fs_initcall(dma_init);
> diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
> index da20569de9d4..138157deeadf 100644
> --- a/arch/powerpc/kernel/dma.c
> +++ b/arch/powerpc/kernel/dma.c
> @@ -309,8 +309,6 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
>   }
>   EXPORT_SYMBOL(dma_set_coherent_mask);
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
>   int dma_set_mask(struct device *dev, u64 dma_mask)
>   {
>   	if (ppc_md.dma_set_mask)
> @@ -361,7 +359,6 @@ EXPORT_SYMBOL_GPL(dma_get_required_mask);
>   
>   static int __init dma_init(void)
>   {
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
>   #ifdef CONFIG_PCI
>   	dma_debug_add_bus(&pci_bus_type);
>   #endif
> diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
> index 2d15d84c20ed..5dee7a922589 100644
> --- a/arch/s390/pci/pci_dma.c
> +++ b/arch/s390/pci/pci_dma.c
> @@ -668,15 +668,6 @@ void zpci_dma_exit(void)
>   	kmem_cache_destroy(dma_region_table_cache);
>   }
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES	(1 << 16)
> -
> -static int __init dma_debug_do_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -fs_initcall(dma_debug_do_init);
> -
>   const struct dma_map_ops s390_pci_dma_ops = {
>   	.alloc		= s390_dma_alloc,
>   	.free		= s390_dma_free,
> diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
> index 8ce98691d822..35ea3099a3b6 100644
> --- a/arch/sh/mm/consistent.c
> +++ b/arch/sh/mm/consistent.c
> @@ -20,18 +20,9 @@
>   #include <asm/cacheflush.h>
>   #include <asm/addrspace.h>
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES	4096
> -
>   const struct dma_map_ops *dma_ops;
>   EXPORT_SYMBOL(dma_ops);
>   
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -fs_initcall(dma_init);
> -
>   void *dma_generic_alloc_coherent(struct device *dev, size_t size,
>   				 dma_addr_t *dma_handle, gfp_t gfp,
>   				 unsigned long attrs)
> diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
> index 76cb57750dda..84cfc5a428d6 100644
> --- a/arch/sparc/kernel/Makefile
> +++ b/arch/sparc/kernel/Makefile
> @@ -74,8 +74,6 @@ obj-$(CONFIG_SPARC64)	+= pcr.o
>   obj-$(CONFIG_SPARC64)	+= nmi.o
>   obj-$(CONFIG_SPARC64_SMP) += cpumap.o
>   
> -obj-y                     += dma.o
> -
>   obj-$(CONFIG_PCIC_PCI)    += pcic.o
>   obj-$(CONFIG_LEON_PCI)    += leon_pci.o
>   obj-$(CONFIG_SPARC_GRPCI2)+= leon_pci_grpci2.o
> diff --git a/arch/sparc/kernel/dma.c b/arch/sparc/kernel/dma.c
> deleted file mode 100644
> index f73e7597c971..000000000000
> --- a/arch/sparc/kernel/dma.c
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -#include <linux/kernel.h>
> -#include <linux/dma-mapping.h>
> -#include <linux/dma-debug.h>
> -
> -#define PREALLOC_DMA_DEBUG_ENTRIES       (1 << 15)
> -
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -fs_initcall(dma_init);
> diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
> index 77625b60a510..bcbaa2e8031e 100644
> --- a/arch/x86/kernel/pci-dma.c
> +++ b/arch/x86/kernel/pci-dma.c
> @@ -55,9 +55,6 @@ struct device x86_dma_fallback_dev = {
>   };
>   EXPORT_SYMBOL(x86_dma_fallback_dev);
>   
> -/* Number of entries preallocated for DMA-API debugging */
> -#define PREALLOC_DMA_DEBUG_ENTRIES       65536
> -
>   void __init pci_iommu_alloc(void)
>   {
>   	struct iommu_table_entry *p;
> @@ -189,7 +186,6 @@ EXPORT_SYMBOL(arch_dma_supported);
>   static int __init pci_iommu_init(void)
>   {
>   	struct iommu_table_entry *p;
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
>   
>   #ifdef CONFIG_PCI
>   	dma_debug_add_bus(&pci_bus_type);
> diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
> index 732631ce250f..392b4a80ebc2 100644
> --- a/arch/xtensa/kernel/pci-dma.c
> +++ b/arch/xtensa/kernel/pci-dma.c
> @@ -261,12 +261,3 @@ const struct dma_map_ops xtensa_dma_map_ops = {
>   	.mapping_error = xtensa_dma_mapping_error,
>   };
>   EXPORT_SYMBOL(xtensa_dma_map_ops);
> -
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init xtensa_dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -fs_initcall(xtensa_dma_init);
> diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
> index c7d844f09c3a..a785f2507159 100644
> --- a/include/linux/dma-debug.h
> +++ b/include/linux/dma-debug.h
> @@ -30,8 +30,6 @@ struct bus_type;
>   
>   extern void dma_debug_add_bus(struct bus_type *bus);
>   
> -extern void dma_debug_init(u32 num_entries);
> -
>   extern int dma_debug_resize_entries(u32 num_entries);
>   
>   extern void debug_dma_map_page(struct device *dev, struct page *page,
> @@ -100,10 +98,6 @@ static inline void dma_debug_add_bus(struct bus_type *bus)
>   {
>   }
>   
> -static inline void dma_debug_init(u32 num_entries)
> -{
> -}
> -
>   static inline int dma_debug_resize_entries(u32 num_entries)
>   {
>   	return 0;
> diff --git a/lib/dma-debug.c b/lib/dma-debug.c
> index 7f5cdc1e6b29..712a897174e4 100644
> --- a/lib/dma-debug.c
> +++ b/lib/dma-debug.c
> @@ -41,6 +41,11 @@
>   #define HASH_FN_SHIFT   13
>   #define HASH_FN_MASK    (HASH_SIZE - 1)
>   
> +/* allow architectures to override this if absolutely required */
> +#ifndef PREALLOC_DMA_DEBUG_ENTRIES
> +#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> +#endif
> +
>   enum {
>   	dma_debug_single,
>   	dma_debug_page,
> @@ -1004,18 +1009,16 @@ void dma_debug_add_bus(struct bus_type *bus)
>   	bus_register_notifier(bus, nb);
>   }
>   
> -/*
> - * Let the architectures decide how many entries should be preallocated.
> - */
> -void dma_debug_init(u32 num_entries)
> +static int dma_debug_init(void)
>   {
> +	u32 num_entries;
>   	int i;
>   
>   	/* Do not use dma_debug_initialized here, since we really want to be
>   	 * called to set dma_debug_initialized
>   	 */
>   	if (global_disable)
> -		return;
> +		return 0;
>   
>   	for (i = 0; i < HASH_SIZE; ++i) {
>   		INIT_LIST_HEAD(&dma_entry_hash[i].list);
> @@ -1026,17 +1029,19 @@ void dma_debug_init(u32 num_entries)
>   		pr_err("DMA-API: error creating debugfs entries - disabling\n");
>   		global_disable = true;
>   
> -		return;
> +		return 0;
>   	}
>   
>   	if (req_entries)
>   		num_entries = req_entries;
> +	else
> +		num_entries = PREALLOC_DMA_DEBUG_ENTRIES;
>   
>   	if (prealloc_memory(num_entries) != 0) {
>   		pr_err("DMA-API: debugging out of memory error - disabled\n");
>   		global_disable = true;
>   
> -		return;
> +		return 0;
>   	}
>   
>   	nr_total_entries = num_free_entries;
> @@ -1044,7 +1049,9 @@ void dma_debug_init(u32 num_entries)
>   	dma_debug_initialized = true;
>   
>   	pr_info("DMA-API: debugging enabled by kernel config\n");
> +	return 0;
>   }
> +core_initcall(dma_debug_init);
>   
>   static __init int dma_debug_cmdline(char *str)
>   {
> 

^ permalink raw reply

* [PATCH 2/3] dma-debug: simplify counting of preallocated requests
From: Robin Murphy @ 2018-05-08  9:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180424140235.9125-3-hch@lst.de>

On 24/04/18 15:02, Christoph Hellwig wrote:
> Just keep a single variable with a descriptive name instead of two
> with confusing names.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   lib/dma-debug.c | 20 ++++----------------
>   1 file changed, 4 insertions(+), 16 deletions(-)
> 
> diff --git a/lib/dma-debug.c b/lib/dma-debug.c
> index 712a897174e4..075253cb613b 100644
> --- a/lib/dma-debug.c
> +++ b/lib/dma-debug.c
> @@ -132,7 +132,7 @@ static u32 min_free_entries;
>   static u32 nr_total_entries;
>   
>   /* number of preallocated entries requested by kernel cmdline */
> -static u32 req_entries;
> +static u32 nr_prealloc_entries = PREALLOC_DMA_DEBUG_ENTRIES;
>   
>   /* debugfs dentry's for the stuff above */
>   static struct dentry *dma_debug_dent        __read_mostly;
> @@ -1011,7 +1011,6 @@ void dma_debug_add_bus(struct bus_type *bus)
>   
>   static int dma_debug_init(void)
>   {
> -	u32 num_entries;
>   	int i;
>   
>   	/* Do not use dma_debug_initialized here, since we really want to be
> @@ -1032,12 +1031,7 @@ static int dma_debug_init(void)
>   		return 0;
>   	}
>   
> -	if (req_entries)
> -		num_entries = req_entries;
> -	else
> -		num_entries = PREALLOC_DMA_DEBUG_ENTRIES;
> -
> -	if (prealloc_memory(num_entries) != 0) {
> +	if (prealloc_memory(nr_prealloc_entries) != 0) {
>   		pr_err("DMA-API: debugging out of memory error - disabled\n");
>   		global_disable = true;
>   
> @@ -1068,16 +1062,10 @@ static __init int dma_debug_cmdline(char *str)
>   
>   static __init int dma_debug_entries_cmdline(char *str)
>   {
> -	int res;
> -
>   	if (!str)
>   		return -EINVAL;
> -
> -	res = get_option(&str, &req_entries);
> -
> -	if (!res)
> -		req_entries = 0;
> -
> +	if (!get_option(&str, &nr_prealloc_entries))
> +		nr_prealloc_entries = PREALLOC_DMA_DEBUG_ENTRIES;
>   	return 0;
>   }
>   
> 

^ permalink raw reply

* [PATCH 4/3] dma-debug: remove CONFIG_HAVE_DMA_API_DEBUG
From: Robin Murphy @ 2018-05-08  9:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180427155342.GA9232@lst.de>

On 27/04/18 16:53, Christoph Hellwig wrote:
> There is no arch specific code required for dma-debug, so there is no
> need to opt into the support either.

Makes sense, and a purely negative diffstat is always pleasing :)

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   .../io/dma-api-debug/arch-support.txt         | 31 -------------------
>   arch/Kconfig                                  |  3 --
>   arch/arm/Kconfig                              |  1 -
>   arch/arm64/Kconfig                            |  1 -
>   arch/c6x/Kconfig                              |  1 -
>   arch/ia64/Kconfig                             |  1 -
>   arch/microblaze/Kconfig                       |  1 -
>   arch/mips/Kconfig                             |  1 -
>   arch/powerpc/Kconfig                          |  1 -
>   arch/riscv/Kconfig                            |  1 -
>   arch/s390/Kconfig                             |  1 -
>   arch/sh/Kconfig                               |  1 -
>   arch/sparc/Kconfig                            |  1 -
>   arch/x86/Kconfig                              |  1 -
>   arch/xtensa/Kconfig                           |  1 -
>   lib/Kconfig.debug                             |  1 -
>   16 files changed, 48 deletions(-)
>   delete mode 100644 Documentation/features/io/dma-api-debug/arch-support.txt
> 
> diff --git a/Documentation/features/io/dma-api-debug/arch-support.txt b/Documentation/features/io/dma-api-debug/arch-support.txt
> deleted file mode 100644
> index e438ed675623..000000000000
> --- a/Documentation/features/io/dma-api-debug/arch-support.txt
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -#
> -# Feature name:          dma-api-debug
> -#         Kconfig:       HAVE_DMA_API_DEBUG
> -#         description:   arch supports DMA debug facilities
> -#
> -    -----------------------
> -    |         arch |status|
> -    -----------------------
> -    |       alpha: | TODO |
> -    |         arc: | TODO |
> -    |         arm: |  ok  |
> -    |       arm64: |  ok  |
> -    |         c6x: |  ok  |
> -    |       h8300: | TODO |
> -    |     hexagon: | TODO |
> -    |        ia64: |  ok  |
> -    |        m68k: | TODO |
> -    |  microblaze: |  ok  |
> -    |        mips: |  ok  |
> -    |       nios2: | TODO |
> -    |    openrisc: | TODO |
> -    |      parisc: | TODO |
> -    |     powerpc: |  ok  |
> -    |        s390: |  ok  |
> -    |          sh: |  ok  |
> -    |       sparc: |  ok  |
> -    |          um: | TODO |
> -    |   unicore32: | TODO |
> -    |         x86: |  ok  |
> -    |      xtensa: |  ok  |
> -    -----------------------
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 8e0d665c8d53..f07a1a99e5db 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -278,9 +278,6 @@ config HAVE_CLK
>   	  The <linux/clk.h> calls support software clock gating and
>   	  thus are a key power management tool on many systems.
>   
> -config HAVE_DMA_API_DEBUG
> -	bool
> -
>   config HAVE_HW_BREAKPOINT
>   	bool
>   	depends on PERF_EVENTS
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 676977bdfe33..c43f5bb55ac8 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -60,7 +60,6 @@ config ARM
>   	select HAVE_CONTEXT_TRACKING
>   	select HAVE_C_RECORDMCOUNT
>   	select HAVE_DEBUG_KMEMLEAK
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_DMA_CONTIGUOUS if MMU
>   	select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) && !CPU_ENDIAN_BE32 && MMU
>   	select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index db51b6445744..b25ed7834f6c 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -105,7 +105,6 @@ config ARM64
>   	select HAVE_CONTEXT_TRACKING
>   	select HAVE_DEBUG_BUGVERBOSE
>   	select HAVE_DEBUG_KMEMLEAK
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_DMA_CONTIGUOUS
>   	select HAVE_DYNAMIC_FTRACE
>   	select HAVE_EFFICIENT_UNALIGNED_ACCESS
> diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
> index c6b4dd1418b4..8c088b96e372 100644
> --- a/arch/c6x/Kconfig
> +++ b/arch/c6x/Kconfig
> @@ -10,7 +10,6 @@ config C6X
>   	select GENERIC_ATOMIC64
>   	select GENERIC_IRQ_SHOW
>   	select HAVE_ARCH_TRACEHOOK
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_MEMBLOCK
>   	select SPARSE_IRQ
>   	select IRQ_DOMAIN
> diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
> index 9485b5490eca..2067289fad4a 100644
> --- a/arch/ia64/Kconfig
> +++ b/arch/ia64/Kconfig
> @@ -29,7 +29,6 @@ config IA64
>   	select HAVE_FUNCTION_TRACER
>   	select TTY
>   	select HAVE_ARCH_TRACEHOOK
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_MEMBLOCK
>   	select HAVE_MEMBLOCK_NODE_MAP
>   	select HAVE_VIRT_CPU_ACCOUNTING
> diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
> index 3817a3e2146c..d14782100088 100644
> --- a/arch/microblaze/Kconfig
> +++ b/arch/microblaze/Kconfig
> @@ -19,7 +19,6 @@ config MICROBLAZE
>   	select HAVE_ARCH_HASH
>   	select HAVE_ARCH_KGDB
>   	select HAVE_DEBUG_KMEMLEAK
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_DYNAMIC_FTRACE
>   	select HAVE_FTRACE_MCOUNT_RECORD
>   	select HAVE_FUNCTION_GRAPH_TRACER
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 0f619b8c0e9e..2dcdc13cd65d 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -42,7 +42,6 @@ config MIPS
>   	select HAVE_C_RECORDMCOUNT
>   	select HAVE_DEBUG_KMEMLEAK
>   	select HAVE_DEBUG_STACKOVERFLOW
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_DMA_CONTIGUOUS
>   	select HAVE_DYNAMIC_FTRACE
>   	select HAVE_EXIT_THREAD
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 1887f8f86a77..268fd46fc3c7 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -181,7 +181,6 @@ config PPC
>   	select HAVE_CONTEXT_TRACKING		if PPC64
>   	select HAVE_DEBUG_KMEMLEAK
>   	select HAVE_DEBUG_STACKOVERFLOW
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_DYNAMIC_FTRACE
>   	select HAVE_DYNAMIC_FTRACE_WITH_REGS	if MPROFILE_KERNEL
>   	select HAVE_EBPF_JIT			if PPC64
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 17212ba54ee3..95e2da34aaad 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -23,7 +23,6 @@ config RISCV
>   	select GENERIC_ATOMIC64 if !64BIT || !RISCV_ISA_A
>   	select HAVE_MEMBLOCK
>   	select HAVE_MEMBLOCK_NODE_MAP
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_DMA_CONTIGUOUS
>   	select HAVE_GENERIC_DMA_COHERENT
>   	select IRQ_DOMAIN
> diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
> index b794a2ab6d15..6a64287ec1da 100644
> --- a/arch/s390/Kconfig
> +++ b/arch/s390/Kconfig
> @@ -130,7 +130,6 @@ config S390
>   	select HAVE_CMPXCHG_LOCAL
>   	select HAVE_COPY_THREAD_TLS
>   	select HAVE_DEBUG_KMEMLEAK
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_DMA_CONTIGUOUS
>   	select DMA_DIRECT_OPS
>   	select HAVE_DYNAMIC_FTRACE
> diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
> index 9417f70e008e..7d521926041e 100644
> --- a/arch/sh/Kconfig
> +++ b/arch/sh/Kconfig
> @@ -13,7 +13,6 @@ config SUPERH
>   	select HAVE_OPROFILE
>   	select HAVE_GENERIC_DMA_COHERENT
>   	select HAVE_ARCH_TRACEHOOK
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_PERF_EVENTS
>   	select HAVE_DEBUG_BUGVERBOSE
>   	select ARCH_HAVE_CUSTOM_GPIO_H
> diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
> index c1cfc17eb504..435dbc033afe 100644
> --- a/arch/sparc/Kconfig
> +++ b/arch/sparc/Kconfig
> @@ -25,7 +25,6 @@ config SPARC
>   	select RTC_CLASS
>   	select RTC_DRV_M48T59
>   	select RTC_SYSTOHC
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_ARCH_JUMP_LABEL if SPARC64
>   	select GENERIC_IRQ_SHOW
>   	select ARCH_WANT_IPC_PARSE_VERSION
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index aad35c568681..3eeca48a146b 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -135,7 +135,6 @@ config X86
>   	select HAVE_C_RECORDMCOUNT
>   	select HAVE_DEBUG_KMEMLEAK
>   	select HAVE_DEBUG_STACKOVERFLOW
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_DMA_CONTIGUOUS
>   	select HAVE_DYNAMIC_FTRACE
>   	select HAVE_DYNAMIC_FTRACE_WITH_REGS
> diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
> index c921e8bccdc8..17df332269b2 100644
> --- a/arch/xtensa/Kconfig
> +++ b/arch/xtensa/Kconfig
> @@ -19,7 +19,6 @@ config XTENSA
>   	select HAVE_ARCH_KASAN if MMU
>   	select HAVE_CC_STACKPROTECTOR
>   	select HAVE_DEBUG_KMEMLEAK
> -	select HAVE_DMA_API_DEBUG
>   	select HAVE_DMA_CONTIGUOUS
>   	select HAVE_EXIT_THREAD
>   	select HAVE_FUNCTION_TRACER
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index 685ed2dd4384..d5175eb7b917 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -1634,7 +1634,6 @@ config PROVIDE_OHCI1394_DMA_INIT
>   
>   config DMA_API_DEBUG
>   	bool "Enable debugging of DMA-API usage"
> -	depends on HAVE_DMA_API_DEBUG
>   	select NEED_DMA_MAP_STATE
>   	help
>   	  Enable this option to debug the use of the DMA API by device drivers.
> 

^ permalink raw reply

* [PATCH v5 06/14] KVM: arm64: Optimise FPSIMD handling to reduce guest/host thrashing
From: Marc Zyngier @ 2018-05-08  9:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525449935-31424-7-git-send-email-Dave.Martin@arm.com>

On 04/05/18 17:05, Dave Martin wrote:
> This patch refactors KVM to align the host and guest FPSIMD
> save/restore logic with each other for arm64.  This reduces the
> number of redundant save/restore operations that must occur, and
> reduces the common-case IRQ blackout time during guest exit storms
> by saving the host state lazily and optimising away the need to
> restore the host state before returning to the run loop.
> 
> Four hooks are defined in order to enable this:
> 
>  * kvm_arch_vcpu_run_map_fp():
>    Called on PID change to map necessary bits of current to Hyp.
> 
>  * kvm_arch_vcpu_load_fp():
>    Set up FP/SIMD for entering the KVM run loop (parse as
>    "vcpu_load fp").
> 
>  * kvm_arch_vcpu_park_fp():
>    Get FP/SIMD into a safe state for re-enabling interrupts after a
>    guest exit back to the run loop.
> 
>    For arm64 specifically, this involves updating the host kernel's
>    FPSIMD context tracking metadata so that kernel-mode NEON use
>    will cause the vcpu's FPSIMD state to be saved back correctly
>    into the vcpu struct.  This must be done before re-enabling
>    interrupts because kernel-mode NEON may be used my softirqs.

s/my/by/

I must admit being slightly confused by the word "park". I tend to read
"park" as "stash away for later use", while it really is "update the
kernel's view of who is actually in control of the FP registers".

No, I don't have a better name for it... ;-) But maybe something along
the lines of "hwsync_fp", in order to be consistent with the rest of the
code that deals with shared resources?

> 
>  * kvm_arch_vcpu_put_fp():
>    Save guest FP/SIMD state back to memory and dissociate from the
>    CPU ("vcpu_put fp").
> 
> Also, the arm64 FPSIMD context switch code is updated to enable it
> to save back FPSIMD state for a vcpu, not just current.  A few
> helpers drive this:
> 
>  * fpsimd_bind_state_to_cpu(struct user_fpsimd_state *fp):
>    mark this CPU as having context fp (which may belong to a vcpu)
>    currently loaded in its registers.  This is the non-task
>    equivalent of the static function fpsimd_bind_to_cpu() in
>    fpsimd.c.
> 
>  * task_fpsimd_save():
>    exported to allow KVM to save the guest's FPSIMD state back to
>    memory on exit from the run loop.
> 
>  * fpsimd_flush_state():
>    invalidate any context's FPSIMD state that is currently loaded.
>    Used to disassociate the vcpu from the CPU regs on run loop exit.
> 
> These changes allow the run loop to enable interrupts (and thus
> softirqs that may use kernel-mode NEON) without having to save the
> guest's FPSIMD state eagerly.
> 
> Some new vcpu_arch fields are added to make all this work.  Because
> host FPSIMD state can now be saved back directly into current's
> thread_struct as appropriate, host_cpu_context is no longer used
> for preserving the FPSIMD state.  However, it is still needed for
> preserving other things such as the host's system registers.  To
> avoid ABI churn, the redundant storage space in host_cpu_context is
> not removed for now.
> 
> arch/arm is not addressed by this patch and continues to use its
> current save/restore logic.  It could provide implementations of
> the helpers later if desired.
> 
> Signed-off-by: Dave Martin <Dave.Martin@arm.com>
> 
> ---
> 
> Changes since RFC v4:
> 
>  * select HAVE_KVM_VCPU_RUN_PID_CHANGE alongside adding the arm64
>    implementation of kvm_arch_vcpu_run_pid_change().
> 
>    (These are no longer done by KVM: arm/arm64: Introduce
>    kvm_arch_vcpu_run_pid_change in this series.)
> 
>  * Some pure refactoring in arch/arm64/kernel/fpsimd.c has been
>    split into the previous patch for clarity.
> 
>  * Migrate to use update_thread_flag().
> ---
>  arch/arm/include/asm/kvm_host.h   |   8 +++
>  arch/arm64/include/asm/fpsimd.h   |   5 ++
>  arch/arm64/include/asm/kvm_host.h |  18 +++++++
>  arch/arm64/kernel/fpsimd.c        |  15 +++++-
>  arch/arm64/kvm/Kconfig            |   1 +
>  arch/arm64/kvm/Makefile           |   2 +-
>  arch/arm64/kvm/fpsimd.c           | 106 ++++++++++++++++++++++++++++++++++++++
>  arch/arm64/kvm/hyp/switch.c       |  50 +++++++++---------
>  virt/kvm/arm/arm.c                |   4 ++
>  9 files changed, 180 insertions(+), 29 deletions(-)
>  create mode 100644 arch/arm64/kvm/fpsimd.c
> 
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index c7c28c8..4cac8d1 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -303,6 +303,14 @@ int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
>  int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
>  			       struct kvm_device_attr *attr);
>  
> +/*
> + * VFP/NEON switching is all done by the hyp switch code, so no need to
> + * coordinate with host context handling for this state:
> + */
> +static inline void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu) {}
> +static inline void kvm_arch_vcpu_park_fp(struct kvm_vcpu *vcpu) {}
> +static inline void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu) {}
> +
>  /* All host FP/SIMD state is restored on guest exit, so nothing to save: */
>  static inline void kvm_fpsimd_flush_cpu_state(void) {}
>  
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index aa7162a..aa60895 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -41,6 +41,8 @@ struct task_struct;
>  extern void fpsimd_save_state(struct user_fpsimd_state *state);
>  extern void fpsimd_load_state(struct user_fpsimd_state *state);
>  
> +extern void fpsimd_save(void);
> +
>  extern void fpsimd_thread_switch(struct task_struct *next);
>  extern void fpsimd_flush_thread(void);
>  
> @@ -49,7 +51,10 @@ extern void fpsimd_preserve_current_state(void);
>  extern void fpsimd_restore_current_state(void);
>  extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
>  
> +extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state);
> +
>  extern void fpsimd_flush_task_state(struct task_struct *target);
> +extern void fpsimd_flush_cpu_state(void);
>  extern void sve_flush_cpu_state(void);
>  
>  /* Maximum VL that SVE VL-agnostic software can transparently support */
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 469de8a..811097e 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -30,6 +30,7 @@
>  #include <asm/kvm.h>
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_mmio.h>
> +#include <asm/thread_info.h>
>  
>  #define __KVM_HAVE_ARCH_INTC_INITIALIZED
>  
> @@ -238,6 +239,12 @@ struct kvm_vcpu_arch {
>  
>  	/* Pointer to host CPU context */
>  	kvm_cpu_context_t *host_cpu_context;
> +
> +	struct thread_info *host_thread_info;	/* hyp VA */
> +	struct user_fpsimd_state *host_fpsimd_state;	/* hyp VA */
> +	bool host_sve_in_use;	/* backup for host TIF_SVE while in guest */
> +	bool fp_enabled;

Could we consider merging these two fields together with debug_flags?
Overall, they share a common purpose (tracking the use of a resource
shared between host and guest). Not necessarily something to do
immediately though.

> +
>  	struct {
>  		/* {Break,watch}point registers */
>  		struct kvm_guest_debug_arch regs;
> @@ -420,6 +427,17 @@ static inline void __cpu_init_stage2(void)
>  		  "PARange is %d bits, unsupported configuration!", parange);
>  }
>  
> +/* Guest/host FPSIMD coordination helpers */
> +int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
> +void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
> +void kvm_arch_vcpu_park_fp(struct kvm_vcpu *vcpu);
> +void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
> +
> +static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
> +{
> +	return kvm_arch_vcpu_run_map_fp(vcpu);
> +}
> +
>  /*
>   * All host FP/SIMD state is restored on guest exit, so nothing needs
>   * doing here except in the SVE case:
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index 5fc0595..e7349b5 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -275,7 +275,7 @@ static void task_fpsimd_load(void)
>   *
>   * Softirqs (and preemption) must be disabled.
>   */
> -static void fpsimd_save(void)
> +void fpsimd_save(void)
>  {
>  	struct user_fpsimd_state *st = __this_cpu_read(fpsimd_last_state.st);
>  
> @@ -1008,6 +1008,17 @@ static void fpsimd_bind_to_cpu(void)
>  	current->thread.fpsimd_cpu = smp_processor_id();
>  }
>  
> +void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st)
> +{
> +	struct fpsimd_last_state_struct *last =
> +		this_cpu_ptr(&fpsimd_last_state);
> +
> +	WARN_ON(!in_softirq() && !irqs_disabled());
> +
> +	last->st = st;
> +	last->sve_in_use = false;
> +}
> +
>  /*
>   * Load the userland FPSIMD state of 'current' from memory, but only if the
>   * FPSIMD state already held in the registers is /not/ the most recent FPSIMD
> @@ -1060,7 +1071,7 @@ void fpsimd_flush_task_state(struct task_struct *t)
>  	t->thread.fpsimd_cpu = NR_CPUS;
>  }
>  
> -static inline void fpsimd_flush_cpu_state(void)
> +void fpsimd_flush_cpu_state(void)
>  {
>  	__this_cpu_write(fpsimd_last_state.st, NULL);
>  }
> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> index a2e3a5a..47b23bf 100644
> --- a/arch/arm64/kvm/Kconfig
> +++ b/arch/arm64/kvm/Kconfig
> @@ -39,6 +39,7 @@ config KVM
>  	select HAVE_KVM_IRQ_ROUTING
>  	select IRQ_BYPASS_MANAGER
>  	select HAVE_KVM_IRQ_BYPASS
> +	select HAVE_KVM_VCPU_RUN_PID_CHANGE
>  	---help---
>  	  Support hosting virtualized guest machines.
>  	  We don't support KVM with 16K page tables yet, due to the multiple
> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> index 93afff9..0f2a135 100644
> --- a/arch/arm64/kvm/Makefile
> +++ b/arch/arm64/kvm/Makefile
> @@ -19,7 +19,7 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/psci.o $(KVM)/arm/perf.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += inject_fault.o regmap.o va_layout.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += guest.o debug.o reset.o sys_regs.o sys_regs_generic_v8.o
> -kvm-$(CONFIG_KVM_ARM_HOST) += vgic-sys-reg-v3.o
> +kvm-$(CONFIG_KVM_ARM_HOST) += vgic-sys-reg-v3.o fpsimd.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/aarch32.o
>  
>  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic.o
> diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
> new file mode 100644
> index 0000000..bbc6889
> --- /dev/null
> +++ b/arch/arm64/kvm/fpsimd.c
> @@ -0,0 +1,106 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * arch/arm64/kvm/fpsimd.c: Guest/host FPSIMD context coordination helpers
> + *
> + * Copyright 2018 Arm Limited
> + * Author: Dave Martin <Dave.Martin@arm.com>
> + */
> +#include <linux/bottom_half.h>
> +#include <linux/sched.h>
> +#include <linux/thread_info.h>
> +#include <linux/kvm_host.h>
> +#include <asm/kvm_host.h>
> +#include <asm/kvm_mmu.h>
> +
> +/*
> + * Called on entry to KVM_RUN unless this vcpu previously ran at least
> + * once and the most recent prior KVM_RUN for this vcpu was called from
> + * the same task as current (highly likely).
> + *
> + * This is guaranteed to execute before kvm_arch_vcpu_load_fp(vcpu),
> + * such that on entering hyp the relevant parts of current are already
> + * mapped.
> + */
> +int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu)
> +{
> +	int ret;
> +
> +	struct thread_info *ti = &current->thread_info;
> +	struct user_fpsimd_state *fpsimd = &current->thread.uw.fpsimd_state;
> +
> +	/*
> +	 * Make sure the host task thread flags and fpsimd state are
> +	 * visible to hyp:
> +	 */
> +	ret = create_hyp_mappings(ti, ti + 1, PAGE_HYP);
> +	if (ret)
> +		goto error;
> +
> +	ret = create_hyp_mappings(fpsimd, fpsimd + 1, PAGE_HYP);
> +	if (ret)
> +		goto error;
> +
> +	vcpu->arch.host_thread_info = kern_hyp_va(ti);
> +	vcpu->arch.host_fpsimd_state = kern_hyp_va(fpsimd);
> +error:
> +	return ret;
> +}
> +
> +/*
> + * Prepare vcpu for saving the host's FPSIMD state and loading the guest's.
> + * The actual loading is done by the FPSIMD access trap taken to hyp.
> + *
> + * Here, we just set the correct metadata to indicate that the FPSIMD
> + * state in the cpu regs (if any) belongs to current, and where to write
> + * it back to if/when a FPSIMD access trap is taken.
> + *
> + * TIF_SVE is backed up here, since it may get clobbered with guest state.
> + * This flag is restored by kvm_arch_vcpu_put_fp(vcpu).
> + */
> +void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
> +{
> +	BUG_ON(system_supports_sve());
> +	BUG_ON(!current->mm);
> +
> +	vcpu->arch.fp_enabled = false;
> +	vcpu->arch.host_fpsimd_state =
> +		kern_hyp_va(&current->thread.uw.fpsimd_state);
> +	vcpu->arch.host_sve_in_use = !!test_thread_flag(TIF_SVE);
> +}
> +
> +/*
> + * If the guest FPSIMD state was loaded, mark the CPU FPSIMD regs as
> + * dirty for vcpu so that they will be written back if the kernel
> + * clobbers them due to kernel-mode NEON before re-entry into the guest.
> + */
> +void kvm_arch_vcpu_park_fp(struct kvm_vcpu *vcpu)
> +{
> +	WARN_ON_ONCE(!irqs_disabled());
> +
> +	if (vcpu->arch.fp_enabled) {
> +		fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.gp_regs.fp_regs);
> +		clear_thread_flag(TIF_FOREIGN_FPSTATE);
> +		clear_thread_flag(TIF_SVE);
> +	}
> +}
> +
> +/*
> + * Write back the vcpu FPSIMD regs if they are dirty, and invalidate the
> + * cpu FPSIMD regs so that they can't be spuriously reused if this vcpu
> + * disappears and another task or vcpu appears that recycles the same
> + * struct fpsimd_state.
> + */
> +void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
> +{
> +	local_bh_disable();
> +
> +	if (vcpu->arch.fp_enabled) {
> +		fpsimd_save();
> +		fpsimd_flush_cpu_state();
> +		set_thread_flag(TIF_FOREIGN_FPSTATE);
> +	}
> +
> +	update_thread_flag(TIF_SVE, vcpu->arch.host_sve_in_use);
> +
> +	local_bh_enable();
> +}
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index c0796c4..10f55d3 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -27,15 +27,16 @@
>  #include <asm/kvm_mmu.h>
>  #include <asm/fpsimd.h>
>  #include <asm/debug-monitors.h>
> +#include <asm/thread_info.h>
>  
> -static bool __hyp_text __fpsimd_enabled_nvhe(void)
> +static bool __hyp_text update_fp_enabled(struct kvm_vcpu *vcpu)
>  {
> -	return !(read_sysreg(cptr_el2) & CPTR_EL2_TFP);
> -}
> +	if (vcpu->arch.host_thread_info->flags & _TIF_FOREIGN_FPSTATE) {
> +		vcpu->arch.host_fpsimd_state = NULL;
> +		vcpu->arch.fp_enabled = false;
> +	}
>  
> -static bool fpsimd_enabled_vhe(void)
> -{
> -	return !!(read_sysreg(cpacr_el1) & CPACR_EL1_FPEN);
> +	return vcpu->arch.fp_enabled;
>  }
>  
>  /* Save the 32-bit only FPSIMD system register state */
> @@ -92,7 +93,10 @@ static void activate_traps_vhe(struct kvm_vcpu *vcpu)
>  
>  	val = read_sysreg(cpacr_el1);
>  	val |= CPACR_EL1_TTA;
> -	val &= ~(CPACR_EL1_FPEN | CPACR_EL1_ZEN);
> +	val &= ~CPACR_EL1_ZEN;
> +	if (!update_fp_enabled(vcpu))
> +		val &= ~CPACR_EL1_FPEN;
> +
>  	write_sysreg(val, cpacr_el1);
>  
>  	write_sysreg(kvm_get_hyp_vector(), vbar_el1);
> @@ -105,7 +109,10 @@ static void __hyp_text __activate_traps_nvhe(struct kvm_vcpu *vcpu)
>  	__activate_traps_common(vcpu);
>  
>  	val = CPTR_EL2_DEFAULT;
> -	val |= CPTR_EL2_TTA | CPTR_EL2_TFP | CPTR_EL2_TZ;
> +	val |= CPTR_EL2_TTA | CPTR_EL2_TZ;
> +	if (!update_fp_enabled(vcpu))
> +		val |= CPTR_EL2_TFP;
> +
>  	write_sysreg(val, cptr_el2);
>  }
>  
> @@ -321,8 +328,6 @@ static bool __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
>  void __hyp_text __hyp_switch_fpsimd(u64 esr __always_unused,
>  				    struct kvm_vcpu *vcpu)
>  {
> -	kvm_cpu_context_t *host_ctxt;
> -
>  	if (has_vhe())
>  		write_sysreg(read_sysreg(cpacr_el1) | CPACR_EL1_FPEN,
>  			     cpacr_el1);
> @@ -332,14 +337,19 @@ void __hyp_text __hyp_switch_fpsimd(u64 esr __always_unused,
>  
>  	isb();
>  
> -	host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
> -	__fpsimd_save_state(&host_ctxt->gp_regs.fp_regs);
> +	if (vcpu->arch.host_fpsimd_state) {
> +		__fpsimd_save_state(vcpu->arch.host_fpsimd_state);
> +		vcpu->arch.host_fpsimd_state = NULL;
> +	}
> +
>  	__fpsimd_restore_state(&vcpu->arch.ctxt.gp_regs.fp_regs);
>  
>  	/* Skip restoring fpexc32 for AArch64 guests */
>  	if (!(read_sysreg(hcr_el2) & HCR_RW))
>  		write_sysreg(vcpu->arch.ctxt.sys_regs[FPEXC32_EL2],
>  			     fpexc32_el2);
> +
> +	vcpu->arch.fp_enabled = true;
>  }
>  
>  /*
> @@ -418,7 +428,6 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
>  {
>  	struct kvm_cpu_context *host_ctxt;
>  	struct kvm_cpu_context *guest_ctxt;
> -	bool fp_enabled;
>  	u64 exit_code;
>  
>  	host_ctxt = vcpu->arch.host_cpu_context;
> @@ -440,19 +449,14 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
>  		/* And we're baaack! */
>  	} while (fixup_guest_exit(vcpu, &exit_code));
>  
> -	fp_enabled = fpsimd_enabled_vhe();
> -
>  	sysreg_save_guest_state_vhe(guest_ctxt);
>  
>  	__deactivate_traps(vcpu);
>  
>  	sysreg_restore_host_state_vhe(host_ctxt);
>  
> -	if (fp_enabled) {
> -		__fpsimd_save_state(&guest_ctxt->gp_regs.fp_regs);
> -		__fpsimd_restore_state(&host_ctxt->gp_regs.fp_regs);
> +	if (vcpu->arch.fp_enabled)
>  		__fpsimd_save_fpexc32(vcpu);
> -	}
>  
>  	__debug_switch_to_host(vcpu);
>  
> @@ -464,7 +468,6 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
>  {
>  	struct kvm_cpu_context *host_ctxt;
>  	struct kvm_cpu_context *guest_ctxt;
> -	bool fp_enabled;
>  	u64 exit_code;
>  
>  	vcpu = kern_hyp_va(vcpu);
> @@ -496,8 +499,6 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
>  		/* And we're baaack! */
>  	} while (fixup_guest_exit(vcpu, &exit_code));
>  
> -	fp_enabled = __fpsimd_enabled_nvhe();
> -
>  	__sysreg_save_state_nvhe(guest_ctxt);
>  	__sysreg32_save_state(vcpu);
>  	__timer_disable_traps(vcpu);
> @@ -508,11 +509,8 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
>  
>  	__sysreg_restore_state_nvhe(host_ctxt);
>  
> -	if (fp_enabled) {
> -		__fpsimd_save_state(&guest_ctxt->gp_regs.fp_regs);
> -		__fpsimd_restore_state(&host_ctxt->gp_regs.fp_regs);
> +	if (vcpu->arch.fp_enabled)
>  		__fpsimd_save_fpexc32(vcpu);
> -	}
>  
>  	/*
>  	 * This must come after restoring the host sysregs, since a non-VHE
> diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
> index a4c1b76..6cf499b 100644
> --- a/virt/kvm/arm/arm.c
> +++ b/virt/kvm/arm/arm.c
> @@ -363,10 +363,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  	kvm_vgic_load(vcpu);
>  	kvm_timer_vcpu_load(vcpu);
>  	kvm_vcpu_load_sysregs(vcpu);
> +	kvm_arch_vcpu_load_fp(vcpu);
>  }
>  
>  void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>  {
> +	kvm_arch_vcpu_put_fp(vcpu);
>  	kvm_vcpu_put_sysregs(vcpu);
>  	kvm_timer_vcpu_put(vcpu);
>  	kvm_vgic_put(vcpu);
> @@ -778,6 +780,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  		if (static_branch_unlikely(&userspace_irqchip_in_use))
>  			kvm_timer_sync_hwstate(vcpu);
>  
> +		kvm_arch_vcpu_park_fp(vcpu);
> +
>  		/*
>  		 * We may have taken a host interrupt in HYP mode (ie
>  		 * while executing the guest). This interrupt is still
> 

Other than the couple of minor nits above,

Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

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

^ permalink raw reply

* [PATCH] ARM: dts: am335x-evmsk: Add phandle for the backlight for the panel
From: Peter Ujfalusi @ 2018-05-08 10:04 UTC (permalink / raw)
  To: linux-arm-kernel

With the backlight phandle the driver can manage the backlight on/off in
sync with the panel enable/disable.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 arch/arm/boot/dts/am335x-evmsk.dts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts
index d0d6bacfafc2..0c096a795e37 100644
--- a/arch/arm/boot/dts/am335x-evmsk.dts
+++ b/arch/arm/boot/dts/am335x-evmsk.dts
@@ -137,7 +137,7 @@
 		};
 	};
 
-	backlight {
+	lcd_bl: backlight {
 		compatible = "pwm-backlight";
 		pwms = <&ecap2 0 50000 PWM_POLARITY_INVERTED>;
 		brightness-levels = <0 58 61 66 75 90 125 170 255>;
@@ -172,6 +172,7 @@
 		pinctrl-names = "default", "sleep";
 		pinctrl-0 = <&lcd_pins_default>;
 		pinctrl-1 = <&lcd_pins_sleep>;
+		backlight = <&lcd_bl>;
 		status = "okay";
 		panel-info {
 			ac-bias		= <255>;
-- 
Peter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

^ permalink raw reply related

* [PATCH 3/3] dma-debug: unexport dma_debug_resize_entries and debug_dma_dump_mappings
From: Robin Murphy @ 2018-05-08 10:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180424140235.9125-4-hch@lst.de>

On 24/04/18 15:02, Christoph Hellwig wrote:
> Only used by the AMD GART driver, which must be built in.

FWIW debug_dma_dump_mappings() is also called by the Intel VT-d driver, 
but the same reasoning still applies. This does rather beg the question 
of whether it's right to have bits of low-level dma-debug internals 
*only* called by a couple of IOMMU drivers, but that can wait for 
another day.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   lib/dma-debug.c | 2 --
>   1 file changed, 2 deletions(-)
> 
> diff --git a/lib/dma-debug.c b/lib/dma-debug.c
> index 075253cb613b..6a1ebaa83623 100644
> --- a/lib/dma-debug.c
> +++ b/lib/dma-debug.c
> @@ -444,7 +444,6 @@ void debug_dma_dump_mappings(struct device *dev)
>   		spin_unlock_irqrestore(&bucket->lock, flags);
>   	}
>   }
> -EXPORT_SYMBOL(debug_dma_dump_mappings);
>   
>   /*
>    * For each mapping (initial cacheline in the case of
> @@ -753,7 +752,6 @@ int dma_debug_resize_entries(u32 num_entries)
>   
>   	return ret;
>   }
> -EXPORT_SYMBOL(dma_debug_resize_entries);
>   
>   /*
>    * DMA-API debugging init code
> 

^ permalink raw reply

* [PATCH v3 0/3] led_trigger_register_format and tty triggers
From: Uwe Kleine-König @ 2018-05-08 10:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

while working on a patch that adds led triggers to drivers/tty (patch 3)
I thought that being able to pass a format string (and the respective
parameters) to led_trigger_register_simple instead of a constant string
would be nice. This is implemented in the first patch. The second patch
converts the can leds to this new function which demonstrates nicely the
added benefit for users. Both patches are new in v3.

The third patch finally implements the triggers for the tty framework.
Compared to v2 I reduced the need for #ifdefs, make use of
led_trigger_register_format() and excluded serdev devices from
triggering as suggested by Johan Hovold.

Also code cleanup in the error case is done now and hopefully the kbuild
test robot is happy now.

Best regards
Uwe

Uwe Kleine-K?nig (3):
  leds: triggers: provide led_trigger_register_format()
  can: simplify LED trigger handling
  tty: implement led triggers

 arch/arm/boot/dts/imx25-logitech-baby.dts | 192 ++++++++++++++++++++++
 drivers/leds/led-triggers.c               |  84 +++++++---
 drivers/net/can/led.c                     |  30 +---
 drivers/tty/Kconfig                       |   7 +
 drivers/tty/tty_buffer.c                  |   2 +
 drivers/tty/tty_io.c                      |   3 +
 drivers/tty/tty_port.c                    |  32 +++-
 include/linux/can/dev.h                   |   3 -
 include/linux/leds.h                      |  30 ++--
 include/linux/tty.h                       |  22 +++
 10 files changed, 341 insertions(+), 64 deletions(-)
 create mode 100644 arch/arm/boot/dts/imx25-logitech-baby.dts

-- 
2.17.0

^ permalink raw reply

* [PATCH v3 1/3] leds: triggers: provide led_trigger_register_format()
From: Uwe Kleine-König @ 2018-05-08 10:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180508100543.12559-1-u.kleine-koenig@pengutronix.de>

This allows one to simplify drivers that provide a trigger with a
non-constant name (e.g. one trigger per device with the trigger name
depending on the device's name).

Internally the memory the name member of struct led_trigger points to
now always allocated dynamically instead of just taken from the caller.

The function led_trigger_rename_static() must be changed accordingly and
was renamed to led_trigger_rename() for consistency, with the only user
adapted.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/leds/led-triggers.c | 84 +++++++++++++++++++++++++++----------
 drivers/net/can/led.c       |  6 +--
 include/linux/leds.h        | 30 +++++++------
 3 files changed, 81 insertions(+), 39 deletions(-)

diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 431123b048a2..5d8bb504b07b 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -175,18 +175,34 @@ void led_trigger_set_default(struct led_classdev *led_cdev)
 }
 EXPORT_SYMBOL_GPL(led_trigger_set_default);
 
-void led_trigger_rename_static(const char *name, struct led_trigger *trig)
+int led_trigger_rename(struct led_trigger *trig, const char *fmt, ...)
 {
-	/* new name must be on a temporary string to prevent races */
-	BUG_ON(name == trig->name);
+	const char *prevname;
+	const char *newname;
+	va_list args;
+
+	if (!trig)
+		return 0;
+
+	va_start(args, fmt);
+	newname = kvasprintf_const(GFP_KERNEL, fmt, args);
+	va_end(args);
+
+	if (!newname) {
+		pr_err("Failed to allocate new name for trigger %s\n", trig->name);
+		return -ENOMEM;
+	}
 
 	down_write(&triggers_list_lock);
-	/* this assumes that trig->name was originaly allocated to
-	 * non constant storage */
-	strcpy((char *)trig->name, name);
+	prevname = trig->name;
+	trig->name = newname;
 	up_write(&triggers_list_lock);
+
+	kfree_const(prevname);
+
+	return 0;
 }
-EXPORT_SYMBOL_GPL(led_trigger_rename_static);
+EXPORT_SYMBOL_GPL(led_trigger_rename);
 
 /* LED Trigger Interface */
 
@@ -333,34 +349,56 @@ void led_trigger_blink_oneshot(struct led_trigger *trig,
 }
 EXPORT_SYMBOL_GPL(led_trigger_blink_oneshot);
 
-void led_trigger_register_simple(const char *name, struct led_trigger **tp)
+int led_trigger_register_format(struct led_trigger **tp, const char *fmt, ...)
 {
+	va_list args;
 	struct led_trigger *trig;
-	int err;
+	int err = -ENOMEM;
+	const char *name;
+
+	va_start(args, fmt);
+	name = kvasprintf_const(GFP_KERNEL, fmt, args);
+	va_end(args);
 
 	trig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
 
-	if (trig) {
-		trig->name = name;
-		err = led_trigger_register(trig);
-		if (err < 0) {
-			kfree(trig);
-			trig = NULL;
-			pr_warn("LED trigger %s failed to register (%d)\n",
-				name, err);
-		}
-	} else {
-		pr_warn("LED trigger %s failed to register (no memory)\n",
-			name);
-	}
+	if (!name || !trig)
+		goto err;
+
+	trig->name = name;
+
+	err = led_trigger_register(trig);
+	if (err < 0)
+		goto err;
+
 	*tp = trig;
+
+	return 0;
+
+err:
+	kfree(trig);
+	kfree_const(name);
+
+	*tp = NULL;
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(led_trigger_register_format);
+
+void led_trigger_register_simple(const char *name, struct led_trigger **tp)
+{
+	int ret = led_trigger_register_format(tp, "%s", name);
+	if (ret < 0)
+		pr_warn("LED trigger %s failed to register (%d)\n", name, ret);
 }
 EXPORT_SYMBOL_GPL(led_trigger_register_simple);
 
 void led_trigger_unregister_simple(struct led_trigger *trig)
 {
-	if (trig)
+	if (trig) {
 		led_trigger_unregister(trig);
+		kfree_const(trig->name);
+	}
 	kfree(trig);
 }
 EXPORT_SYMBOL_GPL(led_trigger_unregister_simple);
diff --git a/drivers/net/can/led.c b/drivers/net/can/led.c
index c1b667675fa1..2d7d1b0d20f9 100644
--- a/drivers/net/can/led.c
+++ b/drivers/net/can/led.c
@@ -115,13 +115,13 @@ static int can_led_notifier(struct notifier_block *nb, unsigned long msg,
 
 	if (msg == NETDEV_CHANGENAME) {
 		snprintf(name, sizeof(name), "%s-tx", netdev->name);
-		led_trigger_rename_static(name, priv->tx_led_trig);
+		led_trigger_rename(priv->tx_led_trig, name);
 
 		snprintf(name, sizeof(name), "%s-rx", netdev->name);
-		led_trigger_rename_static(name, priv->rx_led_trig);
+		led_trigger_rename(priv->rx_led_trig, name);
 
 		snprintf(name, sizeof(name), "%s-rxtx", netdev->name);
-		led_trigger_rename_static(name, priv->rxtx_led_trig);
+		led_trigger_rename(priv->rxtx_led_trig, name);
 	}
 
 	return NOTIFY_DONE;
diff --git a/include/linux/leds.h b/include/linux/leds.h
index b7e82550e655..e706c28bb35b 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -275,6 +275,8 @@ extern void led_trigger_unregister(struct led_trigger *trigger);
 extern int devm_led_trigger_register(struct device *dev,
 				     struct led_trigger *trigger);
 
+extern int led_trigger_register_format(struct led_trigger **trigger,
+				       const char *fmt, ...);
 extern void led_trigger_register_simple(const char *name,
 				struct led_trigger **trigger);
 extern void led_trigger_unregister_simple(struct led_trigger *trigger);
@@ -298,28 +300,25 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev)
 }
 
 /**
- * led_trigger_rename_static - rename a trigger
- * @name: the new trigger name
+ * led_trigger_rename - rename a trigger
  * @trig: the LED trigger to rename
+ * @fmt: format string for new name
  *
- * Change a LED trigger name by copying the string passed in
- * name into current trigger name, which MUST be large
- * enough for the new string.
- *
- * Note that name must NOT point to the same string used
- * during LED registration, as that could lead to races.
- *
- * This is meant to be used on triggers with statically
- * allocated name.
+ * rebaptize the given trigger.
  */
-extern void led_trigger_rename_static(const char *name,
-				      struct led_trigger *trig);
+extern int led_trigger_rename(struct led_trigger *trig, const char *fmt, ...);
 
 #else
 
 /* Trigger has no members */
 struct led_trigger {};
 
+static inline int led_trigger_register_format(struct led_trigger **trigger,
+					      const char *fmt, ...)
+{
+	return 0;
+}
+
 /* Trigger inline empty functions */
 static inline void led_trigger_register_simple(const char *name,
 					struct led_trigger **trigger) {}
@@ -342,6 +341,11 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev)
 	return NULL;
 }
 
+static inline int led_trigger_rename(struct led_trigger *trig, const char *fmt, ...)
+{
+	return 0;
+}
+
 #endif /* CONFIG_LEDS_TRIGGERS */
 
 /* Trigger specific functions */
-- 
2.17.0

^ permalink raw reply related

* [PATCH v3 2/3] can: simplify LED trigger handling
From: Uwe Kleine-König @ 2018-05-08 10:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180508100543.12559-1-u.kleine-koenig@pengutronix.de>

The new function led_trigger_register_format allows one to simplify LED
trigger handling considerably.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/net/can/led.c   | 30 +++++++-----------------------
 include/linux/can/dev.h |  3 ---
 2 files changed, 7 insertions(+), 26 deletions(-)

diff --git a/drivers/net/can/led.c b/drivers/net/can/led.c
index 2d7d1b0d20f9..111f9769e9da 100644
--- a/drivers/net/can/led.c
+++ b/drivers/net/can/led.c
@@ -81,19 +81,9 @@ void devm_can_led_init(struct net_device *netdev)
 		return;
 	}
 
-	snprintf(priv->tx_led_trig_name, sizeof(priv->tx_led_trig_name),
-		 "%s-tx", netdev->name);
-	snprintf(priv->rx_led_trig_name, sizeof(priv->rx_led_trig_name),
-		 "%s-rx", netdev->name);
-	snprintf(priv->rxtx_led_trig_name, sizeof(priv->rxtx_led_trig_name),
-		 "%s-rxtx", netdev->name);
-
-	led_trigger_register_simple(priv->tx_led_trig_name,
-				    &priv->tx_led_trig);
-	led_trigger_register_simple(priv->rx_led_trig_name,
-				    &priv->rx_led_trig);
-	led_trigger_register_simple(priv->rxtx_led_trig_name,
-				    &priv->rxtx_led_trig);
+	led_trigger_register_format(&priv->tx_led_trig, "%s-tx", netdev->name);
+	led_trigger_register_format(&priv->rx_led_trig, "%s-rx", netdev->name);
+	led_trigger_register_format(&priv->rxtx_led_trig, "%s-rxtx", netdev->name);
 
 	devres_add(&netdev->dev, res);
 }
@@ -105,23 +95,17 @@ static int can_led_notifier(struct notifier_block *nb, unsigned long msg,
 {
 	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
 	struct can_priv *priv = safe_candev_priv(netdev);
-	char name[CAN_LED_NAME_SZ];
 
 	if (!priv)
 		return NOTIFY_DONE;
 
-	if (!priv->tx_led_trig || !priv->rx_led_trig || !priv->rxtx_led_trig)
-		return NOTIFY_DONE;
-
 	if (msg == NETDEV_CHANGENAME) {
-		snprintf(name, sizeof(name), "%s-tx", netdev->name);
-		led_trigger_rename(priv->tx_led_trig, name);
+		led_trigger_rename(priv->tx_led_trig, "%s-tx", netdev->name);
 
-		snprintf(name, sizeof(name), "%s-rx", netdev->name);
-		led_trigger_rename(priv->rx_led_trig, name);
+		led_trigger_rename(priv->rx_led_trig, "%s-rx", netdev->name);
 
-		snprintf(name, sizeof(name), "%s-rxtx", netdev->name);
-		led_trigger_rename(priv->rxtx_led_trig, name);
+		led_trigger_rename(priv->rxtx_led_trig,
+				   "%s-rxtx", netdev->name);
 	}
 
 	return NOTIFY_DONE;
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 055aaf5ed9af..ff358269aa9c 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -73,11 +73,8 @@ struct can_priv {
 
 #ifdef CONFIG_CAN_LEDS
 	struct led_trigger *tx_led_trig;
-	char tx_led_trig_name[CAN_LED_NAME_SZ];
 	struct led_trigger *rx_led_trig;
-	char rx_led_trig_name[CAN_LED_NAME_SZ];
 	struct led_trigger *rxtx_led_trig;
-	char rxtx_led_trig_name[CAN_LED_NAME_SZ];
 #endif
 };
 
-- 
2.17.0

^ permalink raw reply related

* [PATCH v3 3/3] tty: implement led triggers
From: Uwe Kleine-König @ 2018-05-08 10:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180508100543.12559-1-u.kleine-koenig@pengutronix.de>

The rx trigger fires when data is pushed to the ldisc by the driver. This
is a bit later than the actual receiving of data but has the nice benefit
that it doesn't need adaption for each driver and isn't in the hot path.

Similarly the tx trigger fires when data was copied from userspace and is
given to the ldisc.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 arch/arm/boot/dts/imx25-logitech-baby.dts | 192 ++++++++++++++++++++++
 drivers/tty/Kconfig                       |   7 +
 drivers/tty/tty_buffer.c                  |   2 +
 drivers/tty/tty_io.c                      |   3 +
 drivers/tty/tty_port.c                    |  32 +++-
 include/linux/tty.h                       |  22 +++
 6 files changed, 256 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/boot/dts/imx25-logitech-baby.dts

diff --git a/arch/arm/boot/dts/imx25-logitech-baby.dts b/arch/arm/boot/dts/imx25-logitech-baby.dts
new file mode 100644
index 000000000000..39cf763d228b
--- /dev/null
+++ b/arch/arm/boot/dts/imx25-logitech-baby.dts
@@ -0,0 +1,192 @@
+/dts-v1/;
+#include "imx25.dtsi"
+
+/ {
+	model = "Logitech MX25 Baby";
+	compatible = "logitech,baby", "fsl,imx25";
+
+	chosen {
+		linux,stdout-path = &uart2;
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+
+	clock-frequency = <100000>;
+
+	status = "okay";
+
+	codec: tlv320aic3104 at 18 {
+		compatible = "ti,tlv320aic310x";
+		reg = <0x18>;
+//		HPVDD-supply
+//		SPRVDD-supply
+//		SPLVDD-supply
+//		AVDD-supply
+//		IOVDD-supply
+//		DVDD-supply
+//		?gpio-reset
+//		?ai31xx-micbias-vg
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+
+	clock-frequency = <100000>;
+
+	status = "okay";
+
+	msp430 at 10 {
+		reg = <0x10>;
+	};
+};
+
+&iomuxc {
+	baby {
+		pinctrl_fec: fecgrp {
+			fsl,pins = <
+				MX25_PAD_FEC_MDC__FEC_MDC		0x040
+				MX25_PAD_FEC_MDIO__FEC_MDIO		0x1f0
+				MX25_PAD_FEC_TDATA0__FEC_TDATA0		0x040
+				MX25_PAD_FEC_TDATA1__FEC_TDATA1		0x040
+				MX25_PAD_A22__FEC_TDATA2		0x000
+				MX25_PAD_A23__FEC_TDATA3		0x000
+				MX25_PAD_FEC_TX_EN__FEC_TX_EN		0x040
+				MX25_PAD_FEC_RDATA0__FEC_RDATA0		0x0c0
+				MX25_PAD_FEC_RDATA1__FEC_RDATA1		0x0c0
+				MX25_PAD_A20__FEC_RDATA2		0x000
+				MX25_PAD_A21__FEC_RDATA3		0x000
+				MX25_PAD_FEC_RX_DV__FEC_RX_DV		0x0c0
+				MX25_PAD_FEC_TX_CLK__FEC_TX_CLK		0x1c0
+				MX25_PAD_A17__FEC_TX_ERR		0x080
+				MX25_PAD_A19__FEC_RX_ERR		0x080
+				MX25_PAD_A24__FEC_RX_CLK		0x000
+				MX25_PAD_A18__FEC_COL			0x080
+				MX25_PAD_A25__FEC_CRS			0x080
+
+				/*
+				 * PHY_RESET:
+				 * hwref 1: MX25_PIN_A10
+				 * hwref 2: MX25_PIN_CSI_D7
+				 * hwref 3+: MX25_PIN_PWM
+				 */
+				MX25_PAD_PWM__GPIO_1_26			0x0c0
+			>;
+		};
+
+		pinctrl_i2c1: i2c1grp {
+			fsl,pins = <
+				MX25_PAD_I2C1_CLK__I2C1_CLK		0x0a8
+				MX25_PAD_I2C1_DAT__I2C1_DAT		0x0a8
+			>;
+		};
+
+		pinctrl_i2c2: i2c2grp {
+			fsl,pins = <
+				MX25_PAD_GPIO_C__I2C2_SCL		0x0e8
+				MX25_PAD_GPIO_D__I2C2_SDA		0x0a8
+			>;
+		};
+
+		pinctrl_nfc: nfcgrp {
+			fsl,pins = <
+				MX25_PAD_NFRB__NFRB			0x0
+				MX25_PAD_NFWP_B__NFWP_B			0x0
+				MX25_PAD_NFRE_B__NFRE_B			0x0
+				MX25_PAD_NFWE_B__NFWE_B			0x0
+				MX25_PAD_NFALE__NFALE			0x0
+				MX25_PAD_NFCLE__NFCLE			0x0
+				MX25_PAD_NF_CE0__NF_CE0			0x0
+				MX25_PAD_D0__D0				0x0
+				MX25_PAD_D1__D1				0x0
+				MX25_PAD_D2__D2				0x0
+				MX25_PAD_D3__D3				0x0
+				MX25_PAD_D4__D4				0x0
+				MX25_PAD_D5__D5				0x0
+				MX25_PAD_D6__D6				0x0
+				MX25_PAD_D7__D7				0x0
+			>;
+		};
+
+		pinctrl_uart2: uart2grp {
+			fsl,pins = <
+				MX25_PAD_UART2_RXD__UART2_RXD	0x1e0
+				MX25_PAD_UART2_TXD__UART2_TXD	0x0e0
+				/*
+				 * These are configured in the vendor kernel,
+				 * but the corresponding lines don't seem to be
+				 * available:
+				 * MX25_PAD_UART2_RTS__UART2_RTS	0x1e0
+				 * MX25_PAD_UART2_CTS__UART2_CTS	0x0e0
+				 */
+			>;
+		};
+	};
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_fec>;
+
+	//phy-reset-gpios = <&gpio1 26 0>;
+	phy-handle = <&ethphy>;
+	phy-mode = "rmii";
+
+	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy: ethernet-phy at 1 {
+			compatible = "ethernet-phy-ieee802.3-c22";
+			reg = <1>;
+			max-speed = <100>;
+		};
+	};
+};
+
+&kpp {
+	linux,keymap = <
+		0x000000cf	/* KEY_PLAY */
+		0x0001004e	/* KEY_KPPLUS */
+		0x00020069	/* KEY_LEFT */
+		0x00030066	/* KEY_HOME */
+		0x0100003b	/* KEY_F1 */
+		0x010100a4	/* KEY_PLAYPAUSE */
+		0x010200a3	/* KEY_NEXTSONG */
+		0x010300a5	/* KEY_PREVIOUSSONG */
+		0x0200003f	/* KEY_F5 */
+		0x0201003e	/* KEY_F4 */
+		0x0202003d	/* KEY_F3 */
+		0x0203003c	/* KEY_F2 */
+		0x03000000	/* KEY_RESERVED */
+		0x03010000	/* KEY_RESERVED */
+		0x0302008e	/* KEY_SLEEP */
+		0x03030040	/* KEY_F6 */
+		>;
+
+	status = "okay";
+};
+
+&nfc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_nfc>;
+
+	nand-on-flash-bbt;
+	nand-bus-width = <8>;
+	nand-ecc-mode = "hw";
+
+	status = "okay";
+};
+
+&uart2 {
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_uart2>;
+
+        status = "okay";
+};
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
index 0840d27381ea..b119c0fa1f5a 100644
--- a/drivers/tty/Kconfig
+++ b/drivers/tty/Kconfig
@@ -41,6 +41,13 @@ config VT
 	  If unsure, say Y, or else you won't be able to do much with your new
 	  shiny Linux system :-)
 
+config TTY_LEDS_TRIGGERS
+	bool "Enable support for TTY actions making LEDs blink"
+	depends on LEDS_TRIGGERS
+	---help---
+	  This enable support for tty triggers. It provides two LED triggers
+	  (rx and tx) for each TTY.
+
 config CONSOLE_TRANSLATIONS
 	depends on VT
 	default y
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index c996b6859c5e..364080ce8e91 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -521,6 +521,8 @@ static void flush_to_ldisc(struct work_struct *work)
 			continue;
 		}
 
+		tty_led_trigger_rx(port);
+
 		count = receive_buf(port, head, count);
 		if (!count)
 			break;
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 7c838b90a31d..8ef597dc0c3d 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -955,6 +955,9 @@ static inline ssize_t do_tty_write(
 		ret = -EFAULT;
 		if (copy_from_user(tty->write_buf, buf, size))
 			break;
+
+		tty_led_trigger_tx(tty->port);
+
 		ret = write(tty, file, tty->write_buf, size);
 		if (ret <= 0)
 			break;
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index 25d736880013..d313edfa6315 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -37,6 +37,8 @@ static int tty_port_default_receive_buf(struct tty_port *port,
 
 	ret = tty_ldisc_receive_buf(disc, p, (char *)f, count);
 
+	tty_led_trigger_rx(port);
+
 	tty_ldisc_deref(disc);
 
 	return ret;
@@ -163,8 +165,31 @@ struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
 		return dev;
 	}
 
-	return tty_register_device_attr(driver, index, device, drvdata,
-			attr_grp);
+	if (IS_ENABLED(CONFIG_TTY_LEDS_TRIGGERS)) {
+		int ret;
+
+		ret = led_trigger_register_format(&port->led_trigger_rx,
+						  "%s%d-rx", driver->name, index);
+		if (ret < 0)
+			pr_warn("Failed to register rx trigger for %s%d (%d)\n",
+				driver->name, index, ret);
+
+		ret = led_trigger_register_format(&port->led_trigger_tx,
+						  "%s%d-tx", driver->name, index);
+		if (ret < 0)
+			pr_warn("Failed to register tx trigger for %s%d (%d)\n",
+				driver->name, index, ret);
+	}
+
+	dev = tty_register_device_attr(driver, index,
+				       device, drvdata, attr_grp);
+
+	if (IS_ENABLED(CONFIG_TTY_LEDS_TRIGGERS) && IS_ERR(dev)) {
+		led_trigger_unregister_simple(port->led_trigger_tx);
+		led_trigger_unregister_simple(port->led_trigger_rx);
+	}
+
+	return dev;
 }
 EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev);
 
@@ -206,6 +231,9 @@ void tty_port_unregister_device(struct tty_port *port,
 	if (ret == 0)
 		return;
 
+	led_trigger_unregister_simple(port->led_trigger_rx);
+	led_trigger_unregister_simple(port->led_trigger_tx);
+
 	tty_unregister_device(driver, index);
 }
 EXPORT_SYMBOL_GPL(tty_port_unregister_device);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 1dd587ba6d88..7e48de671bfa 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -13,6 +13,7 @@
 #include <uapi/linux/tty.h>
 #include <linux/rwsem.h>
 #include <linux/llist.h>
+#include <linux/leds.h>
 
 
 /*
@@ -249,8 +250,29 @@ struct tty_port {
 						   set to size of fifo */
 	struct kref		kref;		/* Ref counter */
 	void 			*client_data;
+
+	struct led_trigger	*led_trigger_rx;
+	struct led_trigger	*led_trigger_tx;
 };
 
+static inline void tty_led_trigger(struct led_trigger *trig)
+{
+	unsigned long delay_ms = 50;
+
+	if (IS_ENABLED(CONFIG_TTY_LEDS_TRIGGERS))
+		led_trigger_blink_oneshot(trig, &delay_ms, &delay_ms, 0);
+}
+
+static inline void tty_led_trigger_rx(struct tty_port *port)
+{
+	tty_led_trigger(port->led_trigger_rx);
+}
+
+static inline void tty_led_trigger_tx(struct tty_port *port)
+{
+	tty_led_trigger(port->led_trigger_tx);
+}
+
 /* tty_port::iflags bits -- use atomic bit ops */
 #define TTY_PORT_INITIALIZED	0	/* device is initialized */
 #define TTY_PORT_SUSPENDED	1	/* device is suspended */
-- 
2.17.0

^ permalink raw reply related

* [PATCH v3 3/3] tty: implement led triggers
From: Johan Hovold @ 2018-05-08 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180508100543.12559-4-u.kleine-koenig@pengutronix.de>

On Tue, May 08, 2018 at 12:05:43PM +0200, Uwe Kleine-K?nig wrote:
> The rx trigger fires when data is pushed to the ldisc by the driver. This
> is a bit later than the actual receiving of data but has the nice benefit
> that it doesn't need adaption for each driver and isn't in the hot path.
> 
> Similarly the tx trigger fires when data was copied from userspace and is
> given to the ldisc.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
> ---
>  arch/arm/boot/dts/imx25-logitech-baby.dts | 192 ++++++++++++++++++++++

Looks like you included more than intended in this patch.

>  drivers/tty/Kconfig                       |   7 +
>  drivers/tty/tty_buffer.c                  |   2 +
>  drivers/tty/tty_io.c                      |   3 +
>  drivers/tty/tty_port.c                    |  32 +++-
>  include/linux/tty.h                       |  22 +++
>  6 files changed, 256 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm/boot/dts/imx25-logitech-baby.dts

Johan

^ permalink raw reply

* [PATCH v5 06/14] KVM: arm64: Optimise FPSIMD handling to reduce guest/host thrashing
From: Dave Martin @ 2018-05-08 10:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <e87c6940-1c79-ccd4-c6ad-2d87790b2e00@arm.com>

On Tue, May 08, 2018 at 10:58:04AM +0100, Marc Zyngier wrote:
> On 04/05/18 17:05, Dave Martin wrote:
> > This patch refactors KVM to align the host and guest FPSIMD
> > save/restore logic with each other for arm64.  This reduces the
> > number of redundant save/restore operations that must occur, and
> > reduces the common-case IRQ blackout time during guest exit storms
> > by saving the host state lazily and optimising away the need to
> > restore the host state before returning to the run loop.
> > 
> > Four hooks are defined in order to enable this:
> > 
> >  * kvm_arch_vcpu_run_map_fp():
> >    Called on PID change to map necessary bits of current to Hyp.
> > 
> >  * kvm_arch_vcpu_load_fp():
> >    Set up FP/SIMD for entering the KVM run loop (parse as
> >    "vcpu_load fp").
> > 
> >  * kvm_arch_vcpu_park_fp():
> >    Get FP/SIMD into a safe state for re-enabling interrupts after a
> >    guest exit back to the run loop.
> > 
> >    For arm64 specifically, this involves updating the host kernel's
> >    FPSIMD context tracking metadata so that kernel-mode NEON use
> >    will cause the vcpu's FPSIMD state to be saved back correctly
> >    into the vcpu struct.  This must be done before re-enabling
> >    interrupts because kernel-mode NEON may be used my softirqs.
> 
> s/my/by/
> 
> I must admit being slightly confused by the word "park". I tend to read
> "park" as "stash away for later use", while it really is "update the
> kernel's view of who is actually in control of the FP registers".

I was thinking park as in parking disk heads, i.e., get things so we can
kick FPSIMD without doing damage.

(Or indeed, applying the handbrake so your car doesn't roll away
downhill while you're gone.)

But of a strained analogy though, I'll admit.

> No, I don't have a better name for it... ;-) But maybe something along
> the lines of "hwsync_fp", in order to be consistent with the rest of the
> code that deals with shared resources?

To me, "hw" carries too much of a suggestion that we would be flushing
the registers back to memory.  In fact, we don't touch the hardware
here, only kernel bookkeeping data.

Trying to come up with an intuitive name for this may be futile; how
about

 * _sync_ (which is suitably vague), or
 * _ctxsync_ (which will avoid fooling people into thinking they know
	what it does without looking at the code)

?

[...]

> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 469de8a..811097e 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -30,6 +30,7 @@
> >  #include <asm/kvm.h>
> >  #include <asm/kvm_asm.h>
> >  #include <asm/kvm_mmio.h>
> > +#include <asm/thread_info.h>
> >  
> >  #define __KVM_HAVE_ARCH_INTC_INITIALIZED
> >  
> > @@ -238,6 +239,12 @@ struct kvm_vcpu_arch {
> >  
> >  	/* Pointer to host CPU context */
> >  	kvm_cpu_context_t *host_cpu_context;
> > +
> > +	struct thread_info *host_thread_info;	/* hyp VA */
> > +	struct user_fpsimd_state *host_fpsimd_state;	/* hyp VA */
> > +	bool host_sve_in_use;	/* backup for host TIF_SVE while in guest */
> > +	bool fp_enabled;
> 
> Could we consider merging these two fields together with debug_flags?
> Overall, they share a common purpose (tracking the use of a resource
> shared between host and guest). Not necessarily something to do
> immediately though.

I expect so.  I added these as bools partly for simplicity and partly
because there was no general-purpose flags field already.

We could make debug_flags into a general-purpose flags field, though.

Once we've agreed about the park_fp renaming, I'll consider reworking
this also -- but I'll punt it to a separate patch if it turns out to be
non-trivial.

[...]

> Other than the couple of minor nits above,
> 
> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

Thanks
---Dave

^ permalink raw reply

* [PATCH 1/3] dma-debug: move initialization to common code
From: Marek Szyprowski @ 2018-05-08 10:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180424140235.9125-2-hch@lst.de>

Hi Christoph,

On 2018-04-24 16:02, Christoph Hellwig wrote:
> Most mainstream architectures are using 65536 entries, so lets stick to
> that.  If someone is really desperate to override it that can still be
> done through <asm/dma-mapping.h>, but I'd rather see a really good
> rationale for that.
>
> dma_debug_init is now called as a core_initcall, which for many
> architectures means much earlier, and provides dma-debug functionality
> earlier in the boot process.  This should be safe as it only relies
> on the memory allocator already being available.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Nice! Unification of this is definitely needed and solves the issues
reported some time ago:

https://patchwork.kernel.org/patch/9429637/ (arm)
https://patchwork.kernel.org/patch/9431161/ (arm64, rejected)

Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>

> ---
>   arch/arm/mm/dma-mapping-nommu.c |  9 ---------
>   arch/arm/mm/dma-mapping.c       |  9 ---------
>   arch/arm64/mm/dma-mapping.c     | 10 ----------
>   arch/c6x/kernel/dma.c           | 11 -----------
>   arch/ia64/kernel/dma-mapping.c  | 10 ----------
>   arch/microblaze/kernel/dma.c    | 11 -----------
>   arch/mips/mm/dma-default.c      | 10 ----------
>   arch/openrisc/kernel/dma.c      | 11 -----------
>   arch/powerpc/kernel/dma.c       |  3 ---
>   arch/s390/pci/pci_dma.c         |  9 ---------
>   arch/sh/mm/consistent.c         |  9 ---------
>   arch/sparc/kernel/Makefile      |  2 --
>   arch/sparc/kernel/dma.c         | 13 -------------
>   arch/x86/kernel/pci-dma.c       |  4 ----
>   arch/xtensa/kernel/pci-dma.c    |  9 ---------
>   include/linux/dma-debug.h       |  6 ------
>   lib/dma-debug.c                 | 21 ++++++++++++++-------
>   17 files changed, 14 insertions(+), 143 deletions(-)
>   delete mode 100644 arch/sparc/kernel/dma.c
>
> diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
> index 619f24a42d09..f448a0663b10 100644
> --- a/arch/arm/mm/dma-mapping-nommu.c
> +++ b/arch/arm/mm/dma-mapping-nommu.c
> @@ -241,12 +241,3 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>   void arch_teardown_dma_ops(struct device *dev)
>   {
>   }
> -
> -#define PREALLOC_DMA_DEBUG_ENTRIES	4096
> -
> -static int __init dma_debug_do_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -core_initcall(dma_debug_do_init);
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 8c398fedbbb6..c26bf83f44ca 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1165,15 +1165,6 @@ int arm_dma_supported(struct device *dev, u64 mask)
>   	return __dma_supported(dev, mask, false);
>   }
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES	4096
> -
> -static int __init dma_debug_do_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -core_initcall(dma_debug_do_init);
> -
>   #ifdef CONFIG_ARM_DMA_USE_IOMMU
>   
>   static int __dma_info_to_prot(enum dma_data_direction dir, unsigned long attrs)
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index a96ec0181818..db01f2709842 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -508,16 +508,6 @@ static int __init arm64_dma_init(void)
>   }
>   arch_initcall(arm64_dma_init);
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES	4096
> -
> -static int __init dma_debug_do_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -fs_initcall(dma_debug_do_init);
> -
> -
>   #ifdef CONFIG_IOMMU_DMA
>   #include <linux/dma-iommu.h>
>   #include <linux/platform_device.h>
> diff --git a/arch/c6x/kernel/dma.c b/arch/c6x/kernel/dma.c
> index 9fff8be75f58..31e1a9ec3a9c 100644
> --- a/arch/c6x/kernel/dma.c
> +++ b/arch/c6x/kernel/dma.c
> @@ -136,14 +136,3 @@ const struct dma_map_ops c6x_dma_ops = {
>   	.sync_sg_for_cpu	= c6x_dma_sync_sg_for_cpu,
>   };
>   EXPORT_SYMBOL(c6x_dma_ops);
> -
> -/* Number of entries preallocated for DMA-API debugging */
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -
> -	return 0;
> -}
> -fs_initcall(dma_init);
> diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c
> index f2d57e66fd86..7a471d8d67d4 100644
> --- a/arch/ia64/kernel/dma-mapping.c
> +++ b/arch/ia64/kernel/dma-mapping.c
> @@ -9,16 +9,6 @@ int iommu_detected __read_mostly;
>   const struct dma_map_ops *dma_ops;
>   EXPORT_SYMBOL(dma_ops);
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -
> -	return 0;
> -}
> -fs_initcall(dma_init);
> -
>   const struct dma_map_ops *dma_get_ops(struct device *dev)
>   {
>   	return dma_ops;
> diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
> index c91e8cef98dd..3145e7dc8ab1 100644
> --- a/arch/microblaze/kernel/dma.c
> +++ b/arch/microblaze/kernel/dma.c
> @@ -184,14 +184,3 @@ const struct dma_map_ops dma_nommu_ops = {
>   	.sync_sg_for_device	= dma_nommu_sync_sg_for_device,
>   };
>   EXPORT_SYMBOL(dma_nommu_ops);
> -
> -/* Number of entries preallocated for DMA-API debugging */
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -
> -	return 0;
> -}
> -fs_initcall(dma_init);
> diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
> index dcafa43613b6..f9fef0028ca2 100644
> --- a/arch/mips/mm/dma-default.c
> +++ b/arch/mips/mm/dma-default.c
> @@ -402,13 +402,3 @@ static const struct dma_map_ops mips_default_dma_map_ops = {
>   
>   const struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops;
>   EXPORT_SYMBOL(mips_dma_map_ops);
> -
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init mips_dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -
> -	return 0;
> -}
> -fs_initcall(mips_dma_init);
> diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c
> index a945f00011b4..ec7fd45704d2 100644
> --- a/arch/openrisc/kernel/dma.c
> +++ b/arch/openrisc/kernel/dma.c
> @@ -247,14 +247,3 @@ const struct dma_map_ops or1k_dma_map_ops = {
>   	.sync_single_for_device = or1k_sync_single_for_device,
>   };
>   EXPORT_SYMBOL(or1k_dma_map_ops);
> -
> -/* Number of entries preallocated for DMA-API debugging */
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -
> -	return 0;
> -}
> -fs_initcall(dma_init);
> diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
> index da20569de9d4..138157deeadf 100644
> --- a/arch/powerpc/kernel/dma.c
> +++ b/arch/powerpc/kernel/dma.c
> @@ -309,8 +309,6 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
>   }
>   EXPORT_SYMBOL(dma_set_coherent_mask);
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
>   int dma_set_mask(struct device *dev, u64 dma_mask)
>   {
>   	if (ppc_md.dma_set_mask)
> @@ -361,7 +359,6 @@ EXPORT_SYMBOL_GPL(dma_get_required_mask);
>   
>   static int __init dma_init(void)
>   {
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
>   #ifdef CONFIG_PCI
>   	dma_debug_add_bus(&pci_bus_type);
>   #endif
> diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
> index 2d15d84c20ed..5dee7a922589 100644
> --- a/arch/s390/pci/pci_dma.c
> +++ b/arch/s390/pci/pci_dma.c
> @@ -668,15 +668,6 @@ void zpci_dma_exit(void)
>   	kmem_cache_destroy(dma_region_table_cache);
>   }
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES	(1 << 16)
> -
> -static int __init dma_debug_do_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -fs_initcall(dma_debug_do_init);
> -
>   const struct dma_map_ops s390_pci_dma_ops = {
>   	.alloc		= s390_dma_alloc,
>   	.free		= s390_dma_free,
> diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
> index 8ce98691d822..35ea3099a3b6 100644
> --- a/arch/sh/mm/consistent.c
> +++ b/arch/sh/mm/consistent.c
> @@ -20,18 +20,9 @@
>   #include <asm/cacheflush.h>
>   #include <asm/addrspace.h>
>   
> -#define PREALLOC_DMA_DEBUG_ENTRIES	4096
> -
>   const struct dma_map_ops *dma_ops;
>   EXPORT_SYMBOL(dma_ops);
>   
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -fs_initcall(dma_init);
> -
>   void *dma_generic_alloc_coherent(struct device *dev, size_t size,
>   				 dma_addr_t *dma_handle, gfp_t gfp,
>   				 unsigned long attrs)
> diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
> index 76cb57750dda..84cfc5a428d6 100644
> --- a/arch/sparc/kernel/Makefile
> +++ b/arch/sparc/kernel/Makefile
> @@ -74,8 +74,6 @@ obj-$(CONFIG_SPARC64)	+= pcr.o
>   obj-$(CONFIG_SPARC64)	+= nmi.o
>   obj-$(CONFIG_SPARC64_SMP) += cpumap.o
>   
> -obj-y                     += dma.o
> -
>   obj-$(CONFIG_PCIC_PCI)    += pcic.o
>   obj-$(CONFIG_LEON_PCI)    += leon_pci.o
>   obj-$(CONFIG_SPARC_GRPCI2)+= leon_pci_grpci2.o
> diff --git a/arch/sparc/kernel/dma.c b/arch/sparc/kernel/dma.c
> deleted file mode 100644
> index f73e7597c971..000000000000
> --- a/arch/sparc/kernel/dma.c
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -#include <linux/kernel.h>
> -#include <linux/dma-mapping.h>
> -#include <linux/dma-debug.h>
> -
> -#define PREALLOC_DMA_DEBUG_ENTRIES       (1 << 15)
> -
> -static int __init dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -fs_initcall(dma_init);
> diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
> index 77625b60a510..bcbaa2e8031e 100644
> --- a/arch/x86/kernel/pci-dma.c
> +++ b/arch/x86/kernel/pci-dma.c
> @@ -55,9 +55,6 @@ struct device x86_dma_fallback_dev = {
>   };
>   EXPORT_SYMBOL(x86_dma_fallback_dev);
>   
> -/* Number of entries preallocated for DMA-API debugging */
> -#define PREALLOC_DMA_DEBUG_ENTRIES       65536
> -
>   void __init pci_iommu_alloc(void)
>   {
>   	struct iommu_table_entry *p;
> @@ -189,7 +186,6 @@ EXPORT_SYMBOL(arch_dma_supported);
>   static int __init pci_iommu_init(void)
>   {
>   	struct iommu_table_entry *p;
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
>   
>   #ifdef CONFIG_PCI
>   	dma_debug_add_bus(&pci_bus_type);
> diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
> index 732631ce250f..392b4a80ebc2 100644
> --- a/arch/xtensa/kernel/pci-dma.c
> +++ b/arch/xtensa/kernel/pci-dma.c
> @@ -261,12 +261,3 @@ const struct dma_map_ops xtensa_dma_map_ops = {
>   	.mapping_error = xtensa_dma_mapping_error,
>   };
>   EXPORT_SYMBOL(xtensa_dma_map_ops);
> -
> -#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> -
> -static int __init xtensa_dma_init(void)
> -{
> -	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
> -	return 0;
> -}
> -fs_initcall(xtensa_dma_init);
> diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h
> index c7d844f09c3a..a785f2507159 100644
> --- a/include/linux/dma-debug.h
> +++ b/include/linux/dma-debug.h
> @@ -30,8 +30,6 @@ struct bus_type;
>   
>   extern void dma_debug_add_bus(struct bus_type *bus);
>   
> -extern void dma_debug_init(u32 num_entries);
> -
>   extern int dma_debug_resize_entries(u32 num_entries);
>   
>   extern void debug_dma_map_page(struct device *dev, struct page *page,
> @@ -100,10 +98,6 @@ static inline void dma_debug_add_bus(struct bus_type *bus)
>   {
>   }
>   
> -static inline void dma_debug_init(u32 num_entries)
> -{
> -}
> -
>   static inline int dma_debug_resize_entries(u32 num_entries)
>   {
>   	return 0;
> diff --git a/lib/dma-debug.c b/lib/dma-debug.c
> index 7f5cdc1e6b29..712a897174e4 100644
> --- a/lib/dma-debug.c
> +++ b/lib/dma-debug.c
> @@ -41,6 +41,11 @@
>   #define HASH_FN_SHIFT   13
>   #define HASH_FN_MASK    (HASH_SIZE - 1)
>   
> +/* allow architectures to override this if absolutely required */
> +#ifndef PREALLOC_DMA_DEBUG_ENTRIES
> +#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
> +#endif
> +
>   enum {
>   	dma_debug_single,
>   	dma_debug_page,
> @@ -1004,18 +1009,16 @@ void dma_debug_add_bus(struct bus_type *bus)
>   	bus_register_notifier(bus, nb);
>   }
>   
> -/*
> - * Let the architectures decide how many entries should be preallocated.
> - */
> -void dma_debug_init(u32 num_entries)
> +static int dma_debug_init(void)
>   {
> +	u32 num_entries;
>   	int i;
>   
>   	/* Do not use dma_debug_initialized here, since we really want to be
>   	 * called to set dma_debug_initialized
>   	 */
>   	if (global_disable)
> -		return;
> +		return 0;
>   
>   	for (i = 0; i < HASH_SIZE; ++i) {
>   		INIT_LIST_HEAD(&dma_entry_hash[i].list);
> @@ -1026,17 +1029,19 @@ void dma_debug_init(u32 num_entries)
>   		pr_err("DMA-API: error creating debugfs entries - disabling\n");
>   		global_disable = true;
>   
> -		return;
> +		return 0;
>   	}
>   
>   	if (req_entries)
>   		num_entries = req_entries;
> +	else
> +		num_entries = PREALLOC_DMA_DEBUG_ENTRIES;
>   
>   	if (prealloc_memory(num_entries) != 0) {
>   		pr_err("DMA-API: debugging out of memory error - disabled\n");
>   		global_disable = true;
>   
> -		return;
> +		return 0;
>   	}
>   
>   	nr_total_entries = num_free_entries;
> @@ -1044,7 +1049,9 @@ void dma_debug_init(u32 num_entries)
>   	dma_debug_initialized = true;
>   
>   	pr_info("DMA-API: debugging enabled by kernel config\n");
> +	return 0;
>   }
> +core_initcall(dma_debug_init);
>   
>   static __init int dma_debug_cmdline(char *str)
>   {

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply

* [PATCH] arm: port KCOV to arm
From: Russell King - ARM Linux @ 2018-05-08 10:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180426130846.130976-1-dvyukov@google.com>

On Thu, Apr 26, 2018 at 03:08:46PM +0200, Dmitry Vyukov wrote:
> KCOV is code coverage collection facility used, in particular, by syzkaller
> system call fuzzer. There is some interest in using syzkaller on arm devices.
> So port KCOV to arm.
> 
> On implementation level this merely declares that KCOV is supported and
> disables instrumentation of 3 special cases. Reasons for disabling are
> commented in code.
> 
> Tested with qemu-system-arm/vexpress-a15.
> 
> Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Abbott Liu <liuwenliang@huawei.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Koguchi Takuo <takuo.koguchi.sw@hitachi.com>
> Cc: Atul Prakash <atulp@google.com>
> Cc: linux at armlinux.org.uk
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: syzkaller at googlegroups.com
> ---
>  arch/arm/Kconfig                  | 1 +
>  arch/arm/boot/compressed/Makefile | 3 +++
>  arch/arm/mm/Makefile              | 4 ++++
>  arch/arm/vdso/Makefile            | 3 +++
>  4 files changed, 11 insertions(+)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index a7f8e7f4b88f..60558a6bb744 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -105,6 +105,7 @@ config ARM
>  	select REFCOUNT_FULL
>  	select RTC_LIB
>  	select SYS_SUPPORTS_APM_EMULATION
> +	select ARCH_HAS_KCOV
>  	# Above selects are sorted alphabetically; please add new ones
>  	# according to that.  Thanks.

Please read this comment and rework your patch, thanks.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply

* [PATCH 7/7] ARM: dts: Fix DTC warnings
From: Robin Murphy @ 2018-05-08 10:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180506134352.2637-8-linus.walleij@linaro.org>

On 06/05/18 14:43, Linus Walleij wrote:
> The DTC was warning a lot about unit names etc, I think I fixed
> them all. One warning remains:
> 
> arch/arm/boot/dts/gemini-rut1xx.dtb: Warning (unit_address_vs_reg):
>   /memory: node has a reg or ranges property, but no unit name
> 
> This comes up all the time even though memory is stated as
> memory at 0 for all boards, I guess this is a bug in the DTC
> syntax checker, like it cannot really differentiate between
> @0 and no unit name at all for the memory node.

That might be because it's pulling in skeleton.dtsi, since I think 
"memory at 0" and "memory" are treated as distinct nodes, such that the 
former from the board DTS no longer overrides the latter from skeleton 
and you end up with both.

Robin.

> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>   arch/arm/boot/dts/gemini-dlink-dir-685.dts |  5 ++---
>   arch/arm/boot/dts/gemini-dlink-dns-313.dts |  5 ++---
>   arch/arm/boot/dts/gemini-nas4220b.dts      | 12 +++++-------
>   arch/arm/boot/dts/gemini-rut1xx.dts        | 10 ++++------
>   arch/arm/boot/dts/gemini-sq201.dts         | 10 ++++------
>   arch/arm/boot/dts/gemini-wbd111.dts        | 15 +++++++--------
>   arch/arm/boot/dts/gemini-wbd222.dts        | 14 ++++++--------
>   7 files changed, 30 insertions(+), 41 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini-dlink-dir-685.dts
> index 89ce0d1916e3..fb5c954ab95a 100644
> --- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts
> +++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts
> @@ -13,7 +13,7 @@
>   	#address-cells = <1>;
>   	#size-cells = <1>;
>   
> -	memory {
> +	memory at 0 {
>   		/* 128 MB SDRAM in 2 x Hynix HY5DU121622DTP-D43 */
>   		device_type = "memory";
>   		reg = <0x00000000 0x8000000>;
> @@ -26,8 +26,7 @@
>   
>   	gpio_keys {
>   		compatible = "gpio-keys";
> -		#address-cells = <1>;
> -		#size-cells = <0>;
> +
>   		button-esc {
>   			debounce-interval = <50>;
>   			wakeup-source;
> diff --git a/arch/arm/boot/dts/gemini-dlink-dns-313.dts b/arch/arm/boot/dts/gemini-dlink-dns-313.dts
> index da78a0aa389a..d1329322b968 100644
> --- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts
> +++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts
> @@ -15,7 +15,7 @@
>   	#address-cells = <1>;
>   	#size-cells = <1>;
>   
> -	memory {
> +	memory at 0 {
>   		/* 64 MB SDRAM in a Nanya NT5DS32M16BS-6K package */
>   		device_type = "memory";
>   		reg = <0x00000000 0x4000000>;
> @@ -32,8 +32,7 @@
>   
>   	gpio_keys {
>   		compatible = "gpio-keys";
> -		#address-cells = <1>;
> -		#size-cells = <0>;
> +
>   		button-esc {
>   			debounce-interval = <50>;
>   			wakeup-source;
> diff --git a/arch/arm/boot/dts/gemini-nas4220b.dts b/arch/arm/boot/dts/gemini-nas4220b.dts
> index 9f78803b2456..963ea890c87f 100644
> --- a/arch/arm/boot/dts/gemini-nas4220b.dts
> +++ b/arch/arm/boot/dts/gemini-nas4220b.dts
> @@ -14,7 +14,7 @@
>   	#address-cells = <1>;
>   	#size-cells = <1>;
>   
> -	memory { /* 128 MB */
> +	memory at 0 { /* 128 MB */
>   		device_type = "memory";
>   		reg = <0x00000000 0x8000000>;
>   	};
> @@ -26,10 +26,8 @@
>   
>   	gpio_keys {
>   		compatible = "gpio-keys";
> -		#address-cells = <1>;
> -		#size-cells = <0>;
>   
> -		button at 29 {
> +		button-setup {
>   			debounce-interval = <50>;
>   			wakeup-source;
>   			linux,code = <KEY_SETUP>;
> @@ -37,7 +35,7 @@
>   			/* Conflict with TVC */
>   			gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
>   		};
> -		button at 31 {
> +		button-restart {
>   			debounce-interval = <50>;
>   			wakeup-source;
>   			linux,code = <KEY_RESTART>;
> @@ -49,13 +47,13 @@
>   
>   	leds {
>   		compatible = "gpio-leds";
> -		led at 28 {
> +		led-orange-hdd {
>   			label = "nas4220b:orange:hdd";
>   			/* Conflict with TVC */
>   			gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
>   			default-state = "on";
>   		};
> -		led at 30 {
> +		led-green-os {
>   			label = "nas4220b:green:os";
>   			/* Conflict with TVC */
>   			gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
> diff --git a/arch/arm/boot/dts/gemini-rut1xx.dts b/arch/arm/boot/dts/gemini-rut1xx.dts
> index a2f14ee37599..eb4f0bf074da 100644
> --- a/arch/arm/boot/dts/gemini-rut1xx.dts
> +++ b/arch/arm/boot/dts/gemini-rut1xx.dts
> @@ -14,7 +14,7 @@
>   	#address-cells = <1>;
>   	#size-cells = <1>;
>   
> -	memory { /* 128 MB */
> +	memory at 0 { /* 128 MB */
>   		device_type = "memory";
>   		reg = <0x00000000 0x8000000>;
>   	};
> @@ -26,10 +26,8 @@
>   
>   	gpio_keys {
>   		compatible = "gpio-keys";
> -		#address-cells = <1>;
> -		#size-cells = <0>;
>   
> -		button at 28 {
> +		button-setup {
>   			debounce-interval = <50>;
>   			wakeup-source;
>   			linux,code = <KEY_SETUP>;
> @@ -41,14 +39,14 @@
>   
>   	leds {
>   		compatible = "gpio-leds";
> -		led at 7 {
> +		led-gsm {
>   			/* FIXME: add the LED color */
>   			label = "rut1xx::gsm";
>   			/* Conflict with ICE */
>   			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
>   			default-state = "on";
>   		};
> -		led at 31 {
> +		led-power {
>   			/* FIXME: add the LED color */
>   			label = "rut1xx::power";
>   			/* Conflict with NAND CE0 */
> diff --git a/arch/arm/boot/dts/gemini-sq201.dts b/arch/arm/boot/dts/gemini-sq201.dts
> index 229c0267617a..e5cf9d1a98cd 100644
> --- a/arch/arm/boot/dts/gemini-sq201.dts
> +++ b/arch/arm/boot/dts/gemini-sq201.dts
> @@ -14,7 +14,7 @@
>   	#address-cells = <1>;
>   	#size-cells = <1>;
>   
> -	memory { /* 128 MB */
> +	memory at 0 { /* 128 MB */
>   		device_type = "memory";
>   		reg = <0x00000000 0x8000000>;
>   	};
> @@ -26,10 +26,8 @@
>   
>   	gpio_keys {
>   		compatible = "gpio-keys";
> -		#address-cells = <1>;
> -		#size-cells = <0>;
>   
> -		button at 18 {
> +		button-setup {
>   			debounce-interval = <50>;
>   			wakeup-source;
>   			linux,code = <KEY_SETUP>;
> @@ -41,14 +39,14 @@
>   
>   	leds {
>   		compatible = "gpio-leds";
> -		led at 20 {
> +		led-green-info {
>   			label = "sq201:green:info";
>   			/* Conflict with parallel flash */
>   			gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
>   			default-state = "on";
>   			linux,default-trigger = "heartbeat";
>   		};
> -		led at 31 {
> +		led-green-usb {
>   			label = "sq201:green:usb";
>   			/* Conflict with parallel and NAND flash */
>   			gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
> diff --git a/arch/arm/boot/dts/gemini-wbd111.dts b/arch/arm/boot/dts/gemini-wbd111.dts
> index b31a9189083f..29af86cd10f7 100644
> --- a/arch/arm/boot/dts/gemini-wbd111.dts
> +++ b/arch/arm/boot/dts/gemini-wbd111.dts
> @@ -14,7 +14,8 @@
>   	#address-cells = <1>;
>   	#size-cells = <1>;
>   
> -	memory { /* 128 MB */
> +	memory at 0 {
> +		/* 128 MB */
>   		device_type = "memory";
>   		reg = <0x00000000 0x8000000>;
>   	};
> @@ -26,10 +27,8 @@
>   
>   	gpio_keys {
>   		compatible = "gpio-keys";
> -		#address-cells = <1>;
> -		#size-cells = <0>;
>   
> -		button at 5 {
> +		button-setup {
>   			debounce-interval = <50>;
>   			wakeup-source;
>   			linux,code = <KEY_SETUP>;
> @@ -42,25 +41,25 @@
>   	leds {
>   		compatible = "gpio-leds";
>   
> -		led at 1 {
> +		led-red-l3 {
>   			label = "wbd111:red:L3";
>   			/* Conflict with TVC and extended parallel flash */
>   			gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
>   			default-state = "off";
>   		};
> -		led at 2 {
> +		led-green-l4 {
>   			label = "wbd111:green:L4";
>   			/* Conflict with TVC and extended parallel flash */
>   			gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
>   			default-state = "off";
>   		};
> -		led at 3 {
> +		led-red-l4 {
>   			label = "wbd111:red:L4";
>   			/* Conflict with TVC and extended parallel flash */
>   			gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
>   			default-state = "off";
>   		};
> -		led at 5 {
> +		led-greeb-l3 {
>   			label = "wbd111:green:L3";
>   			/* Conflict with TVC and extended parallel flash */
>   			gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
> diff --git a/arch/arm/boot/dts/gemini-wbd222.dts b/arch/arm/boot/dts/gemini-wbd222.dts
> index 0be867fbfc69..24e6ae3616f7 100644
> --- a/arch/arm/boot/dts/gemini-wbd222.dts
> +++ b/arch/arm/boot/dts/gemini-wbd222.dts
> @@ -14,7 +14,7 @@
>   	#address-cells = <1>;
>   	#size-cells = <1>;
>   
> -	memory { /* 128 MB */
> +	memory at 0 { /* 128 MB */
>   		device_type = "memory";
>   		reg = <0x00000000 0x8000000>;
>   	};
> @@ -26,10 +26,8 @@
>   
>   	gpio_keys {
>   		compatible = "gpio-keys";
> -		#address-cells = <1>;
> -		#size-cells = <0>;
>   
> -		button at 5 {
> +		button-setup {
>   			debounce-interval = <50>;
>   			wakeup-source;
>   			linux,code = <KEY_SETUP>;
> @@ -42,25 +40,25 @@
>   	leds {
>   		compatible = "gpio-leds";
>   
> -		led at 1 {
> +		led-red-l3 {
>   			label = "wbd111:red:L3";
>   			/* Conflict with TVC and extended parallel flash */
>   			gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
>   			default-state = "off";
>   		};
> -		led at 2 {
> +		led-green-l4 {
>   			label = "wbd111:green:L4";
>   			/* Conflict with TVC and extended parallel flash */
>   			gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
>   			default-state = "off";
>   		};
> -		led at 3 {
> +		led-red-l4 {
>   			label = "wbd111:red:L4";
>   			/* Conflict with TVC and extended parallel flash */
>   			gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
>   			default-state = "off";
>   		};
> -		led at 5 {
> +		led-green-l3 {
>   			label = "wbd111:green:L3";
>   			/* Conflict with TVC and extended parallel flash */
>   			gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
> 

^ permalink raw reply

* [PATCH v5 10/14] KVM: arm64: Save host SVE context as appropriate
From: Marc Zyngier @ 2018-05-08 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525449935-31424-11-git-send-email-Dave.Martin@arm.com>

On 04/05/18 17:05, Dave Martin wrote:
> This patch adds SVE context saving to the hyp FPSIMD context switch
> path.  This means that it is no longer necessary to save the host
> SVE state in advance of entering the guest, when in use.
> 
> In order to avoid adding pointless complexity to the code, VHE is
> assumed if SVE is in use.  VHE is an architectural prerequisite for
> SVE, so there is no good reason to turn CONFIG_ARM64_VHE off in
> kernels that support both SVE and KVM.
> 
> Historically, software models exist that can expose the
> architecturally invalid configuration of SVE without VHE, so if
> this situation is detected this patch warns and refuses to create a
> VM.  Doing this check at VM creation time avoids race issues
> between KVM and SVE initialisation.
> 
> Signed-off-by: Dave Martin <Dave.Martin@arm.com>
> Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
> ---
>  arch/arm64/Kconfig          |  7 +++++++
>  arch/arm64/kvm/fpsimd.c     |  1 -
>  arch/arm64/kvm/hyp/switch.c | 21 +++++++++++++++++++--
>  virt/kvm/arm/arm.c          | 18 ++++++++++++++++++
>  4 files changed, 44 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index eb2cf49..b0d3820 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1130,6 +1130,7 @@ endmenu
>  config ARM64_SVE
>  	bool "ARM Scalable Vector Extension support"
>  	default y
> +	depends on !KVM || ARM64_VHE

In that case, should we consider making ARM64_VHE "default y" as well,
as KVM is "default y" too?

Otherwise, I fear we end-up regressing existing configurations. Also,
you still have to check for the configuration at run time, so I'm not
immediately getting the point of this particular change.

>  	help
>  	  The Scalable Vector Extension (SVE) is an extension to the AArch64
>  	  execution state which complements and extends the SIMD functionality
> @@ -1155,6 +1156,12 @@ config ARM64_SVE
>  	  booting the kernel.  If unsure and you are not observing these
>  	  symptoms, you should assume that it is safe to say Y.
>  
> +	  CPUs that support SVE are architecturally required to support the
> +	  Virtualization Host Extensions (VHE), so the kernel makes no
> +	  provision for supporting SVE alongside KVM without VHE enabled.
> +	  Thus, you will need to enable CONFIG_ARM64_VHE if you want to support
> +	  KVM in the same kernel image.
> +
>  config ARM64_MODULE_PLTS
>  	bool
>  	select HAVE_MOD_ARCH_SPECIFIC
> diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
> index bbc6889..91ad01f 100644
> --- a/arch/arm64/kvm/fpsimd.c
> +++ b/arch/arm64/kvm/fpsimd.c
> @@ -59,7 +59,6 @@ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu)
>   */
>  void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
>  {
> -	BUG_ON(system_supports_sve());
>  	BUG_ON(!current->mm);
>  
>  	vcpu->arch.fp_enabled = false;
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index 10f55d3..8009126 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -21,12 +21,14 @@
>  
>  #include <kvm/arm_psci.h>
>  
> +#include <asm/cpufeature.h>
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_emulate.h>
>  #include <asm/kvm_hyp.h>
>  #include <asm/kvm_mmu.h>
>  #include <asm/fpsimd.h>
>  #include <asm/debug-monitors.h>
> +#include <asm/processor.h>
>  #include <asm/thread_info.h>
>  
>  static bool __hyp_text update_fp_enabled(struct kvm_vcpu *vcpu)
> @@ -328,6 +330,8 @@ static bool __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
>  void __hyp_text __hyp_switch_fpsimd(u64 esr __always_unused,
>  				    struct kvm_vcpu *vcpu)
>  {
> +	struct user_fpsimd_state *host_fpsimd = vcpu->arch.host_fpsimd_state;
> +
>  	if (has_vhe())
>  		write_sysreg(read_sysreg(cpacr_el1) | CPACR_EL1_FPEN,
>  			     cpacr_el1);
> @@ -337,8 +341,21 @@ void __hyp_text __hyp_switch_fpsimd(u64 esr __always_unused,
>  
>  	isb();
>  
> -	if (vcpu->arch.host_fpsimd_state) {
> -		__fpsimd_save_state(vcpu->arch.host_fpsimd_state);
> +	if (host_fpsimd) {
> +		/*
> +		 * In the SVE case, VHE is assumed: it is enforced by
> +		 * Kconfig and kvm_arch_init_vm().
> +		 */
> +		if (system_supports_sve() && vcpu->arch.host_sve_in_use) {
> +			struct thread_struct *thread = container_of(
> +				host_fpsimd,
> +				struct thread_struct, uw.fpsimd_state);
> +
> +			sve_save_state(sve_pffr(thread), &host_fpsimd->fpsr);
> +		} else {
> +			__fpsimd_save_state(vcpu->arch.host_fpsimd_state);
> +		}
> +
>  		vcpu->arch.host_fpsimd_state = NULL;
>  	}
>  
> diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
> index 6cf499b..a7be7bf 100644
> --- a/virt/kvm/arm/arm.c
> +++ b/virt/kvm/arm/arm.c
> @@ -16,6 +16,7 @@
>   * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
>   */
>  
> +#include <linux/bug.h>
>  #include <linux/cpu_pm.h>
>  #include <linux/errno.h>
>  #include <linux/err.h>
> @@ -41,6 +42,7 @@
>  #include <asm/mman.h>
>  #include <asm/tlbflush.h>
>  #include <asm/cacheflush.h>
> +#include <asm/cpufeature.h>
>  #include <asm/virt.h>
>  #include <asm/kvm_arm.h>
>  #include <asm/kvm_asm.h>
> @@ -120,6 +122,22 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>  	if (type)
>  		return -EINVAL;
>  
> +	/*
> +	 * VHE is a prerequisite for SVE in the Arm architecture, and
> +	 * Kconfig ensures that if system_supports_sve() here then
> +	 * CONFIG_ARM64_VHE is enabled, so if VHE support wasn't already
> +	 * detected and enabled, the CPU is architecturally
> +	 * noncompliant.
> +	 *
> +	 * Just in case this mismatch is seen, detect it, warn and give
> +	 * up.  Supporting this forbidden configuration in Hyp would be
> +	 * pointless.
> +	 */
> +	if (system_supports_sve() && !has_vhe()) {
> +		kvm_pr_unimpl("Cannot create VMs on SVE system without VHE.  Broken cpu?");
> +		return -ENXIO;
> +	}

You might as well fail the boot KVM initialization altogether, and not
wait for a VM to be created.

But I'm more concerned with the fact that we're now have a configuration
that drops functionalities on the floor, one way or another.

> +
>  	kvm->arch.last_vcpu_ran = alloc_percpu(typeof(*kvm->arch.last_vcpu_ran));
>  	if (!kvm->arch.last_vcpu_ran)
>  		return -ENOMEM;
> 

Thanks,

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

^ permalink raw reply

* [PATCH 0/2] arm64: Report signal frame size to userspace via auxv
From: Dave Martin @ 2018-05-08 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

Because SVE makes the arm64 signal frame size variable, userspace will
ultimately need a way to detect the size.

This series adds support for exposing this information via a new auxv
entry AT_MINSIGSTKSZ.

These patches are taken from [1], with minor updates.  (They were RFC
in that series, but there has been no significant discussion or
objections raised in the meantime, and no change in the understanding
of the problem being addressed here.  I'd like to get discussions for
binding this to glibc started.)

Changes since [1]:

 * Cache the value computed to AT_MINSIGSTKSZ so that the effort of
   computing it does not need to be repeated on every exec.


[1] [PATCH v5 00/30] ARM Scalable Vector Extension (SVE)
lists.infradead.org/pipermail/linux-arm-kernel/2017-October/539993.html

Dave Martin (2):
  arm64: signal: Report signal frame size to userspace via auxv
  arm64/sve: signal: Include SVE when computing AT_MINSIGSTKSZ

 arch/arm64/include/asm/elf.h         |  5 +++
 arch/arm64/include/asm/processor.h   |  3 ++
 arch/arm64/include/uapi/asm/auxvec.h |  3 +-
 arch/arm64/kernel/signal.c           | 68 ++++++++++++++++++++++++++++++++----
 4 files changed, 71 insertions(+), 8 deletions(-)

-- 
2.1.4

^ permalink raw reply

* [PATCH 1/2] arm64: signal: Report signal frame size to userspace via auxv
From: Dave Martin @ 2018-05-08 10:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525776211-28169-1-git-send-email-Dave.Martin@arm.com>

Stateful CPU architecture extensions may require the signal frame
to grow to a size that exceeds the arch's MINSIGSTKSZ #define.
However, changing this #define is an ABI break.

To allow userspace the option of determining the signal frame size
in a more forwards-compatible way, this patch adds a new auxv entry
tagged with AT_MINSIGSTKSZ, which provides the maximum signal frame
size that the process can observe during its lifetime.

If AT_MINSIGSTKSZ is absent from the aux vector, the caller can
assume that the MINSIGSTKSZ #define is sufficient.  This allows for
a consistent interface with older kernels that do not provide
AT_MINSIGSTKSZ.

The idea is that libc could expose this via sysconf() or some
similar mechanism.

There is deliberately no AT_SIGSTKSZ.  The kernel knows nothing
about userspace's own stack overheads and should not pretend to
know.

For arm64:

The primary motivation for this interface is the Scalable Vector
Extension, which can require at least 4KB or so of extra space
in the signal frame for the largest hardware implementations.

To determine the correct value, a "Christmas tree" mode (via the
add_all argument) is added to setup_sigframe_layout(), to simulate
addition of all possible records to the signal frame at maximum
possible size.

If this procedure goes wrong somehow, resulting in a stupidly large
frame layout and hence failure of sigframe_alloc() to allocate a
record to the frame, then this is indicative of a kernel bug: the
kernel's internal SIGFRAME_MAXSZ is supposed to sanity-check
against generting frames that we consider _impossibly_ large.  In
this case, SIGSTKSZ is returned as a "reasonable guess that is at
least bigger than MINSIGSTKSZ" and we WARN().

Signed-off-by: Dave Martin <Dave.Martin@arm.com>

---

Changes since v5:

 * Cache the value computed for AT_MINSIGSTKSZ.  This is invariant post-
   boot, so recomputing it on every exec is pointless effort.
---
 arch/arm64/include/asm/elf.h         |  5 ++++
 arch/arm64/include/asm/processor.h   |  3 ++
 arch/arm64/include/uapi/asm/auxvec.h |  3 +-
 arch/arm64/kernel/signal.c           | 54 ++++++++++++++++++++++++++++++++----
 4 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index fac1c4d..771c7a8 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -24,6 +24,10 @@
 #include <asm/ptrace.h>
 #include <asm/user.h>
 
+#ifndef __ASSEMBLY__
+#include <asm/processor.h> /* for get_minsigstksz(), used by ARCH_DLINFO */
+#endif
+
 /*
  * AArch64 static relocation types.
  */
@@ -148,6 +152,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
 do {									\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
 		    (elf_addr_t)current->mm->context.vdso);		\
+	NEW_AUX_ENT(AT_MINSIGSTKSZ, get_minsigstksz());			\
 } while (0)
 
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 7675989..eee058f 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -244,6 +244,9 @@ void cpu_enable_pan(const struct arm64_cpu_capabilities *__unused);
 void cpu_enable_cache_maint_trap(const struct arm64_cpu_capabilities *__unused);
 void cpu_clear_disr(const struct arm64_cpu_capabilities *__unused);
 
+/* User signal frame size discovery: */
+int get_minsigstksz(void);
+
 /* Userspace interface for PR_SVE_{SET,GET}_VL prctl()s: */
 #define SVE_SET_VL(arg)	sve_set_current_vl(arg)
 #define SVE_GET_VL()	sve_get_current_vl()
diff --git a/arch/arm64/include/uapi/asm/auxvec.h b/arch/arm64/include/uapi/asm/auxvec.h
index ec0a86d..a35797e 100644
--- a/arch/arm64/include/uapi/asm/auxvec.h
+++ b/arch/arm64/include/uapi/asm/auxvec.h
@@ -19,7 +19,8 @@
 
 /* vDSO location */
 #define AT_SYSINFO_EHDR	33
+#define AT_MINSIGSTKSZ	34	/* stack needed for signal delivery */
 
-#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */
+#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */
 
 #endif
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 154b7d3..a4f1edf 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -17,6 +17,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/atomic.h>
 #include <linux/compat.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -570,8 +571,15 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 	return 0;
 }
 
-/* Determine the layout of optional records in the signal frame */
-static int setup_sigframe_layout(struct rt_sigframe_user_layout *user)
+/*
+ * Determine the layout of optional records in the signal frame
+ *
+ * add_all: if true, lays out the biggest possible signal frame for
+ *	this task; otherwise, generates a layout for the current state
+ *	of the task.
+ */
+static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
+				 bool add_all)
 {
 	int err;
 
@@ -581,7 +589,7 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user)
 		return err;
 
 	/* fault information, if valid */
-	if (current->thread.fault_code) {
+	if (add_all || current->thread.fault_code) {
 		err = sigframe_alloc(user, &user->esr_offset,
 				     sizeof(struct esr_context));
 		if (err)
@@ -603,7 +611,6 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user)
 	return sigframe_alloc_end(user);
 }
 
-
 static int setup_sigframe(struct rt_sigframe_user_layout *user,
 			  struct pt_regs *regs, sigset_t *set)
 {
@@ -701,7 +708,7 @@ static int get_sigframe(struct rt_sigframe_user_layout *user,
 	int err;
 
 	init_user_layout(user);
-	err = setup_sigframe_layout(user);
+	err = setup_sigframe_layout(user, false);
 	if (err)
 		return err;
 
@@ -936,3 +943,40 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 		thread_flags = READ_ONCE(current_thread_info()->flags);
 	} while (thread_flags & _TIF_WORK_MASK);
 }
+
+/*
+ * Determine the stack space required for guaranteed signal devliery.
+ * This function is used to populate AT_MINSIGSTKSZ at process startup.
+ */
+int get_minsigstksz(void)
+{
+	static __read_mostly atomic_t minsigstksz;
+
+	int ret;
+	struct rt_sigframe_user_layout user;
+
+	ret = atomic_read(&minsigstksz);
+	if (ret)
+		return ret;
+
+	init_user_layout(&user);
+	ret = setup_sigframe_layout(&user, true);
+
+	if (ret) {
+		WARN_ON(1);
+
+		ret = SIGSTKSZ;
+	} else {
+		ret = sigframe_size(&user) +
+			round_up(sizeof(struct frame_record), 16) +
+			16; /* max alignment padding */
+	}
+
+	/*
+	 * The computed value (ret) is invariant, so its value can be
+	 * safely stored irrespective of whether some other racing
+	 * task got there first:
+	 */
+	atomic_set(&minsigstksz, ret);
+	return ret;
+}
-- 
2.1.4

^ permalink raw reply related

* [PATCH 2/2] arm64/sve: signal: Include SVE when computing AT_MINSIGSTKSZ
From: Dave Martin @ 2018-05-08 10:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1525776211-28169-1-git-send-email-Dave.Martin@arm.com>

The SVE context block in the signal frame needs to be considered
too when computing the maximum possible signal frame size.

Because the size of this block depends on the vector length, this
patch computes the size based not on the thread's current vector
length but instead on the maximum possible vector length: this
determines the maximum size of SVE context block that can be
observed in any signal frame for the lifetime of the process.

Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Alex Benn?e <alex.bennee@linaro.org>
---
 arch/arm64/kernel/signal.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index a4f1edf..3427c70 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -599,8 +599,18 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
 	if (system_supports_sve()) {
 		unsigned int vq = 0;
 
-		if (test_thread_flag(TIF_SVE))
-			vq = sve_vq_from_vl(current->thread.sve_vl);
+		if (add_all || test_thread_flag(TIF_SVE)) {
+			int vl = sve_max_vl;
+
+			if (!add_all)
+				vl = current->thread.sve_vl;
+
+			/* Fail safe if something wasn't initialised */
+			if (WARN_ON(!sve_vl_valid(vl)))
+				vl = SVE_VL_MIN;
+
+			vq = sve_vq_from_vl(vl);
+		}
 
 		err = sigframe_alloc(user, &user->sve_offset,
 				     SVE_SIG_CONTEXT_SIZE(vq));
-- 
2.1.4

^ permalink raw reply related

* [PATCH 3/3] dma-debug: unexport dma_debug_resize_entries and debug_dma_dump_mappings
From: Christoph Hellwig @ 2018-05-08 10:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <bb5bb25f-24da-9729-a39b-3b88c65ef628@arm.com>

On Tue, May 08, 2018 at 11:05:20AM +0100, Robin Murphy wrote:
> On 24/04/18 15:02, Christoph Hellwig wrote:
>> Only used by the AMD GART driver, which must be built in.
>
> FWIW debug_dma_dump_mappings() is also called by the Intel VT-d driver, but 
> the same reasoning still applies.

I'll update the changelog.

> This does rather beg the question of 
> whether it's right to have bits of low-level dma-debug internals *only* 
> called by a couple of IOMMU drivers, but that can wait for another day.

My gut feeling is that it is wrong, but I didn't have time to look into
the details and history of how this happened.

^ 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