* Applied "regulator: of: add property for allowed modes specification" to the regulator tree
From: Mark Brown @ 2018-05-17 16:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <f3aa166ddd11c8f9813602be68aa5b10e5c90979.1526088289.git.collinsd@codeaurora.org>
The patch
regulator: of: add property for allowed modes specification
has been applied to the regulator tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From d73e2842a3e236a1f58ba498e4d6ae58e18f660a Mon Sep 17 00:00:00 2001
From: David Collins <collinsd@codeaurora.org>
Date: Fri, 11 May 2018 18:46:46 -0700
Subject: [PATCH] regulator: of: add property for allowed modes specification
Add a common device tree property for regulator nodes to support
the specification of allowed operating modes.
Signed-off-by: David Collins <collinsd@codeaurora.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
Documentation/devicetree/bindings/regulator/regulator.txt | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
index 2babe15b618d..c627aa08f0da 100644
--- a/Documentation/devicetree/bindings/regulator/regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -59,6 +59,11 @@ Optional properties:
- regulator-initial-mode: initial operating mode. The set of possible operating
modes depends on the capabilities of every hardware so each device binding
documentation explains which values the regulator supports.
+- regulator-allowed-modes: list of operating modes that software is allowed to
+ configure for the regulator at run-time. Elements may be specified in any
+ order. The set of possible operating modes depends on the capabilities of
+ every hardware so each device binding document explains which values the
+ regulator supports.
- regulator-system-load: Load in uA present on regulator that is not captured by
any consumer request.
- regulator-pull-down: Enable pull down resistor when the regulator is disabled.
--
2.17.0
^ permalink raw reply related
* Applied "regulator: of: add support for allowed modes configuration" to the regulator tree
From: Mark Brown @ 2018-05-17 16:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <58bb4f965515a67a6cbbc726b0d7b092c22b79d7.1526088289.git.collinsd@codeaurora.org>
The patch
regulator: of: add support for allowed modes configuration
has been applied to the regulator tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 54557ad9737e28b06b632cce723ef2373fe6bf12 Mon Sep 17 00:00:00 2001
From: David Collins <collinsd@codeaurora.org>
Date: Fri, 11 May 2018 18:46:47 -0700
Subject: [PATCH] regulator: of: add support for allowed modes configuration
Add support for configuring the machine constraints
valid_modes_mask element based on a list of allowed modes
specified via a device tree property.
Signed-off-by: David Collins <collinsd@codeaurora.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
drivers/regulator/of_regulator.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 0d3f73eacb99..d61fed28fdb9 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -32,7 +32,7 @@ static void of_get_regulation_constraints(struct device_node *np,
struct regulator_state *suspend_state;
struct device_node *suspend_np;
unsigned int mode;
- int ret, i;
+ int ret, i, len;
u32 pval;
constraints->name = of_get_property(np, "regulator-name", NULL);
@@ -136,6 +136,33 @@ static void of_get_regulation_constraints(struct device_node *np,
}
}
+ len = of_property_count_elems_of_size(np, "regulator-allowed-modes",
+ sizeof(u32));
+ if (len > 0) {
+ if (desc && desc->of_map_mode) {
+ for (i = 0; i < len; i++) {
+ ret = of_property_read_u32_index(np,
+ "regulator-allowed-modes", i, &pval);
+ if (ret) {
+ pr_err("%s: couldn't read allowed modes index %d, ret=%d\n",
+ np->name, i, ret);
+ break;
+ }
+ mode = desc->of_map_mode(pval);
+ if (mode == REGULATOR_MODE_INVALID)
+ pr_err("%s: invalid regulator-allowed-modes element %u\n",
+ np->name, pval);
+ else
+ constraints->valid_modes_mask |= mode;
+ }
+ if (constraints->valid_modes_mask)
+ constraints->valid_ops_mask
+ |= REGULATOR_CHANGE_MODE;
+ } else {
+ pr_warn("%s: mode mapping not defined\n", np->name);
+ }
+ }
+
if (!of_property_read_u32(np, "regulator-system-load", &pval))
constraints->system_load = pval;
--
2.17.0
^ permalink raw reply related
* Applied "ASoC: zte: remove duplicate includes" to the asoc tree
From: Mark Brown @ 2018-05-17 16:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1512930723-5037-1-git-send-email-pravin.shedge4linux@gmail.com>
The patch
ASoC: zte: remove duplicate includes
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 3439a083a13981f0da276cb2aeae84bd4e437b2e Mon Sep 17 00:00:00 2001
From: Pravin Shedge <pravin.shedge4linux@gmail.com>
Date: Mon, 11 Dec 2017 00:02:03 +0530
Subject: [PATCH] ASoC: zte: remove duplicate includes
These duplicate includes have been found with scripts/checkincludes.pl but
they have been removed manually to avoid removing false positives.
Signed-off-by: Pravin Shedge <pravin.shedge4linux@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/zte/zx-i2s.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/sound/soc/zte/zx-i2s.c b/sound/soc/zte/zx-i2s.c
index b6b056c607fa..0d36630aa1a7 100644
--- a/sound/soc/zte/zx-i2s.c
+++ b/sound/soc/zte/zx-i2s.c
@@ -20,9 +20,6 @@
#include <sound/core.h>
#include <sound/dmaengine_pcm.h>
#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
#define ZX_I2S_PROCESS_CTRL 0x04
#define ZX_I2S_TIMING_CTRL 0x08
--
2.17.0
^ permalink raw reply related
* Applied "ASoC: qdsp6: q6core: Add q6core driver" to the asoc tree
From: Mark Brown @ 2018-05-17 16:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180509125635.5653-9-srinivas.kandagatla@linaro.org>
The patch
ASoC: qdsp6: q6core: Add q6core driver
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From b73e93e183089176beed8a3f80e5f618a52e02fc Mon Sep 17 00:00:00 2001
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Date: Wed, 9 May 2018 13:56:19 +0100
Subject: [PATCH] ASoC: qdsp6: q6core: Add q6core driver
This patch adds support to core apr service, which is used to query
status of other static and dynamic services on the dsp.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Reviewed-and-tested-by: Rohit kumar <rohitkr@codeaurora.org>
Acked-by: Banajit Goswami <bgoswami@codeaurora.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/qcom/Kconfig | 4 +
sound/soc/qcom/qdsp6/Makefile | 1 +
sound/soc/qcom/qdsp6/q6core.c | 380 ++++++++++++++++++++++++++++++++++
sound/soc/qcom/qdsp6/q6core.h | 15 ++
4 files changed, 400 insertions(+)
create mode 100644 sound/soc/qcom/qdsp6/q6core.c
create mode 100644 sound/soc/qcom/qdsp6/q6core.h
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index b44a9fcd7ed3..37ee0d958145 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -44,10 +44,14 @@ config SND_SOC_APQ8016_SBC
config SND_SOC_QDSP6_COMMON
tristate
+config SND_SOC_QDSP6_CORE
+ tristate
+
config SND_SOC_QDSP6
tristate "SoC ALSA audio driver for QDSP6"
depends on QCOM_APR && HAS_DMA
select SND_SOC_QDSP6_COMMON
+ select SND_SOC_QDSP6_CORE
help
To add support for MSM QDSP6 Soc Audio.
This will enable sound soc platform specific
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
index accebdb49306..03b8e89c9731 100644
--- a/sound/soc/qcom/qdsp6/Makefile
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o
+obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o
diff --git a/sound/soc/qcom/qdsp6/q6core.c b/sound/soc/qcom/qdsp6/q6core.c
new file mode 100644
index 000000000000..06f03a5fe9bd
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6core.c
@@ -0,0 +1,380 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+// Copyright (c) 2018, Linaro Limited
+
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/jiffies.h>
+#include <linux/wait.h>
+#include <linux/soc/qcom/apr.h>
+#include "q6core.h"
+#include "q6dsp-errno.h"
+
+#define ADSP_STATE_READY_TIMEOUT_MS 3000
+#define Q6_READY_TIMEOUT_MS 100
+#define AVCS_CMD_ADSP_EVENT_GET_STATE 0x0001290C
+#define AVCS_CMDRSP_ADSP_EVENT_GET_STATE 0x0001290D
+#define AVCS_GET_VERSIONS 0x00012905
+#define AVCS_GET_VERSIONS_RSP 0x00012906
+#define AVCS_CMD_GET_FWK_VERSION 0x001292c
+#define AVCS_CMDRSP_GET_FWK_VERSION 0x001292d
+
+struct avcs_svc_info {
+ uint32_t service_id;
+ uint32_t version;
+} __packed;
+
+struct avcs_cmdrsp_get_version {
+ uint32_t build_id;
+ uint32_t num_services;
+ struct avcs_svc_info svc_api_info[];
+} __packed;
+
+/* for ADSP2.8 and above */
+struct avcs_svc_api_info {
+ uint32_t service_id;
+ uint32_t api_version;
+ uint32_t api_branch_version;
+} __packed;
+
+struct avcs_cmdrsp_get_fwk_version {
+ uint32_t build_major_version;
+ uint32_t build_minor_version;
+ uint32_t build_branch_version;
+ uint32_t build_subbranch_version;
+ uint32_t num_services;
+ struct avcs_svc_api_info svc_api_info[];
+} __packed;
+
+struct q6core {
+ struct apr_device *adev;
+ wait_queue_head_t wait;
+ uint32_t avcs_state;
+ struct mutex lock;
+ bool resp_received;
+ uint32_t num_services;
+ struct avcs_cmdrsp_get_fwk_version *fwk_version;
+ struct avcs_cmdrsp_get_version *svc_version;
+ bool fwk_version_supported;
+ bool get_state_supported;
+ bool get_version_supported;
+ bool is_version_requested;
+};
+
+static struct q6core *g_core;
+
+static int q6core_callback(struct apr_device *adev, struct apr_resp_pkt *data)
+{
+ struct q6core *core = dev_get_drvdata(&adev->dev);
+ struct aprv2_ibasic_rsp_result_t *result;
+ struct apr_hdr *hdr = &data->hdr;
+
+ result = data->payload;
+ switch (hdr->opcode) {
+ case APR_BASIC_RSP_RESULT:{
+ result = data->payload;
+ switch (result->opcode) {
+ case AVCS_GET_VERSIONS:
+ if (result->status == ADSP_EUNSUPPORTED)
+ core->get_version_supported = false;
+ core->resp_received = true;
+ break;
+ case AVCS_CMD_GET_FWK_VERSION:
+ if (result->status == ADSP_EUNSUPPORTED)
+ core->fwk_version_supported = false;
+ core->resp_received = true;
+ break;
+ case AVCS_CMD_ADSP_EVENT_GET_STATE:
+ if (result->status == ADSP_EUNSUPPORTED)
+ core->get_state_supported = false;
+ core->resp_received = true;
+ break;
+ }
+ break;
+ }
+ case AVCS_CMDRSP_GET_FWK_VERSION: {
+ struct avcs_cmdrsp_get_fwk_version *fwk;
+ int bytes;
+
+ fwk = data->payload;
+ bytes = sizeof(*fwk) + fwk->num_services *
+ sizeof(fwk->svc_api_info[0]);
+
+ core->fwk_version = kzalloc(bytes, GFP_ATOMIC);
+ if (!core->fwk_version)
+ return -ENOMEM;
+
+ memcpy(core->fwk_version, data->payload, bytes);
+
+ core->fwk_version_supported = true;
+ core->resp_received = true;
+
+ break;
+ }
+ case AVCS_GET_VERSIONS_RSP: {
+ struct avcs_cmdrsp_get_version *v;
+ int len;
+
+ v = data->payload;
+
+ len = sizeof(*v) + v->num_services * sizeof(v->svc_api_info[0]);
+
+ core->svc_version = kzalloc(len, GFP_ATOMIC);
+ if (!core->svc_version)
+ return -ENOMEM;
+
+ memcpy(core->svc_version, data->payload, len);
+
+ core->get_version_supported = true;
+ core->resp_received = true;
+
+ break;
+ }
+ case AVCS_CMDRSP_ADSP_EVENT_GET_STATE:
+ core->get_state_supported = true;
+ core->avcs_state = result->opcode;
+
+ core->resp_received = true;
+ break;
+ default:
+ dev_err(&adev->dev, "Message id from adsp core svc: 0x%x\n",
+ hdr->opcode);
+ break;
+ }
+
+ if (core->resp_received)
+ wake_up(&core->wait);
+
+ return 0;
+}
+
+static int q6core_get_fwk_versions(struct q6core *core)
+{
+ struct apr_device *adev = core->adev;
+ struct apr_pkt pkt;
+ int rc;
+
+ pkt.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ pkt.hdr.pkt_size = APR_HDR_SIZE;
+ pkt.hdr.opcode = AVCS_CMD_GET_FWK_VERSION;
+
+ rc = apr_send_pkt(adev, &pkt);
+ if (rc < 0)
+ return rc;
+
+ rc = wait_event_timeout(core->wait, (core->resp_received),
+ msecs_to_jiffies(Q6_READY_TIMEOUT_MS));
+ if (rc > 0 && core->resp_received) {
+ core->resp_received = false;
+
+ if (!core->fwk_version_supported)
+ return -ENOTSUPP;
+ else
+ return 0;
+ }
+
+
+ return rc;
+}
+
+static int q6core_get_svc_versions(struct q6core *core)
+{
+ struct apr_device *adev = core->adev;
+ struct apr_pkt pkt;
+ int rc;
+
+ pkt.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ pkt.hdr.pkt_size = APR_HDR_SIZE;
+ pkt.hdr.opcode = AVCS_GET_VERSIONS;
+
+ rc = apr_send_pkt(adev, &pkt);
+ if (rc < 0)
+ return rc;
+
+ rc = wait_event_timeout(core->wait, (core->resp_received),
+ msecs_to_jiffies(Q6_READY_TIMEOUT_MS));
+ if (rc > 0 && core->resp_received) {
+ core->resp_received = false;
+ return 0;
+ }
+
+ return rc;
+}
+
+static bool __q6core_is_adsp_ready(struct q6core *core)
+{
+ struct apr_device *adev = core->adev;
+ struct apr_pkt pkt;
+ int rc;
+
+ core->get_state_supported = false;
+
+ pkt.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ pkt.hdr.pkt_size = APR_HDR_SIZE;
+ pkt.hdr.opcode = AVCS_CMD_ADSP_EVENT_GET_STATE;
+
+ rc = apr_send_pkt(adev, &pkt);
+ if (rc < 0)
+ return false;
+
+ rc = wait_event_timeout(core->wait, (core->resp_received),
+ msecs_to_jiffies(Q6_READY_TIMEOUT_MS));
+ if (rc > 0 && core->resp_received) {
+ core->resp_received = false;
+
+ if (core->avcs_state)
+ return true;
+ }
+
+ /* assume that the adsp is up if we not support this command */
+ if (!core->get_state_supported)
+ return true;
+
+ return false;
+}
+
+/**
+ * q6core_get_svc_api_info() - Get version number of a service.
+ *
+ * @svc_id: service id of the service.
+ * @ainfo: Valid struct pointer to fill svc api information.
+ *
+ * Return: zero on success and error code on failure or unsupported
+ */
+int q6core_get_svc_api_info(int svc_id, struct q6core_svc_api_info *ainfo)
+{
+ int i;
+ int ret = -ENOTSUPP;
+
+ if (!g_core || !ainfo)
+ return 0;
+
+ mutex_lock(&g_core->lock);
+ if (!g_core->is_version_requested) {
+ if (q6core_get_fwk_versions(g_core) == -ENOTSUPP)
+ q6core_get_svc_versions(g_core);
+ g_core->is_version_requested = true;
+ }
+
+ if (g_core->fwk_version_supported) {
+ for (i = 0; i < g_core->fwk_version->num_services; i++) {
+ struct avcs_svc_api_info *info;
+
+ info = &g_core->fwk_version->svc_api_info[i];
+ if (svc_id != info->service_id)
+ continue;
+
+ ainfo->api_version = info->api_version;
+ ainfo->api_branch_version = info->api_branch_version;
+ ret = 0;
+ break;
+ }
+ } else if (g_core->get_version_supported) {
+ for (i = 0; i < g_core->svc_version->num_services; i++) {
+ struct avcs_svc_info *info;
+
+ info = &g_core->svc_version->svc_api_info[i];
+ if (svc_id != info->service_id)
+ continue;
+
+ ainfo->api_version = info->version;
+ ainfo->api_branch_version = 0;
+ ret = 0;
+ break;
+ }
+ }
+
+ mutex_unlock(&g_core->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(q6core_get_svc_api_info);
+
+/**
+ * q6core_is_adsp_ready() - Get status of adsp
+ *
+ * Return: Will be an true if adsp is ready and false if not.
+ */
+bool q6core_is_adsp_ready(void)
+{
+ unsigned long timeout;
+ bool ret = false;
+
+ if (!g_core)
+ return false;
+
+ mutex_lock(&g_core->lock);
+ timeout = jiffies + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
+ for (;;) {
+ if (__q6core_is_adsp_ready(g_core)) {
+ ret = true;
+ break;
+ }
+
+ if (!time_after(timeout, jiffies)) {
+ ret = false;
+ break;
+ }
+ }
+
+ mutex_unlock(&g_core->lock);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(q6core_is_adsp_ready);
+
+static int q6core_probe(struct apr_device *adev)
+{
+ g_core = kzalloc(sizeof(*g_core), GFP_KERNEL);
+ if (!g_core)
+ return -ENOMEM;
+
+ dev_set_drvdata(&adev->dev, g_core);
+
+ mutex_init(&g_core->lock);
+ g_core->adev = adev;
+ init_waitqueue_head(&g_core->wait);
+ return 0;
+}
+
+static int q6core_exit(struct apr_device *adev)
+{
+ struct q6core *core = dev_get_drvdata(&adev->dev);
+
+ if (core->fwk_version_supported)
+ kfree(core->fwk_version);
+ if (core->get_version_supported)
+ kfree(core->svc_version);
+
+ g_core = NULL;
+ kfree(core);
+
+ return 0;
+}
+
+static const struct of_device_id q6core_device_id[] = {
+ { .compatible = "qcom,q6core" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, q6core_device_id);
+
+static struct apr_driver qcom_q6core_driver = {
+ .probe = q6core_probe,
+ .remove = q6core_exit,
+ .callback = q6core_callback,
+ .driver = {
+ .name = "qcom-q6core",
+ .of_match_table = of_match_ptr(q6core_device_id),
+ },
+};
+
+module_apr_driver(qcom_q6core_driver);
+MODULE_DESCRIPTION("q6 core");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6core.h b/sound/soc/qcom/qdsp6/q6core.h
new file mode 100644
index 000000000000..4105b1d730be
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6core.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __Q6CORE_H__
+#define __Q6CORE_H__
+
+struct q6core_svc_api_info {
+ uint32_t service_id;
+ uint32_t api_version;
+ uint32_t api_branch_version;
+};
+
+bool q6core_is_adsp_ready(void);
+int q6core_get_svc_api_info(int svc_id, struct q6core_svc_api_info *ainfo);
+
+#endif /* __Q6CORE_H__ */
--
2.17.0
^ permalink raw reply related
* [PATCH] arm: bcm2835: Add the PMU to the devicetree.
From: Vince Weaver @ 2018-05-17 16:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1412187220.62585.1526572780332@email.1und1.de>
On Thu, 17 May 2018, Stefan Wahren wrote:
>
> > Eric Anholt <eric@anholt.net> hat am 17. Mai 2018 um 15:17 geschrieben:
> >
> >
> > The a53 and a7 counters seem to match up, so we advertise a7 so that
> > arm32 can probe.
so how closely did you look at the a53/a7 differences? I see some major
differences, especially with the CPU_CYCLES event (0xff vs 0x11).
The proper fix here might be to add a cortex-a53 PMU entry to the armv7
code rather than trying to treat it as a cortex-a7.
Vince
^ permalink raw reply
* [PATCH v7 03/14] clk: qcom: Add CPU clock driver for msm8996
From: kbuild test robot @ 2018-05-17 16:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526375616-16904-4-git-send-email-ilialin@codeaurora.org>
Hi Ilia,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on robh/for-next]
[also build test WARNING on v4.17-rc5]
[cannot apply to clk/clk-next next-20180517]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Ilia-Lin/CPU-scaling-support-for-msm8996/20180516-064721
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=xtensa
All warnings (new ones prefixed by >>):
>> drivers/clk/qcom/clk-cpu-8996.c:142:2: warning: this decimal constant is unsigned only in ISO C90
VCO(0, 1000000000, 2150400000),
^~~
vim +142 drivers/clk/qcom/clk-cpu-8996.c
137
138 static const struct pll_vco alt_pll_vco_modes[] = {
139 VCO(3, 250000000, 500000000),
140 VCO(2, 500000000, 750000000),
141 VCO(1, 750000000, 1000000000),
> 142 VCO(0, 1000000000, 2150400000),
143 };
144
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 52971 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180518/8304b1ad/attachment-0001.gz>
^ permalink raw reply
* [PATCH v3] arm64: signal: Report signal frame size to userspace via auxv
From: Russell King - ARM Linux @ 2018-05-17 16:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526571941-9816-1-git-send-email-Dave.Martin@arm.com>
On Thu, May 17, 2018 at 04:45:41PM +0100, Dave Martin wrote:
> 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.
I'm really not sure I follow your logic here.
POSIX requirements are here:
http://pubs.opengroup.org/onlinepubs/000095399/functions/sigaltstack.html
and the requirement there is that the MINSIGSTKSZ constant is defined
in signal.h to indicate to user programs the minimum signal stack size
that the system requires.
I don't see how passing the minimum signal stack size via AT_MINSIGSTKSZ
helps in any way, since you propose to make programs use a sysconf()
call to get that, and that is not covered by POSIX. So you're asking
programs to do something special for ARM64.
Simply increasing MINSIGSTKSZ doesn't cause an ABI break - new programs
built against an increased MINSIGSTKSZ results in more stack being
allocated, which doesn't break the ABI in any way. The problem comes
when old programs built with the old MINSIGSTKSZ are run against a
kernel requiring a larger MINSIGSTKSZ. It's almost the reverse problem
- the kernel needs to know the MINSIGSTKSZ value that the problem was
built with, but we don't have that facility either.
> 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.
Presumably you only include the SVE state if the application makes use
of SVE? Otherwise, you'd be saving and restoring a lot of state for
features that are not being used.
I suppose part of the issue is that SVE is supported but MINSIGSTKSZ
is incorrect if this state has to be saved and restored, so there's
apps out there using SVE with the too-small MINSIGSTKSZ value?
--
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 v6 6/9] dt-bindings: counter: Document stm32 quadrature encoder
From: Rob Herring @ 2018-05-17 16:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <ccdbbfb2833d274b6bfa234aada57e68d9793dd5.1526487615.git.vilhelm.gray@gmail.com>
On Wed, May 16, 2018 at 12:51 PM, William Breathitt Gray
<vilhelm.gray@gmail.com> wrote:
> From: Benjamin Gaignard <benjamin.gaignard@st.com>
v6? Where's v1-v5?
> Add bindings for STM32 Timer quadrature encoder.
> It is a sub-node of STM32 Timer which implement the
> counter part of the hardware.
>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
> Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
> ---
> .../bindings/counter/stm32-timer-cnt.txt | 26 +++++++++++++++++++
> .../devicetree/bindings/mfd/stm32-timers.txt | 7 +++++
> 2 files changed, 33 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
>
> diff --git a/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
> new file mode 100644
> index 000000000000..377728128bef
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/counter/stm32-timer-cnt.txt
> @@ -0,0 +1,26 @@
> +STMicroelectronics STM32 Timer quadrature encoder
> +
> +STM32 Timer provides quadrature encoder counter mode to detect
'mode' does not sound like a sub-block of the timers block.
> +angular position and direction of rotary elements,
> +from IN1 and IN2 input signals.
> +
> +Must be a sub-node of an STM32 Timer device tree node.
> +See ../mfd/stm32-timers.txt for details about the parent node.
> +
> +Required properties:
> +- compatible: Must be "st,stm32-timer-counter".
> +- pinctrl-names: Set to "default".
> +- pinctrl-0: List of phandles pointing to pin configuration nodes,
> + to set IN1/IN2 pins in mode of operation for Low-Power
> + Timer input on external pin.
> +
> +Example:
> + timers at 40010000 {
> + compatible = "st,stm32-timers";
> + ...
> + counter {
> + compatible = "st,stm32-timer-counter";
Is there only 1? How is the counter addressed?
> + pinctrl-names = "default";
> + pinctrl-0 = <&tim1_in_pins>;
> + };
> + };
^ permalink raw reply
* [PATCH v2 17/40] iommu/arm-smmu-v3: Link domains and devices
From: Jonathan Cameron @ 2018-05-17 16:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511190641.23008-18-jean-philippe.brucker@arm.com>
On Fri, 11 May 2018 20:06:18 +0100
Jean-Philippe Brucker <jean-philippe.brucker@arm.com> wrote:
> When removing a mapping from a domain, we need to send an invalidation to
> all devices that might have stored it in their Address Translation Cache
> (ATC). In addition when updating the context descriptor of a live domain,
> we'll need to send invalidations for all devices attached to it.
>
> Maintain a list of devices in each domain, protected by a spinlock. It is
> updated every time we attach or detach devices to and from domains.
>
> It needs to be a spinlock because we'll invalidate ATC entries from
> within hardirq-safe contexts, but it may be possible to relax the read
> side with RCU later.
>
> Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Trivial naming suggestion...
> ---
> drivers/iommu/arm-smmu-v3.c | 28 ++++++++++++++++++++++++++++
> 1 file changed, 28 insertions(+)
>
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 1d647104bccc..c892f012fb43 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -595,6 +595,11 @@ struct arm_smmu_device {
> struct arm_smmu_master_data {
> struct arm_smmu_device *smmu;
> struct arm_smmu_strtab_ent ste;
> +
> + struct arm_smmu_domain *domain;
> + struct list_head list; /* domain->devices */
More meaningful name perhaps to avoid the need for the comment?
> +
> + struct device *dev;
> };
>
> /* SMMU private data for an IOMMU domain */
> @@ -618,6 +623,9 @@ struct arm_smmu_domain {
> };
>
> struct iommu_domain domain;
> +
> + struct list_head devices;
> + spinlock_t devices_lock;
> };
>
> struct arm_smmu_option_prop {
> @@ -1470,6 +1478,9 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
> }
>
> mutex_init(&smmu_domain->init_mutex);
> + INIT_LIST_HEAD(&smmu_domain->devices);
> + spin_lock_init(&smmu_domain->devices_lock);
> +
> return &smmu_domain->domain;
> }
>
> @@ -1685,7 +1696,17 @@ static void arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec)
>
> static void arm_smmu_detach_dev(struct device *dev)
> {
> + unsigned long flags;
> struct arm_smmu_master_data *master = dev->iommu_fwspec->iommu_priv;
> + struct arm_smmu_domain *smmu_domain = master->domain;
> +
> + if (smmu_domain) {
> + spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> + list_del(&master->list);
> + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
> +
> + master->domain = NULL;
> + }
>
> master->ste.assigned = false;
> arm_smmu_install_ste_for_dev(dev->iommu_fwspec);
> @@ -1694,6 +1715,7 @@ static void arm_smmu_detach_dev(struct device *dev)
> static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
> {
> int ret = 0;
> + unsigned long flags;
> struct arm_smmu_device *smmu;
> struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> struct arm_smmu_master_data *master;
> @@ -1729,6 +1751,11 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
> }
>
> ste->assigned = true;
> + master->domain = smmu_domain;
> +
> + spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> + list_add(&master->list, &smmu_domain->devices);
> + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
>
> if (smmu_domain->stage == ARM_SMMU_DOMAIN_BYPASS) {
> ste->s1_cfg = NULL;
> @@ -1847,6 +1874,7 @@ static int arm_smmu_add_device(struct device *dev)
> return -ENOMEM;
>
> master->smmu = smmu;
> + master->dev = dev;
> fwspec->iommu_priv = master;
> }
>
^ permalink raw reply
* [PATCH] arm: bcm2835: Add the PMU to the devicetree.
From: Stefan Wahren @ 2018-05-17 16:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.21.1805171007260.7820@macbook-air>
> Vince Weaver <vincent.weaver@maine.edu> hat am 17. Mai 2018 um 16:11 geschrieben:
>
>
> On Thu, 17 May 2018, Eric Anholt wrote:
>
> > diff --git a/arch/arm/boot/dts/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi
> > index 7704bb029605..1f5e5c782835 100644
> > --- a/arch/arm/boot/dts/bcm2837.dtsi
> > +++ b/arch/arm/boot/dts/bcm2837.dtsi
> > @@ -17,6 +17,12 @@
> > };
> > };
> >
> > + arm-pmu {
> > + compatible = "arm,cortex-a53-pmu", "arm,cortex-a7-pmu";
> > + interrupt-parent = <&local_intc>;
> > + interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
> > + };
> > +
>
> why this and not
>
> arm-pmu {
> compatible = "arm,armv8-pmuv3";
> interrupt-parent = <&local_intc>;
> interrupts = <9>;
> };
>
> which works, though when I didn't get very far when I submitted the patch
> to add this last August.
Eric's variant is more specific so we better chose this. The init code diverse between the general arm,armv8-pmuv3 and arm,cortex-a53-pmu.
>
> Vince
>
> _______________________________________________
> linux-rpi-kernel mailing list
> linux-rpi-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rpi-kernel
^ permalink raw reply
* [GIT PULL] arm64: tegra: Device tree fixes for v4.17
From: Thierry Reding @ 2018-05-17 16:04 UTC (permalink / raw)
To: linux-arm-kernel
Hi ARM SoC maintainers,
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.17-fixes-2
for you to fetch changes up to 9df50ba76ac1485b844beffa1f3f5d9659d9cdaf:
arm64: tegra: Make BCM89610 PHY interrupt as active low (2018-05-03 11:48:16 +0200)
Thanks,
Thierry
----------------------------------------------------------------
arm64: tegra: Device tree fixes for v4.17
This contains a one-line update to the device tree of the Tegra186 P3310
processor module, fixing the polarity of the PHY interrupt. Originally,
this was queued to go into v4.18, but the PHY ID matching patch has now
found its way into v4.17-rc5, which means that the PHY driver will know
how to identify the PHY on this board and try to use the interrupt. This
will unfortunately cause networking to break on P3310, hence why I think
this should go into v4.17.
----------------------------------------------------------------
Bhadram Varka (1):
arm64: tegra: Make BCM89610 PHY interrupt as active low
arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
^ permalink raw reply
* [PATCH] soc: qcom: apr: fix invalid msg_type check
From: Srinivas Kandagatla @ 2018-05-17 16:03 UTC (permalink / raw)
To: linux-arm-kernel
Removed invalid msg_type check.
This also fixes below static checker warning:
apr.c:95:35: warning: comparison is always true due to limited range of
data type [-Wtype-limits]
warn: always true condition '(msg_type != 69864) => (0-u16max != 69864)'
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
drivers/soc/qcom/apr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
index 97f3622da535..57af8a537332 100644
--- a/drivers/soc/qcom/apr.c
+++ b/drivers/soc/qcom/apr.c
@@ -92,7 +92,7 @@ static int apr_callback(struct rpmsg_device *rpdev, void *buf,
}
msg_type = APR_HDR_FIELD_MT(hdr->hdr_field);
- if (msg_type >= APR_MSG_TYPE_MAX && msg_type != APR_BASIC_RSP_RESULT) {
+ if (msg_type >= APR_MSG_TYPE_MAX) {
dev_err(apr->dev, "APR: Wrong message type: %d\n", msg_type);
return -EINVAL;
}
--
2.16.2
^ permalink raw reply related
* [PATCH] arm: bcm2835: Add the PMU to the devicetree.
From: Vince Weaver @ 2018-05-17 16:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87efia1hjg.fsf@anholt.net>
On Thu, 17 May 2018, Eric Anholt wrote:
>
> Is that better than a53? I'm happy to switch to that. The important
> part to me is the a7, since basically everyone with this hw is running
> arm32.
no, on further investigation it looks like a53 is more proper to use than
the generic armv8.
Is the armv8 pmu on the cortex-a53 backwards compatible with armv7? I'm
dreading having to pull up the various ARM ARMs to look for myself so if
it works for you I'm fine with that part too.
The biggest pushback I had with my original patch was no one believing irq
9 was the right one to use.
Vince
^ permalink raw reply
* [PATCH] arm: bcm2835: Add the PMU to the devicetree.
From: Stefan Wahren @ 2018-05-17 15:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180517131727.29263-1-eric@anholt.net>
> Eric Anholt <eric@anholt.net> hat am 17. Mai 2018 um 15:17 geschrieben:
>
>
> The a53 and a7 counters seem to match up, so we advertise a7 so that
> arm32 can probe.
>
> Signed-off-by: Eric Anholt <eric@anholt.net>
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
^ permalink raw reply
* AArch64 memory
From: Tim Harvey @ 2018-05-17 15:58 UTC (permalink / raw)
To: linux-arm-kernel
Greetings,
I'm trying to understand some details of the AArch64 memory
configuration in the kernel.
I've looked at Documentation/arm64/memory.txt which describes the
virtual memory layout used in terms of translation levels. This
relates to CONFIG_ARM64_{4K,16K,64K}_PAGES and CONFIG_ARM64_VA_BITS*.
My first question has to do with virtual memory layout: What are the
advantages and disadvantages for a system with a fixed 2GB of DRAM
when using using 4KB pages + 3 levels (CONFIG_ARM64_4K_PAGES=y
CONFIG_ARM64_VA_BITS=39) resulting in 512GB user / 512GB kernel vs
using 64KB pages + 3 levels (CONFIG_ARM64_64K_PAGES=y
CONFIG_ARM64_VA_BITS=48)? The physical memory is far less than what
any of the combinations would offer but I'm not clear if the number of
levels affects any sort of performance or how fragmentation could play
into performance.
My second question has to do with CMA and coherent_pool. I have
understood CMA as being a chunk of physical memory carved out by the
kernel for allocations from dma_alloc_coherent by drivers that need
chunks of contiguous memory for DMA buffers. I believe that before CMA
was introduced we had to do this by defining memory holes. I'm not
understanding the difference between CMA and the coherent pool. I've
noticed that if CONFIG_DMA_CMA=y then the coherent pool allocates from
CMA. Is there some disadvantage of CONFIG_DMA_CMA=y other than if
defined you need to make sure your CMA is larger than coherent_pool?
What drivers/calls use coherent_pool vs cma?
Best Regards,
Tim
^ permalink raw reply
* [PATCH v2 13/40] vfio: Add support for Shared Virtual Addressing
From: Jonathan Cameron @ 2018-05-17 15:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511190641.23008-14-jean-philippe.brucker@arm.com>
On Fri, 11 May 2018 20:06:14 +0100
Jean-Philippe Brucker <jean-philippe.brucker@arm.com> wrote:
> Add two new ioctls for VFIO containers. VFIO_IOMMU_BIND_PROCESS creates a
> bond between a container and a process address space, identified by a
> Process Address Space ID (PASID). Devices in the container append this
> PASID to DMA transactions in order to access the process' address space.
> The process page tables are shared with the IOMMU, and mechanisms such as
> PCI ATS/PRI are used to handle faults. VFIO_IOMMU_UNBIND_PROCESS removes a
> bond created with VFIO_IOMMU_BIND_PROCESS.
>
> Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
A couple of small comments inline..
Jonathan
>
> ---
> v1->v2:
> * Simplify mm_exit
> * Can be built as module again
> ---
> drivers/vfio/vfio_iommu_type1.c | 449 ++++++++++++++++++++++++++++++--
> include/uapi/linux/vfio.h | 76 ++++++
> 2 files changed, 504 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index 5c212bf29640..2902774062b8 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -30,6 +30,7 @@
> #include <linux/iommu.h>
> #include <linux/module.h>
> #include <linux/mm.h>
> +#include <linux/ptrace.h>
> #include <linux/rbtree.h>
> #include <linux/sched/signal.h>
> #include <linux/sched/mm.h>
> @@ -60,6 +61,7 @@ MODULE_PARM_DESC(disable_hugepages,
>
> struct vfio_iommu {
> struct list_head domain_list;
> + struct list_head mm_list;
> struct vfio_domain *external_domain; /* domain for external user */
> struct mutex lock;
> struct rb_root dma_list;
> @@ -90,6 +92,14 @@ struct vfio_dma {
> struct vfio_group {
> struct iommu_group *iommu_group;
> struct list_head next;
> + bool sva_enabled;
> +};
> +
> +struct vfio_mm {
> +#define VFIO_PASID_INVALID (-1)
> + int pasid;
> + struct mm_struct *mm;
> + struct list_head next;
> };
>
> /*
> @@ -1238,6 +1248,164 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
> return 0;
> }
>
> +static int vfio_iommu_mm_exit(struct device *dev, int pasid, void *data)
> +{
> + struct vfio_mm *vfio_mm;
> + struct vfio_iommu *iommu = data;
> +
> + mutex_lock(&iommu->lock);
> + list_for_each_entry(vfio_mm, &iommu->mm_list, next) {
> + if (vfio_mm->pasid == pasid) {
> + list_del(&vfio_mm->next);
> + kfree(vfio_mm);
> + break;
> + }
> + }
> + mutex_unlock(&iommu->lock);
> +
> + return 0;
> +}
> +
> +static int vfio_iommu_sva_init(struct device *dev, void *data)
> +{
> + return iommu_sva_device_init(dev, IOMMU_SVA_FEAT_IOPF, 0,
> + vfio_iommu_mm_exit);
> +}
> +
> +static int vfio_iommu_sva_shutdown(struct device *dev, void *data)
> +{
> + iommu_sva_device_shutdown(dev);
> +
> + return 0;
> +}
> +
> +struct vfio_iommu_sva_bind_data {
> + struct vfio_mm *vfio_mm;
> + struct vfio_iommu *iommu;
> + int count;
> +};
> +
> +static int vfio_iommu_sva_bind_dev(struct device *dev, void *data)
> +{
> + struct vfio_iommu_sva_bind_data *bind_data = data;
> +
> + /* Multi-device groups aren't support for SVA */
> + if (bind_data->count++)
> + return -EINVAL;
> +
> + return __iommu_sva_bind_device(dev, bind_data->vfio_mm->mm,
> + &bind_data->vfio_mm->pasid,
> + IOMMU_SVA_FEAT_IOPF, bind_data->iommu);
> +}
> +
> +static int vfio_iommu_sva_unbind_dev(struct device *dev, void *data)
> +{
> + struct vfio_mm *vfio_mm = data;
> +
> + return __iommu_sva_unbind_device(dev, vfio_mm->pasid);
> +}
> +
> +static int vfio_iommu_bind_group(struct vfio_iommu *iommu,
> + struct vfio_group *group,
> + struct vfio_mm *vfio_mm)
> +{
> + int ret;
> + bool enabled_sva = false;
> + struct vfio_iommu_sva_bind_data data = {
> + .vfio_mm = vfio_mm,
> + .iommu = iommu,
> + .count = 0,
> + };
> +
> + if (!group->sva_enabled) {
> + ret = iommu_group_for_each_dev(group->iommu_group, NULL,
> + vfio_iommu_sva_init);
> + if (ret)
> + return ret;
> +
> + group->sva_enabled = enabled_sva = true;
> + }
> +
> + ret = iommu_group_for_each_dev(group->iommu_group, &data,
> + vfio_iommu_sva_bind_dev);
> + if (ret && data.count > 1)
Are we safe to run this even if data.count == 1? I assume that at
that point we would always not have an iommu domain associated with the
device so the initial check would error out.
Just be nice to get rid of the special casing in this error path as then
could just do it all under if (ret) and make it visually clearer these
are different aspects of the same error path.
> + iommu_group_for_each_dev(group->iommu_group, vfio_mm,
> + vfio_iommu_sva_unbind_dev);
> + if (ret && enabled_sva) {
> + iommu_group_for_each_dev(group->iommu_group, NULL,
> + vfio_iommu_sva_shutdown);
> + group->sva_enabled = false;
> + }
> +
> + return ret;
> +}
> +
> +static void vfio_iommu_unbind_group(struct vfio_group *group,
> + struct vfio_mm *vfio_mm)
> +{
> + iommu_group_for_each_dev(group->iommu_group, vfio_mm,
> + vfio_iommu_sva_unbind_dev);
> +}
> +
> +static void vfio_iommu_unbind(struct vfio_iommu *iommu,
> + struct vfio_mm *vfio_mm)
> +{
> + struct vfio_group *group;
> + struct vfio_domain *domain;
> +
> + list_for_each_entry(domain, &iommu->domain_list, next)
> + list_for_each_entry(group, &domain->group_list, next)
> + vfio_iommu_unbind_group(group, vfio_mm);
> +}
> +
> +static int vfio_iommu_replay_bind(struct vfio_iommu *iommu,
> + struct vfio_group *group)
> +{
> + int ret = 0;
> + struct vfio_mm *vfio_mm;
> +
> + list_for_each_entry(vfio_mm, &iommu->mm_list, next) {
> + /*
> + * Ensure that mm doesn't exit while we're binding it to the new
> + * group. It may already have exited, and the mm_exit notifier
> + * might be waiting on the IOMMU mutex to remove this vfio_mm
> + * from the list.
> + */
> + if (!mmget_not_zero(vfio_mm->mm))
> + continue;
> + ret = vfio_iommu_bind_group(iommu, group, vfio_mm);
> + /*
> + * Use async to avoid triggering an mm_exit callback right away,
> + * which would block on the mutex that we're holding.
> + */
> + mmput_async(vfio_mm->mm);
> +
> + if (ret)
> + goto out_unbind;
> + }
> +
> + return 0;
> +
> +out_unbind:
> + list_for_each_entry_continue_reverse(vfio_mm, &iommu->mm_list, next)
> + vfio_iommu_unbind_group(group, vfio_mm);
> +
> + return ret;
> +}
> +
> +static void vfio_iommu_free_all_mm(struct vfio_iommu *iommu)
> +{
> + struct vfio_mm *vfio_mm, *next;
> +
> + /*
> + * No need for unbind() here. Since all groups are detached from this
> + * iommu, bonds have been removed.
> + */
> + list_for_each_entry_safe(vfio_mm, next, &iommu->mm_list, next)
> + kfree(vfio_mm);
> + INIT_LIST_HEAD(&iommu->mm_list);
> +}
> +
> /*
> * We change our unmap behavior slightly depending on whether the IOMMU
> * supports fine-grained superpages. IOMMUs like AMD-Vi will use a superpage
> @@ -1313,6 +1481,44 @@ static bool vfio_iommu_has_sw_msi(struct iommu_group *group, phys_addr_t *base)
> return ret;
> }
>
> +static int vfio_iommu_try_attach_group(struct vfio_iommu *iommu,
> + struct vfio_group *group,
> + struct vfio_domain *cur_domain,
> + struct vfio_domain *new_domain)
> +{
> + struct iommu_group *iommu_group = group->iommu_group;
> +
> + /*
> + * Try to match an existing compatible domain. We don't want to
> + * preclude an IOMMU driver supporting multiple bus_types and being
> + * able to include different bus_types in the same IOMMU domain, so
> + * we test whether the domains use the same iommu_ops rather than
> + * testing if they're on the same bus_type.
> + */
> + if (new_domain->domain->ops != cur_domain->domain->ops ||
> + new_domain->prot != cur_domain->prot)
> + return 1;
> +
> + iommu_detach_group(cur_domain->domain, iommu_group);
> +
> + if (iommu_attach_group(new_domain->domain, iommu_group))
> + goto out_reattach;
> +
> + if (vfio_iommu_replay_bind(iommu, group))
> + goto out_detach;
> +
> + return 0;
> +
> +out_detach:
> + iommu_detach_group(new_domain->domain, iommu_group);
> +
> +out_reattach:
> + if (iommu_attach_group(cur_domain->domain, iommu_group))
> + return -EINVAL;
> +
> + return 1;
> +}
> +
> static int vfio_iommu_type1_attach_group(void *iommu_data,
> struct iommu_group *iommu_group)
> {
> @@ -1410,28 +1616,16 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
> if (iommu_capable(bus, IOMMU_CAP_CACHE_COHERENCY))
> domain->prot |= IOMMU_CACHE;
>
> - /*
> - * Try to match an existing compatible domain. We don't want to
> - * preclude an IOMMU driver supporting multiple bus_types and being
> - * able to include different bus_types in the same IOMMU domain, so
> - * we test whether the domains use the same iommu_ops rather than
> - * testing if they're on the same bus_type.
> - */
> list_for_each_entry(d, &iommu->domain_list, next) {
> - if (d->domain->ops == domain->domain->ops &&
> - d->prot == domain->prot) {
> - iommu_detach_group(domain->domain, iommu_group);
> - if (!iommu_attach_group(d->domain, iommu_group)) {
> - list_add(&group->next, &d->group_list);
> - iommu_domain_free(domain->domain);
> - kfree(domain);
> - mutex_unlock(&iommu->lock);
> - return 0;
> - }
> -
> - ret = iommu_attach_group(domain->domain, iommu_group);
> - if (ret)
> - goto out_domain;
> + ret = vfio_iommu_try_attach_group(iommu, group, domain, d);
> + if (ret < 0) {
> + goto out_domain;
> + } else if (!ret) {
> + list_add(&group->next, &d->group_list);
> + iommu_domain_free(domain->domain);
> + kfree(domain);
> + mutex_unlock(&iommu->lock);
> + return 0;
> }
> }
>
> @@ -1442,6 +1636,10 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
> if (ret)
> goto out_detach;
>
> + ret = vfio_iommu_replay_bind(iommu, group);
> + if (ret)
> + goto out_detach;
> +
> if (resv_msi) {
> ret = iommu_get_msi_cookie(domain->domain, resv_msi_base);
> if (ret)
> @@ -1547,6 +1745,11 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
> continue;
>
> iommu_detach_group(domain->domain, iommu_group);
> + if (group->sva_enabled) {
> + iommu_group_for_each_dev(iommu_group, NULL,
> + vfio_iommu_sva_shutdown);
> + group->sva_enabled = false;
> + }
> list_del(&group->next);
> kfree(group);
> /*
> @@ -1562,6 +1765,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
> vfio_iommu_unmap_unpin_all(iommu);
> else
> vfio_iommu_unmap_unpin_reaccount(iommu);
> + vfio_iommu_free_all_mm(iommu);
> }
> iommu_domain_free(domain->domain);
> list_del(&domain->next);
> @@ -1596,6 +1800,7 @@ static void *vfio_iommu_type1_open(unsigned long arg)
> }
>
> INIT_LIST_HEAD(&iommu->domain_list);
> + INIT_LIST_HEAD(&iommu->mm_list);
> iommu->dma_list = RB_ROOT;
> mutex_init(&iommu->lock);
> BLOCKING_INIT_NOTIFIER_HEAD(&iommu->notifier);
> @@ -1630,6 +1835,7 @@ static void vfio_iommu_type1_release(void *iommu_data)
> kfree(iommu->external_domain);
> }
>
> + vfio_iommu_free_all_mm(iommu);
> vfio_iommu_unmap_unpin_all(iommu);
>
> list_for_each_entry_safe(domain, domain_tmp,
> @@ -1658,6 +1864,169 @@ static int vfio_domains_have_iommu_cache(struct vfio_iommu *iommu)
> return ret;
> }
>
> +static struct mm_struct *vfio_iommu_get_mm_by_vpid(pid_t vpid)
> +{
> + struct mm_struct *mm;
> + struct task_struct *task;
> +
> + task = find_get_task_by_vpid(vpid);
> + if (!task)
> + return ERR_PTR(-ESRCH);
> +
> + /* Ensure that current has RW access on the mm */
> + mm = mm_access(task, PTRACE_MODE_ATTACH_REALCREDS);
> + put_task_struct(task);
> +
> + if (!mm)
> + return ERR_PTR(-ESRCH);
> +
> + return mm;
> +}
> +
> +static long vfio_iommu_type1_bind_process(struct vfio_iommu *iommu,
> + void __user *arg,
> + struct vfio_iommu_type1_bind *bind)
> +{
> + struct vfio_iommu_type1_bind_process params;
> + struct vfio_domain *domain;
> + struct vfio_group *group;
> + struct vfio_mm *vfio_mm;
> + struct mm_struct *mm;
> + unsigned long minsz;
> + int ret = 0;
> +
> + minsz = sizeof(*bind) + sizeof(params);
> + if (bind->argsz < minsz)
> + return -EINVAL;
> +
> + arg += sizeof(*bind);
> + if (copy_from_user(¶ms, arg, sizeof(params)))
> + return -EFAULT;
> +
> + if (params.flags & ~VFIO_IOMMU_BIND_PID)
> + return -EINVAL;
> +
> + if (params.flags & VFIO_IOMMU_BIND_PID) {
> + mm = vfio_iommu_get_mm_by_vpid(params.pid);
> + if (IS_ERR(mm))
> + return PTR_ERR(mm);
> + } else {
> + mm = get_task_mm(current);
> + if (!mm)
> + return -EINVAL;
> + }
> +
> + mutex_lock(&iommu->lock);
> + if (!IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)) {
> + ret = -EINVAL;
> + goto out_unlock;
> + }
> +
> + list_for_each_entry(vfio_mm, &iommu->mm_list, next) {
> + if (vfio_mm->mm == mm) {
> + params.pasid = vfio_mm->pasid;
> + ret = copy_to_user(arg, ¶ms, sizeof(params)) ?
> + -EFAULT : 0;
> + goto out_unlock;
> + }
> + }
> +
> + vfio_mm = kzalloc(sizeof(*vfio_mm), GFP_KERNEL);
> + if (!vfio_mm) {
> + ret = -ENOMEM;
> + goto out_unlock;
> + }
> +
> + vfio_mm->mm = mm;
> + vfio_mm->pasid = VFIO_PASID_INVALID;
> +
> + list_for_each_entry(domain, &iommu->domain_list, next) {
> + list_for_each_entry(group, &domain->group_list, next) {
> + ret = vfio_iommu_bind_group(iommu, group, vfio_mm);
> + if (ret)
> + goto out_unbind;
> + }
> + }
> +
> + list_add(&vfio_mm->next, &iommu->mm_list);
> +
> + params.pasid = vfio_mm->pasid;
> + ret = copy_to_user(arg, ¶ms, sizeof(params)) ? -EFAULT : 0;
> + if (ret)
> + goto out_delete;
> +
> + mutex_unlock(&iommu->lock);
> + mmput(mm);
> + return 0;
> +
> +out_delete:
> + list_del(&vfio_mm->next);
> +
> +out_unbind:
> + /* Undo all binds that already succeeded */
> + vfio_iommu_unbind(iommu, vfio_mm);
> + kfree(vfio_mm);
> +
> +out_unlock:
> + mutex_unlock(&iommu->lock);
> + mmput(mm);
> + return ret;
> +}
> +
> +static long vfio_iommu_type1_unbind_process(struct vfio_iommu *iommu,
> + void __user *arg,
> + struct vfio_iommu_type1_bind *bind)
> +{
> + int ret = -EINVAL;
> + unsigned long minsz;
> + struct mm_struct *mm;
> + struct vfio_mm *vfio_mm;
> + struct vfio_iommu_type1_bind_process params;
> +
> + minsz = sizeof(*bind) + sizeof(params);
> + if (bind->argsz < minsz)
> + return -EINVAL;
> +
> + arg += sizeof(*bind);
> + if (copy_from_user(¶ms, arg, sizeof(params)))
> + return -EFAULT;
> +
> + if (params.flags & ~VFIO_IOMMU_BIND_PID)
> + return -EINVAL;
> +
> + /*
> + * We can't simply call unbind with the PASID, because the process might
> + * have died and the PASID might have been reallocated to another
> + * process. Instead we need to fetch that process mm by PID again to
> + * make sure we remove the right vfio_mm.
> + */
> + if (params.flags & VFIO_IOMMU_BIND_PID) {
> + mm = vfio_iommu_get_mm_by_vpid(params.pid);
> + if (IS_ERR(mm))
> + return PTR_ERR(mm);
> + } else {
> + mm = get_task_mm(current);
> + if (!mm)
> + return -EINVAL;
> + }
> +
> + ret = -ESRCH;
> + mutex_lock(&iommu->lock);
> + list_for_each_entry(vfio_mm, &iommu->mm_list, next) {
> + if (vfio_mm->mm == mm) {
> + vfio_iommu_unbind(iommu, vfio_mm);
> + list_del(&vfio_mm->next);
> + kfree(vfio_mm);
> + ret = 0;
> + break;
> + }
> + }
> + mutex_unlock(&iommu->lock);
> + mmput(mm);
> +
> + return ret;
> +}
> +
> static long vfio_iommu_type1_ioctl(void *iommu_data,
> unsigned int cmd, unsigned long arg)
> {
> @@ -1728,6 +2097,44 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
>
> return copy_to_user((void __user *)arg, &unmap, minsz) ?
> -EFAULT : 0;
> +
> + } else if (cmd == VFIO_IOMMU_BIND) {
> + struct vfio_iommu_type1_bind bind;
> +
> + minsz = offsetofend(struct vfio_iommu_type1_bind, flags);
> +
> + if (copy_from_user(&bind, (void __user *)arg, minsz))
> + return -EFAULT;
> +
> + if (bind.argsz < minsz)
> + return -EINVAL;
> +
> + switch (bind.flags) {
> + case VFIO_IOMMU_BIND_PROCESS:
> + return vfio_iommu_type1_bind_process(iommu, (void *)arg,
> + &bind);
Can we combine these two blocks given it is only this case statement that is different?
> + default:
> + return -EINVAL;
> + }
> +
> + } else if (cmd == VFIO_IOMMU_UNBIND) {
> + struct vfio_iommu_type1_bind bind;
> +
> + minsz = offsetofend(struct vfio_iommu_type1_bind, flags);
> +
> + if (copy_from_user(&bind, (void __user *)arg, minsz))
> + return -EFAULT;
> +
> + if (bind.argsz < minsz)
> + return -EINVAL;
> +
> + switch (bind.flags) {
> + case VFIO_IOMMU_BIND_PROCESS:
> + return vfio_iommu_type1_unbind_process(iommu, (void *)arg,
> + &bind);
> + default:
> + return -EINVAL;
> + }
> }
>
> return -ENOTTY;
> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> index 1aa7b82e8169..dc07752c8fe8 100644
> --- a/include/uapi/linux/vfio.h
> +++ b/include/uapi/linux/vfio.h
> @@ -665,6 +665,82 @@ struct vfio_iommu_type1_dma_unmap {
> #define VFIO_IOMMU_ENABLE _IO(VFIO_TYPE, VFIO_BASE + 15)
> #define VFIO_IOMMU_DISABLE _IO(VFIO_TYPE, VFIO_BASE + 16)
>
> +/*
> + * VFIO_IOMMU_BIND_PROCESS
> + *
> + * Allocate a PASID for a process address space, and use it to attach this
> + * process to all devices in the container. Devices can then tag their DMA
> + * traffic with the returned @pasid to perform transactions on the associated
> + * virtual address space. Mapping and unmapping buffers is performed by standard
> + * functions such as mmap and malloc.
> + *
> + * If flag is VFIO_IOMMU_BIND_PID, @pid contains the pid of a foreign process to
> + * bind. Otherwise the current task is bound. Given that the caller owns the
> + * device, setting this flag grants the caller read and write permissions on the
> + * entire address space of foreign process described by @pid. Therefore,
> + * permission to perform the bind operation on a foreign process is governed by
> + * the ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check. See man ptrace(2)
> + * for more information.
> + *
> + * On success, VFIO writes a Process Address Space ID (PASID) into @pasid. This
> + * ID is unique to a process and can be used on all devices in the container.
> + *
> + * On fork, the child inherits the device fd and can use the bonds setup by its
> + * parent. Consequently, the child has R/W access on the address spaces bound by
> + * its parent. After an execv, the device fd is closed and the child doesn't
> + * have access to the address space anymore.
> + *
> + * To remove a bond between process and container, VFIO_IOMMU_UNBIND ioctl is
> + * issued with the same parameters. If a pid was specified in VFIO_IOMMU_BIND,
> + * it should also be present for VFIO_IOMMU_UNBIND. Otherwise unbind the current
> + * task from the container.
> + */
> +struct vfio_iommu_type1_bind_process {
> + __u32 flags;
> +#define VFIO_IOMMU_BIND_PID (1 << 0)
> + __u32 pasid;
> + __s32 pid;
> +};
> +
> +/*
> + * Only mode supported at the moment is VFIO_IOMMU_BIND_PROCESS, which takes
> + * vfio_iommu_type1_bind_process in data.
> + */
> +struct vfio_iommu_type1_bind {
> + __u32 argsz;
> + __u32 flags;
> +#define VFIO_IOMMU_BIND_PROCESS (1 << 0)
> + __u8 data[];
> +};
> +
> +/*
> + * VFIO_IOMMU_BIND - _IOWR(VFIO_TYPE, VFIO_BASE + 22, struct vfio_iommu_bind)
> + *
> + * Manage address spaces of devices in this container. Initially a TYPE1
> + * container can only have one address space, managed with
> + * VFIO_IOMMU_MAP/UNMAP_DMA.
> + *
> + * An IOMMU of type VFIO_TYPE1_NESTING_IOMMU can be managed by both MAP/UNMAP
> + * and BIND ioctls at the same time. MAP/UNMAP acts on the stage-2 (host) page
> + * tables, and BIND manages the stage-1 (guest) page tables. Other types of
> + * IOMMU may allow MAP/UNMAP and BIND to coexist, where MAP/UNMAP controls
> + * non-PASID traffic and BIND controls PASID traffic. But this depends on the
> + * underlying IOMMU architecture and isn't guaranteed.
> + *
> + * Availability of this feature depends on the device, its bus, the underlying
> + * IOMMU and the CPU architecture.
> + *
> + * returns: 0 on success, -errno on failure.
> + */
> +#define VFIO_IOMMU_BIND _IO(VFIO_TYPE, VFIO_BASE + 22)
> +
> +/*
> + * VFIO_IOMMU_UNBIND - _IOWR(VFIO_TYPE, VFIO_BASE + 23, struct vfio_iommu_bind)
> + *
> + * Undo what was done by the corresponding VFIO_IOMMU_BIND ioctl.
> + */
> +#define VFIO_IOMMU_UNBIND _IO(VFIO_TYPE, VFIO_BASE + 23)
> +
> /* -------- Additional API for SPAPR TCE (Server POWERPC) IOMMU -------- */
>
> /*
^ permalink raw reply
* [PATCH v3-UPADATE 2/3] ioremap: Update pgtable free interfaces with addr
From: Toshi Kani @ 2018-05-17 15:57 UTC (permalink / raw)
To: linux-arm-kernel
From: Chintan Pandya <cpandya@codeaurora.org>
The following kernel panic was observed on ARM64 platform due to a stale
TLB entry.
1. ioremap with 4K size, a valid pte page table is set.
2. iounmap it, its pte entry is set to 0.
3. ioremap the same address with 2M size, update its pmd entry with
a new value.
4. CPU may hit an exception because the old pmd entry is still in TLB,
which leads to a kernel panic.
Commit b6bdb7517c3d ("mm/vmalloc: add interfaces to free unmapped page
table") has addressed this panic by falling to pte mappings in the above
case on ARM64.
To support pmd mappings in all cases, TLB purge needs to be performed
in this case on ARM64.
Add a new arg, 'addr', to pud_free_pmd_page() and pmd_free_pte_page()
so that TLB purge can be added later in seprate patches.
[toshi at hpe.com: merge changes, rewrite patch description]
Fixes: 28ee90fe6048 ("x86/mm: implement free pmd/pte page interfaces")
Signed-off-by: Chintan Pandya <cpandya@codeaurora.org>
Signed-off-by: Toshi Kani <toshi.kani@hpe.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: <stable@vger.kernel.org>
---
v3-UPDATE - Rewrite patch description
---
arch/arm64/mm/mmu.c | 4 ++--
arch/x86/mm/pgtable.c | 12 +++++++-----
include/asm-generic/pgtable.h | 8 ++++----
lib/ioremap.c | 4 ++--
4 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 2dbb2c9f1ec1..da98828609a1 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -973,12 +973,12 @@ int pmd_clear_huge(pmd_t *pmdp)
return 1;
}
-int pud_free_pmd_page(pud_t *pud)
+int pud_free_pmd_page(pud_t *pud, unsigned long addr)
{
return pud_none(*pud);
}
-int pmd_free_pte_page(pmd_t *pmd)
+int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
{
return pmd_none(*pmd);
}
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 3f7180bc5f52..f60fdf411103 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -719,11 +719,12 @@ int pmd_clear_huge(pmd_t *pmd)
/**
* pud_free_pmd_page - Clear pud entry and free pmd page.
* @pud: Pointer to a PUD.
+ * @addr: Virtual address associated with pud.
*
* Context: The pud range has been unmaped and TLB purged.
* Return: 1 if clearing the entry succeeded. 0 otherwise.
*/
-int pud_free_pmd_page(pud_t *pud)
+int pud_free_pmd_page(pud_t *pud, unsigned long addr)
{
pmd_t *pmd;
int i;
@@ -734,7 +735,7 @@ int pud_free_pmd_page(pud_t *pud)
pmd = (pmd_t *)pud_page_vaddr(*pud);
for (i = 0; i < PTRS_PER_PMD; i++)
- if (!pmd_free_pte_page(&pmd[i]))
+ if (!pmd_free_pte_page(&pmd[i], addr + (i * PMD_SIZE)))
return 0;
pud_clear(pud);
@@ -746,11 +747,12 @@ int pud_free_pmd_page(pud_t *pud)
/**
* pmd_free_pte_page - Clear pmd entry and free pte page.
* @pmd: Pointer to a PMD.
+ * @addr: Virtual address associated with pmd.
*
* Context: The pmd range has been unmaped and TLB purged.
* Return: 1 if clearing the entry succeeded. 0 otherwise.
*/
-int pmd_free_pte_page(pmd_t *pmd)
+int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
{
pte_t *pte;
@@ -766,7 +768,7 @@ int pmd_free_pte_page(pmd_t *pmd)
#else /* !CONFIG_X86_64 */
-int pud_free_pmd_page(pud_t *pud)
+int pud_free_pmd_page(pud_t *pud, unsigned long addr)
{
return pud_none(*pud);
}
@@ -775,7 +777,7 @@ int pud_free_pmd_page(pud_t *pud)
* Disable free page handling on x86-PAE. This assures that ioremap()
* does not update sync'd pmd entries. See vmalloc_sync_one().
*/
-int pmd_free_pte_page(pmd_t *pmd)
+int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
{
return pmd_none(*pmd);
}
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index f59639afaa39..b081794ba135 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -1019,8 +1019,8 @@ int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot);
int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot);
int pud_clear_huge(pud_t *pud);
int pmd_clear_huge(pmd_t *pmd);
-int pud_free_pmd_page(pud_t *pud);
-int pmd_free_pte_page(pmd_t *pmd);
+int pud_free_pmd_page(pud_t *pud, unsigned long addr);
+int pmd_free_pte_page(pmd_t *pmd, unsigned long addr);
#else /* !CONFIG_HAVE_ARCH_HUGE_VMAP */
static inline int p4d_set_huge(p4d_t *p4d, phys_addr_t addr, pgprot_t prot)
{
@@ -1046,11 +1046,11 @@ static inline int pmd_clear_huge(pmd_t *pmd)
{
return 0;
}
-static inline int pud_free_pmd_page(pud_t *pud)
+static inline int pud_free_pmd_page(pud_t *pud, unsigned long addr)
{
return 0;
}
-static inline int pmd_free_pte_page(pmd_t *pmd)
+static inline int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
{
return 0;
}
diff --git a/lib/ioremap.c b/lib/ioremap.c
index 54e5bbaa3200..517f5853ffed 100644
--- a/lib/ioremap.c
+++ b/lib/ioremap.c
@@ -92,7 +92,7 @@ static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
if (ioremap_pmd_enabled() &&
((next - addr) == PMD_SIZE) &&
IS_ALIGNED(phys_addr + addr, PMD_SIZE) &&
- pmd_free_pte_page(pmd)) {
+ pmd_free_pte_page(pmd, addr)) {
if (pmd_set_huge(pmd, phys_addr + addr, prot))
continue;
}
@@ -119,7 +119,7 @@ static inline int ioremap_pud_range(p4d_t *p4d, unsigned long addr,
if (ioremap_pud_enabled() &&
((next - addr) == PUD_SIZE) &&
IS_ALIGNED(phys_addr + addr, PUD_SIZE) &&
- pud_free_pmd_page(pud)) {
+ pud_free_pmd_page(pud, addr)) {
if (pud_set_huge(pud, phys_addr + addr, prot))
continue;
}
^ permalink raw reply related
* [PROBLEM] orion5x: Kernel boot panic at of_clk_get()/orion_mdio_probe() on a non DT box on linux-4.16.7
From: Joao Cardoso @ 2018-05-17 15:49 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
On a DNS-323-rev-B1 D-Link NAS box, with a Marvell MV88F5182-A2 SoC,
linux-4.16.7 configured for a multi-platform armv5 Marvell Orion without
device tree, panics on of_clk_get() called from orion_mdio_probe().
If MV643XX_ETH and MVMDIO are not configured and build, the kernel boots
fine and userland works, obviously without ethernet.
I can also test proposed patches on a DNS-323-rev-A1 box (MV88F5181-B1).
This problem exibits also on linux-4.14.39, and know working
configurations are linux-4.4.131 and linux-4.9.98.
linux-4.4.86 is being used on Alt-F, a free alternative firmware for the
DLINK DNS-320/320L/321/323/325/327L [1]
The DNS-323 has three hardware revision levels boards, probed, and has
not a DT capable u-boot.
Any hope, patches or suggestions?
Thanks
Jo?o
[1]-https://sourceforge.net/projects/alt-f/
...
libphy: Fixed MDIO Bus: probed
Unable to handle kernel NULL pointer dereference at virtual address 0000000c
pgd = (ptrval)
[0000000c] *pgd=00000000
Internal error: Oops: 5 [#1] ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper Tainted: G??????? W??????? 4.16.7 #5
Hardware name: D-Link DNS-323
PC is at of_clk_get+0x14/0x60
LR is at orion_mdio_probe+0x110/0x2c4
pc : [<c022e528>]??? lr : [<c02bbb08>]??? psr: 60000053
sp : c3819c50? ip : c3819cb8? fp : c3819cb4
r10: c0548998? r9 : c0548aa0? r8 : c0548988
r7 : c0905280? r6 : c0905000? r5 : 00000000? r4 : 00000000
r3 : c08fece0? r2 : c057bb08? r1 : 00000000? r0 : 00000000
Flags: nZCv? IRQs on? FIQs off? Mode SVC_32? ISA ARM? Segment user
Control: a005317f? Table: 00004000? DAC: 00000055
Process swapper (pid: 1, stack limit = 0x(ptrval))
Stack: (0xc3819c50 to 0xc381a000)
9c40:???????????????????????????????????? c0548aa0 c0548998 c3819c84
c3819c68
9c60: c0012108 c0011e68 c01fca1c c0548998 c08fecd0 f1072004 c08fecc0
c08fecc0
9c80: c08fecd0 fe072004 c3819cb4 c3819c98 c01fca34 c025a2ac 00000000
c0548998
9ca0: 00000000 00000000 c3819cf4 c3819cb8 c02bbb08 c022e524 00000000
c0548998
9cc0: 00000000 c05489a0 c055bbcc c055bbb8 c0548998 00000000 c055bbcc
c0579884
9ce0: c0510798 00000000 c3819d0c c3819cf8 c02590e0 c02bba08 c0548998
00000000
9d00: c3819d44 c3819d10 c02578d4 c02590ac c3819d2c c3819d20 c0548a58
00000000
9d20: c0548998 c05489cc c055bbcc c055bbcc c0569210 00000000 c3819d64
c3819d48
9d40: c0257ad0 c0257768 00000000 00000000 c3819d68 c0257a44 c3819d8c
c3819d68
9d60: c0255ec4 c0257a54 c3833f6c c38375f0 c08fb980 c055bbcc 00000000
c0558a70
9d80: c3819d9c c3819d90 c02574e4 c0255e7c c3819dc4 c3819da0 c02565f4
c02574d4
9da0: c04a8b67 c3819db0 c055bbcc c0545480 00000007 c052ad98 c3819ddc
c3819dc8
9dc0: c0257fbc c025652c c3819e08 c0545480 c3819dec c3819de0 c0258f34
c0257f24
9de0: c3819dfc c3819df0 c052adb0 c0258f0c c3819f54 c3819e00 c000a474
c052ada8
9e00: c3819e6c c3819e10 00000000 c04096fc 00000001 00000000 00000000
00000000
9e20: 00000001 00000001 00000000 c380a000 014000c0 c3836c80 0fffffff
c380a000
9e40: c3819e6c c0553a34 20000053 0fffffff 00000000 014000c0 00000000
c3819e74
9e60: c3819e9c c3819e70 c040578c c040542c 014080c0 00000094 c3836ca0
c3836c80
9e80: c3837da0 c05726e4 00000000 00000000 c3819eb4 c3819ea0 c01030e4
00000000
9ea0: c3836c80 00000003 c3819ee4 c3819eb8 c01031ac 60000053 c3819ee8
00000000
9ec0: 00000003 c054b86c 00000000 00000000 c3819f04 c3819ee0 c04021cc
c0412698
9ee0: c3819f04 c3819ef0 c0030000 c041274c c050ec3c c050ec3c c3819f54
c3819f08
9f00: c00305d0 c05107a8 00000006 00000006 0000005d c050e4f8 20000053
c3ffce60
9f20: 00000000 c3ffce56 00000000 c0545480 c053f440 c0536048 00000007
0000005d
9f40: c0569210 00000000 c3819f94 c3819f58 c05106bc c000a364 00000006
00000006
9f60: 00000000 c0510798 00000000 00000000 c0417220 00000000 00000000
00000000
9f80: 00000000 00000000 c3819fac c3819f98 c0417234 c05105d0 00000000
00000000
9fa0: 00000000 c3819fb0 c00090d0 c0417230 00000000 00000000 00000000
00000000
9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000
9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000
00000000
Backtrace:
[<c022e514>] (of_clk_get) from [<c02bbb08>] (orion_mdio_probe+0x110/0x2c4)
?r5:00000000 r4:00000000
[<c02bb9f8>] (orion_mdio_probe) from [<c02590e0>]
(platform_drv_probe+0x44/0x74)
?r10:00000000 r9:c0510798 r8:c0579884 r7:c055bbcc r6:00000000 r5:c0548998
?r4:c055bbb8
[<c025909c>] (platform_drv_probe) from [<c02578d4>]
(driver_probe_device+0x17c/0x2ec)
?r5:00000000 r4:c0548998
[<c0257758>] (driver_probe_device) from [<c0257ad0>]
(__driver_attach+0x8c/0xb0)
?r10:00000000 r8:c0569210 r7:c055bbcc r6:c055bbcc r5:c05489cc r4:c0548998
[<c0257a44>] (__driver_attach) from [<c0255ec4>]
(bus_for_each_dev+0x58/0xa0)
?r6:c0257a44 r5:c3819d68 r4:00000000
[<c0255e6c>] (bus_for_each_dev) from [<c02574e4>] (driver_attach+0x20/0x28)
?r7:c0558a70 r6:00000000 r5:c055bbcc r4:c08fb980
[<c02574c4>] (driver_attach) from [<c02565f4>] (bus_add_driver+0xd8/0x1ec)
[<c025651c>] (bus_add_driver) from [<c0257fbc>] (driver_register+0xa8/0xec)
?r7:c052ad98 r6:00000007 r5:c0545480 r4:c055bbcc
[<c0257f14>] (driver_register) from [<c0258f34>]
(__platform_driver_register+0x38/0x4c)
?r5:c0545480 r4:c3819e08
[<c0258efc>] (__platform_driver_register) from [<c052adb0>]
(orion_mdio_driver_init+0x18/0x20)
[<c052ad98>] (orion_mdio_driver_init) from [<c000a474>]
(do_one_initcall+0x120/0x1e0)
[<c000a354>] (do_one_initcall) from [<c05106bc>]
(kernel_init_freeable+0xfc/0x1d8)
?r10:00000000 r8:c0569210 r7:0000005d r6:00000007 r5:c0536048 r4:c053f440
[<c05105c0>] (kernel_init_freeable) from [<c0417234>]
(kernel_init+0x14/0x104)
?r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0417220
?r4:00000000
[<c0417220>] (kernel_init) from [<c00090d0>] (ret_from_fork+0x14/0x24)
Exception stack(0xc3819fb0 to 0xc3819ff8)
9fa0:???????????????????????????????????? 00000000 00000000 00000000
00000000
9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000
9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
?r4:00000000
Code: e92dd830 e24cb004 e24dd050 e3510000 (e590500c)
---[ end trace d7e19ee84cbea244 ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
---[ end Kernel panic - not syncing: Attempted to kill init!
exitcode=0x0000000b
random: fast init done
--------------------------------------------------------------------------------------------------------------------------------------
The full log:
kexec_core: Starting new kernel
Bye!
Booting Linux on physical CPU 0x0
Linux version 4.16.7 (jcard at silver) (gcc version 4.3.3 (GCC)) #5 Tue May
15 15:13:18 WEST 2018
CPU: Feroceon [41069260] revision 0 (ARMv5TEJ), cr=a005317f
CPU: VIVT data cache, VIVT instruction cache
Machine: D-Link DNS-323
Ignoring unrecognised tag 0x41000403
bootconsole [earlycon0] enabled
Memory policy: Data cache writeback
Built 1 zonelists, mobility grouping on.? Total pages: 16256
Kernel command line: console=ttyS0,115200 root=/dev/ram0 init=/init
earlyprintk console=ttyS0,115200 root=/dev/ram0 init=/init earlyprintk
kexecmode
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 53012K/65536K available (4177K kernel code, 164K rwdata, 968K
rodata, 192K init, 91K bss, 12524K reserved, 0K cma-reserved)
Virtual kernel memory layout:
??? vector? : 0xffff0000 - 0xffff1000?? (?? 4 kB)
??? fixmap? : 0xffc00000 - 0xfff00000?? (3072 kB)
??? vmalloc : 0xc4800000 - 0xff800000?? ( 944 MB)
??? lowmem? : 0xc0000000 - 0xc4000000?? (? 64 MB)
??? modules : 0xbf000000 - 0xc0000000?? (? 16 MB)
????? .text : 0x(ptrval) - 0x(ptrval)?? (4178 kB)
????? .init : 0x(ptrval) - 0x(ptrval)?? ( 192 kB)
????? .data : 0x(ptrval) - 0x(ptrval)?? ( 165 kB)
?????? .bss : 0x(ptrval) - 0x(ptrval)?? (? 92 kB)
NR_IRQS: 16, nr_irqs: 65, preallocated irqs: 65
Switching to timer-based delay loop, resolution 6ns
sched_clock: 32 bits at 166MHz, resolution 6ns, wraps every 12884901885ns
clocksource: orion_clocksource: mask: 0xffffffff max_cycles: 0xffffffff,
max_idle_ns: 11467562657 ns
Calibrating delay loop (skipped), value calculated using timer
frequency.. 333.33 BogoMIPS (lpj=1666666)
pid_max: default: 4096 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
CPU: Testing write buffer coherency: ok
Setting up static identity map for 0x8200 - 0x823c
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff,
max_idle_ns: 19112604462750000 ns
futex hash table entries: 16 (order: -5, 192 bytes)
xor: measuring software checksum speed
?? arm4regs? :?? 386.000 MB/sec
?? 8regs???? :?? 336.000 MB/sec
?? 32regs??? :?? 302.800 MB/sec
xor: using function: arm4regs (386.000 MB/sec)
pinctrl core: initialized pinctrl subsystem
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
Orion ID: MV88F5182-A2. TCLK=166666667.
DNS-323: Identified HW revision B1
?00000003
?55550000
?03ff0000
?00000003
?55550000
?03ff0000
DNS-323: Found ethernet MAC address: 00:80:5a:53:1c:38
raid6: int32x1? gen()??? 20 MB/s
raid6: int32x1? xor()??? 38 MB/s
raid6: int32x2? gen()??? 30 MB/s
raid6: int32x2? xor()??? 39 MB/s
raid6: int32x4? gen()??? 39 MB/s
raid6: int32x4? xor()??? 33 MB/s
raid6: int32x8? gen()??? 34 MB/s
raid6: int32x8? xor()??? 24 MB/s
raid6: using algorithm int32x4 gen() 39 MB/s
raid6: .... xor() 33 MB/s, rmw enabled
raid6: using intx1 recovery algorithm
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
clocksource: Switched to clocksource orion_clocksource
VFS: Disk quotas dquot_6.6.0
VFS: Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
NET: Registered protocol family 2
tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 0, 4096 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
Trying to unpack rootfs image as initramfs...
rootfs image is not initramfs (junk in compressed archive); looks like
an initrd
Freeing initrd memory: 6292K
Initialise system trusted keyrings
workingset: timestamp_bits=30 max_order=14 bucket_order=0
squashfs: version 4.0 (2009/01/31) Phillip Lougher
aufs 4.16-20180409
async_tx: api initialized (async)
Key type asymmetric registered
Asymmetric key parser 'x509' registered
io scheduler noop registered
io scheduler cfq registered (default)
io scheduler mq-deadline registered
io scheduler kyber registered
Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
console [ttyS0] disabled
serial8250.0: ttyS0 at MMIO 0xf1012000 (irq = 4, base_baud = 10416666)
is a 16550A
console [ttyS0] enabled
console [ttyS0] enabled
bootconsole [earlycon0] disabled
bootconsole [earlycon0] disabled
brd: module loaded
loop: module loaded
sata_mv sata_mv.0: cannot get optional clkdev
sata_mv sata_mv.0: slots 32 ports 2
scsi host0: sata_mv
scsi host1: sata_mv
ata1: SATA max UDMA/133 irq 30
ata2: SATA max UDMA/133 irq 30
physmap platform flash device: 00800000 at f4000000
physmap-flash.0: Found 1 x16 devices at 0x0 in 8-bit bank. Manufacturer
ID 0x000001 Chip ID 0x001000
Amd/Fujitsu Extended Query Table at 0x0040
? Amd/Fujitsu Extended Query version 1.3.
number of CFI chips: 1
Creating 5 MTD partitions on "physmap-flash.0":
0x000000000000-0x000000010000 : "MTD1"
0x000000010000-0x000000020000 : "MTD2"
0x000000020000-0x0000001a0000 : "Linux Kernel"
0x0000001a0000-0x0000007d0000 : "File System"
0x0000007d0000-0x000000800000 : "u-boot"
libphy: Fixed MDIO Bus: probed
Unable to handle kernel NULL pointer dereference at virtual address 0000000c
pgd = (ptrval)
[0000000c] *pgd=00000000
Internal error: Oops: 5 [#1] ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper Tainted: G??????? W??????? 4.16.7 #5
Hardware name: D-Link DNS-323
PC is at of_clk_get+0x14/0x60
LR is at orion_mdio_probe+0x110/0x2c4
pc : [<c022e528>]??? lr : [<c02bbb08>]??? psr: 60000053
sp : c3819c50? ip : c3819cb8? fp : c3819cb4
r10: c0548998? r9 : c0548aa0? r8 : c0548988
r7 : c0905280? r6 : c0905000? r5 : 00000000? r4 : 00000000
r3 : c08fece0? r2 : c057bb08? r1 : 00000000? r0 : 00000000
Flags: nZCv? IRQs on? FIQs off? Mode SVC_32? ISA ARM? Segment user
Control: a005317f? Table: 00004000? DAC: 00000055
Process swapper (pid: 1, stack limit = 0x(ptrval))
Stack: (0xc3819c50 to 0xc381a000)
9c40:???????????????????????????????????? c0548aa0 c0548998 c3819c84
c3819c68
9c60: c0012108 c0011e68 c01fca1c c0548998 c08fecd0 f1072004 c08fecc0
c08fecc0
9c80: c08fecd0 fe072004 c3819cb4 c3819c98 c01fca34 c025a2ac 00000000
c0548998
9ca0: 00000000 00000000 c3819cf4 c3819cb8 c02bbb08 c022e524 00000000
c0548998
9cc0: 00000000 c05489a0 c055bbcc c055bbb8 c0548998 00000000 c055bbcc
c0579884
9ce0: c0510798 00000000 c3819d0c c3819cf8 c02590e0 c02bba08 c0548998
00000000
9d00: c3819d44 c3819d10 c02578d4 c02590ac c3819d2c c3819d20 c0548a58
00000000
9d20: c0548998 c05489cc c055bbcc c055bbcc c0569210 00000000 c3819d64
c3819d48
9d40: c0257ad0 c0257768 00000000 00000000 c3819d68 c0257a44 c3819d8c
c3819d68
9d60: c0255ec4 c0257a54 c3833f6c c38375f0 c08fb980 c055bbcc 00000000
c0558a70
9d80: c3819d9c c3819d90 c02574e4 c0255e7c c3819dc4 c3819da0 c02565f4
c02574d4
9da0: c04a8b67 c3819db0 c055bbcc c0545480 00000007 c052ad98 c3819ddc
c3819dc8
9dc0: c0257fbc c025652c c3819e08 c0545480 c3819dec c3819de0 c0258f34
c0257f24
9de0: c3819dfc c3819df0 c052adb0 c0258f0c c3819f54 c3819e00 c000a474
c052ada8
9e00: c3819e6c c3819e10 00000000 c04096fc 00000001 00000000 00000000
00000000
9e20: 00000001 00000001 00000000 c380a000 014000c0 c3836c80 0fffffff
c380a000
9e40: c3819e6c c0553a34 20000053 0fffffff 00000000 014000c0 00000000
c3819e74
9e60: c3819e9c c3819e70 c040578c c040542c 014080c0 00000094 c3836ca0
c3836c80
9e80: c3837da0 c05726e4 00000000 00000000 c3819eb4 c3819ea0 c01030e4
00000000
9ea0: c3836c80 00000003 c3819ee4 c3819eb8 c01031ac 60000053 c3819ee8
00000000
9ec0: 00000003 c054b86c 00000000 00000000 c3819f04 c3819ee0 c04021cc
c0412698
9ee0: c3819f04 c3819ef0 c0030000 c041274c c050ec3c c050ec3c c3819f54
c3819f08
9f00: c00305d0 c05107a8 00000006 00000006 0000005d c050e4f8 20000053
c3ffce60
9f20: 00000000 c3ffce56 00000000 c0545480 c053f440 c0536048 00000007
0000005d
9f40: c0569210 00000000 c3819f94 c3819f58 c05106bc c000a364 00000006
00000006
9f60: 00000000 c0510798 00000000 00000000 c0417220 00000000 00000000
00000000
9f80: 00000000 00000000 c3819fac c3819f98 c0417234 c05105d0 00000000
00000000
9fa0: 00000000 c3819fb0 c00090d0 c0417230 00000000 00000000 00000000
00000000
9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000
9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000
00000000
Backtrace:
[<c022e514>] (of_clk_get) from [<c02bbb08>] (orion_mdio_probe+0x110/0x2c4)
?r5:00000000 r4:00000000
[<c02bb9f8>] (orion_mdio_probe) from [<c02590e0>]
(platform_drv_probe+0x44/0x74)
?r10:00000000 r9:c0510798 r8:c0579884 r7:c055bbcc r6:00000000 r5:c0548998
?r4:c055bbb8
[<c025909c>] (platform_drv_probe) from [<c02578d4>]
(driver_probe_device+0x17c/0x2ec)
?r5:00000000 r4:c0548998
[<c0257758>] (driver_probe_device) from [<c0257ad0>]
(__driver_attach+0x8c/0xb0)
?r10:00000000 r8:c0569210 r7:c055bbcc r6:c055bbcc r5:c05489cc r4:c0548998
[<c0257a44>] (__driver_attach) from [<c0255ec4>]
(bus_for_each_dev+0x58/0xa0)
?r6:c0257a44 r5:c3819d68 r4:00000000
[<c0255e6c>] (bus_for_each_dev) from [<c02574e4>] (driver_attach+0x20/0x28)
?r7:c0558a70 r6:00000000 r5:c055bbcc r4:c08fb980
[<c02574c4>] (driver_attach) from [<c02565f4>] (bus_add_driver+0xd8/0x1ec)
[<c025651c>] (bus_add_driver) from [<c0257fbc>] (driver_register+0xa8/0xec)
?r7:c052ad98 r6:00000007 r5:c0545480 r4:c055bbcc
[<c0257f14>] (driver_register) from [<c0258f34>]
(__platform_driver_register+0x38/0x4c)
?r5:c0545480 r4:c3819e08
[<c0258efc>] (__platform_driver_register) from [<c052adb0>]
(orion_mdio_driver_init+0x18/0x20)
[<c052ad98>] (orion_mdio_driver_init) from [<c000a474>]
(do_one_initcall+0x120/0x1e0)
[<c000a354>] (do_one_initcall) from [<c05106bc>]
(kernel_init_freeable+0xfc/0x1d8)
?r10:00000000 r8:c0569210 r7:0000005d r6:00000007 r5:c0536048 r4:c053f440
[<c05105c0>] (kernel_init_freeable) from [<c0417234>]
(kernel_init+0x14/0x104)
?r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0417220
?r4:00000000
[<c0417220>] (kernel_init) from [<c00090d0>] (ret_from_fork+0x14/0x24)
Exception stack(0xc3819fb0 to 0xc3819ff8)
9fa0:???????????????????????????????????? 00000000 00000000 00000000
00000000
9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000
9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
?r4:00000000
Code: e92dd830 e24cb004 e24dd050 e3510000 (e590500c)
---[ end trace d7e19ee84cbea244 ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
---[ end Kernel panic - not syncing: Attempted to kill init!
exitcode=0x0000000b
random: fast init done
--------------------------------------------------------------------------------------------------------------------------------------
The config:
CONFIG_ARM=y
CONFIG_ARM_HAS_SG_CHAIN=y
CONFIG_MIGHT_HAVE_PCI=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_ARM_PATCH_PHYS_VIRT=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
CONFIG_LOCALVERSION=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_KERNEL_XZ=y
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_USELIB=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_ARCH_CLOCKSOURCE_DATA=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TINY_RCU=y
CONFIG_SRCU=y
CONFIG_TINY_SRCU=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_XZ=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_HAVE_UID16=y
CONFIG_BPF=y
CONFIG_EXPERT=y
CONFIG_MULTIUSER=y
CONFIG_SYSFS_SYSCALL=y
CONFIG_POSIX_TIMERS=y
CONFIG_PRINTK=y
CONFIG_PRINTK_NMI=y
CONFIG_FUTEX=y
CONFIG_FUTEX_PI=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_MEMBARRIER=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_BASE_RELATIVE=y
CONFIG_EMBEDDED=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
CONFIG_SLAB_MERGE_DEFAULT=y
CONFIG_SYSTEM_DATA_VERIFICATION=y
CONFIG_CRASH_CORE=y
CONFIG_KEXEC_CORE=y
CONFIG_HAVE_OPROFILE=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_NMI=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_ARCH_HAS_SET_MEMORY=y
CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_GCC_PLUGINS=y
CONFIG_HAVE_CC_STACKPROTECTOR=y
CONFIG_CC_STACKPROTECTOR_NONE=y
CONFIG_THIN_ARCHIVES=y
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
CONFIG_HAVE_EXIT_THREAD=y
CONFIG_ARCH_MMAP_RND_BITS_MIN=8
CONFIG_ARCH_MMAP_RND_BITS_MAX=16
CONFIG_ARCH_MMAP_RND_BITS=8
CONFIG_CLONE_BACKWARDS=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OLD_SIGACTION=y
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
CONFIG_ARCH_HAS_PHYS_TO_DMA=y
CONFIG_REFCOUNT_FULL=y
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=1
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_BLOCK=y
CONFIG_LBDAF=y
CONFIG_BLK_SCSI_REQUEST=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_MSDOS_PARTITION=y
CONFIG_EFI_PARTITION=y
CONFIG_BLK_MQ_PCI=y
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_MQ_IOSCHED_DEADLINE=y
CONFIG_MQ_IOSCHED_KYBER=y
CONFIG_ASN1=y
CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
CONFIG_INLINE_READ_UNLOCK=y
CONFIG_INLINE_READ_UNLOCK_IRQ=y
CONFIG_INLINE_WRITE_UNLOCK=y
CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_MMU=y
CONFIG_ARCH_MULTIPLATFORM=y
CONFIG_ARCH_MULTI_V5=y
CONFIG_ARCH_MULTI_V4_V5=y
CONFIG_ARCH_MULTI_CPU_AUTO=y
CONFIG_ARCH_MVEBU=y
CONFIG_ARCH_ORION5X=y
CONFIG_MACH_DNS323=y
CONFIG_PLAT_ORION=y
CONFIG_PLAT_ORION_LEGACY=y
CONFIG_CPU_FEROCEON=y
CONFIG_CPU_FEROCEON_OLD_ID=y
CONFIG_CPU_THUMB_CAPABLE=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
CONFIG_CPU_PABRT_LEGACY=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_FEROCEON=y
CONFIG_CPU_TLB_FEROCEON=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
CONFIG_CPU_USE_DOMAINS=y
CONFIG_NEED_KUSER_HELPERS=y
CONFIG_KUSER_HELPERS=y
CONFIG_OUTER_CACHE=y
CONFIG_CACHE_FEROCEON_L2=y
CONFIG_ARM_L1_CACHE_SHIFT=5
CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
CONFIG_MULTI_IRQ_HANDLER=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_SYSCALL=y
CONFIG_PCI_QUIRKS=y
CONFIG_VMSPLIT_3G=y
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_ARCH_NR_GPIO=0
CONFIG_PREEMPT_NONE=y
CONFIG_HZ_FIXED=0
CONFIG_HZ_100=y
CONFIG_HZ=100
CONFIG_SCHED_HRTICK=y
CONFIG_AEABI=y
CONFIG_HAVE_ARCH_PFN_VALID=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_NO_BOOTMEM=y
CONFIG_SPLIT_PTLOCK_CPUS=999999
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_NEED_PER_CPU_KM=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_ALIGNMENT_TRAP=y
CONFIG_UACCESS_WITH_MEMCPY=y
CONFIG_SWIOTLB=y
CONFIG_IOMMU_HELPER=y
CONFIG_USE_OF=y
CONFIG_ATAGS=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 init=/init earlyprintk"
CONFIG_CMDLINE_EXTEND=y
CONFIG_KEXEC=y
CONFIG_ATAGS_PROC=y
CONFIG_AUTO_ZRELADDR=y
CONFIG_BINFMT_ELF=y
CONFIG_ELFCORE=y
CONFIG_BINFMT_SCRIPT=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_NET=y
CONFIG_NET_INGRESS=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_ALGO=m
CONFIG_XFRM_IPCOMP=m
CONFIG_NET_KEY=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_NET_IP_TUNNEL=m
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_XFRM_TUNNEL=m
CONFIG_INET_TUNNEL=m
CONFIG_INET_XFRM_MODE_TRANSPORT=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_INET_XFRM_MODE_BEET=m
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
CONFIG_IPV6=m
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
CONFIG_INET6_XFRM_TUNNEL=m
CONFIG_INET6_TUNNEL=m
CONFIG_INET6_XFRM_MODE_TRANSPORT=m
CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_MODE_BEET=m
CONFIG_IPV6_SIT=m
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_NETFILTER=y
CONFIG_NETFILTER_INGRESS=y
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NF_CONNTRACK=m
CONFIG_NF_LOG_COMMON=m
CONFIG_NF_CONNTRACK_PROCFS=y
CONFIG_NF_CONNTRACK_FTP=m
CONFIG_NF_CONNTRACK_IRC=m
CONFIG_NF_CONNTRACK_BROADCAST=m
CONFIG_NF_CONNTRACK_NETBIOS_NS=m
CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CT_NETLINK=m
CONFIG_NF_NAT=m
CONFIG_NF_NAT_NEEDED=y
CONFIG_NF_NAT_FTP=m
CONFIG_NF_NAT_IRC=m
CONFIG_NF_NAT_SIP=m
CONFIG_NF_NAT_REDIRECT=m
CONFIG_NETFILTER_XTABLES=m
CONFIG_NETFILTER_XT_MARK=m
CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_NAT=m
CONFIG_NETFILTER_XT_TARGET_NETMAP=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_REDIRECT=m
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
CONFIG_NETFILTER_XT_MATCH_POLICY=m
CONFIG_NETFILTER_XT_MATCH_STATE=m
CONFIG_NF_DEFRAG_IPV4=m
CONFIG_NF_CONNTRACK_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_NF_REJECT_IPV4=m
CONFIG_NF_NAT_IPV4=m
CONFIG_NF_NAT_MASQUERADE_IPV4=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_MANGLE=m
CONFIG_NF_DEFRAG_IPV6=m
CONFIG_NF_CONNTRACK_IPV6=m
CONFIG_NF_REJECT_IPV6=m
CONFIG_NF_LOG_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_STP=m
CONFIG_BRIDGE=m
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_HAVE_NET_DSA=y
CONFIG_VLAN_8021Q=m
CONFIG_LLC=m
CONFIG_ATALK=m
CONFIG_NET_RX_BUSY_POLL=y
CONFIG_BQL=y
CONFIG_WIRELESS=y
CONFIG_WIRELESS_EXT=y
CONFIG_WEXT_CORE=y
CONFIG_WEXT_PROC=y
CONFIG_WEXT_SPY=y
CONFIG_WEXT_PRIV=y
CONFIG_CFG80211=m
CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y
CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y
CONFIG_CFG80211_DEFAULT_PS=y
CONFIG_CFG80211_CRDA_SUPPORT=y
CONFIG_CFG80211_WEXT=y
CONFIG_CFG80211_WEXT_EXPORT=y
CONFIG_LIB80211=m
CONFIG_LIB80211_CRYPT_WEP=m
CONFIG_LIB80211_CRYPT_CCMP=m
CONFIG_LIB80211_CRYPT_TKIP=m
CONFIG_MAC80211=m
CONFIG_MAC80211_HAS_RC=y
CONFIG_MAC80211_RC_MINSTREL=y
CONFIG_MAC80211_RC_MINSTREL_HT=y
CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
CONFIG_MAC80211_LEDS=y
CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
CONFIG_DST_CACHE=y
CONFIG_GRO_CELLS=y
CONFIG_MAY_USE_DEVLINK=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_UEVENT_HELPER=y
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=m
CONFIG_EXTRA_FIRMWARE=""
CONFIG_WANT_DEV_COREDUMP=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_SOC_BUS=y
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_MMIO=y
CONFIG_MVEBU_MBUS=y
CONFIG_MTD=y
CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_GEN_PROBE=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_NOSWAP=y
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_PHYSMAP=y
CONFIG_DTC=y
CONFIG_OF=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_KOBJ=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_NET=y
CONFIG_OF_MDIO=y
CONFIG_OF_RESERVED_MEM=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=2
CONFIG_BLK_DEV_RAM_SIZE=16384
CONFIG_SRAM=y
CONFIG_SRAM_EXEC=y
CONFIG_EEPROM_93CX6=m
CONFIG_HAVE_IDE=y
CONFIG_SCSI_MOD=y
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_ATA=y
CONFIG_SATA_PMP=y
CONFIG_ATA_SFF=y
CONFIG_ATA_BMDMA=y
CONFIG_SATA_MV=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_MD_RAID456=y
CONFIG_BLK_DEV_DM_BUILTIN=y
CONFIG_BLK_DEV_DM=m
CONFIG_DM_BUFIO=m
CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
CONFIG_NETDEVICES=y
CONFIG_MII=m
CONFIG_NET_CORE=y
CONFIG_TUN=m
CONFIG_ETHERNET=y
CONFIG_NET_VENDOR_MARVELL=y
CONFIG_MV643XX_ETH=y
CONFIG_MVMDIO=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_BUS=y
CONFIG_PHYLIB=y
CONFIG_SWPHY=y
CONFIG_FIXED_PHY=y
CONFIG_PPP=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_MPPE=m
CONFIG_PPPOE=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_SLHC=m
CONFIG_USB_NET_DRIVERS=m
CONFIG_USB_USBNET=m
CONFIG_USB_NET_AX8817X=m
CONFIG_USB_NET_AX88179_178A=m
CONFIG_USB_NET_CDCETHER=m
CONFIG_USB_NET_CDC_NCM=m
CONFIG_USB_NET_NET1080=m
CONFIG_USB_NET_RNDIS_HOST=m
CONFIG_USB_NET_CDC_SUBSET_ENABLE=m
CONFIG_USB_NET_CDC_SUBSET=m
CONFIG_USB_BELKIN=y
CONFIG_USB_ARMLINUX=y
CONFIG_USB_NET_ZAURUS=m
CONFIG_WLAN=y
CONFIG_WLAN_VENDOR_ADMTEK=y
CONFIG_ATH_COMMON=m
CONFIG_WLAN_VENDOR_ATH=y
CONFIG_CARL9170=m
CONFIG_CARL9170_LEDS=y
CONFIG_CARL9170_WPC=y
CONFIG_ATH6KL=m
CONFIG_ATH6KL_USB=m
CONFIG_AR5523=m
CONFIG_ATH10K=m
CONFIG_WLAN_VENDOR_ATMEL=y
CONFIG_AT76C50X_USB=m
CONFIG_WLAN_VENDOR_BROADCOM=y
CONFIG_BRCMUTIL=m
CONFIG_BRCMFMAC=m
CONFIG_BRCMFMAC_PROTO_BCDC=y
CONFIG_BRCMFMAC_USB=y
CONFIG_WLAN_VENDOR_CISCO=y
CONFIG_WLAN_VENDOR_INTEL=y
CONFIG_WLAN_VENDOR_INTERSIL=y
CONFIG_HOSTAP=m
CONFIG_HERMES=m
CONFIG_ORINOCO_USB=m
CONFIG_P54_COMMON=m
CONFIG_P54_USB=m
CONFIG_P54_LEDS=y
CONFIG_WLAN_VENDOR_MARVELL=y
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_USB=m
CONFIG_WLAN_VENDOR_MEDIATEK=y
CONFIG_MT7601U=m
CONFIG_WLAN_VENDOR_RALINK=y
CONFIG_RT2X00=m
CONFIG_RT2500USB=m
CONFIG_RT73USB=m
CONFIG_RT2800USB=m
CONFIG_RT2800USB_RT33XX=y
CONFIG_RT2800USB_RT35XX=y
CONFIG_RT2800_LIB=m
CONFIG_RT2X00_LIB_USB=m
CONFIG_RT2X00_LIB=m
CONFIG_RT2X00_LIB_FIRMWARE=y
CONFIG_RT2X00_LIB_CRYPTO=y
CONFIG_RT2X00_LIB_LEDS=y
CONFIG_WLAN_VENDOR_REALTEK=y
CONFIG_RTL8187=m
CONFIG_RTL8187_LEDS=y
CONFIG_RTL_CARDS=m
CONFIG_RTL8192CU=m
CONFIG_RTLWIFI=m
CONFIG_RTLWIFI_USB=m
CONFIG_RTL8192C_COMMON=m
CONFIG_WLAN_VENDOR_RSI=y
CONFIG_WLAN_VENDOR_ST=y
CONFIG_WLAN_VENDOR_TI=y
CONFIG_WLAN_VENDOR_ZYDAS=y
CONFIG_USB_ZD1201=m
CONFIG_ZD1211RW=m
CONFIG_WLAN_VENDOR_QUANTENNA=y
CONFIG_USB_NET_RNDIS_WLAN=m
CONFIG_INPUT=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_GPIO=y
CONFIG_TTY=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=8
CONFIG_DEVMEM=y
CONFIG_SERIAL_EARLYCON=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_HW_RANDOM=m
CONFIG_HW_RANDOM_OMAP=m
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_MV64XXX=y
CONFIG_PINCTRL=y
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_GPIOLIB=y
CONFIG_OF_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_MVEBU=y
CONFIG_HWMON=y
CONFIG_SENSORS_G760A=y
CONFIG_SENSORS_LM75=y
CONFIG_SSB_POSSIBLE=y
CONFIG_BCMA_POSSIBLE=y
CONFIG_SOUND=m
CONFIG_SOUND_OSS_CORE=y
CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
CONFIG_SND_HWDEP=m
CONFIG_SND_SEQ_DEVICE=m
CONFIG_SND_RAWMIDI=m
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_SEQUENCER=m
CONFIG_SND_SEQUENCER_OSS=m
CONFIG_SND_SEQ_MIDI_EVENT=m
CONFIG_SND_SEQ_MIDI=m
CONFIG_SND_DRIVERS=y
CONFIG_SND_DUMMY=m
CONFIG_SND_HDA_PREALLOC_SIZE=64
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=m
CONFIG_SND_USB_UA101=m
CONFIG_SND_USB_CAIAQ=m
CONFIG_HID=y
CONFIG_HID_GENERIC=y
CONFIG_USB_HID=y
CONFIG_USB_HIDDEV=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=y
CONFIG_USB_PCI=y
CONFIG_USB_DEFAULT_PERSIST=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_PCI=y
CONFIG_USB_EHCI_HCD_ORION=y
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m
CONFIG_USB_WDM=m
CONFIG_USB_STORAGE=m
CONFIG_USB_STORAGE_REALTEK=m
CONFIG_USB_STORAGE_DATAFAB=m
CONFIG_USB_STORAGE_FREECOM=m
CONFIG_USB_STORAGE_ISD200=m
CONFIG_USB_STORAGE_USBAT=m
CONFIG_USB_STORAGE_SDDR09=m
CONFIG_USB_STORAGE_SDDR55=m
CONFIG_USB_STORAGE_JUMPSHOT=m
CONFIG_USB_STORAGE_ALAUDA=m
CONFIG_USB_STORAGE_ONETOUCH=m
CONFIG_USB_STORAGE_KARMA=m
CONFIG_USB_STORAGE_CYPRESS_ATACB=m
CONFIG_USB_STORAGE_ENE_UB6250=m
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_AIRCABLE=m
CONFIG_USB_SERIAL_ARK3116=m
CONFIG_USB_SERIAL_BELKIN=m
CONFIG_USB_SERIAL_CH341=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
CONFIG_USB_SERIAL_CP210X=m
CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_VISOR=m
CONFIG_USB_SERIAL_IPAQ=m
CONFIG_USB_SERIAL_IR=m
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_EDGEPORT_TI=m
CONFIG_USB_SERIAL_F81232=m
CONFIG_USB_SERIAL_GARMIN=m
CONFIG_USB_SERIAL_IPW=m
CONFIG_USB_SERIAL_IUU=m
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_SERIAL_METRO=m
CONFIG_USB_SERIAL_MOS7720=m
CONFIG_USB_SERIAL_MOS7840=m
CONFIG_USB_SERIAL_MXUPORT=m
CONFIG_USB_SERIAL_NAVMAN=m
CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_SERIAL_OTI6858=m
CONFIG_USB_SERIAL_QCAUX=m
CONFIG_USB_SERIAL_QUALCOMM=m
CONFIG_USB_SERIAL_SPCP8X5=m
CONFIG_USB_SERIAL_SIERRAWIRELESS=m
CONFIG_USB_SERIAL_SYMBOL=m
CONFIG_USB_SERIAL_TI=m
CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_WWAN=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_SERIAL_OMNINET=m
CONFIG_USB_SERIAL_OPTICON=m
CONFIG_USB_SERIAL_XSENS_MT=m
CONFIG_USB_SERIAL_WISHBONE=m
CONFIG_USB_SERIAL_SSU100=m
CONFIG_USB_SERIAL_QT2=m
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_NVMEM=y
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_DRV_M41T80=y
CONFIG_RTC_I2C_AND_SPI=y
CONFIG_DMADEVICES=y
CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_OF=y
CONFIG_MV_XOR=y
CONFIG_ASYNC_TX_DMA=y
CONFIG_DMA_ENGINE_RAID=y
CONFIG_CLKDEV_LOOKUP=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_CLKSRC_MMIO=y
CONFIG_IRQCHIP=y
CONFIG_ARM_GIC_MAX_NR=1
CONFIG_GENERIC_PHY=y
CONFIG_DAX=y
CONFIG_NVMEM=y
CONFIG_FS_IOMAP=y
CONFIG_EXT2_FS=m
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_JBD2=y
CONFIG_FS_MBCACHE=y
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
CONFIG_XFS_FS=m
CONFIG_XFS_POSIX_ACL=y
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=m
CONFIG_FILE_LOCKING=y
CONFIG_MANDATORY_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QUOTA_TREE=m
CONFIG_QFMT_V2=m
CONFIG_QUOTACTL=y
CONFIG_FUSE_FS=m
CONFIG_OVERLAY_FS=m
CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_KERNFS=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TMPFS_XATTR=y
CONFIG_MISC_FILESYSTEMS=y
CONFIG_HFS_FS=m
CONFIG_HFSPLUS_FS=m
CONFIG_SQUASHFS=y
CONFIG_SQUASHFS_FILE_DIRECT=y
CONFIG_SQUASHFS_DECOMP_SINGLE=y
CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
CONFIG_MINIX_FS=y
CONFIG_AUFS_FS=y
CONFIG_AUFS_BRANCH_MAX_127=y
CONFIG_AUFS_SBILIST=y
CONFIG_AUFS_HNOTIFY=y
CONFIG_AUFS_HFSNOTIFY=y
CONFIG_AUFS_SHWH=y
CONFIG_AUFS_BDEV_LOOP=y
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=m
CONFIG_NFS_V2=m
CONFIG_NFS_V3=m
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
CONFIG_GRACE_PERIOD=m
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_CIFS=m
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=y
CONFIG_NLS_UTF8=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
CONFIG_FRAME_WARN=1024
CONFIG_STRIP_ASM_SYMS=y
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_KERNEL=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_PANIC_TIMEOUT=0
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_TRACING_SUPPORT=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
CONFIG_DEBUG_LL=y
CONFIG_DEBUG_LL_UART_8250=y
CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
CONFIG_DEBUG_UART_PHYS=0xf1012000
CONFIG_DEBUG_UART_VIRT=0xfe012000
CONFIG_DEBUG_UART_8250_SHIFT=2
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_EARLY_PRINTK=y
CONFIG_KEYS=y
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_DEFAULT_SECURITY=""
CONFIG_XOR_BLOCKS=y
CONFIG_ASYNC_CORE=y
CONFIG_ASYNC_MEMCPY=y
CONFIG_ASYNC_XOR=y
CONFIG_ASYNC_PQ=y
CONFIG_ASYNC_RAID6_RECOV=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=m
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=m
CONFIG_CRYPTO_AKCIPHER2=y
CONFIG_CRYPTO_AKCIPHER=y
CONFIG_CRYPTO_KPP2=y
CONFIG_CRYPTO_ACOMP2=y
CONFIG_CRYPTO_RSA=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
CONFIG_CRYPTO_GF128MUL=m
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_NULL2=y
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_AUTHENC=m
CONFIG_CRYPTO_CCM=m
CONFIG_CRYPTO_GCM=m
CONFIG_CRYPTO_SEQIV=m
CONFIG_CRYPTO_ECHAINIV=m
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_CTR=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_CMAC=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_GHASH=m
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_BLOWFISH_COMMON=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_CRYPTO_DRBG_MENU=m
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_HASH=y
CONFIG_CRYPTO_DRBG_CTR=y
CONFIG_CRYPTO_DRBG=m
CONFIG_CRYPTO_JITTERENTROPY=m
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_MARVELL_CESA=m
CONFIG_ASYMMETRIC_KEY_TYPE=y
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
CONFIG_X509_CERTIFICATE_PARSER=y
CONFIG_PKCS7_MESSAGE_PARSER=y
CONFIG_SYSTEM_TRUSTED_KEYRING=y
CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_RAID6_PQ=y
CONFIG_BITREVERSE=y
CONFIG_RATIONAL=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
CONFIG_CRC_CCITT=m
CONFIG_CRC16=y
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
CONFIG_CRC32_SLICEBY8=y
CONFIG_LIBCRC32C=y
CONFIG_XXHASH=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
CONFIG_LZO_COMPRESS=m
CONFIG_LZO_DECOMPRESS=m
CONFIG_ZSTD_COMPRESS=m
CONFIG_ZSTD_DECOMPRESS=m
CONFIG_XZ_DEC=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_ASSOCIATIVE_ARRAY=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAS_DMA=y
CONFIG_SGL_ALLOC=y
CONFIG_DQL=y
CONFIG_GLOB=y
CONFIG_NLATTR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_CLZ_TAB=y
CONFIG_MPILIB=y
CONFIG_LIBFDT=y
CONFIG_OID_REGISTRY=y
CONFIG_SG_POOL=y
CONFIG_ARCH_HAS_SG_CHAIN=y
CONFIG_SBITMAP=y
^ permalink raw reply
* [PATCH 2/2] ARM: dts: stm32: enable USB OTG HS on stm32mp157c-ev1
From: Amelie Delaunay @ 2018-05-17 15:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526572052-17155-1-git-send-email-amelie.delaunay@st.com>
This patch enables USB OTG HS on stm32mp157c-ev1 in Peripheral mode.
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
arch/arm/boot/dts/stm32mp157c-ev1.dts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/stm32mp157c-ev1.dts b/arch/arm/boot/dts/stm32mp157c-ev1.dts
index 9382d80..5a0b77e 100644
--- a/arch/arm/boot/dts/stm32mp157c-ev1.dts
+++ b/arch/arm/boot/dts/stm32mp157c-ev1.dts
@@ -103,6 +103,13 @@
};
};
+&usbotg_hs {
+ dr_mode = "peripheral";
+ phys = <&usbphyc_port1 0>;
+ phy-names = "usb2-phy";
+ status = "okay";
+};
+
&usbphyc {
status = "okay";
};
--
2.7.4
^ permalink raw reply related
* [PATCH 1/2] ARM: dts: stm32: add USB OTG HS support for stm32mp157c SoC
From: Amelie Delaunay @ 2018-05-17 15:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526572052-17155-1-git-send-email-amelie.delaunay@st.com>
This patch adds support for USB OTG HS on STM32MP157C SoC.
USB OTG HS controller is based on DWC2 controller.
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
arch/arm/boot/dts/stm32mp157c.dtsi | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/arm/boot/dts/stm32mp157c.dtsi b/arch/arm/boot/dts/stm32mp157c.dtsi
index b66f673..6c3815f 100644
--- a/arch/arm/boot/dts/stm32mp157c.dtsi
+++ b/arch/arm/boot/dts/stm32mp157c.dtsi
@@ -600,6 +600,21 @@
clocks = <&rcc DMAMUX>;
};
+ usbotg_hs: usb-otg at 49000000 {
+ compatible = "snps,dwc2";
+ reg = <0x49000000 0x10000>;
+ clocks = <&rcc USBO_K>;
+ clock-names = "otg";
+ resets = <&rcc USBO_R>;
+ reset-names = "dwc2";
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ g-rx-fifo-size = <256>;
+ g-np-tx-fifo-size = <32>;
+ g-tx-fifo-size = <128 128 64 64 64 64 32 32>;
+ dr_mode = "otg";
+ status = "disabled";
+ };
+
rcc: rcc at 50000000 {
compatible = "st,stm32mp1-rcc", "syscon";
reg = <0x50000000 0x1000>;
--
2.7.4
^ permalink raw reply related
* [PATCH 0/2] Add USB OTG HS support on stm32mp157c
From: Amelie Delaunay @ 2018-05-17 15:47 UTC (permalink / raw)
To: linux-arm-kernel
This patchset adds support for USB OTG HS on stm32mp157c SoC.
It also enables USB OTG HS on stm32mp157c-ev1 board in Peripheral mode.
Amelie Delaunay (2):
ARM: dts: stm32: add USB OTG HS support for stm32mp157c SoC
ARM: dts: stm32: enable USB OTG HS on stm32mp157c-ev1
arch/arm/boot/dts/stm32mp157c-ev1.dts | 7 +++++++
arch/arm/boot/dts/stm32mp157c.dtsi | 15 +++++++++++++++
2 files changed, 22 insertions(+)
--
2.7.4
^ permalink raw reply
* [PATCH v9 02/12] drivers: base: cacheinfo: setup DT cache properties early
From: Sudeep Holla @ 2018-05-17 15:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <a64ed431-0f60-2711-4138-eeefc7ba2d8b@arm.com>
On 16/05/18 11:56, Sudeep Holla wrote:
> Hi Andy,
>
> On 15/05/18 20:32, Andy Shevchenko wrote:
>> On Tue, May 15, 2018 at 8:15 PM, Jeremy Linton <jeremy.linton@arm.com> wrote:
>>> On 05/11/2018 06:57 PM, Jeremy Linton wrote:
>>
>>>> - cache_size = of_get_property(this_leaf->of_node, propname, NULL);
>>>> + cache_size = of_get_property(np, propname, NULL);
>>>> if (cache_size)
>>>> this_leaf->size = of_read_number(cache_size, 1);
>>
>> Can't you switch to of_read_property_uXX() variant here?
>>
>
> This patch is just changing the first argument to the calls. So if we
> need to change, it has to be separate patch.
>
> Now, we can use of_property_read_u64() but is there any particular
> reason you mention that ? One reason I can see is that we can avoid
> making explicit of_get_property call. Just wanted to the motive before I
> can write the patch.
>
Is below patch does what you were looking for ?
Regards,
Sudeep
--
>From 71f1c10ddb5915a92fa74d38a4e2406d0ab27845 Mon Sep 17 00:00:00 2001
From: Sudeep Holla <sudeep.holla@arm.com>
Date: Wed, 16 May 2018 13:45:53 +0100
Subject: [PATCH] drivers: base: cacheinfo: use OF property_read_u64 instead of
get_property,read_number
of_property_read_u64 searches for a property in a device node and read
a 64-bit value from it. Instead of using of_get_property to get the
property and then read 64-bit value using of_read_number, we can make
use of of_property_read_u64.
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
drivers/base/cacheinfo.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c
index 2880e2ab01f5..56715014f07b 100644
--- a/drivers/base/cacheinfo.c
+++ b/drivers/base/cacheinfo.c
@@ -74,22 +74,21 @@ static inline int get_cacheinfo_idx(enum cache_type type)
static void cache_size(struct cacheinfo *this_leaf, struct device_node *np)
{
const char *propname;
- const __be32 *cache_size;
+ u64 cache_size;
int ct_idx;
ct_idx = get_cacheinfo_idx(this_leaf->type);
propname = cache_type_info[ct_idx].size_prop;
- cache_size = of_get_property(np, propname, NULL);
- if (cache_size)
- this_leaf->size = of_read_number(cache_size, 1);
+ if (!of_property_read_u64(np, propname, &cache_size))
+ this_leaf->size = cache_size;
}
/* not cache_line_size() because that's a macro in include/linux/cache.h */
static void cache_get_line_size(struct cacheinfo *this_leaf,
struct device_node *np)
{
- const __be32 *line_size;
+ u64 line_size;
int i, lim, ct_idx;
ct_idx = get_cacheinfo_idx(this_leaf->type);
@@ -99,27 +98,26 @@ static void cache_get_line_size(struct cacheinfo *this_leaf,
const char *propname;
propname = cache_type_info[ct_idx].line_size_props[i];
- line_size = of_get_property(np, propname, NULL);
- if (line_size)
+ line_size = of_property_read_u64(np, propname, &line_size);
+ if (line_size) {
+ this_leaf->coherency_line_size = line_size;
break;
+ }
}
- if (line_size)
- this_leaf->coherency_line_size = of_read_number(line_size, 1);
}
static void cache_nr_sets(struct cacheinfo *this_leaf, struct device_node *np)
{
const char *propname;
- const __be32 *nr_sets;
+ u64 nr_sets;
int ct_idx;
ct_idx = get_cacheinfo_idx(this_leaf->type);
propname = cache_type_info[ct_idx].nr_sets_prop;
- nr_sets = of_get_property(np, propname, NULL);
- if (nr_sets)
- this_leaf->number_of_sets = of_read_number(nr_sets, 1);
+ if (!of_property_read_u64(np, propname, &nr_sets))
+ this_leaf->number_of_sets = nr_sets;
}
static void cache_associativity(struct cacheinfo *this_leaf)
--
2.7.4
^ permalink raw reply related
* [PATCH v3] arm64: signal: Report signal frame size to userspace via auxv
From: Dave Martin @ 2018-05-17 15:45 UTC (permalink / raw)
To: linux-arm-kernel
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().
For arm64 SVE:
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: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Alex Benn?e <alex.bennee@linaro.org>
---
Changes since v2:
* Redefine AT_MINSIGSTKSZ as 51 to avoid clash with values defined by
other architectures.
This turns out to be a problem for glibc; also random userspace
software does not necessary check the architecture before using
getauxval() or otherwise parsing the aux vector, which can make
aliased tags problematic.
Really, the headers need cleaning up tree-wide in such away that the
AT_* definitions do not appear to be arch-private. To be addressed
separately.
---
arch/arm64/include/asm/elf.h | 11 ++++++++
arch/arm64/include/asm/processor.h | 5 ++++
arch/arm64/include/uapi/asm/auxvec.h | 3 ++-
arch/arm64/kernel/cpufeature.c | 1 +
arch/arm64/kernel/signal.c | 51 +++++++++++++++++++++++++++++++-----
5 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index fac1c4d..dc32adb 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -24,6 +24,11 @@
#include <asm/ptrace.h>
#include <asm/user.h>
+#ifndef __ASSEMBLY__
+#include <linux/bug.h>
+#include <asm/processor.h> /* for signal_minsigstksz, used by ARCH_DLINFO */
+#endif
+
/*
* AArch64 static relocation types.
*/
@@ -146,8 +151,14 @@ typedef struct user_fpsimd_state elf_fpregset_t;
/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
#define ARCH_DLINFO \
do { \
+ int minsigstksz = signal_minsigstksz; \
+ \
+ if (WARN_ON(minsigstksz <= 0)) \
+ minsigstksz = MINSIGSTKSZ; \
+ \
NEW_AUX_ENT(AT_SYSINFO_EHDR, \
(elf_addr_t)current->mm->context.vdso); \
+ NEW_AUX_ENT(AT_MINSIGSTKSZ, 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..6f60e92 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -35,6 +35,8 @@
#ifdef __KERNEL__
#include <linux/build_bug.h>
+#include <linux/cache.h>
+#include <linux/init.h>
#include <linux/stddef.h>
#include <linux/string.h>
@@ -244,6 +246,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);
+extern int __ro_after_init signal_minsigstksz; /* user signal frame size */
+extern void __init minsigstksz_setup(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..743c0b8 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 51 /* 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/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 9d1b06d..0e0b53d 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1619,6 +1619,7 @@ void __init setup_cpu_features(void)
pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
sve_setup();
+ minsigstksz_setup();
/* Advertise that we have computed the system capabilities */
set_sys_caps_initialised();
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 154b7d3..ae8d4ea 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/cache.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)
@@ -591,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));
@@ -603,7 +621,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 +718,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 +953,23 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
thread_flags = READ_ONCE(current_thread_info()->flags);
} while (thread_flags & _TIF_WORK_MASK);
}
+
+int __ro_after_init signal_minsigstksz;
+
+/*
+ * Determine the stack space required for guaranteed signal devliery.
+ * This function is used to populate AT_MINSIGSTKSZ at process startup.
+ */
+void __init minsigstksz_setup(void)
+{
+ struct rt_sigframe_user_layout user;
+
+ init_user_layout(&user);
+
+ if (WARN_ON(setup_sigframe_layout(&user, true)))
+ signal_minsigstksz = SIGSTKSZ;
+ else
+ signal_minsigstksz = sigframe_size(&user) +
+ round_up(sizeof(struct frame_record), 16) +
+ 16; /* max alignment padding */
+}
--
2.1.4
^ permalink raw reply related
* [PATCH v2 07/40] iommu: Add a page fault handler
From: Jonathan Cameron @ 2018-05-17 15:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511190641.23008-8-jean-philippe.brucker@arm.com>
On Fri, 11 May 2018 20:06:08 +0100
Jean-Philippe Brucker <jean-philippe.brucker@arm.com> wrote:
> Some systems allow devices to handle I/O Page Faults in the core mm. For
> example systems implementing the PCI PRI extension or Arm SMMU stall
> model. Infrastructure for reporting these recoverable page faults was
> recently added to the IOMMU core for SVA virtualisation. Add a page fault
> handler for host SVA.
>
> IOMMU driver can now instantiate several fault workqueues and link them to
> IOPF-capable devices. Drivers can choose between a single global
> workqueue, one per IOMMU device, one per low-level fault queue, one per
> domain, etc.
>
> When it receives a fault event, supposedly in an IRQ handler, the IOMMU
> driver reports the fault using iommu_report_device_fault(), which calls
> the registered handler. The page fault handler then calls the mm fault
> handler, and reports either success or failure with iommu_page_response().
> When the handler succeeded, the IOMMU retries the access.
>
> The iopf_param pointer could be embedded into iommu_fault_param. But
> putting iopf_param into the iommu_param structure allows us not to care
> about ordering between calls to iopf_queue_add_device() and
> iommu_register_device_fault_handler().
>
> Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Hi Jean-Phillipe,
One question below on how we would end up with partial faults left when
doing the queue remove. Code looks fine, but I'm not seeing how that
would happen without buggy hardware... + we presumably have to rely on
the hardware timing out on that request or it's dead anyway...
Jonathan
>
> ---
> v1->v2: multiple queues registered by IOMMU driver
> ---
> drivers/iommu/Kconfig | 4 +
> drivers/iommu/Makefile | 1 +
> drivers/iommu/io-pgfault.c | 363 +++++++++++++++++++++++++++++++++++++
> include/linux/iommu.h | 58 ++++++
> 4 files changed, 426 insertions(+)
> create mode 100644 drivers/iommu/io-pgfault.c
>
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 38434899e283..09f13a7c4b60 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -79,6 +79,10 @@ config IOMMU_SVA
> select IOMMU_API
> select MMU_NOTIFIER
>
> +config IOMMU_PAGE_FAULT
> + bool
> + select IOMMU_API
> +
> config FSL_PAMU
> bool "Freescale IOMMU support"
> depends on PCI
> diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
> index 1dbcc89ebe4c..4b744e399a1b 100644
> --- a/drivers/iommu/Makefile
> +++ b/drivers/iommu/Makefile
> @@ -4,6 +4,7 @@ obj-$(CONFIG_IOMMU_API) += iommu-traces.o
> obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
> obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
> obj-$(CONFIG_IOMMU_SVA) += iommu-sva.o
> +obj-$(CONFIG_IOMMU_PAGE_FAULT) += io-pgfault.o
> obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
> obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
> obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
> diff --git a/drivers/iommu/io-pgfault.c b/drivers/iommu/io-pgfault.c
> new file mode 100644
> index 000000000000..321c00dd3a3d
> --- /dev/null
> +++ b/drivers/iommu/io-pgfault.c
> @@ -0,0 +1,363 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Handle device page faults
> + *
> + * Copyright (C) 2018 ARM Ltd.
> + */
> +
> +#include <linux/iommu.h>
> +#include <linux/list.h>
> +#include <linux/slab.h>
> +#include <linux/workqueue.h>
> +
> +/**
> + * struct iopf_queue - IO Page Fault queue
> + * @wq: the fault workqueue
> + * @flush: low-level flush callback
> + * @flush_arg: flush() argument
> + * @refs: references to this structure taken by producers
> + */
> +struct iopf_queue {
> + struct workqueue_struct *wq;
> + iopf_queue_flush_t flush;
> + void *flush_arg;
> + refcount_t refs;
> +};
> +
> +/**
> + * struct iopf_device_param - IO Page Fault data attached to a device
> + * @queue: IOPF queue
> + * @partial: faults that are part of a Page Request Group for which the last
> + * request hasn't been submitted yet.
> + */
> +struct iopf_device_param {
> + struct iopf_queue *queue;
> + struct list_head partial;
> +};
> +
> +struct iopf_context {
> + struct device *dev;
> + struct iommu_fault_event evt;
> + struct list_head head;
> +};
> +
> +struct iopf_group {
> + struct iopf_context last_fault;
> + struct list_head faults;
> + struct work_struct work;
> +};
> +
> +static int iopf_complete(struct device *dev, struct iommu_fault_event *evt,
> + enum page_response_code status)
> +{
> + struct page_response_msg resp = {
> + .addr = evt->addr,
> + .pasid = evt->pasid,
> + .pasid_present = evt->pasid_valid,
> + .page_req_group_id = evt->page_req_group_id,
> + .private_data = evt->iommu_private,
> + .resp_code = status,
> + };
> +
> + return iommu_page_response(dev, &resp);
> +}
> +
> +static enum page_response_code
> +iopf_handle_single(struct iopf_context *fault)
> +{
> + /* TODO */
> + return -ENODEV;
> +}
> +
> +static void iopf_handle_group(struct work_struct *work)
> +{
> + struct iopf_group *group;
> + struct iopf_context *fault, *next;
> + enum page_response_code status = IOMMU_PAGE_RESP_SUCCESS;
> +
> + group = container_of(work, struct iopf_group, work);
> +
> + list_for_each_entry_safe(fault, next, &group->faults, head) {
> + struct iommu_fault_event *evt = &fault->evt;
> + /*
> + * Errors are sticky: don't handle subsequent faults in the
> + * group if there is an error.
> + */
> + if (status == IOMMU_PAGE_RESP_SUCCESS)
> + status = iopf_handle_single(fault);
> +
> + if (!evt->last_req)
> + kfree(fault);
> + }
> +
> + iopf_complete(group->last_fault.dev, &group->last_fault.evt, status);
> + kfree(group);
> +}
> +
> +/**
> + * iommu_queue_iopf - IO Page Fault handler
> + * @evt: fault event
> + * @cookie: struct device, passed to iommu_register_device_fault_handler.
> + *
> + * Add a fault to the device workqueue, to be handled by mm.
> + */
> +int iommu_queue_iopf(struct iommu_fault_event *evt, void *cookie)
> +{
> + struct iopf_group *group;
> + struct iopf_context *fault, *next;
> + struct iopf_device_param *iopf_param;
> +
> + struct device *dev = cookie;
> + struct iommu_param *param = dev->iommu_param;
> +
> + if (WARN_ON(!mutex_is_locked(¶m->lock)))
> + return -EINVAL;
> +
> + if (evt->type != IOMMU_FAULT_PAGE_REQ)
> + /* Not a recoverable page fault */
> + return IOMMU_PAGE_RESP_CONTINUE;
> +
> + /*
> + * As long as we're holding param->lock, the queue can't be unlinked
> + * from the device and therefore cannot disappear.
> + */
> + iopf_param = param->iopf_param;
> + if (!iopf_param)
> + return -ENODEV;
> +
> + if (!evt->last_req) {
> + fault = kzalloc(sizeof(*fault), GFP_KERNEL);
> + if (!fault)
> + return -ENOMEM;
> +
> + fault->evt = *evt;
> + fault->dev = dev;
> +
> + /* Non-last request of a group. Postpone until the last one */
> + list_add(&fault->head, &iopf_param->partial);
> +
> + return IOMMU_PAGE_RESP_HANDLED;
> + }
> +
> + group = kzalloc(sizeof(*group), GFP_KERNEL);
> + if (!group)
> + return -ENOMEM;
> +
> + group->last_fault.evt = *evt;
> + group->last_fault.dev = dev;
> + INIT_LIST_HEAD(&group->faults);
> + list_add(&group->last_fault.head, &group->faults);
> + INIT_WORK(&group->work, iopf_handle_group);
> +
> + /* See if we have partial faults for this group */
> + list_for_each_entry_safe(fault, next, &iopf_param->partial, head) {
> + if (fault->evt.page_req_group_id == evt->page_req_group_id)
> + /* Insert *before* the last fault */
> + list_move(&fault->head, &group->faults);
> + }
> +
> + queue_work(iopf_param->queue->wq, &group->work);
> +
> + /* Postpone the fault completion */
> + return IOMMU_PAGE_RESP_HANDLED;
> +}
> +EXPORT_SYMBOL_GPL(iommu_queue_iopf);
> +
> +/**
> + * iopf_queue_flush_dev - Ensure that all queued faults have been processed
> + * @dev: the endpoint whose faults need to be flushed.
> + *
> + * Users must call this function when releasing a PASID, to ensure that all
> + * pending faults for this PASID have been handled, and won't hit the address
> + * space of the next process that uses this PASID.
> + *
> + * Return 0 on success.
> + */
> +int iopf_queue_flush_dev(struct device *dev)
> +{
> + int ret = 0;
> + struct iopf_queue *queue;
> + struct iommu_param *param = dev->iommu_param;
> +
> + if (!param)
> + return -ENODEV;
> +
> + /*
> + * It is incredibly easy to find ourselves in a deadlock situation if
> + * we're not careful, because we're taking the opposite path as
> + * iommu_queue_iopf:
> + *
> + * iopf_queue_flush_dev() | PRI queue handler
> + * lock(mutex) | iommu_queue_iopf()
> + * queue->flush() | lock(mutex)
> + * wait PRI queue empty |
> + *
> + * So we can't hold the device param lock while flushing. We don't have
> + * to, because the queue or the device won't disappear until all flush
> + * are finished.
> + */
> + mutex_lock(¶m->lock);
> + if (param->iopf_param) {
> + queue = param->iopf_param->queue;
> + } else {
> + ret = -ENODEV;
> + }
> + mutex_unlock(¶m->lock);
> + if (ret)
> + return ret;
> +
> + queue->flush(queue->flush_arg, dev);
> +
> + /*
> + * No need to clear the partial list. All PRGs containing the PASID that
> + * needs to be decommissioned are whole (the device driver made sure of
> + * it before this function was called). They have been submitted to the
> + * queue by the above flush().
> + */
> + flush_workqueue(queue->wq);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(iopf_queue_flush_dev);
> +
> +/**
> + * iopf_queue_add_device - Add producer to the fault queue
> + * @queue: IOPF queue
> + * @dev: device to add
> + */
> +int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev)
> +{
> + int ret = -EINVAL;
> + struct iopf_device_param *iopf_param;
> + struct iommu_param *param = dev->iommu_param;
> +
> + if (!param)
> + return -ENODEV;
> +
> + iopf_param = kzalloc(sizeof(*iopf_param), GFP_KERNEL);
> + if (!iopf_param)
> + return -ENOMEM;
> +
> + INIT_LIST_HEAD(&iopf_param->partial);
> + iopf_param->queue = queue;
> +
> + mutex_lock(¶m->lock);
> + if (!param->iopf_param) {
> + refcount_inc(&queue->refs);
> + param->iopf_param = iopf_param;
> + ret = 0;
> + }
> + mutex_unlock(¶m->lock);
> +
> + if (ret)
> + kfree(iopf_param);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(iopf_queue_add_device);
> +
> +/**
> + * iopf_queue_remove_device - Remove producer from fault queue
> + * @dev: device to remove
> + *
> + * Caller makes sure that no more fault is reported for this device, and no more
> + * flush is scheduled for this device.
> + *
> + * Note: safe to call unconditionally on a cleanup path, even if the device
> + * isn't registered to any IOPF queue.
> + *
> + * Return 0 if the device was attached to the IOPF queue
> + */
> +int iopf_queue_remove_device(struct device *dev)
> +{
> + struct iopf_context *fault, *next;
> + struct iopf_device_param *iopf_param;
> + struct iommu_param *param = dev->iommu_param;
> +
> + if (!param)
> + return -EINVAL;
> +
> + mutex_lock(¶m->lock);
> + iopf_param = param->iopf_param;
> + if (iopf_param) {
> + refcount_dec(&iopf_param->queue->refs);
> + param->iopf_param = NULL;
> + }
> + mutex_unlock(¶m->lock);
> + if (!iopf_param)
> + return -EINVAL;
> +
> + list_for_each_entry_safe(fault, next, &iopf_param->partial, head)
> + kfree(fault);
> +
Why would we end up here with partials still in the list? Buggy hardware?
> + /*
> + * No more flush is scheduled, and the caller removed all bonds from
> + * this device. unbind() waited until any concurrent mm_exit() finished,
> + * therefore there is no flush() running anymore and we can free the
> + * param.
> + */
> + kfree(iopf_param);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(iopf_queue_remove_device);
> +
> +/**
> + * iopf_queue_alloc - Allocate and initialize a fault queue
> + * @name: a unique string identifying the queue (for workqueue)
> + * @flush: a callback that flushes the low-level queue
> + * @cookie: driver-private data passed to the flush callback
> + *
> + * The callback is called before the workqueue is flushed. The IOMMU driver must
> + * commit all faults that are pending in its low-level queues at the time of the
> + * call, into the IOPF queue (with iommu_report_device_fault). The callback
> + * takes a device pointer as argument, hinting what endpoint is causing the
> + * flush. When the device is NULL, all faults should be committed.
> + */
> +struct iopf_queue *
> +iopf_queue_alloc(const char *name, iopf_queue_flush_t flush, void *cookie)
> +{
> + struct iopf_queue *queue;
> +
> + queue = kzalloc(sizeof(*queue), GFP_KERNEL);
> + if (!queue)
> + return NULL;
> +
> + /*
> + * The WQ is unordered because the low-level handler enqueues faults by
> + * group. PRI requests within a group have to be ordered, but once
> + * that's dealt with, the high-level function can handle groups out of
> + * order.
> + */
> + queue->wq = alloc_workqueue("iopf_queue/%s", WQ_UNBOUND, 0, name);
> + if (!queue->wq) {
> + kfree(queue);
> + return NULL;
> + }
> +
> + queue->flush = flush;
> + queue->flush_arg = cookie;
> + refcount_set(&queue->refs, 1);
> +
> + return queue;
> +}
> +EXPORT_SYMBOL_GPL(iopf_queue_alloc);
> +
> +/**
> + * iopf_queue_free - Free IOPF queue
> + * @queue: queue to free
> + *
> + * Counterpart to iopf_queue_alloc(). Caller must make sure that all producers
> + * have been removed.
> + */
> +void iopf_queue_free(struct iopf_queue *queue)
> +{
> +
Nitpick : Blank line here doesn't add anything.
> + /* Caller should have removed all producers first */
> + if (WARN_ON(!refcount_dec_and_test(&queue->refs)))
> + return;
> +
> + destroy_workqueue(queue->wq);
> + kfree(queue);
> +}
> +EXPORT_SYMBOL_GPL(iopf_queue_free);
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index faf3390ce89d..fad3a60e1c14 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -461,11 +461,20 @@ struct iommu_fault_param {
> void *data;
> };
>
> +/**
> + * iopf_queue_flush_t - Flush low-level page fault queue
> + *
> + * Report all faults currently pending in the low-level page fault queue
> + */
> +struct iopf_queue;
> +typedef int (*iopf_queue_flush_t)(void *cookie, struct device *dev);
> +
> /**
> * struct iommu_param - collection of per-device IOMMU data
> *
> * @fault_param: IOMMU detected device fault reporting data
> * @sva_param: SVA parameters
> + * @iopf_param: I/O Page Fault queue and data
> *
> * TODO: migrate other per device data pointers under iommu_dev_data, e.g.
> * struct iommu_group *iommu_group;
> @@ -475,6 +484,7 @@ struct iommu_param {
> struct mutex lock;
> struct iommu_fault_param *fault_param;
> struct iommu_sva_param *sva_param;
> + struct iopf_device_param *iopf_param;
> };
>
> int iommu_device_register(struct iommu_device *iommu);
> @@ -874,6 +884,12 @@ static inline int iommu_report_device_fault(struct device *dev, struct iommu_fau
> return 0;
> }
>
> +static inline int iommu_page_response(struct device *dev,
> + struct page_response_msg *msg)
> +{
> + return -ENODEV;
> +}
> +
> static inline int iommu_group_id(struct iommu_group *group)
> {
> return -ENODEV;
> @@ -1038,4 +1054,46 @@ static inline struct mm_struct *iommu_sva_find(int pasid)
> }
> #endif /* CONFIG_IOMMU_SVA */
>
> +#ifdef CONFIG_IOMMU_PAGE_FAULT
> +extern int iommu_queue_iopf(struct iommu_fault_event *evt, void *cookie);
> +
> +extern int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev);
> +extern int iopf_queue_remove_device(struct device *dev);
> +extern int iopf_queue_flush_dev(struct device *dev);
> +extern struct iopf_queue *
> +iopf_queue_alloc(const char *name, iopf_queue_flush_t flush, void *cookie);
> +extern void iopf_queue_free(struct iopf_queue *queue);
> +#else /* CONFIG_IOMMU_PAGE_FAULT */
> +static inline int iommu_queue_iopf(struct iommu_fault_event *evt, void *cookie)
> +{
> + return -ENODEV;
> +}
> +
> +static inline int iopf_queue_add_device(struct iopf_queue *queue,
> + struct device *dev)
> +{
> + return -ENODEV;
> +}
> +
> +static inline int iopf_queue_remove_device(struct device *dev)
> +{
> + return -ENODEV;
> +}
> +
> +static inline int iopf_queue_flush_dev(struct device *dev)
> +{
> + return -ENODEV;
> +}
> +
> +static inline struct iopf_queue *
> +iopf_queue_alloc(const char *name, iopf_queue_flush_t flush, void *cookie)
> +{
> + return NULL;
> +}
> +
> +static inline void iopf_queue_free(struct iopf_queue *queue)
> +{
> +}
> +#endif /* CONFIG_IOMMU_PAGE_FAULT */
> +
> #endif /* __LINUX_IOMMU_H */
^ permalink raw reply
* [PATCH v10 25/27] ARM: davinci: add device tree support to timer
From: David Lechner @ 2018-05-17 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8fa98514-7651-58cb-595e-6c7f713540b8@ti.com>
On 05/17/2018 09:35 AM, Sekhar Nori wrote:
> Hi David,
>
> On Wednesday 09 May 2018 10:56 PM, David Lechner wrote:
>> This adds device tree support to the davinci timer so that when clocks
>> are moved to device tree, the timer will still work.
>>
>> Signed-off-by: David Lechner <david@lechnology.com>
>> ---
>
>> +static int __init of_davinci_timer_init(struct device_node *np)
>> +{
>> + struct clk *clk;
>> +
>> + clk = of_clk_get(np, 0);
>> + if (IS_ERR(clk)) {
>> + struct of_phandle_args clkspec;
>> +
>> + /*
>> + * Fall back to using ref_clk if the actual clock is not
>> + * available. There will be problems later if the real clock
>> + * source is disabled.
>> + */
>> +
>> + pr_warn("%s: falling back to ref_clk\n", __func__);
>> +
>> + clkspec.np = of_find_node_by_name(NULL, "ref_clk");
>> + if (IS_ERR(clkspec.np)) {
>> + pr_err("%s: No clock available for timer!\n", __func__);
>> + return PTR_ERR(clkspec.np);
>> + }
>> + clk = of_clk_get_from_provider(&clkspec);
>> + of_node_put(clkspec.np);
>> + }
>
> Do we need this error path now?
>
> Thanks,
> Sekhar
>
No, not really.
^ permalink raw reply
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;
as well as URLs for NNTP newsgroup(s).