* [PATCH v3 1/3] crypto: engine - permit to enqueue aead_request
From: Herbert Xu @ 2017-10-05 3:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20206811-7075-5ca9-98cd-26a5709751fb@st.com>
On Tue, Oct 03, 2017 at 07:48:08AM +0000, Fabien DESSENNE wrote:
>
> It looks like there is no more activity around this "crypto_engine
> interface clean up" task.
> This unfortunately has been blocking the introduction of this new STM32
> crypto driver for 3 months now.
> Would it make sense to have this driver reviewed first, and then
> reworked (I expect minor update here) when the interface update is ready?
Hmm, is it possible to disable the AEAD part of the driver first?
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v3 1/3] crypto: engine - permit to enqueue aead_request
From: Herbert Xu @ 2017-10-05 3:39 UTC (permalink / raw)
To: Fabien DESSENNE
Cc: David S . Miller, Rob Herring, Mark Rutland, Maxime Coquelin,
Alexandre TORGUE, linux-crypto@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Benjamin GAIGNARD, Lionel DEBIEVE,
Ludovic BARRE, Corentin Labbe
In-Reply-To: <20206811-7075-5ca9-98cd-26a5709751fb@st.com>
On Tue, Oct 03, 2017 at 07:48:08AM +0000, Fabien DESSENNE wrote:
>
> It looks like there is no more activity around this "crypto_engine
> interface clean up" task.
> This unfortunately has been blocking the introduction of this new STM32
> crypto driver for 3 months now.
> Would it make sense to have this driver reviewed first, and then
> reworked (I expect minor update here) when the interface update is ready?
Hmm, is it possible to disable the AEAD part of the driver first?
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v4 05/15] perf report: create real callchain entries for inlined frames
From: Namhyung Kim @ 2017-10-05 3:35 UTC (permalink / raw)
To: Milian Wolff
Cc: acme, jolsa, Jin Yao, Linux-kernel, linux-perf-users, Jiri Olsa,
Arnaldo Carvalho de Melo, David Ahern, Peter Zijlstra,
kernel-team
In-Reply-To: <20171001143100.19988-6-milian.wolff@kdab.com>
On Sun, Oct 01, 2017 at 04:30:50PM +0200, Milian Wolff wrote:
> The inline_node structs are maintained by the new dso->inlines
> tree. This in turn keeps ownership of the fake symbols and
> srcline string representing an inline frame.
>
> This tree is always sorted by name. All other entries of the symbol
Isn't it sorted by address?
> beside the function name are unused for inline frames. The advantage
> of this approach is that all existing users of the callchain API can
> now transparently display inlined frames without having to patch
> their code.
>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Yao Jin <yao.jin@linux.intel.com>
> Signed-off-by: Milian Wolff <milian.wolff@kdab.com>
> ---
> tools/perf/util/dso.c | 3 +++
> tools/perf/util/dso.h | 1 +
> tools/perf/util/machine.c | 37 ++++++++++++++++++++++++++++++++++
> tools/perf/util/srcline.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++
> tools/perf/util/srcline.h | 9 +++++++++
> 5 files changed, 101 insertions(+)
>
> diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
> index 339e52971380..6e743dffc487 100644
> --- a/tools/perf/util/dso.c
> +++ b/tools/perf/util/dso.c
> @@ -10,6 +10,7 @@
> #include "compress.h"
> #include "path.h"
> #include "symbol.h"
> +#include "srcline.h"
> #include "dso.h"
> #include "machine.h"
> #include "auxtrace.h"
> @@ -1201,6 +1202,7 @@ struct dso *dso__new(const char *name)
> for (i = 0; i < MAP__NR_TYPES; ++i)
> dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
> dso->data.cache = RB_ROOT;
> + dso->inlined_nodes = RB_ROOT;
> dso->data.fd = -1;
> dso->data.status = DSO_DATA_STATUS_UNKNOWN;
> dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND;
> @@ -1234,6 +1236,7 @@ void dso__delete(struct dso *dso)
> dso->long_name);
> for (i = 0; i < MAP__NR_TYPES; ++i)
> symbols__delete(&dso->symbols[i]);
> + inlines__tree_delete(&dso->inlined_nodes);
I'm still curious why it doesn't make a trouble (I think there's
use-after-free for non-inlined symbols). Anyway moving the
inlines__tree_delete() above the symbols__delete() will solve the
concern IMHO.
Thanks,
Namhyung
>
> if (dso->short_name_allocated) {
> zfree((char **)&dso->short_name);
[SNIP]
> diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
> index 07d1a058d7c4..69241d805275 100644
> --- a/tools/perf/util/srcline.c
> +++ b/tools/perf/util/srcline.c
> @@ -583,3 +583,54 @@ void inline_node__delete(struct inline_node *node)
>
> free(node);
> }
> +
> +void inlines__tree_insert(struct rb_root *tree, struct inline_node *inlines)
> +{
> + struct rb_node **p = &tree->rb_node;
> + struct rb_node *parent = NULL;
> + const u64 addr = inlines->addr;
> + struct inline_node *i;
> +
> + while (*p != NULL) {
> + parent = *p;
> + i = rb_entry(parent, struct inline_node, rb_node);
> + if (addr < i->addr)
> + p = &(*p)->rb_left;
> + else
> + p = &(*p)->rb_right;
> + }
> + rb_link_node(&inlines->rb_node, parent, p);
> + rb_insert_color(&inlines->rb_node, tree);
> +}
> +
> +struct inline_node *inlines__tree_find(struct rb_root *tree, u64 addr)
> +{
> + struct rb_node *n = tree->rb_node;
> +
> + while (n) {
> + struct inline_node *i = rb_entry(n, struct inline_node,
> + rb_node);
> +
> + if (addr < i->addr)
> + n = n->rb_left;
> + else if (addr > i->addr)
> + n = n->rb_right;
> + else
> + return i;
> + }
> +
> + return NULL;
> +}
> +
> +void inlines__tree_delete(struct rb_root *tree)
> +{
> + struct inline_node *pos;
> + struct rb_node *next = rb_first(tree);
> +
> + while (next) {
> + pos = rb_entry(next, struct inline_node, rb_node);
> + next = rb_next(&pos->rb_node);
> + rb_erase(&pos->rb_node, tree);
> + inline_node__delete(pos);
> + }
> +}
> diff --git a/tools/perf/util/srcline.h b/tools/perf/util/srcline.h
> index 0201ed2c0b9c..ebe38cd22294 100644
> --- a/tools/perf/util/srcline.h
> +++ b/tools/perf/util/srcline.h
> @@ -2,6 +2,7 @@
> #define PERF_SRCLINE_H
>
> #include <linux/list.h>
> +#include <linux/rbtree.h>
> #include <linux/types.h>
>
> struct dso;
> @@ -25,6 +26,7 @@ struct inline_list {
> struct inline_node {
> u64 addr;
> struct list_head val;
> + struct rb_node rb_node;
> };
>
> /* parse inlined frames for the given address */
> @@ -33,4 +35,11 @@ struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr,
> /* free resources associated to the inline node list */
> void inline_node__delete(struct inline_node *node);
>
> +/* insert the inline node list into the DSO, which will take ownership */
> +void inlines__tree_insert(struct rb_root *tree, struct inline_node *inlines);
> +/* find previously inserted inline node list */
> +struct inline_node *inlines__tree_find(struct rb_root *tree, u64 addr);
> +/* delete all nodes within the tree of inline_node s */
> +void inlines__tree_delete(struct rb_root *tree);
> +
> #endif /* PERF_SRCLINE_H */
> --
> 2.14.2
>
^ permalink raw reply
* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
From: Dave Airlie @ 2017-10-05 3:37 UTC (permalink / raw)
To: Keith Packard; +Cc: LKML, Dave Airlie, Daniel Vetter, dri-devel
In-Reply-To: <CAPM=9tw59ctS4VC_b8JUR-mJBWJ_1CQ3BiyWciDBCVj15_98yQ@mail.gmail.com>
On 5 October 2017 at 13:24, Dave Airlie <airlied@gmail.com> wrote:
> On 5 October 2017 at 13:17, Dave Airlie <airlied@gmail.com> wrote:
>>> ---
>>> drivers/gpu/drm/drm_ioctl.c | 4 +
>>> drivers/gpu/drm/drm_lease.c | 270 ++++++++++++++++++++++++++++++++++++++++++++
>>> include/drm/drm_lease.h | 12 ++
>>> include/uapi/drm/drm.h | 5 +
>>> include/uapi/drm/drm_mode.h | 64 +++++++++++
>>> 5 files changed, 355 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
>>> index a5a259964c7d..0a43e82d3f06 100644
>>> --- a/drivers/gpu/drm/drm_ioctl.c
>>> +++ b/drivers/gpu/drm/drm_ioctl.c
>>> @@ -657,6 +657,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>>> DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>> DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
>>> DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>>> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>>> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>>> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>>> };
>>>
>>> #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
>>> diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
>>> index a8bd4bdd2977..f233d8b488f2 100644
>>> --- a/drivers/gpu/drm/drm_lease.c
>>> +++ b/drivers/gpu/drm/drm_lease.c
>>> @@ -23,6 +23,8 @@
>>> #define drm_for_each_lessee(lessee, lessor) \
>>> list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
>>>
>>> +static uint64_t drm_lease_idr_object;
>>
>> What is this for? ^^
>>
>>> + ret = idr_alloc(&leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
>>
>> You can just pass NULL here.
>>
>
> Just read the comment, this smells a bit of black magic, I'll spend
> some time staring at it :-)
I think a comment in here is definitely warranted with what you expect
from the idr interface here.
You seem to be storing the object ids in it from the user, and failing
if you get a duplicate, then later dequeuing the idr.
I'm not sure this an intended use of idr :-), my brain is saying a
bitmap would work just as well, or even why we want/need
deduplication here. If userspace does something stupid does it matter?
Because otherwise you could just memdup_user the array of ids, and
pass that in without the idr stuff.
Dave.
^ permalink raw reply
* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
From: Dave Airlie @ 2017-10-05 3:37 UTC (permalink / raw)
To: Keith Packard; +Cc: Dave Airlie, dri-devel, LKML
In-Reply-To: <CAPM=9tw59ctS4VC_b8JUR-mJBWJ_1CQ3BiyWciDBCVj15_98yQ@mail.gmail.com>
On 5 October 2017 at 13:24, Dave Airlie <airlied@gmail.com> wrote:
> On 5 October 2017 at 13:17, Dave Airlie <airlied@gmail.com> wrote:
>>> ---
>>> drivers/gpu/drm/drm_ioctl.c | 4 +
>>> drivers/gpu/drm/drm_lease.c | 270 ++++++++++++++++++++++++++++++++++++++++++++
>>> include/drm/drm_lease.h | 12 ++
>>> include/uapi/drm/drm.h | 5 +
>>> include/uapi/drm/drm_mode.h | 64 +++++++++++
>>> 5 files changed, 355 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
>>> index a5a259964c7d..0a43e82d3f06 100644
>>> --- a/drivers/gpu/drm/drm_ioctl.c
>>> +++ b/drivers/gpu/drm/drm_ioctl.c
>>> @@ -657,6 +657,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>>> DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>> DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
>>> DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>>> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>>> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>>> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>>> };
>>>
>>> #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
>>> diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
>>> index a8bd4bdd2977..f233d8b488f2 100644
>>> --- a/drivers/gpu/drm/drm_lease.c
>>> +++ b/drivers/gpu/drm/drm_lease.c
>>> @@ -23,6 +23,8 @@
>>> #define drm_for_each_lessee(lessee, lessor) \
>>> list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
>>>
>>> +static uint64_t drm_lease_idr_object;
>>
>> What is this for? ^^
>>
>>> + ret = idr_alloc(&leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
>>
>> You can just pass NULL here.
>>
>
> Just read the comment, this smells a bit of black magic, I'll spend
> some time staring at it :-)
I think a comment in here is definitely warranted with what you expect
from the idr interface here.
You seem to be storing the object ids in it from the user, and failing
if you get a duplicate, then later dequeuing the idr.
I'm not sure this an intended use of idr :-), my brain is saying a
bitmap would work just as well, or even why we want/need
deduplication here. If userspace does something stupid does it matter?
Because otherwise you could just memdup_user the array of ids, and
pass that in without the idr stuff.
Dave.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* [PATCH v3 1/5] of/platform: Generalize /reserved-memory handling
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: Andy Gross, Anton Vorontsov, Colin Cross, Frank Rowand, Kees Cook,
Rob Herring, Tony Luck
Cc: David Brown, devicetree, linux-arm-kernel, linux-arm-msm,
linux-kernel, linux-soc
In-Reply-To: <20171005033258.12825-1-bjorn.andersson@linaro.org>
By iterating over all /reserved-memory child nodes and match each one to
a list of compatibles that we want to treat specially, we can easily
extend the list of compatibles to handle - without having to resort to
of_platform_populate() that would create unnecessary platform_devices.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v2:
- Simplify logic per Rob's suggestion.
Changes since v1:
- New patch
drivers/of/platform.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b19524623498..ee89f096f0f3 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -497,6 +497,11 @@ int of_platform_default_populate(struct device_node *root,
EXPORT_SYMBOL_GPL(of_platform_default_populate);
#ifndef CONFIG_PPC
+static const struct of_device_id reserved_mem_matches[] = {
+ { .compatible = "ramoops" },
+ {}
+};
+
static int __init of_platform_default_populate_init(void)
{
struct device_node *node;
@@ -505,15 +510,12 @@ static int __init of_platform_default_populate_init(void)
return -ENODEV;
/*
- * Handle ramoops explicitly, since it is inside /reserved-memory,
- * which lacks a "compatible" property.
+ * Handle certain compatibles explicitly, since we don't want to create
+ * platform_devices for every node in /reserved-memory with a
+ * "compatible",
*/
- node = of_find_node_by_path("/reserved-memory");
- if (node) {
- node = of_find_compatible_node(node, NULL, "ramoops");
- if (node)
- of_platform_device_create(node, NULL, NULL);
- }
+ for_each_matching_node(node, reserved_mem_matches)
+ of_platform_device_create(node, NULL, NULL);
/* Populate everything else. */
of_platform_default_populate(NULL, NULL, NULL);
--
2.12.0
^ permalink raw reply related
* [PATCH v3 0/5] Qualcomm remote filesystem shared memory driver
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: Andy Gross
Cc: Anton Vorontsov, Colin Cross, David Brown, Frank Rowand,
Kees Cook, Rob Herring, Tony Luck, devicetree, linux-arm-kernel,
linux-arm-msm, linux-kernel, linux-soc
Some remote processors (in particular the modem) found in Qualcomm platforms
stores configuration parameters and other data in a file system. As the remotes
does not have direct storage access it needs to relay block accesses through a
service running on the application CPU.
The memory is described in DeviceTree by a new reserved-memory compatible and
the implementation provides the user space service a read/write interface to
this chunk of memory.
Bjorn Andersson (5):
of/platform: Generalize /reserved-memory handling
of: reserved_mem: Accessor for acquiring reserved_mem
dt-binding: soc: qcom: Add binding for rmtfs memory
soc: qcom: Remote filesystem memory driver
arm64: dts: msm8916: Mark rmtfs node as qcom,rmtfs-mem compatible
.../bindings/reserved-memory/qcom,rmtfs-mem.txt | 51 ++++
arch/arm64/boot/dts/qcom/msm8916.dtsi | 3 +
drivers/of/of_reserved_mem.c | 26 ++
drivers/of/platform.c | 19 +-
drivers/soc/qcom/Kconfig | 11 +
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/rmtfs_mem.c | 272 +++++++++++++++++++++
include/linux/of_reserved_mem.h | 5 +
8 files changed, 380 insertions(+), 8 deletions(-)
create mode 100644 Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.txt
create mode 100644 drivers/soc/qcom/rmtfs_mem.c
--
2.12.0
^ permalink raw reply
* [PATCH v3 5/5] arm64: dts: msm8916: Mark rmtfs node as qcom, rmtfs-mem compatible
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171005033258.12825-1-bjorn.andersson@linaro.org>
Now that we have a binding defined for the shared file system memory use
this to describe the rmtfs memory region.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v2:
- None
Changes since v1:
- New patch
arch/arm64/boot/dts/qcom/msm8916.dtsi | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 039991f80831..f6ae6f9b27e1 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -69,8 +69,11 @@
};
rmtfs at 86700000 {
+ compatible = "qcom,rmtfs-mem";
reg = <0x0 0x86700000 0x0 0xe0000>;
no-map;
+
+ qcom,client-id = <1>;
};
rfsa at 867e00000 {
--
2.12.0
^ permalink raw reply related
* [PATCH v3 5/5] arm64: dts: msm8916: Mark rmtfs node as qcom,rmtfs-mem compatible
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: Andy Gross
Cc: Anton Vorontsov, Colin Cross, David Brown, Frank Rowand,
Kees Cook, Rob Herring, Tony Luck, devicetree, linux-arm-kernel,
linux-arm-msm, linux-kernel, linux-soc
In-Reply-To: <20171005033258.12825-1-bjorn.andersson@linaro.org>
Now that we have a binding defined for the shared file system memory use
this to describe the rmtfs memory region.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v2:
- None
Changes since v1:
- New patch
arch/arm64/boot/dts/qcom/msm8916.dtsi | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 039991f80831..f6ae6f9b27e1 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -69,8 +69,11 @@
};
rmtfs@86700000 {
+ compatible = "qcom,rmtfs-mem";
reg = <0x0 0x86700000 0x0 0xe0000>;
no-map;
+
+ qcom,client-id = <1>;
};
rfsa@867e00000 {
--
2.12.0
^ permalink raw reply related
* [PATCH v3 4/5] soc: qcom: Remote filesystem memory driver
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171005033258.12825-1-bjorn.andersson@linaro.org>
The Qualcomm remote file system protocol is used by certain remoteprocs,
in particular the modem, to read and write persistent storage in
platforms where only the application CPU has physical storage access.
The protocol is based on a set of QMI-encoded control-messages and a
shared memory buffer for exchaning the data. This driver implements the
latter, providing the user space service access to the carved out chunk
of memory.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v2:
- Renamed driver to "rmtfs_mem" in attempt to clarify that this is not a
file system, but some chunk of memory.
Changes since v1:
- RFSA device represented direclty by the reserved-memory node
drivers/of/platform.c | 1 +
drivers/soc/qcom/Kconfig | 11 ++
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/rmtfs_mem.c | 272 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 285 insertions(+)
create mode 100644 drivers/soc/qcom/rmtfs_mem.c
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index ee89f096f0f3..e7548c9a9915 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -498,6 +498,7 @@ EXPORT_SYMBOL_GPL(of_platform_default_populate);
#ifndef CONFIG_PPC
static const struct of_device_id reserved_mem_matches[] = {
+ { .compatible = "qcom,rmtfs-mem" },
{ .compatible = "ramoops" },
{}
};
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 9fca977ef18d..6dff89eaf3f8 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -24,6 +24,17 @@ config QCOM_PM
modes. It interface with various system drivers to put the cores in
low power modes.
+config QCOM_RMTFS_MEM
+ tristate "Qualcomm Remote Filesystem memory driver"
+ depends on ARCH_QCOM
+ help
+ The Qualcomm remote filesystem memory driver is used for allocating
+ and exposing regions of shared memory with remote processors for the
+ purpose of exchanging sector-data between the remote filesystem
+ service and its clients.
+
+ Say y here if you intend to boot the modem remoteproc.
+
config QCOM_SMEM
tristate "Qualcomm Shared Memory Manager (SMEM)"
depends on ARCH_QCOM
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 414f0de274fa..541c1f40d126 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
obj-$(CONFIG_QCOM_PM) += spm.o
+obj-$(CONFIG_QCOM_RMTFS_MEM) += rmtfs_mem.o
obj-$(CONFIG_QCOM_SMD_RPM) += smd-rpm.o
obj-$(CONFIG_QCOM_SMEM) += smem.o
obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c
new file mode 100644
index 000000000000..2e7c955e7cf0
--- /dev/null
+++ b/drivers/soc/qcom/rmtfs_mem.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2017 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cdev.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/of_fdt.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/qcom_scm.h>
+
+#define QCOM_RMTFS_MEM_DEV_MAX (MINORMASK + 1)
+
+static dev_t qcom_rmtfs_mem_major;
+
+struct qcom_rmtfs_mem {
+ struct device dev;
+ struct cdev cdev;
+
+ void *base;
+ phys_addr_t addr;
+ phys_addr_t size;
+
+ unsigned int client_id;
+};
+
+static ssize_t qcom_rmtfs_mem_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static DEVICE_ATTR(phys_addr, 0400, qcom_rmtfs_mem_show, NULL);
+static DEVICE_ATTR(size, 0400, qcom_rmtfs_mem_show, NULL);
+static DEVICE_ATTR(client_id, 0400, qcom_rmtfs_mem_show, NULL);
+
+static ssize_t qcom_rmtfs_mem_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = container_of(dev,
+ struct qcom_rmtfs_mem,
+ dev);
+
+ if (attr == &dev_attr_phys_addr)
+ return sprintf(buf, "%pa\n", &rmtfs_mem->addr);
+ if (attr == &dev_attr_size)
+ return sprintf(buf, "%pa\n", &rmtfs_mem->size);
+ if (attr == &dev_attr_client_id)
+ return sprintf(buf, "%d\n", rmtfs_mem->client_id);
+
+ return -EINVAL;
+}
+
+static struct attribute *qcom_rmtfs_mem_attrs[] = {
+ &dev_attr_phys_addr.attr,
+ &dev_attr_size.attr,
+ &dev_attr_client_id.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(qcom_rmtfs_mem);
+
+static int qcom_rmtfs_mem_open(struct inode *inode, struct file *filp)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = container_of(inode->i_cdev,
+ struct qcom_rmtfs_mem,
+ cdev);
+
+ get_device(&rmtfs_mem->dev);
+ filp->private_data = rmtfs_mem;
+
+ return 0;
+}
+static ssize_t qcom_rmtfs_mem_read(struct file *filp,
+ char __user *buf, size_t count, loff_t *f_pos)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = filp->private_data;
+
+ if (*f_pos >= rmtfs_mem->size)
+ return 0;
+
+ if (*f_pos + count >= rmtfs_mem->size)
+ count = rmtfs_mem->size - *f_pos;
+
+ if (copy_to_user(buf, rmtfs_mem->base + *f_pos, count))
+ return -EFAULT;
+
+ *f_pos += count;
+ return count;
+}
+
+static ssize_t qcom_rmtfs_mem_write(struct file *filp,
+ const char __user *buf, size_t count,
+ loff_t *f_pos)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = filp->private_data;
+
+ if (*f_pos >= rmtfs_mem->size)
+ return 0;
+
+ if (*f_pos + count >= rmtfs_mem->size)
+ count = rmtfs_mem->size - *f_pos;
+
+ if (copy_from_user(rmtfs_mem->base + *f_pos, buf, count))
+ return -EFAULT;
+
+ *f_pos += count;
+ return count;
+}
+
+static int qcom_rmtfs_mem_release(struct inode *inode, struct file *filp)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = filp->private_data;
+
+ put_device(&rmtfs_mem->dev);
+
+ return 0;
+}
+
+static const struct file_operations qcom_rmtfs_mem_fops = {
+ .owner = THIS_MODULE,
+ .open = qcom_rmtfs_mem_open,
+ .read = qcom_rmtfs_mem_read,
+ .write = qcom_rmtfs_mem_write,
+ .release = qcom_rmtfs_mem_release,
+ .llseek = default_llseek,
+};
+
+static void qcom_rmtfs_mem_release_device(struct device *dev)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = container_of(dev,
+ struct qcom_rmtfs_mem,
+ dev);
+
+ kfree(rmtfs_mem);
+}
+
+static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
+{
+ struct device_node *node = pdev->dev.of_node;
+ struct reserved_mem *rmem;
+ struct qcom_rmtfs_mem *rmtfs_mem;
+ u32 client_id;
+ int ret;
+
+ rmem = of_reserved_mem_get(node);
+ if (!rmem) {
+ dev_err(&pdev->dev, "failed to acquire memory region\n");
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32(node, "qcom,client-id", &client_id);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to parse \"qcom,client-id\"\n");
+ return ret;
+
+ }
+
+ rmtfs_mem = kzalloc(sizeof(*rmtfs_mem), GFP_KERNEL);
+ if (!rmtfs_mem)
+ return -ENOMEM;
+
+ rmtfs_mem->addr = rmem->base;
+ rmtfs_mem->client_id = client_id;
+ rmtfs_mem->size = rmem->size;
+
+ device_initialize(&rmtfs_mem->dev);
+ rmtfs_mem->dev.parent = &pdev->dev;
+ rmtfs_mem->dev.groups = qcom_rmtfs_mem_groups;
+
+ rmtfs_mem->base = devm_memremap(&rmtfs_mem->dev, rmtfs_mem->addr,
+ rmtfs_mem->size, MEMREMAP_WC);
+ if (IS_ERR(rmtfs_mem->base)) {
+ dev_err(&pdev->dev, "failed to remap rmtfs_mem region\n");
+ ret = PTR_ERR(rmtfs_mem->base);
+ goto put_device;
+ }
+
+ cdev_init(&rmtfs_mem->cdev, &qcom_rmtfs_mem_fops);
+ rmtfs_mem->cdev.owner = THIS_MODULE;
+
+ dev_set_name(&rmtfs_mem->dev, "qcom_rmtfs_mem%d", client_id);
+ rmtfs_mem->dev.id = client_id;
+ rmtfs_mem->dev.devt = MKDEV(MAJOR(qcom_rmtfs_mem_major), client_id);
+
+ ret = cdev_device_add(&rmtfs_mem->cdev, &rmtfs_mem->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add cdev: %d\n", ret);
+ goto put_device;
+ }
+
+ rmtfs_mem->dev.release = qcom_rmtfs_mem_release_device;
+
+ dev_set_drvdata(&pdev->dev, rmtfs_mem);
+
+ return 0;
+
+remove_cdev:
+ cdev_device_del(&rmtfs_mem->cdev, &rmtfs_mem->dev);
+put_device:
+ put_device(&rmtfs_mem->dev);
+
+ return ret;
+}
+
+static int qcom_rmtfs_mem_remove(struct platform_device *pdev)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = dev_get_drvdata(&pdev->dev);
+
+ cdev_device_del(&rmtfs_mem->cdev, &rmtfs_mem->dev);
+ put_device(&rmtfs_mem->dev);
+
+ return 0;
+}
+
+static const struct of_device_id qcom_rmtfs_mem_of_match[] = {
+ { .compatible = "qcom,rmtfs-mem" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, qcom_rmtfs_mem_of_match);
+
+static struct platform_driver qcom_rmtfs_mem_driver = {
+ .probe = qcom_rmtfs_mem_probe,
+ .remove = qcom_rmtfs_mem_remove,
+ .driver = {
+ .name = "qcom_rmtfs_mem",
+ .of_match_table = qcom_rmtfs_mem_of_match,
+ },
+};
+
+static int qcom_rmtfs_mem_init(void)
+{
+ int ret;
+
+ ret = alloc_chrdev_region(&qcom_rmtfs_mem_major, 0,
+ QCOM_RMTFS_MEM_DEV_MAX, "qcom_rmtfs_mem");
+ if (ret < 0) {
+ pr_err("qcom_rmtfs_mem: failed to allocate char dev region\n");
+ return ret;
+ }
+
+ ret = platform_driver_register(&qcom_rmtfs_mem_driver);
+ if (ret < 0) {
+ pr_err("qcom_rmtfs_mem: failed to register rmtfs_mem driver\n");
+ unregister_chrdev_region(qcom_rmtfs_mem_major,
+ QCOM_RMTFS_MEM_DEV_MAX);
+ }
+
+ return ret;
+}
+module_init(qcom_rmtfs_mem_init);
+
+static void qcom_rmtfs_mem_exit(void)
+{
+ platform_driver_unregister(&qcom_rmtfs_mem_driver);
+ unregister_chrdev_region(qcom_rmtfs_mem_major, QCOM_RMTFS_MEM_DEV_MAX);
+}
+module_exit(qcom_rmtfs_mem_exit);
--
2.12.0
^ permalink raw reply related
* [PATCH v3 4/5] soc: qcom: Remote filesystem memory driver
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: Andy Gross, Rob Herring
Cc: Anton Vorontsov, Colin Cross, David Brown, Frank Rowand,
Kees Cook, Tony Luck, devicetree, linux-arm-kernel, linux-arm-msm,
linux-kernel, linux-soc
In-Reply-To: <20171005033258.12825-1-bjorn.andersson@linaro.org>
The Qualcomm remote file system protocol is used by certain remoteprocs,
in particular the modem, to read and write persistent storage in
platforms where only the application CPU has physical storage access.
The protocol is based on a set of QMI-encoded control-messages and a
shared memory buffer for exchaning the data. This driver implements the
latter, providing the user space service access to the carved out chunk
of memory.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v2:
- Renamed driver to "rmtfs_mem" in attempt to clarify that this is not a
file system, but some chunk of memory.
Changes since v1:
- RFSA device represented direclty by the reserved-memory node
drivers/of/platform.c | 1 +
drivers/soc/qcom/Kconfig | 11 ++
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/rmtfs_mem.c | 272 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 285 insertions(+)
create mode 100644 drivers/soc/qcom/rmtfs_mem.c
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index ee89f096f0f3..e7548c9a9915 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -498,6 +498,7 @@ EXPORT_SYMBOL_GPL(of_platform_default_populate);
#ifndef CONFIG_PPC
static const struct of_device_id reserved_mem_matches[] = {
+ { .compatible = "qcom,rmtfs-mem" },
{ .compatible = "ramoops" },
{}
};
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 9fca977ef18d..6dff89eaf3f8 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -24,6 +24,17 @@ config QCOM_PM
modes. It interface with various system drivers to put the cores in
low power modes.
+config QCOM_RMTFS_MEM
+ tristate "Qualcomm Remote Filesystem memory driver"
+ depends on ARCH_QCOM
+ help
+ The Qualcomm remote filesystem memory driver is used for allocating
+ and exposing regions of shared memory with remote processors for the
+ purpose of exchanging sector-data between the remote filesystem
+ service and its clients.
+
+ Say y here if you intend to boot the modem remoteproc.
+
config QCOM_SMEM
tristate "Qualcomm Shared Memory Manager (SMEM)"
depends on ARCH_QCOM
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 414f0de274fa..541c1f40d126 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
obj-$(CONFIG_QCOM_PM) += spm.o
+obj-$(CONFIG_QCOM_RMTFS_MEM) += rmtfs_mem.o
obj-$(CONFIG_QCOM_SMD_RPM) += smd-rpm.o
obj-$(CONFIG_QCOM_SMEM) += smem.o
obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c
new file mode 100644
index 000000000000..2e7c955e7cf0
--- /dev/null
+++ b/drivers/soc/qcom/rmtfs_mem.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2017 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cdev.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/of_fdt.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/qcom_scm.h>
+
+#define QCOM_RMTFS_MEM_DEV_MAX (MINORMASK + 1)
+
+static dev_t qcom_rmtfs_mem_major;
+
+struct qcom_rmtfs_mem {
+ struct device dev;
+ struct cdev cdev;
+
+ void *base;
+ phys_addr_t addr;
+ phys_addr_t size;
+
+ unsigned int client_id;
+};
+
+static ssize_t qcom_rmtfs_mem_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static DEVICE_ATTR(phys_addr, 0400, qcom_rmtfs_mem_show, NULL);
+static DEVICE_ATTR(size, 0400, qcom_rmtfs_mem_show, NULL);
+static DEVICE_ATTR(client_id, 0400, qcom_rmtfs_mem_show, NULL);
+
+static ssize_t qcom_rmtfs_mem_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = container_of(dev,
+ struct qcom_rmtfs_mem,
+ dev);
+
+ if (attr == &dev_attr_phys_addr)
+ return sprintf(buf, "%pa\n", &rmtfs_mem->addr);
+ if (attr == &dev_attr_size)
+ return sprintf(buf, "%pa\n", &rmtfs_mem->size);
+ if (attr == &dev_attr_client_id)
+ return sprintf(buf, "%d\n", rmtfs_mem->client_id);
+
+ return -EINVAL;
+}
+
+static struct attribute *qcom_rmtfs_mem_attrs[] = {
+ &dev_attr_phys_addr.attr,
+ &dev_attr_size.attr,
+ &dev_attr_client_id.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(qcom_rmtfs_mem);
+
+static int qcom_rmtfs_mem_open(struct inode *inode, struct file *filp)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = container_of(inode->i_cdev,
+ struct qcom_rmtfs_mem,
+ cdev);
+
+ get_device(&rmtfs_mem->dev);
+ filp->private_data = rmtfs_mem;
+
+ return 0;
+}
+static ssize_t qcom_rmtfs_mem_read(struct file *filp,
+ char __user *buf, size_t count, loff_t *f_pos)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = filp->private_data;
+
+ if (*f_pos >= rmtfs_mem->size)
+ return 0;
+
+ if (*f_pos + count >= rmtfs_mem->size)
+ count = rmtfs_mem->size - *f_pos;
+
+ if (copy_to_user(buf, rmtfs_mem->base + *f_pos, count))
+ return -EFAULT;
+
+ *f_pos += count;
+ return count;
+}
+
+static ssize_t qcom_rmtfs_mem_write(struct file *filp,
+ const char __user *buf, size_t count,
+ loff_t *f_pos)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = filp->private_data;
+
+ if (*f_pos >= rmtfs_mem->size)
+ return 0;
+
+ if (*f_pos + count >= rmtfs_mem->size)
+ count = rmtfs_mem->size - *f_pos;
+
+ if (copy_from_user(rmtfs_mem->base + *f_pos, buf, count))
+ return -EFAULT;
+
+ *f_pos += count;
+ return count;
+}
+
+static int qcom_rmtfs_mem_release(struct inode *inode, struct file *filp)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = filp->private_data;
+
+ put_device(&rmtfs_mem->dev);
+
+ return 0;
+}
+
+static const struct file_operations qcom_rmtfs_mem_fops = {
+ .owner = THIS_MODULE,
+ .open = qcom_rmtfs_mem_open,
+ .read = qcom_rmtfs_mem_read,
+ .write = qcom_rmtfs_mem_write,
+ .release = qcom_rmtfs_mem_release,
+ .llseek = default_llseek,
+};
+
+static void qcom_rmtfs_mem_release_device(struct device *dev)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = container_of(dev,
+ struct qcom_rmtfs_mem,
+ dev);
+
+ kfree(rmtfs_mem);
+}
+
+static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
+{
+ struct device_node *node = pdev->dev.of_node;
+ struct reserved_mem *rmem;
+ struct qcom_rmtfs_mem *rmtfs_mem;
+ u32 client_id;
+ int ret;
+
+ rmem = of_reserved_mem_get(node);
+ if (!rmem) {
+ dev_err(&pdev->dev, "failed to acquire memory region\n");
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32(node, "qcom,client-id", &client_id);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to parse \"qcom,client-id\"\n");
+ return ret;
+
+ }
+
+ rmtfs_mem = kzalloc(sizeof(*rmtfs_mem), GFP_KERNEL);
+ if (!rmtfs_mem)
+ return -ENOMEM;
+
+ rmtfs_mem->addr = rmem->base;
+ rmtfs_mem->client_id = client_id;
+ rmtfs_mem->size = rmem->size;
+
+ device_initialize(&rmtfs_mem->dev);
+ rmtfs_mem->dev.parent = &pdev->dev;
+ rmtfs_mem->dev.groups = qcom_rmtfs_mem_groups;
+
+ rmtfs_mem->base = devm_memremap(&rmtfs_mem->dev, rmtfs_mem->addr,
+ rmtfs_mem->size, MEMREMAP_WC);
+ if (IS_ERR(rmtfs_mem->base)) {
+ dev_err(&pdev->dev, "failed to remap rmtfs_mem region\n");
+ ret = PTR_ERR(rmtfs_mem->base);
+ goto put_device;
+ }
+
+ cdev_init(&rmtfs_mem->cdev, &qcom_rmtfs_mem_fops);
+ rmtfs_mem->cdev.owner = THIS_MODULE;
+
+ dev_set_name(&rmtfs_mem->dev, "qcom_rmtfs_mem%d", client_id);
+ rmtfs_mem->dev.id = client_id;
+ rmtfs_mem->dev.devt = MKDEV(MAJOR(qcom_rmtfs_mem_major), client_id);
+
+ ret = cdev_device_add(&rmtfs_mem->cdev, &rmtfs_mem->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add cdev: %d\n", ret);
+ goto put_device;
+ }
+
+ rmtfs_mem->dev.release = qcom_rmtfs_mem_release_device;
+
+ dev_set_drvdata(&pdev->dev, rmtfs_mem);
+
+ return 0;
+
+remove_cdev:
+ cdev_device_del(&rmtfs_mem->cdev, &rmtfs_mem->dev);
+put_device:
+ put_device(&rmtfs_mem->dev);
+
+ return ret;
+}
+
+static int qcom_rmtfs_mem_remove(struct platform_device *pdev)
+{
+ struct qcom_rmtfs_mem *rmtfs_mem = dev_get_drvdata(&pdev->dev);
+
+ cdev_device_del(&rmtfs_mem->cdev, &rmtfs_mem->dev);
+ put_device(&rmtfs_mem->dev);
+
+ return 0;
+}
+
+static const struct of_device_id qcom_rmtfs_mem_of_match[] = {
+ { .compatible = "qcom,rmtfs-mem" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, qcom_rmtfs_mem_of_match);
+
+static struct platform_driver qcom_rmtfs_mem_driver = {
+ .probe = qcom_rmtfs_mem_probe,
+ .remove = qcom_rmtfs_mem_remove,
+ .driver = {
+ .name = "qcom_rmtfs_mem",
+ .of_match_table = qcom_rmtfs_mem_of_match,
+ },
+};
+
+static int qcom_rmtfs_mem_init(void)
+{
+ int ret;
+
+ ret = alloc_chrdev_region(&qcom_rmtfs_mem_major, 0,
+ QCOM_RMTFS_MEM_DEV_MAX, "qcom_rmtfs_mem");
+ if (ret < 0) {
+ pr_err("qcom_rmtfs_mem: failed to allocate char dev region\n");
+ return ret;
+ }
+
+ ret = platform_driver_register(&qcom_rmtfs_mem_driver);
+ if (ret < 0) {
+ pr_err("qcom_rmtfs_mem: failed to register rmtfs_mem driver\n");
+ unregister_chrdev_region(qcom_rmtfs_mem_major,
+ QCOM_RMTFS_MEM_DEV_MAX);
+ }
+
+ return ret;
+}
+module_init(qcom_rmtfs_mem_init);
+
+static void qcom_rmtfs_mem_exit(void)
+{
+ platform_driver_unregister(&qcom_rmtfs_mem_driver);
+ unregister_chrdev_region(qcom_rmtfs_mem_major, QCOM_RMTFS_MEM_DEV_MAX);
+}
+module_exit(qcom_rmtfs_mem_exit);
--
2.12.0
^ permalink raw reply related
* [PATCH v3 3/5] dt-binding: soc: qcom: Add binding for rmtfs memory
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171005033258.12825-1-bjorn.andersson@linaro.org>
This adds the binding for describing shared memory used to exchange file
system blocks between the RMTFS client and service. A client for this is
generally found in the modem firmware and is used for accessing
persistent storage for things such as radio calibration.
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v2:
- Renamed compatible to "rmtfs-mem" in attempt to clarify that this is not a
file system, but some chunk of memory.
Changed since v1:
- Memory described in a single reserved-memory node, rather than by reference
from a "dummy" node
- qcom,vmdid added
.../bindings/reserved-memory/qcom,rmtfs-mem.txt | 51 ++++++++++++++++++++++
1 file changed, 51 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.txt
diff --git a/Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.txt b/Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.txt
new file mode 100644
index 000000000000..8562ba1dce69
--- /dev/null
+++ b/Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.txt
@@ -0,0 +1,51 @@
+Qualcomm Remote File System Memory binding
+
+This binding describes the Qualcomm remote filesystem memory, which serves the
+purpose of describing the shared memory region used for remote processors to
+access block device data using the Remote Filesystem protocol.
+
+- compatible:
+ Usage: required
+ Value type: <stringlist>
+ Definition: must be:
+ "qcom,rmtfs-mem"
+
+- reg:
+ Usage: required for static allocation
+ Value type: <prop-encoded-array>
+ Definition: must specify base address and size of the memory region,
+ as described in reserved-memory.txt
+
+- size:
+ Usage: required for dynamic allocation
+ Value type: <prop-encoded-array>
+ Definition: must specify a size of the memory region, as described in
+ reserved-memory.txt
+
+- qcom,client-id:
+ Usage: required
+ Value type: <u32>
+ Definition: identifier of the client to use this region for buffers.
+
+- qcom,vmid:
+ Usage: optional
+ Value type: <u32>
+ Definition: vmid of the remote processor, to set up memory protection.
+
+= EXAMPLE
+The following example shows the remote filesystem memory setup for APQ8016,
+with the rmtfs region for the Hexagon DSP (id #1) located at 0x86700000.
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ rmtfs at 86700000 {
+ compatible = "qcom,rmtfs-mem";
+ reg = <0x0 0x86700000 0x0 0xe0000>;
+ no-map;
+
+ qcom,client-id = <1>;
+ };
+ };
--
2.12.0
^ permalink raw reply related
* [PATCH v3 3/5] dt-binding: soc: qcom: Add binding for rmtfs memory
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: Andy Gross
Cc: Anton Vorontsov, Colin Cross, David Brown, Frank Rowand,
Kees Cook, Rob Herring, Tony Luck, devicetree, linux-arm-kernel,
linux-arm-msm, linux-kernel, linux-soc
In-Reply-To: <20171005033258.12825-1-bjorn.andersson@linaro.org>
This adds the binding for describing shared memory used to exchange file
system blocks between the RMTFS client and service. A client for this is
generally found in the modem firmware and is used for accessing
persistent storage for things such as radio calibration.
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v2:
- Renamed compatible to "rmtfs-mem" in attempt to clarify that this is not a
file system, but some chunk of memory.
Changed since v1:
- Memory described in a single reserved-memory node, rather than by reference
from a "dummy" node
- qcom,vmdid added
.../bindings/reserved-memory/qcom,rmtfs-mem.txt | 51 ++++++++++++++++++++++
1 file changed, 51 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.txt
diff --git a/Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.txt b/Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.txt
new file mode 100644
index 000000000000..8562ba1dce69
--- /dev/null
+++ b/Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.txt
@@ -0,0 +1,51 @@
+Qualcomm Remote File System Memory binding
+
+This binding describes the Qualcomm remote filesystem memory, which serves the
+purpose of describing the shared memory region used for remote processors to
+access block device data using the Remote Filesystem protocol.
+
+- compatible:
+ Usage: required
+ Value type: <stringlist>
+ Definition: must be:
+ "qcom,rmtfs-mem"
+
+- reg:
+ Usage: required for static allocation
+ Value type: <prop-encoded-array>
+ Definition: must specify base address and size of the memory region,
+ as described in reserved-memory.txt
+
+- size:
+ Usage: required for dynamic allocation
+ Value type: <prop-encoded-array>
+ Definition: must specify a size of the memory region, as described in
+ reserved-memory.txt
+
+- qcom,client-id:
+ Usage: required
+ Value type: <u32>
+ Definition: identifier of the client to use this region for buffers.
+
+- qcom,vmid:
+ Usage: optional
+ Value type: <u32>
+ Definition: vmid of the remote processor, to set up memory protection.
+
+= EXAMPLE
+The following example shows the remote filesystem memory setup for APQ8016,
+with the rmtfs region for the Hexagon DSP (id #1) located at 0x86700000.
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ rmtfs@86700000 {
+ compatible = "qcom,rmtfs-mem";
+ reg = <0x0 0x86700000 0x0 0xe0000>;
+ no-map;
+
+ qcom,client-id = <1>;
+ };
+ };
--
2.12.0
^ permalink raw reply related
* [PATCH v3 2/5] of: reserved_mem: Accessor for acquiring reserved_mem
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171005033258.12825-1-bjorn.andersson@linaro.org>
In some cases drivers referencing a reserved-memory region might want to
remap the entire region, but when defining the reserved-memory by "size"
the client driver has no means to know the associated base address of
the reserved memory region.
This patch adds an accessor for such drivers to acquire a handle to
their associated reserved-memory for this purpose.
A complicating factor for the implementation is that the reserved_mem
objects are created from the flattened DeviceTree, as such we can't
use the device_node address for comparison. Fortunately the name of the
node will be used as "name" of the reserved_mem and will be used when
building the full_name, so we can compare the "name" with the basename
of the full_name to find the match.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v2:
- None
Changes since v1:
- Previous patch provided interface to resolve memory-region reference, instead
of direct lookup by device_node
drivers/of/of_reserved_mem.c | 26 ++++++++++++++++++++++++++
include/linux/of_reserved_mem.h | 5 +++++
2 files changed, 31 insertions(+)
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index d507c3569a88..b40cfce68fd4 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -397,3 +397,29 @@ void of_reserved_mem_device_release(struct device *dev)
rmem->ops->device_release(rmem, dev);
}
EXPORT_SYMBOL_GPL(of_reserved_mem_device_release);
+
+/**
+ * of_reserved_mem_get() - acquire reserved_mem from a device node
+ * @np: node pointer of the desired reserved-memory region
+ *
+ * This function allows drivers to acquire a reference to the reserved_mem
+ * struct based on a device node handle.
+ *
+ * Returns a reserved_mem reference, or NULL on error.
+ */
+struct reserved_mem *of_reserved_mem_get(struct device_node *np)
+{
+ const char *name;
+ int i;
+
+ if (!np->full_name)
+ return NULL;
+
+ name = kbasename(np->full_name);
+ for (i = 0; i < reserved_mem_count; i++)
+ if (!strcmp(reserved_mem[i].name, name))
+ return &reserved_mem[i];
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(of_reserved_mem_get);
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index f8e1992d6423..91b1eb5076e4 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -44,6 +44,7 @@ int early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
void fdt_init_reserved_mem(void);
void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
phys_addr_t base, phys_addr_t size);
+struct reserved_mem *of_reserved_mem_get(struct device_node *np);
#else
static inline int of_reserved_mem_device_init_by_idx(struct device *dev,
struct device_node *np, int idx)
@@ -55,6 +56,10 @@ static inline void of_reserved_mem_device_release(struct device *pdev) { }
static inline void fdt_init_reserved_mem(void) { }
static inline void fdt_reserved_mem_save_node(unsigned long node,
const char *uname, phys_addr_t base, phys_addr_t size) { }
+static inline struct reserved_mem *of_reserved_mem_get(struct device_node *np)
+{
+ return NULL;
+}
#endif
/**
--
2.12.0
^ permalink raw reply related
* [PATCH v3 2/5] of: reserved_mem: Accessor for acquiring reserved_mem
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: Andy Gross, Frank Rowand, Rob Herring
Cc: Anton Vorontsov, Colin Cross, David Brown, Kees Cook, Tony Luck,
devicetree, linux-arm-kernel, linux-arm-msm, linux-kernel,
linux-soc
In-Reply-To: <20171005033258.12825-1-bjorn.andersson@linaro.org>
In some cases drivers referencing a reserved-memory region might want to
remap the entire region, but when defining the reserved-memory by "size"
the client driver has no means to know the associated base address of
the reserved memory region.
This patch adds an accessor for such drivers to acquire a handle to
their associated reserved-memory for this purpose.
A complicating factor for the implementation is that the reserved_mem
objects are created from the flattened DeviceTree, as such we can't
use the device_node address for comparison. Fortunately the name of the
node will be used as "name" of the reserved_mem and will be used when
building the full_name, so we can compare the "name" with the basename
of the full_name to find the match.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v2:
- None
Changes since v1:
- Previous patch provided interface to resolve memory-region reference, instead
of direct lookup by device_node
drivers/of/of_reserved_mem.c | 26 ++++++++++++++++++++++++++
include/linux/of_reserved_mem.h | 5 +++++
2 files changed, 31 insertions(+)
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index d507c3569a88..b40cfce68fd4 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -397,3 +397,29 @@ void of_reserved_mem_device_release(struct device *dev)
rmem->ops->device_release(rmem, dev);
}
EXPORT_SYMBOL_GPL(of_reserved_mem_device_release);
+
+/**
+ * of_reserved_mem_get() - acquire reserved_mem from a device node
+ * @np: node pointer of the desired reserved-memory region
+ *
+ * This function allows drivers to acquire a reference to the reserved_mem
+ * struct based on a device node handle.
+ *
+ * Returns a reserved_mem reference, or NULL on error.
+ */
+struct reserved_mem *of_reserved_mem_get(struct device_node *np)
+{
+ const char *name;
+ int i;
+
+ if (!np->full_name)
+ return NULL;
+
+ name = kbasename(np->full_name);
+ for (i = 0; i < reserved_mem_count; i++)
+ if (!strcmp(reserved_mem[i].name, name))
+ return &reserved_mem[i];
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(of_reserved_mem_get);
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index f8e1992d6423..91b1eb5076e4 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -44,6 +44,7 @@ int early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
void fdt_init_reserved_mem(void);
void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
phys_addr_t base, phys_addr_t size);
+struct reserved_mem *of_reserved_mem_get(struct device_node *np);
#else
static inline int of_reserved_mem_device_init_by_idx(struct device *dev,
struct device_node *np, int idx)
@@ -55,6 +56,10 @@ static inline void of_reserved_mem_device_release(struct device *pdev) { }
static inline void fdt_init_reserved_mem(void) { }
static inline void fdt_reserved_mem_save_node(unsigned long node,
const char *uname, phys_addr_t base, phys_addr_t size) { }
+static inline struct reserved_mem *of_reserved_mem_get(struct device_node *np)
+{
+ return NULL;
+}
#endif
/**
--
2.12.0
^ permalink raw reply related
* [PATCH v3 1/5] of/platform: Generalize /reserved-memory handling
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171005033258.12825-1-bjorn.andersson@linaro.org>
By iterating over all /reserved-memory child nodes and match each one to
a list of compatibles that we want to treat specially, we can easily
extend the list of compatibles to handle - without having to resort to
of_platform_populate() that would create unnecessary platform_devices.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v2:
- Simplify logic per Rob's suggestion.
Changes since v1:
- New patch
drivers/of/platform.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b19524623498..ee89f096f0f3 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -497,6 +497,11 @@ int of_platform_default_populate(struct device_node *root,
EXPORT_SYMBOL_GPL(of_platform_default_populate);
#ifndef CONFIG_PPC
+static const struct of_device_id reserved_mem_matches[] = {
+ { .compatible = "ramoops" },
+ {}
+};
+
static int __init of_platform_default_populate_init(void)
{
struct device_node *node;
@@ -505,15 +510,12 @@ static int __init of_platform_default_populate_init(void)
return -ENODEV;
/*
- * Handle ramoops explicitly, since it is inside /reserved-memory,
- * which lacks a "compatible" property.
+ * Handle certain compatibles explicitly, since we don't want to create
+ * platform_devices for every node in /reserved-memory with a
+ * "compatible",
*/
- node = of_find_node_by_path("/reserved-memory");
- if (node) {
- node = of_find_compatible_node(node, NULL, "ramoops");
- if (node)
- of_platform_device_create(node, NULL, NULL);
- }
+ for_each_matching_node(node, reserved_mem_matches)
+ of_platform_device_create(node, NULL, NULL);
/* Populate everything else. */
of_platform_default_populate(NULL, NULL, NULL);
--
2.12.0
^ permalink raw reply related
* [PATCH v3 1/5] of/platform: Generalize /reserved-memory handling
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: Andy Gross, Anton Vorontsov, Colin Cross, Frank Rowand, Kees Cook,
Rob Herring, Tony Luck
Cc: devicetree, linux-arm-msm, linux-kernel, David Brown, linux-soc,
linux-arm-kernel
In-Reply-To: <20171005033258.12825-1-bjorn.andersson@linaro.org>
By iterating over all /reserved-memory child nodes and match each one to
a list of compatibles that we want to treat specially, we can easily
extend the list of compatibles to handle - without having to resort to
of_platform_populate() that would create unnecessary platform_devices.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Changes since v2:
- Simplify logic per Rob's suggestion.
Changes since v1:
- New patch
drivers/of/platform.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b19524623498..ee89f096f0f3 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -497,6 +497,11 @@ int of_platform_default_populate(struct device_node *root,
EXPORT_SYMBOL_GPL(of_platform_default_populate);
#ifndef CONFIG_PPC
+static const struct of_device_id reserved_mem_matches[] = {
+ { .compatible = "ramoops" },
+ {}
+};
+
static int __init of_platform_default_populate_init(void)
{
struct device_node *node;
@@ -505,15 +510,12 @@ static int __init of_platform_default_populate_init(void)
return -ENODEV;
/*
- * Handle ramoops explicitly, since it is inside /reserved-memory,
- * which lacks a "compatible" property.
+ * Handle certain compatibles explicitly, since we don't want to create
+ * platform_devices for every node in /reserved-memory with a
+ * "compatible",
*/
- node = of_find_node_by_path("/reserved-memory");
- if (node) {
- node = of_find_compatible_node(node, NULL, "ramoops");
- if (node)
- of_platform_device_create(node, NULL, NULL);
- }
+ for_each_matching_node(node, reserved_mem_matches)
+ of_platform_device_create(node, NULL, NULL);
/* Populate everything else. */
of_platform_default_populate(NULL, NULL, NULL);
--
2.12.0
^ permalink raw reply related
* [PATCH v3 0/5] Qualcomm remote filesystem shared memory driver
From: Bjorn Andersson @ 2017-10-05 3:32 UTC (permalink / raw)
To: linux-arm-kernel
Some remote processors (in particular the modem) found in Qualcomm platforms
stores configuration parameters and other data in a file system. As the remotes
does not have direct storage access it needs to relay block accesses through a
service running on the application CPU.
The memory is described in DeviceTree by a new reserved-memory compatible and
the implementation provides the user space service a read/write interface to
this chunk of memory.
Bjorn Andersson (5):
of/platform: Generalize /reserved-memory handling
of: reserved_mem: Accessor for acquiring reserved_mem
dt-binding: soc: qcom: Add binding for rmtfs memory
soc: qcom: Remote filesystem memory driver
arm64: dts: msm8916: Mark rmtfs node as qcom,rmtfs-mem compatible
.../bindings/reserved-memory/qcom,rmtfs-mem.txt | 51 ++++
arch/arm64/boot/dts/qcom/msm8916.dtsi | 3 +
drivers/of/of_reserved_mem.c | 26 ++
drivers/of/platform.c | 19 +-
drivers/soc/qcom/Kconfig | 11 +
drivers/soc/qcom/Makefile | 1 +
drivers/soc/qcom/rmtfs_mem.c | 272 +++++++++++++++++++++
include/linux/of_reserved_mem.h | 5 +
8 files changed, 380 insertions(+), 8 deletions(-)
create mode 100644 Documentation/devicetree/bindings/reserved-memory/qcom,rmtfs-mem.txt
create mode 100644 drivers/soc/qcom/rmtfs_mem.c
--
2.12.0
^ permalink raw reply
* Re: Line ending normalization doesn't work as expected
From: Junio C Hamano @ 2017-10-05 3:31 UTC (permalink / raw)
To: Torsten Bögershausen; +Cc: Robert Dailey, Git
In-Reply-To: <xmqq7ewa9xw6.fsf@gitster.mtv.corp.google.com>
Junio C Hamano <gitster@pobox.com> writes:
> Both this and its "git read-tree --empty" cousin share a grave
> issue. The "git add ." step would mean that before doing these
> commands, your working tree must be truly clean, i.e. the paths
> in the filesystem known to the index must match what is in the
> index (modulo the line-ending gotcha you are trying to correct),
> *AND* there must be *NO* untracked paths you do not want to add
> in the working tree.
>
> That is a reason why we should solve it differently. Perhaps adding
> a new option "git add --rehash" to tell Git "Hey, you may think some
> paths in the index and in the working tree are identical and no need
> to re-register, but you are WRONG. For each path in the index,
> remove it and then register the object by hashing the contents from
> the filesystem afresh!" would be the best way to go.
Here is just to illustrate the direction I was heading to in the
above. This is not even compile tested and I won't guarantee what
corner cases there are, though.
In a true production code, we shouldn't be using string-list with
two loops, but I just didn't want to spend more braincycles worrying
about removing from the list and then adding to it, both inside a
single loop that iterates over it in a mere illustration patch.
The second loop uses a simple "remove then add", but I think it
should rather be a "mark ce that it will _never_ match anything on
the working tree" followed by "add_file_to_cache()". Currently we
do not have the "mark ce that it never matches" operation that lets
us bypass the comparison with the current cache entry (with safecrlf
thing that interferes), but we can afford to use a (in-core only)
bit in the ce flags word to represent this and plumb it through.
That way, we will still preserve the executable bit from the
original entry, hopefully ;-)
builtin/add.c | 42 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/builtin/add.c b/builtin/add.c
index 5d5773d5cd..264f84dbe7 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -26,6 +26,7 @@ static const char * const builtin_add_usage[] = {
};
static int patch_interactive, add_interactive, edit_interactive;
static int take_worktree_changes;
+static int rehash;
struct update_callback_data {
int flags;
@@ -121,6 +122,41 @@ int add_files_to_cache(const char *prefix,
return !!data.add_errors;
}
+static int rehash_tracked_files(const char *prefix, const struct pathspec *pathspec,
+ int flags)
+{
+ struct string_list paths = STRING_LIST_INIT_DUP;
+ struct string_list_item *path;
+ int i, retval = 0;
+
+ for (i = 0; i < active_nr; i++) {
+ struct cache_entry *ce = active_cache[i];
+
+ if (ce_stage(ce))
+ continue; /* do not touch unmerged paths */
+ if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode))
+ continue; /* do not touch non blobs */
+ if (pathspec && !ce_path_match(ce, pathspec, NULL))
+ continue;
+ string_list_append(&paths, ce->name);
+ }
+
+ for_each_string_list_item(path, &paths) {
+ /*
+ * Having a blob contaminated with CR will trigger the
+ * safe-crlf kludge, avoidance of which is the primary
+ * thing this helper function exists. Remove it and
+ * then re-add it. Note that this may lose executable
+ * bit on a filesystem that lacks it.
+ */
+ remove_file_from_cache(path->string);
+ add_file_to_cache(path->string, flags);
+ }
+
+ string_list_clear(&paths, 0);
+ return retval;
+}
+
static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix)
{
char *seen;
@@ -274,6 +310,7 @@ static struct option builtin_add_options[] = {
OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
+ OPT_BOOL(0, "rehash", &rehash, N_("really update tracked files")),
OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
{ OPTION_CALLBACK, 0, "ignore-removal", &addremove_explicit,
@@ -498,7 +535,10 @@ int cmd_add(int argc, const char **argv, const char *prefix)
plug_bulk_checkin();
- exit_status |= add_files_to_cache(prefix, &pathspec, flags);
+ if (rehash)
+ exit_status |= rehash_tracked_files(prefix, &pathspec, flags);
+ else
+ exit_status |= add_files_to_cache(prefix, &pathspec, flags);
if (add_new_files)
exit_status |= add_files(&dir, flags);
^ permalink raw reply related
* Re: [Qemu-devel] [Qemu-arm] [PATCH 16/20] target/arm: Factor out "get mmuidx for specified security state"
From: Philippe Mathieu-Daudé @ 2017-10-05 3:29 UTC (permalink / raw)
To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches
In-Reply-To: <1506092407-26985-17-git-send-email-peter.maydell@linaro.org>
On 09/22/2017 12:00 PM, Peter Maydell wrote:
> For the SG instruction and secure function return we are going
> to want to do memory accesses using the MMU index of the CPU
> in secure state, even though the CPU is currently in non-secure
> state. Write arm_v7m_mmu_idx_for_secstate() to do this job,
> and use it in cpu_mmu_index().
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> target/arm/cpu.h | 32 +++++++++++++++++++++-----------
> 1 file changed, 21 insertions(+), 11 deletions(-)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 70c1f85..89d49cd 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -2329,23 +2329,33 @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
> }
> }
>
> +/* Return the MMU index for a v7M CPU in the specified security state */
> +static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
> + bool secstate)
> +{
> + int el = arm_current_el(env);
> + ARMMMUIdx mmu_idx;
> +
> + if (el == 0) {
> + mmu_idx = secstate ? ARMMMUIdx_MSUser : ARMMMUIdx_MUser;
> + } else {
> + mmu_idx = secstate ? ARMMMUIdx_MSPriv : ARMMMUIdx_MPriv;
> + }
> +
> + if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
> + mmu_idx = secstate ? ARMMMUIdx_MSNegPri : ARMMMUIdx_MNegPri;
> + }
> +
> + return mmu_idx;
> +}
> +
> /* Determine the current mmu_idx to use for normal loads/stores */
> static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
> {
> int el = arm_current_el(env);
>
> if (arm_feature(env, ARM_FEATURE_M)) {
> - ARMMMUIdx mmu_idx;
> -
> - if (el == 0) {
> - mmu_idx = env->v7m.secure ? ARMMMUIdx_MSUser : ARMMMUIdx_MUser;
> - } else {
> - mmu_idx = env->v7m.secure ? ARMMMUIdx_MSPriv : ARMMMUIdx_MPriv;
> - }
> -
> - if (armv7m_nvic_neg_prio_requested(env->nvic, env->v7m.secure)) {
> - mmu_idx = env->v7m.secure ? ARMMMUIdx_MSNegPri : ARMMMUIdx_MNegPri;
> - }
> + ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
>
> return arm_to_core_mmu_idx(mmu_idx);
> }
>
^ permalink raw reply
* Re: [PATCH 09/12] of: overlay: avoid race condition between applying multiple overlays
From: Frank Rowand @ 2017-10-05 3:29 UTC (permalink / raw)
To: Rob Herring
Cc: Pantelis Antoniou, David Airlie, Jyri Sarha,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
Mark Rutland, Tomi Valkeinen, dri-devel
In-Reply-To: <CAL_JsqKHkPp6M-aE9yVM1Bs599NTpjV33hGXvnOo-W8KKPPsJw@mail.gmail.com>
On 10/04/17 08:19, Rob Herring wrote:
> On Mon, Oct 2, 2017 at 10:53 PM, <frowand.list@gmail.com> wrote:
>> From: Frank Rowand <frank.rowand@sony.com>
>>
>> The process of applying an overlay consists of:
>> - unflatten an overlay FDT (flattened device tree) into an
>> EDT (expanded device tree)
>> - fixup the phandle values in the overlay EDT to fit in a
>> range above the phandle values in the live device tree
>> - create the overlay changeset to reflect the contents of
>> the overlay EDT
>> - apply the overlay changeset, to modify the live device tree,
>> potentially changing the maximum phandle value in the live
>> device tree
>>
>> There is currently no protection against two overlay applies
>> concurrently determining what range of phandle values are in use
>> in the live device tree, and subsequently changing that range.
>> Add a mutex to prevent multiple overlay applies from occurring
>> simultaneously.
>>
>> Ignoring 2 checkpatch warnings: Prefer using '"%s...", __func__'
>> so that the WARN() string will be more easily grepped.
>>
>> Signed-off-by: Frank Rowand <frank.rowand@sony.com>
>> ---
>> drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c | 7 +++++++
>> drivers/of/overlay.c | 22 ++++++++++++++++++++++
>> drivers/of/unittest.c | 21 +++++++++++++++++++++
>> include/linux/of.h | 19 +++++++++++++++++++
>> 4 files changed, 69 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
>> index 7a7be0515bfd..c99f7924b1c6 100644
>> --- a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
>> +++ b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
>> @@ -221,6 +221,11 @@ static void __init tilcdc_convert_slave_node(void)
>> goto out;
>> }
>>
>> + /*
>> + * protect from of_resolve_phandles() through of_overlay_apply()
>> + */
>> + of_overlay_mutex_lock();
>> +
>
> We can't be relying on callers to get the locking right...
Agreed.
>
>> overlay = tilcdc_get_overlay(&kft);
>> if (!overlay)
>> goto out;
>> @@ -256,6 +261,8 @@ static void __init tilcdc_convert_slave_node(void)
>> pr_info("%s: ti,tilcdc,slave node successfully converted\n",
>> __func__);
>> out:
>> + of_overlay_mutex_unlock();
>> +
>> kfree_table_free(&kft);
>> of_node_put(i2c);
>> of_node_put(slave);
>> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
>> index a0d3222febdc..4ed372af6ce7 100644
>> --- a/drivers/of/overlay.c
>> +++ b/drivers/of/overlay.c
>> @@ -71,6 +71,28 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs,
>> const struct device_node *overlay_node,
>> bool is_symbols_node);
>>
>> +/*
>> + * of_resolve_phandles() finds the largest phandle in the live tree.
>> + * of_overlay_apply() may add a larger phandle to the live tree.
>> + * Do not allow race between two overlays being applied simultaneously:
>> + * mutex_lock(&of_overlay_phandle_mutex)
>> + * of_resolve_phandles()
>> + * of_overlay_apply()
>> + * mutex_unlock(&of_overlay_phandle_mutex)
>
> Why do these need to be separate functions? I think I mentioned it
> before, but essentially overlay_data_add() should be part of the
> overlay API. We may need to allow for callers to do each step, but
> generally I think the interface should just be "apply this fdt blob".
Yes, that is where I want to end up.
>
> Rob
>
^ permalink raw reply
* Re: [PATCH 0/2] powerpc/xive: fix CPU hot unplug
From: Nikunj A Dadhania @ 2017-10-05 3:29 UTC (permalink / raw)
To: David Gibson, Cédric Le Goater
Cc: linuxppc-dev, Michael Ellerman, Benjamin Herrenschmidt
In-Reply-To: <20171003065858.GL3260@umbus.fritz.box>
David Gibson <david@gibson.dropbear.id.au> writes:
> On Tue, Oct 03, 2017 at 08:24:07AM +0200, C=C3=A9dric Le Goater wrote:
>> On 10/03/2017 05:36 AM, David Gibson wrote:
>> > On Mon, Oct 02, 2017 at 06:27:20PM +0200, C=C3=A9dric Le Goater wrote:
>> >> On 09/23/2017 10:26 AM, C=C3=A9dric Le Goater wrote:
>> >>> Hi,
>> >>>
>> >>> Here are a couple of small fixes to support CPU hot unplug. There are
>> >>> still some issues to be investigated as, in some occasions, after a
>> >>> couple of plug and unplug, the cpu which was removed receives a 'los=
t'
>> >>> interrupt. This showed to be the decrementer under QEMU.
>> >>
>> >> So this seems to be a QEMU issue only which can be solved by=20
>> >> removing the DEE bit from the LPCR on P9 processor when the CPU=20
>> >> is stopped in rtas. PECE3 bit on P8 processors.=20
>> >>
>> >> I think these patches are valuable fixes for 4.14. The first=20
>> >> is trivial and the second touches the common xive part but it
>> >> is only called on the pseries platform.=20=20
>> >>
>> >> Could you please take a look ?
>> >=20
>> > Sorry, I think I've missed something here.
>> >=20
>> > Is there a qemu bug involved in this? Has there been a patch sent
>> > that I didn't spot?
>>=20
>>=20
>> No, not yet, but I will today probably. something like below to stop
>> the decrementer when a CPU is stopped:
>>=20
>> --- qemu.git.orig/hw/ppc/spapr_rtas.c
>> +++ qemu.git/hw/ppc/spapr_rtas.c
>> @@ -174,6 +174,15 @@ static void rtas_start_cpu(PowerPCCPU *c
>> kvm_cpu_synchronize_state(cs);
>>=20=09=20
>> env->msr =3D (1ULL << MSR_SF) | (1ULL << MSR_ME);
>> +
>> + /* Enable DECR interrupt */
>> + if (env->mmu_model =3D=3D POWERPC_MMU_3_00) {
>> + env->spr[SPR_LPCR] |=3D LPCR_DEE;
>> + } else {
>> + /* P7 and P8 both have same bit for DECR */
>> + env->spr[SPR_LPCR] |=3D LPCR_P8_PECE3;
>> + }
>> +
>> env->nip =3D start;
>> env->gpr[3] =3D r3;
>> cs->halted =3D 0;
>> @@ -210,6 +219,13 @@ static void rtas_stop_self(PowerPCCPU *c
>> * no need to bother with specific bits, we just clear it.
>> */
>> env->msr =3D 0;
>> +
>> + if (env->mmu_model =3D=3D POWERPC_MMU_3_00) {
>> + env->spr[SPR_LPCR] &=3D ~LPCR_DEE;
>> + } else {
>> + /* P7 and P8 both have same bit for DECR */
>> + env->spr[SPR_LPCR] &=3D ~LPCR_P8_PECE3;
>> + }
>> }
>>=20=09=20
>> static inline int sysparm_st(target_ulong addr, target_ulong len,
>>=20=09
>> I haven't yet because I fail to understand why the decrementer is not=20
>> interrupting the dying CPU under xics as it is the case under XIVE.
>
> Oh.. ok. This sounds very similar to the problem Nikunj hit under TCG
> with decrementer interrupts waking up a supposedly dead CPU. He had a
> couple of proposed fixes, but we got bogged down trying to work out
> why (with TCG at least).
Yeah, I wasnt able to get to the exact reason for that.
Regards
Nikunj
^ permalink raw reply
* cron job: media_tree daily build: ERRORS
From: Hans Verkuil @ 2017-10-05 3:29 UTC (permalink / raw)
To: linux-media
This message is generated daily by a cron job that builds media_tree for
the kernels and architectures in the list below.
Results of the daily build of media_tree:
date: Thu Oct 5 05:00:07 CEST 2017
media-tree git hash: a8c779eb056e9874c6278151ade857c3ac227db9
media_build git hash: b829b621b4c2e6c5cbedbd1ce62b4e958f7d13a4
v4l-utils git hash: 997ed5a4abba619282d9ffb8bb173e8589176d73
gcc version: i686-linux-gcc (GCC) 7.1.0
sparse version: v0.5.0
smatch version: v0.5.0-3553-g78b2ea6
host hardware: x86_64
host os: 4.12.0-164
linux-git-arm-at91: ERRORS
linux-git-arm-davinci: ERRORS
linux-git-arm-multi: ERRORS
linux-git-arm-pxa: ERRORS
linux-git-arm-stm32: ERRORS
linux-git-blackfin-bf561: ERRORS
linux-git-i686: OK
linux-git-m32r: WARNINGS
linux-git-mips: ERRORS
linux-git-powerpc64: OK
linux-git-sh: ERRORS
linux-git-x86_64: OK
linux-2.6.36.4-i686: ERRORS
linux-2.6.37.6-i686: ERRORS
linux-2.6.38.8-i686: ERRORS
linux-2.6.39.4-i686: ERRORS
linux-3.0.60-i686: ERRORS
linux-3.1.10-i686: ERRORS
linux-3.2.37-i686: ERRORS
linux-3.3.8-i686: ERRORS
linux-3.4.27-i686: ERRORS
linux-3.5.7-i686: ERRORS
linux-3.6.11-i686: ERRORS
linux-3.7.4-i686: ERRORS
linux-3.8-i686: ERRORS
linux-3.9.2-i686: ERRORS
linux-3.10.1-i686: ERRORS
linux-3.11.1-i686: ERRORS
linux-3.12.67-i686: ERRORS
linux-3.13.11-i686: ERRORS
linux-3.14.9-i686: ERRORS
linux-3.15.2-i686: ERRORS
linux-3.16.7-i686: ERRORS
linux-3.17.8-i686: ERRORS
linux-3.18.7-i686: ERRORS
linux-3.19-i686: ERRORS
linux-4.0.9-i686: ERRORS
linux-4.1.33-i686: ERRORS
linux-4.2.8-i686: ERRORS
linux-4.3.6-i686: ERRORS
linux-4.4.22-i686: ERRORS
linux-4.5.7-i686: ERRORS
linux-4.6.7-i686: ERRORS
linux-4.7.5-i686: ERRORS
linux-4.8-i686: ERRORS
linux-4.9.26-i686: ERRORS
linux-4.10.14-i686: ERRORS
linux-4.11-i686: ERRORS
linux-4.12.1-i686: ERRORS
linux-4.13-i686: ERRORS
linux-2.6.36.4-x86_64: ERRORS
linux-2.6.37.6-x86_64: ERRORS
linux-2.6.38.8-x86_64: ERRORS
linux-2.6.39.4-x86_64: ERRORS
linux-3.0.60-x86_64: ERRORS
linux-3.1.10-x86_64: ERRORS
linux-3.2.37-x86_64: ERRORS
linux-3.3.8-x86_64: ERRORS
linux-3.4.27-x86_64: ERRORS
linux-3.5.7-x86_64: ERRORS
linux-3.6.11-x86_64: ERRORS
linux-3.7.4-x86_64: ERRORS
linux-3.8-x86_64: ERRORS
linux-3.9.2-x86_64: ERRORS
linux-3.10.1-x86_64: ERRORS
linux-3.11.1-x86_64: ERRORS
linux-3.12.67-x86_64: ERRORS
linux-3.13.11-x86_64: ERRORS
linux-3.14.9-x86_64: ERRORS
linux-3.15.2-x86_64: ERRORS
linux-3.16.7-x86_64: ERRORS
linux-3.17.8-x86_64: ERRORS
linux-3.18.7-x86_64: ERRORS
linux-3.19-x86_64: ERRORS
linux-4.0.9-x86_64: ERRORS
linux-4.1.33-x86_64: ERRORS
linux-4.2.8-x86_64: ERRORS
linux-4.3.6-x86_64: ERRORS
linux-4.4.22-x86_64: ERRORS
linux-4.5.7-x86_64: ERRORS
linux-4.6.7-x86_64: ERRORS
linux-4.7.5-x86_64: ERRORS
linux-4.8-x86_64: ERRORS
linux-4.9.26-x86_64: ERRORS
linux-4.10.14-x86_64: ERRORS
linux-4.11-x86_64: ERRORS
linux-4.12.1-x86_64: ERRORS
linux-4.13-x86_64: ERRORS
apps: OK
spec-git: OK
Detailed results are available here:
http://www.xs4all.nl/~hverkuil/logs/Thursday.log
Full logs are available here:
http://www.xs4all.nl/~hverkuil/logs/Thursday.tar.bz2
The Media Infrastructure API from this daily build is here:
http://www.xs4all.nl/~hverkuil/spec/index.html
^ permalink raw reply
* Re: [PATCH net-next v4 0/3] tools: add bpftool
From: David Ahern @ 2017-10-05 3:26 UTC (permalink / raw)
To: Jakub Kicinski, netdev; +Cc: alexei.starovoitov, daniel, oss-drivers, brouer
In-Reply-To: <20171005031005.15364-1-jakub.kicinski@netronome.com>
On 10/4/17 8:10 PM, Jakub Kicinski wrote:
> Hi!
>
> This set adds bpftool to the tools/ directory. The first
> patch renames tools/net to tools/bpf, the second one adds
> the new code, while the third adds simple documentation.
>
> v4:
> - rename docs *.txt -> *.rst (Jesper).
> v3:
> - address Alexei's comments about output and docs.
> v2:
> - report names, map ids, load time, uid;
> - add docs/man pages;
> - general cleanups & fixes.
>
> Jakub Kicinski (3):
> tools: rename tools/net directory to tools/bpf
> tools: bpf: add bpftool
> tools: bpftool: add documentation
>
LGTM. Thanks for the work, Jakub.
Acked-by: David Ahern <dsahern@gmail.com>
^ permalink raw reply
* Re: [Qemu-arm] [PATCH 03/20] target/arm: Prepare for CONTROL.SPSEL being nonzero in Handler mode
From: Philippe Mathieu-Daudé @ 2017-10-05 3:25 UTC (permalink / raw)
To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches
In-Reply-To: <1506092407-26985-4-git-send-email-peter.maydell@linaro.org>
On 09/22/2017 11:59 AM, Peter Maydell wrote:
> In the v7M architecture, there is an invariant that if the CPU is
> in Handler mode then the CONTROL.SPSEL bit cannot be nonzero.
> This in turn means that the current stack pointer is always
> indicated by CONTROL.SPSEL, even though Handler mode always uses
> the Main stack pointer.
>
> In v8M, this invariant is removed, and CONTROL.SPSEL may now
> be nonzero in Handler mode (though Handler mode still always
> uses the Main stack pointer). In preparation for this change,
> change how we handle this bit: rename switch_v7m_sp() to
> the now more accurate write_v7m_control_spsel(), and make it
> check both the handler mode state and the SPSEL bit.
>
> Note that this implicitly changes the point at which we switch
> active SP on exception exit from before we pop the exception
> frame to after it.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> target/arm/cpu.h | 8 ++++++-
> hw/intc/armv7m_nvic.c | 2 +-
> target/arm/helper.c | 65 ++++++++++++++++++++++++++++++++++-----------------
> 3 files changed, 51 insertions(+), 24 deletions(-)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 8afceca..ad6eff4 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -991,6 +991,11 @@ void pmccntr_sync(CPUARMState *env);
> #define PSTATE_MODE_EL1t 4
> #define PSTATE_MODE_EL0t 0
>
> +/* Write a new value to v7m.exception, thus transitioning into or out
> + * of Handler mode; this may result in a change of active stack pointer.
> + */
> +void write_v7m_exception(CPUARMState *env, uint32_t new_exc);
> +
> /* Map EL and handler into a PSTATE_MODE. */
> static inline unsigned int aarch64_pstate_mode(unsigned int el, bool handler)
> {
> @@ -1071,7 +1076,8 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
> env->condexec_bits |= (val >> 8) & 0xfc;
> }
> if (mask & XPSR_EXCP) {
> - env->v7m.exception = val & XPSR_EXCP;
> + /* Note that this only happens on exception exit */
> + write_v7m_exception(env, val & XPSR_EXCP);
> }
> }
>
> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
> index bc7b66d..a1041c2 100644
> --- a/hw/intc/armv7m_nvic.c
> +++ b/hw/intc/armv7m_nvic.c
> @@ -616,7 +616,7 @@ bool armv7m_nvic_acknowledge_irq(void *opaque)
> vec->active = 1;
> vec->pending = 0;
>
> - env->v7m.exception = s->vectpending;
> + write_v7m_exception(env, s->vectpending);
>
> nvic_irq_update(s);
>
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index f13b99d..509a1aa 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -6052,21 +6052,44 @@ static bool v7m_using_psp(CPUARMState *env)
> env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK;
> }
>
> -/* Switch to V7M main or process stack pointer. */
> -static void switch_v7m_sp(CPUARMState *env, bool new_spsel)
> +/* Write to v7M CONTROL.SPSEL bit. This may change the current
> + * stack pointer between Main and Process stack pointers.
> + */
> +static void write_v7m_control_spsel(CPUARMState *env, bool new_spsel)
> {
> uint32_t tmp;
> - uint32_t old_control = env->v7m.control[env->v7m.secure];
> - bool old_spsel = old_control & R_V7M_CONTROL_SPSEL_MASK;
> + bool new_is_psp, old_is_psp = v7m_using_psp(env);
> +
> + env->v7m.control[env->v7m.secure] =
> + deposit32(env->v7m.control[env->v7m.secure],
> + R_V7M_CONTROL_SPSEL_SHIFT,
> + R_V7M_CONTROL_SPSEL_LENGTH, new_spsel);
> +
> + new_is_psp = v7m_using_psp(env);
>
> - if (old_spsel != new_spsel) {
> + if (old_is_psp != new_is_psp) {
> tmp = env->v7m.other_sp;
> env->v7m.other_sp = env->regs[13];
> env->regs[13] = tmp;
> + }
> +}
> +
> +void write_v7m_exception(CPUARMState *env, uint32_t new_exc)
> +{
> + /* Write a new value to v7m.exception, thus transitioning into or out
> + * of Handler mode; this may result in a change of active stack pointer.
> + */
> + bool new_is_psp, old_is_psp = v7m_using_psp(env);
> + uint32_t tmp;
>
> - env->v7m.control[env->v7m.secure] = deposit32(old_control,
> - R_V7M_CONTROL_SPSEL_SHIFT,
> - R_V7M_CONTROL_SPSEL_LENGTH, new_spsel);
> + env->v7m.exception = new_exc;
> +
> + new_is_psp = v7m_using_psp(env);
> +
> + if (old_is_psp != new_is_psp) {
> + tmp = env->v7m.other_sp;
> + env->v7m.other_sp = env->regs[13];
> + env->regs[13] = tmp;
> }
> }
>
> @@ -6149,13 +6172,11 @@ static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
> bool want_psp = threadmode && spsel;
>
> if (secure == env->v7m.secure) {
> - /* Currently switch_v7m_sp switches SP as it updates SPSEL,
> - * so the SP we want is always in regs[13].
> - * When we decouple SPSEL from the actually selected SP
> - * we need to check want_psp against v7m_using_psp()
> - * to see whether we need regs[13] or v7m.other_sp.
> - */
> - return &env->regs[13];
> + if (want_psp == v7m_using_psp(env)) {
> + return &env->regs[13];
> + } else {
> + return &env->v7m.other_sp;
> + }
> } else {
> if (want_psp) {
> return &env->v7m.other_ss_psp;
> @@ -6198,7 +6219,7 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr)
> uint32_t addr;
>
> armv7m_nvic_acknowledge_irq(env->nvic);
> - switch_v7m_sp(env, 0);
> + write_v7m_control_spsel(env, 0);
> arm_clear_exclusive(env);
> /* Clear IT bits */
> env->condexec_bits = 0;
> @@ -6344,11 +6365,11 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
> return;
> }
>
> - /* Set CONTROL.SPSEL from excret.SPSEL. For QEMU this currently
> - * causes us to switch the active SP, but we will change this
> - * later to not do that so we can support v8M.
> + /* Set CONTROL.SPSEL from excret.SPSEL. Since we're still in
> + * Handler mode (and will be until we write the new XPSR.Interrupt
> + * field) this does not switch around the current stack pointer.
> */
> - switch_v7m_sp(env, return_to_sp_process);
> + write_v7m_control_spsel(env, return_to_sp_process);
>
> {
> /* The stack pointer we should be reading the exception frame from
> @@ -9163,11 +9184,11 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
> case 20: /* CONTROL */
> /* Writing to the SPSEL bit only has an effect if we are in
> * thread mode; other bits can be updated by any privileged code.
> - * switch_v7m_sp() deals with updating the SPSEL bit in
> + * write_v7m_control_spsel() deals with updating the SPSEL bit in
> * env->v7m.control, so we only need update the others.
> */
> if (!arm_v7m_is_handler_mode(env)) {
> - switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
> + write_v7m_control_spsel(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
> }
> env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
> env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.