Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [RFC V1 00/16] hci_ldisc hci_uart_tty_close() fixes
From: Marcel Holtmann @ 2017-04-03 15:51 UTC (permalink / raw)
  To: Dean Jenkins; +Cc: Gustavo F. Padovan, Johan Hedberg, linux-bluetooth
In-Reply-To: <ee49f939-1094-0ae0-0fa7-6c5cad112527@mentor.com>

Hi Dean,

>>> This is RFC patchset V1 which reorganises hci_uart_tty_close() to overcome a
>>> design flaw. I would like some comments on the changes.
>>> 
>>> Design Flaw
>>> ===========
>>> 
>>> An example callstack is as follows
>>> 
>>> Have Bluetooth running using a BCSP based UART Bluetooth Radio Module.
>>> 
>>> Now kill the userland hciattach program by doing
>>> killall hciattach
>> is there any chance we can convert BCSP support to run fully inside the kernel with the new parts we have put in. And with that then also use btattach. The split of some parts of BCSP in userspace seems never been a good idea.
> 
> I am not aware of "the new parts we [you] have put in" to the kernel because I am working with the older 3.14 kernel with userland components that are not Bluez based but the kernel issue is observable. Is there a web page where I can find out about your design changes for the new parts ?
> 
> My efforts are to improve the latest upstream kernel to eliminate this kernel design flaw in HCI UART LDISC (Note TTY LDISC is also broken but not fixed by my patchset).
> 
> I see that "btattach" is at https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/tools/btattach.c, however, I am unable to identify whether Linux distributions such as Ubuntu have a bluez package that contains "btattach". Is "btattach" a replacement for "hciattach” ?

yes, we want to move towards btattach that just assigned the line discipline and selects the UART protocol. Everything else including firmware download, speed changes, recover etc. should be done inside the kernel.

And later with serdev, we would not even need btattach anymore. UART based Bluetooth devices would be enumerated via DT and the TTY not even exposed to userspace. We are slowly getting to that point.

The latest kernel has UART drivers like hci_intel.c and hci_bcm.c which do a lot of things in the kernel. And btattach is just the process that keeps the line discipline open.

>> I am a bit reluctant to change major hci_ldisc pieces because of just one broken protocol. Running BCSP fully in the kernel seems a better solution to deal with some of these issues.
> 
> The kernel BCSP software in the kernel is not broken although it is not fully implemented as you already highlighted. The issue is that HCI UART LDISC (and TTY LDISC) has a broken procedure for closing down the HCI UART device via hci_uart_tty_close().
> 
> This means that I don't see how your suggestion helps to resolve the kernel design flaw which is related to closing down any of the Bluetooth Data Link protocol layers such as H4, H5, and BCSP (I use BCSP). This flaw seems to me to be a long standing Bluetooth kernel Data Link protocol layer closedown issue and is unrelated to how the Data Link protocol layer is established (connected). Therefore, having BCSP partly in userland is irrelevant to this kernel design flaw. Even with BCSP fully in the kernel, the protocol closedown issue will remain present I think.

If you think there are issues, then lets fix them for all protocols. I assumed this was BCSP specific.

> I might try to build "btattach" and have a go to use it. If you look inside the source code of "btattach" and "hciattach" you can see the problem area in closing down an established Bluetooth Data Link protocol layer by the use of:
> 
>    if (ioctl(fd, TIOCSETD, &ldisc) < 0) {
>        perror("Failed set serial line discipline");
>        close(fd);
>        return -1;
>    }
> 
> This userland call is the problem area as this asynchronous ioctl TIOCSETD can cause hci_uart_tty_close() to run and I think it can cause trouble for ALL the Bluetooth Data Link protocol layers such as H4, H5 and BCSP.
> 
> The design flaw is exposed after the Data Link protocol layer has been established (connected) and ioctl TIOCSETD is used from userland. In my example, I killed "hciattach" which is an abnormal scenario but it still needs good handling. I think I have strace evidence of TIOCSETD being used due to SIGTERM.
> 
> The design flaw is because TIOCSETD can trigger the sending of a HCI RESET command during closedown of HCI UART LDISC, TTY LDISC and the Data Link protocol layer. I only have experience of BCSP but I suspect H4 and H5 have retransmission procedures similar to BCSP so would also be susceptible to this issue of trying to send a HCI RESET command whilst closing down the needed data path to the UART driver which causes sending of the HCI RESET command to be unsuccessful.
> 
> I think the callstack is:
> 
> Userland ioctl TIOCSETD executes causing =>
> Kernel ioctl system call which runs
> tty_ioctl()
> tiocsetd()
> tty_set_ldisc()
> tty_ldisc_close()
> hci_uart_tty_close()
> hci_unregister_dev()
> hci_dev_do_close()
> __hci_req_sync() which tries to send a HCI RESET command which depends on
> HCI_QUIRK_RESET_ON_CLOSE being enabled and that is the default condition
> 
> I believe It will affect the closure of any of the Bluetooth Data Link protocol layers.
> 
> Note that not enabling HCI_QUIRK_RESET_ON_CLOSE does not fully help because if Data Link protocol layer retransmissions are occurring when hci_uart_tty_close() runs then the various race conditions are still present in hci_uart_tty_close().
> 
> I suspect evidence of the design flaw can be observed by measuring the execution time of the userland ioctl TIOCSETD calls. I predict that sometimes it will take 2 seconds for TIOCSETD to complete due to being blocked waiting for the unsuccessful attempt at sending the HCI RESET command because the HCI command time-out expires. I believe this will be independent of the underlying Bluetooth Data Link protocol layer.
> 
> Do you have any suggestions for moving forward in accepting my proposed changes ? I will try to provide more observable evidence of the issue on kernel v.4.10 on a Linux PC.

If this is an issue in 4.10, then lets get this fixed / hardened.

Regards

Marcel


^ permalink raw reply

* Re: [RFC V1 00/16] hci_ldisc hci_uart_tty_close() fixes
From: Dean Jenkins @ 2017-04-03 15:09 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Gustavo F. Padovan, Johan Hedberg, linux-bluetooth
In-Reply-To: <AA3DD0DD-5CAC-4ADD-9B0C-4E652C93E4D6@holtmann.org>

Hi Marcel,

On 30/03/17 11:11, Marcel Holtmann wrote:
> Hi Dean,
>
>> This is RFC patchset V1 which reorganises hci_uart_tty_close() to overcome a
>> design flaw. I would like some comments on the changes.
>>
>> Design Flaw
>> ===========
>>
>> An example callstack is as follows
>>
>> Have Bluetooth running using a BCSP based UART Bluetooth Radio Module.
>>
>> Now kill the userland hciattach program by doing
>> killall hciattach
> is there any chance we can convert BCSP support to run fully inside the kernel with the new parts we have put in. And with that then also use btattach. The split of some parts of BCSP in userspace seems never been a good idea.

I am not aware of "the new parts we [you] have put in" to the kernel 
because I am working with the older 3.14 kernel with userland components 
that are not Bluez based but the kernel issue is observable. Is there a 
web page where I can find out about your design changes for the new parts ?

My efforts are to improve the latest upstream kernel to eliminate this 
kernel design flaw in HCI UART LDISC (Note TTY LDISC is also broken but 
not fixed by my patchset).

I see that "btattach" is at 
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/tools/btattach.c, 
however, I am unable to identify whether Linux distributions such as 
Ubuntu have a bluez package that contains "btattach". Is "btattach" a 
replacement for "hciattach" ?


>
> I am a bit reluctant to change major hci_ldisc pieces because of just one broken protocol. Running BCSP fully in the kernel seems a better solution to deal with some of these issues.

The kernel BCSP software in the kernel is not broken although it is not 
fully implemented as you already highlighted. The issue is that HCI UART 
LDISC (and TTY LDISC) has a broken procedure for closing down the HCI 
UART device via hci_uart_tty_close().

This means that I don't see how your suggestion helps to resolve the 
kernel design flaw which is related to closing down any of the Bluetooth 
Data Link protocol layers such as H4, H5, and BCSP (I use BCSP). This 
flaw seems to me to be a long standing Bluetooth kernel Data Link 
protocol layer closedown issue and is unrelated to how the Data Link 
protocol layer is established (connected). Therefore, having BCSP partly 
in userland is irrelevant to this kernel design flaw. Even with BCSP 
fully in the kernel, the protocol closedown issue will remain present I 
think.

I might try to build "btattach" and have a go to use it. If you look 
inside the source code of "btattach" and "hciattach" you can see the 
problem area in closing down an established Bluetooth Data Link protocol 
layer by the use of:

     if (ioctl(fd, TIOCSETD, &ldisc) < 0) {
         perror("Failed set serial line discipline");
         close(fd);
         return -1;
     }

This userland call is the problem area as this asynchronous ioctl 
TIOCSETD can cause hci_uart_tty_close() to run and I think it can cause 
trouble for ALL the Bluetooth Data Link protocol layers such as H4, H5 
and BCSP.

The design flaw is exposed after the Data Link protocol layer has been 
established (connected) and ioctl TIOCSETD is used from userland. In my 
example, I killed "hciattach" which is an abnormal scenario but it still 
needs good handling. I think I have strace evidence of TIOCSETD being 
used due to SIGTERM.

The design flaw is because TIOCSETD can trigger the sending of a HCI 
RESET command during closedown of HCI UART LDISC, TTY LDISC and the Data 
Link protocol layer. I only have experience of BCSP but I suspect H4 and 
H5 have retransmission procedures similar to BCSP so would also be 
susceptible to this issue of trying to send a HCI RESET command whilst 
closing down the needed data path to the UART driver which causes 
sending of the HCI RESET command to be unsuccessful.

I think the callstack is:

Userland ioctl TIOCSETD executes causing =>
Kernel ioctl system call which runs
tty_ioctl()
tiocsetd()
tty_set_ldisc()
tty_ldisc_close()
hci_uart_tty_close()
hci_unregister_dev()
hci_dev_do_close()
__hci_req_sync() which tries to send a HCI RESET command which depends on
HCI_QUIRK_RESET_ON_CLOSE being enabled and that is the default condition

I believe It will affect the closure of any of the Bluetooth Data Link 
protocol layers.

Note that not enabling HCI_QUIRK_RESET_ON_CLOSE does not fully help 
because if Data Link protocol layer retransmissions are occurring when 
hci_uart_tty_close() runs then the various race conditions are still 
present in hci_uart_tty_close().

I suspect evidence of the design flaw can be observed by measuring the 
execution time of the userland ioctl TIOCSETD calls. I predict that 
sometimes it will take 2 seconds for TIOCSETD to complete due to being 
blocked waiting for the unsuccessful attempt at sending the HCI RESET 
command because the HCI command time-out expires. I believe this will be 
independent of the underlying Bluetooth Data Link protocol layer.

Do you have any suggestions for moving forward in accepting my proposed 
changes ? I will try to provide more observable evidence of the issue on 
kernel v.4.10 on a Linux PC.

Thanks for your time in looking at my proposed patches.

Best regards,
Dean

-- 
Dean Jenkins
Embedded Software Engineer
Linux Transportation Solutions
Mentor Embedded Software Division
Mentor Graphics (UK) Ltd.

^ permalink raw reply

* [PATCH 3/3] Bluetooth: L2CAP: Don't return -EAGAIN if out of credits
From: Luiz Augusto von Dentz @ 2017-04-03 14:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: aar, jukka.rissanen, linux-wpan
In-Reply-To: <20170403144857.4661-1-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Just keep queueing them into TX queue since the caller might just have
to do the same and there is no impact in adding another packet to the
TX queue even if there aren't any credits to transmit them.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 net/bluetooth/l2cap_core.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index fc7f321..3a202b0 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2458,9 +2458,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
 		if (len > chan->omtu)
 			return -EMSGSIZE;
 
-		if (!chan->tx_credits)
-			return -EAGAIN;
-
 		__skb_queue_head_init(&seg_queue);
 
 		err = l2cap_segment_le_sdu(chan, &seg_queue, msg, len);
-- 
2.9.3


^ permalink raw reply related

* [PATCH 2/3] Bluetooth: 6lowpan: Print errors during recv_pkt
From: Luiz Augusto von Dentz @ 2017-04-03 14:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: aar, jukka.rissanen, linux-wpan
In-Reply-To: <20170403144857.4661-1-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This makes should make it more clear why a packet is being dropped.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 net/bluetooth/6lowpan.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 2063e96..5b91e85 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -337,6 +337,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
 
 		ret = iphc_decompress(local_skb, dev, peer);
 		if (ret < 0) {
+			BT_DBG("iphc_decompress failed: %d", ret);
 			kfree_skb(local_skb);
 			goto drop;
 		}
@@ -356,6 +357,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
 		consume_skb(local_skb);
 		consume_skb(skb);
 	} else {
+		BT_DBG("unknown packet type");
 		goto drop;
 	}
 
-- 
2.9.3


^ permalink raw reply related

* [PATCH 1/3] Bluetooth: 6lowpan: Remove unnecessary peer lookup
From: Luiz Augusto von Dentz @ 2017-04-03 14:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: aar, jukka.rissanen, linux-wpan

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

During chan_recv_cb there is already a peer lookup which can be passed
to recv_pkt directly instead of the channel.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 net/bluetooth/6lowpan.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index b39da8d..2063e96 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -269,27 +269,20 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
 }
 
 static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
-			   struct l2cap_chan *chan)
+			   struct lowpan_peer *peer)
 {
 	const u8 *saddr;
 	struct lowpan_btle_dev *dev;
-	struct lowpan_peer *peer;
 
 	dev = lowpan_btle_dev(netdev);
 
-	rcu_read_lock();
-	peer = __peer_lookup_chan(dev, chan);
-	rcu_read_unlock();
-	if (!peer)
-		return -EINVAL;
-
 	saddr = peer->lladdr;
 
 	return lowpan_header_decompress(skb, netdev, netdev->dev_addr, saddr);
 }
 
 static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
-		    struct l2cap_chan *chan)
+		    struct lowpan_peer *peer)
 {
 	struct sk_buff *local_skb;
 	int ret;
@@ -342,7 +335,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
 
 		local_skb->dev = dev;
 
-		ret = iphc_decompress(local_skb, dev, chan);
+		ret = iphc_decompress(local_skb, dev, peer);
 		if (ret < 0) {
 			kfree_skb(local_skb);
 			goto drop;
@@ -388,7 +381,7 @@ static int chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
 	if (!dev || !dev->netdev)
 		return -ENOENT;
 
-	err = recv_pkt(skb, dev->netdev, chan);
+	err = recv_pkt(skb, dev->netdev, peer);
 	if (err) {
 		BT_DBG("recv pkt %d", err);
 		err = -EAGAIN;
-- 
2.9.3


^ permalink raw reply related

* Re: [PATCH BlueZ] build: Make btmgmt tools installable
From: Luiz Augusto von Dentz @ 2017-04-03 11:08 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <20170331135823.21883-1-luiz.dentz@gmail.com>

Hi,

On Fri, Mar 31, 2017 at 4:58 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> ---
>  Makefile.tools | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/Makefile.tools b/Makefile.tools
> index 55d392e..73b2eef 100644
> --- a/Makefile.tools
> +++ b/Makefile.tools
> @@ -348,7 +348,9 @@ EXTRA_DIST += tools/hid2hci.1
>  endif
>
>  if READLINE
> -noinst_PROGRAMS += tools/btmgmt tools/obex-client-tool tools/obex-server-tool \
> +bin_PROGRAMS += tools/btmgmt
> +
> +noinst_PROGRAMS += tools/obex-client-tool tools/obex-server-tool \
>                         tools/bluetooth-player tools/obexctl
>
>  tools_obex_client_tool_SOURCES = $(gobex_sources) $(btio_sources) \
> --
> 2.9.3

Applied.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH v2] core: replace sizeof(filename) with PATH_MAX
From: Luiz Augusto von Dentz @ 2017-04-03 11:08 UTC (permalink / raw)
  To: Konrad Zapalowicz
  Cc: Marcel Holtmann, Luiz Augusto Von Dentz,
	linux-bluetooth@vger.kernel.org
In-Reply-To: <1490971474-9719-1-git-send-email-bergo.torino@gmail.com>

Hi Konrad,

On Fri, Mar 31, 2017 at 5:44 PM, Konrad Zapalowicz
<konrad.zapalowicz@canonical.com> wrote:
> From: Konrad Zapa=C5=82owicz <konrad.zapalowicz@canonical.com>
>
> This commit replaces sizeof(filename) with PATH_MAX to match the common
> scheme which is used in other places.
> ---
>  src/adapter.c     | 2 +-
>  src/shared/util.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/src/adapter.c b/src/adapter.c
> index 3dac7d6..3935460 100644
> --- a/src/adapter.c
> +++ b/src/adapter.c
> @@ -7107,7 +7107,7 @@ static void store_csrk(struct btd_adapter *adapter,=
 const bdaddr_t *peer,
>
>         ba2str(peer, device_addr);
>
> -       snprintf(filename, sizeof(filename), STORAGEDIR "/%s/%s/info",
> +       snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
>                                         adapter_dir(adapter), device_addr=
);
>
>         key_file =3D g_key_file_new();
> diff --git a/src/shared/util.c b/src/shared/util.c
> index 7878552..4b59fad 100644
> --- a/src/shared/util.c
> +++ b/src/shared/util.c
> @@ -117,7 +117,7 @@ unsigned char util_get_dt(const char *parent, const c=
har *name)
>         char filename[PATH_MAX];
>         struct stat st;
>
> -       snprintf(filename, sizeof(filename), "%s/%s", parent, name);
> +       snprintf(filename, PATH_MAX, "%s/%s", parent, name);
>         if (lstat(filename, &st) =3D=3D 0 && S_ISDIR(st.st_mode))
>                 return DT_DIR;
>
> --
> 2.7.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth=
" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Applied, thanks.

--=20
Luiz Augusto von Dentz

^ permalink raw reply

* Re: Possible crashing bug in bluez 5.44
From: Bastien Nocera @ 2017-04-03  9:24 UTC (permalink / raw)
  To: Cysioland, linux-bluetooth
In-Reply-To: <05483ac0-282d-5f1d-55ed-e2dadcb60dd1@cysioland.pl>

On Sat, 2017-04-01 at 11:15 +0200, Cysioland wrote:
> Hello,
> 
> I've encountered a possible bug when trying to connect my Bluetooth
> headset via A2DP. Pairing is fine, but when it tries to connect the
> bluetoothd segfaults, with the following stacktrace:
> 
> #0 0x0000000000469d60 n/a (bluetoothd)
> #1 0x00000000004472d3 n/a (bluetoothd)
> #2 0x000000000047a31d n/a (bluetoothd)
> #3 0x0000000000447405 n/a (bluetoothd)
> #4 0x00007f8ac61cf45a g_main_context_dispatch (libglib-2.0.so.0)
> #5 0x00007f8ac61cf810 n/a (libglib-2.0.so.0)
> #6 0x00007f8ac61cfb32 g_main_loop_run (libglib-2.0.so.0)
> #7 0x000000000040b6b2 n/a (bluetoothd)
> #8 0x00007f8ac57a5511 __libc_start_main (libc.so.6)
> #9 0x000000000040bf0a n/a (bluetoothd)

You'll need to install debugging symbols, this is unusable
unfortunately.

> I've installed bluez via Arch Linux packages, and after downgrading
> to
> 5.43 the bug no longer appears. I recall seeing lots of work done
> between these two on A2DP, so I suspect a regression there.
> 
> Relevant Arch bug, where they told me to hit here:
> https://bugs.archlinux.org/task/53442
> 
> Should I report it to your Bugzilla? Do you need any more info or
> help?

Cheers

^ permalink raw reply

* [bluetooth-next:master 25/36] drivers/clocksource/timer-sun5i.c:52:21: error: field 'clksrc' has incomplete type
From: kbuild test robot @ 2017-04-02  3:39 UTC (permalink / raw)
  To: Harry Morris; +Cc: kbuild-all, linux-bluetooth, Marcel Holtmann

[-- Attachment #1: Type: text/plain, Size: 44633 bytes --]

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
head:   733db4ccec579e027f54011573a2304c205e7b3d
commit: 3c599b249f3c6090e886bae8e7258bb6176205ef [25/36] ieee802154: Add CA8210 IEEE 802.15.4 device driver
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 6.2.0
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        git checkout 3c599b249f3c6090e886bae8e7258bb6176205ef
        # save the attached .config to linux build tree
        make.cross ARCH=ia64 

All errors (new ones prefixed by >>):

>> drivers/clocksource/timer-sun5i.c:52:21: error: field 'clksrc' has incomplete type
     struct clocksource clksrc;
                        ^~~~~~
>> drivers/clocksource/timer-sun5i.c:60:28: error: field 'clkevt' has incomplete type
     struct clock_event_device clkevt;
                               ^~~~~~
   In file included from include/linux/clk.h:16:0,
                    from drivers/clocksource/timer-sun5i.c:13:
   drivers/clocksource/timer-sun5i.c: In function 'sun5i_clkevt_shutdown':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:108:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:108:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c: In function 'sun5i_clkevt_set_oneshot':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:116:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:116:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c: In function 'sun5i_clkevt_set_periodic':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:125:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:125:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c: In function 'sun5i_clkevt_next_event':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:136:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:136:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c: In function 'sun5i_clksrc_read':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/timer-sun5i.c:56:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clksrc, clksrc)
     ^~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:157:34: note: in expansion of macro 'to_sun5i_timer_clksrc'
     struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
                                     ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'cs')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/timer-sun5i.c:56:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clksrc, clksrc)
     ^~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:157:34: note: in expansion of macro 'to_sun5i_timer_clksrc'
     struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
                                     ^~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c: In function 'sun5i_rate_cb_clksrc':
>> drivers/clocksource/timer-sun5i.c:171:3: error: implicit declaration of function 'clocksource_unregister' [-Werror=implicit-function-declaration]
      clocksource_unregister(&cs->clksrc);
      ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/timer-sun5i.c:175:3: error: implicit declaration of function 'clocksource_register_hz' [-Werror=implicit-function-declaration]
      clocksource_register_hz(&cs->clksrc, ndata->new_rate);
      ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c: In function 'sun5i_setup_clocksource':
>> drivers/clocksource/timer-sun5i.c:223:20: error: implicit declaration of function 'CLOCKSOURCE_MASK' [-Werror=implicit-function-declaration]
     cs->clksrc.mask = CLOCKSOURCE_MASK(32);
                       ^~~~~~~~~~~~~~~~
>> drivers/clocksource/timer-sun5i.c:224:21: error: 'CLOCK_SOURCE_IS_CONTINUOUS' undeclared (first use in this function)
     cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:224:21: note: each undeclared identifier is reported only once for each function it appears in
   drivers/clocksource/timer-sun5i.c: In function 'sun5i_rate_cb_clkevt':
>> drivers/clocksource/timer-sun5i.c:251:3: error: implicit declaration of function 'clockevents_update_freq' [-Werror=implicit-function-declaration]
      clockevents_update_freq(&ce->clkevt, ndata->new_rate);
      ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c: In function 'sun5i_setup_clockevent':
>> drivers/clocksource/timer-sun5i.c:291:24: error: 'CLOCK_EVT_FEAT_PERIODIC' undeclared (first use in this function)
     ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
                           ^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/timer-sun5i.c:291:50: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared (first use in this function)
     ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
                                                     ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/timer-sun5i.c:305:2: error: implicit declaration of function 'clockevents_config_and_register' [-Werror=implicit-function-declaration]
     clockevents_config_and_register(&ce->clkevt, rate,
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c: At top level:
>> drivers/clocksource/timer-sun5i.c:361:35: error: expected ')' before string constant
    CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer",
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:363:35: error: expected ')' before string constant
    CLOCKSOURCE_OF_DECLARE(sun7i_a20, "allwinner,sun7i-a20-hstimer",
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/timer-sun5i.c:326:19: warning: 'sun5i_timer_init' defined but not used [-Wunused-function]
    static int __init sun5i_timer_init(struct device_node *node)
                      ^~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
>> drivers/clocksource/cadence_ttc_timer.c:92:21: error: field 'cs' has incomplete type
     struct clocksource cs;
                        ^~
>> drivers/clocksource/cadence_ttc_timer.c:100:28: error: field 'ce' has incomplete type
     struct clock_event_device ce;
                               ^~
   In file included from include/linux/clk.h:16:0,
                    from drivers/clocksource/cadence_ttc_timer.c:18:
   drivers/clocksource/cadence_ttc_timer.c: In function '__ttc_clocksource_read':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/cadence_ttc_timer.c:96:3: note: in expansion of macro 'container_of'
      container_of(x, struct ttc_timer_clocksource, cs)
      ^~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:163:29: note: in expansion of macro 'to_ttc_timer_clksrc'
     struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc;
                                ^~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'timer')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/cadence_ttc_timer.c:96:3: note: in expansion of macro 'container_of'
      container_of(x, struct ttc_timer_clocksource, cs)
      ^~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:163:29: note: in expansion of macro 'to_ttc_timer_clksrc'
     struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc;
                                ^~~~~~~~~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_set_next_event':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
      container_of(x, struct ttc_timer_clockevent, ce)
      ^~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:185:38: note: in expansion of macro 'to_ttc_timer_clkevent'
     struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
                                         ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ttce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
      container_of(x, struct ttc_timer_clockevent, ce)
      ^~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:185:38: note: in expansion of macro 'to_ttc_timer_clkevent'
     struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
                                         ^~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_shutdown':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
      container_of(x, struct ttc_timer_clockevent, ce)
      ^~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:199:38: note: in expansion of macro 'to_ttc_timer_clkevent'
     struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
                                         ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ttce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
      container_of(x, struct ttc_timer_clockevent, ce)
      ^~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:199:38: note: in expansion of macro 'to_ttc_timer_clkevent'
     struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
                                         ^~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_set_periodic':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
      container_of(x, struct ttc_timer_clockevent, ce)
      ^~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:211:38: note: in expansion of macro 'to_ttc_timer_clkevent'
     struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
                                         ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ttce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
      container_of(x, struct ttc_timer_clockevent, ce)
      ^~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:211:38: note: in expansion of macro 'to_ttc_timer_clkevent'
     struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
                                         ^~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_resume':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
      container_of(x, struct ttc_timer_clockevent, ce)
      ^~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:221:38: note: in expansion of macro 'to_ttc_timer_clkevent'
     struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
                                         ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ttce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers/clocksource/cadence_ttc_timer.c:104:3: note: in expansion of macro 'container_of'
      container_of(x, struct ttc_timer_clockevent, ce)
      ^~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:221:38: note: in expansion of macro 'to_ttc_timer_clkevent'
     struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
                                         ^~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_setup_clocksource':
>> drivers/clocksource/cadence_ttc_timer.c:358:19: error: implicit declaration of function 'CLOCKSOURCE_MASK' [-Werror=implicit-function-declaration]
     ttccs->cs.mask = CLOCKSOURCE_MASK(timer_width);
                      ^~~~~~~~~~~~~~~~
>> drivers/clocksource/cadence_ttc_timer.c:359:20: error: 'CLOCK_SOURCE_IS_CONTINUOUS' undeclared (first use in this function)
     ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:359:20: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/clocksource/cadence_ttc_timer.c:372:8: error: implicit declaration of function 'clocksource_register_hz' [-Werror=implicit-function-declaration]
     err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE);
           ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_rate_change_clockevent_cb':
>> drivers/clocksource/cadence_ttc_timer.c:398:3: error: implicit declaration of function 'clockevents_update_freq' [-Werror=implicit-function-declaration]
      clockevents_update_freq(&ttcce->ce, ndata->new_rate / PRESCALE);
      ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c: In function 'ttc_setup_clockevent':
>> drivers/clocksource/cadence_ttc_timer.c:441:23: error: 'CLOCK_EVT_FEAT_PERIODIC' undeclared (first use in this function)
     ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
                          ^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/cadence_ttc_timer.c:441:49: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared (first use in this function)
     ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
                                                    ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/clocksource/cadence_ttc_timer.c:468:2: error: implicit declaration of function 'clockevents_config_and_register' [-Werror=implicit-function-declaration]
     clockevents_config_and_register(&ttcce->ce,
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c: At top level:
>> drivers/clocksource/cadence_ttc_timer.c:542:29: error: expected ')' before string constant
    CLOCKSOURCE_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init);
                                ^~~~~~~~~~
   drivers/clocksource/cadence_ttc_timer.c:480:19: warning: 'ttc_timer_init' defined but not used [-Wunused-function]
    static int __init ttc_timer_init(struct device_node *timer)
                      ^~~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   drivers//clocksource/timer-sun5i.c:52:21: error: field 'clksrc' has incomplete type
     struct clocksource clksrc;
                        ^~~~~~
   drivers//clocksource/timer-sun5i.c:60:28: error: field 'clkevt' has incomplete type
     struct clock_event_device clkevt;
                               ^~~~~~
   In file included from include/linux/clk.h:16:0,
                    from drivers//clocksource/timer-sun5i.c:13:
   drivers//clocksource/timer-sun5i.c: In function 'sun5i_clkevt_shutdown':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:108:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:108:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c: In function 'sun5i_clkevt_set_oneshot':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:116:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:116:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c: In function 'sun5i_clkevt_set_periodic':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:125:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:125:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c: In function 'sun5i_clkevt_next_event':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:136:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'ce')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers//clocksource/timer-sun5i.c:64:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clkevt, clkevt)
     ^~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:136:34: note: in expansion of macro 'to_sun5i_timer_clkevt'
     struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
                                     ^~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c: In function 'sun5i_clksrc_read':
>> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers//clocksource/timer-sun5i.c:56:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clksrc, clksrc)
     ^~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:157:34: note: in expansion of macro 'to_sun5i_timer_clksrc'
     struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
                                     ^~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: note: (near initialization for 'cs')
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
   drivers//clocksource/timer-sun5i.c:56:2: note: in expansion of macro 'container_of'
     container_of(x, struct sun5i_timer_clksrc, clksrc)
     ^~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:157:34: note: in expansion of macro 'to_sun5i_timer_clksrc'
     struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
                                     ^~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c: In function 'sun5i_rate_cb_clksrc':
   drivers//clocksource/timer-sun5i.c:171:3: error: implicit declaration of function 'clocksource_unregister' [-Werror=implicit-function-declaration]
      clocksource_unregister(&cs->clksrc);
      ^~~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:175:3: error: implicit declaration of function 'clocksource_register_hz' [-Werror=implicit-function-declaration]
      clocksource_register_hz(&cs->clksrc, ndata->new_rate);
      ^~~~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c: In function 'sun5i_setup_clocksource':
   drivers//clocksource/timer-sun5i.c:223:20: error: implicit declaration of function 'CLOCKSOURCE_MASK' [-Werror=implicit-function-declaration]
     cs->clksrc.mask = CLOCKSOURCE_MASK(32);
                       ^~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:224:21: error: 'CLOCK_SOURCE_IS_CONTINUOUS' undeclared (first use in this function)
     cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:224:21: note: each undeclared identifier is reported only once for each function it appears in
   drivers//clocksource/timer-sun5i.c: In function 'sun5i_rate_cb_clkevt':
   drivers//clocksource/timer-sun5i.c:251:3: error: implicit declaration of function 'clockevents_update_freq' [-Werror=implicit-function-declaration]
      clockevents_update_freq(&ce->clkevt, ndata->new_rate);
      ^~~~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c: In function 'sun5i_setup_clockevent':
   drivers//clocksource/timer-sun5i.c:291:24: error: 'CLOCK_EVT_FEAT_PERIODIC' undeclared (first use in this function)
     ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
                           ^~~~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:291:50: error: 'CLOCK_EVT_FEAT_ONESHOT' undeclared (first use in this function)
     ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
                                                     ^~~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:305:2: error: implicit declaration of function 'clockevents_config_and_register' [-Werror=implicit-function-declaration]
     clockevents_config_and_register(&ce->clkevt, rate,
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c: At top level:
   drivers//clocksource/timer-sun5i.c:361:35: error: expected ')' before string constant
    CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer",
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:363:35: error: expected ')' before string constant
    CLOCKSOURCE_OF_DECLARE(sun7i_a20, "allwinner,sun7i-a20-hstimer",
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers//clocksource/timer-sun5i.c:326:19: warning: 'sun5i_timer_init' defined but not used [-Wunused-function]
    static int __init sun5i_timer_init(struct device_node *node)
                      ^~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors
..

vim +/clksrc +52 drivers/clocksource/timer-sun5i.c

4a59058f Maxime Ripard   2015-03-31   46  
3071efa4 Maxime Ripard   2015-03-31   47  #define to_sun5i_timer(x) \
3071efa4 Maxime Ripard   2015-03-31   48  	container_of(x, struct sun5i_timer, clk_rate_cb)
3071efa4 Maxime Ripard   2015-03-31   49  
4a59058f Maxime Ripard   2015-03-31   50  struct sun5i_timer_clksrc {
4a59058f Maxime Ripard   2015-03-31   51  	struct sun5i_timer	timer;
4a59058f Maxime Ripard   2015-03-31  @52  	struct clocksource	clksrc;
4a59058f Maxime Ripard   2015-03-31   53  };
4a59058f Maxime Ripard   2015-03-31   54  
4a59058f Maxime Ripard   2015-03-31   55  #define to_sun5i_timer_clksrc(x) \
4a59058f Maxime Ripard   2015-03-31  @56  	container_of(x, struct sun5i_timer_clksrc, clksrc)
4a59058f Maxime Ripard   2015-03-31   57  
4a59058f Maxime Ripard   2015-03-31   58  struct sun5i_timer_clkevt {
4a59058f Maxime Ripard   2015-03-31   59  	struct sun5i_timer		timer;
4a59058f Maxime Ripard   2015-03-31  @60  	struct clock_event_device	clkevt;
4a59058f Maxime Ripard   2015-03-31   61  };
4a59058f Maxime Ripard   2015-03-31   62  
4a59058f Maxime Ripard   2015-03-31   63  #define to_sun5i_timer_clkevt(x) \
4a59058f Maxime Ripard   2015-03-31   64  	container_of(x, struct sun5i_timer_clkevt, clkevt)
67905540 Maxime Ripard   2013-11-07   65  
67905540 Maxime Ripard   2013-11-07   66  /*
67905540 Maxime Ripard   2013-11-07   67   * When we disable a timer, we need to wait at least for 2 cycles of
67905540 Maxime Ripard   2013-11-07   68   * the timer source clock. We will use for that the clocksource timer
67905540 Maxime Ripard   2013-11-07   69   * that is already setup and runs at the same frequency than the other
67905540 Maxime Ripard   2013-11-07   70   * timers, and we never will be disabled.
67905540 Maxime Ripard   2013-11-07   71   */
4a59058f Maxime Ripard   2015-03-31   72  static void sun5i_clkevt_sync(struct sun5i_timer_clkevt *ce)
67905540 Maxime Ripard   2013-11-07   73  {
4a59058f Maxime Ripard   2015-03-31   74  	u32 old = readl(ce->timer.base + TIMER_CNTVAL_LO_REG(1));
67905540 Maxime Ripard   2013-11-07   75  
4a59058f Maxime Ripard   2015-03-31   76  	while ((old - readl(ce->timer.base + TIMER_CNTVAL_LO_REG(1))) < TIMER_SYNC_TICKS)
67905540 Maxime Ripard   2013-11-07   77  		cpu_relax();
67905540 Maxime Ripard   2013-11-07   78  }
67905540 Maxime Ripard   2013-11-07   79  
4a59058f Maxime Ripard   2015-03-31   80  static void sun5i_clkevt_time_stop(struct sun5i_timer_clkevt *ce, u8 timer)
67905540 Maxime Ripard   2013-11-07   81  {
4a59058f Maxime Ripard   2015-03-31   82  	u32 val = readl(ce->timer.base + TIMER_CTL_REG(timer));
4a59058f Maxime Ripard   2015-03-31   83  	writel(val & ~TIMER_CTL_ENABLE, ce->timer.base + TIMER_CTL_REG(timer));
67905540 Maxime Ripard   2013-11-07   84  
4a59058f Maxime Ripard   2015-03-31   85  	sun5i_clkevt_sync(ce);
67905540 Maxime Ripard   2013-11-07   86  }
67905540 Maxime Ripard   2013-11-07   87  
4a59058f Maxime Ripard   2015-03-31   88  static void sun5i_clkevt_time_setup(struct sun5i_timer_clkevt *ce, u8 timer, u32 delay)
67905540 Maxime Ripard   2013-11-07   89  {
4a59058f Maxime Ripard   2015-03-31   90  	writel(delay, ce->timer.base + TIMER_INTVAL_LO_REG(timer));
67905540 Maxime Ripard   2013-11-07   91  }
67905540 Maxime Ripard   2013-11-07   92  
4a59058f Maxime Ripard   2015-03-31   93  static void sun5i_clkevt_time_start(struct sun5i_timer_clkevt *ce, u8 timer, bool periodic)
67905540 Maxime Ripard   2013-11-07   94  {
4a59058f Maxime Ripard   2015-03-31   95  	u32 val = readl(ce->timer.base + TIMER_CTL_REG(timer));
67905540 Maxime Ripard   2013-11-07   96  
67905540 Maxime Ripard   2013-11-07   97  	if (periodic)
67905540 Maxime Ripard   2013-11-07   98  		val &= ~TIMER_CTL_ONESHOT;
67905540 Maxime Ripard   2013-11-07   99  	else
67905540 Maxime Ripard   2013-11-07  100  		val |= TIMER_CTL_ONESHOT;
67905540 Maxime Ripard   2013-11-07  101  
67905540 Maxime Ripard   2013-11-07  102  	writel(val | TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
4a59058f Maxime Ripard   2015-03-31  103  	       ce->timer.base + TIMER_CTL_REG(timer));
67905540 Maxime Ripard   2013-11-07  104  }
67905540 Maxime Ripard   2013-11-07  105  
7486f5ad Viresh Kumar    2015-06-18  106  static int sun5i_clkevt_shutdown(struct clock_event_device *clkevt)
67905540 Maxime Ripard   2013-11-07  107  {
4a59058f Maxime Ripard   2015-03-31  108  	struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
4a59058f Maxime Ripard   2015-03-31  109  
4a59058f Maxime Ripard   2015-03-31  110  	sun5i_clkevt_time_stop(ce, 0);
7486f5ad Viresh Kumar    2015-06-18  111  	return 0;
7486f5ad Viresh Kumar    2015-06-18  112  }
7486f5ad Viresh Kumar    2015-06-18  113  
7486f5ad Viresh Kumar    2015-06-18  114  static int sun5i_clkevt_set_oneshot(struct clock_event_device *clkevt)
7486f5ad Viresh Kumar    2015-06-18  115  {
7486f5ad Viresh Kumar    2015-06-18  116  	struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
7486f5ad Viresh Kumar    2015-06-18  117  
4a59058f Maxime Ripard   2015-03-31  118  	sun5i_clkevt_time_stop(ce, 0);
4a59058f Maxime Ripard   2015-03-31  119  	sun5i_clkevt_time_start(ce, 0, false);
7486f5ad Viresh Kumar    2015-06-18  120  	return 0;
67905540 Maxime Ripard   2013-11-07  121  }
7486f5ad Viresh Kumar    2015-06-18  122  
7486f5ad Viresh Kumar    2015-06-18  123  static int sun5i_clkevt_set_periodic(struct clock_event_device *clkevt)
7486f5ad Viresh Kumar    2015-06-18  124  {
7486f5ad Viresh Kumar    2015-06-18  125  	struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
7486f5ad Viresh Kumar    2015-06-18  126  
7486f5ad Viresh Kumar    2015-06-18  127  	sun5i_clkevt_time_stop(ce, 0);
7486f5ad Viresh Kumar    2015-06-18  128  	sun5i_clkevt_time_setup(ce, 0, ce->timer.ticks_per_jiffy);
7486f5ad Viresh Kumar    2015-06-18  129  	sun5i_clkevt_time_start(ce, 0, true);
7486f5ad Viresh Kumar    2015-06-18  130  	return 0;
67905540 Maxime Ripard   2013-11-07  131  }
67905540 Maxime Ripard   2013-11-07  132  
67905540 Maxime Ripard   2013-11-07  133  static int sun5i_clkevt_next_event(unsigned long evt,
4a59058f Maxime Ripard   2015-03-31  134  				   struct clock_event_device *clkevt)
67905540 Maxime Ripard   2013-11-07  135  {
4a59058f Maxime Ripard   2015-03-31  136  	struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
4a59058f Maxime Ripard   2015-03-31  137  
4a59058f Maxime Ripard   2015-03-31  138  	sun5i_clkevt_time_stop(ce, 0);
4a59058f Maxime Ripard   2015-03-31  139  	sun5i_clkevt_time_setup(ce, 0, evt - TIMER_SYNC_TICKS);
4a59058f Maxime Ripard   2015-03-31  140  	sun5i_clkevt_time_start(ce, 0, false);
67905540 Maxime Ripard   2013-11-07  141  
67905540 Maxime Ripard   2013-11-07  142  	return 0;
67905540 Maxime Ripard   2013-11-07  143  }
67905540 Maxime Ripard   2013-11-07  144  
67905540 Maxime Ripard   2013-11-07  145  static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
67905540 Maxime Ripard   2013-11-07  146  {
4a59058f Maxime Ripard   2015-03-31  147  	struct sun5i_timer_clkevt *ce = (struct sun5i_timer_clkevt *)dev_id;
67905540 Maxime Ripard   2013-11-07  148  
4a59058f Maxime Ripard   2015-03-31  149  	writel(0x1, ce->timer.base + TIMER_IRQ_ST_REG);
4a59058f Maxime Ripard   2015-03-31  150  	ce->clkevt.event_handler(&ce->clkevt);
67905540 Maxime Ripard   2013-11-07  151  
67905540 Maxime Ripard   2013-11-07  152  	return IRQ_HANDLED;
67905540 Maxime Ripard   2013-11-07  153  }
67905540 Maxime Ripard   2013-11-07  154  
a5a1d1c2 Thomas Gleixner 2016-12-21  155  static u64 sun5i_clksrc_read(struct clocksource *clksrc)
59387683 Chen-Yu Tsai    2016-10-18  156  {
59387683 Chen-Yu Tsai    2016-10-18 @157  	struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
59387683 Chen-Yu Tsai    2016-10-18  158  
59387683 Chen-Yu Tsai    2016-10-18  159  	return ~readl(cs->timer.base + TIMER_CNTVAL_LO_REG(1));
59387683 Chen-Yu Tsai    2016-10-18  160  }
59387683 Chen-Yu Tsai    2016-10-18  161  
3071efa4 Maxime Ripard   2015-03-31  162  static int sun5i_rate_cb_clksrc(struct notifier_block *nb,
3071efa4 Maxime Ripard   2015-03-31  163  				unsigned long event, void *data)
3071efa4 Maxime Ripard   2015-03-31  164  {
3071efa4 Maxime Ripard   2015-03-31  165  	struct clk_notifier_data *ndata = data;
3071efa4 Maxime Ripard   2015-03-31  166  	struct sun5i_timer *timer = to_sun5i_timer(nb);
3071efa4 Maxime Ripard   2015-03-31  167  	struct sun5i_timer_clksrc *cs = container_of(timer, struct sun5i_timer_clksrc, timer);
3071efa4 Maxime Ripard   2015-03-31  168  
3071efa4 Maxime Ripard   2015-03-31  169  	switch (event) {
3071efa4 Maxime Ripard   2015-03-31  170  	case PRE_RATE_CHANGE:
3071efa4 Maxime Ripard   2015-03-31 @171  		clocksource_unregister(&cs->clksrc);
3071efa4 Maxime Ripard   2015-03-31  172  		break;
3071efa4 Maxime Ripard   2015-03-31  173  
3071efa4 Maxime Ripard   2015-03-31  174  	case POST_RATE_CHANGE:
3071efa4 Maxime Ripard   2015-03-31 @175  		clocksource_register_hz(&cs->clksrc, ndata->new_rate);
3071efa4 Maxime Ripard   2015-03-31  176  		break;
3071efa4 Maxime Ripard   2015-03-31  177  
3071efa4 Maxime Ripard   2015-03-31  178  	default:
3071efa4 Maxime Ripard   2015-03-31  179  		break;
3071efa4 Maxime Ripard   2015-03-31  180  	}
3071efa4 Maxime Ripard   2015-03-31  181  
3071efa4 Maxime Ripard   2015-03-31  182  	return NOTIFY_DONE;
3071efa4 Maxime Ripard   2015-03-31  183  }
3071efa4 Maxime Ripard   2015-03-31  184  
4a59058f Maxime Ripard   2015-03-31  185  static int __init sun5i_setup_clocksource(struct device_node *node,
4a59058f Maxime Ripard   2015-03-31  186  					  void __iomem *base,
4a59058f Maxime Ripard   2015-03-31  187  					  struct clk *clk, int irq)
4a59058f Maxime Ripard   2015-03-31  188  {
4a59058f Maxime Ripard   2015-03-31  189  	struct sun5i_timer_clksrc *cs;
4a59058f Maxime Ripard   2015-03-31  190  	unsigned long rate;
4a59058f Maxime Ripard   2015-03-31  191  	int ret;
4a59058f Maxime Ripard   2015-03-31  192  
4a59058f Maxime Ripard   2015-03-31  193  	cs = kzalloc(sizeof(*cs), GFP_KERNEL);
4a59058f Maxime Ripard   2015-03-31  194  	if (!cs)
4a59058f Maxime Ripard   2015-03-31  195  		return -ENOMEM;
4a59058f Maxime Ripard   2015-03-31  196  
4a59058f Maxime Ripard   2015-03-31  197  	ret = clk_prepare_enable(clk);
4a59058f Maxime Ripard   2015-03-31  198  	if (ret) {
4a59058f Maxime Ripard   2015-03-31  199  		pr_err("Couldn't enable parent clock\n");
4a59058f Maxime Ripard   2015-03-31  200  		goto err_free;
4a59058f Maxime Ripard   2015-03-31  201  	}
4a59058f Maxime Ripard   2015-03-31  202  
4a59058f Maxime Ripard   2015-03-31  203  	rate = clk_get_rate(clk);
4a59058f Maxime Ripard   2015-03-31  204  
4a59058f Maxime Ripard   2015-03-31  205  	cs->timer.base = base;
4a59058f Maxime Ripard   2015-03-31  206  	cs->timer.clk = clk;
3071efa4 Maxime Ripard   2015-03-31  207  	cs->timer.clk_rate_cb.notifier_call = sun5i_rate_cb_clksrc;
3071efa4 Maxime Ripard   2015-03-31  208  	cs->timer.clk_rate_cb.next = NULL;
3071efa4 Maxime Ripard   2015-03-31  209  
3071efa4 Maxime Ripard   2015-03-31  210  	ret = clk_notifier_register(clk, &cs->timer.clk_rate_cb);
3071efa4 Maxime Ripard   2015-03-31  211  	if (ret) {
3071efa4 Maxime Ripard   2015-03-31  212  		pr_err("Unable to register clock notifier.\n");
3071efa4 Maxime Ripard   2015-03-31  213  		goto err_disable_clk;
3071efa4 Maxime Ripard   2015-03-31  214  	}
4a59058f Maxime Ripard   2015-03-31  215  
4a59058f Maxime Ripard   2015-03-31  216  	writel(~0, base + TIMER_INTVAL_LO_REG(1));
4a59058f Maxime Ripard   2015-03-31  217  	writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
4a59058f Maxime Ripard   2015-03-31  218  	       base + TIMER_CTL_REG(1));
4a59058f Maxime Ripard   2015-03-31  219  
59387683 Chen-Yu Tsai    2016-10-18  220  	cs->clksrc.name = node->name;
59387683 Chen-Yu Tsai    2016-10-18  221  	cs->clksrc.rating = 340;
59387683 Chen-Yu Tsai    2016-10-18  222  	cs->clksrc.read = sun5i_clksrc_read;
59387683 Chen-Yu Tsai    2016-10-18 @223  	cs->clksrc.mask = CLOCKSOURCE_MASK(32);
59387683 Chen-Yu Tsai    2016-10-18 @224  	cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
59387683 Chen-Yu Tsai    2016-10-18  225  
59387683 Chen-Yu Tsai    2016-10-18  226  	ret = clocksource_register_hz(&cs->clksrc, rate);
4a59058f Maxime Ripard   2015-03-31  227  	if (ret) {
4a59058f Maxime Ripard   2015-03-31  228  		pr_err("Couldn't register clock source.\n");
3071efa4 Maxime Ripard   2015-03-31  229  		goto err_remove_notifier;
4a59058f Maxime Ripard   2015-03-31  230  	}
4a59058f Maxime Ripard   2015-03-31  231  
4a59058f Maxime Ripard   2015-03-31  232  	return 0;
4a59058f Maxime Ripard   2015-03-31  233  
3071efa4 Maxime Ripard   2015-03-31  234  err_remove_notifier:
3071efa4 Maxime Ripard   2015-03-31  235  	clk_notifier_unregister(clk, &cs->timer.clk_rate_cb);
4a59058f Maxime Ripard   2015-03-31  236  err_disable_clk:
4a59058f Maxime Ripard   2015-03-31  237  	clk_disable_unprepare(clk);
4a59058f Maxime Ripard   2015-03-31  238  err_free:
4a59058f Maxime Ripard   2015-03-31  239  	kfree(cs);
4a59058f Maxime Ripard   2015-03-31  240  	return ret;
4a59058f Maxime Ripard   2015-03-31  241  }
4a59058f Maxime Ripard   2015-03-31  242  
3071efa4 Maxime Ripard   2015-03-31  243  static int sun5i_rate_cb_clkevt(struct notifier_block *nb,
3071efa4 Maxime Ripard   2015-03-31  244  				unsigned long event, void *data)
3071efa4 Maxime Ripard   2015-03-31  245  {
3071efa4 Maxime Ripard   2015-03-31  246  	struct clk_notifier_data *ndata = data;
3071efa4 Maxime Ripard   2015-03-31  247  	struct sun5i_timer *timer = to_sun5i_timer(nb);
3071efa4 Maxime Ripard   2015-03-31  248  	struct sun5i_timer_clkevt *ce = container_of(timer, struct sun5i_timer_clkevt, timer);
3071efa4 Maxime Ripard   2015-03-31  249  
3071efa4 Maxime Ripard   2015-03-31  250  	if (event == POST_RATE_CHANGE) {
3071efa4 Maxime Ripard   2015-03-31 @251  		clockevents_update_freq(&ce->clkevt, ndata->new_rate);
3071efa4 Maxime Ripard   2015-03-31  252  		ce->timer.ticks_per_jiffy = DIV_ROUND_UP(ndata->new_rate, HZ);
3071efa4 Maxime Ripard   2015-03-31  253  	}
3071efa4 Maxime Ripard   2015-03-31  254  

:::::: The code at line 52 was first introduced by commit
:::::: 4a59058f0b09682200c04b1db236b4a3b92128d7 clocksource/drivers/sun5i: Refactor the current code

:::::: TO: Maxime Ripard <maxime.ripard@free-electrons.com>
:::::: CC: Ingo Molnar <mingo@kernel.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 47639 bytes --]

^ permalink raw reply

* Possible crashing bug in bluez 5.44
From: Cysioland @ 2017-04-01  9:15 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <bbe1720b-5d67-2257-1be1-d1051790dbc4@cysioland.pl>

Hello,

I've encountered a possible bug when trying to connect my Bluetooth
headset via A2DP. Pairing is fine, but when it tries to connect the
bluetoothd segfaults, with the following stacktrace:

#0 0x0000000000469d60 n/a (bluetoothd)
#1 0x00000000004472d3 n/a (bluetoothd)
#2 0x000000000047a31d n/a (bluetoothd)
#3 0x0000000000447405 n/a (bluetoothd)
#4 0x00007f8ac61cf45a g_main_context_dispatch (libglib-2.0.so.0)
#5 0x00007f8ac61cf810 n/a (libglib-2.0.so.0)
#6 0x00007f8ac61cfb32 g_main_loop_run (libglib-2.0.so.0)
#7 0x000000000040b6b2 n/a (bluetoothd)
#8 0x00007f8ac57a5511 __libc_start_main (libc.so.6)
#9 0x000000000040bf0a n/a (bluetoothd)

I've installed bluez via Arch Linux packages, and after downgrading to
5.43 the bug no longer appears. I recall seeing lots of work done
between these two on A2DP, so I suspect a regression there.

Relevant Arch bug, where they told me to hit here:
https://bugs.archlinux.org/task/53442

Should I report it to your Bugzilla? Do you need any more info or help?

-- 
Yours Faithfully,
Cysioland
https://cysioland.pl

^ permalink raw reply

* [PATCH v2] core: replace sizeof(filename) with PATH_MAX
From: Konrad Zapalowicz @ 2017-03-31 14:44 UTC (permalink / raw)
  To: marcel; +Cc: luiz.von.dentz, linux-bluetooth, Konrad Zapałowicz
In-Reply-To: <1490958237-9299-1-git-send-email-bergo.torino@gmail.com>

From: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>

This commit replaces sizeof(filename) with PATH_MAX to match the common
scheme which is used in other places.
---
 src/adapter.c     | 2 +-
 src/shared/util.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 3dac7d6..3935460 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -7107,7 +7107,7 @@ static void store_csrk(struct btd_adapter *adapter, const bdaddr_t *peer,
 
 	ba2str(peer, device_addr);
 
-	snprintf(filename, sizeof(filename), STORAGEDIR "/%s/%s/info",
+	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
 					adapter_dir(adapter), device_addr);
 
 	key_file = g_key_file_new();
diff --git a/src/shared/util.c b/src/shared/util.c
index 7878552..4b59fad 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -117,7 +117,7 @@ unsigned char util_get_dt(const char *parent, const char *name)
 	char filename[PATH_MAX];
 	struct stat st;
 
-	snprintf(filename, sizeof(filename), "%s/%s", parent, name);
+	snprintf(filename, PATH_MAX, "%s/%s", parent, name);
 	if (lstat(filename, &st) == 0 && S_ISDIR(st.st_mode))
 		return DT_DIR;
 
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH] core: replace sizeof(filename) with PATH_MAX
From: Konrad Zapalowicz @ 2017-03-31 14:15 UTC (permalink / raw)
  To: Von Dentz, Luiz
  Cc: Bastien Nocera, Marcel Holtmann, linux-bluetooth@vger.kernel.org
In-Reply-To: <CACumGOK1ZvY87+Y-XKLRVPN_JGGvpJMcaOHQ0tCWdXyGh4Nb1A@mail.gmail.com>

On 03/31, Von Dentz, Luiz wrote:
> Hi Konrad,
> 
> On Fri, Mar 31, 2017 at 2:32 PM, Konrad Zapalowicz
> <konrad.zapalowicz@canonical.com> wrote:
> > On 03/31, Bastien Nocera wrote:
> >> On Fri, 2017-03-31 at 13:03 +0200, Konrad Zapalowicz wrote:
> >> > From: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>
> >> >
> >> > This commit replaces sizeof(filename) with PATH_MAX to match the
> >> > common
> >> > scheme which is used in other places.
> >>
> >> I wonder why g_strdup_printf() isn't used instead. Would allow ignoring
> >> PATH_MAX.
> >
> > I guess it is because it is easier. With g_strdup_printf() one would
> > have to take care about freeing memory. This is not a case with having
> > filename as an atomatic variable.
> 
> Patch looks fine, but we don't use Signed-off-by in userspace tree

Ok, will resend.

Thanks,
K

^ permalink raw reply

* Re: [PATCH] core: replace sizeof(filename) with PATH_MAX
From: Von Dentz, Luiz @ 2017-03-31 14:00 UTC (permalink / raw)
  To: Konrad Zapalowicz
  Cc: Bastien Nocera, Marcel Holtmann, linux-bluetooth@vger.kernel.org
In-Reply-To: <20170331113218.GA28779@annapurna>

Hi Konrad,

On Fri, Mar 31, 2017 at 2:32 PM, Konrad Zapalowicz
<konrad.zapalowicz@canonical.com> wrote:
> On 03/31, Bastien Nocera wrote:
>> On Fri, 2017-03-31 at 13:03 +0200, Konrad Zapalowicz wrote:
>> > From: Konrad Zapa=C5=82owicz <konrad.zapalowicz@canonical.com>
>> >
>> > This commit replaces sizeof(filename) with PATH_MAX to match the
>> > common
>> > scheme which is used in other places.
>>
>> I wonder why g_strdup_printf() isn't used instead. Would allow ignoring
>> PATH_MAX.
>
> I guess it is because it is easier. With g_strdup_printf() one would
> have to take care about freeing memory. This is not a case with having
> filename as an atomatic variable.

Patch looks fine, but we don't use Signed-off-by in userspace tree.

^ permalink raw reply

* [PATCH BlueZ] build: Make btmgmt tools installable
From: Luiz Augusto von Dentz @ 2017-03-31 13:58 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 Makefile.tools | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Makefile.tools b/Makefile.tools
index 55d392e..73b2eef 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -348,7 +348,9 @@ EXTRA_DIST += tools/hid2hci.1
 endif
 
 if READLINE
-noinst_PROGRAMS += tools/btmgmt tools/obex-client-tool tools/obex-server-tool \
+bin_PROGRAMS += tools/btmgmt
+
+noinst_PROGRAMS += tools/obex-client-tool tools/obex-server-tool \
 			tools/bluetooth-player tools/obexctl
 
 tools_obex_client_tool_SOURCES = $(gobex_sources) $(btio_sources) \
-- 
2.9.3


^ permalink raw reply related

* Re: [PATCHv3 00/10] Nokia H4+ support
From: Greg Kroah-Hartman @ 2017-03-31 13:33 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Rob Herring, Sebastian Reichel, Gustavo F. Padovan, Johan Hedberg,
	Samuel Thibault, Pavel Machek, Tony Lindgren, Jiri Slaby,
	Mark Rutland, open list:BLUETOOTH DRIVERS,
	linux-serial@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, David S. Miller
In-Reply-To: <C1A408F2-1DF8-4F49-B399-B936542DE6BC@holtmann.org>

On Wed, Mar 29, 2017 at 11:33:26PM +0200, Marcel Holtmann wrote:
> Hi Rob,
> 
> >> Here is PATCHv3 for the Nokia bluetooth patchset. I addressed all comments from
> >> Rob and Pavel regarding the serdev patches and dropped the *.dts patches, since
> >> they were queued by Tony. I also changed the patch order, so that the serdev
> >> patches come first. All of them have Acked-by from Rob, so I think it makes
> >> sense to merge them to serdev subsystem (now) and provide an immutable branch
> >> for the bluetooth subsystem.
> > 
> > Greg doesn't read cover letters generally and since the serdev patches
> > are Cc rather than To him, he's probably not planning to pick them up.
> 
> I wonder actually if we should merge all of these via bluetooth-next
> tree with proper Ack from Greg. However it would be good to also get
> buy in from Dave for merging this ultimately through net-next.

I don't really care where it goes.  I can take the whole thing in my
tty/serial tree now if no one objects and I get an ack from the relevant
maintainers {hint...}

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH] core: replace sizeof(filename) with PATH_MAX
From: Konrad Zapalowicz @ 2017-03-31 11:32 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: marcel, luiz.von.dentz, linux-bluetooth
In-Reply-To: <1490959289.13868.12.camel@hadess.net>

On 03/31, Bastien Nocera wrote:
> On Fri, 2017-03-31 at 13:03 +0200, Konrad Zapalowicz wrote:
> > From: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>
> > 
> > This commit replaces sizeof(filename) with PATH_MAX to match the
> > common
> > scheme which is used in other places.
> 
> I wonder why g_strdup_printf() isn't used instead. Would allow ignoring
> PATH_MAX.

I guess it is because it is easier. With g_strdup_printf() one would
have to take care about freeing memory. This is not a case with having
filename as an atomatic variable.

^ permalink raw reply

* Re: [PATCH] core: replace sizeof(filename) with PATH_MAX
From: Bastien Nocera @ 2017-03-31 11:21 UTC (permalink / raw)
  To: Konrad Zapalowicz, marcel; +Cc: luiz.von.dentz, linux-bluetooth
In-Reply-To: <1490958237-9299-1-git-send-email-bergo.torino@gmail.com>

On Fri, 2017-03-31 at 13:03 +0200, Konrad Zapalowicz wrote:
> From: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>
> 
> This commit replaces sizeof(filename) with PATH_MAX to match the
> common
> scheme which is used in other places.

I wonder why g_strdup_printf() isn't used instead. Would allow ignoring
PATH_MAX.

^ permalink raw reply

* [PATCH] core: replace sizeof(filename) with PATH_MAX
From: Konrad Zapalowicz @ 2017-03-31 11:03 UTC (permalink / raw)
  To: marcel; +Cc: luiz.von.dentz, linux-bluetooth, Konrad Zapałowicz

From: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>

This commit replaces sizeof(filename) with PATH_MAX to match the common
scheme which is used in other places.

Signed-off-by: Konrad Zapałowicz <konrad.zapalowicz@canonical.com>
---
 src/adapter.c     | 2 +-
 src/shared/util.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 3dac7d6..3935460 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -7107,7 +7107,7 @@ static void store_csrk(struct btd_adapter *adapter, const bdaddr_t *peer,
 
 	ba2str(peer, device_addr);
 
-	snprintf(filename, sizeof(filename), STORAGEDIR "/%s/%s/info",
+	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
 					adapter_dir(adapter), device_addr);
 
 	key_file = g_key_file_new();
diff --git a/src/shared/util.c b/src/shared/util.c
index 7878552..4b59fad 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -117,7 +117,7 @@ unsigned char util_get_dt(const char *parent, const char *name)
 	char filename[PATH_MAX];
 	struct stat st;
 
-	snprintf(filename, sizeof(filename), "%s/%s", parent, name);
+	snprintf(filename, PATH_MAX, "%s/%s", parent, name);
 	if (lstat(filename, &st) == 0 && S_ISDIR(st.st_mode))
 		return DT_DIR;
 
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH v3 1/2] Bluetooth: btmrvl: disable platform wakeup interrupt in suspend failure path
From: Marcel Holtmann @ 2017-03-31 10:11 UTC (permalink / raw)
  To: Xinming Hu; +Cc: Linux Bluetooth, Amitkumar Karwar, Cathy Luo
In-Reply-To: <1490941952-9048-1-git-send-email-huxm@marvell.com>

Hi Xinming,

> Host sleep handshake with device might been fail, disable platform wakeup
> interrupt in this case.
> 
> Reported-by: Guenter Roeck <groeck@chromium.org>
> Signed-off-by: Xinming Hu <huxm@marvell.com>
> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
> ---
> v2: same as v1
> v3: use Reported-by (Guenter)
> ---
> drivers/bluetooth/btmrvl_sdio.c | 7 +++++++
> 1 file changed, 7 insertions(+)

both patches have been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH] bluetooth: 6lowpan: fix delay work init in add_peer_chan()
From: Marcel Holtmann @ 2017-03-31 10:10 UTC (permalink / raw)
  To: Michael Scott
  Cc: Gustavo F. Padovan, Johan Hedberg, David S. Miller,
	Jukka Rissanen, linux-bluetooth, linux-wpan, netdev, linux-kernel
In-Reply-To: <20170329061054.4300-1-michael.scott@linaro.org>

Hi Michael,

> When adding 6lowpan devices very rapidly we sometimes see a crash:
> [23122.306615] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 4.9.0-43-arm64 #1 Debian 4.9.9.linaro.43-1
> [23122.315400] Hardware name: HiKey Development Board (DT)
> [23122.320623] task: ffff800075443080 task.stack: ffff800075484000
> [23122.326551] PC is at expire_timers+0x70/0x150
> [23122.330907] LR is at run_timer_softirq+0xa0/0x1a0
> [23122.335616] pc : [<ffff000008142dd8>] lr : [<ffff000008142f58>] pstate: 600001c5
> 
> This was due to add_peer_chan() unconditionally initializing the
> lowpan_btle_dev->notify_peers delayed work structure, even if the
> lowpan_btle_dev passed into add_peer_chan() had previously been
> initialized.
> 
> Normally, this would go unnoticed as the delayed work timer is set for
> 100 msec, however when calling add_peer_chan() faster than 100 msec it
> clears out a previously queued delay work causing the crash above.
> 
> To fix this, let add_peer_chan() know when a new lowpan_btle_dev is passed
> in so that it only performs the delay work initialization when needed.
> 
> Signed-off-by: Michael Scott <michael.scott@linaro.org>
> ---
> net/bluetooth/6lowpan.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel

^ permalink raw reply

* Re: [PATCH] bluetooth: 6lowpan: fix use after free in chan_suspend/resume
From: Marcel Holtmann @ 2017-03-31 10:10 UTC (permalink / raw)
  To: Michael Scott
  Cc: Gustavo F. Padovan, Johan Hedberg, David S. Miller,
	Jukka Rissanen, linux-bluetooth, linux-wpan, netdev, linux-kernel
In-Reply-To: <20170329061018.4243-1-michael.scott@linaro.org>

Hi Michael,

> A status field in the skb_cb struct was storing a channel status
> based on channel suspend/resume events.  This stored status was
> then used to return EAGAIN if there were packet sending issues
> in snd_pkt().
> 
> The issue is that the skb has been freed by the time the callback
> to 6lowpan's suspend/resume was called.  So, this generates a
> "use after free" issue that was noticed while running kernel tests
> with KASAN debug enabled.
> 
> Let's eliminate the status field entirely as we can use the channel
> tx_credits to indicate whether we should return EAGAIN when handling
> packets.
> 
> Signed-off-by: Michael Scott <michael.scott@linaro.org>
> ---
> net/bluetooth/6lowpan.c | 21 +++------------------
> 1 file changed, 3 insertions(+), 18 deletions(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel

^ permalink raw reply

* Re: [PATCH] bluetooth: 6lowpan: fix delay work init in add_peer_chan()
From: Jukka Rissanen @ 2017-03-31  9:37 UTC (permalink / raw)
  To: Michael Scott, Marcel Holtmann, Gustavo Padovan, Johan Hedberg
  Cc: David S . Miller, linux-bluetooth, linux-wpan, netdev,
	linux-kernel
In-Reply-To: <20170329061054.4300-1-michael.scott@linaro.org>

Hi Michael,

On Tue, 2017-03-28 at 23:10 -0700, Michael Scott wrote:
> When adding 6lowpan devices very rapidly we sometimes see a crash:
> [23122.306615] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 4.9.0-43-
> arm64 #1 Debian 4.9.9.linaro.43-1
> [23122.315400] Hardware name: HiKey Development Board (DT)
> [23122.320623] task: ffff800075443080 task.stack: ffff800075484000
> [23122.326551] PC is at expire_timers+0x70/0x150
> [23122.330907] LR is at run_timer_softirq+0xa0/0x1a0
> [23122.335616] pc : [<ffff000008142dd8>] lr : [<ffff000008142f58>]
> pstate: 600001c5
> 
> This was due to add_peer_chan() unconditionally initializing the
> lowpan_btle_dev->notify_peers delayed work structure, even if the
> lowpan_btle_dev passed into add_peer_chan() had previously been
> initialized.
> 
> Normally, this would go unnoticed as the delayed work timer is set
> for
> 100 msec, however when calling add_peer_chan() faster than 100 msec
> it
> clears out a previously queued delay work causing the crash above.
> 
> To fix this, let add_peer_chan() know when a new lowpan_btle_dev is
> passed
> in so that it only performs the delay work initialization when
> needed.
> 
> Signed-off-by: Michael Scott <michael.scott@linaro.org>
> ---
>  net/bluetooth/6lowpan.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index e27be3ca0a0c..c282482edc2c 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -754,7 +754,8 @@ static void set_ip_addr_bits(u8 addr_type, u8
> *addr)
>  }
>  
>  static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
> -					struct lowpan_btle_dev *dev)
> +					struct lowpan_btle_dev *dev,
> +					bool new_netdev)
>  {
>  	struct lowpan_peer *peer;
>  
> @@ -785,7 +786,8 @@ static struct l2cap_chan *add_peer_chan(struct
> l2cap_chan *chan,
>  	spin_unlock(&devices_lock);
>  
>  	/* Notifying peers about us needs to be done without locks
> held */
> -	INIT_DELAYED_WORK(&dev->notify_peers, do_notify_peers);
> +	if (new_netdev)
> +		INIT_DELAYED_WORK(&dev->notify_peers,
> do_notify_peers);
>  	schedule_delayed_work(&dev->notify_peers,
> msecs_to_jiffies(100));
>  
>  	return peer->chan;
> @@ -842,6 +844,7 @@ static int setup_netdev(struct l2cap_chan *chan,
> struct lowpan_btle_dev **dev)
>  static inline void chan_ready_cb(struct l2cap_chan *chan)
>  {
>  	struct lowpan_btle_dev *dev;
> +	bool new_netdev = false;
>  
>  	dev = lookup_dev(chan->conn);
>  
> @@ -852,12 +855,13 @@ static inline void chan_ready_cb(struct
> l2cap_chan *chan)
>  			l2cap_chan_del(chan, -ENOENT);
>  			return;
>  		}
> +		new_netdev = true;
>  	}
>  
>  	if (!try_module_get(THIS_MODULE))
>  		return;
>  
> -	add_peer_chan(chan, dev);
> +	add_peer_chan(chan, dev, new_netdev);
>  	ifup(dev->netdev);
>  }
>  

Good catch!

Acked-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>


Cheers,
Jukka

^ permalink raw reply

* Re: [PATCH] bluetooth: 6lowpan: fix use after free in chan_suspend/resume
From: Jukka Rissanen @ 2017-03-31  9:35 UTC (permalink / raw)
  To: Michael Scott, Marcel Holtmann, Gustavo Padovan, Johan Hedberg,
	Luiz Augusto von Dentz
  Cc: David S . Miller, linux-bluetooth, linux-wpan, netdev,
	linux-kernel
In-Reply-To: <20170329061018.4243-1-michael.scott@linaro.org>

Hi Michael,

On Tue, 2017-03-28 at 23:10 -0700, Michael Scott wrote:
> A status field in the skb_cb struct was storing a channel status
> based on channel suspend/resume events.  This stored status was
> then used to return EAGAIN if there were packet sending issues
> in snd_pkt().
> 
> The issue is that the skb has been freed by the time the callback
> to 6lowpan's suspend/resume was called.  So, this generates a
> "use after free" issue that was noticed while running kernel tests
> with KASAN debug enabled.
> 
> Let's eliminate the status field entirely as we can use the channel
> tx_credits to indicate whether we should return EAGAIN when handling
> packets.
> 
> Signed-off-by: Michael Scott <michael.scott@linaro.org>
> ---
>  net/bluetooth/6lowpan.c | 21 +++------------------
>  1 file changed, 3 insertions(+), 18 deletions(-)
> 
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index d491529332f4..e27be3ca0a0c 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -38,7 +38,6 @@ struct skb_cb {
>  	struct in6_addr addr;
>  	struct in6_addr gw;
>  	struct l2cap_chan *chan;
> -	int status;
>  };
>  #define lowpan_cb(skb) ((struct skb_cb *)((skb)->cb))
>  
> @@ -528,7 +527,7 @@ static int send_pkt(struct l2cap_chan *chan,
> struct sk_buff *skb,
>  	}
>  
>  	if (!err)
> -		err = lowpan_cb(skb)->status;
> +		err = (!chan->tx_credits ? -EAGAIN : 0);
>  
>  	if (err < 0) {
>  		if (err == -EAGAIN)
> @@ -964,26 +963,12 @@ static struct sk_buff *chan_alloc_skb_cb(struct
> l2cap_chan *chan,
>  
>  static void chan_suspend_cb(struct l2cap_chan *chan)
>  {
> -	struct sk_buff *skb = chan->data;
> -
> -	BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
> -
> -	if (!skb)
> -		return;
> -
> -	lowpan_cb(skb)->status = -EAGAIN;
> +	BT_DBG("chan %p suspend", chan);
>  }
>  
>  static void chan_resume_cb(struct l2cap_chan *chan)
>  {
> -	struct sk_buff *skb = chan->data;
> -
> -	BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
> -
> -	if (!skb)
> -		return;
> -
> -	lowpan_cb(skb)->status = 0;
> +	BT_DBG("chan %p resume", chan);
>  }
>  
>  static long chan_get_sndtimeo_cb(struct l2cap_chan *chan)

Good catch! If we can avoid using the status variable, that is very
good. We could probably also remove the resume and suspend callbacks as
they are now empty functions (unless we need the debug info for
something).

Acked-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>


Cheers,
Jukka

^ permalink raw reply

* Re: [PATCH] bluetooth: 6lowpan: fix use after free in chan_suspend/resume
From: Luiz Augusto von Dentz @ 2017-03-31  8:33 UTC (permalink / raw)
  To: Michael Scott
  Cc: Marcel Holtmann, Gustavo Padovan, Johan Hedberg, David S . Miller,
	Jukka Rissanen, linux-bluetooth@vger.kernel.org, linux-wpan,
	open list:NETWORKING [GENERAL], Linux Kernel Mailing List
In-Reply-To: <20170329061018.4243-1-michael.scott@linaro.org>

Hi Michael,

On Wed, Mar 29, 2017 at 9:10 AM, Michael Scott <michael.scott@linaro.org> wrote:
> A status field in the skb_cb struct was storing a channel status
> based on channel suspend/resume events.  This stored status was
> then used to return EAGAIN if there were packet sending issues
> in snd_pkt().
>
> The issue is that the skb has been freed by the time the callback
> to 6lowpan's suspend/resume was called.  So, this generates a
> "use after free" issue that was noticed while running kernel tests
> with KASAN debug enabled.
>
> Let's eliminate the status field entirely as we can use the channel
> tx_credits to indicate whether we should return EAGAIN when handling
> packets.
>
> Signed-off-by: Michael Scott <michael.scott@linaro.org>
> ---
>  net/bluetooth/6lowpan.c | 21 +++------------------
>  1 file changed, 3 insertions(+), 18 deletions(-)
>
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index d491529332f4..e27be3ca0a0c 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -38,7 +38,6 @@ struct skb_cb {
>         struct in6_addr addr;
>         struct in6_addr gw;
>         struct l2cap_chan *chan;
> -       int status;
>  };
>  #define lowpan_cb(skb) ((struct skb_cb *)((skb)->cb))
>
> @@ -528,7 +527,7 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb,
>         }
>
>         if (!err)
> -               err = lowpan_cb(skb)->status;
> +               err = (!chan->tx_credits ? -EAGAIN : 0);
>
>         if (err < 0) {
>                 if (err == -EAGAIN)
> @@ -964,26 +963,12 @@ static struct sk_buff *chan_alloc_skb_cb(struct l2cap_chan *chan,
>
>  static void chan_suspend_cb(struct l2cap_chan *chan)
>  {
> -       struct sk_buff *skb = chan->data;
> -
> -       BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
> -
> -       if (!skb)
> -               return;
> -
> -       lowpan_cb(skb)->status = -EAGAIN;
> +       BT_DBG("chan %p suspend", chan);
>  }
>
>  static void chan_resume_cb(struct l2cap_chan *chan)
>  {
> -       struct sk_buff *skb = chan->data;
> -
> -       BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
> -
> -       if (!skb)
> -               return;
> -
> -       lowpan_cb(skb)->status = 0;
> +       BT_DBG("chan %p resume", chan);
>  }
>
>  static long chan_get_sndtimeo_cb(struct l2cap_chan *chan)
> --
> 2.11.0

It should be possible to queue the packets on l2cap_chan_send, Im not
sure why we have this suspend logic in the first place so perhaps
Jukka can shed some light here.



-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH v3 2/2] Bluetooth: btmrvl: remove unnecessary wakeup interrupt number sanity check
From: Xinming Hu @ 2017-03-31  6:32 UTC (permalink / raw)
  To: Linux Bluetooth; +Cc: Marcel Holtmann, Amitkumar Karwar, Cathy Luo, Xinming Hu
In-Reply-To: <1490941952-9048-1-git-send-email-huxm@marvell.com>

Sanity check of interrupt number in interrupt handler is unnecessary and
confusion, remove it.

Reported-by: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
v2: fix apply error in v1
v3: use Reported-by (Guenter)
---
 drivers/bluetooth/btmrvl_sdio.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 95e40ec..eb794f0 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -64,11 +64,9 @@ static irqreturn_t btmrvl_wake_irq_bt(int irq, void *priv)
 	struct btmrvl_sdio_card *card = priv;
 	struct btmrvl_plt_wake_cfg *cfg = card->plt_wake_cfg;
 
-	if (cfg->irq_bt >= 0) {
-		pr_info("%s: wake by bt", __func__);
-		cfg->wake_by_bt = true;
-		disable_irq_nosync(irq);
-	}
+	pr_info("%s: wake by bt", __func__);
+	cfg->wake_by_bt = true;
+	disable_irq_nosync(irq);
 
 	pm_wakeup_event(&card->func->dev, 0);
 	pm_system_wakeup();
-- 
1.8.1.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox