* Re: [PATCH net-next] tcp: provide SYN headers for passive connections
From: Eric Dumazet @ 2015-05-05 21:02 UTC (permalink / raw)
To: David Miller
Cc: emunson-JqFfY2XvxFXQT0dZR+AlfA, tom-BjP2VixgY4xUbtYUoyoikg,
linux-api-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20150505.160535.1034497188259706110.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
On Tue, 2015-05-05 at 16:05 -0400, David Miller wrote:
> Applied, but I think you should give maybe a little bit more thought
> into the behavior when a not-large-enough buffer is supplied by the
> user.
>
> Since we're talking about things on the order of 60 bytes or so at
> most, it seems clear to me that signalling an error is probably the
> most advisable thing to do in this situation.
>
> Maybe you could signal an error, yet write the actual length to
> "optlen". That way the user can figure out how much they need. Then
> they at least would have the option of retrying with a larger buffer.
Seems fine to me, I'll provide a patch implementing your suggestions.
Thanks.
^ permalink raw reply
* Re: [PATCH] ipc/sem: 64bit union semun definition
From: Arnd Bergmann @ 2015-05-05 21:40 UTC (permalink / raw)
To: Sandy Sun
Cc: akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CACwVHNr9K0XXvB8JVEet_OtTRAJmjkHTsKsOc9h5HNts9+X5QA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tuesday 05 May 2015 14:09:14 Sandy Sun wrote:
> Hi Arnd,
>
> If user space uses union semun to define.It will use semid_ds not
> semid64_ds.
>
> I used LTP test case semctl01 IPC_STAT to do the test on 64 bit
> system.According to the test results:
>
> Before the change, semun uses semid_ds, the field of sem_nsems reporting of
> semaphore STAT info is incorrect:
>
> semctl01 1 TFAIL : semaphore STAT info is incorrect
> semctl01 2 TFAIL : semaphore mode info is incorrect
>
> After this change, the return value is correct:
> semctl01 1 TPASS : buf.sem_nsems and buf.sem_perm.mode are correct
> semctl01 2 TPASS : buf.sem_perm.mode is correct
I don't understand: semctl01 does not reference 'union semun64'. How
does this change make a difference, and why would that difference
be limited to 64-bit systems?
Arnd
^ permalink raw reply
* Re: [PATCH 1/2] clone: Support passing tls argument via C rather than pt_regs magic
From: josh @ 2015-05-05 23:12 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Andy Lutomirski, Ingo Molnar, H. Peter Anvin, Peter Zijlstra,
Linus Torvalds, linux-api, linux-kernel, x86
In-Reply-To: <alpine.DEB.2.11.1505052050100.4225@nanos>
On Tue, May 05, 2015 at 08:53:03PM +0200, Thomas Gleixner wrote:
> On Tue, 21 Apr 2015, Josh Triplett wrote:
> >
> > Signed-off-by: Josh Triplett <josh@joshtriplett.org>
> > Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
>
> Can you please clarify that SOB chain? It does not make any sense.
Co-authored patch. We both worked on it together, and sadly git doesn't
support a commit with multiple authors, so this is the next best thing.
- Josh Triplett
^ permalink raw reply
* Re: [PATCH RFC 0/3] simple copy offloading system call
From: Michael Kerrisk @ 2015-05-06 6:15 UTC (permalink / raw)
To: Zach Brown
Cc: Linux Kernel, Linux-Fsdevel, Linux btrfs Developers List,
linux-nfs-u79uwXL29TY76Z2rM5mHXA,
linux-scsi-u79uwXL29TY76Z2rM5mHXA, Linux API
In-Reply-To: <1428703236-24735-1-git-send-email-zab-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
[CC += linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org]
Zach,
Since this is a kernel-user-space API change, please CC linux-api@.
The kernel source file Documentation/SubmitChecklist notes that all
Linux kernel patches that change userspace interfaces should be CCed
to linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, so that the various parties who are
interested in API changes are informed. For further information, see
https://www.kernel.org/doc/man-pages/linux-api-ml.html
Thanks,
Michael
On Sat, Apr 11, 2015 at 12:00 AM, Zach Brown <zab-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> Hello everyone!
>
> Here's my current attempt at the most basic system call interface for
> offloading copying between files. The system call and vfs function
> are relatively light wrappers around the file_operation method that
> does the heavy lifting.
>
> There was interest at LSF in getting the basic infrastructure merged
> before worrying about adding behavioural flags and more complicated
> implementations. This series only offers a refactoring of the btrfs
> clone ioctl as an example of an implementation of the file
> copy_file_range method.
>
> I've added support for copy_file_range() to xfs_io in xfsprogs and
> have the start of an xfstest that tests the system call. I'll send
> those to fstests@.
>
> So how does this look?
>
> Do we want to merge this and let the NFS and block XCOPY patches add
> their changes when they're ready?
>
> - z
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Michael Kerrisk Linux man-pages maintainer;
http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface", http://blog.man7.org/
^ permalink raw reply
* [PATCH] virtio: Fix typecast of pointer in vring_init()
From: Thomas Huth @ 2015-05-06 10:33 UTC (permalink / raw)
To: Michael S. Tsirkin,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: linux-api-u79uwXL29TY76Z2rM5mHXA
The virtio_ring.h header is used in userspace programs (ie. QEMU),
too. Here we can not assume that sizeof(pointer) is the same as
sizeof(long), e.g. when compiling for Windows, so the typecast
in vring_init() should be done with (uintptr_t) instead of
(unsigned long). This fixes a compiler warning when compiling
QEMU with the mingw32 cross-compiler.
Signed-off-by: Thomas Huth <thuth-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
include/uapi/linux/virtio_ring.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/uapi/linux/virtio_ring.h b/include/uapi/linux/virtio_ring.h
index 915980a..8682551 100644
--- a/include/uapi/linux/virtio_ring.h
+++ b/include/uapi/linux/virtio_ring.h
@@ -143,7 +143,7 @@ static inline void vring_init(struct vring *vr, unsigned int num, void *p,
vr->num = num;
vr->desc = p;
vr->avail = p + num*sizeof(struct vring_desc);
- vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__virtio16)
+ vr->used = (void *)(((uintptr_t)&vr->avail->ring[num] + sizeof(__virtio16)
+ align-1) & ~(align - 1));
}
--
1.8.3.1
^ permalink raw reply related
* Re: [RFC PATCH] mmap.2: clarify MAP_LOCKED semantic (was: Re: Should mmap MAP_LOCKED fail if mm_poppulate fails?)
From: Michal Hocko @ 2015-05-06 12:21 UTC (permalink / raw)
To: Linus Torvalds, Michael Kerrisk
Cc: linux-mm, Cyril Hrubis, Andrew Morton, Hugh Dickins,
Michel Lespinasse, Rik van Riel, LKML, Linux API
In-Reply-To: <20150429113818.GC16097@dhcp22.suse.cz>
If there are no objections here I will resubmit this and MAP_POPULATE
patches in few days.
On Wed 29-04-15 13:38:18, Michal Hocko wrote:
> On Tue 28-04-15 11:38:35, Linus Torvalds wrote:
> > On Tue, Apr 28, 2015 at 11:35 AM, Michal Hocko <mhocko@suse.cz> wrote:
> > >
> > > I am still not sure I see the problem here.
> >
> > Basically, I absolutely hate the notion of us doing something
> > unsynchronized, when I can see us undoing a mmap that another thread
> > is doing. It's wrong.
>
> OK, I have checked the mmap(2) man page and there is no single mention
> about multi-threaded usage. So even though I personally think that
> user fault handlers which do mmap(MAP_FIXED) without synchronization
> to parallel mmaps are broken by definition we cannot simply rule them
> out and it is not the kernel job to make them broken even more or in a
> subtly different way.
> So here is an RFC for the man page patch. I am not very good in the
> format but man doesn't complain about any formating issues.
> ---
> From 903ed733187afaa4d27fef3c24f413304494411c Mon Sep 17 00:00:00 2001
> From: Michal Hocko <mhocko@suse.cz>
> Date: Wed, 29 Apr 2015 11:02:19 +0200
> Subject: [RFC PATCH] mmap.2: clarify MAP_LOCKED semantic
>
> MAP_LOCKED had a subtly different semantic from mmap(2)+mlock(2) since
> it has been introduced.
> mlock(2) fails if the memory range cannot get populated to guarantee
> that no future major faults will happen on the range. mmap(MAP_LOCKED) on
> the other hand silently succeeds even if the range was populated only
> partially.
>
> Fixing this subtle difference in the kernel is rather awkward because
> the memory population happens after mm locks have been dropped and so
> the cleanup before returning failure (munlock) could operate on something
> else than the originally mapped area.
>
> E.g. speculative userspace page fault handler catching SEGV and doing
> mmap(fault_addr, MAP_FIXED|MAP_LOCKED) might discard portion of a racing
> mmap and lead to lost data. Although it is not clear whether such a
> usage would be valid, mmap page doesn't explicitly describe requirements
> for threaded applications so we cannot exclude this possibility.
>
> This patch makes the semantic of MAP_LOCKED explicit and suggest using
> mmap + mlock as the only way to guarantee no later major page faults.
>
> Signed-off-by: Michal Hocko <mhocko@suse.cz>
> ---
> man2/mmap.2 | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/man2/mmap.2 b/man2/mmap.2
> index 54d68cf87e9e..1486be2e96b3 100644
> --- a/man2/mmap.2
> +++ b/man2/mmap.2
> @@ -235,8 +235,19 @@ See the Linux kernel source file
> for further information.
> .TP
> .BR MAP_LOCKED " (since Linux 2.5.37)"
> -Lock the pages of the mapped region into memory in the manner of
> +Mark the mmaped region to be locked in the same way as
> .BR mlock (2).
> +This implementation will try to populate (prefault) the whole range but
> +the mmap call doesn't fail with
> +.B ENOMEM
> +if this fails. Therefore major faults might happen later on. So the semantic
> +is not as strong as
> +.BR mlock (2).
> +.BR mmap (2)
> ++
> +.BR mlock (2)
> +should be used when major faults are not acceptable after the initialization
> +of the mapping.
> This flag is ignored in older kernels.
> .\" If set, the mapped pages will not be swapped out.
> .TP
> --
> 2.1.4
>
> --
> Michal Hocko
> SUSE Labs
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH v10 12/12] manpage: update FALLOC_FL_INSERT_RANGE flag in fallocate
From: Michael Kerrisk (man-pages) @ 2015-05-06 12:43 UTC (permalink / raw)
To: Namjae Jeon, david-FqsqvQoI3Ljby3iVrkZq2A, tytso-3s7WtUTddSA
Cc: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, xfs-VZNHf3L845pBDgjK7y7TUQ,
a.sangwan-Sze3O3UU22JBDgjK7y7TUQ, bfoster-H+wXaHxf7aLQT0dZR+AlfA,
linux-man-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Namjae Jeon
In-Reply-To: <1424533554-28024-13-git-send-email-linkinjeon-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Hello Namjae Jeon,
I see that FALLOC_FL_INSERT_RANGE has hit mainline. Could I ask you refresh
this patch, please? (Against latest man-pages Git, please, since the current
patch does not apply cleanly).
See some comments below.
On 02/21/2015 04:45 PM, Namjae Jeon wrote:
> From: Namjae Jeon <namjae.jeon-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>
> Update FALLOC_FL_INSERT_RANGE flag in fallocate.
>
> Signed-off-by: Namjae Jeon <namjae.jeon-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Ashish Sangwan <a.sangwan-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
> man2/fallocate.2 | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 82 insertions(+), 6 deletions(-)
>
> diff --git a/man2/fallocate.2 b/man2/fallocate.2
> index adf42db..9b3c460 100644
> --- a/man2/fallocate.2
> +++ b/man2/fallocate.2
> @@ -8,7 +8,7 @@
> .\" 2011-09-19: Added FALLOC_FL_PUNCH_HOLE
> .\" 2011-09-19: Substantial restructuring of the page
> .\"
> -.TH FALLOCATE 2 2015-01-22 "Linux" "Linux Programmer's Manual"
> +.TH FALLOCATE 2 2015-02-14 "Linux" "Linux Programmer's Manual"
No need to update the timestamp on the page. I have scripts
that do this automatically.
> .SH NAME
> fallocate \- manipulate file space
> .SH SYNOPSIS
> @@ -225,6 +225,56 @@ XFS (since Linux 3.14)
> .IP *
> ext4, for extent-based files (since Linux 3.14)
> .\" commit b8a8684502a0fc852afa0056c6bb2a9273f6fcc0
> +.SS Increasing file space
> +.\" TODO: Mention commit id and supporting Linux version
Yes, please add the commit ID and "Linux 4.1".
> +Specifying the
> +.BR FALLOC_FL_INSERT_RANGE
> +flag in
> +.I mode
> +will increase the file space by inserting a hole within the file size without
> +overwriting any existing data. The hole will start at
^
Please start new sentences on new source lines. (Same thing at various
lines below.)
> +.I offset
> +and continue for
> +.I len
> +bytes. For inserting hole inside file, the contents of the file starting at
Please start new sentences on new source lines.
> +.I offset
> +will be shifted towards right by
> +.I len
> +bytes. Inserting a hole inside the file will increase the file size by
Please start new sentences on new source lines.
> +.I len
> +bytes.
> +
> +This mode has the same limitation as
> +.BR FALLOC_FL_COLLAPSE_RANGE
> +regarding the
> +granularity of the operation.
> +If the granulrity requirements are not met,
Spelling: "granularity"
> +.BR fallocate ()
> +will fail with the error
> +.BR EINVAL.
> +If the
> +.I offset
> +overlaps with end of file OR if it is greater than end of file, an error is
> +returned. For such type of operations, i.e. inserting a hole at the end of
Please start new sentences on new source lines.
> +file,
> +.BR ftruncate(2)
> +should be used.
> +In case
> +.IR offset + len
> +exceeds the maximum file size, errno will be set to
> +.B EFBIG.
> +
> +No other flags may be specified in
> +.IR mode
> +in conjunction with
> +.BR FALLOC_FL_INSERT_RANGE .
> +
> +As of Linux XXXX,
> +.\" TODO: Mention commit id and supporting Linux version
> +.B FALLOC_FL_INSERT_RANGE
> +is supported by
> +ext4 (only for extent-based files) and XFS.
Is the ext4 support really there? Grep Linus's current Git, it appears
that only XFS support is currently there?
> +
> .SH RETURN VALUE
> On success,
> .BR fallocate ()
> @@ -242,6 +292,12 @@ is not a valid file descriptor, or is not opened for writing.
> .IR offset + len
> exceeds the maximum file size.
> .TP
> +.B EFBIG
> +.I mode
> +is
> +.BR FALLOC_FL_INSERT_RANGE ,
> +the current file size+len excceds the maximum file size.
"exceeds"
> +.TP
> .B EINTR
> A signal was caught during execution.
> .TP
> @@ -270,7 +326,17 @@ reaches or passes the end of the file.
> .B EINVAL
> .I mode
> is
> -.BR FALLOC_FL_COLLAPSE_RANGE ,
> +.BR FALLOC_FL_INSERT_RANGE
> +and the range specified by
> +.I offset
> +reaches or passes the end of the file.
> +.TP
> +.B EINVAL
> +.I mode
> +is
> +.BR FALLOC_FL_COLLAPSE_RANGE
> +or
> +.BR FALLOC_FL_INSERT_RANGE ,
> but either
> .I offset
> or
> @@ -279,18 +345,24 @@ is not a multiple of the filesystem block size.
> .TP
> .B EINVAL
> .I mode
> -contains both
> +contains either of
> .B FALLOC_FL_COLLAPSE_RANGE
> +or
> +.B FALLOC_FL_INSERT_RANGE
> and other flags;
> no other flags are permitted with
> -.BR FALLOC_FL_COLLAPSE_RANGE .
> +.BR FALLOC_FL_COLLAPSE_RANGE
> +or
> +.BR FALLOC_FL_INSERT_RANGE .
> .TP
> .B EINVAL
> .I mode
> is
> .BR FALLOC_FL_COLLAPSE_RANGE
> or
> -.BR FALLOC_FL_ZERO_RANGE ,
> +.BR FALLOC_FL_ZERO_RANGE
> +or
> +.BR FALLOC_FL_INSERT_RANGE ,
> but the file referred to by
> .I fd
> is not a regular file.
> @@ -342,6 +414,8 @@ specifies
> .BR FALLOC_FL_PUNCH_HOLE
> or
> .BR FALLOC_FL_COLLAPSE_RANGE
> +or
> +.BR FALLOC_FL_INSERT_RANGE
> and
> the file referred to by
> .I fd
> @@ -360,7 +434,9 @@ refers to a pipe or FIFO.
> .B ETXTBSY
> .I mode
> specifies
> -.BR FALLOC_FL_COLLAPSE_RANGE ,
> +.BR FALLOC_FL_COLLAPSE_RANGE
> +or
> +.BR FALLOC_FL_INSERT_RANGE ,
> but the file referred to by
> .IR fd
> is currently being executed.
>
Thanks,
Michael
--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
^ permalink raw reply
* [PATCH v3 00/11] Support for coresight ETMv4 tracer
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh
Cc: linux-arm-kernel, linux-api, linux-kernel, kaixu.xia,
zhang.chunyan, mathieu.poirier
Please find in this patchset a driver implementation that conforms
to the coresight framework and provide support for the Embedded
Trace Macrocell version 4.
Regards,
Mathieu
---
Changes for v3:
- Fixed cosmetic detail in Kconfig.
- Removed THIS_MODULE from driver declaration.
- Removed MODULE_XYX() declarations at the bottom of the file.
---
Pratik Patel (11):
coresight-etm4x: Adding CoreSight ETM4x driver
coresight-etm4x: Controls pertaining to tracer configuration
coresight-etm4x: Controls pertaining to the reset, mode, pe and events
coresight-etm4x: Controls pertaining to various configuration options
coresight-etm4x: Controls pertaining to the ViewInst register
coresight-etm4x: Controls pertaining to the address comparator
functions
coresight-etm4x: Controls pertaining to the sequencer functions
coresight-etm4x: Controls pertaining to the counter functions
coresight-etm4x: Controls pertaining to the selection of resources
coresight-etm4x: Controls pertaining to the context ID functions
coresight-etm4x: Controls pertaining to the VM ID functions
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 295 +++
drivers/hwtracing/coresight/Kconfig | 11 +
drivers/hwtracing/coresight/Makefile | 1 +
drivers/hwtracing/coresight/coresight-etm4x.c | 2740 ++++++++++++++++++++
drivers/hwtracing/coresight/coresight-etm4x.h | 391 +++
5 files changed, 3438 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
create mode 100644 drivers/hwtracing/coresight/coresight-etm4x.c
create mode 100644 drivers/hwtracing/coresight/coresight-etm4x.h
--
1.9.1
^ permalink raw reply
* [PATCH v3 01/11] coresight-etm4x: Adding CoreSight ETM4x driver
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
kaixu.xia-QSEj5FYQhm4dnm+yROfE0A,
zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A,
mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
From: Pratik Patel <pratikp-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
This driver manages the CoreSight ETMv4 (Embedded Trace Macrocell) IP block
to support HW assisted tracing on ARMv7 and ARMv8 architectures.
Signed-off-by: Pratik Patel <pratikp-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Signed-off-by: Kaixu Xia <xiakaixu-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 28 +
drivers/hwtracing/coresight/Kconfig | 11 +
drivers/hwtracing/coresight/Makefile | 1 +
drivers/hwtracing/coresight/coresight-etm4x.c | 825 +++++++++++++++++++++
drivers/hwtracing/coresight/coresight-etm4x.h | 391 ++++++++++
5 files changed, 1256 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
create mode 100644 drivers/hwtracing/coresight/coresight-etm4x.c
create mode 100644 drivers/hwtracing/coresight/coresight-etm4x.h
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
new file mode 100644
index 000000000000..a4b623871ca0
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -0,0 +1,28 @@
+What: /sys/bus/coresight/devices/<memory_map>.etm/enable_source
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (RW) Enable/disable tracing on this specific trace entiry.
+ Enabling a source implies the source has been configured
+ properly and a sink has been identidifed for it. The path
+ of coresight components linking the source to the sink is
+ configured and managed automatically by the coresight framework.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/status
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) List various control and status registers. The specific
+ layout and content is driver specific.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/mgmt
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) Provides the current value of all the management registers.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/trcidr
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) Provides value of all the ID registers (TRCIDRx).
diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index fc1f1ae7a49d..8fac01eedee7 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -58,4 +58,15 @@ config CORESIGHT_SOURCE_ETM3X
which allows tracing the instructions that a processor is executing
This is primarily useful for instruction level tracing. Depending
the ETM version data tracing may also be available.
+
+config CORESIGHT_SOURCE_ETM4X
+ bool "CoreSight Embedded Trace Macrocell 4.x driver"
+ depends on ARM64
+ select CORESIGHT_LINKS_AND_SINKS
+ help
+ This driver provides support for the ETM4.x tracer module, tracing the
+ instructions that a processor is executing. This is primarily useful
+ for instruction level tracing. Depending on the implemented version
+ data tracing may also be available.
+
endif
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 4b4bec890ef5..0af28d43465c 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o
obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \
coresight-replicator.o
obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o coresight-etm-cp14.o
+obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
new file mode 100644
index 000000000000..db0bea4d4661
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -0,0 +1,825 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * 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/moduleparam.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/sysfs.h>
+#include <linux/stat.h>
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/coresight.h>
+#include <linux/pm_wakeup.h>
+#include <linux/amba/bus.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+#include <linux/pm_runtime.h>
+#include <asm/sections.h>
+
+#include "coresight-etm4x.h"
+
+static int boot_enable;
+module_param_named(boot_enable, boot_enable, int, S_IRUGO);
+
+/* The number of ETMv4 currently registered */
+static int etm4_count;
+static struct etmv4_drvdata *etmdrvdata[NR_CPUS];
+
+static void etm4_os_unlock(void *info)
+{
+ struct etmv4_drvdata *drvdata = (struct etmv4_drvdata *)info;
+
+ /* Writing any value to ETMOSLAR unlocks the trace registers */
+ writel_relaxed(0x0, drvdata->base + TRCOSLAR);
+ isb();
+}
+
+static bool etm4_arch_supported(u8 arch)
+{
+ switch (arch) {
+ case ETM_ARCH_V4:
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+static int etm4_trace_id(struct coresight_device *csdev)
+{
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ unsigned long flags;
+ int trace_id = -1;
+
+ if (!drvdata->enable)
+ return drvdata->trcid;
+
+ pm_runtime_get_sync(drvdata->dev);
+ spin_lock_irqsave(&drvdata->spinlock, flags);
+
+ CS_UNLOCK(drvdata->base);
+ trace_id = readl_relaxed(drvdata->base + TRCTRACEIDR);
+ trace_id &= ETM_TRACEID_MASK;
+ CS_LOCK(drvdata->base);
+
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ pm_runtime_put(drvdata->dev);
+
+ return trace_id;
+}
+
+static void etm4_enable_hw(void *info)
+{
+ int i;
+ struct etmv4_drvdata *drvdata = info;
+
+ CS_UNLOCK(drvdata->base);
+
+ etm4_os_unlock(drvdata);
+
+ /* Disable the trace unit before programming trace registers */
+ writel_relaxed(0, drvdata->base + TRCPRGCTLR);
+
+ /* wait for TRCSTATR.IDLE to go up */
+ if (coresight_timeout(drvdata->base, TRCSTATR, TRCSTATR_IDLE_BIT, 1))
+ dev_err(drvdata->dev,
+ "timeout observed when probing at offset %#x\n",
+ TRCSTATR);
+
+ writel_relaxed(drvdata->pe_sel, drvdata->base + TRCPROCSELR);
+ writel_relaxed(drvdata->cfg, drvdata->base + TRCCONFIGR);
+ /* nothing specific implemented */
+ writel_relaxed(0x0, drvdata->base + TRCAUXCTLR);
+ writel_relaxed(drvdata->eventctrl0, drvdata->base + TRCEVENTCTL0R);
+ writel_relaxed(drvdata->eventctrl1, drvdata->base + TRCEVENTCTL1R);
+ writel_relaxed(drvdata->stall_ctrl, drvdata->base + TRCSTALLCTLR);
+ writel_relaxed(drvdata->ts_ctrl, drvdata->base + TRCTSCTLR);
+ writel_relaxed(drvdata->syncfreq, drvdata->base + TRCSYNCPR);
+ writel_relaxed(drvdata->ccctlr, drvdata->base + TRCCCCTLR);
+ writel_relaxed(drvdata->bb_ctrl, drvdata->base + TRCBBCTLR);
+ writel_relaxed(drvdata->trcid, drvdata->base + TRCTRACEIDR);
+ writel_relaxed(drvdata->vinst_ctrl, drvdata->base + TRCVICTLR);
+ writel_relaxed(drvdata->viiectlr, drvdata->base + TRCVIIECTLR);
+ writel_relaxed(drvdata->vissctlr,
+ drvdata->base + TRCVISSCTLR);
+ writel_relaxed(drvdata->vipcssctlr,
+ drvdata->base + TRCVIPCSSCTLR);
+ for (i = 0; i < drvdata->nrseqstate - 1; i++)
+ writel_relaxed(drvdata->seq_ctrl[i],
+ drvdata->base + TRCSEQEVRn(i));
+ writel_relaxed(drvdata->seq_rst, drvdata->base + TRCSEQRSTEVR);
+ writel_relaxed(drvdata->seq_state, drvdata->base + TRCSEQSTR);
+ writel_relaxed(drvdata->ext_inp, drvdata->base + TRCEXTINSELR);
+ for (i = 0; i < drvdata->nr_cntr; i++) {
+ writel_relaxed(drvdata->cntrldvr[i],
+ drvdata->base + TRCCNTRLDVRn(i));
+ writel_relaxed(drvdata->cntr_ctrl[i],
+ drvdata->base + TRCCNTCTLRn(i));
+ writel_relaxed(drvdata->cntr_val[i],
+ drvdata->base + TRCCNTVRn(i));
+ }
+ for (i = 0; i < drvdata->nr_resource; i++)
+ writel_relaxed(drvdata->res_ctrl[i],
+ drvdata->base + TRCRSCTLRn(i));
+
+ for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ writel_relaxed(drvdata->ss_ctrl[i],
+ drvdata->base + TRCSSCCRn(i));
+ writel_relaxed(drvdata->ss_status[i],
+ drvdata->base + TRCSSCSRn(i));
+ writel_relaxed(drvdata->ss_pe_cmp[i],
+ drvdata->base + TRCSSPCICRn(i));
+ }
+ for (i = 0; i < drvdata->nr_addr_cmp; i++) {
+ writeq_relaxed(drvdata->addr_val[i],
+ drvdata->base + TRCACVRn(i));
+ writeq_relaxed(drvdata->addr_acc[i],
+ drvdata->base + TRCACATRn(i));
+ }
+ for (i = 0; i < drvdata->numcidc; i++)
+ writeq_relaxed(drvdata->ctxid_val[i],
+ drvdata->base + TRCCIDCVRn(i));
+ writel_relaxed(drvdata->ctxid_mask0, drvdata->base + TRCCIDCCTLR0);
+ writel_relaxed(drvdata->ctxid_mask1, drvdata->base + TRCCIDCCTLR1);
+
+ for (i = 0; i < drvdata->numvmidc; i++)
+ writeq_relaxed(drvdata->vmid_val[i],
+ drvdata->base + TRCVMIDCVRn(i));
+ writel_relaxed(drvdata->vmid_mask0, drvdata->base + TRCVMIDCCTLR0);
+ writel_relaxed(drvdata->vmid_mask1, drvdata->base + TRCVMIDCCTLR1);
+
+ /* Enable the trace unit */
+ writel_relaxed(1, drvdata->base + TRCPRGCTLR);
+
+ /* wait for TRCSTATR.IDLE to go back down to '0' */
+ if (coresight_timeout(drvdata->base, TRCSTATR, TRCSTATR_IDLE_BIT, 0))
+ dev_err(drvdata->dev,
+ "timeout observed when probing at offset %#x\n",
+ TRCSTATR);
+
+ CS_LOCK(drvdata->base);
+
+ dev_dbg(drvdata->dev, "cpu: %d enable smp call done\n", drvdata->cpu);
+}
+
+static int etm4_enable(struct coresight_device *csdev)
+{
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ int ret;
+
+ pm_runtime_get_sync(drvdata->dev);
+ spin_lock(&drvdata->spinlock);
+
+ /*
+ * Executing etm4_enable_hw on the cpu whose ETM is being enabled
+ * ensures that register writes occur when cpu is powered.
+ */
+ ret = smp_call_function_single(drvdata->cpu,
+ etm4_enable_hw, drvdata, 1);
+ if (ret)
+ goto err;
+ drvdata->enable = true;
+ drvdata->sticky_enable = true;
+
+ spin_unlock(&drvdata->spinlock);
+
+ dev_info(drvdata->dev, "ETM tracing enabled\n");
+ return 0;
+err:
+ spin_unlock(&drvdata->spinlock);
+ pm_runtime_put(drvdata->dev);
+ return ret;
+}
+
+static void etm4_disable_hw(void *info)
+{
+ u32 control;
+ struct etmv4_drvdata *drvdata = info;
+
+ CS_UNLOCK(drvdata->base);
+
+ control = readl_relaxed(drvdata->base + TRCPRGCTLR);
+
+ /* EN, bit[0] Trace unit enable bit */
+ control &= ~0x1;
+
+ /* make sure everything completes before disabling */
+ mb();
+ isb();
+ writel_relaxed(control, drvdata->base + TRCPRGCTLR);
+
+ CS_LOCK(drvdata->base);
+
+ dev_dbg(drvdata->dev, "cpu: %d disable smp call done\n", drvdata->cpu);
+}
+
+static void etm4_disable(struct coresight_device *csdev)
+{
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+ /*
+ * Taking hotplug lock here protects from clocks getting disabled
+ * with tracing being left on (crash scenario) if user disable occurs
+ * after cpu online mask indicates the cpu is offline but before the
+ * DYING hotplug callback is serviced by the ETM driver.
+ */
+ get_online_cpus();
+ spin_lock(&drvdata->spinlock);
+
+ /*
+ * Executing etm4_disable_hw on the cpu whose ETM is being disabled
+ * ensures that register writes occur when cpu is powered.
+ */
+ smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
+ drvdata->enable = false;
+
+ spin_unlock(&drvdata->spinlock);
+ put_online_cpus();
+
+ pm_runtime_put(drvdata->dev);
+
+ dev_info(drvdata->dev, "ETM tracing disabled\n");
+}
+
+static const struct coresight_ops_source etm4_source_ops = {
+ .trace_id = etm4_trace_id,
+ .enable = etm4_enable,
+ .disable = etm4_disable,
+};
+
+static const struct coresight_ops etm4_cs_ops = {
+ .source_ops = &etm4_source_ops,
+};
+
+static ssize_t status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret;
+ unsigned long flags;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ pm_runtime_get_sync(drvdata->dev);
+
+ spin_lock_irqsave(&drvdata->spinlock, flags);
+ CS_UNLOCK(drvdata->base);
+ ret = sprintf(buf,
+ "TRCCONFIGR:\t0x%08x\n"
+ "TRCEVENTCTL0R:\t0x%08x\n"
+ "TRCEVENTCTL1R:\t0x%08x\n"
+ "TRCSTALLCTLR:\t0x%08x\n"
+ "TRCSYNCPR:\t0x%08x\n"
+ "TRCTRACEIDR:\t0x%08x\n"
+ "TRCTSCTLR:\t0x%08x\n"
+ "TRCVDARCCTLR:\t0x%08x\n"
+ "TRCVDCTLR:\t0x%08x\n"
+ "TRCVDSACCTLR:\t0x%08x\n"
+ "TRCVICTLR:\t0x%08x\n"
+ "TRCVIIECTLR:\t0x%08x\n"
+ "TRCVISSCTLR:\t0x%08x\n"
+ "TRCPRGCTLR:\t0x%08x\n"
+ "CPU affinity:\t%d\n",
+ readl_relaxed(drvdata->base + TRCCONFIGR),
+ readl_relaxed(drvdata->base + TRCEVENTCTL0R),
+ readl_relaxed(drvdata->base + TRCEVENTCTL1R),
+ readl_relaxed(drvdata->base + TRCSTALLCTLR),
+ readl_relaxed(drvdata->base + TRCSYNCPR),
+ readl_relaxed(drvdata->base + TRCTRACEIDR),
+ readl_relaxed(drvdata->base + TRCTSCTLR),
+ readl_relaxed(drvdata->base + TRCVDARCCTLR),
+ readl_relaxed(drvdata->base + TRCVDCTLR),
+ readl_relaxed(drvdata->base + TRCVDSACCTLR),
+ readl_relaxed(drvdata->base + TRCVICTLR),
+ readl_relaxed(drvdata->base + TRCVIIECTLR),
+ readl_relaxed(drvdata->base + TRCVISSCTLR),
+ readl_relaxed(drvdata->base + TRCPRGCTLR),
+ drvdata->cpu);
+ CS_LOCK(drvdata->base);
+
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ pm_runtime_put(drvdata->dev);
+
+ return ret;
+}
+static DEVICE_ATTR_RO(status);
+
+static ssize_t mgmt_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret;
+ unsigned long flags;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ pm_runtime_get_sync(drvdata->dev);
+
+ spin_lock_irqsave(&drvdata->spinlock, flags);
+ CS_UNLOCK(drvdata->base);
+ ret = sprintf(buf,
+ "TRCOSLSR:\t0x%08x\n"
+ "TRCPDCR:\t0x%08x\n"
+ "TRCPDSR:\t0x%08x\n"
+ "TRCLSR:\t\t0x%08x\n"
+ "TRCAUTHSTATUS:\t0x%08x\n"
+ "TRCDEVID:\t0x%08x\n"
+ "TRCDEVTYPE:\t0x%08x\n"
+ "TRCPIDR0:\t0x%08x\n"
+ "TRCPIDR1:\t0x%08x\n"
+ "TRCPIDR2:\t0x%08x\n"
+ "TRCPIDR3:\t0x%08x\n",
+ readl_relaxed(drvdata->base + TRCOSLSR),
+ readl_relaxed(drvdata->base + TRCPDCR),
+ readl_relaxed(drvdata->base + TRCPDSR),
+ readl_relaxed(drvdata->base + TRCLSR),
+ readl_relaxed(drvdata->base + TRCAUTHSTATUS),
+ readl_relaxed(drvdata->base + TRCDEVID),
+ readl_relaxed(drvdata->base + TRCDEVTYPE),
+ readl_relaxed(drvdata->base + TRCPIDR0),
+ readl_relaxed(drvdata->base + TRCPIDR1),
+ readl_relaxed(drvdata->base + TRCPIDR2),
+ readl_relaxed(drvdata->base + TRCPIDR3));
+ CS_LOCK(drvdata->base);
+
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ pm_runtime_put(drvdata->dev);
+
+ return ret;
+}
+static DEVICE_ATTR_RO(mgmt);
+
+static ssize_t trcidr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret;
+ unsigned long flags;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ pm_runtime_get_sync(drvdata->dev);
+
+ spin_lock_irqsave(&drvdata->spinlock, flags);
+ CS_UNLOCK(drvdata->base);
+ ret = sprintf(buf,
+ "TRCIDR0:\t0x%08x\n"
+ "TRCIDR1:\t0x%08x\n"
+ "TRCIDR2:\t0x%08x\n"
+ "TRCIDR3:\t0x%08x\n"
+ "TRCIDR4:\t0x%08x\n"
+ "TRCIDR5:\t0x%08x\n"
+ "TRCIDR6:\t0x%08x\n"
+ "TRCIDR7:\t0x%08x\n"
+ "TRCIDR8:\t0x%08x\n"
+ "TRCIDR9:\t0x%08x\n"
+ "TRCIDR10:\t0x%08x\n"
+ "TRCIDR11:\t0x%08x\n"
+ "TRCIDR12:\t0x%08x\n"
+ "TRCIDR13:\t0x%08x\n",
+ readl_relaxed(drvdata->base + TRCIDR0),
+ readl_relaxed(drvdata->base + TRCIDR1),
+ readl_relaxed(drvdata->base + TRCIDR2),
+ readl_relaxed(drvdata->base + TRCIDR3),
+ readl_relaxed(drvdata->base + TRCIDR4),
+ readl_relaxed(drvdata->base + TRCIDR5),
+ readl_relaxed(drvdata->base + TRCIDR6),
+ readl_relaxed(drvdata->base + TRCIDR7),
+ readl_relaxed(drvdata->base + TRCIDR8),
+ readl_relaxed(drvdata->base + TRCIDR9),
+ readl_relaxed(drvdata->base + TRCIDR10),
+ readl_relaxed(drvdata->base + TRCIDR11),
+ readl_relaxed(drvdata->base + TRCIDR12),
+ readl_relaxed(drvdata->base + TRCIDR13));
+ CS_LOCK(drvdata->base);
+
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ pm_runtime_put(drvdata->dev);
+
+ return ret;
+}
+static DEVICE_ATTR_RO(trcidr);
+
+static struct attribute *coresight_etmv4_attrs[] = {
+ &dev_attr_status.attr,
+ &dev_attr_mgmt.attr,
+ &dev_attr_trcidr.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(coresight_etmv4);
+
+static void etm4_init_arch_data(void *info)
+{
+ u32 etmidr0;
+ u32 etmidr1;
+ u32 etmidr2;
+ u32 etmidr3;
+ u32 etmidr4;
+ u32 etmidr5;
+ struct etmv4_drvdata *drvdata = info;
+
+ CS_UNLOCK(drvdata->base);
+
+ /* find all capabilities of the tracing unit */
+ etmidr0 = readl_relaxed(drvdata->base + TRCIDR0);
+
+ /* INSTP0, bits[2:1] P0 tracing support field */
+ if (BMVAL(etmidr0, 1, 1) && BMVAL(etmidr0, 2, 2))
+ drvdata->instrp0 = true;
+ else
+ drvdata->instrp0 = false;
+
+ /* TRCBB, bit[5] Branch broadcast tracing support bit */
+ if (BMVAL(etmidr0, 5, 5))
+ drvdata->trcbb = true;
+ else
+ drvdata->trcbb = false;
+
+ /* TRCCOND, bit[6] Conditional instruction tracing support bit */
+ if (BMVAL(etmidr0, 6, 6))
+ drvdata->trccond = true;
+ else
+ drvdata->trccond = false;
+
+ /* TRCCCI, bit[7] Cycle counting instruction bit */
+ if (BMVAL(etmidr0, 7, 7))
+ drvdata->trccci = true;
+ else
+ drvdata->trccci = false;
+
+ /* RETSTACK, bit[9] Return stack bit */
+ if (BMVAL(etmidr0, 9, 9))
+ drvdata->retstack = true;
+ else
+ drvdata->retstack = false;
+
+ /* NUMEVENT, bits[11:10] Number of events field */
+ drvdata->nr_event = BMVAL(etmidr0, 10, 11);
+ /* QSUPP, bits[16:15] Q element support field */
+ drvdata->q_support = BMVAL(etmidr0, 15, 16);
+ /* TSSIZE, bits[28:24] Global timestamp size field */
+ drvdata->ts_size = BMVAL(etmidr0, 24, 28);
+
+ /* base architecture of trace unit */
+ etmidr1 = readl_relaxed(drvdata->base + TRCIDR1);
+ /*
+ * TRCARCHMIN, bits[7:4] architecture the minor version number
+ * TRCARCHMAJ, bits[11:8] architecture major versin number
+ */
+ drvdata->arch = BMVAL(etmidr1, 4, 11);
+
+ /* maximum size of resources */
+ etmidr2 = readl_relaxed(drvdata->base + TRCIDR2);
+ /* CIDSIZE, bits[9:5] Indicates the Context ID size */
+ drvdata->ctxid_size = BMVAL(etmidr2, 5, 9);
+ /* VMIDSIZE, bits[14:10] Indicates the VMID size */
+ drvdata->vmid_size = BMVAL(etmidr2, 10, 14);
+ /* CCSIZE, bits[28:25] size of the cycle counter in bits minus 12 */
+ drvdata->ccsize = BMVAL(etmidr2, 25, 28);
+
+ etmidr3 = readl_relaxed(drvdata->base + TRCIDR3);
+ /* CCITMIN, bits[11:0] minimum threshold value that can be programmed */
+ drvdata->ccitmin = BMVAL(etmidr3, 0, 11);
+ /* EXLEVEL_S, bits[19:16] Secure state instruction tracing */
+ drvdata->s_ex_level = BMVAL(etmidr3, 16, 19);
+ /* EXLEVEL_NS, bits[23:20] Non-secure state instruction tracing */
+ drvdata->ns_ex_level = BMVAL(etmidr3, 20, 23);
+
+ /*
+ * TRCERR, bit[24] whether a trace unit can trace a
+ * system error exception.
+ */
+ if (BMVAL(etmidr3, 24, 24))
+ drvdata->trc_error = true;
+ else
+ drvdata->trc_error = false;
+
+ /* SYNCPR, bit[25] implementation has a fixed synchronization period? */
+ if (BMVAL(etmidr3, 25, 25))
+ drvdata->syncpr = true;
+ else
+ drvdata->syncpr = false;
+
+ /* STALLCTL, bit[26] is stall control implemented? */
+ if (BMVAL(etmidr3, 26, 26))
+ drvdata->stallctl = true;
+ else
+ drvdata->stallctl = false;
+
+ /* SYSSTALL, bit[27] implementation can support stall control? */
+ if (BMVAL(etmidr3, 27, 27))
+ drvdata->sysstall = true;
+ else
+ drvdata->sysstall = false;
+
+ /* NUMPROC, bits[30:28] the number of PEs available for tracing */
+ drvdata->nr_pe = BMVAL(etmidr3, 28, 30);
+
+ /* NOOVERFLOW, bit[31] is trace overflow prevention supported */
+ if (BMVAL(etmidr3, 31, 31))
+ drvdata->nooverflow = true;
+ else
+ drvdata->nooverflow = false;
+
+ /* number of resources trace unit supports */
+ etmidr4 = readl_relaxed(drvdata->base + TRCIDR4);
+ /* NUMACPAIRS, bits[0:3] number of addr comparator pairs for tracing */
+ drvdata->nr_addr_cmp = BMVAL(etmidr4, 0, 3);
+ /* NUMPC, bits[15:12] number of PE comparator inputs for tracing */
+ drvdata->nr_pe_cmp = BMVAL(etmidr4, 12, 15);
+ /* NUMRSPAIR, bits[19:16] the number of resource pairs for tracing */
+ drvdata->nr_resource = BMVAL(etmidr4, 16, 19);
+ /*
+ * NUMSSCC, bits[23:20] the number of single-shot
+ * comparator control for tracing
+ */
+ drvdata->nr_ss_cmp = BMVAL(etmidr4, 20, 23);
+ /* NUMCIDC, bits[27:24] number of Context ID comparators for tracing */
+ drvdata->numcidc = BMVAL(etmidr4, 24, 27);
+ /* NUMVMIDC, bits[31:28] number of VMID comparators for tracing */
+ drvdata->numvmidc = BMVAL(etmidr4, 28, 31);
+
+ etmidr5 = readl_relaxed(drvdata->base + TRCIDR5);
+ /* NUMEXTIN, bits[8:0] number of external inputs implemented */
+ drvdata->nr_ext_inp = BMVAL(etmidr5, 0, 8);
+ /* TRACEIDSIZE, bits[21:16] indicates the trace ID width */
+ drvdata->trcid_size = BMVAL(etmidr5, 16, 21);
+ /* ATBTRIG, bit[22] implementation can support ATB triggers? */
+ if (BMVAL(etmidr5, 22, 22))
+ drvdata->atbtrig = true;
+ else
+ drvdata->atbtrig = false;
+ /*
+ * LPOVERRIDE, bit[23] implementation supports
+ * low-power state override
+ */
+ if (BMVAL(etmidr5, 23, 23))
+ drvdata->lpoverride = true;
+ else
+ drvdata->lpoverride = false;
+ /* NUMSEQSTATE, bits[27:25] number of sequencer states implemented */
+ drvdata->nrseqstate = BMVAL(etmidr5, 25, 27);
+ /* NUMCNTR, bits[30:28] number of counters available for tracing */
+ drvdata->nr_cntr = BMVAL(etmidr5, 28, 30);
+ CS_LOCK(drvdata->base);
+}
+
+static void etm4_init_default_data(struct etmv4_drvdata *drvdata)
+{
+ int i;
+
+ drvdata->pe_sel = 0x0;
+ drvdata->cfg = (ETMv4_MODE_CTXID | ETM_MODE_VMID |
+ ETMv4_MODE_TIMESTAMP | ETM_MODE_RETURNSTACK);
+
+ /* disable all events tracing */
+ drvdata->eventctrl0 = 0x0;
+ drvdata->eventctrl1 = 0x0;
+
+ /* disable stalling */
+ drvdata->stall_ctrl = 0x0;
+
+ /* disable timestamp event */
+ drvdata->ts_ctrl = 0x0;
+
+ /* enable trace synchronization every 4096 bytes for trace */
+ if (drvdata->syncpr == false)
+ drvdata->syncfreq = 0xC;
+
+ /*
+ * enable viewInst to trace everything with start-stop logic in
+ * started state
+ */
+ drvdata->vinst_ctrl |= BIT(0);
+ /* set initial state of start-stop logic */
+ if (drvdata->nr_addr_cmp)
+ drvdata->vinst_ctrl |= BIT(9);
+
+ /* no address range filtering for ViewInst */
+ drvdata->viiectlr = 0x0;
+ /* no start-stop filtering for ViewInst */
+ drvdata->vissctlr = 0x0;
+
+ /* disable seq events */
+ for (i = 0; i < drvdata->nrseqstate-1; i++)
+ drvdata->seq_ctrl[i] = 0x0;
+ drvdata->seq_rst = 0x0;
+ drvdata->seq_state = 0x0;
+
+ /* disable external input events */
+ drvdata->ext_inp = 0x0;
+
+ for (i = 0; i < drvdata->nr_cntr; i++) {
+ drvdata->cntrldvr[i] = 0x0;
+ drvdata->cntr_ctrl[i] = 0x0;
+ drvdata->cntr_val[i] = 0x0;
+ }
+
+ for (i = 2; i < drvdata->nr_resource * 2; i++)
+ drvdata->res_ctrl[i] = 0x0;
+
+ for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ drvdata->ss_ctrl[i] = 0x0;
+ drvdata->ss_pe_cmp[i] = 0x0;
+ }
+
+ if (drvdata->nr_addr_cmp >= 1) {
+ drvdata->addr_val[0] = (unsigned long)_stext;
+ drvdata->addr_val[1] = (unsigned long)_etext;
+ drvdata->addr_type[0] = ETM_ADDR_TYPE_RANGE;
+ drvdata->addr_type[1] = ETM_ADDR_TYPE_RANGE;
+ }
+
+ for (i = 0; i < drvdata->numcidc; i++)
+ drvdata->ctxid_val[i] = 0x0;
+ drvdata->ctxid_mask0 = 0x0;
+ drvdata->ctxid_mask1 = 0x0;
+
+ for (i = 0; i < drvdata->numvmidc; i++)
+ drvdata->vmid_val[i] = 0x0;
+ drvdata->vmid_mask0 = 0x0;
+ drvdata->vmid_mask1 = 0x0;
+
+ /*
+ * A trace ID value of 0 is invalid, so let's start at some
+ * random value that fits in 7 bits. ETMv3.x has 0x10 so let's
+ * start at 0x20.
+ */
+ drvdata->trcid = 0x20 + drvdata->cpu;
+}
+
+static int etm4_cpu_callback(struct notifier_block *nfb, unsigned long action,
+ void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ if (!etmdrvdata[cpu])
+ goto out;
+
+ switch (action & (~CPU_TASKS_FROZEN)) {
+ case CPU_STARTING:
+ spin_lock(&etmdrvdata[cpu]->spinlock);
+ if (!etmdrvdata[cpu]->os_unlock) {
+ etm4_os_unlock(etmdrvdata[cpu]);
+ etmdrvdata[cpu]->os_unlock = true;
+ }
+
+ if (etmdrvdata[cpu]->enable)
+ etm4_enable_hw(etmdrvdata[cpu]);
+ spin_unlock(&etmdrvdata[cpu]->spinlock);
+ break;
+
+ case CPU_ONLINE:
+ if (etmdrvdata[cpu]->boot_enable &&
+ !etmdrvdata[cpu]->sticky_enable)
+ coresight_enable(etmdrvdata[cpu]->csdev);
+ break;
+
+ case CPU_DYING:
+ spin_lock(&etmdrvdata[cpu]->spinlock);
+ if (etmdrvdata[cpu]->enable)
+ etm4_disable_hw(etmdrvdata[cpu]);
+ spin_unlock(&etmdrvdata[cpu]->spinlock);
+ break;
+ }
+out:
+ return NOTIFY_OK;
+}
+
+static struct notifier_block etm4_cpu_notifier = {
+ .notifier_call = etm4_cpu_callback,
+};
+
+static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
+{
+ int ret;
+ void __iomem *base;
+ struct device *dev = &adev->dev;
+ struct coresight_platform_data *pdata = NULL;
+ struct etmv4_drvdata *drvdata;
+ struct resource *res = &adev->res;
+ struct coresight_desc *desc;
+ struct device_node *np = adev->dev.of_node;
+
+ desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ if (np) {
+ pdata = of_get_coresight_platform_data(dev, np);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ adev->dev.platform_data = pdata;
+ }
+
+ drvdata->dev = &adev->dev;
+ dev_set_drvdata(dev, drvdata);
+
+ /* Validity for the resource is already checked by the AMBA core */
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ drvdata->base = base;
+
+ spin_lock_init(&drvdata->spinlock);
+
+ drvdata->cpu = pdata ? pdata->cpu : 0;
+
+ get_online_cpus();
+ etmdrvdata[drvdata->cpu] = drvdata;
+
+ if (!smp_call_function_single(drvdata->cpu, etm4_os_unlock, drvdata, 1))
+ drvdata->os_unlock = true;
+
+ if (smp_call_function_single(drvdata->cpu,
+ etm4_init_arch_data, drvdata, 1))
+ dev_err(dev, "ETM arch init failed\n");
+
+ if (!etm4_count++)
+ register_hotcpu_notifier(&etm4_cpu_notifier);
+
+ put_online_cpus();
+
+ if (etm4_arch_supported(drvdata->arch) == false) {
+ ret = -EINVAL;
+ goto err_arch_supported;
+ }
+ etm4_init_default_data(drvdata);
+
+ pm_runtime_put(&adev->dev);
+
+ desc->type = CORESIGHT_DEV_TYPE_SOURCE;
+ desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC;
+ desc->ops = &etm4_cs_ops;
+ desc->pdata = pdata;
+ desc->dev = dev;
+ desc->groups = coresight_etmv4_groups;
+ drvdata->csdev = coresight_register(desc);
+ if (IS_ERR(drvdata->csdev)) {
+ ret = PTR_ERR(drvdata->csdev);
+ goto err_coresight_register;
+ }
+
+ dev_info(dev, "%s initialized\n", (char *)id->data);
+
+ if (boot_enable) {
+ coresight_enable(drvdata->csdev);
+ drvdata->boot_enable = true;
+ }
+
+ return 0;
+
+err_arch_supported:
+ pm_runtime_put(&adev->dev);
+err_coresight_register:
+ if (--etm4_count == 0)
+ unregister_hotcpu_notifier(&etm4_cpu_notifier);
+ return ret;
+}
+
+static int etm4_remove(struct amba_device *adev)
+{
+ struct etmv4_drvdata *drvdata = amba_get_drvdata(adev);
+
+ coresight_unregister(drvdata->csdev);
+ if (--etm4_count == 0)
+ unregister_hotcpu_notifier(&etm4_cpu_notifier);
+
+ return 0;
+}
+
+static struct amba_id etm4_ids[] = {
+ { /* ETM 4.0 - Juno board */
+ .id = 0x000bb95e,
+ .mask = 0x000fffff,
+ .data = "ETM 4.0",
+ },
+ { 0, 0},
+};
+
+static struct amba_driver etm4x_driver = {
+ .drv = {
+ .name = "coresight-etm4x",
+ },
+ .probe = etm4_probe,
+ .remove = etm4_remove,
+ .id_table = etm4_ids,
+};
+
+module_amba_driver(etm4x_driver);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
new file mode 100644
index 000000000000..e08e983dd2d9
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -0,0 +1,391 @@
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef _CORESIGHT_CORESIGHT_ETM_H
+#define _CORESIGHT_CORESIGHT_ETM_H
+
+#include <linux/spinlock.h>
+#include "coresight-priv.h"
+
+/*
+ * Device registers:
+ * 0x000 - 0x2FC: Trace registers
+ * 0x300 - 0x314: Management registers
+ * 0x318 - 0xEFC: Trace registers
+ * 0xF00: Management registers
+ * 0xFA0 - 0xFA4: Trace registers
+ * 0xFA8 - 0xFFC: Management registers
+ */
+/* Trace registers (0x000-0x2FC) */
+/* Main control and configuration registers */
+#define TRCPRGCTLR 0x004
+#define TRCPROCSELR 0x008
+#define TRCSTATR 0x00C
+#define TRCCONFIGR 0x010
+#define TRCAUXCTLR 0x018
+#define TRCEVENTCTL0R 0x020
+#define TRCEVENTCTL1R 0x024
+#define TRCSTALLCTLR 0x02C
+#define TRCTSCTLR 0x030
+#define TRCSYNCPR 0x034
+#define TRCCCCTLR 0x038
+#define TRCBBCTLR 0x03C
+#define TRCTRACEIDR 0x040
+#define TRCQCTLR 0x044
+/* Filtering control registers */
+#define TRCVICTLR 0x080
+#define TRCVIIECTLR 0x084
+#define TRCVISSCTLR 0x088
+#define TRCVIPCSSCTLR 0x08C
+#define TRCVDCTLR 0x0A0
+#define TRCVDSACCTLR 0x0A4
+#define TRCVDARCCTLR 0x0A8
+/* Derived resources registers */
+#define TRCSEQEVRn(n) (0x100 + (n * 4))
+#define TRCSEQRSTEVR 0x118
+#define TRCSEQSTR 0x11C
+#define TRCEXTINSELR 0x120
+#define TRCCNTRLDVRn(n) (0x140 + (n * 4))
+#define TRCCNTCTLRn(n) (0x150 + (n * 4))
+#define TRCCNTVRn(n) (0x160 + (n * 4))
+/* ID registers */
+#define TRCIDR8 0x180
+#define TRCIDR9 0x184
+#define TRCIDR10 0x188
+#define TRCIDR11 0x18C
+#define TRCIDR12 0x190
+#define TRCIDR13 0x194
+#define TRCIMSPEC0 0x1C0
+#define TRCIMSPECn(n) (0x1C0 + (n * 4))
+#define TRCIDR0 0x1E0
+#define TRCIDR1 0x1E4
+#define TRCIDR2 0x1E8
+#define TRCIDR3 0x1EC
+#define TRCIDR4 0x1F0
+#define TRCIDR5 0x1F4
+#define TRCIDR6 0x1F8
+#define TRCIDR7 0x1FC
+/* Resource selection registers */
+#define TRCRSCTLRn(n) (0x200 + (n * 4))
+/* Single-shot comparator registers */
+#define TRCSSCCRn(n) (0x280 + (n * 4))
+#define TRCSSCSRn(n) (0x2A0 + (n * 4))
+#define TRCSSPCICRn(n) (0x2C0 + (n * 4))
+/* Management registers (0x300-0x314) */
+#define TRCOSLAR 0x300
+#define TRCOSLSR 0x304
+#define TRCPDCR 0x310
+#define TRCPDSR 0x314
+/* Trace registers (0x318-0xEFC) */
+/* Comparator registers */
+#define TRCACVRn(n) (0x400 + (n * 8))
+#define TRCACATRn(n) (0x480 + (n * 8))
+#define TRCDVCVRn(n) (0x500 + (n * 16))
+#define TRCDVCMRn(n) (0x580 + (n * 16))
+#define TRCCIDCVRn(n) (0x600 + (n * 8))
+#define TRCVMIDCVRn(n) (0x640 + (n * 8))
+#define TRCCIDCCTLR0 0x680
+#define TRCCIDCCTLR1 0x684
+#define TRCVMIDCCTLR0 0x688
+#define TRCVMIDCCTLR1 0x68C
+/* Management register (0xF00) */
+/* Integration control registers */
+#define TRCITCTRL 0xF00
+/* Trace registers (0xFA0-0xFA4) */
+/* Claim tag registers */
+#define TRCCLAIMSET 0xFA0
+#define TRCCLAIMCLR 0xFA4
+/* Management registers (0xFA8-0xFFC) */
+#define TRCDEVAFF0 0xFA8
+#define TRCDEVAFF1 0xFAC
+#define TRCLAR 0xFB0
+#define TRCLSR 0xFB4
+#define TRCAUTHSTATUS 0xFB8
+#define TRCDEVARCH 0xFBC
+#define TRCDEVID 0xFC8
+#define TRCDEVTYPE 0xFCC
+#define TRCPIDR4 0xFD0
+#define TRCPIDR5 0xFD4
+#define TRCPIDR6 0xFD8
+#define TRCPIDR7 0xFDC
+#define TRCPIDR0 0xFE0
+#define TRCPIDR1 0xFE4
+#define TRCPIDR2 0xFE8
+#define TRCPIDR3 0xFEC
+#define TRCCIDR0 0xFF0
+#define TRCCIDR1 0xFF4
+#define TRCCIDR2 0xFF8
+#define TRCCIDR3 0xFFC
+
+/* ETMv4 resources */
+#define ETM_MAX_NR_PE 8
+#define ETMv4_MAX_CNTR 4
+#define ETM_MAX_SEQ_STATES 4
+#define ETM_MAX_EXT_INP_SEL 4
+#define ETM_MAX_EXT_INP 256
+#define ETM_MAX_EXT_OUT 4
+#define ETM_MAX_SINGLE_ADDR_CMP 16
+#define ETM_MAX_ADDR_RANGE_CMP (ETM_MAX_SINGLE_ADDR_CMP / 2)
+#define ETM_MAX_DATA_VAL_CMP 8
+#define ETMv4_MAX_CTXID_CMP 8
+#define ETM_MAX_VMID_CMP 8
+#define ETM_MAX_PE_CMP 8
+#define ETM_MAX_RES_SEL 16
+#define ETM_MAX_SS_CMP 8
+
+#define ETM_ARCH_V4 0x40
+#define ETMv4_SYNC_MASK 0x1F
+#define ETM_CYC_THRESHOLD_MASK 0xFFF
+#define ETMv4_EVENT_MASK 0xFF
+#define ETM_CNTR_MAX_VAL 0xFFFF
+#define ETM_TRACEID_MASK 0x3f
+
+/* ETMv4 programming modes */
+#define ETM_MODE_EXCLUDE BIT(0)
+#define ETM_MODE_LOAD BIT(1)
+#define ETM_MODE_STORE BIT(2)
+#define ETM_MODE_LOAD_STORE BIT(3)
+#define ETM_MODE_BB BIT(4)
+#define ETMv4_MODE_CYCACC BIT(5)
+#define ETMv4_MODE_CTXID BIT(6)
+#define ETM_MODE_VMID BIT(7)
+#define ETM_MODE_COND(val) BMVAL(val, 8, 10)
+#define ETMv4_MODE_TIMESTAMP BIT(11)
+#define ETM_MODE_RETURNSTACK BIT(12)
+#define ETM_MODE_QELEM(val) BMVAL(val, 13, 14)
+#define ETM_MODE_DATA_TRACE_ADDR BIT(15)
+#define ETM_MODE_DATA_TRACE_VAL BIT(16)
+#define ETM_MODE_ISTALL BIT(17)
+#define ETM_MODE_DSTALL BIT(18)
+#define ETM_MODE_ATB_TRIGGER BIT(19)
+#define ETM_MODE_LPOVERRIDE BIT(20)
+#define ETM_MODE_ISTALL_EN BIT(21)
+#define ETM_MODE_DSTALL_EN BIT(22)
+#define ETM_MODE_INSTPRIO BIT(23)
+#define ETM_MODE_NOOVERFLOW BIT(24)
+#define ETM_MODE_TRACE_RESET BIT(25)
+#define ETM_MODE_TRACE_ERR BIT(26)
+#define ETM_MODE_VIEWINST_STARTSTOP BIT(27)
+#define ETMv4_MODE_ALL 0xFFFFFFF
+
+#define TRCSTATR_IDLE_BIT 0
+
+/**
+ * struct etm4_drvdata - specifics associated to an ETM component
+ * @base: Memory mapped base address for this component.
+ * @dev: The device entity associated to this component.
+ * @csdev: Component vitals needed by the framework.
+ * @spinlock: Only one at a time pls.
+ * @cpu: The cpu this component is affined to.
+ * @arch: ETM version number.
+ * @enable: Is this ETM currently tracing.
+ * @sticky_enable: true if ETM base configuration has been done.
+ * @boot_enable:True if we should start tracing at boot time.
+ * @os_unlock: True if access to management registers is allowed.
+ * @nr_pe: The number of processing entity available for tracing.
+ * @nr_pe_cmp: The number of processing entity comparator inputs that are
+ * available for tracing.
+ * @nr_addr_cmp:Number of pairs of address comparators available
+ * as found in ETMIDR4 0-3.
+ * @nr_cntr: Number of counters as found in ETMIDR5 bit 28-30.
+ * @nr_ext_inp: Number of external input.
+ * @numcidc: Number of contextID comparators.
+ * @numvmidc: Number of VMID comparators.
+ * @nrseqstate: The number of sequencer states that are implemented.
+ * @nr_event: Indicates how many events the trace unit support.
+ * @nr_resource:The number of resource selection pairs available for tracing.
+ * @nr_ss_cmp: Number of single-shot comparator controls that are available.
+ * @mode: Controls various modes supported by this ETM.
+ * @trcid: value of the current ID for this component.
+ * @trcid_size: Indicates the trace ID width.
+ * @instrp0: Tracing of load and store instructions
+ * as P0 elements is supported.
+ * @trccond: If the trace unit supports conditional
+ * instruction tracing.
+ * @retstack: Indicates if the implementation supports a return stack.
+ * @trc_error: Whether a trace unit can trace a system
+ * error exception.
+ * @atbtrig: If the implementation can support ATB triggers
+ * @lpoverride: If the implementation can support low-power state over.
+ * @pe_sel: Controls which PE to trace.
+ * @cfg: Controls the tracing options.
+ * @eventctrl0: Controls the tracing of arbitrary events.
+ * @eventctrl1: Controls the behavior of the events that @event_ctrl0 selects.
+ * @stallctl: If functionality that prevents trace unit buffer overflows
+ * is available.
+ * @sysstall: Does the system support stall control of the PE?
+ * @nooverflow: Indicate if overflow prevention is supported.
+ * @stall_ctrl: Enables trace unit functionality that prevents trace
+ * unit buffer overflows.
+ * @ts_size: Global timestamp size field.
+ * @ts_ctrl: Controls the insertion of global timestamps in the
+ * trace streams.
+ * @syncpr: Indicates if an implementation has a fixed
+ * synchronization period.
+ * @syncfreq: Controls how often trace synchronization requests occur.
+ * @trccci: Indicates if the trace unit supports cycle counting
+ * for instruction.
+ * @ccsize: Indicates the size of the cycle counter in bits.
+ * @ccitmin: minimum value that can be programmed in
+ * the TRCCCCTLR register.
+ * @ccctlr: Sets the threshold value for cycle counting.
+ * @trcbb: Indicates if the trace unit supports branch broadcast tracing.
+ * @q_support: Q element support characteristics.
+ * @vinst_ctrl: Controls instruction trace filtering.
+ * @viiectlr: Set or read, the address range comparators.
+ * @vissctlr: Set, or read, the single address comparators that control the
+ * ViewInst start-stop logic.
+ * @vipcssctlr: Set, or read, which PE comparator inputs can control the
+ * ViewInst start-stop logic.
+ * @seq_idx: Sequencor index selector.
+ * @seq_ctrl: Control for the sequencer state transition control register.
+ * @seq_rst: Moves the sequencer to state 0 when a programmed event occurs.
+ * @seq_state: Set, or read the sequencer state.
+ * @cntr_idx: Counter index seletor.
+ * @cntrldvr: Sets or returns the reload count value for a counter.
+ * @cntr_ctrl: Controls the operation of a counter.
+ * @cntr_val: Sets or returns the value for a counter.
+ * @res_idx: Resource index selector.
+ * @res_ctrl: Controls the selection of the resources in the trace unit.
+ * @ss_ctrl: Controls the corresponding single-shot comparator resource.
+ * @ss_status: The status of the corresponding single-shot comparator.
+ * @ss_pe_cmp: Selects the PE comparator inputs for Single-shot control.
+ * @addr_idx: Address comparator index selector.
+ * @addr_val: Value for address comparator.
+ * @addr_acc: Address comparator access type.
+ * @addr_type: Current status of the comparator register.
+ * @ctxid_idx: Context ID index selector.
+ * @ctxid_size: Size of the context ID field to consider.
+ * @ctxid_val: Value of the context ID comparator.
+ * @ctxid_mask0:Context ID comparator mask for comparator 0-3.
+ * @ctxid_mask1:Context ID comparator mask for comparator 4-7.
+ * @vmid_idx: VM ID index selector.
+ * @vmid_size: Size of the VM ID comparator to consider.
+ * @vmid_val: Value of the VM ID comparator.
+ * @vmid_mask0: VM ID comparator mask for comparator 0-3.
+ * @vmid_mask1: VM ID comparator mask for comparator 4-7.
+ * @s_ex_level: In secure state, indicates whether instruction tracing is
+ * supported for the corresponding Exception level.
+ * @ns_ex_level:In non-secure state, indicates whether instruction tracing is
+ * supported for the corresponding Exception level.
+ * @ext_inp: External input selection.
+ */
+struct etmv4_drvdata {
+ void __iomem *base;
+ struct device *dev;
+ struct coresight_device *csdev;
+ spinlock_t spinlock;
+ int cpu;
+ u8 arch;
+ bool enable;
+ bool sticky_enable;
+ bool boot_enable;
+ bool os_unlock;
+ u8 nr_pe;
+ u8 nr_pe_cmp;
+ u8 nr_addr_cmp;
+ u8 nr_cntr;
+ u8 nr_ext_inp;
+ u8 numcidc;
+ u8 numvmidc;
+ u8 nrseqstate;
+ u8 nr_event;
+ u8 nr_resource;
+ u8 nr_ss_cmp;
+ u32 mode;
+ u8 trcid;
+ u8 trcid_size;
+ bool instrp0;
+ bool trccond;
+ bool retstack;
+ bool trc_error;
+ bool atbtrig;
+ bool lpoverride;
+ u32 pe_sel;
+ u32 cfg;
+ u32 eventctrl0;
+ u32 eventctrl1;
+ bool stallctl;
+ bool sysstall;
+ bool nooverflow;
+ u32 stall_ctrl;
+ u8 ts_size;
+ u32 ts_ctrl;
+ bool syncpr;
+ u32 syncfreq;
+ bool trccci;
+ u8 ccsize;
+ u8 ccitmin;
+ u32 ccctlr;
+ bool trcbb;
+ u32 bb_ctrl;
+ bool q_support;
+ u32 vinst_ctrl;
+ u32 viiectlr;
+ u32 vissctlr;
+ u32 vipcssctlr;
+ u8 seq_idx;
+ u32 seq_ctrl[ETM_MAX_SEQ_STATES];
+ u32 seq_rst;
+ u32 seq_state;
+ u8 cntr_idx;
+ u32 cntrldvr[ETMv4_MAX_CNTR];
+ u32 cntr_ctrl[ETMv4_MAX_CNTR];
+ u32 cntr_val[ETMv4_MAX_CNTR];
+ u8 res_idx;
+ u32 res_ctrl[ETM_MAX_RES_SEL];
+ u32 ss_ctrl[ETM_MAX_SS_CMP];
+ u32 ss_status[ETM_MAX_SS_CMP];
+ u32 ss_pe_cmp[ETM_MAX_SS_CMP];
+ u8 addr_idx;
+ u64 addr_val[ETM_MAX_SINGLE_ADDR_CMP];
+ u64 addr_acc[ETM_MAX_SINGLE_ADDR_CMP];
+ u8 addr_type[ETM_MAX_SINGLE_ADDR_CMP];
+ u8 ctxid_idx;
+ u8 ctxid_size;
+ u64 ctxid_val[ETMv4_MAX_CTXID_CMP];
+ u32 ctxid_mask0;
+ u32 ctxid_mask1;
+ u8 vmid_idx;
+ u8 vmid_size;
+ u64 vmid_val[ETM_MAX_VMID_CMP];
+ u32 vmid_mask0;
+ u32 vmid_mask1;
+ u8 s_ex_level;
+ u8 ns_ex_level;
+ u32 ext_inp;
+};
+
+/* Address comparator access types */
+enum etm_addr_acctype {
+ ETM_INSTR_ADDR,
+ ETM_DATA_LOAD_ADDR,
+ ETM_DATA_STORE_ADDR,
+ ETM_DATA_LOAD_STORE_ADDR,
+};
+
+/* Address comparator context types */
+enum etm_addr_ctxtype {
+ ETM_CTX_NONE,
+ ETM_CTX_CTXID,
+ ETM_CTX_VMID,
+ ETM_CTX_CTXID_VMID,
+};
+
+enum etm_addr_type {
+ ETM_ADDR_TYPE_NONE,
+ ETM_ADDR_TYPE_SINGLE,
+ ETM_ADDR_TYPE_RANGE,
+ ETM_ADDR_TYPE_START,
+ ETM_ADDR_TYPE_STOP,
+};
+#endif
--
1.9.1
^ permalink raw reply related
* [PATCH v3 02/11] coresight-etm4x: Controls pertaining to tracer configuration
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
kaixu.xia-QSEj5FYQhm4dnm+yROfE0A,
zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A,
mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
From: Pratik Patel <pratikp-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Tracers can be configured with various options at synthesis
time and knowing what resources are available is important for
SW configuration purposes.
As such adding RO sysfs entries for characteristics related to the
tracer implementation.
Signed-off-by: Pratik Patel <pratikp-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 61 +++++++++++
drivers/hwtracing/coresight/coresight-etm4x.c | 117 +++++++++++++++++++++
2 files changed, 178 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
index a4b623871ca0..0f579eb24631 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -26,3 +26,64 @@ Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Description: (R) Provides value of all the ID registers (TRCIDRx).
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/nr_pe_cmp
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) Indicates the number of PE comparator inputs that are
+ available for tracing.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/nr_addr_cmp
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) Indicates the number of address comparator pairs that are
+ available for tracing.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/nr_cntr
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) Indicates the number of counters that are available for
+ tracing.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/nr_ext_inp
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) Indicates how many external inputs are implemented.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/numcidc
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) Indicates the number of Context ID comparators that are
+ available for tracing.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/numvmidc
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) Indicates the number of VMID comparators that are available
+ for tracing.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/nrseqstate
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) Indicates the number of sequencer states that are implemented.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/nr_resource
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) Indicates the number of resource selection pairs that are
+ available for tracing.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/nr_ss_cmp
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (R) Indicates the number of single-shot comparator controls that
+ are available for tracing.
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index db0bea4d4661..c7421f319350 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -268,6 +268,114 @@ static const struct coresight_ops etm4_cs_ops = {
.source_ops = &etm4_source_ops,
};
+static ssize_t nr_pe_cmp_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->nr_pe_cmp;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR_RO(nr_pe_cmp);
+
+static ssize_t nr_addr_cmp_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->nr_addr_cmp;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR_RO(nr_addr_cmp);
+
+static ssize_t nr_cntr_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->nr_cntr;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR_RO(nr_cntr);
+
+static ssize_t nr_ext_inp_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->nr_ext_inp;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR_RO(nr_ext_inp);
+
+static ssize_t numcidc_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->numcidc;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR_RO(numcidc);
+
+static ssize_t numvmidc_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->numvmidc;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR_RO(numvmidc);
+
+static ssize_t nrseqstate_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->nrseqstate;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR_RO(nrseqstate);
+
+static ssize_t nr_resource_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->nr_resource;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR_RO(nr_resource);
+
+static ssize_t nr_ss_cmp_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->nr_ss_cmp;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR_RO(nr_ss_cmp);
+
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -412,6 +520,15 @@ static ssize_t trcidr_show(struct device *dev,
static DEVICE_ATTR_RO(trcidr);
static struct attribute *coresight_etmv4_attrs[] = {
+ &dev_attr_nr_pe_cmp.attr,
+ &dev_attr_nr_addr_cmp.attr,
+ &dev_attr_nr_cntr.attr,
+ &dev_attr_nr_ext_inp.attr,
+ &dev_attr_numcidc.attr,
+ &dev_attr_numvmidc.attr,
+ &dev_attr_nrseqstate.attr,
+ &dev_attr_nr_resource.attr,
+ &dev_attr_nr_ss_cmp.attr,
&dev_attr_status.attr,
&dev_attr_mgmt.attr,
&dev_attr_trcidr.attr,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 03/11] coresight-etm4x: Controls pertaining to the reset, mode, pe and events
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh
Cc: mathieu.poirier, linux-api, linux-kernel, zhang.chunyan,
linux-arm-kernel, kaixu.xia
In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier@linaro.org>
From: Pratik Patel <pratikp@codeaurora.org>
Adding sysfs entries to:
. set the tracing entity with default values.
. set various mode associated to the tracing entity.
. select the processing entity the tracing entity relates to.
. select various events of interest.
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 33 ++
drivers/hwtracing/coresight/coresight-etm4x.c | 442 ++++++++++++++++++++-
2 files changed, 474 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
index 0f579eb24631..9caf70382088 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -87,3 +87,36 @@ KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (R) Indicates the number of single-shot comparator controls that
are available for tracing.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/reset
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (W) Cancels all configuration on a trace unit and set it back
+ to its boot configuration.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/mode
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Controls various modes supported by this ETM, for example
+ P0 instruction tracing, branch broadcast, cycle counting and
+ context ID tracing.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/pe
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Controls which PE to trace.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/event
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Controls the tracing of arbitrary events from bank 0 to 3.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/event_instren
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Controls the behavior of the events in bank 0 to 3.
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index c7421f319350..1a93b968ab6e 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -268,6 +268,46 @@ static const struct coresight_ops etm4_cs_ops = {
.source_ops = &etm4_source_ops,
};
+static int etm4_set_mode_exclude(struct etmv4_drvdata *drvdata, bool exclude)
+{
+ u8 idx = drvdata->addr_idx;
+
+ /*
+ * TRCACATRn.TYPE bit[1:0]: type of comparison
+ * the trace unit performs
+ */
+ if (BMVAL(drvdata->addr_acc[idx], 0, 1) == ETM_INSTR_ADDR) {
+ if (idx % 2 != 0)
+ return -EINVAL;
+
+ /*
+ * We are performing instruction address comparison. Set the
+ * relevant bit of ViewInst Include/Exclude Control register
+ * for corresponding address comparator pair.
+ */
+ if (drvdata->addr_type[idx] != ETM_ADDR_TYPE_RANGE ||
+ drvdata->addr_type[idx + 1] != ETM_ADDR_TYPE_RANGE)
+ return -EINVAL;
+
+ if (exclude == true) {
+ /*
+ * Set exclude bit and unset the include bit
+ * corresponding to comparator pair
+ */
+ drvdata->viiectlr |= BIT(idx / 2 + 16);
+ drvdata->viiectlr &= ~BIT(idx / 2);
+ } else {
+ /*
+ * Set include bit and unset exclude bit
+ * corresponding to comparator pair
+ */
+ drvdata->viiectlr |= BIT(idx / 2);
+ drvdata->viiectlr &= ~BIT(idx / 2 + 16);
+ }
+ }
+ return 0;
+}
+
static ssize_t nr_pe_cmp_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -376,6 +416,402 @@ static ssize_t nr_ss_cmp_show(struct device *dev,
}
static DEVICE_ATTR_RO(nr_ss_cmp);
+static ssize_t reset_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ int i;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ if (val)
+ drvdata->mode = 0x0;
+
+ /* Disable data tracing: do not trace load and store data transfers */
+ drvdata->mode &= ~(ETM_MODE_LOAD | ETM_MODE_STORE);
+ drvdata->cfg &= ~(BIT(1) | BIT(2));
+
+ /* Disable data value and data address tracing */
+ drvdata->mode &= ~(ETM_MODE_DATA_TRACE_ADDR |
+ ETM_MODE_DATA_TRACE_VAL);
+ drvdata->cfg &= ~(BIT(16) | BIT(17));
+
+ /* Disable all events tracing */
+ drvdata->eventctrl0 = 0x0;
+ drvdata->eventctrl1 = 0x0;
+
+ /* Disable timestamp event */
+ drvdata->ts_ctrl = 0x0;
+
+ /* Disable stalling */
+ drvdata->stall_ctrl = 0x0;
+
+ /* Reset trace synchronization period to 2^8 = 256 bytes*/
+ if (drvdata->syncpr == false)
+ drvdata->syncfreq = 0x8;
+
+ /*
+ * Enable ViewInst to trace everything with start-stop logic in
+ * started state. ARM recommends start-stop logic is set before
+ * each trace run.
+ */
+ drvdata->vinst_ctrl |= BIT(0);
+ if (drvdata->nr_addr_cmp == true) {
+ drvdata->mode |= ETM_MODE_VIEWINST_STARTSTOP;
+ /* SSSTATUS, bit[9] */
+ drvdata->vinst_ctrl |= BIT(9);
+ }
+
+ /* No address range filtering for ViewInst */
+ drvdata->viiectlr = 0x0;
+
+ /* No start-stop filtering for ViewInst */
+ drvdata->vissctlr = 0x0;
+
+ /* Disable seq events */
+ for (i = 0; i < drvdata->nrseqstate-1; i++)
+ drvdata->seq_ctrl[i] = 0x0;
+ drvdata->seq_rst = 0x0;
+ drvdata->seq_state = 0x0;
+
+ /* Disable external input events */
+ drvdata->ext_inp = 0x0;
+
+ drvdata->cntr_idx = 0x0;
+ for (i = 0; i < drvdata->nr_cntr; i++) {
+ drvdata->cntrldvr[i] = 0x0;
+ drvdata->cntr_ctrl[i] = 0x0;
+ drvdata->cntr_val[i] = 0x0;
+ }
+
+ drvdata->res_idx = 0x0;
+ for (i = 0; i < drvdata->nr_resource; i++)
+ drvdata->res_ctrl[i] = 0x0;
+
+ for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ drvdata->ss_ctrl[i] = 0x0;
+ drvdata->ss_pe_cmp[i] = 0x0;
+ }
+
+ drvdata->addr_idx = 0x0;
+ for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
+ drvdata->addr_val[i] = 0x0;
+ drvdata->addr_acc[i] = 0x0;
+ drvdata->addr_type[i] = ETM_ADDR_TYPE_NONE;
+ }
+
+ drvdata->ctxid_idx = 0x0;
+ for (i = 0; i < drvdata->numcidc; i++)
+ drvdata->ctxid_val[i] = 0x0;
+ drvdata->ctxid_mask0 = 0x0;
+ drvdata->ctxid_mask1 = 0x0;
+
+ drvdata->vmid_idx = 0x0;
+ for (i = 0; i < drvdata->numvmidc; i++)
+ drvdata->vmid_val[i] = 0x0;
+ drvdata->vmid_mask0 = 0x0;
+ drvdata->vmid_mask1 = 0x0;
+
+ drvdata->trcid = drvdata->cpu + 1;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_WO(reset);
+
+static ssize_t mode_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->mode;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val, mode;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ drvdata->mode = val & ETMv4_MODE_ALL;
+
+ if (drvdata->mode & ETM_MODE_EXCLUDE)
+ etm4_set_mode_exclude(drvdata, true);
+ else
+ etm4_set_mode_exclude(drvdata, false);
+
+ if (drvdata->instrp0 == true) {
+ /* start by clearing instruction P0 field */
+ drvdata->cfg &= ~(BIT(1) | BIT(2));
+ if (drvdata->mode & ETM_MODE_LOAD)
+ /* 0b01 Trace load instructions as P0 instructions */
+ drvdata->cfg |= BIT(1);
+ if (drvdata->mode & ETM_MODE_STORE)
+ /* 0b10 Trace store instructions as P0 instructions */
+ drvdata->cfg |= BIT(2);
+ if (drvdata->mode & ETM_MODE_LOAD_STORE)
+ /*
+ * 0b11 Trace load and store instructions
+ * as P0 instructions
+ */
+ drvdata->cfg |= BIT(1) | BIT(2);
+ }
+
+ /* bit[3], Branch broadcast mode */
+ if ((drvdata->mode & ETM_MODE_BB) && (drvdata->trcbb == true))
+ drvdata->cfg |= BIT(3);
+ else
+ drvdata->cfg &= ~BIT(3);
+
+ /* bit[4], Cycle counting instruction trace bit */
+ if ((drvdata->mode & ETMv4_MODE_CYCACC) &&
+ (drvdata->trccci == true))
+ drvdata->cfg |= BIT(4);
+ else
+ drvdata->cfg &= ~BIT(4);
+
+ /* bit[6], Context ID tracing bit */
+ if ((drvdata->mode & ETMv4_MODE_CTXID) && (drvdata->ctxid_size))
+ drvdata->cfg |= BIT(6);
+ else
+ drvdata->cfg &= ~BIT(6);
+
+ if ((drvdata->mode & ETM_MODE_VMID) && (drvdata->vmid_size))
+ drvdata->cfg |= BIT(7);
+ else
+ drvdata->cfg &= ~BIT(7);
+
+ /* bits[10:8], Conditional instruction tracing bit */
+ mode = ETM_MODE_COND(drvdata->mode);
+ if (drvdata->trccond == true) {
+ drvdata->cfg &= ~(BIT(8) | BIT(9) | BIT(10));
+ drvdata->cfg |= mode << 8;
+ }
+
+ /* bit[11], Global timestamp tracing bit */
+ if ((drvdata->mode & ETMv4_MODE_TIMESTAMP) && (drvdata->ts_size))
+ drvdata->cfg |= BIT(11);
+ else
+ drvdata->cfg &= ~BIT(11);
+
+ /* bit[12], Return stack enable bit */
+ if ((drvdata->mode & ETM_MODE_RETURNSTACK) &&
+ (drvdata->retstack == true))
+ drvdata->cfg |= BIT(12);
+ else
+ drvdata->cfg &= ~BIT(12);
+
+ /* bits[14:13], Q element enable field */
+ mode = ETM_MODE_QELEM(drvdata->mode);
+ /* start by clearing QE bits */
+ drvdata->cfg &= ~(BIT(13) | BIT(14));
+ /* if supported, Q elements with instruction counts are enabled */
+ if ((mode & BIT(0)) && (drvdata->q_support & BIT(0)))
+ drvdata->cfg |= BIT(13);
+ /*
+ * if supported, Q elements with and without instruction
+ * counts are enabled
+ */
+ if ((mode & BIT(1)) && (drvdata->q_support & BIT(1)))
+ drvdata->cfg |= BIT(14);
+
+ /* bit[11], AMBA Trace Bus (ATB) trigger enable bit */
+ if ((drvdata->mode & ETM_MODE_ATB_TRIGGER) &&
+ (drvdata->atbtrig == true))
+ drvdata->eventctrl1 |= BIT(11);
+ else
+ drvdata->eventctrl1 &= ~BIT(11);
+
+ /* bit[12], Low-power state behavior override bit */
+ if ((drvdata->mode & ETM_MODE_LPOVERRIDE) &&
+ (drvdata->lpoverride == true))
+ drvdata->eventctrl1 |= BIT(12);
+ else
+ drvdata->eventctrl1 &= ~BIT(12);
+
+ /* bit[8], Instruction stall bit */
+ if (drvdata->mode & ETM_MODE_ISTALL_EN)
+ drvdata->stall_ctrl |= BIT(8);
+ else
+ drvdata->stall_ctrl &= ~BIT(8);
+
+ /* bit[10], Prioritize instruction trace bit */
+ if (drvdata->mode & ETM_MODE_INSTPRIO)
+ drvdata->stall_ctrl |= BIT(10);
+ else
+ drvdata->stall_ctrl &= ~BIT(10);
+
+ /* bit[13], Trace overflow prevention bit */
+ if ((drvdata->mode & ETM_MODE_NOOVERFLOW) &&
+ (drvdata->nooverflow == true))
+ drvdata->stall_ctrl |= BIT(13);
+ else
+ drvdata->stall_ctrl &= ~BIT(13);
+
+ /* bit[9] Start/stop logic control bit */
+ if (drvdata->mode & ETM_MODE_VIEWINST_STARTSTOP)
+ drvdata->vinst_ctrl |= BIT(9);
+ else
+ drvdata->vinst_ctrl &= ~BIT(9);
+
+ /* bit[10], Whether a trace unit must trace a Reset exception */
+ if (drvdata->mode & ETM_MODE_TRACE_RESET)
+ drvdata->vinst_ctrl |= BIT(10);
+ else
+ drvdata->vinst_ctrl &= ~BIT(10);
+
+ /* bit[11], Whether a trace unit must trace a system error exception */
+ if ((drvdata->mode & ETM_MODE_TRACE_ERR) &&
+ (drvdata->trc_error == true))
+ drvdata->vinst_ctrl |= BIT(11);
+ else
+ drvdata->vinst_ctrl &= ~BIT(11);
+
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(mode);
+
+static ssize_t pe_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->pe_sel;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t pe_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ if (val > drvdata->nr_pe) {
+ spin_unlock(&drvdata->spinlock);
+ return -EINVAL;
+ }
+
+ drvdata->pe_sel = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(pe);
+
+static ssize_t event_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->eventctrl0;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t event_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ switch (drvdata->nr_event) {
+ case 0x0:
+ /* EVENT0, bits[7:0] */
+ drvdata->eventctrl0 = val & 0xFF;
+ break;
+ case 0x1:
+ /* EVENT1, bits[15:8] */
+ drvdata->eventctrl0 = val & 0xFFFF;
+ break;
+ case 0x2:
+ /* EVENT2, bits[23:16] */
+ drvdata->eventctrl0 = val & 0xFFFFFF;
+ break;
+ case 0x3:
+ /* EVENT3, bits[31:24] */
+ drvdata->eventctrl0 = val;
+ break;
+ default:
+ break;
+ }
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(event);
+
+static ssize_t event_instren_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = BMVAL(drvdata->eventctrl1, 0, 3);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t event_instren_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ /* start by clearing all instruction event enable bits */
+ drvdata->eventctrl1 &= ~(BIT(0) | BIT(1) | BIT(2) | BIT(3));
+ switch (drvdata->nr_event) {
+ case 0x0:
+ /* generate Event element for event 1 */
+ drvdata->eventctrl1 |= val & BIT(1);
+ break;
+ case 0x1:
+ /* generate Event element for event 1 and 2 */
+ drvdata->eventctrl1 |= val & (BIT(0) | BIT(1));
+ break;
+ case 0x2:
+ /* generate Event element for event 1, 2 and 3 */
+ drvdata->eventctrl1 |= val & (BIT(0) | BIT(1) | BIT(2));
+ break;
+ case 0x3:
+ /* generate Event element for all 4 events */
+ drvdata->eventctrl1 |= val & 0xF;
+ break;
+ default:
+ break;
+ }
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(event_instren);
+
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -518,7 +954,6 @@ static ssize_t trcidr_show(struct device *dev,
return ret;
}
static DEVICE_ATTR_RO(trcidr);
-
static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_nr_pe_cmp.attr,
&dev_attr_nr_addr_cmp.attr,
@@ -529,6 +964,11 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_nrseqstate.attr,
&dev_attr_nr_resource.attr,
&dev_attr_nr_ss_cmp.attr,
+ &dev_attr_reset.attr,
+ &dev_attr_mode.attr,
+ &dev_attr_pe.attr,
+ &dev_attr_event.attr,
+ &dev_attr_event_instren.attr,
&dev_attr_status.attr,
&dev_attr_mgmt.attr,
&dev_attr_trcidr.attr,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 04/11] coresight-etm4x: Controls pertaining to various configuration options
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh
Cc: mathieu.poirier, linux-api, linux-kernel, zhang.chunyan,
linux-arm-kernel, kaixu.xia
In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier@linaro.org>
From: Pratik Patel <pratikp@codeaurora.org>
Adding sysfs entries to configure:
. global timestamp.
. how often trace synchronisation occur.
. the threashold value for cycle counting.
. branch and broadcasting regions.
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 28 ++++-
drivers/hwtracing/coresight/coresight-etm4x.c | 124 +++++++++++++++++++++
2 files changed, 151 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
index 9caf70382088..2aeae2976c10 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -119,4 +119,30 @@ What: /sys/bus/coresight/devices/<memory_map>.etm/event_instren
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
-Description: (RW) Controls the behavior of the events in bank 0 to 3.
+Description: (RW) Controls the behavior of the events in bank 0 to 3
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/event_ts
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Controls the insertion of global timestamps in the trace
+ streams.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/syncfreq
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Controls how often trace synchronization requests occur.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/cyc_threshold
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Sets the threshold value for cycle counting.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/bb_ctrl
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Controls which regions in the memory map are enabled to
+ use branch broadcasting.
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 1a93b968ab6e..9812fbfdbeae 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -812,6 +812,126 @@ static ssize_t event_instren_store(struct device *dev,
}
static DEVICE_ATTR_RW(event_instren);
+static ssize_t event_ts_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->ts_ctrl;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t event_ts_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (!drvdata->ts_size)
+ return -EINVAL;
+
+ drvdata->ts_ctrl = val & ETMv4_EVENT_MASK;
+ return size;
+}
+static DEVICE_ATTR_RW(event_ts);
+
+static ssize_t syncfreq_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->syncfreq;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t syncfreq_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (drvdata->syncpr == true)
+ return -EINVAL;
+
+ drvdata->syncfreq = val & ETMv4_SYNC_MASK;
+ return size;
+}
+static DEVICE_ATTR_RW(syncfreq);
+
+static ssize_t cyc_threshold_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->ccctlr;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t cyc_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (val < drvdata->ccitmin)
+ return -EINVAL;
+
+ drvdata->ccctlr = val & ETM_CYC_THRESHOLD_MASK;
+ return size;
+}
+static DEVICE_ATTR_RW(cyc_threshold);
+
+static ssize_t bb_ctrl_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->bb_ctrl;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t bb_ctrl_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (drvdata->trcbb == false)
+ return -EINVAL;
+ if (!drvdata->nr_addr_cmp)
+ return -EINVAL;
+ /*
+ * Bit[7:0] selects which address range comparator is used for
+ * branch broadcast control.
+ */
+ if (BMVAL(val, 0, 7) > drvdata->nr_addr_cmp)
+ return -EINVAL;
+
+ drvdata->bb_ctrl = val;
+ return size;
+}
+static DEVICE_ATTR_RW(bb_ctrl);
+
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -969,6 +1089,10 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_pe.attr,
&dev_attr_event.attr,
&dev_attr_event_instren.attr,
+ &dev_attr_event_ts.attr,
+ &dev_attr_syncfreq.attr,
+ &dev_attr_cyc_threshold.attr,
+ &dev_attr_bb_ctrl.attr,
&dev_attr_status.attr,
&dev_attr_mgmt.attr,
&dev_attr_trcidr.attr,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 05/11] coresight-etm4x: Controls pertaining to the ViewInst register
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh
Cc: linux-arm-kernel, linux-api, linux-kernel, kaixu.xia,
zhang.chunyan, mathieu.poirier
In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier@linaro.org>
From: Pratik Patel <pratikp@codeaurora.org>
Adding sysfs entries to control the ViewInst register's event
selector along with secure and non-secure exception level
instruction tracing.
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 20 +++++
drivers/hwtracing/coresight/coresight-etm4x.c | 98 ++++++++++++++++++++++
2 files changed, 118 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
index 2aeae2976c10..d7409c3d58e6 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -146,3 +146,23 @@ KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls which regions in the memory map are enabled to
use branch broadcasting.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/event_vinst
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Controls instruction trace filtering.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/s_exlevel_vinst
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) In Secure state, each bit controls whether instruction
+ tracing is enabled for the corresponding exception level.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/ns_exlevel_vinst
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) In non-secure state, each bit controls whether instruction
+ tracing is enabled for the corresponding exception level.
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 9812fbfdbeae..4eb3babb4592 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -932,6 +932,101 @@ static ssize_t bb_ctrl_store(struct device *dev,
}
static DEVICE_ATTR_RW(bb_ctrl);
+static ssize_t event_vinst_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->vinst_ctrl & ETMv4_EVENT_MASK;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t event_vinst_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ val &= ETMv4_EVENT_MASK;
+ drvdata->vinst_ctrl &= ~ETMv4_EVENT_MASK;
+ drvdata->vinst_ctrl |= val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(event_vinst);
+
+static ssize_t s_exlevel_vinst_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = BMVAL(drvdata->vinst_ctrl, 16, 19);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t s_exlevel_vinst_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ /* clear all EXLEVEL_S bits (bit[18] is never implemented) */
+ drvdata->vinst_ctrl &= ~(BIT(16) | BIT(17) | BIT(19));
+ /* enable instruction tracing for corresponding exception level */
+ val &= drvdata->s_ex_level;
+ drvdata->vinst_ctrl |= (val << 16);
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(s_exlevel_vinst);
+
+static ssize_t ns_exlevel_vinst_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ /* EXLEVEL_NS, bits[23:20] */
+ val = BMVAL(drvdata->vinst_ctrl, 20, 23);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t ns_exlevel_vinst_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ /* clear EXLEVEL_NS bits (bit[23] is never implemented */
+ drvdata->vinst_ctrl &= ~(BIT(20) | BIT(21) | BIT(22));
+ /* enable instruction tracing for corresponding exception level */
+ val &= drvdata->ns_ex_level;
+ drvdata->vinst_ctrl |= (val << 20);
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(ns_exlevel_vinst);
+
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1093,6 +1188,9 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_syncfreq.attr,
&dev_attr_cyc_threshold.attr,
&dev_attr_bb_ctrl.attr,
+ &dev_attr_event_vinst.attr,
+ &dev_attr_s_exlevel_vinst.attr,
+ &dev_attr_ns_exlevel_vinst.attr,
&dev_attr_status.attr,
&dev_attr_mgmt.attr,
&dev_attr_trcidr.attr,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 06/11] coresight-etm4x: Controls pertaining to the address comparator functions
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh
Cc: linux-arm-kernel, linux-api, linux-kernel, kaixu.xia,
zhang.chunyan, mathieu.poirier
In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier@linaro.org>
From: Pratik Patel <pratikp@codeaurora.org>
Adding sysfs entries to control the various mode the address comparator
registers can enact, i.e, start/top, single, and range. Also supplementing
with address comparator types configuration registers access, mandatory
to complete the configuration of the comparator functions.
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 25 ++
drivers/hwtracing/coresight/coresight-etm4x.c | 423 +++++++++++++++++++++
2 files changed, 448 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
index d7409c3d58e6..8cdc4ad10bd6 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -166,3 +166,28 @@ KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) In non-secure state, each bit controls whether instruction
tracing is enabled for the corresponding exception level.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/addr_idx
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Select which address comparator or pair (of comparators) to
+ work with.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/addr_instdatatype
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Controls what type of comparison the trace unit performs.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/addr_single
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Used to setup single address comparator values.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/addr_range
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Used to setup address range comparator values.
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 4eb3babb4592..6671be0036e2 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -1027,6 +1027,421 @@ static ssize_t ns_exlevel_vinst_store(struct device *dev,
}
static DEVICE_ATTR_RW(ns_exlevel_vinst);
+static ssize_t addr_idx_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->addr_idx;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t addr_idx_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (val >= drvdata->nr_addr_cmp * 2)
+ return -EINVAL;
+
+ /*
+ * Use spinlock to ensure index doesn't change while it gets
+ * dereferenced multiple times within a spinlock block elsewhere.
+ */
+ spin_lock(&drvdata->spinlock);
+ drvdata->addr_idx = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(addr_idx);
+
+static ssize_t addr_instdatatype_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t len;
+ u8 val, idx;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+ val = BMVAL(drvdata->addr_acc[idx], 0, 1);
+ len = scnprintf(buf, PAGE_SIZE, "%s\n",
+ val == ETM_INSTR_ADDR ? "instr" :
+ (val == ETM_DATA_LOAD_ADDR ? "data_load" :
+ (val == ETM_DATA_STORE_ADDR ? "data_store" :
+ "data_load_store")));
+ spin_unlock(&drvdata->spinlock);
+ return len;
+}
+
+static ssize_t addr_instdatatype_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ char str[20] = "";
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (strlen(buf) >= 20)
+ return -EINVAL;
+ if (sscanf(buf, "%s", str) != 1)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+ if (!strcmp(str, "instr"))
+ /* TYPE, bits[1:0] */
+ drvdata->addr_acc[idx] &= ~(BIT(0) | BIT(1));
+
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(addr_instdatatype);
+
+static ssize_t addr_single_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ idx = drvdata->addr_idx;
+ spin_lock(&drvdata->spinlock);
+ if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
+ spin_unlock(&drvdata->spinlock);
+ return -EPERM;
+ }
+ val = (unsigned long)drvdata->addr_val[idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t addr_single_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+ if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
+ spin_unlock(&drvdata->spinlock);
+ return -EPERM;
+ }
+
+ drvdata->addr_val[idx] = (u64)val;
+ drvdata->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(addr_single);
+
+static ssize_t addr_range_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val1, val2;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+ if (idx % 2 != 0) {
+ spin_unlock(&drvdata->spinlock);
+ return -EPERM;
+ }
+ if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
+ drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
+ (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
+ drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
+ spin_unlock(&drvdata->spinlock);
+ return -EPERM;
+ }
+
+ val1 = (unsigned long)drvdata->addr_val[idx];
+ val2 = (unsigned long)drvdata->addr_val[idx + 1];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
+}
+
+static ssize_t addr_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val1, val2;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+ return -EINVAL;
+ /* lower address comparator cannot have a higher address value */
+ if (val1 > val2)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+ if (idx % 2 != 0) {
+ spin_unlock(&drvdata->spinlock);
+ return -EPERM;
+ }
+
+ if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
+ drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
+ (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
+ drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
+ spin_unlock(&drvdata->spinlock);
+ return -EPERM;
+ }
+
+ drvdata->addr_val[idx] = (u64)val1;
+ drvdata->addr_type[idx] = ETM_ADDR_TYPE_RANGE;
+ drvdata->addr_val[idx + 1] = (u64)val2;
+ drvdata->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
+ /*
+ * Program include or exclude control bits for vinst or vdata
+ * whenever we change addr comparators to ETM_ADDR_TYPE_RANGE
+ */
+ if (drvdata->mode & ETM_MODE_EXCLUDE)
+ etm4_set_mode_exclude(drvdata, true);
+ else
+ etm4_set_mode_exclude(drvdata, false);
+
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(addr_range);
+
+static ssize_t addr_start_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+
+ if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) {
+ spin_unlock(&drvdata->spinlock);
+ return -EPERM;
+ }
+
+ val = (unsigned long)drvdata->addr_val[idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t addr_start_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+ if (!drvdata->nr_addr_cmp) {
+ spin_unlock(&drvdata->spinlock);
+ return -EINVAL;
+ }
+ if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) {
+ spin_unlock(&drvdata->spinlock);
+ return -EPERM;
+ }
+
+ drvdata->addr_val[idx] = (u64)val;
+ drvdata->addr_type[idx] = ETM_ADDR_TYPE_START;
+ drvdata->vissctlr |= BIT(idx);
+ /* SSSTATUS, bit[9] - turn on start/stop logic */
+ drvdata->vinst_ctrl |= BIT(9);
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(addr_start);
+
+static ssize_t addr_stop_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+
+ if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
+ spin_unlock(&drvdata->spinlock);
+ return -EPERM;
+ }
+
+ val = (unsigned long)drvdata->addr_val[idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t addr_stop_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+ if (!drvdata->nr_addr_cmp) {
+ spin_unlock(&drvdata->spinlock);
+ return -EINVAL;
+ }
+ if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
+ spin_unlock(&drvdata->spinlock);
+ return -EPERM;
+ }
+
+ drvdata->addr_val[idx] = (u64)val;
+ drvdata->addr_type[idx] = ETM_ADDR_TYPE_STOP;
+ drvdata->vissctlr |= BIT(idx + 16);
+ /* SSSTATUS, bit[9] - turn on start/stop logic */
+ drvdata->vinst_ctrl |= BIT(9);
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(addr_stop);
+
+static ssize_t addr_ctxtype_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t len;
+ u8 idx, val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+ /* CONTEXTTYPE, bits[3:2] */
+ val = BMVAL(drvdata->addr_acc[idx], 2, 3);
+ len = scnprintf(buf, PAGE_SIZE, "%s\n", val == ETM_CTX_NONE ? "none" :
+ (val == ETM_CTX_CTXID ? "ctxid" :
+ (val == ETM_CTX_VMID ? "vmid" : "all")));
+ spin_unlock(&drvdata->spinlock);
+ return len;
+}
+
+static ssize_t addr_ctxtype_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ char str[10] = "";
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (strlen(buf) >= 10)
+ return -EINVAL;
+ if (sscanf(buf, "%s", str) != 1)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+ if (!strcmp(str, "none"))
+ /* start by clearing context type bits */
+ drvdata->addr_acc[idx] &= ~(BIT(2) | BIT(3));
+ else if (!strcmp(str, "ctxid")) {
+ /* 0b01 The trace unit performs a Context ID */
+ if (drvdata->numcidc) {
+ drvdata->addr_acc[idx] |= BIT(2);
+ drvdata->addr_acc[idx] &= ~BIT(3);
+ }
+ } else if (!strcmp(str, "vmid")) {
+ /* 0b10 The trace unit performs a VMID */
+ if (drvdata->numvmidc) {
+ drvdata->addr_acc[idx] &= ~BIT(2);
+ drvdata->addr_acc[idx] |= BIT(3);
+ }
+ } else if (!strcmp(str, "all")) {
+ /*
+ * 0b11 The trace unit performs a Context ID
+ * comparison and a VMID
+ */
+ if (drvdata->numcidc)
+ drvdata->addr_acc[idx] |= BIT(2);
+ if (drvdata->numvmidc)
+ drvdata->addr_acc[idx] |= BIT(3);
+ }
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(addr_ctxtype);
+
+static ssize_t addr_context_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+ /* context ID comparator bits[6:4] */
+ val = BMVAL(drvdata->addr_acc[idx], 4, 6);
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t addr_context_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if ((drvdata->numcidc <= 1) && (drvdata->numvmidc <= 1))
+ return -EINVAL;
+ if (val >= (drvdata->numcidc >= drvdata->numvmidc ?
+ drvdata->numcidc : drvdata->numvmidc))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->addr_idx;
+ /* clear context ID comparator bits[6:4] */
+ drvdata->addr_acc[idx] &= ~(BIT(4) | BIT(5) | BIT(6));
+ drvdata->addr_acc[idx] |= (val << 4);
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(addr_context);
+
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1191,6 +1606,14 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_event_vinst.attr,
&dev_attr_s_exlevel_vinst.attr,
&dev_attr_ns_exlevel_vinst.attr,
+ &dev_attr_addr_idx.attr,
+ &dev_attr_addr_instdatatype.attr,
+ &dev_attr_addr_single.attr,
+ &dev_attr_addr_range.attr,
+ &dev_attr_addr_start.attr,
+ &dev_attr_addr_stop.attr,
+ &dev_attr_addr_ctxtype.attr,
+ &dev_attr_addr_context.attr,
&dev_attr_status.attr,
&dev_attr_mgmt.attr,
&dev_attr_trcidr.attr,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 07/11] coresight-etm4x: Controls pertaining to the sequencer functions
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh
Cc: linux-arm-kernel, linux-api, linux-kernel, kaixu.xia,
zhang.chunyan, mathieu.poirier
In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier@linaro.org>
From: Pratik Patel <pratikp@codeaurora.org>
Adding sysfs entries to access the sequencers related registers,
more specifically the sequencer state, the sequencer state
transition and the sequencer reset control registers.
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 25 ++++
drivers/hwtracing/coresight/coresight-etm4x.c | 129 +++++++++++++++++++++
2 files changed, 154 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
index 8cdc4ad10bd6..44723f2e107e 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -191,3 +191,28 @@ Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Used to setup address range comparator values.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/seq_idx
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Select which sequensor.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/seq_state
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Use this to set, or read, the sequencer state.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/seq_event
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Moves the sequencer state to a specific state.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/seq_reset_event
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Moves the sequencer to state 0 when a programmed event
+ occurs.
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 6671be0036e2..ca89e7ba4b75 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -1442,6 +1442,131 @@ static ssize_t addr_context_store(struct device *dev,
}
static DEVICE_ATTR_RW(addr_context);
+static ssize_t seq_idx_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->seq_idx;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t seq_idx_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (val >= drvdata->nrseqstate - 1)
+ return -EINVAL;
+
+ /*
+ * Use spinlock to ensure index doesn't change while it gets
+ * dereferenced multiple times within a spinlock block elsewhere.
+ */
+ spin_lock(&drvdata->spinlock);
+ drvdata->seq_idx = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(seq_idx);
+
+static ssize_t seq_state_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->seq_state;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t seq_state_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (val >= drvdata->nrseqstate)
+ return -EINVAL;
+
+ drvdata->seq_state = val;
+ return size;
+}
+static DEVICE_ATTR_RW(seq_state);
+
+static ssize_t seq_event_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->seq_idx;
+ val = drvdata->seq_ctrl[idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t seq_event_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->seq_idx;
+ /* RST, bits[7:0] */
+ drvdata->seq_ctrl[idx] = val & 0xFF;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(seq_event);
+
+static ssize_t seq_reset_event_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->seq_rst;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t seq_reset_event_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (!(drvdata->nrseqstate))
+ return -EINVAL;
+
+ drvdata->seq_rst = val & ETMv4_EVENT_MASK;
+ return size;
+}
+static DEVICE_ATTR_RW(seq_reset_event);
+
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1614,6 +1739,10 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_addr_stop.attr,
&dev_attr_addr_ctxtype.attr,
&dev_attr_addr_context.attr,
+ &dev_attr_seq_idx.attr,
+ &dev_attr_seq_state.attr,
+ &dev_attr_seq_event.attr,
+ &dev_attr_seq_reset_event.attr,
&dev_attr_status.attr,
&dev_attr_mgmt.attr,
&dev_attr_trcidr.attr,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 08/11] coresight-etm4x: Controls pertaining to the counter functions
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
kaixu.xia-QSEj5FYQhm4dnm+yROfE0A,
zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A,
mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
From: Pratik Patel <pratikp-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Adding sysfs entries related to the counter functionality, more specifically
to set, control and reload the counters.
Signed-off-by: Pratik Patel <pratikp-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 26 ++++
drivers/hwtracing/coresight/coresight-etm4x.c | 144 +++++++++++++++++++++
2 files changed, 170 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
index 44723f2e107e..b4581c9426d3 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -216,3 +216,29 @@ KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Description: (RW) Moves the sequencer to state 0 when a programmed event
occurs.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/cntr_idx
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (RW) Select which counter unit to work with.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/cntrldvr
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (RW) This sets or returns the reload count value of the
+ specific counter.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/cntr_val
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (RW) This sets or returns the current count value of the
+ specific counter.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/cntr_ctrl
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (RW) Controls the operation of the selected counter.
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index ca89e7ba4b75..7d22a630ec8a 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -1567,6 +1567,146 @@ static ssize_t seq_reset_event_store(struct device *dev,
}
static DEVICE_ATTR_RW(seq_reset_event);
+static ssize_t cntr_idx_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->cntr_idx;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t cntr_idx_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (val >= drvdata->nr_cntr)
+ return -EINVAL;
+
+ /*
+ * Use spinlock to ensure index doesn't change while it gets
+ * dereferenced multiple times within a spinlock block elsewhere.
+ */
+ spin_lock(&drvdata->spinlock);
+ drvdata->cntr_idx = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(cntr_idx);
+
+static ssize_t cntrldvr_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->cntr_idx;
+ val = drvdata->cntrldvr[idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t cntrldvr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (val > ETM_CNTR_MAX_VAL)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->cntr_idx;
+ drvdata->cntrldvr[idx] = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(cntrldvr);
+
+static ssize_t cntr_val_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->cntr_idx;
+ val = drvdata->cntr_val[idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t cntr_val_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (val > ETM_CNTR_MAX_VAL)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->cntr_idx;
+ drvdata->cntr_val[idx] = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(cntr_val);
+
+static ssize_t cntr_ctrl_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->cntr_idx;
+ val = drvdata->cntr_ctrl[idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t cntr_ctrl_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->cntr_idx;
+ drvdata->cntr_ctrl[idx] = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(cntr_ctrl);
+
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1743,6 +1883,10 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_seq_state.attr,
&dev_attr_seq_event.attr,
&dev_attr_seq_reset_event.attr,
+ &dev_attr_cntr_idx.attr,
+ &dev_attr_cntrldvr.attr,
+ &dev_attr_cntr_val.attr,
+ &dev_attr_cntr_ctrl.attr,
&dev_attr_status.attr,
&dev_attr_mgmt.attr,
&dev_attr_trcidr.attr,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 09/11] coresight-etm4x: Controls pertaining to the selection of resources
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh
Cc: linux-arm-kernel, linux-api, linux-kernel, kaixu.xia,
zhang.chunyan, mathieu.poirier
In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier@linaro.org>
From: Pratik Patel <pratikp@codeaurora.org>
Adding sysfs entries to control the selection of the resources the
trace unit will use as triggers to perform a trace run.
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 12 ++++
drivers/hwtracing/coresight/coresight-etm4x.c | 75 ++++++++++++++++++++++
2 files changed, 87 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
index b4581c9426d3..b5c0456290ab 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -242,3 +242,15 @@ Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls the operation of the selected counter.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/res_idx
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Select which resource selection unit to work with.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/res_ctrl
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Controls the selection of the resources in the trace unit.
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 7d22a630ec8a..d578500f937d 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -1707,6 +1707,79 @@ static ssize_t cntr_ctrl_store(struct device *dev,
}
static DEVICE_ATTR_RW(cntr_ctrl);
+static ssize_t res_idx_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->res_idx;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t res_idx_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ /* Resource selector pair 0 is always implemented and reserved */
+ if ((val == 0) || (val >= drvdata->nr_resource))
+ return -EINVAL;
+
+ /*
+ * Use spinlock to ensure index doesn't change while it gets
+ * dereferenced multiple times within a spinlock block elsewhere.
+ */
+ spin_lock(&drvdata->spinlock);
+ drvdata->res_idx = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(res_idx);
+
+static ssize_t res_ctrl_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->res_idx;
+ val = drvdata->res_ctrl[idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t res_ctrl_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->res_idx;
+ /* For odd idx pair inversal bit is RES0 */
+ if (idx % 2 != 0)
+ /* PAIRINV, bit[21] */
+ val &= ~BIT(21);
+ drvdata->res_ctrl[idx] = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(res_ctrl);
+
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1887,6 +1960,8 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_cntrldvr.attr,
&dev_attr_cntr_val.attr,
&dev_attr_cntr_ctrl.attr,
+ &dev_attr_res_idx.attr,
+ &dev_attr_res_ctrl.attr,
&dev_attr_status.attr,
&dev_attr_mgmt.attr,
&dev_attr_trcidr.attr,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 10/11] coresight-etm4x: Controls pertaining to the context ID functions
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh
Cc: linux-arm-kernel, linux-api, linux-kernel, kaixu.xia,
zhang.chunyan, mathieu.poirier
In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier@linaro.org>
From: Pratik Patel <pratikp@codeaurora.org>
Adding sysfs entries to access and configure specifics about the
context ID comparator functions.
Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 19 +++
drivers/hwtracing/coresight/coresight-etm4x.c | 187 +++++++++++++++++++++
2 files changed, 206 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
index b5c0456290ab..8b32cb7b9723 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -254,3 +254,22 @@ Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Controls the selection of the resources in the trace unit.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/ctxid_idx
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Select which context ID comparator to work with.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/ctxid_val
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Get/Set the context ID comparator value to trigger on.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/ctxid_masks
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
+Description: (RW) Mask for all 8 context ID comparator value
+ registers (if implemented).
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index d578500f937d..da1b3cdb0413 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -1780,6 +1780,190 @@ static ssize_t res_ctrl_store(struct device *dev,
}
static DEVICE_ATTR_RW(res_ctrl);
+static ssize_t ctxid_idx_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->ctxid_idx;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t ctxid_idx_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (val >= drvdata->numcidc)
+ return -EINVAL;
+
+ /*
+ * Use spinlock to ensure index doesn't change while it gets
+ * dereferenced multiple times within a spinlock block elsewhere.
+ */
+ spin_lock(&drvdata->spinlock);
+ drvdata->ctxid_idx = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(ctxid_idx);
+
+static ssize_t ctxid_val_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->ctxid_idx;
+ val = (unsigned long)drvdata->ctxid_val[idx];
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t ctxid_val_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 idx;
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ /*
+ * only implemented when ctxid tracing is enabled, i.e. at least one
+ * ctxid comparator is implemented and ctxid is greater than 0 bits
+ * in length
+ */
+ if (!drvdata->ctxid_size || !drvdata->numcidc)
+ return -EINVAL;
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ idx = drvdata->ctxid_idx;
+ drvdata->ctxid_val[idx] = (u64)val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(ctxid_val);
+
+static ssize_t ctxid_masks_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val1, val2;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ val1 = drvdata->ctxid_mask0;
+ val2 = drvdata->ctxid_mask1;
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
+}
+
+static ssize_t ctxid_masks_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 i, j, maskbyte;
+ unsigned long val1, val2, mask;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ /*
+ * only implemented when ctxid tracing is enabled, i.e. at least one
+ * ctxid comparator is implemented and ctxid is greater than 0 bits
+ * in length
+ */
+ if (!drvdata->ctxid_size || !drvdata->numcidc)
+ return -EINVAL;
+ if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ /*
+ * each byte[0..3] controls mask value applied to ctxid
+ * comparator[0..3]
+ */
+ switch (drvdata->numcidc) {
+ case 0x1:
+ /* COMP0, bits[7:0] */
+ drvdata->ctxid_mask0 = val1 & 0xFF;
+ break;
+ case 0x2:
+ /* COMP1, bits[15:8] */
+ drvdata->ctxid_mask0 = val1 & 0xFFFF;
+ break;
+ case 0x3:
+ /* COMP2, bits[23:16] */
+ drvdata->ctxid_mask0 = val1 & 0xFFFFFF;
+ break;
+ case 0x4:
+ /* COMP3, bits[31:24] */
+ drvdata->ctxid_mask0 = val1;
+ break;
+ case 0x5:
+ /* COMP4, bits[7:0] */
+ drvdata->ctxid_mask0 = val1;
+ drvdata->ctxid_mask1 = val2 & 0xFF;
+ break;
+ case 0x6:
+ /* COMP5, bits[15:8] */
+ drvdata->ctxid_mask0 = val1;
+ drvdata->ctxid_mask1 = val2 & 0xFFFF;
+ break;
+ case 0x7:
+ /* COMP6, bits[23:16] */
+ drvdata->ctxid_mask0 = val1;
+ drvdata->ctxid_mask1 = val2 & 0xFFFFFF;
+ break;
+ case 0x8:
+ /* COMP7, bits[31:24] */
+ drvdata->ctxid_mask0 = val1;
+ drvdata->ctxid_mask1 = val2;
+ break;
+ default:
+ break;
+ }
+ /*
+ * If software sets a mask bit to 1, it must program relevant byte
+ * of ctxid comparator value 0x0, otherwise behavior is unpredictable.
+ * For example, if bit[3] of ctxid_mask0 is 1, we must clear bits[31:24]
+ * of ctxid comparator0 value (corresponding to byte 0) register.
+ */
+ mask = drvdata->ctxid_mask0;
+ for (i = 0; i < drvdata->numcidc; i++) {
+ /* mask value of corresponding ctxid comparator */
+ maskbyte = mask & ETMv4_EVENT_MASK;
+ /*
+ * each bit corresponds to a byte of respective ctxid comparator
+ * value register
+ */
+ for (j = 0; j < 8; j++) {
+ if (maskbyte & 1)
+ drvdata->ctxid_val[i] &= ~(0xFF << (j * 8));
+ maskbyte >>= 1;
+ }
+ /* Select the next ctxid comparator mask value */
+ if (i == 3)
+ /* ctxid comparators[4-7] */
+ mask = drvdata->ctxid_mask1;
+ else
+ mask >>= 0x8;
+ }
+
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(ctxid_masks);
+
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1962,6 +2146,9 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_cntr_ctrl.attr,
&dev_attr_res_idx.attr,
&dev_attr_res_ctrl.attr,
+ &dev_attr_ctxid_idx.attr,
+ &dev_attr_ctxid_val.attr,
+ &dev_attr_ctxid_masks.attr,
&dev_attr_status.attr,
&dev_attr_mgmt.attr,
&dev_attr_trcidr.attr,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 11/11] coresight-etm4x: Controls pertaining to the VM ID functions
From: Mathieu Poirier @ 2015-05-06 15:27 UTC (permalink / raw)
To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
kaixu.xia-QSEj5FYQhm4dnm+yROfE0A,
zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A,
mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
From: Pratik Patel <pratikp-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Adding sysfs entries to access and configure specifics about the
virtual machine ID comparator functions.
Signed-off-by: Pratik Patel <pratikp-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
.../ABI/testing/sysfs-bus-coresight-devices-etm4x | 20 +++
drivers/hwtracing/coresight/coresight-etm4x.c | 178 +++++++++++++++++++++
2 files changed, 198 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
index 8b32cb7b9723..eb5153891919 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
@@ -273,3 +273,23 @@ KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Description: (RW) Mask for all 8 context ID comparator value
registers (if implemented).
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/vmid_idx
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (RW) Select which virtual machine ID comparator to work with.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/vmid_val
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (RW) Get/Set the virtual machine ID comparator value to
+ trigger on.
+
+What: /sys/bus/coresight/devices/<memory_map>.etm/vmid_masks
+Date: April 2015
+KernelVersion: 4.01
+Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+Description: (RW) Mask for all 8 virtual machine ID comparator value
+ registers (if implemented).
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index da1b3cdb0413..15bf5be5004a 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -1964,6 +1964,181 @@ static ssize_t ctxid_masks_store(struct device *dev,
}
static DEVICE_ATTR_RW(ctxid_masks);
+static ssize_t vmid_idx_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = drvdata->vmid_idx;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t vmid_idx_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+ if (val >= drvdata->numvmidc)
+ return -EINVAL;
+
+ /*
+ * Use spinlock to ensure index doesn't change while it gets
+ * dereferenced multiple times within a spinlock block elsewhere.
+ */
+ spin_lock(&drvdata->spinlock);
+ drvdata->vmid_idx = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(vmid_idx);
+
+static ssize_t vmid_val_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ val = (unsigned long)drvdata->vmid_val[drvdata->vmid_idx];
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t vmid_val_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ /*
+ * only implemented when vmid tracing is enabled, i.e. at least one
+ * vmid comparator is implemented and at least 8 bit vmid size
+ */
+ if (!drvdata->vmid_size || !drvdata->numvmidc)
+ return -EINVAL;
+ if (kstrtoul(buf, 16, &val))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ drvdata->vmid_val[drvdata->vmid_idx] = (u64)val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(vmid_val);
+
+static ssize_t vmid_masks_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val1, val2;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ spin_lock(&drvdata->spinlock);
+ val1 = drvdata->vmid_mask0;
+ val2 = drvdata->vmid_mask1;
+ spin_unlock(&drvdata->spinlock);
+ return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
+}
+
+static ssize_t vmid_masks_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u8 i, j, maskbyte;
+ unsigned long val1, val2, mask;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ /*
+ * only implemented when vmid tracing is enabled, i.e. at least one
+ * vmid comparator is implemented and at least 8 bit vmid size
+ */
+ if (!drvdata->vmid_size || !drvdata->numvmidc)
+ return -EINVAL;
+ if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+
+ /*
+ * each byte[0..3] controls mask value applied to vmid
+ * comparator[0..3]
+ */
+ switch (drvdata->numvmidc) {
+ case 0x1:
+ /* COMP0, bits[7:0] */
+ drvdata->vmid_mask0 = val1 & 0xFF;
+ break;
+ case 0x2:
+ /* COMP1, bits[15:8] */
+ drvdata->vmid_mask0 = val1 & 0xFFFF;
+ break;
+ case 0x3:
+ /* COMP2, bits[23:16] */
+ drvdata->vmid_mask0 = val1 & 0xFFFFFF;
+ break;
+ case 0x4:
+ /* COMP3, bits[31:24] */
+ drvdata->vmid_mask0 = val1;
+ break;
+ case 0x5:
+ /* COMP4, bits[7:0] */
+ drvdata->vmid_mask0 = val1;
+ drvdata->vmid_mask1 = val2 & 0xFF;
+ break;
+ case 0x6:
+ /* COMP5, bits[15:8] */
+ drvdata->vmid_mask0 = val1;
+ drvdata->vmid_mask1 = val2 & 0xFFFF;
+ break;
+ case 0x7:
+ /* COMP6, bits[23:16] */
+ drvdata->vmid_mask0 = val1;
+ drvdata->vmid_mask1 = val2 & 0xFFFFFF;
+ break;
+ case 0x8:
+ /* COMP7, bits[31:24] */
+ drvdata->vmid_mask0 = val1;
+ drvdata->vmid_mask1 = val2;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * If software sets a mask bit to 1, it must program relevant byte
+ * of vmid comparator value 0x0, otherwise behavior is unpredictable.
+ * For example, if bit[3] of vmid_mask0 is 1, we must clear bits[31:24]
+ * of vmid comparator0 value (corresponding to byte 0) register.
+ */
+ mask = drvdata->vmid_mask0;
+ for (i = 0; i < drvdata->numvmidc; i++) {
+ /* mask value of corresponding vmid comparator */
+ maskbyte = mask & ETMv4_EVENT_MASK;
+ /*
+ * each bit corresponds to a byte of respective vmid comparator
+ * value register
+ */
+ for (j = 0; j < 8; j++) {
+ if (maskbyte & 1)
+ drvdata->vmid_val[i] &= ~(0xFF << (j * 8));
+ maskbyte >>= 1;
+ }
+ /* Select the next vmid comparator mask value */
+ if (i == 3)
+ /* vmid comparators[4-7] */
+ mask = drvdata->vmid_mask1;
+ else
+ mask >>= 0x8;
+ }
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(vmid_masks);
+
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -2149,6 +2324,9 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_ctxid_idx.attr,
&dev_attr_ctxid_val.attr,
&dev_attr_ctxid_masks.attr,
+ &dev_attr_vmid_idx.attr,
+ &dev_attr_vmid_val.attr,
+ &dev_attr_vmid_masks.attr,
&dev_attr_status.attr,
&dev_attr_mgmt.attr,
&dev_attr_trcidr.attr,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 01/12] KVM: add comments for kvm_debug_exit_arch struct
From: Alex Bennée @ 2015-05-06 16:23 UTC (permalink / raw)
To: kvm, linux-arm-kernel, kvmarm, christoffer.dall, marc.zyngier,
peter.maydell, agraf, drjones, pbonzini, zhichao.huang
Cc: Jonathan Corbet, Gleb Natapov, jan.kiszka,
open list:DOCUMENTATION, open list, open list:ABI/API, dahi,
r65777, bp
In-Reply-To: <1430929407-3487-1-git-send-email-alex.bennee@linaro.org>
Bring into line with the comments for the other structures and their
KVM_EXIT_* cases. Also update api.txt to reflect use in kvm_run
documentation.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
---
v2
- add comments for other exit types
v3
- s/commentary/comments/
- add rb tags
- update api.txt kvm_run to include KVM_EXIT_DEBUG desc
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 9fa2bf8..cb90025 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3070,11 +3070,13 @@ data_offset describes where the data is located (KVM_EXIT_IO_OUT) or
where kvm expects application code to place the data for the next
KVM_RUN invocation (KVM_EXIT_IO_IN). Data format is a packed array.
+ /* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
-Unused.
+If the exit_reason in KVM_EXIT_DEBUG, then a vcpu is processing a debug event
+for which architecture dependant information is returned.
/* KVM_EXIT_MMIO */
struct {
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 4b60056..70ac641 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -237,6 +237,7 @@ struct kvm_run {
__u32 count;
__u64 data_offset; /* relative to kvm_run start */
} io;
+ /* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
@@ -285,6 +286,7 @@ struct kvm_run {
__u32 data;
__u8 is_write;
} dcr;
+ /* KVM_EXIT_INTERNAL_ERROR */
struct {
__u32 suberror;
/* Available with KVM_CAP_INTERNAL_ERROR_DATA: */
@@ -295,6 +297,7 @@ struct kvm_run {
struct {
__u64 gprs[32];
} osi;
+ /* KVM_EXIT_PAPR_HCALL */
struct {
__u64 nr;
__u64 ret;
--
2.3.5
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
^ permalink raw reply related
* [PATCH v3 02/12] KVM: define common __KVM_GUESTDBG_USE_SW/HW_BP values
From: Alex Bennée @ 2015-05-06 16:23 UTC (permalink / raw)
To: kvm, linux-arm-kernel, kvmarm, christoffer.dall, marc.zyngier,
peter.maydell, agraf, drjones, pbonzini, zhichao.huang
Cc: maintainer:X86 ARCHITECTURE..., Benjamin Herrenschmidt,
Alexey Kardashevskiy, Nadav Amit, Gleb Natapov, jan.kiszka,
H. Peter Anvin, open list:LINUX FOR POWERPC..., open list:ABI/API,
open list, dahi, Ingo Molnar, Paul Mackerras, Michael Ellerman,
r65777, Thomas Gleixner, bp
In-Reply-To: <1430929407-3487-1-git-send-email-alex.bennee@linaro.org>
Currently x86, powerpc and soon arm64 use the same two architecture
specific bits for guest debug support for software and hardware
breakpoints. This makes the shared values explicit while leaving the
gate open for another architecture to use some other value if they
really really want to.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Andrew Jones <drjones@redhat.com>
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index ab4d473..1731569 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -310,8 +310,8 @@ struct kvm_guest_debug_arch {
* and upper 16 bits are architecture specific. Architecture specific defines
* that ioctl is for setting hardware breakpoint or software breakpoint.
*/
-#define KVM_GUESTDBG_USE_SW_BP 0x00010000
-#define KVM_GUESTDBG_USE_HW_BP 0x00020000
+#define KVM_GUESTDBG_USE_SW_BP __KVM_GUESTDBG_USE_SW_BP
+#define KVM_GUESTDBG_USE_HW_BP __KVM_GUESTDBG_USE_HW_BP
/* definition of registers in kvm_run */
struct kvm_sync_regs {
diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index d7dcef5..1438202 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -250,8 +250,8 @@ struct kvm_debug_exit_arch {
__u64 dr7;
};
-#define KVM_GUESTDBG_USE_SW_BP 0x00010000
-#define KVM_GUESTDBG_USE_HW_BP 0x00020000
+#define KVM_GUESTDBG_USE_SW_BP __KVM_GUESTDBG_USE_SW_BP
+#define KVM_GUESTDBG_USE_HW_BP __KVM_GUESTDBG_USE_HW_BP
#define KVM_GUESTDBG_INJECT_DB 0x00040000
#define KVM_GUESTDBG_INJECT_BP 0x00080000
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 70ac641..3b6252e 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -570,8 +570,16 @@ struct kvm_s390_irq_state {
/* for KVM_SET_GUEST_DEBUG */
-#define KVM_GUESTDBG_ENABLE 0x00000001
-#define KVM_GUESTDBG_SINGLESTEP 0x00000002
+#define KVM_GUESTDBG_ENABLE (1 << 0)
+#define KVM_GUESTDBG_SINGLESTEP (1 << 1)
+
+/*
+ * Architecture specific stuff uses the top 16 bits of the field,
+ * however there is some shared commonality for the common cases
+ */
+#define __KVM_GUESTDBG_USE_SW_BP (1 << 16)
+#define __KVM_GUESTDBG_USE_HW_BP (1 << 17)
+
struct kvm_guest_debug {
__u32 control;
--
2.3.5
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
^ permalink raw reply related
* [PATCH 00/19] converting system calls to 64-bit time_t, part 1
From: Arnd Bergmann @ 2015-05-06 16:30 UTC (permalink / raw)
To: y2038-cunTk1MwBs8s++Sfvej+rw
Cc: baolin.wang-QSEj5FYQhm4dnm+yROfE0A, tglx-hfZtesqFncYOwBW4kG4KsQ,
albert.aribaud-iEu9NFBzPZE, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
bamvor.zhangjian-QSEj5FYQhm4dnm+yROfE0A,
ruchandani.tina-Re5JQEeQqe8AvxtiuMwx3w,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
libc-alpha-9JcytcrH/bA+uJoB2kUjGw, Arnd Bergmann
This is my second draft of how we could modify the system call interface
in Linux to support user space with 64-bit time_t in addition to the
existing 32-bit time_t based interfaces. In order to avoid spamming people
too much, I've picked the first half of the patches only now, and left
some of the more complex ones for later.
If you are interested in the big picture, see
http://git.kernel.org/cgit/linux/kernel/git/arnd/playground.git/log/?h=y2038-syscalls
with currently 42 patches. That number may go up a bit over time, but
only because I plan to split some of the patches into smaller chunks
for review purposes, as opposed to adding more system calls.
As part 1 of the series only switches over half the system calls,
I've left out the bits that changes the ARM and x86 architectures.
There are 24 additional architectures that need to moved over to
the new system calls once the basic patches get merged.
The main part I'm not sure about is how the header files should be
structured in order to make it easy for every libc implementation
to pick out the right definitions of the data structures I had to
modify. Hopefully, people on libc-alpha can help me out here.
The overall approach I have taken here is as follows:
* Since 64-bit architectures already support two versions of each system
call that passes a time value in order to run 32-bit user space,
I'm not adding new system calls for the most part, but instead make
32-bit architectures use the same compat handlers that 64-bit
architectures already use.
* The existing syscall numbers are modified to point to the compat_sys_*
functions, and new numbers are assigned to point to the existing handlers
that now deal with 64-bit time_t based structures
* This series does not touch any ioctl implementation, but should be
otherwise complete regarding the system calls. We are still trying
to find out exactly which ioctls are affected and have not come
up with a complete list at this point. It's probably a good idea
though to do at least the essential ioctls before merging the series,
so we can have a better understanding of how it will be done in the
end.
* Each data structure we need to modify gets a new definition with a
__kernel_ prefix, e.g. struct __kernel_timespec to replace struct
timespec. This keeps the new structures out of the user libc
namespace, but still allows the structure to be integrated into
other data structures, e.g. for ioctl.
* There is no #ifdef in the UAPI headers at this point that would
check for the kind of user space that is in use. Unfortunately,
I believe we will need to add that in order to do some of the
particularly tricky ioctls later.
* At first, all system call implementations are modified, but this
is done in a way that is not supposed to have any ABI-visible
effect on existing architectures.
* After all system calls are converted, we can change one architecture
at a time to select ARCH_HAS_COMPAT_TIME, and modify its system
call table accordingly. In this version, I do it for ARM32, x86-32,
and x86-64 for demonstration purposes.
* A follow-up series changes over all other architectures.
* The last patch in the series changes the CONFIG_COMPAT_TIME
Kconfig symbol to be user visible. Disabling this symbol will
get you a kernel that intentionally breaks support for old tasks
in order to provide an interface that will survive 2038.
This is meant mostly as a debugging help for now, to let people
build a y2038 safe distro, but at some point in the 2030s, we
should remove that option and all the compat handling.
Arnd Bergmann (19):
compat: remove compat_printk
initramfs: use vfs_stat/lstat directly
y2038: introduce linux/compat_time.h header
y2038: introduce CONFIG_COMPAT_TIME
y2038: make linux/compat_time.h usable on 32-bit
y2038: compile compat time code even when CONFIG_COMPAT is not set
y2038: add compat_sys_rt_sigtimedwait variants
y2038: introduce struct __kernel_timespec
y2038: introduce struct __kernel_stat
y2038: use __kernel_stat for sys_newstat syscalls
y2038: introduce and use struct __kernel_rusage
y2038: add compat_{get,put}_timespec64
y2038: add compat handling for sys_semtimedop
y2038: use __kernel_timespec for sys_mq_timed{send,receive}
y2038: introduce timespec64_to_jiffies
y2038: use __kernel_timespec in sys_rt_sigtimedwait
y2038: use __kernel_timespec in sys_futex
y2038: introduce jiffies_to_timespec64
y2038: use __kernel_timespec in sys_sched_rr_get_interval
arch/Kconfig | 11 ++
arch/alpha/include/uapi/asm/stat.h | 4 +
arch/alpha/kernel/osf_sys.c | 4 +-
arch/arm/include/uapi/asm/stat.h | 2 +
arch/arm64/include/asm/compat.h | 11 --
arch/avr32/include/uapi/asm/stat.h | 2 +
arch/blackfin/include/uapi/asm/stat.h | 2 +
arch/cris/include/uapi/asm/stat.h | 2 +
arch/frv/include/uapi/asm/stat.h | 2 +
arch/ia64/include/uapi/asm/stat.h | 4 +
arch/m32r/include/uapi/asm/stat.h | 1 +
arch/m68k/include/uapi/asm/stat.h | 2 +
arch/mips/include/asm/compat.h | 11 --
arch/mips/include/uapi/asm/stat.h | 1 +
arch/mn10300/include/uapi/asm/stat.h | 2 +
arch/parisc/include/asm/compat.h | 11 --
arch/parisc/include/uapi/asm/stat.h | 1 +
arch/powerpc/include/asm/compat.h | 11 --
arch/powerpc/include/uapi/asm/stat.h | 25 +++
arch/s390/include/asm/compat.h | 11 --
arch/s390/include/uapi/asm/stat.h | 24 +++
arch/sh/include/uapi/asm/stat.h | 2 +
arch/sparc/include/asm/compat.h | 11 --
arch/sparc/include/uapi/asm/stat.h | 28 ++++
arch/tile/include/asm/compat.h | 11 --
arch/x86/include/asm/compat.h | 12 +-
arch/x86/include/asm/ftrace.h | 2 +-
arch/x86/include/asm/sys_ia32.h | 2 +-
arch/x86/include/uapi/asm/stat.h | 49 ++++--
arch/x86/kernel/cpu/perf_event.c | 2 +-
arch/xtensa/include/uapi/asm/stat.h | 2 +
fs/Makefile | 1 +
fs/compat.c | 26 ++-
fs/stat.c | 12 +-
include/linux/audit.h | 4 +-
include/linux/compat.h | 232 +--------------------------
include/linux/compat_time.h | 285 +++++++++++++++++++++++++++++++++
include/linux/jiffies.h | 23 ++-
include/linux/resource.h | 8 +-
include/linux/signal.h | 3 +-
include/linux/stat.h | 3 +
include/linux/syscalls.h | 32 ++--
include/linux/thread_info.h | 2 +-
include/linux/time64.h | 17 +-
include/uapi/asm-generic/kernel_stat.h | 36 +++++
include/uapi/asm-generic/stat.h | 12 +-
include/uapi/linux/resource.h | 32 ++++
include/uapi/linux/time.h | 17 ++
init/do_mounts.h | 22 +--
init/initramfs.c | 12 +-
ipc/compat.c | 10 --
ipc/mqueue.c | 16 +-
ipc/sem.c | 60 +++++--
ipc/syscall.c | 7 +
kernel/Makefile | 1 +
kernel/audit.h | 2 +-
kernel/auditsc.c | 14 +-
kernel/compat.c | 184 ++++++++++++++++++---
kernel/exit.c | 6 +-
kernel/futex.c | 10 +-
kernel/sched/core.c | 35 +++-
kernel/signal.c | 13 +-
kernel/sys.c | 23 +--
kernel/sysctl.c | 10 --
kernel/time/time.c | 45 ++++--
65 files changed, 950 insertions(+), 530 deletions(-)
create mode 100644 include/linux/compat_time.h
create mode 100644 include/uapi/asm-generic/kernel_stat.h
--
2.1.0.rc2
^ permalink raw reply
* [PATCH 01/19] compat: remove compat_printk
From: Arnd Bergmann @ 2015-05-06 16:30 UTC (permalink / raw)
To: y2038
Cc: baolin.wang, tglx, albert.aribaud, john.stultz, bamvor.zhangjian,
ruchandani.tina, linux-api, linux-kernel, libc-alpha,
Arnd Bergmann
In-Reply-To: <1430929826-318934-1-git-send-email-arnd@arndb.de>
After 7e8e385aaf6e ("x86/compat: Remove sys32_vm86_warning"), this
function has become unused, so we can remove it as well.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
fs/compat.c | 14 --------------
include/linux/compat.h | 1 -
kernel/sysctl.c | 10 ----------
3 files changed, 25 deletions(-)
diff --git a/fs/compat.c b/fs/compat.c
index 6fd272d455e4..7d78cde20fc3 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -54,20 +54,6 @@
#include <asm/ioctls.h>
#include "internal.h"
-int compat_log = 1;
-
-int compat_printk(const char *fmt, ...)
-{
- va_list ap;
- int ret;
- if (!compat_log)
- return 0;
- va_start(ap, fmt);
- ret = vprintk(fmt, ap);
- va_end(ap);
- return ret;
-}
-
/*
* Not all architectures have sys_utime, so implement this in terms
* of sys_utimes.
diff --git a/include/linux/compat.h b/include/linux/compat.h
index ab25814690bc..d533d06146a8 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -424,7 +424,6 @@ asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
-extern int compat_printk(const char *fmt, ...);
extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat);
extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 2082b1a88fb9..4020ade0ce4d 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -105,7 +105,6 @@ extern unsigned int core_pipe_limit;
extern int pid_max;
extern int pid_max_min, pid_max_max;
extern int percpu_pagelist_fraction;
-extern int compat_log;
extern int latencytop_enabled;
extern int sysctl_nr_open_min, sysctl_nr_open_max;
#ifndef CONFIG_MMU
@@ -1043,15 +1042,6 @@ static struct ctl_table kern_table[] = {
.extra1 = &neg_one,
},
#endif
-#ifdef CONFIG_COMPAT
- {
- .procname = "compat-log",
- .data = &compat_log,
- .maxlen = sizeof (int),
- .mode = 0644,
- .proc_handler = proc_dointvec,
- },
-#endif
#ifdef CONFIG_RT_MUTEXES
{
.procname = "max_lock_depth",
--
2.1.0.rc2
^ permalink raw reply related
* [PATCH 02/19] initramfs: use vfs_stat/lstat directly
From: Arnd Bergmann @ 2015-05-06 16:30 UTC (permalink / raw)
To: y2038
Cc: libc-alpha, Arnd Bergmann, baolin.wang, linux-api,
ruchandani.tina, linux-kernel, albert.aribaud, john.stultz, tglx,
bamvor.zhangjian
In-Reply-To: <1430929826-318934-1-git-send-email-arnd@arndb.de>
sys_newlstat is a system call implementation that is meant for user
space, and that copies kernel-internal data structure to the user
format, which is not needed for in-kernel users.
Further, as we rearrange the system call implementation so we can
extend it with 64-bit time_t, the prototype for sys_newlstat changes.
This changes the initramfs code to use vfs_lstat directly, to get
it out of the way of the time_t changes, and make it slightly more
efficient in the process. Along the same lines we also replace
sys_stat and sys_stat64 with vfs_stat.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
init/do_mounts.h | 22 ++++------------------
init/initramfs.c | 12 ++++++------
2 files changed, 10 insertions(+), 24 deletions(-)
diff --git a/init/do_mounts.h b/init/do_mounts.h
index f5b978a9bb92..74e75bb20fe3 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -19,29 +19,15 @@ static inline int create_dev(char *name, dev_t dev)
return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
}
-#if BITS_PER_LONG == 32
static inline u32 bstat(char *name)
{
- struct stat64 stat;
- if (sys_stat64(name, &stat) != 0)
+ struct kstat stat;
+ if (vfs_stat(name, &stat) != 0)
return 0;
- if (!S_ISBLK(stat.st_mode))
+ if (!S_ISBLK(stat.mode))
return 0;
- if (stat.st_rdev != (u32)stat.st_rdev)
- return 0;
- return stat.st_rdev;
-}
-#else
-static inline u32 bstat(char *name)
-{
- struct stat stat;
- if (sys_newstat(name, &stat) != 0)
- return 0;
- if (!S_ISBLK(stat.st_mode))
- return 0;
- return stat.st_rdev;
+ return stat.rdev;
}
-#endif
#ifdef CONFIG_BLK_DEV_RAM
diff --git a/init/initramfs.c b/init/initramfs.c
index ad1bd7787bbb..10c808e97023 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -311,10 +311,10 @@ static int __init maybe_link(void)
static void __init clean_path(char *path, umode_t fmode)
{
- struct stat st;
+ struct kstat st;
- if (!sys_newlstat(path, &st) && (st.st_mode ^ fmode) & S_IFMT) {
- if (S_ISDIR(st.st_mode))
+ if (!vfs_lstat(path, &st) && (st.mode ^ fmode) & S_IFMT) {
+ if (S_ISDIR(st.mode))
sys_rmdir(path);
else
sys_unlink(path);
@@ -580,13 +580,13 @@ static void __init clean_rootfs(void)
num = sys_getdents64(fd, dirp, BUF_SIZE);
while (num > 0) {
while (num > 0) {
- struct stat st;
+ struct kstat st;
int ret;
- ret = sys_newlstat(dirp->d_name, &st);
+ ret = vfs_lstat(dirp->d_name, &st);
WARN_ON_ONCE(ret);
if (!ret) {
- if (S_ISDIR(st.st_mode))
+ if (S_ISDIR(st.mode))
sys_rmdir(dirp->d_name);
else
sys_unlink(dirp->d_name);
--
2.1.0.rc2
_______________________________________________
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038
^ permalink raw reply related
* [PATCH 03/19] y2038: introduce linux/compat_time.h header
From: Arnd Bergmann @ 2015-05-06 16:30 UTC (permalink / raw)
To: y2038
Cc: baolin.wang, tglx, albert.aribaud, john.stultz, bamvor.zhangjian,
ruchandani.tina, linux-api, linux-kernel, libc-alpha,
Arnd Bergmann
In-Reply-To: <1430929826-318934-1-git-send-email-arnd@arndb.de>
We want to reuse all the compat syscall handling for native syscalls
on 32-bit architectures when dealing with 32-bit time_t types.
This moves all time-related system call declarations from
include/linux/compat.h to include/linux/compat_time.h, along
with the associated data structures and typedefs.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm64/include/asm/compat.h | 11 --
arch/mips/include/asm/compat.h | 11 --
arch/parisc/include/asm/compat.h | 11 --
arch/powerpc/include/asm/compat.h | 11 --
arch/s390/include/asm/compat.h | 11 --
arch/sparc/include/asm/compat.h | 11 --
arch/tile/include/asm/compat.h | 11 --
arch/x86/include/asm/compat.h | 12 +-
arch/x86/include/asm/ftrace.h | 2 +-
arch/x86/include/asm/sys_ia32.h | 2 +-
arch/x86/kernel/cpu/perf_event.c | 2 +-
include/linux/compat.h | 225 +--------------------------------
include/linux/compat_time.h | 255 ++++++++++++++++++++++++++++++++++++++
13 files changed, 262 insertions(+), 313 deletions(-)
create mode 100644 include/linux/compat_time.h
diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 7fbed6919b54..4d0786a73a93 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -34,7 +34,6 @@
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
-typedef s32 compat_time_t;
typedef s32 compat_clock_t;
typedef s32 compat_pid_t;
typedef u16 __compat_uid_t;
@@ -66,16 +65,6 @@ typedef u32 compat_ulong_t;
typedef u64 compat_u64;
typedef u32 compat_uptr_t;
-struct compat_timespec {
- compat_time_t tv_sec;
- s32 tv_nsec;
-};
-
-struct compat_timeval {
- compat_time_t tv_sec;
- s32 tv_usec;
-};
-
struct compat_stat {
#ifdef __AARCH64EB__
short st_dev;
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index c4bd54a7f5ce..6495b37a6fbc 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -13,7 +13,6 @@
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
-typedef s32 compat_time_t;
typedef s32 compat_clock_t;
typedef s32 compat_suseconds_t;
@@ -45,16 +44,6 @@ typedef u32 compat_ulong_t;
typedef u64 compat_u64;
typedef u32 compat_uptr_t;
-struct compat_timespec {
- compat_time_t tv_sec;
- s32 tv_nsec;
-};
-
-struct compat_timeval {
- compat_time_t tv_sec;
- s32 tv_usec;
-};
-
struct compat_stat {
compat_dev_t st_dev;
s32 st_pad1[3];
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index 94710cfc1ce8..cc20c7b203f4 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -12,7 +12,6 @@
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
-typedef s32 compat_time_t;
typedef s32 compat_clock_t;
typedef s32 compat_pid_t;
typedef u32 __compat_uid_t;
@@ -39,16 +38,6 @@ typedef u32 compat_ulong_t;
typedef u64 compat_u64;
typedef u32 compat_uptr_t;
-struct compat_timespec {
- compat_time_t tv_sec;
- s32 tv_nsec;
-};
-
-struct compat_timeval {
- compat_time_t tv_sec;
- s32 tv_usec;
-};
-
struct compat_stat {
compat_dev_t st_dev; /* dev_t is 32 bits on parisc */
compat_ino_t st_ino; /* 32 bits */
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index b142b8e0ed9e..4f8901448eba 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -16,7 +16,6 @@
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
-typedef s32 compat_time_t;
typedef s32 compat_clock_t;
typedef s32 compat_pid_t;
typedef u32 __compat_uid_t;
@@ -44,16 +43,6 @@ typedef u32 compat_ulong_t;
typedef u64 compat_u64;
typedef u32 compat_uptr_t;
-struct compat_timespec {
- compat_time_t tv_sec;
- s32 tv_nsec;
-};
-
-struct compat_timeval {
- compat_time_t tv_sec;
- s32 tv_usec;
-};
-
struct compat_stat {
compat_dev_t st_dev;
compat_ino_t st_ino;
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index d350ed9d0fbb..91398bb0695c 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -50,7 +50,6 @@
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
-typedef s32 compat_time_t;
typedef s32 compat_clock_t;
typedef s32 compat_pid_t;
typedef u16 __compat_uid_t;
@@ -94,16 +93,6 @@ typedef struct {
u32 gprs_high[NUM_GPRS];
} s390_compat_regs_high;
-struct compat_timespec {
- compat_time_t tv_sec;
- s32 tv_nsec;
-};
-
-struct compat_timeval {
- compat_time_t tv_sec;
- s32 tv_usec;
-};
-
struct compat_stat {
compat_dev_t st_dev;
u16 __pad1;
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index 830502fe62b4..c7e71a6d7232 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -10,7 +10,6 @@
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
-typedef s32 compat_time_t;
typedef s32 compat_clock_t;
typedef s32 compat_pid_t;
typedef u16 __compat_uid_t;
@@ -38,16 +37,6 @@ typedef u32 compat_ulong_t;
typedef u64 compat_u64;
typedef u32 compat_uptr_t;
-struct compat_timespec {
- compat_time_t tv_sec;
- s32 tv_nsec;
-};
-
-struct compat_timeval {
- compat_time_t tv_sec;
- s32 tv_usec;
-};
-
struct compat_stat {
compat_dev_t st_dev;
compat_ino_t st_ino;
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h
index c14e36f008c8..c3a326c9ae75 100644
--- a/arch/tile/include/asm/compat.h
+++ b/arch/tile/include/asm/compat.h
@@ -29,7 +29,6 @@ typedef u32 compat_ulong_t;
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
typedef s32 compat_off_t;
-typedef s32 compat_time_t;
typedef s32 compat_clock_t;
typedef u32 compat_ino_t;
typedef u32 compat_caddr_t;
@@ -59,16 +58,6 @@ typedef unsigned long compat_elf_greg_t;
#define COMPAT_ELF_NGREG (sizeof(struct pt_regs) / sizeof(compat_elf_greg_t))
typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
-struct compat_timespec {
- compat_time_t tv_sec;
- s32 tv_nsec;
-};
-
-struct compat_timeval {
- compat_time_t tv_sec;
- s32 tv_usec;
-};
-
#define compat_stat stat
#define compat_statfs statfs
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index acdee09228b3..b8ce4e15b511 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -15,7 +15,6 @@
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;
-typedef s32 compat_time_t;
typedef s32 compat_clock_t;
typedef s32 compat_pid_t;
typedef u16 __compat_uid_t;
@@ -43,16 +42,6 @@ typedef u32 compat_ulong_t;
typedef u64 __attribute__((aligned(4))) compat_u64;
typedef u32 compat_uptr_t;
-struct compat_timespec {
- compat_time_t tv_sec;
- s32 tv_nsec;
-};
-
-struct compat_timeval {
- compat_time_t tv_sec;
- s32 tv_usec;
-};
-
struct compat_stat {
compat_dev_t st_dev;
u16 __pad1;
@@ -270,6 +259,7 @@ typedef struct user_regs_struct compat_elf_gregset_t;
do { *(int *) (((void *) &((S)->pr_reg)) + PR_REG_SIZE(0)) = (V); } \
while (0)
+#undef COMPAT_USE_64BIT_TIME
#define COMPAT_USE_64BIT_TIME \
(!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
#else
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
index f45acad3c4b6..2c2a23cb716c 100644
--- a/arch/x86/include/asm/ftrace.h
+++ b/arch/x86/include/asm/ftrace.h
@@ -45,7 +45,7 @@ int ftrace_int3_handler(struct pt_regs *regs);
#if !defined(__ASSEMBLY__) && !defined(COMPILE_OFFSETS)
#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_IA32_EMULATION)
-#include <asm/compat.h>
+#include <linux/compat.h>
/*
* Because ia32 syscalls do not map to x86_64 syscall numbers
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h
index 82c34ee25a65..8527b26ad36f 100644
--- a/arch/x86/include/asm/sys_ia32.h
+++ b/arch/x86/include/asm/sys_ia32.h
@@ -16,7 +16,7 @@
#include <linux/linkage.h>
#include <linux/types.h>
#include <linux/signal.h>
-#include <asm/compat.h>
+#include <linux/compat.h>
#include <asm/ia32.h>
/* ia32/sys_ia32.c */
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 87848ebe2bb7..6649e07bfe66 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -2134,7 +2134,7 @@ static unsigned long get_segment_base(unsigned int segment)
#ifdef CONFIG_COMPAT
-#include <asm/compat.h>
+#include <linux/compat.h>
static inline int
perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
diff --git a/include/linux/compat.h b/include/linux/compat.h
index d533d06146a8..41b0dae6203b 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -15,15 +15,12 @@
#include <linux/fs.h>
#include <linux/aio_abi.h> /* for aio_context_t */
#include <linux/unistd.h>
+#include <linux/compat_time.h>
#include <asm/compat.h>
#include <asm/siginfo.h>
#include <asm/signal.h>
-#ifndef COMPAT_USE_64BIT_TIME
-#define COMPAT_USE_64BIT_TIME 0
-#endif
-
#ifndef __SC_DELOUSE
#define __SC_DELOUSE(t,v) ((t)(unsigned long)(v))
#endif
@@ -72,26 +69,9 @@ typedef struct compat_sigaltstack {
typedef __compat_uid32_t compat_uid_t;
typedef __compat_gid32_t compat_gid_t;
-typedef compat_ulong_t compat_aio_context_t;
-
struct compat_sel_arg_struct;
struct rusage;
-struct compat_itimerspec {
- struct compat_timespec it_interval;
- struct compat_timespec it_value;
-};
-
-struct compat_utimbuf {
- compat_time_t actime;
- compat_time_t modtime;
-};
-
-struct compat_itimerval {
- struct compat_timeval it_interval;
- struct compat_timeval it_value;
-};
-
struct compat_tms {
compat_clock_t tms_utime;
compat_clock_t tms_stime;
@@ -99,39 +79,6 @@ struct compat_tms {
compat_clock_t tms_cstime;
};
-struct compat_timex {
- compat_uint_t modes;
- compat_long_t offset;
- compat_long_t freq;
- compat_long_t maxerror;
- compat_long_t esterror;
- compat_int_t status;
- compat_long_t constant;
- compat_long_t precision;
- compat_long_t tolerance;
- struct compat_timeval time;
- compat_long_t tick;
- compat_long_t ppsfreq;
- compat_long_t jitter;
- compat_int_t shift;
- compat_long_t stabil;
- compat_long_t jitcnt;
- compat_long_t calcnt;
- compat_long_t errcnt;
- compat_long_t stbcnt;
- compat_int_t tai;
-
- compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
- compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
- compat_int_t:32; compat_int_t:32; compat_int_t:32;
-};
-
-#define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW)
-
-typedef struct {
- compat_sigset_word sig[_COMPAT_NSIG_WORDS];
-} compat_sigset_t;
-
struct compat_sigaction {
#ifndef __ARCH_HAS_IRIX_SIGACTION
compat_uptr_t sa_handler;
@@ -146,24 +93,6 @@ struct compat_sigaction {
compat_sigset_t sa_mask __packed;
};
-/*
- * These functions operate on 32- or 64-bit specs depending on
- * COMPAT_USE_64BIT_TIME, hence the void user pointer arguments.
- */
-extern int compat_get_timespec(struct timespec *, const void __user *);
-extern int compat_put_timespec(const struct timespec *, void __user *);
-extern int compat_get_timeval(struct timeval *, const void __user *);
-extern int compat_put_timeval(const struct timeval *, void __user *);
-
-/*
- * This function convert a timespec if necessary and returns a *user
- * space* pointer. If no conversion is necessary, it returns the
- * initial pointer. NULL is a legitimate argument and will always
- * output NULL.
- */
-extern int compat_convert_timespec(struct timespec __user **,
- const void __user *);
-
struct compat_iovec {
compat_uptr_t iov_base;
compat_size_t iov_len;
@@ -174,28 +103,6 @@ struct compat_rlimit {
compat_ulong_t rlim_max;
};
-struct compat_rusage {
- struct compat_timeval ru_utime;
- struct compat_timeval ru_stime;
- compat_long_t ru_maxrss;
- compat_long_t ru_ixrss;
- compat_long_t ru_idrss;
- compat_long_t ru_isrss;
- compat_long_t ru_minflt;
- compat_long_t ru_majflt;
- compat_long_t ru_nswap;
- compat_long_t ru_inblock;
- compat_long_t ru_oublock;
- compat_long_t ru_msgsnd;
- compat_long_t ru_msgrcv;
- compat_long_t ru_nsignals;
- compat_long_t ru_nvcsw;
- compat_long_t ru_nivcsw;
-};
-
-extern int put_compat_rusage(const struct rusage *,
- struct compat_rusage __user *);
-
struct compat_siginfo;
extern asmlinkage long compat_sys_waitid(int, compat_pid_t,
@@ -324,8 +231,6 @@ asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp,
compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg);
long compat_sys_msgctl(int first, int second, void __user *uptr);
long compat_sys_shmctl(int first, int second, void __user *uptr);
-long compat_sys_semtimedop(int semid, struct sembuf __user *tsems,
- unsigned nsems, const struct compat_timespec __user *timeout);
asmlinkage long compat_sys_keyctl(u32 option,
u32 arg2, u32 arg3, u32 arg4, u32 arg5);
asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32);
@@ -361,12 +266,6 @@ asmlinkage long compat_sys_execveat(int dfd, const char __user *filename,
const compat_uptr_t __user *argv,
const compat_uptr_t __user *envp, int flags);
-asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
- compat_ulong_t __user *outp, compat_ulong_t __user *exp,
- struct compat_timeval __user *tvp);
-
-asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg);
-
asmlinkage long compat_sys_wait4(compat_pid_t pid,
compat_uint_t __user *stat_addr, int options,
struct compat_rusage __user *ru);
@@ -392,38 +291,6 @@ asmlinkage long compat_sys_sigaction(int sig,
struct compat_old_sigaction __user *oact);
#endif
-static inline int compat_timeval_compare(struct compat_timeval *lhs,
- struct compat_timeval *rhs)
-{
- if (lhs->tv_sec < rhs->tv_sec)
- return -1;
- if (lhs->tv_sec > rhs->tv_sec)
- return 1;
- return lhs->tv_usec - rhs->tv_usec;
-}
-
-static inline int compat_timespec_compare(struct compat_timespec *lhs,
- struct compat_timespec *rhs)
-{
- if (lhs->tv_sec < rhs->tv_sec)
- return -1;
- if (lhs->tv_sec > rhs->tv_sec)
- return 1;
- return lhs->tv_nsec - rhs->tv_nsec;
-}
-
-extern int get_compat_itimerspec(struct itimerspec *dst,
- const struct compat_itimerspec __user *src);
-extern int put_compat_itimerspec(struct compat_itimerspec __user *dst,
- const struct itimerspec *src);
-
-asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
- struct timezone __user *tz);
-asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
- struct timezone __user *tz);
-
-asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
-
extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat);
extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set);
@@ -451,48 +318,20 @@ asmlinkage long compat_sys_epoll_pwait(int epfd,
const compat_sigset_t __user *sigmask,
compat_size_t sigsetsize);
-asmlinkage long compat_sys_utime(const char __user *filename,
- struct compat_utimbuf __user *t);
-asmlinkage long compat_sys_utimensat(unsigned int dfd,
- const char __user *filename,
- struct compat_timespec __user *t,
- int flags);
-
-asmlinkage long compat_sys_time(compat_time_t __user *tloc);
-asmlinkage long compat_sys_stime(compat_time_t __user *tptr);
asmlinkage long compat_sys_signalfd(int ufd,
const compat_sigset_t __user *sigmask,
compat_size_t sigsetsize);
-asmlinkage long compat_sys_timerfd_settime(int ufd, int flags,
- const struct compat_itimerspec __user *utmr,
- struct compat_itimerspec __user *otmr);
-asmlinkage long compat_sys_timerfd_gettime(int ufd,
- struct compat_itimerspec __user *otmr);
-
asmlinkage long compat_sys_move_pages(pid_t pid, compat_ulong_t nr_pages,
__u32 __user *pages,
const int __user *nodes,
int __user *status,
int flags);
-asmlinkage long compat_sys_futimesat(unsigned int dfd,
- const char __user *filename,
- struct compat_timeval __user *t);
-asmlinkage long compat_sys_utimes(const char __user *filename,
- struct compat_timeval __user *t);
-asmlinkage long compat_sys_newstat(const char __user *filename,
- struct compat_stat __user *statbuf);
-asmlinkage long compat_sys_newlstat(const char __user *filename,
- struct compat_stat __user *statbuf);
-asmlinkage long compat_sys_newfstatat(unsigned int dfd,
- const char __user *filename,
- struct compat_stat __user *statbuf,
- int flag);
-asmlinkage long compat_sys_newfstat(unsigned int fd,
- struct compat_stat __user *statbuf);
+struct compat_statfs;
asmlinkage long compat_sys_statfs(const char __user *pathname,
struct compat_statfs __user *buf);
asmlinkage long compat_sys_fstatfs(unsigned int fd,
struct compat_statfs __user *buf);
+struct compat_statfs64;
asmlinkage long compat_sys_statfs64(const char __user *pathname,
compat_size_t sz,
struct compat_statfs64 __user *buf);
@@ -503,11 +342,6 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd,
compat_ulong_t arg);
asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p);
-asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id,
- compat_long_t min_nr,
- compat_long_t nr,
- struct io_event __user *events,
- struct compat_timespec __user *timeout);
asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr,
u32 __user *iocb);
asmlinkage long compat_sys_mount(const char __user *dev_name,
@@ -536,16 +370,6 @@ asmlinkage long compat_sys_open_by_handle_at(int mountdirfd,
int flags);
asmlinkage long compat_sys_truncate(const char __user *, compat_off_t);
asmlinkage long compat_sys_ftruncate(unsigned int, compat_ulong_t);
-asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp,
- compat_ulong_t __user *outp,
- compat_ulong_t __user *exp,
- struct compat_timespec __user *tsp,
- void __user *sig);
-asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
- unsigned int nfds,
- struct compat_timespec __user *tsp,
- const compat_sigset_t __user *sigmask,
- compat_size_t sigsetsize);
asmlinkage long compat_sys_signalfd4(int ufd,
const compat_sigset_t __user *sigmask,
compat_size_t sigsetsize, int flags);
@@ -574,16 +398,6 @@ asmlinkage long compat_sys_recv(int fd, void __user *buf, compat_size_t len,
asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, compat_size_t len,
unsigned flags, struct sockaddr __user *addr,
int __user *addrlen);
-asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
- unsigned vlen, unsigned int flags,
- struct compat_timespec __user *timeout);
-asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
- struct compat_timespec __user *rmtp);
-asmlinkage long compat_sys_getitimer(int which,
- struct compat_itimerval __user *it);
-asmlinkage long compat_sys_setitimer(int which,
- struct compat_itimerval __user *in,
- struct compat_itimerval __user *out);
asmlinkage long compat_sys_times(struct compat_tms __user *tbuf);
asmlinkage long compat_sys_setrlimit(unsigned int resource,
struct compat_rlimit __user *rlim);
@@ -599,25 +413,6 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid,
asmlinkage long compat_sys_timer_create(clockid_t which_clock,
struct compat_sigevent __user *timer_event_spec,
timer_t __user *created_timer_id);
-asmlinkage long compat_sys_timer_settime(timer_t timer_id, int flags,
- struct compat_itimerspec __user *new,
- struct compat_itimerspec __user *old);
-asmlinkage long compat_sys_timer_gettime(timer_t timer_id,
- struct compat_itimerspec __user *setting);
-asmlinkage long compat_sys_clock_settime(clockid_t which_clock,
- struct compat_timespec __user *tp);
-asmlinkage long compat_sys_clock_gettime(clockid_t which_clock,
- struct compat_timespec __user *tp);
-asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock,
- struct compat_timex __user *tp);
-asmlinkage long compat_sys_clock_getres(clockid_t which_clock,
- struct compat_timespec __user *tp);
-asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
- struct compat_timespec __user *rqtp,
- struct compat_timespec __user *rmtp);
-asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese,
- struct compat_siginfo __user *uinfo,
- struct compat_timespec __user *uts, compat_size_t sigsetsize);
asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset,
compat_size_t sigsetsize);
asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set,
@@ -636,9 +431,6 @@ asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig,
asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
compat_ulong_t arg);
-asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
- struct compat_timespec __user *utime, u32 __user *uaddr2,
- u32 val3);
asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
char __user *optval, int __user *optlen);
asmlinkage long compat_sys_kexec_load(compat_ulong_t entry,
@@ -653,14 +445,6 @@ asmlinkage long compat_sys_mq_notify(mqd_t mqdes,
asmlinkage long compat_sys_mq_open(const char __user *u_name,
int oflag, compat_mode_t mode,
struct compat_mq_attr __user *u_attr);
-asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes,
- const char __user *u_msg_ptr,
- compat_size_t msg_len, unsigned int msg_prio,
- const struct compat_timespec __user *u_abs_timeout);
-asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes,
- char __user *u_msg_ptr,
- compat_size_t msg_len, unsigned int __user *u_msg_prio,
- const struct compat_timespec __user *u_abs_timeout);
asmlinkage long compat_sys_socketcall(int call, u32 __user *args);
asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args);
@@ -707,9 +491,6 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
put_user_ex(t->sas_ss_size, &__uss->ss_size); \
} while (0);
-asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
- struct compat_timespec __user *interval);
-
asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
int, const char __user *);
#else
diff --git a/include/linux/compat_time.h b/include/linux/compat_time.h
new file mode 100644
index 000000000000..37564582f6a5
--- /dev/null
+++ b/include/linux/compat_time.h
@@ -0,0 +1,255 @@
+#ifndef _LINUX_COMPAT_TIME_H
+#define _LINUX_COMPAT_TIME_H
+/*
+ * These are the type definitions for the architecture specific
+ * syscall compatibility layer for 32-bit time_t.
+ *
+ * The emulation is used both on 32-bit architectures that have
+ * been converted to 64-bit __kernel_time_t as well as on 64-bit
+ * architectures with 32-bit user space.
+ */
+#include <linux/resource.h>
+#include <linux/signal.h>
+
+#ifndef COMPAT_USE_64BIT_TIME
+#define COMPAT_USE_64BIT_TIME 0
+#endif
+
+typedef s32 compat_int_t;
+typedef u32 compat_uint_t;
+typedef s32 compat_long_t;
+typedef u32 compat_ulong_t;
+typedef u32 compat_size_t;
+typedef s32 compat_ssize_t;
+typedef s32 compat_time_t;
+typedef u32 compat_aio_context_t;
+typedef u32 compat_uptr_t;
+typedef __kernel_pid_t compat_pid_t;
+
+struct compat_timespec {
+ compat_time_t tv_sec;
+ s32 tv_nsec;
+};
+
+struct compat_timeval {
+ compat_time_t tv_sec;
+ s32 tv_usec;
+};
+
+struct compat_itimerspec {
+ struct compat_timespec it_interval;
+ struct compat_timespec it_value;
+};
+
+struct compat_utimbuf {
+ compat_time_t actime;
+ compat_time_t modtime;
+};
+
+struct compat_itimerval {
+ struct compat_timeval it_interval;
+ struct compat_timeval it_value;
+};
+
+struct compat_timex {
+ compat_uint_t modes;
+ compat_long_t offset;
+ compat_long_t freq;
+ compat_long_t maxerror;
+ compat_long_t esterror;
+ compat_int_t status;
+ compat_long_t constant;
+ compat_long_t precision;
+ compat_long_t tolerance;
+ struct compat_timeval time;
+ compat_long_t tick;
+ compat_long_t ppsfreq;
+ compat_long_t jitter;
+ compat_int_t shift;
+ compat_long_t stabil;
+ compat_long_t jitcnt;
+ compat_long_t calcnt;
+ compat_long_t errcnt;
+ compat_long_t stbcnt;
+ compat_int_t tai;
+
+ compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
+ compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
+ compat_int_t:32; compat_int_t:32; compat_int_t:32;
+};
+
+
+/*
+ * These functions operate on 32- or 64-bit specs depending on
+ * COMPAT_USE_64BIT_TIME, hence the void user pointer arguments.
+ */
+extern int compat_get_timespec(struct timespec *, const void __user *);
+extern int compat_put_timespec(const struct timespec *, void __user *);
+extern int compat_get_timeval(struct timeval *, const void __user *);
+extern int compat_put_timeval(const struct timeval *, void __user *);
+
+/*
+ * This function convert a timespec if necessary and returns a *user
+ * space* pointer. If no conversion is necessary, it returns the
+ * initial pointer. NULL is a legitimate argument and will always
+ * output NULL.
+ */
+extern int compat_convert_timespec(struct timespec __user **,
+ const void __user *);
+
+struct compat_rusage {
+ struct compat_timeval ru_utime;
+ struct compat_timeval ru_stime;
+ compat_long_t ru_maxrss;
+ compat_long_t ru_ixrss;
+ compat_long_t ru_idrss;
+ compat_long_t ru_isrss;
+ compat_long_t ru_minflt;
+ compat_long_t ru_majflt;
+ compat_long_t ru_nswap;
+ compat_long_t ru_inblock;
+ compat_long_t ru_oublock;
+ compat_long_t ru_msgsnd;
+ compat_long_t ru_msgrcv;
+ compat_long_t ru_nsignals;
+ compat_long_t ru_nvcsw;
+ compat_long_t ru_nivcsw;
+};
+
+struct rusage;
+extern int put_compat_rusage(const struct rusage *,
+ struct compat_rusage __user *);
+
+static inline int compat_timeval_compare(struct compat_timeval *lhs,
+ struct compat_timeval *rhs)
+{
+ if (lhs->tv_sec < rhs->tv_sec)
+ return -1;
+ if (lhs->tv_sec > rhs->tv_sec)
+ return 1;
+ return lhs->tv_usec - rhs->tv_usec;
+}
+
+static inline int compat_timespec_compare(struct compat_timespec *lhs,
+ struct compat_timespec *rhs)
+{
+ if (lhs->tv_sec < rhs->tv_sec)
+ return -1;
+ if (lhs->tv_sec > rhs->tv_sec)
+ return 1;
+ return lhs->tv_nsec - rhs->tv_nsec;
+}
+
+extern int get_compat_itimerspec(struct itimerspec *dst,
+ const struct compat_itimerspec __user *src);
+extern int put_compat_itimerspec(struct compat_itimerspec __user *dst,
+ const struct itimerspec *src);
+
+struct sembuf;
+asmlinkage long compat_sys_semtimedop(int semid, struct sembuf __user *tsems,
+ unsigned nsems, const struct compat_timespec __user *timeout);
+asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
+ compat_ulong_t __user *outp, compat_ulong_t __user *exp,
+ struct compat_timeval __user *tvp);
+struct compat_sel_arg_struct;
+asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg);
+asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp,
+ compat_ulong_t __user *outp,
+ compat_ulong_t __user *exp,
+ struct compat_timespec __user *tsp,
+ void __user *sig);
+asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
+ struct timezone __user *tz);
+asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
+ struct timezone __user *tz);
+
+asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
+
+asmlinkage long compat_sys_utime(const char __user *filename,
+ struct compat_utimbuf __user *t);
+asmlinkage long compat_sys_utimensat(unsigned int dfd,
+ const char __user *filename,
+ struct compat_timespec __user *t,
+ int flags);
+
+asmlinkage long compat_sys_time(compat_time_t __user *tloc);
+asmlinkage long compat_sys_stime(compat_time_t __user *tptr);
+
+asmlinkage long compat_sys_timerfd_settime(int ufd, int flags,
+ const struct compat_itimerspec __user *utmr,
+ struct compat_itimerspec __user *otmr);
+asmlinkage long compat_sys_timerfd_gettime(int ufd,
+ struct compat_itimerspec __user *otmr);
+
+asmlinkage long compat_sys_futimesat(unsigned int dfd,
+ const char __user *filename,
+ struct compat_timeval __user *t);
+asmlinkage long compat_sys_utimes(const char __user *filename,
+ struct compat_timeval __user *t);
+struct compat_stat;
+asmlinkage long compat_sys_newstat(const char __user *filename,
+ struct compat_stat __user *statbuf);
+asmlinkage long compat_sys_newlstat(const char __user *filename,
+ struct compat_stat __user *statbuf);
+asmlinkage long compat_sys_newfstatat(unsigned int dfd,
+ const char __user *filename,
+ struct compat_stat __user *statbuf,
+ int flag);
+asmlinkage long compat_sys_newfstat(unsigned int fd,
+ struct compat_stat __user *statbuf);
+struct io_event;
+asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id,
+ compat_long_t min_nr,
+ compat_long_t nr,
+ struct io_event __user *events,
+ struct compat_timespec __user *timeout);
+asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
+ unsigned int nfds,
+ struct compat_timespec __user *tsp,
+ const compat_sigset_t __user *sigmask,
+ compat_size_t sigsetsize);
+struct compat_mmsghdr;
+asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
+ unsigned vlen, unsigned int flags,
+ struct compat_timespec __user *timeout);
+asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
+ struct compat_timespec __user *rmtp);
+asmlinkage long compat_sys_getitimer(int which,
+ struct compat_itimerval __user *it);
+asmlinkage long compat_sys_setitimer(int which,
+ struct compat_itimerval __user *in,
+ struct compat_itimerval __user *out);
+asmlinkage long compat_sys_timer_settime(timer_t timer_id, int flags,
+ struct compat_itimerspec __user *new,
+ struct compat_itimerspec __user *old);
+asmlinkage long compat_sys_timer_gettime(timer_t timer_id,
+ struct compat_itimerspec __user *setting);
+asmlinkage long compat_sys_clock_settime(clockid_t which_clock,
+ struct compat_timespec __user *tp);
+asmlinkage long compat_sys_clock_gettime(clockid_t which_clock,
+ struct compat_timespec __user *tp);
+asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock,
+ struct compat_timex __user *tp);
+asmlinkage long compat_sys_clock_getres(clockid_t which_clock,
+ struct compat_timespec __user *tp);
+asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
+ struct compat_timespec __user *rqtp,
+ struct compat_timespec __user *rmtp);
+struct compat_siginfo;
+asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese,
+ struct compat_siginfo __user *uinfo,
+ struct compat_timespec __user *uts, compat_size_t sigsetsize);
+asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
+ struct compat_timespec __user *utime, u32 __user *uaddr2,
+ u32 val3);
+asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes,
+ const char __user *u_msg_ptr,
+ compat_size_t msg_len, unsigned int msg_prio,
+ const struct compat_timespec __user *u_abs_timeout);
+asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes,
+ char __user *u_msg_ptr,
+ compat_size_t msg_len, unsigned int __user *u_msg_prio,
+ const struct compat_timespec __user *u_abs_timeout);
+asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
+ struct compat_timespec __user *interval);
+#endif
--
2.1.0.rc2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox