* [PATCH 0/3] clk: keystone: add sci clock support
From: Tero Kristo @ 2016-10-21 12:45 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Version 3 has following changes compared to v2 [1]:
- rebased on top of 4.9-rc1
- dropped some of the controversial DT properties like ti,ssc-clocks etc.
- driver now registers all the SCI clocks during probe time, for this,
there is an array built-in to the driver with knowledge of valid clocks
for the device
- xlate only picks up the clocks registered during probe
This series depends on the base SCI protocol support series [2]
and the TI-SCI generic PM domain support series for the device
ID include file [3].
Quick boot test seems to be fine.
-Tero
[1] http://www.spinics.net/lists/devicetree/msg141319.html
[2] http://www.spinics.net/lists/devicetree/msg146621.html
[3] http://www.spinics.net/lists/arm-kernel/msg536851.html
Tero Kristo (3):
Documentation: dt: Add TI SCI clock driver
dt-binding: clock: Add k2g clock definitions
clk: keystone: Add sci-clk driver support
.../devicetree/bindings/clock/ti,sci-clk.txt | 37 ++
MAINTAINERS | 3 +
drivers/clk/Kconfig | 9 +
drivers/clk/keystone/Makefile | 1 +
drivers/clk/keystone/sci-clk.c | 589 +++++++++++++++++++++
include/dt-bindings/clock/k2g.h | 234 ++++++++
6 files changed, 873 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt
create mode 100644 drivers/clk/keystone/sci-clk.c
create mode 100644 include/dt-bindings/clock/k2g.h
--
1.9.1
^ permalink raw reply
* [PATCH] PM / Domains: Restrict "samsung, power-domain" checks to ARCH_EXYNOS
From: Rafael J. Wysocki @ 2016-10-21 12:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477049656-27535-1-git-send-email-geert+renesas@glider.be>
On Fri, Oct 21, 2016 at 1:34 PM, Geert Uytterhoeven
<geert+renesas@glider.be> wrote:
> Currently the generic PM Domain code code checks for the presence of
> both (generic) "power-domains" and (Samsung Exynos legacy)
> "samsung,power-domain" properties in all device tree nodes representing
> devices.
>
> There are two issues with this:
> 1. This imposes a small boot-time penalty on all platforms using DT,
> 2. Platform-specific checks do not really belong in core framework
> code.
>
> While moving the check from platform-agnostic code to Samsung-specific
> code is non-trivial, the runtime overhead can be restricted to kernels
> including support for 32-bit Samsung Exynos platforms.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> "samsung,power-domain" was only ever used in:
> - arch/arm/boot/dts/exynos4415.dtsi: Unused?
> - arch/arm/boot/dts/exynos3250.dtsi: CONFIG_ARCH_EXYNOS3
> - arch/arm/boot/dts/exynos4.dtsi: CONFIG_ARCH_EXYNOS4
> - arch/arm/boot/dts/exynos4x12.dtsi: CONFIG_ARCH_EXYNOS4
> exynos4212.dtsi is unused?
> - arch/arm/boot/dts/exynos5250.dtsi: CONFIG_ARCH_EXYNOS5
> - arch/arm/boot/dts/exynos5420.dtsi: CONFIG_ARCH_EXYNOS5
> ---
> drivers/base/power/domain.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index e023066e421547c5..d94d6a4b9b527108 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -1853,7 +1853,8 @@ int genpd_dev_pm_attach(struct device *dev)
> ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
> "#power-domain-cells", 0, &pd_args);
> if (ret < 0) {
> - if (ret != -ENOENT)
> + if (ret != -ENOENT || !IS_ENABLED(CONFIG_ARCH_EXYNOS) ||
Please don't check things like CONFIG_ARCH_EXYNOS in the core.
If you need to put checks like that here, there is a design problem somewhere.
And imagine someone 5 years ahead from now looking at this code and
wondering why on Earth the check is here.
> + IS_ENABLED(CONFIG_64BIT))
> return ret;
>
> /*
> --
Thanks,
Rafael
^ permalink raw reply
* [PATCH] [media] c8sectpfe: Remove clk_disable_unprepare hacks
From: Patrice Chotard @ 2016-10-21 12:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477040132-31442-1-git-send-email-peter.griffin@linaro.org>
On 10/21/2016 10:55 AM, Peter Griffin wrote:
> Now that CLK_PROC_STFE is defined as a critical clock in
> DT, we can remove the commented clk_disable_unprepare from
> the c8sectpfe driver. This means we now have balanced
> clk*enable/disable calls in the driver, but on STiH407
> family the clock in reality will never actually be disabled.
>
> This is due to a HW bug where once the IP has been configured
> and the SLIM core is running, disabling the clock causes a
> unrecoverable bus lockup.
>
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c | 6 +-----
> 1 file changed, 1 insertion(+), 5 deletions(-)
>
> diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> index 30c148b..79d793b 100644
> --- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> +++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> @@ -888,8 +888,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
> return 0;
>
> err_clk_disable:
> - /* TODO uncomment when upstream has taken a reference on this clk */
> - /*clk_disable_unprepare(fei->c8sectpfeclk);*/
> + clk_disable_unprepare(fei->c8sectpfeclk);
> return ret;
> }
>
> @@ -924,11 +923,8 @@ static int c8sectpfe_remove(struct platform_device *pdev)
> if (readl(fei->io + SYS_OTHER_CLKEN))
> writel(0, fei->io + SYS_OTHER_CLKEN);
>
> - /* TODO uncomment when upstream has taken a reference on this clk */
> - /*
> if (fei->c8sectpfeclk)
> clk_disable_unprepare(fei->c8sectpfeclk);
> - */
>
> return 0;
> }
>
Acked-by: Patrice Chotard <patrice.chotard@st.com>
^ permalink raw reply
* [PATCH] ARM: sti: stih407-clocks: Identify critical clocks
From: Patrice Chotard @ 2016-10-21 12:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477040891-31611-1-git-send-email-peter.griffin@linaro.org>
On 10/21/2016 11:08 AM, Peter Griffin wrote:
> Lots of platforms contain clocks which if turned off would prove fatal.
> The only way to recover is to restart the board(s). This driver takes
> references to clocks which are required to be always-on. The Common
> Clk Framework will then take references to them. This way they will
> not be turned off during the clk_disabled_unused() procedure.
>
> In this patch we are identifying clocks, which if gated would render
> the STiH407 development board unserviceable.
>
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> arch/arm/boot/dts/stih407-clock.dtsi | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/arch/arm/boot/dts/stih407-clock.dtsi b/arch/arm/boot/dts/stih407-clock.dtsi
> index 13029c0..34c119a 100644
> --- a/arch/arm/boot/dts/stih407-clock.dtsi
> +++ b/arch/arm/boot/dts/stih407-clock.dtsi
> @@ -101,6 +101,7 @@
> clocks = <&clk_sysin>;
>
> clock-output-names = "clk-s-a0-pll-ofd-0";
> + clock-critical = <0>; /* clk-s-a0-pll-ofd-0 */
> };
>
> clk_s_a0_flexgen: clk-s-a0-flexgen {
> @@ -112,6 +113,7 @@
> <&clk_sysin>;
>
> clock-output-names = "clk-ic-lmi0";
> + clock-critical = <CLK_IC_LMI0>;
> };
> };
>
> @@ -126,6 +128,7 @@
> "clk-s-c0-fs0-ch1",
> "clk-s-c0-fs0-ch2",
> "clk-s-c0-fs0-ch3";
> + clock-critical = <0>; /* clk-s-c0-fs0-ch0 */
> };
>
> clk_s_c0: clockgen-c at 09103000 {
> @@ -139,6 +142,7 @@
> clocks = <&clk_sysin>;
>
> clock-output-names = "clk-s-c0-pll0-odf-0";
> + clock-critical = <0>; /* clk-s-c0-pll0-odf-0 */
> };
>
> clk_s_c0_pll1: clk-s-c0-pll1 {
> @@ -194,6 +198,12 @@
> "clk-main-disp",
> "clk-aux-disp",
> "clk-compo-dvp";
> + clock-critical = <CLK_PROC_STFE>,
> + <CLK_ICN_CPU>,
> + <CLK_TX_ICN_DMU>,
> + <CLK_EXT2F_A9>,
> + <CLK_ICN_LMI>,
> + <CLK_ICN_SBC>;
> };
> };
>
>
Acked-by: Patrice Chotard <patrice.chotard@st.com>
And applied !
Effectively, the job was done for STiH410 but i forgot to apply the same for STiH407
Thanks Peter ;-)
^ permalink raw reply
* [PATCH V7 2/3] stm class: ftrace: Add ftrace-export-over-stm driver
From: Chunyan Zhang @ 2016-10-21 12:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161018122928.0c9449a4@gandalf.local.home>
On 19 October 2016 at 00:29, Steven Rostedt <rostedt@goodmis.org> wrote:
> On Tue, 18 Oct 2016 16:08:59 +0800
> Chunyan Zhang <zhang.chunyan@linaro.org> wrote:
>
>> This patch adds a driver that models itself as an stm_source called
>> stm_ftrace. Once the stm device and stm_ftrace have been linked via
>> sysfs, the driver registers itself as a trace_export and everything
>> passed to the interface from Ftrace subsystem will end up in the STM
>> trace engine.
>>
>> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
>> ---
>> drivers/hwtracing/stm/Kconfig | 11 ++++++
>> drivers/hwtracing/stm/Makefile | 2 +
>> drivers/hwtracing/stm/ftrace.c | 88 ++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 101 insertions(+)
>> create mode 100644 drivers/hwtracing/stm/ftrace.c
>>
>> diff --git a/drivers/hwtracing/stm/Kconfig b/drivers/hwtracing/stm/Kconfig
>> index 847a39b..b34ea96 100644
>> --- a/drivers/hwtracing/stm/Kconfig
>> +++ b/drivers/hwtracing/stm/Kconfig
>> @@ -39,4 +39,15 @@ config STM_SOURCE_HEARTBEAT
>> If you want to send heartbeat messages over STM devices,
>> say Y.
>>
>> +config STM_SOURCE_FTRACE
>> + tristate "Copy the output from kernel Ftrace to STM engine"
>> + depends on TRACING
>
> I think it should depend on FUNCTION_TRACER
I think we should support other type of tracer in the future, but
you're right it only should depend on FUNCTION_TRACER for now, I will
revise this.
>
>> + help
>> + This option can be used to copy the output from kernel Ftrace
>> + to STM engine. Enabling this option will introduce a slight
>> + timing effect.
>> +
>> + If you want to send kernel Ftrace messages over STM devices,
>> + say Y.
>> +
>> endif
>> diff --git a/drivers/hwtracing/stm/Makefile b/drivers/hwtracing/stm/Makefile
>> index a9ce3d4..3abd84c 100644
>> --- a/drivers/hwtracing/stm/Makefile
>> +++ b/drivers/hwtracing/stm/Makefile
>> @@ -6,6 +6,8 @@ obj-$(CONFIG_STM_DUMMY) += dummy_stm.o
>>
>> obj-$(CONFIG_STM_SOURCE_CONSOLE) += stm_console.o
>> obj-$(CONFIG_STM_SOURCE_HEARTBEAT) += stm_heartbeat.o
>> +obj-$(CONFIG_STM_SOURCE_FTRACE) += stm_ftrace.o
>>
>> stm_console-y := console.o
>> stm_heartbeat-y := heartbeat.o
>> +stm_ftrace-y := ftrace.o
>> diff --git a/drivers/hwtracing/stm/ftrace.c b/drivers/hwtracing/stm/ftrace.c
>> new file mode 100644
>> index 0000000..1a114c8f
>> --- /dev/null
>> +++ b/drivers/hwtracing/stm/ftrace.c
>> @@ -0,0 +1,88 @@
>> +/*
>> + * Simple kernel driver to link kernel Ftrace and an STM device
>> + * Copyright (c) 2016, Linaro Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
>> + * more details.
>> + *
>> + * STM Ftrace will be registered as a trace_export.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/stm.h>
>> +#include <linux/trace.h>
>> +
>> +#define STM_FTRACE_NR_CHANNELS 1
>> +#define STM_FTRACE_CHAN 0
>> +
>> +static int stm_ftrace_link(struct stm_source_data *data);
>> +static void stm_ftrace_unlink(struct stm_source_data *data);
>> +
>> +static struct stm_ftrace {
>> + struct stm_source_data data;
>> + struct trace_export ftrace;
>> +} stm_ftrace = {
>> + .data = {
>> + .name = "ftrace",
>> + .nr_chans = STM_FTRACE_NR_CHANNELS,
>> + .link = stm_ftrace_link,
>> + .unlink = stm_ftrace_unlink,
>> + },
>> +};
>> +
>> +/**
>> + * stm_ftrace_write() - write data to STM via 'stm_ftrace' source
>> + * @buf: buffer containing the data packet
>> + * @len: length of the data packet
>> + */
>> +static void notrace
>> +stm_ftrace_write(const char *buf, unsigned int len)
>> +{
>> + stm_source_write(&stm_ftrace.data, STM_FTRACE_CHAN, buf, len);
>> +}
>> +
>> +static int stm_ftrace_link(struct stm_source_data *data)
>> +{
>> + struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
>> +
>> + sf->ftrace.write = stm_ftrace_write;
>> + sf->ftrace.next = NULL;
>
> Why setting this to NULL? register_ftrace_export() should not require
> nor depend on that.
Right, it's not required indeed, will remove it.
Thanks,
Chunyan
>
> -- Steve
>
>> +
>> + return register_ftrace_export(&sf->ftrace);
>> +}
>> +
>> +static void stm_ftrace_unlink(struct stm_source_data *data)
>> +{
>> + struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
>> +
>> + unregister_ftrace_export(&sf->ftrace);
>> +}
>> +
>> +static int __init stm_ftrace_init(void)
>> +{
>> + int ret;
>> +
>> + ret = stm_source_register_device(NULL, &stm_ftrace.data);
>> + if (ret)
>> + pr_err("Failed to register stm_source - ftrace.\n");
>> +
>> + return ret;
>> +}
>> +
>> +static void __exit stm_ftrace_exit(void)
>> +{
>> + stm_source_unregister_device(&stm_ftrace.data);
>> +}
>> +
>> +module_init(stm_ftrace_init);
>> +module_exit(stm_ftrace_exit);
>> +
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_DESCRIPTION("stm_ftrace driver");
>> +MODULE_AUTHOR("Chunyan Zhang <zhang.chunyan@linaro.org>");
>
^ permalink raw reply
* [PATCH V7 1/3] tracing: add a possibility of exporting function trace to other places instead of ring buffer only
From: Chunyan Zhang @ 2016-10-21 12:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161018114418.3445c390@gandalf.local.home>
On 18 October 2016 at 23:44, Steven Rostedt <rostedt@goodmis.org> wrote:
> On Tue, 18 Oct 2016 16:08:58 +0800
> Chunyan Zhang <zhang.chunyan@linaro.org> wrote:
>
>> Currently Function traces can be only exported to ring buffer, this
>> patch added trace_export concept which can process traces and export
>> them to a registered destination as an addition to the current only
>> one output of Ftrace - i.e. ring buffer.
>>
>> In this way, if we want Function traces to be sent to other destination
>> rather than ring buffer only, we just need to register a new trace_export
>> and implement its own .write() function for writing traces to storage.
>>
>> With this patch, only Function trace (trace type is TRACE_FN)
>> is supported.
>
> This is getting better, but I still have some nits.
>
Thanks.
>>
>> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
>> ---
>> include/linux/trace.h | 28 +++++++++++
>> kernel/trace/trace.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++-
>> 2 files changed, 159 insertions(+), 1 deletion(-)
>> create mode 100644 include/linux/trace.h
>>
>> diff --git a/include/linux/trace.h b/include/linux/trace.h
>> new file mode 100644
>> index 0000000..eb1c5b8
>> --- /dev/null
>> +++ b/include/linux/trace.h
>> @@ -0,0 +1,28 @@
>> +#ifndef _LINUX_TRACE_H
>> +#define _LINUX_TRACE_H
>> +
>> +#ifdef CONFIG_TRACING
>> +/*
>> + * The trace export - an export of Ftrace output. The trace_export
>> + * can process traces and export them to a registered destination as
>> + * an addition to the current only output of Ftrace - i.e. ring buffer.
>> + *
>> + * If you want traces to be sent to some other place rather than ring
>> + * buffer only, just need to register a new trace_export and implement
>> + * its own .write() function for writing traces to the storage.
>> + *
>> + * next - pointer to the next trace_export
>> + * write - copy traces which have been delt with ->commit() to
>> + * the destination
>> + */
>> +struct trace_export {
>> + struct trace_export __rcu *next;
>> + void (*write)(const char *, unsigned int);
>
> Why const char*? Why not const void *? This will never be a string.
>
Will revise this.
>
>> +};
>> +
>> +int register_ftrace_export(struct trace_export *export);
>> +int unregister_ftrace_export(struct trace_export *export);
>> +
>> +#endif /* CONFIG_TRACING */
>> +
>> +#endif /* _LINUX_TRACE_H */
>> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
>> index 8696ce6..db94ec1 100644
>> --- a/kernel/trace/trace.c
>> +++ b/kernel/trace/trace.c
>> @@ -40,6 +40,7 @@
>> #include <linux/poll.h>
>> #include <linux/nmi.h>
>> #include <linux/fs.h>
>> +#include <linux/trace.h>
>> #include <linux/sched/rt.h>
>>
>> #include "trace.h"
>> @@ -2128,6 +2129,132 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
>> ftrace_trace_userstack(buffer, flags, pc);
>> }
>>
>> +static void
>> +trace_process_export(struct trace_export *export,
>> + struct ring_buffer_event *event)
>> +{
>> + struct trace_entry *entry;
>> + unsigned int size = 0;
>> +
>> + entry = ring_buffer_event_data(event);
>> +
>> + size = ring_buffer_event_length(event);
>> +
>> + if (export->write)
>> + export->write((char *)entry, size);
>
> Is there ever going to be a time where export->write wont be set?
There hasn't been since only one trace_export (i.e. stm_ftrace) was
added in this patch-set , I just wanted to make sure the write() has
been set before registering trace_export like what I added in 2/3 of
this series.
>
> And if there is, this can be racy. As in
>
>
> CPU 0: CPU 1:
> ------ ------
> if (export->write)
>
> export->write = NULL;
Is there going to be this kind of use case? Why some one needs to
change export->write() rather than register a new trace_export?
I probably haven't understood your point thoroughly, please correct me
if my guess was wrong.
Thanks for the review,
Chunyan
>
> export->write(entry, size);
>
> BOOM!
>
>
> -- Steve
>
>> +}
>> +
>> +static DEFINE_MUTEX(ftrace_export_lock);
>> +
>> +static struct trace_export __rcu *ftrace_exports_list __read_mostly;
>> +
>> +static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);
>> +
>> +static inline void ftrace_exports_enable(void)
>> +{
>> + static_branch_enable(&ftrace_exports_enabled);
>> +}
>> +
>> +static inline void ftrace_exports_disable(void)
>> +{
>> + static_branch_disable(&ftrace_exports_enabled);
>> +}
>> +
>> +void ftrace_exports(struct ring_buffer_event *event)
>> +{
>> + struct trace_export *export;
>> +
>> + preempt_disable_notrace();
>> +
>> + export = rcu_dereference_raw_notrace(ftrace_exports_list);
>> + while (export) {
>> + trace_process_export(export, event);
>> + export = rcu_dereference_raw_notrace(export->next);
>> + }
>> +
>> + preempt_enable_notrace();
>> +}
>> +
>> +static inline void
>> +add_trace_export(struct trace_export **list, struct trace_export *export)
>> +{
>> + rcu_assign_pointer(export->next, *list);
>> + /*
>> + * We are entering export into the list but another
>> + * CPU might be walking that list. We need to make sure
>> + * the export->next pointer is valid before another CPU sees
>> + * the export pointer included into the list.
>> + */
>> + rcu_assign_pointer(*list, export);
>> +}
>> +
>> +static inline int
>> +rm_trace_export(struct trace_export **list, struct trace_export *export)
>> +{
>> + struct trace_export **p;
>> +
>> + for (p = list; *p != NULL; p = &(*p)->next)
>> + if (*p == export)
>> + break;
>> +
>> + if (*p != export)
>> + return -1;
>> +
>> + rcu_assign_pointer(*p, (*p)->next);
>> +
>> + return 0;
>> +}
>> +
>> +static inline void
>> +add_ftrace_export(struct trace_export **list, struct trace_export *export)
>> +{
>> + if (*list == NULL)
>> + ftrace_exports_enable();
>> +
>> + add_trace_export(list, export);
>> +}
>> +
>> +static inline int
>> +rm_ftrace_export(struct trace_export **list, struct trace_export *export)
>> +{
>> + int ret;
>> +
>> + ret = rm_trace_export(list, export);
>> + if (*list == NULL)
>> + ftrace_exports_disable();
>> +
>> + return ret;
>> +}
>> +
>> +int register_ftrace_export(struct trace_export *export)
>> +{
>> + if (WARN_ON_ONCE(!export->write))
>> + return -1;
>> +
>> + mutex_lock(&ftrace_export_lock);
>> +
>> + add_ftrace_export(&ftrace_exports_list, export);
>> +
>> + mutex_unlock(&ftrace_export_lock);
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(register_ftrace_export);
>> +
>> +int unregister_ftrace_export(struct trace_export *export)
>> +{
>> + int ret;
>> +
>> + mutex_lock(&ftrace_export_lock);
>> +
>> + ret = rm_ftrace_export(&ftrace_exports_list, export);
>> +
>> + mutex_unlock(&ftrace_export_lock);
>> +
>> + return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(unregister_ftrace_export);
>> +
>> void
>> trace_function(struct trace_array *tr,
>> unsigned long ip, unsigned long parent_ip, unsigned long flags,
>> @@ -2146,8 +2273,11 @@ trace_function(struct trace_array *tr,
>> entry->ip = ip;
>> entry->parent_ip = parent_ip;
>>
>> - if (!call_filter_check_discard(call, entry, buffer, event))
>> + if (!call_filter_check_discard(call, entry, buffer, event)) {
>> + if (static_branch_unlikely(&ftrace_exports_enabled))
>> + ftrace_exports(event);
>> __buffer_unlock_commit(buffer, event);
>> + }
>> }
>>
>> #ifdef CONFIG_STACKTRACE
>
^ permalink raw reply
* [PATCH] net: stmmac: Add OXNAS Glue Driver
From: Giuseppe CAVALLARO @ 2016-10-21 11:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGhQ9Vxe8fe8kfF_WY40xdh6YX9TuxQ3-Dd6pBG=AHpLtrHnMA@mail.gmail.com>
Hello
some my minor cents below
On 10/21/2016 12:20 PM, Joachim Eastwood wrote:
> Hi Neil,
>
> On 21 October 2016 at 10:44, Neil Armstrong <narmstrong@baylibre.com> wrote:
>> Add Synopsys Designware MAC Glue layer for the Oxford Semiconductor OX820.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>> .../devicetree/bindings/net/oxnas-dwmac.txt | 44 +++++
>> drivers/net/ethernet/stmicro/stmmac/Kconfig | 11 ++
>> drivers/net/ethernet/stmicro/stmmac/Makefile | 1 +
>> drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 219 +++++++++++++++++++++
>> 4 files changed, 275 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/net/oxnas-dwmac.txt
>> create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
>>
>> Changes since RFC at https://patchwork.kernel.org/patch/9387257 :
>> - Drop init/exit callbacks
>> - Implement proper remove and PM callback
>> - Call init from probe
>> - Disable/Unprepare clock if stmmac probe fails
>
> <snip>
>
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
>> @@ -0,0 +1,219 @@
>> +/*
>> + * Oxford Semiconductor OXNAS DWMAC glue layer
>> + *
>> + * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
>> + * Copyright (C) 2014 Daniel Golle <daniel@makrotopia.org>
>> + * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
>> + * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/device.h>
>> +#include <linux/io.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/stmmac.h>
>> +
>> +#include "stmmac_platform.h"
>> +
>> +/* System Control regmap offsets */
>> +#define OXNAS_DWMAC_CTRL_REGOFFSET 0x78
>> +#define OXNAS_DWMAC_DELAY_REGOFFSET 0x100
>> +
>> +/* Control Register */
>> +#define DWMAC_CKEN_RX_IN 14
>> +#define DWMAC_CKEN_RXN_OUT 13
>> +#define DWMAC_CKEN_RX_OUT 12
>> +#define DWMAC_CKEN_TX_IN 10
>> +#define DWMAC_CKEN_TXN_OUT 9
>> +#define DWMAC_CKEN_TX_OUT 8
>> +#define DWMAC_RX_SOURCE 7
>> +#define DWMAC_TX_SOURCE 6
>> +#define DWMAC_LOW_TX_SOURCE 4
>> +#define DWMAC_AUTO_TX_SOURCE 3
>> +#define DWMAC_RGMII 2
>> +#define DWMAC_SIMPLE_MUX 1
>> +#define DWMAC_CKEN_GTX 0
>> +
>> +/* Delay register */
>> +#define DWMAC_TX_VARDELAY_SHIFT 0
>> +#define DWMAC_TXN_VARDELAY_SHIFT 8
>> +#define DWMAC_RX_VARDELAY_SHIFT 16
>> +#define DWMAC_RXN_VARDELAY_SHIFT 24
>> +#define DWMAC_TX_VARDELAY(d) ((d) << DWMAC_TX_VARDELAY_SHIFT)
>> +#define DWMAC_TXN_VARDELAY(d) ((d) << DWMAC_TXN_VARDELAY_SHIFT)
>> +#define DWMAC_RX_VARDELAY(d) ((d) << DWMAC_RX_VARDELAY_SHIFT)
>> +#define DWMAC_RXN_VARDELAY(d) ((d) << DWMAC_RXN_VARDELAY_SHIFT)
>> +
>> +struct oxnas_dwmac {
>> + struct device *dev;
>> + struct clk *clk;
>> + struct regmap *regmap;
>> +};
>> +
>> +static int oxnas_dwmac_init(struct oxnas_dwmac *dwmac)
>> +{
>> + unsigned int value;
>> + int ret;
>> +
>> + /* Reset HW here before changing the glue configuration */
>> + ret = device_reset(dwmac->dev);
>> + if (ret)
>> + return ret;
>> +
>> + clk_prepare_enable(dwmac->clk);
>
> You might want to check the return value from clk_prepare_enable() as well.
>
>> +
>> + ret = regmap_read(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, &value);
>> + if (ret < 0)
>> + return ret;
>> +
>> + /* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
>> + value |= BIT(DWMAC_CKEN_GTX);
>> + /* Use simple mux for 25/125 Mhz clock switching */
>> + value |= BIT(DWMAC_SIMPLE_MUX);
>> + /* set auto switch tx clock source */
>> + value |= BIT(DWMAC_AUTO_TX_SOURCE);
>> + /* enable tx & rx vardelay */
>> + value |= BIT(DWMAC_CKEN_TX_OUT);
>> + value |= BIT(DWMAC_CKEN_TXN_OUT);
>> + value |= BIT(DWMAC_CKEN_TX_IN);
>> + value |= BIT(DWMAC_CKEN_RX_OUT);
>> + value |= BIT(DWMAC_CKEN_RXN_OUT);
>> + value |= BIT(DWMAC_CKEN_RX_IN);
>> + regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
>> +
>> + /* set tx & rx vardelay */
>> + value = DWMAC_TX_VARDELAY(4);
>> + value |= DWMAC_TXN_VARDELAY(2);
>> + value |= DWMAC_RX_VARDELAY(10);
>> + value |= DWMAC_RXN_VARDELAY(8);
>> + regmap_write(dwmac->regmap, OXNAS_DWMAC_DELAY_REGOFFSET, value);
there is no if condition so, I can suggest you, to hardwire
value with macros instead of computing at runtime:
e.g.
var = DWMAC_VARDELAY where
#define DWMAC_VARDELAY (DWMAC_TX_VARDELAY(4) | ...)
... same for OXNAS_DWMAC_CTRL_REGOFFSET where
BIT(DWMAC_CKEN_ ... ) should be re-organized as macros,
I mean:
#define DWMAC_CKEN_.. BIT(xxx)
>> +
>> + return 0;
>> +}
>> +
>> +static int oxnas_dwmac_probe(struct platform_device *pdev)
>> +{
>> + struct plat_stmmacenet_data *plat_dat;
>> + struct stmmac_resources stmmac_res;
>> + struct device_node *sysctrl;
>> + struct oxnas_dwmac *dwmac;
>> + int ret;
>> +
>> + sysctrl = of_parse_phandle(pdev->dev.of_node, "oxsemi,sys-ctrl", 0);
>> + if (!sysctrl) {
>> + dev_err(&pdev->dev, "failed to get sys-ctrl node\n");
>> + return -EINVAL;
>> + }
>> +
>> + ret = stmmac_get_platform_resources(pdev, &stmmac_res);
>> + if (ret)
>> + return ret;
>> +
>> + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
>> + if (IS_ERR(plat_dat))
>> + return PTR_ERR(plat_dat);
>> +
>> + dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
>> + if (!dwmac)
>> + return -ENOMEM;
>> +
>> + dwmac->dev = &pdev->dev;
>> + plat_dat->bsp_priv = dwmac;
>> +
>> + dwmac->regmap = syscon_node_to_regmap(sysctrl);
>> + if (IS_ERR(dwmac->regmap)) {
>> + dev_err(&pdev->dev, "failed to have sysctrl regmap\n");
>> + return PTR_ERR(dwmac->regmap);
>> + }
>> +
>> + dwmac->clk = devm_clk_get(&pdev->dev, "gmac");
>> + if (IS_ERR(dwmac->clk))
>> + return PTR_ERR(dwmac->clk);
>> +
>> + ret = oxnas_dwmac_init(dwmac);
>> + if (ret)
>> + return ret;
>> +
>> + ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
>> + if (ret)
>> + clk_disable_unprepare(dwmac->clk);
>> +
>> + return ret;
>> +}
>> +
>> +static int oxnas_dwmac_remove(struct platform_device *pdev)
>> +{
>> + struct net_device *ndev = platform_get_drvdata(pdev);
>> + struct stmmac_priv *priv = netdev_priv(ndev);
>> + struct oxnas_dwmac *dwmac = priv->plat->bsp_priv;
>
> Instead of this long dance of variables use the get_stmmac_bsp_priv()-helper.
>
> You can take a look at dwmac-meson8b.c for reference.
>
>
>> + int ret = stmmac_dvr_remove(&pdev->dev);
>> +
>> + clk_disable_unprepare(dwmac->clk);
>> +
>> + return ret;
>> +}
>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int oxnas_dwmac_suspend(struct device *dev)
>> +{
>> + struct net_device *ndev = dev_get_drvdata(dev);
>> + struct stmmac_priv *priv = netdev_priv(ndev);
>> + struct oxnas_dwmac *dwmac = priv->plat->bsp_priv;
>
> get_stmmac_bsp_priv()
>
>
>> + int ret;
>> +
>> + ret = stmmac_suspend(dev);
>> + clk_disable_unprepare(dwmac->clk);
>> +
>> + return ret;
>> +}
>> +
>> +static int oxnas_dwmac_resume(struct device *dev)
>> +{
>> + struct net_device *ndev = dev_get_drvdata(dev);
>> + struct stmmac_priv *priv = netdev_priv(ndev);
>> + struct oxnas_dwmac *dwmac = priv->plat->bsp_priv;
>
> get_stmmac_bsp_priv()
>
>
>> + int ret;
>> +
>> + ret = oxnas_dwmac_init(dwmac);
>> + if (ret)
>> + return ret;
>> +
>> + ret = stmmac_resume(dev);
>> +
>> + return ret;
>> +}
>> +#endif /* CONFIG_PM_SLEEP */
>
> With these changes:
> Acked-by: Joachim Eastwood <manabian@gmail.com>
>
>
> best regards,
> Joachim Eastwood
>
^ permalink raw reply
* [STLinux Kernel] [PATCH v2 1/6] ARM: dts: STiH407: DT fix s/interrupts-names/interrupt-names/
From: Patrice Chotard @ 2016-10-21 11:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161021101156.GA32234@griffinp-ThinkPad-X1-Carbon-2nd>
On 10/21/2016 12:11 PM, Peter Griffin wrote:
> On Fri, 21 Oct 2016, Geert Uytterhoeven wrote:
>
>> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>> Acked-by: Rob Herring <robh@kernel.org>
>> ---
>> v2:
>> - Add Acked-by.
>> ---
>
> Acked-by: Peter Griffin <peter.griffin@linaro.org>
>
applied with Peter Acked-by
Thanks Geert
^ permalink raw reply
* [PATCH] PM / Domains: Restrict "samsung, power-domain" checks to ARCH_EXYNOS
From: Geert Uytterhoeven @ 2016-10-21 11:34 UTC (permalink / raw)
To: linux-arm-kernel
Currently the generic PM Domain code code checks for the presence of
both (generic) "power-domains" and (Samsung Exynos legacy)
"samsung,power-domain" properties in all device tree nodes representing
devices.
There are two issues with this:
1. This imposes a small boot-time penalty on all platforms using DT,
2. Platform-specific checks do not really belong in core framework
code.
While moving the check from platform-agnostic code to Samsung-specific
code is non-trivial, the runtime overhead can be restricted to kernels
including support for 32-bit Samsung Exynos platforms.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
"samsung,power-domain" was only ever used in:
- arch/arm/boot/dts/exynos4415.dtsi: Unused?
- arch/arm/boot/dts/exynos3250.dtsi: CONFIG_ARCH_EXYNOS3
- arch/arm/boot/dts/exynos4.dtsi: CONFIG_ARCH_EXYNOS4
- arch/arm/boot/dts/exynos4x12.dtsi: CONFIG_ARCH_EXYNOS4
exynos4212.dtsi is unused?
- arch/arm/boot/dts/exynos5250.dtsi: CONFIG_ARCH_EXYNOS5
- arch/arm/boot/dts/exynos5420.dtsi: CONFIG_ARCH_EXYNOS5
---
drivers/base/power/domain.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index e023066e421547c5..d94d6a4b9b527108 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1853,7 +1853,8 @@ int genpd_dev_pm_attach(struct device *dev)
ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
"#power-domain-cells", 0, &pd_args);
if (ret < 0) {
- if (ret != -ENOENT)
+ if (ret != -ENOENT || !IS_ENABLED(CONFIG_ARCH_EXYNOS) ||
+ IS_ENABLED(CONFIG_64BIT))
return ret;
/*
--
1.9.1
^ permalink raw reply related
* [PATCH] arm64: fix show_regs fallout from KERN_CONT changes
From: Robin Murphy @ 2016-10-21 11:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476962596-21046-1-git-send-email-mark.rutland@arm.com>
Hi Mark,
On 20/10/16 12:23, Mark Rutland wrote:
> Recently in commit 4bcc595ccd80decb ("printk: reinstate KERN_CONT for
> printing continuation lines"), the behaviour of printk changed w.r.t.
> KERN_CONT. Now, KERN_CONT is mandatory to continue existing lines.
> Without this, prefixes are inserted, making output illegible, e.g.
>
> [ 1007.069010] pc : [<ffff00000871898c>] lr : [<ffff000008718948>] pstate: 40000145
> [ 1007.076329] sp : ffff000008d53ec0
> [ 1007.079606] x29: ffff000008d53ec0 [ 1007.082797] x28: 0000000080c50018
> [ 1007.086160]
> [ 1007.087630] x27: ffff000008e0c7f8 [ 1007.090820] x26: ffff80097631ca00
> [ 1007.094183]
> [ 1007.095653] x25: 0000000000000001 [ 1007.098843] x24: 000000ea68b61cac
> [ 1007.102206]
>
> ... or when dumped with the userpace dmesg tool, which has slightly
> different implicit newline behaviour. e.g.
>
> [ 1007.069010] pc : [<ffff00000871898c>] lr : [<ffff000008718948>] pstate: 40000145
> [ 1007.076329] sp : ffff000008d53ec0
> [ 1007.079606] x29: ffff000008d53ec0
> [ 1007.082797] x28: 0000000080c50018
> [ 1007.086160]
> [ 1007.087630] x27: ffff000008e0c7f8
> [ 1007.090820] x26: ffff80097631ca00
> [ 1007.094183]
> [ 1007.095653] x25: 0000000000000001
> [ 1007.098843] x24: 000000ea68b61cac
> [ 1007.102206]
>
> We can't simply always use KERN_CONT for lines which may or may not be
> continuations. That causes line prefixes (e.g. timestamps) to be
> supressed, and the alignment of all but the first line will be broken.
>
> For even more fun, we can't simply insert some dummy empty-string printk
> calls, as GCC warns for an empty printk string, and even if we pass
> KERN_DEFAULT explcitly to silence the warning, the prefix gets swallowed
> unless there is an additional part to the string.
>
> Instead, we must manually iterate over pairs of registers, which gives
> us the legible output we want in either case, e.g.
>
> [ 169.771790] pc : [<ffff00000871898c>] lr : [<ffff000008718948>] pstate: 40000145
> [ 169.779109] sp : ffff000008d53ec0
> [ 169.782386] x29: ffff000008d53ec0 x28: 0000000080c50018
> [ 169.787650] x27: ffff000008e0c7f8 x26: ffff80097631de00
> [ 169.792913] x25: 0000000000000001 x24: 00000027827b2cf4
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
> arch/arm64/kernel/process.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index ddce61b..3f31cf93 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -187,10 +187,19 @@ void __show_regs(struct pt_regs *regs)
> printk("pc : [<%016llx>] lr : [<%016llx>] pstate: %08llx\n",
> regs->pc, lr, regs->pstate);
> printk("sp : %016llx\n", sp);
> - for (i = top_reg; i >= 0; i--) {
> +
> + i = top_reg;
> +
> + while (i >= 0) {
> printk("x%-2d: %016llx ", i, regs->regs[i]);
> - if (i % 2 == 0)
> - printk("\n");
> + i--;
> +
> + if (i % 2 == 0) {
> + pr_cont("x%-2d: %016llx ", i, regs->regs[i]);
> + i--;
> + }
> +
> + pr_cont("\n");
> }
Might it be nicer to simply do this (or thereabouts)?
for (i = top_reg; i > 1; i -= 2)
printk("x%-2d: %016llx x%-2d: %016llx\n", i-1,
regs->regs[i-1], i, regs->regs[i]);
if (i > 0)
printk("x%-2d: %016llx\n", i-1, regs->regs[i-1]);
Robin.
> printk("\n");
> }
>
^ permalink raw reply
* [PATCH v14 7/9] clocksource/drivers/arm_arch_timer: Refactor the timer init code to prepare for GTDT
From: Mark Rutland @ 2016-10-21 11:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475086637-1914-8-git-send-email-fu.wei@linaro.org>
On Thu, Sep 29, 2016 at 02:17:15AM +0800, fu.wei at linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
>
> The patch refactor original memory-mapped timer init code:
> (1) extract some subfunction for reusing some common code
> a. get_cnttidr
> b. is_best_frame
> (2) move base address and irq code for arch_timer_mem to
> arch_timer_mem_register
>
> Signed-off-by: Fu Wei <fu.wei@linaro.org>
> ---
> drivers/clocksource/arm_arch_timer.c | 159 +++++++++++++++++++++--------------
> 1 file changed, 96 insertions(+), 63 deletions(-)
>
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index c7b0040..e78095f 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -57,6 +57,7 @@
> static unsigned arch_timers_present __initdata;
>
> static void __iomem *arch_counter_base;
> +static void __iomem *cntctlbase __initdata;
>
> struct arch_timer {
> void __iomem *base;
> @@ -656,15 +657,49 @@ out:
> return err;
> }
>
> -static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq)
> +static int __init arch_timer_mem_register(struct device_node *np, void *frame)
> {
> - int ret;
> - irq_handler_t func;
> + struct device_node *frame_node = NULL;
> struct arch_timer *t;
> + void __iomem *base;
> + irq_handler_t func;
> + unsigned int irq;
> + int ret;
> +
> + if (!frame)
> + return -EINVAL;
Why would we call this without a frame?
> +
> + if (np) {
... or without a node?
> + frame_node = (struct device_node *)frame;
> + base = of_iomap(frame_node, 0);
> + arch_timer_detect_rate(base, np);
... BANG! (we check base too late, below).
Please as Marc requested several versions ago: split the FW parsing
(ACPI and DT) so that happens first, *then* once we have the data in a
common format, use that to drive poking the HW, requesting IRQs, etc,
completely independent of the source.
In patches, do this by:
(1) adding the data structures
(2) splitting the existing DT probing to use them
(3) Adding ACPI functionality atop
> -static int __init arch_timer_mem_init(struct device_node *np)
> +static int __init get_cnttidr(struct device_node *np, u32 *cnttidr)
> {
> - struct device_node *frame, *best_frame = NULL;
> - void __iomem *cntctlbase, *base;
> - unsigned int irq, ret = -EINVAL;
> - u32 cnttidr;
> + if (!cnttidr)
> + return -EINVAL;
> +
> + if (np)
> + cntctlbase = of_iomap(np, 0);
> + else
> + return -EINVAL;
We want to check this for ACPI too, no?
Thanks,
Mark.
^ permalink raw reply
* [PATCH v4 3/3] arm64: mm: set the contiguous bit for kernel mappings where appropriate
From: Ard Biesheuvel @ 2016-10-21 11:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477048978-4140-1-git-send-email-ard.biesheuvel@linaro.org>
Now that we no longer allow live kernel PMDs to be split, it is safe to
start using the contiguous bit for kernel mappings. So set the contiguous
bit in the kernel page mappings for regions whose size and alignment are
suitable for this.
This enables the following contiguous range sizes for the virtual mapping
of the kernel image, and for the linear mapping:
granule size | cont PTE | cont PMD |
-------------+------------+------------+
4 KB | 64 KB | 32 MB |
16 KB | 2 MB | 1 GB* |
64 KB | 2 MB | 16 GB* |
* Only when built for 3 or more levels of translation. This is due to the
fact that a 2 level configuration only consists of PGDs and PTEs, and the
added complexity of dealing with folded PMDs is not justified considering
that 16 GB contiguous ranges are likely to be ignored by the hardware (and
16k/2 levels is a niche configuration)
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/mm/mmu.c | 34 +++++++++++++++++---
1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 7b0dd07212ae..dd5f12d0959e 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -107,8 +107,10 @@ static bool pgattr_change_is_safe(u64 old, u64 new)
static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
unsigned long end, unsigned long pfn,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(void))
+ phys_addr_t (*pgtable_alloc)(void),
+ bool page_mappings_only)
{
+ pgprot_t __prot = prot;
pte_t *pte;
BUG_ON(pmd_sect(*pmd));
@@ -126,7 +128,18 @@ static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
do {
pte_t old_pte = *pte;
- set_pte(pte, pfn_pte(pfn, prot));
+ /*
+ * Set the contiguous bit for the subsequent group of PTEs if
+ * its size and alignment are appropriate.
+ */
+ if (((addr | PFN_PHYS(pfn)) & ~CONT_PTE_MASK) == 0) {
+ if (end - addr >= CONT_PTE_SIZE && !page_mappings_only)
+ __prot = __pgprot(pgprot_val(prot) | PTE_CONT);
+ else
+ __prot = prot;
+ }
+
+ set_pte(pte, pfn_pte(pfn, __prot));
pfn++;
/*
@@ -145,6 +158,7 @@ static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end,
phys_addr_t (*pgtable_alloc)(void),
bool page_mappings_only)
{
+ pgprot_t __prot = prot;
pmd_t *pmd;
unsigned long next;
@@ -171,7 +185,18 @@ static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end,
/* try section mapping first */
if (((addr | next | phys) & ~SECTION_MASK) == 0 &&
!page_mappings_only) {
- pmd_set_huge(pmd, phys, prot);
+ /*
+ * Set the contiguous bit for the subsequent group of
+ * PMDs if its size and alignment are appropriate.
+ */
+ if (((addr | phys) & ~CONT_PMD_MASK) == 0) {
+ if (end - addr >= CONT_PMD_SIZE)
+ __prot = __pgprot(pgprot_val(prot) |
+ PTE_CONT);
+ else
+ __prot = prot;
+ }
+ pmd_set_huge(pmd, phys, __prot);
/*
* After the PMD entry has been populated once, we
@@ -181,7 +206,8 @@ static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end,
pmd_val(*pmd)));
} else {
alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys),
- prot, pgtable_alloc);
+ prot, pgtable_alloc,
+ page_mappings_only);
BUG_ON(pmd_val(old_pmd) != 0 &&
pmd_val(old_pmd) != pmd_val(*pmd));
--
2.7.4
^ permalink raw reply related
* [PATCH v4 2/3] arm64: mm: replace 'block_mappings_allowed' with 'page_mappings_only'
From: Ard Biesheuvel @ 2016-10-21 11:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477048978-4140-1-git-send-email-ard.biesheuvel@linaro.org>
In preparation of adding support for contiguous PTE and PMD mappings,
let's replace 'block_mappings_allowed' with 'page_mappings_only', which
will be a more accurate description of the nature of the setting once we
add such contiguous mappings into the mix.
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/include/asm/mmu.h | 2 +-
arch/arm64/kernel/efi.c | 8 ++---
arch/arm64/mm/mmu.c | 32 ++++++++++----------
3 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 8d9fce037b2f..a81454ad5455 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -34,7 +34,7 @@ extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt);
extern void init_mem_pgprot(void);
extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
- pgprot_t prot, bool allow_block_mappings);
+ pgprot_t prot, bool page_mappings_only);
extern void *fixmap_remap_fdt(phys_addr_t dt_phys);
#endif
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index ba9bee389fd5..5d17f377d905 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -62,8 +62,8 @@ struct screen_info screen_info __section(.data);
int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
{
pteval_t prot_val = create_mapping_protection(md);
- bool allow_block_mappings = (md->type != EFI_RUNTIME_SERVICES_CODE &&
- md->type != EFI_RUNTIME_SERVICES_DATA);
+ bool page_mappings_only = (md->type == EFI_RUNTIME_SERVICES_CODE ||
+ md->type == EFI_RUNTIME_SERVICES_DATA);
if (!PAGE_ALIGNED(md->phys_addr) ||
!PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT)) {
@@ -76,12 +76,12 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
* from the MMU routines. So avoid block mappings altogether in
* that case.
*/
- allow_block_mappings = false;
+ page_mappings_only = true;
}
create_pgd_mapping(mm, md->phys_addr, md->virt_addr,
md->num_pages << EFI_PAGE_SHIFT,
- __pgprot(prot_val | PTE_NG), allow_block_mappings);
+ __pgprot(prot_val | PTE_NG), page_mappings_only);
return 0;
}
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 27dc0e5012a8..7b0dd07212ae 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -143,7 +143,7 @@ static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
phys_addr_t (*pgtable_alloc)(void),
- bool allow_block_mappings)
+ bool page_mappings_only)
{
pmd_t *pmd;
unsigned long next;
@@ -170,7 +170,7 @@ static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end,
/* try section mapping first */
if (((addr | next | phys) & ~SECTION_MASK) == 0 &&
- allow_block_mappings) {
+ !page_mappings_only) {
pmd_set_huge(pmd, phys, prot);
/*
@@ -207,7 +207,7 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next,
static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
phys_addr_t (*pgtable_alloc)(void),
- bool allow_block_mappings)
+ bool page_mappings_only)
{
pud_t *pud;
unsigned long next;
@@ -229,7 +229,7 @@ static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
/*
* For 4K granule only, attempt to put down a 1GB block
*/
- if (use_1G_block(addr, next, phys) && allow_block_mappings) {
+ if (use_1G_block(addr, next, phys) && !page_mappings_only) {
pud_set_huge(pud, phys, prot);
/*
@@ -240,7 +240,7 @@ static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
pud_val(*pud)));
} else {
alloc_init_pmd(pud, addr, next, phys, prot,
- pgtable_alloc, allow_block_mappings);
+ pgtable_alloc, page_mappings_only);
BUG_ON(pud_val(old_pud) != 0 &&
pud_val(old_pud) != pud_val(*pud));
@@ -255,7 +255,7 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
phys_addr_t (*pgtable_alloc)(void),
- bool allow_block_mappings)
+ bool page_mappings_only)
{
unsigned long addr, length, end, next;
pgd_t *pgd = pgd_offset_raw(pgdir, virt);
@@ -275,7 +275,7 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
do {
next = pgd_addr_end(addr, end);
alloc_init_pud(pgd, addr, next, phys, prot, pgtable_alloc,
- allow_block_mappings);
+ page_mappings_only);
phys += next - addr;
} while (pgd++, addr = next, addr != end);
}
@@ -304,17 +304,17 @@ static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
&phys, virt);
return;
}
- __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, true);
+ __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, false);
}
void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
- pgprot_t prot, bool allow_block_mappings)
+ pgprot_t prot, bool page_mappings_only)
{
BUG_ON(mm == &init_mm);
__create_pgd_mapping(mm->pgd, phys, virt, size, prot,
- pgd_pgtable_alloc, allow_block_mappings);
+ pgd_pgtable_alloc, page_mappings_only);
}
static void create_mapping_late(phys_addr_t phys, unsigned long virt,
@@ -327,7 +327,7 @@ static void create_mapping_late(phys_addr_t phys, unsigned long virt,
}
__create_pgd_mapping(init_mm.pgd, phys, virt, size, prot,
- NULL, !debug_pagealloc_enabled());
+ NULL, debug_pagealloc_enabled());
}
static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end)
@@ -345,7 +345,7 @@ static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end
__create_pgd_mapping(pgd, start, __phys_to_virt(start),
end - start, PAGE_KERNEL,
early_pgtable_alloc,
- !debug_pagealloc_enabled());
+ debug_pagealloc_enabled());
return;
}
@@ -358,13 +358,13 @@ static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end
__phys_to_virt(start),
kernel_start - start, PAGE_KERNEL,
early_pgtable_alloc,
- !debug_pagealloc_enabled());
+ debug_pagealloc_enabled());
if (kernel_end < end)
__create_pgd_mapping(pgd, kernel_end,
__phys_to_virt(kernel_end),
end - kernel_end, PAGE_KERNEL,
early_pgtable_alloc,
- !debug_pagealloc_enabled());
+ debug_pagealloc_enabled());
/*
* Map the linear alias of the [_text, __init_begin) interval as
@@ -374,7 +374,7 @@ static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end
*/
__create_pgd_mapping(pgd, kernel_start, __phys_to_virt(kernel_start),
kernel_end - kernel_start, PAGE_KERNEL_RO,
- early_pgtable_alloc, !debug_pagealloc_enabled());
+ early_pgtable_alloc, debug_pagealloc_enabled());
}
static void __init map_mem(pgd_t *pgd)
@@ -424,7 +424,7 @@ static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
BUG_ON(!PAGE_ALIGNED(size));
__create_pgd_mapping(pgd, pa_start, (unsigned long)va_start, size, prot,
- early_pgtable_alloc, !debug_pagealloc_enabled());
+ early_pgtable_alloc, debug_pagealloc_enabled());
vma->addr = va_start;
vma->phys_addr = pa_start;
--
2.7.4
^ permalink raw reply related
* [PATCH v4 1/3] arm64: mm: BUG on unsupported manipulations of live kernel mappings
From: Ard Biesheuvel @ 2016-10-21 11:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477048978-4140-1-git-send-email-ard.biesheuvel@linaro.org>
Now that we take care not manipulate the live kernel page tables in a
way that may lead to TLB conflicts, the case where a table mapping is
replaced by a block mapping can no longer occur. So remove the handling
of this at the PUD and PMD levels, and instead, BUG() on any occurrence
of live kernel page table manipulations that modify anything other than
the permission bits.
Since mark_rodata_ro() is the only caller where the kernel mappings that
are being manipulated are actually live, drop the various conditional
flush_tlb_all() invocations, and add a single call to mark_rodata_ro()
instead.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/mm/mmu.c | 70 ++++++++++++--------
1 file changed, 43 insertions(+), 27 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 05615a3fdc6f..27dc0e5012a8 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -28,8 +28,6 @@
#include <linux/memblock.h>
#include <linux/fs.h>
#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/stop_machine.h>
#include <asm/barrier.h>
#include <asm/cputype.h>
@@ -95,6 +93,17 @@ static phys_addr_t __init early_pgtable_alloc(void)
return phys;
}
+static bool pgattr_change_is_safe(u64 old, u64 new)
+{
+ /*
+ * The following mapping attributes may be updated in live
+ * kernel mappings without the need for break-before-make.
+ */
+ static const pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE;
+
+ return old == 0 || new == 0 || ((old ^ new) & ~mask) == 0;
+}
+
static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
unsigned long end, unsigned long pfn,
pgprot_t prot,
@@ -115,8 +124,17 @@ static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
pte = pte_set_fixmap_offset(pmd, addr);
do {
+ pte_t old_pte = *pte;
+
set_pte(pte, pfn_pte(pfn, prot));
pfn++;
+
+ /*
+ * After the PTE entry has been populated once, we
+ * only allow updates to the permission attributes.
+ */
+ BUG_ON(!pgattr_change_is_safe(pte_val(old_pte), pte_val(*pte)));
+
} while (pte++, addr += PAGE_SIZE, addr != end);
pte_clear_fixmap();
@@ -146,27 +164,27 @@ static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end,
pmd = pmd_set_fixmap_offset(pud, addr);
do {
+ pmd_t old_pmd = *pmd;
+
next = pmd_addr_end(addr, end);
+
/* try section mapping first */
if (((addr | next | phys) & ~SECTION_MASK) == 0 &&
allow_block_mappings) {
- pmd_t old_pmd =*pmd;
pmd_set_huge(pmd, phys, prot);
+
/*
- * Check for previous table entries created during
- * boot (__create_page_tables) and flush them.
+ * After the PMD entry has been populated once, we
+ * only allow updates to the permission attributes.
*/
- if (!pmd_none(old_pmd)) {
- flush_tlb_all();
- if (pmd_table(old_pmd)) {
- phys_addr_t table = pmd_page_paddr(old_pmd);
- if (!WARN_ON_ONCE(slab_is_available()))
- memblock_free(table, PAGE_SIZE);
- }
- }
+ BUG_ON(!pgattr_change_is_safe(pmd_val(old_pmd),
+ pmd_val(*pmd)));
} else {
alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys),
prot, pgtable_alloc);
+
+ BUG_ON(pmd_val(old_pmd) != 0 &&
+ pmd_val(old_pmd) != pmd_val(*pmd));
}
phys += next - addr;
} while (pmd++, addr = next, addr != end);
@@ -204,33 +222,28 @@ static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
pud = pud_set_fixmap_offset(pgd, addr);
do {
+ pud_t old_pud = *pud;
+
next = pud_addr_end(addr, end);
/*
* For 4K granule only, attempt to put down a 1GB block
*/
if (use_1G_block(addr, next, phys) && allow_block_mappings) {
- pud_t old_pud = *pud;
pud_set_huge(pud, phys, prot);
/*
- * If we have an old value for a pud, it will
- * be pointing to a pmd table that we no longer
- * need (from swapper_pg_dir).
- *
- * Look up the old pmd table and free it.
+ * After the PUD entry has been populated once, we
+ * only allow updates to the permission attributes.
*/
- if (!pud_none(old_pud)) {
- flush_tlb_all();
- if (pud_table(old_pud)) {
- phys_addr_t table = pud_page_paddr(old_pud);
- if (!WARN_ON_ONCE(slab_is_available()))
- memblock_free(table, PAGE_SIZE);
- }
- }
+ BUG_ON(!pgattr_change_is_safe(pud_val(old_pud),
+ pud_val(*pud)));
} else {
alloc_init_pmd(pud, addr, next, phys, prot,
pgtable_alloc, allow_block_mappings);
+
+ BUG_ON(pud_val(old_pud) != 0 &&
+ pud_val(old_pud) != pud_val(*pud));
}
phys += next - addr;
} while (pud++, addr = next, addr != end);
@@ -396,6 +409,9 @@ void mark_rodata_ro(void)
section_size = (unsigned long)__init_begin - (unsigned long)__start_rodata;
create_mapping_late(__pa(__start_rodata), (unsigned long)__start_rodata,
section_size, PAGE_KERNEL_RO);
+
+ /* flush the TLBs after updating live kernel mappings */
+ flush_tlb_all();
}
static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
--
2.7.4
^ permalink raw reply related
* [PATCH v4 0/3] arm64/mm: use the contiguous attribute for kernel mappings
From: Ard Biesheuvel @ 2016-10-21 11:22 UTC (permalink / raw)
To: linux-arm-kernel
Back to a 3-piece series.
Changes in v4:
- dropped handling of contiguous PUDs and folded PMDs, given that the hardware
is likely to ignore the contiguous bit at this level anyway
- factor out the pte/pmd/pgd attribute BUG check (#1)
Changes in v3 [0]:
- add support for contiguous PMDs for all granule sizes (not just 16k)
- add a separate patch to deal with contiguous PUDs (4k granule only), and
contiguous PMDs for 2 levels of translation (which requires special handling)
- avoid pmd_none/pud_none in the BUG() statements in patch #1, since they
may resolve in unexpected ways with folded PMDs/PUDs
Version v2 [1] addressed the following issues:
- the contiguous attribute is also useful for contigous PMD mappings on 16k
granule kernels (i.e., 1 GB blocks)
- the function parameter 'block_mappings_allowed' does not clearly convey
whether contiguous page mappings should be used, so it is renamed to
'page_mappings_only', and its meaning inverted
- instead of BUGging on changes in the PTE_CONT attribute in PMD or PTE entries
that have been populated already, BUG on any modification except for
permission attributes, which don't require break-before-make when changed.
[0] http://marc.info/?l=linux-arm-kernel&m=147627155206982
[1] http://marc.info/?l=linux-arm-kernel&m=147618975314593
Ard Biesheuvel (3):
arm64: mm: BUG on unsupported manipulations of live kernel mappings
arm64: mm: replace 'block_mappings_allowed' with 'page_mappings_only'
arm64: mm: set the contiguous bit for kernel mappings where
appropriate
arch/arm64/include/asm/mmu.h | 2 +-
arch/arm64/kernel/efi.c | 8 +-
arch/arm64/mm/mmu.c | 134 +++++++++++++-------
3 files changed, 93 insertions(+), 51 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH v14 5/9] clocksource/drivers/arm_arch_timer: Simplify ACPI support code.
From: Mark Rutland @ 2016-10-21 11:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161021111352.GA16630@leverpostej>
On Fri, Oct 21, 2016 at 12:14:01PM +0100, Mark Rutland wrote:
> On Thu, Oct 20, 2016 at 05:58:17PM +0100, Mark Rutland wrote:
> > On Thu, Sep 29, 2016 at 02:17:13AM +0800, fu.wei at linaro.org wrote:
> > > + arch_timer_ppi[PHYS_NONSECURE_PPI] = acpi_gtdt_map_ppi(PHYS_NONSECURE_PPI);
> > > + arch_timer_ppi[VIRT_PPI] = acpi_gtdt_map_ppi(VIRT_PPI);
> > > + arch_timer_ppi[HYP_PPI] = acpi_gtdt_map_ppi(HYP_PPI);
> > > + /* Always-on capability */
> > > + arch_timer_c3stop = acpi_gtdt_c3stop();
> >
> > ... I think we should check the flag on the relevant interrupt, though
> > that's worth clarifying.
>
> I see I misread the spec; this is part of the common flags.
>
> Please ignore this point; sorry for the noise.
Actually, I misread the spec this time around; the flag *can* differ per
interrupt for the sysreg/cp15 timer, but not for the MMIO timers where
the flag is in a common field.
So please *do* consider the above.
Thanks,
Mark.
^ permalink raw reply
* [RFC PATCH 8/8] ARM: KVM: Support vGICv3 ITS
From: Vladimir Murzin @ 2016-10-21 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <857fb7fd-b8eb-7a44-2a6c-be2ec41927ec@arm.com>
On 21/10/16 12:02, Andre Przywara wrote:
> Hi,
>
> On 21/10/16 10:36, Vladimir Murzin wrote:
>> This patch allows to build and use vGICv3 ITS in 32-bit mode.
>
> Ah, what a relief to see that config option go. Thanks for that!
>
> I quickly booted an ITS guest on a (64-bit) model and couldn't spot any
> regressions.
Awesome!
>
>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Thanks for your time!
Cheers
Vladimir
>
> Cheers,
> Andre.
>
>> ---
>> Documentation/virtual/kvm/api.txt | 2 +-
>> arch/arm/include/uapi/asm/kvm.h | 2 ++
>> arch/arm/kvm/Kconfig | 1 +
>> arch/arm/kvm/Makefile | 1 +
>> arch/arm/kvm/arm.c | 6 ++++++
>> arch/arm64/kvm/Kconfig | 4 ----
>> arch/arm64/kvm/reset.c | 6 ------
>> virt/kvm/arm/vgic/vgic-kvm-device.c | 2 --
>> virt/kvm/arm/vgic/vgic-mmio-v3.c | 2 --
>> virt/kvm/arm/vgic/vgic.h | 26 --------------------------
>> 10 files changed, 11 insertions(+), 41 deletions(-)
>>
>> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
>> index 739db9a..2feeae6 100644
>> --- a/Documentation/virtual/kvm/api.txt
>> +++ b/Documentation/virtual/kvm/api.txt
>> @@ -2198,7 +2198,7 @@ after pausing the vcpu, but before it is resumed.
>> 4.71 KVM_SIGNAL_MSI
>>
>> Capability: KVM_CAP_SIGNAL_MSI
>> -Architectures: x86 arm64
>> +Architectures: x86 arm arm64
>> Type: vm ioctl
>> Parameters: struct kvm_msi (in)
>> Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error
>> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
>> index b38c10c..af05f8e 100644
>> --- a/arch/arm/include/uapi/asm/kvm.h
>> +++ b/arch/arm/include/uapi/asm/kvm.h
>> @@ -87,9 +87,11 @@ struct kvm_regs {
>> /* Supported VGICv3 address types */
>> #define KVM_VGIC_V3_ADDR_TYPE_DIST 2
>> #define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
>> +#define KVM_VGIC_ITS_ADDR_TYPE 4
>>
>> #define KVM_VGIC_V3_DIST_SIZE SZ_64K
>> #define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
>> +#define KVM_VGIC_V3_ITS_SIZE (2 * SZ_64K)
>>
>> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
>> #define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
>> diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
>> index 3e1cd04..90d0176 100644
>> --- a/arch/arm/kvm/Kconfig
>> +++ b/arch/arm/kvm/Kconfig
>> @@ -34,6 +34,7 @@ config KVM
>> select HAVE_KVM_IRQFD
>> select HAVE_KVM_IRQCHIP
>> select HAVE_KVM_IRQ_ROUTING
>> + select HAVE_KVM_MSI
>> depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
>> ---help---
>> Support hosting virtualized guest machines.
>> diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
>> index f19842e..d571243 100644
>> --- a/arch/arm/kvm/Makefile
>> +++ b/arch/arm/kvm/Makefile
>> @@ -32,5 +32,6 @@ obj-y += $(KVM)/arm/vgic/vgic-mmio.o
>> obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
>> obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
>> obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
>> +obj-y += $(KVM)/arm/vgic/vgic-its.o
>> obj-y += $(KVM)/irqchip.o
>> obj-y += $(KVM)/arm/arch_timer.o
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 03e9273..8b13448 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -209,6 +209,12 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>> case KVM_CAP_MAX_VCPUS:
>> r = KVM_MAX_VCPUS;
>> break;
>> + case KVM_CAP_MSI_DEVID:
>> + if (!kvm)
>> + r = -EINVAL;
>> + else
>> + r = kvm->arch.vgic.msis_require_devid;
>> + break;
>> default:
>> r = kvm_arch_dev_ioctl_check_extension(kvm, ext);
>> break;
>> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
>> index 6eaf12c..52cb7ad 100644
>> --- a/arch/arm64/kvm/Kconfig
>> +++ b/arch/arm64/kvm/Kconfig
>> @@ -16,9 +16,6 @@ menuconfig VIRTUALIZATION
>>
>> if VIRTUALIZATION
>>
>> -config KVM_ARM_VGIC_V3_ITS
>> - bool
>> -
>> config KVM
>> bool "Kernel-based Virtual Machine (KVM) support"
>> depends on OF
>> @@ -34,7 +31,6 @@ config KVM
>> select KVM_VFIO
>> select HAVE_KVM_EVENTFD
>> select HAVE_KVM_IRQFD
>> - select KVM_ARM_VGIC_V3_ITS
>> select KVM_ARM_PMU if HW_PERF_EVENTS
>> select HAVE_KVM_MSI
>> select HAVE_KVM_IRQCHIP
>> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
>> index 5bc4608..e95d4f6 100644
>> --- a/arch/arm64/kvm/reset.c
>> +++ b/arch/arm64/kvm/reset.c
>> @@ -86,12 +86,6 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
>> case KVM_CAP_VCPU_ATTRIBUTES:
>> r = 1;
>> break;
>> - case KVM_CAP_MSI_DEVID:
>> - if (!kvm)
>> - r = -EINVAL;
>> - else
>> - r = kvm->arch.vgic.msis_require_devid;
>> - break;
>> default:
>> r = 0;
>> }
>> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> index ce1f4ed..fbe87a6 100644
>> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
>> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> @@ -221,11 +221,9 @@ int kvm_register_vgic_device(unsigned long type)
>> ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
>> KVM_DEV_TYPE_ARM_VGIC_V3);
>>
>> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>> if (ret)
>> break;
>> ret = kvm_vgic_register_its_device();
>> -#endif
>> break;
>> }
>>
>> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> index 0d3c76a..50f42f0 100644
>> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> @@ -42,7 +42,6 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
>> return reg | ((u64)val << lower);
>> }
>>
>> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>> bool vgic_has_its(struct kvm *kvm)
>> {
>> struct vgic_dist *dist = &kvm->arch.vgic;
>> @@ -52,7 +51,6 @@ bool vgic_has_its(struct kvm *kvm)
>>
>> return dist->has_its;
>> }
>> -#endif
>>
>> static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
>> gpa_t addr, unsigned int len)
>> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
>> index 9d9e014..859f65c 100644
>> --- a/virt/kvm/arm/vgic/vgic.h
>> +++ b/virt/kvm/arm/vgic/vgic.h
>> @@ -84,37 +84,11 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
>> int vgic_v3_map_resources(struct kvm *kvm);
>> int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
>>
>> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>> int vgic_register_its_iodevs(struct kvm *kvm);
>> bool vgic_has_its(struct kvm *kvm);
>> int kvm_vgic_register_its_device(void);
>> void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>> int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
>> -#else
>> -static inline int vgic_register_its_iodevs(struct kvm *kvm)
>> -{
>> - return -ENODEV;
>> -}
>> -
>> -static inline bool vgic_has_its(struct kvm *kvm)
>> -{
>> - return false;
>> -}
>> -
>> -static inline int kvm_vgic_register_its_device(void)
>> -{
>> - return -ENODEV;
>> -}
>> -
>> -static inline void vgic_enable_lpis(struct kvm_vcpu *vcpu)
>> -{
>> -}
>> -
>> -static inline int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
>> -{
>> - return -ENODEV;
>> -}
>> -#endif
>>
>> int kvm_register_vgic_device(unsigned long type);
>> int vgic_lazy_init(struct kvm *kvm);
>>
>
^ permalink raw reply
* [RFC PATCH 7/8] KVM: arm64: vgic-its: fix compatability with 32-bit
From: Vladimir Murzin @ 2016-10-21 11:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5ea0ecc0-edb1-f770-16f3-7c48dbdb5c29@arm.com>
On 21/10/16 10:49, Andre Przywara wrote:
> Hi,
>
> On 21/10/16 10:36, Vladimir Murzin wrote:
>> Evaluate GITS_BASER_ENTRY_SIZE once as an int data (GITS_BASER<n>'s
>> Entry Size is 5-bit wide only), so when used as divider no reference
>> to __aeabi_uldivmod is generated when build for AArch32.
>>
>> Use unsigned long long for GITS_BASER_PAGE_SIZE_* since they are
>> used in conjunction with 64-bit data.
>>
>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>
> Looks good to me, thanks for fixing this!
>
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Thanks!
Vladimir
>
> Cheers,
> Andre.
>
>> ---
>> include/linux/irqchip/arm-gic-v3.h | 8 ++++----
>> virt/kvm/arm/vgic/vgic-its.c | 11 ++++++-----
>> 2 files changed, 10 insertions(+), 9 deletions(-)
>>
>> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
>> index 5118d3a..e808f8a 100644
>> --- a/include/linux/irqchip/arm-gic-v3.h
>> +++ b/include/linux/irqchip/arm-gic-v3.h
>> @@ -295,10 +295,10 @@
>> #define GITS_BASER_InnerShareable \
>> GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable)
>> #define GITS_BASER_PAGE_SIZE_SHIFT (8)
>> -#define GITS_BASER_PAGE_SIZE_4K (0UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> -#define GITS_BASER_PAGE_SIZE_16K (1UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> -#define GITS_BASER_PAGE_SIZE_64K (2UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> -#define GITS_BASER_PAGE_SIZE_MASK (3UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_4K (0ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_16K (1ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_64K (2ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_MASK (3ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>> #define GITS_BASER_PAGES_MAX 256
>> #define GITS_BASER_PAGES_SHIFT (0)
>> #define GITS_BASER_NR_PAGES(r) (((r) & 0xff) + 1)
>> diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
>> index 4660a7d..8c2b3cd 100644
>> --- a/virt/kvm/arm/vgic/vgic-its.c
>> +++ b/virt/kvm/arm/vgic/vgic-its.c
>> @@ -632,21 +632,22 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
>> int index;
>> u64 indirect_ptr;
>> gfn_t gfn;
>> + int esz = GITS_BASER_ENTRY_SIZE(baser);
>>
>> if (!(baser & GITS_BASER_INDIRECT)) {
>> phys_addr_t addr;
>>
>> - if (id >= (l1_tbl_size / GITS_BASER_ENTRY_SIZE(baser)))
>> + if (id >= (l1_tbl_size / esz))
>> return false;
>>
>> - addr = BASER_ADDRESS(baser) + id * GITS_BASER_ENTRY_SIZE(baser);
>> + addr = BASER_ADDRESS(baser) + id * esz;
>> gfn = addr >> PAGE_SHIFT;
>>
>> return kvm_is_visible_gfn(its->dev->kvm, gfn);
>> }
>>
>> /* calculate and check the index into the 1st level */
>> - index = id / (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
>> + index = id / (SZ_64K / esz);
>> if (index >= (l1_tbl_size / sizeof(u64)))
>> return false;
>>
>> @@ -670,8 +671,8 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
>> indirect_ptr &= GENMASK_ULL(51, 16);
>>
>> /* Find the address of the actual entry */
>> - index = id % (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
>> - indirect_ptr += index * GITS_BASER_ENTRY_SIZE(baser);
>> + index = id % (SZ_64K / esz);
>> + indirect_ptr += index * esz;
>> gfn = indirect_ptr >> PAGE_SHIFT;
>>
>> return kvm_is_visible_gfn(its->dev->kvm, gfn);
>>
>
^ permalink raw reply
* [PATCH v14 6/9] acpi/arm64: Add memory-mapped timer support in GTDT driver
From: Mark Rutland @ 2016-10-21 11:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475086637-1914-7-git-send-email-fu.wei@linaro.org>
On Thu, Sep 29, 2016 at 02:17:14AM +0800, fu.wei at linaro.org wrote:
> From: Fu Wei <fu.wei@linaro.org>
>
> On platforms booting with ACPI, architected memory-mapped timers'
> configuration data is provided by firmware through the ACPI GTDT
> static table.
>
> The clocksource architected timer kernel driver requires a firmware
> interface to collect timer configuration and configure its driver.
> this infrastructure is present for device tree systems, but it is
> missing on systems booting with ACPI.
>
> Implement the kernel infrastructure required to parse the static
> ACPI GTDT table so that the architected timer clocksource driver can
> make use of it on systems booting with ACPI, therefore enabling
> the corresponding timers configuration.
>
> Signed-off-by: Fu Wei <fu.wei@linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> ---
> drivers/acpi/arm64/gtdt.c | 70 ++++++++++++++++++++++++++++++++++++
> include/clocksource/arm_arch_timer.h | 15 ++++++++
> include/linux/acpi.h | 1 +
> 3 files changed, 86 insertions(+)
>
> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
> index b24844d..b6021db 100644
> --- a/drivers/acpi/arm64/gtdt.c
> +++ b/drivers/acpi/arm64/gtdt.c
> @@ -150,3 +150,73 @@ int __init acpi_gtdt_init(struct acpi_table_header *table)
>
> return gtdt->platform_timer_count;
> }
> +
> +static int __init gtdt_parse_gt_block(struct acpi_gtdt_timer_block *block,
> + struct gt_block_data *data)
> +{
> + struct acpi_gtdt_timer_entry *frame;
> + int i;
> +
> + if (!block || !data)
> + return -EINVAL;
As far as I can see, the !block case cannot happen; if it can, we'd
already have derferenced it with the is_timer_block() check in
gtdt_arch_timer_mem_init().
Why do we not handle the !data check in gtdt_arch_timer_mem_init()? It
seems fragile, given we add an index there...
> +
> + if (!block->block_address || !block->timer_count)
> + return -EINVAL;
Looking at Table 5-120 in the ACPI 6.1 spec, zero is not called out as
an invalid physical address for the block...
Surely if you don't have an MMIO timer, you don't have a GT Block
Structure, rather than an invalid one!?
The block->timer_count check should be more thorough, e.g.
if (!block->timer_count) {
pr_warn("GTDT present, but frame count is zero");
return -ENODEV:
}
if (block->timer_count > 8) {
pr_warn(FW_BUG "GTDT lists %d frames, ACPI spec only allows 8\n",
block->timer_count);
}
... note that without the latter we could go off the end of the array...
> + data->cntctlbase_phy = (phys_addr_t)block->block_address;
> + data->timer_count = block->timer_count;
> +
> + frame = (void *)block + block->timer_offset;
> + if (frame + block->timer_count != (void *)block + block->header.length)
> + return -EINVAL;
> +
> + /*
> + * Get the GT timer Frame data for every GT Block Timer
> + */
> + for (i = 0; i < block->timer_count; i++, frame++) {
> + if (!frame->base_address || !frame->timer_interrupt)
> + return -EINVAL;
> +
> + data->timer[i].irq = map_gt_gsi(frame->timer_interrupt,
> + frame->timer_flags);
> + if (data->timer[i].irq <= 0)
> + return -EINVAL;
Can we please print something describing the failure, e.g.
pr_warn("failed to map GTDT frame %d, physical timer interrupt\n",
i);
> +
> + if (frame->virtual_timer_interrupt) {
Same comment as previously about GSIV zero being valid; this is arguably
a spec bug that should be reported...
> + data->timer[i].virtual_irq =
> + map_gt_gsi(frame->virtual_timer_interrupt,
> + frame->virtual_timer_flags);
> + if (data->timer[i].virtual_irq <= 0)
> + return -EINVAL;
Likewise, a message here would be useful, e.g.
pr_warn("failed to map GTDT frame %d, virtual timer interrupt\n",
i);
> + }
> +
> + data->timer[i].frame_nr = frame->frame_number;
> + data->timer[i].cntbase_phy = frame->base_address;
What about CntEL0BaseX?
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * Get the GT block info for memory-mapped timer from GTDT table.
> + */
> +int __init gtdt_arch_timer_mem_init(struct gt_block_data *data)
> +{
> + void *platform_timer;
> + int index = 0;
> + int ret;
> +
> + for_each_platform_timer(platform_timer) {
> + if (!is_timer_block(platform_timer))
> + continue;
> + ret = gtdt_parse_gt_block(platform_timer, data + index);
> + if (ret)
> + return ret;
> + index++;
> + }
> +
> + if (index)
> + pr_info("found %d memory-mapped timer block(s).\n", index);
> +
> + return index;
> +}
> diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
> index 16dcd10..94a5d14 100644
> --- a/include/clocksource/arm_arch_timer.h
> +++ b/include/clocksource/arm_arch_timer.h
> @@ -56,6 +56,8 @@ enum spi_nr {
> #define ARCH_TIMER_MEM_PHYS_ACCESS 2
> #define ARCH_TIMER_MEM_VIRT_ACCESS 3
>
> +#define ARCH_TIMER_MEM_MAX_FRAME 8
Nit: please call this ARCH_TIMER_MEM_MAX_FRAMES, so it's clear that the
maximum index is 7.
> #define ARCH_TIMER_USR_PCT_ACCESS_EN (1 << 0) /* physical counter */
> #define ARCH_TIMER_USR_VCT_ACCESS_EN (1 << 1) /* virtual counter */
> #define ARCH_TIMER_VIRT_EVT_EN (1 << 2)
> @@ -71,6 +73,19 @@ struct arch_timer_kvm_info {
> int virtual_irq;
> };
>
> +struct gt_timer_data {
s/gt_timer_data/arch_timer_mem_frame/
> + int frame_nr;
> + phys_addr_t cntbase_phy;
Please get rid of the '_phy' suffix; it clashes with other terminology,
'phys' is generally preferable, and given the name and type it's obvious
that it's a physical address anyhow.
Just call this 'cntbase'.
> + int irq;
> + int virtual_irq;
Call these phys_irq and virt_irq.
> +};
> +
> +struct gt_block_data {
s/gt_block_data/arch_timer_mem/
> + phys_addr_t cntctlbase_phy;
Same comment w.r.t. the '_phy' suffix. Likewise, just call this
'cntctlbase_phy'
> + int timer_count;
s/timer_count/num_frames/
> + struct gt_timer_data timer[ARCH_TIMER_MEM_MAX_FRAME];
> +};
Please split this part out into a patch which moves the existing driver
over to this new abstraction, *then* introduce the ACPI parser for it in
a subsequent patch.
Thanks,
Mark.
^ permalink raw reply
* [PATCH v2 0/2] ARM: oxnas: Add SMP support for OX820
From: Arnd Bergmann @ 2016-10-21 11:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161021085848.1754-1-narmstrong@baylibre.com>
On Friday, October 21, 2016 10:58:46 AM CEST Neil Armstrong wrote:
> In order to support the SMP feature of the Oxford Semiconductor OX820 SoC,
> add the necessary code to handle the wake-up, hotplug and cpu entry.
>
> The OX820 has an ARM11MPCORE cluster with 2 cores and has proper hardware
> support for secondary core booting.
>
> Changes since v1 at http://lkml.kernel.org/r/20161017084303.20078-1-narmstrong at baylibre.com
> - Remove useless holding pen loops and spinlock in boot_secondary
>
Thanks for the update, much nicer!
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* [PATCH v14 5/9] clocksource/drivers/arm_arch_timer: Simplify ACPI support code.
From: Mark Rutland @ 2016-10-21 11:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161020165747.GD27598@leverpostej>
On Thu, Oct 20, 2016 at 05:58:17PM +0100, Mark Rutland wrote:
> On Thu, Sep 29, 2016 at 02:17:13AM +0800, fu.wei at linaro.org wrote:
> > + arch_timer_ppi[PHYS_NONSECURE_PPI] = acpi_gtdt_map_ppi(PHYS_NONSECURE_PPI);
> > + arch_timer_ppi[VIRT_PPI] = acpi_gtdt_map_ppi(VIRT_PPI);
> > + arch_timer_ppi[HYP_PPI] = acpi_gtdt_map_ppi(HYP_PPI);
> > + /* Always-on capability */
> > + arch_timer_c3stop = acpi_gtdt_c3stop();
>
> ... I think we should check the flag on the relevant interrupt, though
> that's worth clarifying.
I see I misread the spec; this is part of the common flags.
Please ignore this point; sorry for the noise.
Thanks,
Mark.
^ permalink raw reply
* [PATCH v2] dt/bindings: arm-boards: Remove skeleton.dtsi inclusion from example
From: Javier Martinez Canillas @ 2016-10-21 11:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477045693-6820-1-git-send-email-geert+renesas@glider.be>
Hello Geert,
On Fri, Oct 21, 2016 at 7:28 AM, Geert Uytterhoeven
<geert+renesas@glider.be> wrote:
> As of commit 9c0da3cc61f1233c ("ARM: dts: explicitly mark skeleton.dtsi
> as deprecated"), including skeleton.dtsi is deprecated.
> Hence remove it from the example.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> Acked-by: Mark Rutland <mark.rutland@arm.com>
> ---
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Best regards,
Javier
^ permalink raw reply
* [RFC PATCH 8/8] ARM: KVM: Support vGICv3 ITS
From: Andre Przywara @ 2016-10-21 11:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1477042601-15227-9-git-send-email-vladimir.murzin@arm.com>
Hi,
On 21/10/16 10:36, Vladimir Murzin wrote:
> This patch allows to build and use vGICv3 ITS in 32-bit mode.
Ah, what a relief to see that config option go. Thanks for that!
I quickly booted an ITS guest on a (64-bit) model and couldn't spot any
regressions.
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre.
> ---
> Documentation/virtual/kvm/api.txt | 2 +-
> arch/arm/include/uapi/asm/kvm.h | 2 ++
> arch/arm/kvm/Kconfig | 1 +
> arch/arm/kvm/Makefile | 1 +
> arch/arm/kvm/arm.c | 6 ++++++
> arch/arm64/kvm/Kconfig | 4 ----
> arch/arm64/kvm/reset.c | 6 ------
> virt/kvm/arm/vgic/vgic-kvm-device.c | 2 --
> virt/kvm/arm/vgic/vgic-mmio-v3.c | 2 --
> virt/kvm/arm/vgic/vgic.h | 26 --------------------------
> 10 files changed, 11 insertions(+), 41 deletions(-)
>
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index 739db9a..2feeae6 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -2198,7 +2198,7 @@ after pausing the vcpu, but before it is resumed.
> 4.71 KVM_SIGNAL_MSI
>
> Capability: KVM_CAP_SIGNAL_MSI
> -Architectures: x86 arm64
> +Architectures: x86 arm arm64
> Type: vm ioctl
> Parameters: struct kvm_msi (in)
> Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error
> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
> index b38c10c..af05f8e 100644
> --- a/arch/arm/include/uapi/asm/kvm.h
> +++ b/arch/arm/include/uapi/asm/kvm.h
> @@ -87,9 +87,11 @@ struct kvm_regs {
> /* Supported VGICv3 address types */
> #define KVM_VGIC_V3_ADDR_TYPE_DIST 2
> #define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
> +#define KVM_VGIC_ITS_ADDR_TYPE 4
>
> #define KVM_VGIC_V3_DIST_SIZE SZ_64K
> #define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
> +#define KVM_VGIC_V3_ITS_SIZE (2 * SZ_64K)
>
> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
> #define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
> diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
> index 3e1cd04..90d0176 100644
> --- a/arch/arm/kvm/Kconfig
> +++ b/arch/arm/kvm/Kconfig
> @@ -34,6 +34,7 @@ config KVM
> select HAVE_KVM_IRQFD
> select HAVE_KVM_IRQCHIP
> select HAVE_KVM_IRQ_ROUTING
> + select HAVE_KVM_MSI
> depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
> ---help---
> Support hosting virtualized guest machines.
> diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
> index f19842e..d571243 100644
> --- a/arch/arm/kvm/Makefile
> +++ b/arch/arm/kvm/Makefile
> @@ -32,5 +32,6 @@ obj-y += $(KVM)/arm/vgic/vgic-mmio.o
> obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
> obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
> obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
> +obj-y += $(KVM)/arm/vgic/vgic-its.o
> obj-y += $(KVM)/irqchip.o
> obj-y += $(KVM)/arm/arch_timer.o
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 03e9273..8b13448 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -209,6 +209,12 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> case KVM_CAP_MAX_VCPUS:
> r = KVM_MAX_VCPUS;
> break;
> + case KVM_CAP_MSI_DEVID:
> + if (!kvm)
> + r = -EINVAL;
> + else
> + r = kvm->arch.vgic.msis_require_devid;
> + break;
> default:
> r = kvm_arch_dev_ioctl_check_extension(kvm, ext);
> break;
> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> index 6eaf12c..52cb7ad 100644
> --- a/arch/arm64/kvm/Kconfig
> +++ b/arch/arm64/kvm/Kconfig
> @@ -16,9 +16,6 @@ menuconfig VIRTUALIZATION
>
> if VIRTUALIZATION
>
> -config KVM_ARM_VGIC_V3_ITS
> - bool
> -
> config KVM
> bool "Kernel-based Virtual Machine (KVM) support"
> depends on OF
> @@ -34,7 +31,6 @@ config KVM
> select KVM_VFIO
> select HAVE_KVM_EVENTFD
> select HAVE_KVM_IRQFD
> - select KVM_ARM_VGIC_V3_ITS
> select KVM_ARM_PMU if HW_PERF_EVENTS
> select HAVE_KVM_MSI
> select HAVE_KVM_IRQCHIP
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index 5bc4608..e95d4f6 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -86,12 +86,6 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
> case KVM_CAP_VCPU_ATTRIBUTES:
> r = 1;
> break;
> - case KVM_CAP_MSI_DEVID:
> - if (!kvm)
> - r = -EINVAL;
> - else
> - r = kvm->arch.vgic.msis_require_devid;
> - break;
> default:
> r = 0;
> }
> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
> index ce1f4ed..fbe87a6 100644
> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
> @@ -221,11 +221,9 @@ int kvm_register_vgic_device(unsigned long type)
> ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
> KVM_DEV_TYPE_ARM_VGIC_V3);
>
> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
> if (ret)
> break;
> ret = kvm_vgic_register_its_device();
> -#endif
> break;
> }
>
> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> index 0d3c76a..50f42f0 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> @@ -42,7 +42,6 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
> return reg | ((u64)val << lower);
> }
>
> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
> bool vgic_has_its(struct kvm *kvm)
> {
> struct vgic_dist *dist = &kvm->arch.vgic;
> @@ -52,7 +51,6 @@ bool vgic_has_its(struct kvm *kvm)
>
> return dist->has_its;
> }
> -#endif
>
> static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
> gpa_t addr, unsigned int len)
> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
> index 9d9e014..859f65c 100644
> --- a/virt/kvm/arm/vgic/vgic.h
> +++ b/virt/kvm/arm/vgic/vgic.h
> @@ -84,37 +84,11 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
> int vgic_v3_map_resources(struct kvm *kvm);
> int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
>
> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
> int vgic_register_its_iodevs(struct kvm *kvm);
> bool vgic_has_its(struct kvm *kvm);
> int kvm_vgic_register_its_device(void);
> void vgic_enable_lpis(struct kvm_vcpu *vcpu);
> int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
> -#else
> -static inline int vgic_register_its_iodevs(struct kvm *kvm)
> -{
> - return -ENODEV;
> -}
> -
> -static inline bool vgic_has_its(struct kvm *kvm)
> -{
> - return false;
> -}
> -
> -static inline int kvm_vgic_register_its_device(void)
> -{
> - return -ENODEV;
> -}
> -
> -static inline void vgic_enable_lpis(struct kvm_vcpu *vcpu)
> -{
> -}
> -
> -static inline int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
> -{
> - return -ENODEV;
> -}
> -#endif
>
> int kvm_register_vgic_device(unsigned long type);
> int vgic_lazy_init(struct kvm *kvm);
>
^ permalink raw reply
* [PATCH v3 5/6] ARM: sunxi: Remove useless allwinner, pull property
From: Maxime Ripard @ 2016-10-21 10:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161020173848.be9cf97854f8933b3ce90d55@free.fr>
Hi,
On Thu, Oct 20, 2016 at 05:38:48PM +0200, Jean-Francois Moine wrote:
> On Thu, 20 Oct 2016 15:49:06 +0200
> Maxime Ripard <maxime.ripard@free-electrons.com> wrote:
>
> > The allwinner,pull property set to NO_PULL was really considered our
> > default (and wasn't even changing the default value in the code).
> >
> > Remove these properties to make it obvious that we do not set anything in
> > such a case.
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > Acked-by: Chen-Yu Tsai <wens@csie.org>
> > Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> > ---
> > arch/arm/boot/dts/ntc-gr8-evb.dts | 4 +-
> > arch/arm/boot/dts/ntc-gr8.dtsi | 14 +-----
> > arch/arm/boot/dts/sun4i-a10-a1000.dts | 2 +-
> > arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 1 +-
> > arch/arm/boot/dts/sun4i-a10-dserve-dsrv9703c.dts | 4 +-
> > arch/arm/boot/dts/sun4i-a10-gemei-g9.dts | 1 +-
> > arch/arm/boot/dts/sun4i-a10-hackberry.dts | 2 +-
> > arch/arm/boot/dts/sun4i-a10-inet1.dts | 2 +-
> > arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts | 2 +-
> > arch/arm/boot/dts/sun4i-a10-marsboard.dts | 1 +-
> > arch/arm/boot/dts/sun4i-a10-mk802.dts | 3 +-
> > arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts | 2 +-
> > arch/arm/boot/dts/sun4i-a10-pcduino.dts | 2 +-
> > arch/arm/boot/dts/sun4i-a10-pcduino2.dts | 1 +-
> > arch/arm/boot/dts/sun4i-a10-pov-protab2-ips9.dts | 3 +-
> > arch/arm/boot/dts/sun4i-a10.dtsi | 24 +--------
> > arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts | 1 +-
> > arch/arm/boot/dts/sun5i-a10s-auxtek-t004.dts | 2 +-
> > arch/arm/boot/dts/sun5i-a10s-mk802.dts | 2 +-
> > arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 2 +-
> > arch/arm/boot/dts/sun5i-a10s-r7-tv-dongle.dts | 2 +-
> > arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts | 2 +-
> > arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +--
> > arch/arm/boot/dts/sun5i-a13-hsg-h702.dts | 1 +-
> > arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts | 3 +-
> > arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 2 +-
> > arch/arm/boot/dts/sun5i-a13-utoo-p66.dts | 1 +-
> > arch/arm/boot/dts/sun5i-a13.dtsi | 3 +-
> > arch/arm/boot/dts/sun5i-r8-chip.dts | 2 +-
> > arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi | 2 +-
> > arch/arm/boot/dts/sun5i.dtsi | 7 +--
> > arch/arm/boot/dts/sun6i-a31-app4-evb1.dts | 1 +-
> > arch/arm/boot/dts/sun6i-a31-colombus.dts | 1 +-
> > arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 2 +-
> > arch/arm/boot/dts/sun6i-a31-i7.dts | 2 +-
> > arch/arm/boot/dts/sun6i-a31-m9.dts | 2 +-
> > arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts | 2 +-
> > arch/arm/boot/dts/sun6i-a31.dtsi | 13 +----
> > arch/arm/boot/dts/sun6i-a31s-primo81.dts | 1 +-
> > arch/arm/boot/dts/sun6i-a31s-sina31s.dts | 1 +-
> > arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts | 3 +-
> > arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts | 3 +-
> > arch/arm/boot/dts/sun7i-a20-bananapi.dts | 2 +-
> > arch/arm/boot/dts/sun7i-a20-bananapro.dts | 5 +--
> > arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 1 +-
> > arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 6 +--
> > arch/arm/boot/dts/sun7i-a20-hummingbird.dts | 4 +-
> > arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts | 4 +-
> > arch/arm/boot/dts/sun7i-a20-itead-ibox.dts | 1 +-
> > arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts | 2 +-
> > arch/arm/boot/dts/sun7i-a20-m3.dts | 1 +-
> > arch/arm/boot/dts/sun7i-a20-mk808c.dts | 2 +-
> > arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts | 4 +-
> > arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts | 2 +-
> > arch/arm/boot/dts/sun7i-a20-olinuxino-lime2-emmc.dts | 1 +-
> > arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts | 3 +-
> > arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 1 +-
> > arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts | 4 +-
> > arch/arm/boot/dts/sun7i-a20-orangepi.dts | 4 +-
> > arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts | 3 +-
> > arch/arm/boot/dts/sun7i-a20-pcduino3.dts | 2 +-
> > arch/arm/boot/dts/sun7i-a20-wexler-tab7200.dts | 3 +-
> > arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts | 1 +-
> > arch/arm/boot/dts/sun7i-a20.dtsi | 37 +------------
> > arch/arm/boot/dts/sun8i-a23-a33.dtsi | 10 +---
> > arch/arm/boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts | 1 +-
> > arch/arm/boot/dts/sun8i-a23-polaroid-mid2809pxe04.dts | 1 +-
> > arch/arm/boot/dts/sun8i-a33-inet-d978-rev2.dts | 1 +-
> > arch/arm/boot/dts/sun8i-a33-olinuxino.dts | 3 +-
> > arch/arm/boot/dts/sun8i-a33.dtsi | 1 +-
> > arch/arm/boot/dts/sun8i-a83t.dtsi | 3 +-
> > arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts | 3 +-
> > arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts | 2 +-
> > arch/arm/boot/dts/sun8i-h3-orangepi-2.dts | 4 +-
> > arch/arm/boot/dts/sun8i-h3-orangepi-lite.dts | 3 +-
> > arch/arm/boot/dts/sun8i-h3-orangepi-one.dts | 3 +-
> > arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts | 3 +-
> > arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts | 1 +-
> > arch/arm/boot/dts/sun8i-h3.dtsi | 12 +----
> > arch/arm/boot/dts/sun8i-r16-parrot.dts | 3 +-
> > arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi | 2 +-
> > arch/arm/boot/dts/sun9i-a80-cubieboard4.dts | 1 +-
> > arch/arm/boot/dts/sun9i-a80-optimus.dts | 4 +-
> > arch/arm/boot/dts/sun9i-a80.dtsi | 6 +--
> > arch/arm/boot/dts/sunxi-common-regulators.dtsi | 4 +-
> > 85 files changed, 0 insertions(+), 302 deletions(-)
> [snip]
>
> Is it really usefull to change all these files while in a previous
> patch you were writing:
> > The generic pin configuration and multiplexing should be preferred now,
> > even though we still support the old one.
> ?
I assume you wanted to comment on the sixth patch.
Yes, it's useful, because that way we avoid using a deprecated
binding, that we would have to mix the newer binding which would be
completely inconsistent, and that way we use the generic binding that
everyone uses everywhere.
The backward compatibility is just here to avoid breaking the ABI.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161021/b625a715/attachment.sig>
^ permalink raw reply
* [PATCH v2 9/9] ARM: omap2plus_defconfig: Enable LP873X support
From: Lokesh Vutla @ 2016-10-21 10:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161021103841.8044-1-lokeshvutla@ti.com>
LP873X family of PMICs are used in dra71x-evm, So enable the same.
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
arch/arm/configs/omap2plus_defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 5695cff..e3fdf4d 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -267,11 +267,13 @@ CONFIG_TWL4030_WATCHDOG=m
CONFIG_MFD_TI_AM335X_TSCADC=m
CONFIG_MFD_PALMAS=y
CONFIG_MFD_TPS65217=y
+CONFIG_MFD_TI_LP873X=y
CONFIG_MFD_TPS65218=y
CONFIG_MFD_TPS65910=y
CONFIG_TWL6040_CORE=y
CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_LP872X=y
+CONFIG_REGULATOR_LP873X=y
CONFIG_REGULATOR_PALMAS=y
CONFIG_REGULATOR_PBIAS=y
CONFIG_REGULATOR_TI_ABB=y
--
2.10.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox