* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
From: Christian Borntraeger @ 2017-03-02 19:00 UTC (permalink / raw)
To: Arnd Bergmann
Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
Networking, Linux Kernel Mailing List, linux-media,
linux-wireless, kernel-build-reports, David S . Miller,
Paul McKenney
In-Reply-To: <CAK8P3a082Bi6Vf5gEFLAJtJvUm=7MtddBzcCOqagQyfJPFTu_g@mail.gmail.com>
On 03/02/2017 06:55 PM, Arnd Bergmann wrote:
> On Thu, Mar 2, 2017 at 5:51 PM, Christian Borntraeger
> <borntraeger@de.ibm.com> wrote:
>> On 03/02/2017 05:38 PM, Arnd Bergmann wrote:
>>>
>>> This attempts a rewrite of the two macros, using a simpler implementation
>>> for the most common case of having a naturally aligned 1, 2, 4, or (on
>>> 64-bit architectures) 8 byte object that can be accessed with a single
>>> instruction. For these, we go back to a volatile pointer dereference
>>> that we had with the ACCESS_ONCE macro.
>>
>> We had changed that back then because gcc 4.6 and 4.7 had a bug that could
>> removed the volatile statement on aggregate types like the following one
>>
>> union ipte_control {
>> unsigned long val;
>> struct {
>> unsigned long k : 1;
>> unsigned long kh : 31;
>> unsigned long kg : 32;
>> };
>> };
>>
>> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145
>>
>> If I see that right, your __ALIGNED_WORD(x)
>> macro would say that for above structure sizeof(x) == sizeof(long)) is true,
>> so it would fall back to the old volatile cast and might reintroduce the
>> old compiler bug?
Oh dear, I should double check my sentences in emails before sending...anyway
the full story is referenced in
commit 60815cf2e05057db5b78e398d9734c493560b11e
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/borntraeger/linux
which has a pointer to
http://marc.info/?i=54611D86.4040306%40de.ibm.com
which contains the full story.
>
> Ah, right, that's the missing piece. For some reason I didn't find
> the reference in the source or the git log.
>
>> Could you maybe you fence your simple macro for anything older than 4.9? After
>> all there was no kasan support anyway on these older gcc version.
>
> Yes, that should work, thanks!
^ permalink raw reply
* [PATCH 4.12 V2] brcmfmac: move brcmf_txcomplete function to fwsignal.c
From: Rafał Miłecki @ 2017-03-03 6:38 UTC (permalink / raw)
To: Kalle Valo
Cc: Arend van Spriel, Franky Lin, Hante Meuleman,
Pieter-Paul Giesberts, Franky Lin, linux-wireless,
brcm80211-dev-list.pdl, Rafał Miłecki
In-Reply-To: <20170227124251.30338-1-zajec5@gmail.com>
From: Rafał Miłecki <rafal@milecki.pl>
This function is called by USB and SDIO only, both using BCDC & FW
Signalling. Move it out of core.c to make this file more generic and
allow making fwsignal optional in the future.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
V2: Make code with this patch compile when not based on top of (to be dropped)
[PATCH 4.12] brcmfmac: get rid of brcmf_txflowblock helper function
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 3 ---
.../net/wireless/broadcom/brcm80211/brcmfmac/core.c | 18 ------------------
.../wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 18 ++++++++++++++++++
.../wireless/broadcom/brcm80211/brcmfmac/fwsignal.h | 9 +++++++++
.../net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 ++-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 3 ++-
6 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index 76693df34742..059e40fdc3d5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -232,9 +232,6 @@ void brcmf_dev_reset(struct device *dev);
/* Indication from bus module to change flow-control state */
void brcmf_txflowblock(struct device *dev, bool state);
-/* Notify the bus has transferred the tx packet to firmware */
-void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
-
/* Configure the "global" bus state used by upper layers */
void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 2f2f3a5ad86a..45ed24049b37 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -393,24 +393,6 @@ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
brcmu_pkt_buf_free_skb(txp);
}
-void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
-{
- struct brcmf_bus *bus_if = dev_get_drvdata(dev);
- struct brcmf_pub *drvr = bus_if->drvr;
- struct brcmf_if *ifp;
-
- /* await txstatus signal for firmware if active */
- if (brcmf_fws_fc_active(drvr->fws)) {
- if (!success)
- brcmf_fws_bustxfail(drvr->fws, txp);
- } else {
- if (brcmf_proto_hdrpull(drvr, false, txp, &ifp))
- brcmu_pkt_buf_free_skb(txp);
- else
- brcmf_txfinalize(ifp, txp, success);
- }
-}
-
static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *info)
{
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
index 5f1a5929cb30..07f0b3cfd59c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
@@ -2445,6 +2445,24 @@ bool brcmf_fws_fc_active(struct brcmf_fws_info *fws)
return fws->fcmode != BRCMF_FWS_FCMODE_NONE;
}
+void brcmf_fws_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pub *drvr = bus_if->drvr;
+ struct brcmf_if *ifp;
+
+ /* await txstatus signal for firmware if active */
+ if (brcmf_fws_fc_active(drvr->fws)) {
+ if (!success)
+ brcmf_fws_bustxfail(drvr->fws, txp);
+ } else {
+ if (brcmf_proto_hdrpull(drvr, false, txp, &ifp))
+ brcmu_pkt_buf_free_skb(txp);
+ else
+ brcmf_txfinalize(ifp, txp, success);
+ }
+}
+
void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
{
u32 hslot;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
index 96df66073b2a..d534164785de 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
@@ -18,6 +18,10 @@
#ifndef FWSIGNAL_H_
#define FWSIGNAL_H_
+struct brcmf_fws_info;
+struct brcmf_if;
+struct brcmf_pub;
+
int brcmf_fws_init(struct brcmf_pub *drvr);
void brcmf_fws_deinit(struct brcmf_pub *drvr);
bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws);
@@ -28,6 +32,11 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb);
void brcmf_fws_reset_interface(struct brcmf_if *ifp);
void brcmf_fws_add_interface(struct brcmf_if *ifp);
void brcmf_fws_del_interface(struct brcmf_if *ifp);
+
+/* Notify the bus has transferred the tx packet to firmware */
+void brcmf_fws_txcomplete(struct device *dev, struct sk_buff *txp,
+ bool success);
+
void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb);
void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked);
void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index c5744b45ec8f..22d21643ed8c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -42,6 +42,7 @@
#include "sdio.h"
#include "chip.h"
#include "firmware.h"
+#include "fwsignal.h"
#include "core.h"
#include "common.h"
@@ -2265,7 +2266,7 @@ static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
bus->tx_seq = (bus->tx_seq + pktq->qlen) % SDPCM_SEQ_WRAP;
skb_queue_walk_safe(pktq, pkt_next, tmp) {
__skb_unlink(pkt_next, pktq);
- brcmf_txcomplete(bus->sdiodev->dev, pkt_next, ret == 0);
+ brcmf_fws_txcomplete(bus->sdiodev->dev, pkt_next, ret == 0);
}
return ret;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index d93ebbdc7737..676c28081dc5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -26,6 +26,7 @@
#include "bus.h"
#include "debug.h"
#include "firmware.h"
+#include "fwsignal.h"
#include "usb.h"
#include "core.h"
#include "common.h"
@@ -482,7 +483,7 @@ static void brcmf_usb_tx_complete(struct urb *urb)
req->skb);
brcmf_usb_del_fromq(devinfo, req);
- brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
+ brcmf_fws_txcomplete(devinfo->dev, req->skb, urb->status == 0);
req->skb = NULL;
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
--
2.11.0
^ permalink raw reply related
* Re: Hostapd de-auth connected clients
From: ravin goyal @ 2017-03-03 5:02 UTC (permalink / raw)
To: Arend Van Spriel; +Cc: Jouni Malinen, wpa_supplicant, linux-wireless
In-Reply-To: <04d7fcd5-52eb-760d-a74b-c93756321c9e@broadcom.com>
Hi, I think I need to mention the hardware specification
I was first trying on banana pi m2+ which has WLAN chip AP6212(ampak)
here is the link to it: http://linux-sunxi.org/Wifi#Ampak
I tried both raspbian and debian jessie on it both distros has
wireless driver bcmhd linked to the wifi chip.
Both these distros has flaws in its wireless driver when it comes to
run hostapd on it.
Then I tired on orange pi zero running debian jessie and its wifi
chipset is XR819 and wlan driver is xradio_wlan
http://linux-sunxi.org/Wifi#Allwinner
This driver seems to be working fine with hostapd so far.
I hope the confusion is clear now.
Regards,
Ravin
On 2 March 2017 at 18:07, Arend Van Spriel <arend.vanspriel@broadcom.com> wrote:
> + linux-wireless
>
> On 2-3-2017 10:28, ravin goyal wrote:
>> Hi Arend
>>
>> Thanks, I will certainly try with brcmfmac if you say so.
>> Currently I am testing hostapd on orange pi zero board running debian
>> jessie and its wlan driver is xradio_wlan and it is working fine.
>> I don't know why raspbian and debian have introduced bcmdhd for WLAN
>> in their distros.
>> I have filed bug on raspbian but received on response yet.
>
> Now it gets confusing. From what I found xradio_wlan is for some
> Allwinner flavor based on ST/Ericsson chipset with sdio id 0020:2281.
> That would not be a device that bcmdhd would try to bind to.
>
> Regards,
> Arend
>
>> Regards
>> Ravin
>>
>> On 1 March 2017 at 18:59, Arend Van Spriel <arend.vanspriel@broadcom.com> wrote:
>>> On 28-2-2017 23:28, Jouni Malinen wrote:
>>>> On Tue, Feb 28, 2017 at 04:06:48PM +0530, ravin goyal wrote:
>>>>> I am sharing link to recent debug log related to de-auth messages in
>>>>> hostapd, I hope it might help to figure out what's really happening
>>>>> and to know whether it is due to driver or hostapd.
>>>>>
>>>>> Please take a look at this.
>>>>>
>>>>> link to log file: https://clbin.com/0flGD
>>>>
>>>> It looks like number of the disconnections in the two logs are triggered
>>>> by station inactivity check:
>>>>
>>>> 1488275056.529235: wlan0: Station 00:73:8d:43:87:2e has been inactive too long: 308 sec, max allowed: 300
>>>> 1488275056.529389: Polling STA
>>>> 1488275056.529457: nl80211: send_mlme - da= 00:73:8d:43:87:2e noack=0 freq=0 no_cck=0 offchanok=0 wait_time=0 fc=0x248 (WLAN_FC_STYPE_NULLFUNC) nlmode=3
>>>> 1488275056.529574: nl80211: Use bss->freq=2442
>>>> 1488275056.529634: nl80211: CMD_FRAME freq=2442 wait=0 no_cck=0 no_ack=0 offchanok=0
>>>> 1488275056.529711: CMD_FRAME - hexdump(len=24): 48 02 00 00 00 73 8d 43 87 2e 02 1a 11 f5 47 06 02 1a 11 f5 47 06 00 00
>>>> 1488275056.530129: nl80211: Frame command failed: ret=-22 (Invalid argument) (freq=2442 wait=0)
>>>> 1488275056.530231: nl80211_send_null_frame: Failed to send poll frame
>>>> 1488275056.530295: ap_handle_timer: register ap_handle_timer timeout for 00:73:8d:43:87:2e (1 seconds - AP_DISASSOC_DELAY)
>>>>
>>>>
>>>> This code should not have been triggered at all if the driver reported
>>>> activity in the expected way, so I'm assuming the driver does not
>>>> support that.. And then it does not support sending out the poll frame
>>>> to check whether the STA is still there.
>>>>
>>>> You might be able to work around this by setting a significantly larger
>>>> ap_max_inactivity value in hostapd.conf, but for a proper fix, someone
>>>> more familiar with the particular driver would need to take a look at
>>>> what's happening and why the driver does not indicate station activity.
>>>
>>> I would suggest trying brcmfmac instead of bcmdhd. The bcmdhd is
>>> specifically for Android and verification is done on Android targets.
>>> Not saying your problems will be gone, but at least you can ask me for help.
>>>
>>> Regards,
>>> Arend
^ permalink raw reply
* [PATCH 4.12 2/2] bcma: fill core OF info independently of bus type
From: Rafał Miłecki @ 2017-03-03 10:34 UTC (permalink / raw)
To: Kalle Valo, linux-wireless; +Cc: Hauke Mehrtens, Rafał Miłecki
In-Reply-To: <20170303103415.5188-1-zajec5@gmail.com>
From: Rafał Miłecki <rafal@milecki.pl>
PCI devices can be described in DT as well so we should always execute
relevant code. This will make bcma e.g. set of_node for cores described
in DT.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
drivers/bcma/main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 4f88821c1b2a..2da7fe1d20a7 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -243,6 +243,8 @@ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
core->dev.bus = &bcma_bus_type;
dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index);
core->dev.parent = bcma_bus_get_host_dev(bus);
+ if (core->dev.parent)
+ bcma_of_fill_device(core->dev.parent, core);
switch (bus->hosttype) {
case BCMA_HOSTTYPE_PCI:
@@ -252,8 +254,6 @@ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
case BCMA_HOSTTYPE_SOC:
if (IS_ENABLED(CONFIG_OF) && bus->host_pdev) {
core->dma_dev = &bus->host_pdev->dev;
- if (core->dev.parent)
- bcma_of_fill_device(core->dev.parent, core);
} else {
core->dev.dma_mask = &core->dev.coherent_dma_mask;
core->dma_dev = &core->dev;
--
2.11.0
^ permalink raw reply related
* [PATCH 4.12 1/2] bcma: use helper function to set core dev's parent
From: Rafał Miłecki @ 2017-03-03 10:34 UTC (permalink / raw)
To: Kalle Valo, linux-wireless; +Cc: Hauke Mehrtens, Rafał Miłecki
From: Rafał Miłecki <rafal@milecki.pl>
A tiny code deduplication thanks to the bcma_bus_get_host_dev.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
drivers/bcma/main.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 12da68ec48ba..4f88821c1b2a 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -242,17 +242,16 @@ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
core->dev.release = bcma_release_core_dev;
core->dev.bus = &bcma_bus_type;
dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index);
+ core->dev.parent = bcma_bus_get_host_dev(bus);
switch (bus->hosttype) {
case BCMA_HOSTTYPE_PCI:
- core->dev.parent = &bus->host_pci->dev;
core->dma_dev = &bus->host_pci->dev;
core->irq = bus->host_pci->irq;
break;
case BCMA_HOSTTYPE_SOC:
if (IS_ENABLED(CONFIG_OF) && bus->host_pdev) {
core->dma_dev = &bus->host_pdev->dev;
- core->dev.parent = &bus->host_pdev->dev;
if (core->dev.parent)
bcma_of_fill_device(core->dev.parent, core);
} else {
--
2.11.0
^ permalink raw reply related
* [PATCH 4.12] bcma: drop unneeded check for CONFIG_OF_IRQ
From: Rafał Miłecki @ 2017-03-03 10:33 UTC (permalink / raw)
To: Kalle Valo, linux-wireless
Cc: Hauke Mehrtens, Rafał Miłecki, Arnd Bergmann
From: Rafał Miłecki <rafal@milecki.pl>
We already have the same check in bcma_of_get_irq which really calls
symbols available with CONFIG_OF_IRQ only. It appears this duplicated
check was accidentally added in commit c58d900cc96a ("bcma: fix building
without OF_IRQ"). The rest of code in bcma_of_fill_device should work
fine without CONFIG_OF_IRQ.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Cc: Arnd Bergmann <arnd@arndb.de>
---
drivers/bcma/main.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 2da7fe1d20a7..e6986c7608f1 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -201,9 +201,6 @@ static void bcma_of_fill_device(struct device *parent,
{
struct device_node *node;
- if (!IS_ENABLED(CONFIG_OF_IRQ))
- return;
-
node = bcma_of_find_child_device(parent, core);
if (node)
core->dev.of_node = node;
--
2.11.0
^ permalink raw reply related
* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
From: Arnd Bergmann @ 2017-03-03 9:54 UTC (permalink / raw)
To: Christian Borntraeger
Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
Networking, Linux Kernel Mailing List, linux-media,
linux-wireless, kernel-build-reports, David S . Miller,
Paul McKenney
In-Reply-To: <f86cf852-3960-0dcf-5917-509080ca7bf5@de.ibm.com>
On Fri, Mar 3, 2017 at 9:26 AM, Christian Borntraeger
<borntraeger@de.ibm.com> wrote:
> On 03/02/2017 10:45 PM, Arnd Bergmann wrote:
>> Ok, got it. So I guess the behavior of forcing aligned accesses on aligned
>> data is accidental, and allowing non-power-of-two arguments is also not
>> the main purpose.
>
>
> Right. The main purpose is to read/write _ONCE_. You can assume a somewhat
> atomic access for sizes <= word size. And there are certainly places that
> rely on that. But the *ONCE thing is mostly used for things where we used
> barrier() 10 years ago.
Ok
>
> Maybe we could just bail out on new compilers if we get
>> either of those? That might catch code that accidentally does something
>> that is inherently non-atomic or that causes a trap when the intention was
>> to have a simple atomic access.
>
> I think Linus stated that its ok to assume that the compiler is smart enough
> to uses a single instruction to access aligned and properly sized scalar types
> for *ONCE.
>
> Back then when I changed ACCESS_ONCE there were many places that did use it
> for non-atomic, > word size accesses. For example on some architectures a pmd_t
> is a typedef to an array, for which there is no way to read that atomically.
> So the focus must be on the "ONCE" part.
>
> If some code uses a properly aligned, word sized object we can also assume
> atomic access. If the access is not properly sized/aligned we do not get
> atomicity, but we do get the "ONCE".
> But adding a check for alignment/size would break the compilation of some
> code.
So what should be the expected behavior for objects that have a smaller
alignment? E.g. this structure
struct fourbytes {
char bytes[4];
} __packed;
when passed into the current READ_ONCE() will be accessed with
a 32-bit load, while reading it with
struct fourbytes local = *(volatile struct fourbytes *)voidpointer;
on architectures like ARMv5 or lower will turn into four single-byte
reads to avoid an alignment trap when the pointer is actually
unaligned.
I can see arguments for and against either behavior, but what should
I do when modifying it for newer compilers? The possible options
that I see are
- keep assuming that the pointer will be aligned at runtime
and doesn't trap
- use the regular gcc behavior and do byte-accesses on those
architectures that otherwise might trap
- add a runtime alignment check to do atomic accesses whenever
possible, but never trap
- fail the build
Arnd
^ permalink raw reply
* [RFCv2 0/2] Add new transmit data path for ethernet frame format
From: mpubbise @ 2017-03-03 11:33 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Manikanta Pubbisetty
From: Manikanta Pubbisetty <mpubbise@qti.qualcomm.com>
This patch set adds a new transmit data path to offload 802.11 header
encap to driver/hardware. Drivers having support for ieee80211
header encap and other offload functionalities which can't be done
before encap can make use of this new data path. Currently it is
implemented for STA and AP interface type, this can be extend other
interface types like adhoc.
This patchset only adds support for tx in ethernet frame format
and receive can happen in 802.11 format with existing rx framework.
With ath10k driver changes using this new Tx/Rx path, 10 - 15%
CPU usage and upto ~20Mbps TCP performance improvements are
observed with this ethernet data path.
Vasanthakumar Thiagarajan (2):
mac80211: Add provision for 802.11 encap offload
mac80211: Implement data xmit for 802.11 encap offload
V2:
* 802.11 decap offload is removed from the patchset
* Code changes as per review comments of v1.
include/net/mac80211.h | 30 ++++++-
net/mac80211/cfg.c | 9 ++
net/mac80211/debugfs.c | 1 +
net/mac80211/ieee80211_i.h | 10 +++
net/mac80211/iface.c | 72 +++++++++++++++
net/mac80211/key.c | 3 +
net/mac80211/status.c | 79 +++++++++++++++++
net/mac80211/tx.c | 207 +++++++++++++++++++++++++++++++++++++++++++-
8 files changed, 406 insertions(+), 5 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [RFCv2 2/2] mac80211: Implement data xmit for 802.11 encap offload
From: mpubbise @ 2017-03-03 11:33 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Vasanthakumar Thiagarajan
In-Reply-To: <1488540807-27415-1-git-send-email-mpubbise@qti.qualcomm.com>
From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
Driver (or hw) supporting 802.11 encapsulation offload
for data frames can make use of this new xmit path.
This patch defines new ndo_ops, all these callbacks are same as
ieee80211_dataif_ops other than ndo_start_xmit() which does
minimal processing leaving 802.11 encap related to driver.
This patch makes netdev_ops registration based on the
driver/hardware capability for 802.11 encap offload and interface type.
There is a field, no_80211_encap, added to ieee80211_tx_info:control
to mark if the 802.11 encapsulation is offloaded to driver.
There is also a new callback for tx completion status indication
to handle data frames using 802.11 encap offload.
Currently ath10k fw is capable of doing 802.11 encapsulation offload
and with the corresponding driver changes, 802.11 encap offload
might improve performance.
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
Signed-off-by: Manikanta Pubbisetty <mpubbise@qti.qualcomm.com>
---
include/net/mac80211.h | 26 +++++-
net/mac80211/cfg.c | 9 ++
net/mac80211/ieee80211_i.h | 11 +++
net/mac80211/iface.c | 72 +++++++++++++++
net/mac80211/key.c | 3 +
net/mac80211/status.c | 82 ++++++++++++++++++
net/mac80211/tx.c | 207 +++++++++++++++++++++++++++++++++++++++++++-
7 files changed, 405 insertions(+), 5 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 0239b7d..b9e74b3 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -921,7 +921,12 @@ struct ieee80211_tx_info {
};
struct ieee80211_key_conf *hw_key;
u32 flags;
- /* 4 bytes free */
+ /* XXX: This frame is not encapsulated with 802.11
+ * header. Should this be added to %IEEE80211_TX_CTRL_*
+ * flags?.
+ */
+ bool no_80211_encap;
+ /* 3 bytes free */
} control;
struct {
u64 cookie;
@@ -4265,6 +4270,25 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
struct sk_buff *skb);
/**
+ * ieee80211_tx_status_8023 - transmit status callback for 802.3 frame format
+ *
+ * Call this function for all transmitted data frames after their transmit
+ * completion. This callback should only be called for data frames which
+ * are are using driver's (or hardware's) offload capability of encap/decap
+ * 802.11 frames.
+ *
+ * This function may not be called in IRQ context. Calls to this function
+ * for a single hardware must be synchronized against each other.
+ *
+ * @hw: the hardware the frame was transmitted by
+ * @vif: the interface for which the frame was transmitted
+ * @skb: the frame that was transmitted, owned by mac80211 after this call
+ */
+void ieee80211_tx_status_8023(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct sk_buff *skb);
+
+/**
* ieee80211_report_low_ack - report non-responding station
*
* When operating in AP-mode, call this function to report a non-responding
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9c7490c..e1c6f3e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -129,6 +129,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
}
}
+ if (!ieee80211_sdata_running(sdata))
+ ieee80211_if_check_80211_encap_offl(sdata);
+
return 0;
}
@@ -2273,6 +2276,12 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
ieee80211_check_fast_xmit_all(local);
+ if (ieee80211_iface_uses_80211_encap_offl(local))
+ return -EINVAL;
+
+ if (!local->ops->set_frag_threshold)
+ return -EINVAL;
+
err = drv_set_frag_threshold(local, wiphy->frag_threshold);
if (err) {
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 0e71843..1618806 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -966,6 +966,8 @@ struct ieee80211_sub_if_data {
} debugfs;
#endif
+ bool data_80211_encap_offloaded;
+
/* must be last, dynamically sized area in this! */
struct ieee80211_vif vif;
};
@@ -1696,6 +1698,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
struct vif_params *params);
int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
enum nl80211_iftype type);
+void ieee80211_if_check_80211_encap_offl(struct ieee80211_sub_if_data *sdata);
+bool ieee80211_iface_uses_80211_encap_offl(struct ieee80211_local *local);
void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
void ieee80211_remove_interfaces(struct ieee80211_local *local);
u32 ieee80211_idle_off(struct ieee80211_local *local);
@@ -1723,6 +1727,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
struct net_device *dev);
netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev);
+netdev_tx_t ieee80211_subif_8023_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev,
u32 info_flags);
@@ -1877,6 +1883,11 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, int tid,
enum nl80211_band band);
+/* sta_out needs to be checked for ERR_PTR() before using */
+int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb,
+ struct sta_info **sta_out);
+
static inline void
ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, int tid,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 40813dd..d8cabfa 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1161,6 +1161,17 @@ static u16 ieee80211_netdev_select_queue(struct net_device *dev,
.ndo_get_stats64 = ieee80211_get_stats64,
};
+static const struct net_device_ops ieee80211_dataif_8023_ops = {
+ .ndo_open = ieee80211_open,
+ .ndo_stop = ieee80211_stop,
+ .ndo_uninit = ieee80211_uninit,
+ .ndo_start_xmit = ieee80211_subif_8023_start_xmit,
+ .ndo_set_rx_mode = ieee80211_set_multicast_list,
+ .ndo_set_mac_address = ieee80211_change_mac,
+ .ndo_select_queue = ieee80211_netdev_select_queue,
+ .ndo_get_stats64 = ieee80211_get_stats64,
+};
+
static u16 ieee80211_monitor_select_queue(struct net_device *dev,
struct sk_buff *skb,
void *accel_priv,
@@ -1194,6 +1205,63 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
.ndo_get_stats64 = ieee80211_get_stats64,
};
+static bool
+ieee80211_if_encap_offl_supported(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+
+ if (!ieee80211_hw_check(&local->hw, SUPPORTS_80211_ENCAP))
+ return false;
+
+ if (local->hw.wiphy->frag_threshold != (u32)-1 &&
+ !local->ops->set_frag_threshold)
+ return false;
+
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_AP:
+ return true;
+ case NL80211_IFTYPE_STATION:
+ if (sdata->u.mgd.use_4addr)
+ return false;
+ return true;
+ case NL80211_IFTYPE_AP_VLAN:
+ if (sdata->wdev.use_4addr)
+ return false;
+ return true;
+ default:
+ return false;
+ }
+}
+
+void ieee80211_if_check_80211_encap_offl(struct ieee80211_sub_if_data *sdata)
+{
+ if (!sdata->dev)
+ return;
+
+ if (!ieee80211_if_encap_offl_supported(sdata))
+ return;
+
+ sdata->dev->netdev_ops = &ieee80211_dataif_8023_ops;
+ sdata->data_80211_encap_offloaded = true;
+}
+
+bool ieee80211_iface_uses_80211_encap_offl(struct ieee80211_local *local)
+{
+ struct ieee80211_sub_if_data *sdata;
+ bool offloaded = false;
+
+ mutex_lock(&local->iflist_mtx);
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ if (sdata->data_80211_encap_offloaded) {
+ offloaded = true;
+ break;
+ }
+ }
+ mutex_unlock(&local->iflist_mtx);
+
+ return offloaded;
+}
+
static void ieee80211_if_free(struct net_device *dev)
{
free_percpu(dev->tstats);
@@ -1425,6 +1493,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
sdata->noack_map = 0;
+ sdata->data_80211_encap_offloaded = false;
+
/* only monitor/p2p-device differ */
if (sdata->dev) {
sdata->dev->netdev_ops = &ieee80211_dataif_ops;
@@ -1907,6 +1977,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
list_add_tail_rcu(&sdata->list, &local->interfaces);
mutex_unlock(&local->iflist_mtx);
+ ieee80211_if_check_80211_encap_offl(sdata);
+
if (new_wdev)
*new_wdev = &sdata->wdev;
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index a98fc2b..960eed1 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -193,6 +193,9 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
key->conf.keyidx,
sta ? sta->sta.addr : bcast_addr, ret);
+ if (sdata->data_80211_encap_offloaded)
+ return -EINVAL;
+
out_unsupported:
switch (key->conf.cipher) {
case WLAN_CIPHER_SUITE_WEP40:
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index a3af6e1..620a826 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -952,6 +952,88 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
}
EXPORT_SYMBOL(ieee80211_tx_status);
+/* TODO: Check the possibility to use ieee80211_tx_status for reporting the tx status
+ * of 802.11 encap offloaded frames.
+ */
+void ieee80211_tx_status_8023(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct sk_buff *skb)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct sta_info *sta;
+ int retry_count;
+ int rates_idx;
+ bool acked;
+
+ if (WARN_ON(!ieee80211_hw_check(hw, SUPPORTS_80211_ENCAP)))
+ goto skip_stats_update;
+
+ sdata = vif_to_sdata(info->control.vif);
+
+ acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
+ rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
+
+ rcu_read_lock();
+
+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) {
+ rcu_read_unlock();
+ goto counters_update;
+ }
+
+ if (!sta || IS_ERR(sta)) {
+ rcu_read_unlock();
+ goto counters_update;
+ }
+
+ if (!acked)
+ sta->status_stats.retry_failed++;
+
+ if (rates_idx != -1)
+ sta->tx_stats.last_rate = info->status.rates[rates_idx];
+
+ sta->status_stats.retry_count += retry_count;
+
+ if (ieee80211_hw_check(hw, REPORTS_TX_ACK_STATUS)) {
+ if (acked && vif->type == NL80211_IFTYPE_STATION)
+ ieee80211_sta_reset_conn_monitor(sdata);
+
+ sta->status_stats.last_ack = jiffies;
+ if (info->flags & IEEE80211_TX_STAT_ACK) {
+ if (sta->status_stats.lost_packets)
+ sta->status_stats.lost_packets = 0;
+
+ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
+ sta->status_stats.last_tdls_pkt_time = jiffies;
+ } else {
+ ieee80211_lost_packet(sta, info);
+ }
+ }
+
+ rcu_read_unlock();
+
+counters_update:
+ ieee80211_led_tx(local);
+
+ if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
+ !(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED))
+ goto skip_stats_update;
+
+ I802_DEBUG_INC(local->dot11TransmittedFrameCount);
+ if (is_multicast_ether_addr(skb->data))
+ I802_DEBUG_INC(local->dot11MulticastTransmittedFrameCount);
+ if (retry_count > 0)
+ I802_DEBUG_INC(local->dot11RetryCount);
+ if (retry_count > 1)
+ I802_DEBUG_INC(local->dot11MultipleRetryCount);
+
+skip_stats_update:
+ ieee80211_report_used_skb(local, skb, false);
+ dev_kfree_skb(skb);
+}
+EXPORT_SYMBOL(ieee80211_tx_status_8023);
+
void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)
{
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ba8d7db..1d7844e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1250,12 +1250,18 @@ static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_txq *txq = NULL;
+ bool is_data;
if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) ||
(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE))
return NULL;
- if (!ieee80211_is_data(hdr->frame_control))
+ if (!info->control.no_80211_encap)
+ is_data = ieee80211_is_data(hdr->frame_control);
+ else
+ is_data = true;
+
+ if (!is_data)
return NULL;
if (sta) {
@@ -1427,6 +1433,7 @@ void ieee80211_txq_purge(struct ieee80211_local *local,
{
struct fq *fq = &local->fq;
struct fq_tin *tin = &txqi->tin;
+ struct ieee80211_tx_info *info;
fq_tin_reset(fq, tin, fq_skb_free_func);
ieee80211_purge_tx_queue(&local->hw, &txqi->frags);
@@ -2262,9 +2269,9 @@ static inline bool ieee80211_is_tdls_setup(struct sk_buff *skb)
skb->data[14] == WLAN_TDLS_SNAP_RFTYPE;
}
-static int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *skb,
- struct sta_info **sta_out)
+int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb,
+ struct sta_info **sta_out)
{
struct sta_info *sta;
@@ -3432,6 +3439,9 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
hdr = (struct ieee80211_hdr *)skb->data;
info = IEEE80211_SKB_CB(skb);
+ if (info->control.no_80211_encap)
+ goto out;
+
memset(&tx, 0, sizeof(tx));
__skb_queue_head_init(&tx.skbs);
tx.local = local;
@@ -3705,6 +3715,185 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
}
+static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, int led_len,
+ struct sta_info *sta,
+ bool txpending)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_tx_control control = {};
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_sta *pubsta = NULL;
+ unsigned long flags;
+ int q = info->hw_queue;
+
+ if (ieee80211_queue_skb(local, sdata, sta, skb))
+ return true;
+
+ spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+
+ if (local->queue_stop_reasons[q] ||
+ (!txpending && !skb_queue_empty(&local->pending[q]))) {
+ if (txpending)
+ skb_queue_head(&local->pending[q], skb);
+ else
+ skb_queue_tail(&local->pending[q], skb);
+
+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+
+ return false;
+ }
+
+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+
+
+ if (sta && sta->uploaded)
+ pubsta = &sta->sta;
+
+ control.sta = pubsta;
+
+ drv_tx(local, &control, skb);
+
+ /* TODO: Update throughput led trigger with the number of tx bytes */
+
+ return true;
+}
+
+static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
+ struct net_device *dev, struct sta_info *sta,
+ struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ethhdr *ehdr = (struct ethhdr *)skb->data;
+ struct ieee80211_local *local = sdata->local;
+ bool authorized = false;
+ bool multicast;
+ bool tdls_peer;
+ unsigned char *ra = NULL;
+
+ if (IS_ERR(sta) || (sta && !sta->uploaded))
+ sta = NULL;
+
+ /* XXX: Add a generic helper for this */
+ if (sdata->vif.type == NL80211_IFTYPE_AP ||
+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
+ sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ ra = ehdr->h_dest;
+
+ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+ tdls_peer = test_sta_flag(sta, WLAN_STA_TDLS_PEER);
+ if (tdls_peer)
+ ra = skb->data;
+ else
+ ra = sdata->u.mgd.bssid;
+ }
+
+ if (!ra)
+ goto out_free;
+
+ multicast = is_multicast_ether_addr(ra);
+
+ if (sta)
+ authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
+
+ /* XXX: Should we add new txrx stats for 802.3 to update stats
+ * like if the frame is dropped due to unathourized port,
+ * just like the ones available in tx_handlers?.
+ */
+
+ if (!multicast && !authorized &&
+ ((ehdr->h_proto != sdata->control_port_protocol) ||
+ !ether_addr_equal(sdata->vif.addr, ehdr->h_source)))
+ goto out_free;
+
+ if (multicast && sdata->vif.type == NL80211_IFTYPE_AP &&
+ !atomic_read(&sdata->u.ap.num_mcast_sta))
+ goto out_free;
+
+ if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) &&
+ test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
+ goto out_free;
+
+ /* TODO: Handle frames requiring wifi tx status to be notified */
+
+ memset(info, 0, sizeof(*info));
+
+ if (unlikely(sdata->control_port_protocol == ehdr->h_proto)) {
+ if (sdata->control_port_no_encrypt)
+ info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+ info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
+ }
+
+ if (multicast)
+ info->flags |= IEEE80211_TX_CTL_NO_ACK;
+
+ info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)];
+
+ ieee80211_tx_stats(dev, skb->len);
+
+ if (sta) {
+ sta->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len;
+ sta->tx_stats.packets[skb_get_queue_mapping(skb)]++;
+ }
+
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ sdata = container_of(sdata->bss,
+ struct ieee80211_sub_if_data, u.ap);
+
+ info->control.no_80211_encap = true;
+
+ info->control.vif = &sdata->vif;
+
+ ieee80211_tx_8023(sdata, skb, skb->len, sta, false);
+
+ return;
+
+out_free:
+ kfree_skb(skb);
+}
+
+netdev_tx_t ieee80211_subif_8023_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct sta_info *sta;
+
+ if (WARN_ON(unlikely(!sdata->data_80211_encap_offloaded))) {
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ if (unlikely(skb->len < ETH_HLEN)) {
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ /* TODO: Extend it for Adhoc interface type */
+ if (WARN_ON(dev->ieee80211_ptr->use_4addr ||
+ (sdata->vif.type != NL80211_IFTYPE_STATION &&
+ sdata->vif.type != NL80211_IFTYPE_AP &&
+ sdata->vif.type != NL80211_IFTYPE_AP_VLAN))) {
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ rcu_read_lock();
+
+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
+ goto out_free;
+
+ ieee80211_8023_xmit(sdata, dev, sta, skb);
+
+ goto out;
+
+ out_free:
+ kfree_skb(skb);
+ out:
+ rcu_read_unlock();
+
+ return NETDEV_TX_OK;
+}
+
struct sk_buff *
ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, u32 info_flags)
@@ -3783,6 +3972,16 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
}
info->band = chanctx_conf->def.chan->band;
result = ieee80211_tx(sdata, NULL, skb, true);
+ } else if (info->control.no_80211_encap) {
+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) {
+ dev_kfree_skb(skb);
+ return true;
+ }
+
+ if (IS_ERR(sta) || (sta && !sta->uploaded))
+ sta = NULL;
+
+ result = ieee80211_tx_8023(sdata, skb, skb->len, sta, true);
} else {
struct sk_buff_head skbs;
--
1.7.9.5
^ permalink raw reply related
* [RFC] cfg80211: Add support for FILS shared key authentication offload
From: Jouni Malinen @ 2017-03-03 11:53 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Kanchanapally, Vidyullatha, Jouni Malinen
From: "Kanchanapally, Vidyullatha" <vkanchan@qti.qualcomm.com>
Enhance nl80211 and cfg80211 connect request and response APIs to
support FILS shared key authentication Offload. The new nl80211
attributes can be used to provide additional information to the driver
to establish a FILS connection. Also enhance the set/del PMKSA to allow
support for adding and deleting PMKSA based on FILS cache identifier.
Add a new feature flag that drivers can use to advertize support for
FILS shared key authentication and association in station mode when
using their own SME.
Signed-off-by: Vidyullatha Kanchanapally <vkanchan@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
include/linux/ieee80211.h | 9 ++++
include/net/cfg80211.h | 115 +++++++++++++++++++++++++++++++++++++++----
include/uapi/linux/nl80211.h | 48 ++++++++++++++++--
net/wireless/core.h | 12 ++++-
net/wireless/mlme.c | 1 +
net/wireless/nl80211.c | 89 ++++++++++++++++++++++++++++++---
net/wireless/nl80211.h | 5 +-
net/wireless/sme.c | 64 ++++++++++++++++++------
net/wireless/util.c | 4 ++
9 files changed, 311 insertions(+), 36 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 22bf067..51e2748 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1723,6 +1723,9 @@ enum ieee80211_statuscode {
WLAN_STATUS_REJECT_DSE_BAND = 96,
WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,
WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,
+ /* 802.11ai */
+ WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108,
+ WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109,
};
@@ -2104,6 +2107,12 @@ enum ieee80211_key_len {
#define FILS_NONCE_LEN 16
#define FILS_MAX_KEK_LEN 64
+#define FILS_ERP_MAX_USERNAME_LEN 16
+#define FILS_ERP_MAX_REALM_LEN 253
+#define FILS_ERP_MAX_RRK_LEN 64
+
+#define PMK_MAX_LEN 48
+
/* Public action codes */
enum ieee80211_pub_actioncode {
WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 86c12f8..a5009d0 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2073,6 +2073,17 @@ struct cfg80211_bss_selection {
* the BSSID of the current association, i.e., to the value that is
* included in the Current AP address field of the Reassociation Request
* frame.
+ * @fils_erp_username: EAP re-authentication protocol (ERP) username part of the
+ * NAI. This is used to refer to the keys used in ERP, i.e., rRK and rIK.
+ * @fils_erp_username_len: Length of @fils_erp_username in octets.
+ * @fils_erp_realm: EAP re-authentication protocol (ERP) realm part of NAI. This
+ * specifies the domain name of ER server.
+ * @fils_erp_realm_len: Length of @fils_erp_realm in octets.
+ * @fils_erp_sequence_num: The start sequence number to be used in the next ERP
+ * message.
+ * @fils_erp_rrk: ERP re-authentication Root Key (rRK) used to derive additional
+ * keys in FILS.
+ * @fils_erp_rrk_len: Length of @fils_erp_rrk in octets.
*/
struct cfg80211_connect_params {
struct ieee80211_channel *channel;
@@ -2098,6 +2109,13 @@ struct cfg80211_connect_params {
bool pbss;
struct cfg80211_bss_selection bss_select;
const u8 *prev_bssid;
+ const u8 *fils_erp_username;
+ size_t fils_erp_username_len;
+ const u8 *fils_erp_realm;
+ size_t fils_erp_realm_len;
+ u16 fils_erp_sequence_num;
+ const u8 *fils_erp_rrk;
+ size_t fils_erp_rrk_len;
};
/**
@@ -2137,11 +2155,24 @@ enum wiphy_params_flags {
* caching.
*
* @bssid: The AP's BSSID.
- * @pmkid: The PMK material itself.
+ * @pmkid: The identifer to refer a PMKSA.
+ * @pmk: The PMK for the PMKSA identified by @pmkid. This is used for key
+ * derivation by a FILS STA. Otherwise, %NULL.
+ * @pmk_len: Length of the @pmk. The length of @pmk can differ depending on
+ * the hash algorithm used to generate this.
+ * @ssid: SSID to specify the ESS within which a PMKSA is valid.
+ * @ssid_len: Length of the @ssid in octets.
+ * @cache_id: Unsigned 16 bit identifier advertized by an AP identifying the
+ * scope of PMKSA. This is valid only if @ssid_len is non-zero.
*/
struct cfg80211_pmksa {
const u8 *bssid;
const u8 *pmkid;
+ const u8 *pmk;
+ size_t pmk_len;
+ const u8 *ssid;
+ size_t ssid_len;
+ u16 cache_id;
};
/**
@@ -5136,6 +5167,60 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
#endif
/**
+ * cfg80211_connect_done - notify cfg80211 of connection result
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the AP
+ * @bss: entry of bss to which STA got connected to, can be obtained
+ * through cfg80211_get_bss (may be %NULL)
+ * @req_ie: association request IEs (maybe be %NULL)
+ * @req_ie_len: association request IEs length
+ * @resp_ie: association response IEs (may be %NULL)
+ * @resp_ie_len: assoc response IEs length
+ * @fils_kek: KEK derived from a successful FILS connection (may be %NULL)
+ * @fils_kek_len: length of @fils_kek
+ * @update_erp_seq_num: Bool value to specify if the value in @fils_erp_seq_num
+ * is valid.
+ * @fils_erp_seq_num: The last used ERP sequence number in FILS Authentication.
+ * This value should be specified irrespective of the status for a FILS
+ * connection.
+ * @pmk: A new PMK if derived from a successful FILS connection (may be %NULL).
+ * @pmk_len: Length of @pmk.
+ * @pmkid: A new PMKID if derived from a successful FILS connection (may be
+ * %NULL).
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful connection, use
+ * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
+ * the real status code for failures. If this call is used to report a
+ * failure due to a timeout (e.g., not receiving an Authentication frame
+ * from the AP) instead of an explicit rejection by the AP, -1 is used to
+ * indicate that this is a failure, but without a status code.
+ * @timeout_reason is used to report the reason for the timeout in that
+ * case.
+ * @gfp: allocation flags
+ * @timeout_reason: reason for connection timeout. This is used when the
+ * connection fails due to a timeout instead of an explicit rejection from
+ * the AP. %NL80211_TIMEOUT_UNSPECIFIED is used when the timeout reason is
+ * not known. This value is used only if @status < 0 to indicate that the
+ * failure is due to a timeout and not due to explicit rejection by the AP.
+ * This value is ignored in other cases (@status >= 0).
+ *
+ * It should be called by the underlying driver once execution of the connection
+ * request from connect() has been completed. This is similar to
+ * cfg80211_connect_bss(), but with additional parameters that a user
+ * space should know to maintain a successful connection in case of FILS. Only
+ * one of the functions among cfg80211_connect_bss(), cfg80211_connect_result()
+ * cfg80211_connect_timeout() and cfg80211_connect_done() should be called.
+ */
+void cfg80211_connect_done(struct net_device *dev, const u8 *bssid,
+ struct cfg80211_bss *bss, const u8 *req_ie,
+ size_t req_ie_len, const u8 *resp_ie,
+ size_t resp_ie_len, const u8 *fils_kek,
+ size_t fils_kek_len, bool update_erp_seq_num,
+ u16 fils_erp_seq_num, const u8 *pmk, size_t pmk_len,
+ const u8 *pmkid, int status, gfp_t gfp,
+ enum nl80211_timeout_reason timeout_reason);
+
+/**
* cfg80211_connect_bss - notify cfg80211 of connection result
*
* @dev: network device
@@ -5165,13 +5250,21 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
* It should be called by the underlying driver once execution of the connection
* request from connect() has been completed. This is similar to
* cfg80211_connect_result(), but with the option of identifying the exact bss
- * entry for the connection. Only one of these functions should be called.
+ * entry for the connection. Only one of the functions among
+ * cfg80211_connect_bss(), cfg80211_connect_result(),
+ * cfg80211_connect_timeout(), and cfg80211_connect_done() should be called.
*/
-void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
- struct cfg80211_bss *bss, const u8 *req_ie,
- size_t req_ie_len, const u8 *resp_ie,
- size_t resp_ie_len, int status, gfp_t gfp,
- enum nl80211_timeout_reason timeout_reason);
+static inline void
+cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
+ struct cfg80211_bss *bss, const u8 *req_ie,
+ size_t req_ie_len, const u8 *resp_ie,
+ size_t resp_ie_len, int status, gfp_t gfp,
+ enum nl80211_timeout_reason timeout_reason)
+{
+ cfg80211_connect_done(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
+ resp_ie_len, NULL, 0, false, 0, NULL, 0, NULL,
+ status, gfp, timeout_reason);
+}
/**
* cfg80211_connect_result - notify cfg80211 of connection result
@@ -5190,7 +5283,9 @@ void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
* It should be called by the underlying driver once execution of the connection
* request from connect() has been completed. This is similar to
* cfg80211_connect_bss() which allows the exact bss entry to be specified. Only
- * one of these functions should be called.
+ * one of the functions among cfg80211_connect_bss(),
+ * cfg80211_connect_result(), cfg80211_connect_timeout(), and
+ * cfg80211_connect_done() should be called.
*/
static inline void
cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
@@ -5217,7 +5312,9 @@ cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
* in a sequence where no explicit authentication/association rejection was
* received from the AP. This could happen, e.g., due to not being able to send
* out the Authentication or Association Request frame or timing out while
- * waiting for the response.
+ * waiting for the response. Only one of the functions among
+ * cfg80211_connect_bss(), cfg80211_connect_result(), cfg80211_connect_timeout()
+ * and cfg80211_connect_done() should be called.
*/
static inline void
cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 9a499b1..08d8988 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -370,10 +370,16 @@
* @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
* NL80211_CMD_GET_SURVEY and on the "scan" multicast group)
*
- * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry, using %NL80211_ATTR_MAC
- * (for the BSSID) and %NL80211_ATTR_PMKID.
+ * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry using %NL80211_ATTR_MAC
+ * (for the BSSID), %NL80211_ATTR_PMKID, and optionally %NL80211_ATTR_PMK
+ * (for PTKSA derivation in case of FILS SK offload) or using
+ * %NL80211_ATTR_SSID, %NL80211_ATTR_FILS_CACHE_ID,
+ * %NL80211_ATTR_PMKID, and %NL80211_ATTR_PMK in case of FILS
+ * authentication.
* @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC
- * (for the BSSID) and %NL80211_ATTR_PMKID.
+ * (for the BSSID) and %NL80211_ATTR_PMKID or using %NL80211_ATTR_SSID,
+ * %NL80211_ATTR_FILS_CACHE_ID, and %NL80211_ATTR_PMKID in case of FILS
+ * authentication.
* @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries.
*
* @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
@@ -2012,6 +2018,31 @@ enum nl80211_commands {
* u32 attribute with an &enum nl80211_timeout_reason value. This is used,
* e.g., with %NL80211_CMD_CONNECT event.
*
+ * @NL80211_ATTR_FILS_ERP_USERNAME: EAP Re-authentication Protocol (ERP)
+ * username part of NAI used to refer keys rRK and rIK. This is used with
+ * %NL80211_CMD_CONNECT.
+ *
+ * @NL80211_ATTR_FILS_ERP_REALM: EAP Re-authentication Protocol (ERP) realm part
+ * of NAI specifying the domain name of the ER server. This is used with
+ * %NL80211_CMD_CONNECT.
+ *
+ * @NL80211_ATTR_FILS_ERP_SEQUENCE_NUM: Unsigned 16-bit ERP sequence number used
+ * for replay protection. This is used in generating the FILS wrapped data
+ * for FILS authentication and is used with %NL80211_CMD_CONNECT.
+ *
+ * @NL80211_ATTR_FILS_ERP_RRK: ERP re-authentication Root Key (rRK) for the
+ * NAI specified by %NL80211_ATTR_FILS_ERP_USERNAME and
+ * %NL80211_ATTR_FILS_ERP_REALM. This is used for generating rIK and rMSK
+ * from successful FILS authentication and is used with
+ * %NL80211_CMD_CONNECT.
+ *
+ * @NL80211_ATTR_FILS_CACHE_ID: Unsigned 16 bit identifier advertized by a FILS
+ * AP identifying the scope of PMKSAs. This is used with
+ * @NL80211_CMD_SET_PMKSA and @NL80211_CMD_DEL_PMKSA.
+ *
+ * @NL80211_ATTR_PMK: PMK for the PMKSA identified by %NL80211_ATTR_PMKID.
+ * This is used with @NL80211_CMD_SET_PMKSA.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2423,6 +2454,14 @@ enum nl80211_attrs {
NL80211_ATTR_TIMEOUT_REASON,
+ NL80211_ATTR_FILS_ERP_USERNAME,
+ NL80211_ATTR_FILS_ERP_REALM,
+ NL80211_ATTR_FILS_ERP_SEQUENCE_NUM,
+ NL80211_ATTR_FILS_ERP_RRK,
+ NL80211_ATTR_FILS_CACHE_ID,
+
+ NL80211_ATTR_PMK,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -4759,6 +4798,8 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_CQM_RSSI_LIST: With this driver the
* %NL80211_ATTR_CQM_RSSI_THOLD attribute accepts a list of zero or more
* RSSI threshold values to monitor rather than exactly one threshold.
+ * @NL80211_EXT_FEATURE_FILS_SK_OFFLOAD: Driver SME supports FILS shared key
+ * authentication with %NL80211_CMD_CONNECT.
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4778,6 +4819,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED,
NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
NL80211_EXT_FEATURE_CQM_RSSI_LIST,
+ NL80211_EXT_FEATURE_FILS_SK_OFFLOAD,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/core.h b/net/wireless/core.h
index efa690a..ee6f6b5 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -227,6 +227,13 @@ struct cfg80211_event {
size_t req_ie_len;
size_t resp_ie_len;
struct cfg80211_bss *bss;
+ const u8 *kek;
+ size_t kek_len;
+ bool update_erp_seq_num;
+ u16 fils_erp_seq_num;
+ const u8 *pmk;
+ size_t pmk_len;
+ const u8 *pmkid;
int status; /* -1 = failed; 0..65535 = status code */
enum nl80211_timeout_reason timeout_reason;
} cr;
@@ -395,7 +402,10 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
const u8 *req_ie, size_t req_ie_len,
const u8 *resp_ie, size_t resp_ie_len,
- int status, bool wextev,
+ const u8 *fils_kek, size_t fils_kek_len,
+ bool update_erp_seq_num, u16 fils_erp_seq_num,
+ const u8 *fils_pmk, size_t fils_pmk_len,
+ const u8 *fils_pmkid, int status, bool wextev,
struct cfg80211_bss *bss,
enum nl80211_timeout_reason timeout_reason);
void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 22b3d99..644527c 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -47,6 +47,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues);
/* update current_bss etc., consumes the bss reference */
__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
+ NULL, 0, false, 0, NULL, 0, NULL,
status_code,
status_code == WLAN_STATUS_SUCCESS, bss,
NL80211_TIMEOUT_UNSPECIFIED);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d516527..d97020a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -410,6 +410,15 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
.len = sizeof(struct nl80211_bss_select_rssi_adjust)
},
[NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
+ [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
+ .len = FILS_ERP_MAX_USERNAME_LEN },
+ [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
+ .len = FILS_ERP_MAX_REALM_LEN },
+ [NL80211_ATTR_FILS_ERP_SEQUENCE_NUM] = { .type = NLA_U16 },
+ [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
+ .len = FILS_ERP_MAX_RRK_LEN },
+ [NL80211_ATTR_FILS_CACHE_ID] = { .type = NLA_U16 },
+ [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
};
/* policy for the key attributes */
@@ -3832,6 +3841,19 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
return false;
return true;
case NL80211_CMD_CONNECT:
+ /* SAE not supported yet */
+ if (auth_type == NL80211_AUTHTYPE_SAE)
+ return false;
+ /* FILS with SK PFS or PK not supported yet */
+ if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
+ auth_type == NL80211_AUTHTYPE_FILS_PK)
+ return false;
+ if (!wiphy_ext_feature_isset(
+ &rdev->wiphy,
+ NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
+ auth_type == NL80211_AUTHTYPE_FILS_SK)
+ return false;
+ return true;
case NL80211_CMD_START_AP:
/* SAE not supported yet */
if (auth_type == NL80211_AUTHTYPE_SAE)
@@ -8874,6 +8896,34 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
}
}
+ if (wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
+ info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
+ info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
+ info->attrs[NL80211_ATTR_FILS_ERP_SEQUENCE_NUM] &&
+ info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
+ connect.fils_erp_username =
+ nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
+ connect.fils_erp_username_len =
+ nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
+ connect.fils_erp_realm =
+ nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
+ connect.fils_erp_realm_len =
+ nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
+ connect.fils_erp_sequence_num =
+ nla_get_u16(
+ info->attrs[NL80211_ATTR_FILS_ERP_SEQUENCE_NUM]);
+ connect.fils_erp_rrk =
+ nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
+ connect.fils_erp_rrk_len =
+ nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
+ } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
+ info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
+ info->attrs[NL80211_ATTR_FILS_ERP_SEQUENCE_NUM] ||
+ info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
+ return -EINVAL;
+ }
+
wdev_lock(dev->ieee80211_ptr);
err = cfg80211_connect(rdev, dev, &connect, connkeys,
@@ -8993,14 +9043,28 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
- if (!info->attrs[NL80211_ATTR_MAC])
- return -EINVAL;
-
if (!info->attrs[NL80211_ATTR_PMKID])
return -EINVAL;
pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
- pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+ if (info->attrs[NL80211_ATTR_MAC]) {
+ pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ } else if (info->attrs[NL80211_ATTR_SSID] &&
+ info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
+ (info->genlhdr->cmd == NL80211_CMD_DEL_PMKSA ||
+ info->attrs[NL80211_ATTR_PMK])) {
+ pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+ pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+ pmksa.cache_id =
+ nla_get_u16(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
+ } else {
+ return -EINVAL;
+ }
+ if (info->attrs[NL80211_ATTR_PMK]) {
+ pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
+ pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
+ }
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
@@ -13415,7 +13479,10 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *bssid,
const u8 *req_ie, size_t req_ie_len,
const u8 *resp_ie, size_t resp_ie_len,
- int status,
+ const u8 *fils_kek, size_t fils_kek_len,
+ bool update_erp_seq_num, u16 fils_erp_seq_num,
+ const u8 *fils_pmk, size_t fils_pmk_len,
+ const u8 *fils_pmkid, int status,
enum nl80211_timeout_reason timeout_reason,
gfp_t gfp)
{
@@ -13444,7 +13511,17 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
(req_ie &&
nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
(resp_ie &&
- nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
+ nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)) ||
+ (update_erp_seq_num &&
+ nla_put_u16(msg, NL80211_ATTR_FILS_ERP_SEQUENCE_NUM,
+ fils_erp_seq_num)) ||
+ (status == WLAN_STATUS_SUCCESS &&
+ ((fils_kek &&
+ nla_put(msg, NL80211_ATTR_FILS_KEK, fils_kek_len, fils_kek)) ||
+ (fils_pmk &&
+ nla_put(msg, NL80211_ATTR_PMK, fils_pmk_len, fils_pmk)) ||
+ (fils_pmkid &&
+ nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, fils_pmkid)))))
goto nla_put_failure;
genlmsg_end(msg, hdr);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index e488dca..354dd44 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -56,7 +56,10 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *bssid,
const u8 *req_ie, size_t req_ie_len,
const u8 *resp_ie, size_t resp_ie_len,
- int status,
+ const u8 *fils_kek, size_t fils_kek_len,
+ bool update_erp_seq_num, u16 fils_erp_seq_num,
+ const u8 *fils_pmk, size_t fils_pmk_len,
+ const u8 *fils_pmkid, int status,
enum nl80211_timeout_reason timeout_reason,
gfp_t gfp);
void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index b347e63..5d5204f 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -255,7 +255,8 @@ void cfg80211_conn_work(struct work_struct *work)
if (cfg80211_conn_do_work(wdev, &treason)) {
__cfg80211_connect_result(
wdev->netdev, bssid,
- NULL, 0, NULL, 0, -1, false, NULL,
+ NULL, 0, NULL, 0, NULL, 0, false, 0,
+ NULL, 0, NULL, -1, false, NULL,
treason);
}
wdev_unlock(wdev);
@@ -360,9 +361,9 @@ void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len)
schedule_work(&rdev->conn_work);
} else if (status_code != WLAN_STATUS_SUCCESS) {
__cfg80211_connect_result(wdev->netdev, mgmt->bssid,
- NULL, 0, NULL, 0,
- status_code, false, NULL,
- NL80211_TIMEOUT_UNSPECIFIED);
+ NULL, 0, NULL, 0, NULL, 0, false, 0,
+ NULL, 0, NULL, status_code, false,
+ NULL, NL80211_TIMEOUT_UNSPECIFIED);
} else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
schedule_work(&rdev->conn_work);
@@ -672,7 +673,10 @@ static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
const u8 *req_ie, size_t req_ie_len,
const u8 *resp_ie, size_t resp_ie_len,
- int status, bool wextev,
+ const u8 *fils_kek, size_t fils_kek_len,
+ bool update_erp_seq_num, u16 fils_erp_seq_num,
+ const u8 *fils_pmk, size_t fils_pmk_len,
+ const u8 *fils_pmkid, int status, bool wextev,
struct cfg80211_bss *bss,
enum nl80211_timeout_reason timeout_reason)
{
@@ -690,10 +694,12 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
return;
}
- nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev,
- bssid, req_ie, req_ie_len,
- resp_ie, resp_ie_len,
- status, timeout_reason, GFP_KERNEL);
+ nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, bssid,
+ req_ie, req_ie_len, resp_ie, resp_ie_len,
+ fils_kek, fils_kek_len, update_erp_seq_num,
+ fils_erp_seq_num, fils_pmk, fils_pmk_len,
+ fils_pmkid, status, timeout_reason,
+ GFP_KERNEL);
#ifdef CONFIG_CFG80211_WEXT
if (wextev) {
@@ -781,11 +787,16 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
}
/* Consumes bss object one way or another */
-void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
- struct cfg80211_bss *bss, const u8 *req_ie,
- size_t req_ie_len, const u8 *resp_ie,
- size_t resp_ie_len, int status, gfp_t gfp,
- enum nl80211_timeout_reason timeout_reason)
+void cfg80211_connect_done(struct net_device *dev,
+ const u8 *bssid, struct cfg80211_bss *bss,
+ const u8 *req_ie, size_t req_ie_len,
+ const u8 *resp_ie, size_t resp_ie_len,
+ const u8 *fils_kek, size_t fils_kek_len,
+ bool update_erp_seq_num, u16 fils_erp_seq_num,
+ const u8 *fils_pmk, size_t fils_pmk_len,
+ const u8 *fils_pmkid,
+ int status, gfp_t gfp,
+ enum nl80211_timeout_reason timeout_reason)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
@@ -802,7 +813,8 @@ void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
}
}
- ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
+ ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len + fils_kek_len +
+ fils_pmk_len + WLAN_PMKID_LEN, gfp);
if (!ev) {
cfg80211_put_bss(wdev->wiphy, bss);
return;
@@ -821,6 +833,26 @@ void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
ev->cr.resp_ie_len = resp_ie_len;
memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
}
+ if (fils_kek_len) {
+ ev->cr.kek = ((u8 *)ev) + sizeof(*ev) + req_ie_len +
+ resp_ie_len;
+ ev->cr.kek_len = fils_kek_len;
+ memcpy((void *)ev->cr.kek, fils_kek, fils_kek_len);
+ }
+ if (fils_pmk_len) {
+ ev->cr.pmk = ((u8 *)ev) + sizeof(*ev) + req_ie_len +
+ resp_ie_len + fils_kek_len;
+ ev->cr.pmk_len = fils_pmk_len;
+ memcpy((void *)ev->cr.pmk, fils_pmk, fils_pmk_len);
+ }
+ if (fils_pmkid) {
+ ev->cr.pmkid = ((u8 *)ev) + sizeof(*ev) + req_ie_len +
+ resp_ie_len + fils_kek_len + fils_pmk_len;
+ memcpy((void *)ev->cr.pmkid, fils_pmkid, WLAN_PMKID_LEN);
+ }
+ ev->cr.update_erp_seq_num = update_erp_seq_num;
+ if (update_erp_seq_num)
+ ev->cr.fils_erp_seq_num = fils_erp_seq_num;
if (bss)
cfg80211_hold_bss(bss_from_pub(bss));
ev->cr.bss = bss;
@@ -832,7 +864,7 @@ void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
spin_unlock_irqrestore(&wdev->event_lock, flags);
queue_work(cfg80211_wq, &rdev->event_work);
}
-EXPORT_SYMBOL(cfg80211_connect_bss);
+EXPORT_SYMBOL(cfg80211_connect_done);
/* Consumes bss object one way or another */
void __cfg80211_roamed(struct wireless_dev *wdev,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 737c9c2..78e004e 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -947,6 +947,10 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
wdev->netdev, bssid,
ev->cr.req_ie, ev->cr.req_ie_len,
ev->cr.resp_ie, ev->cr.resp_ie_len,
+ ev->cr.kek, ev->cr.kek_len,
+ ev->cr.update_erp_seq_num,
+ ev->cr.fils_erp_seq_num,
+ ev->cr.pmk, ev->cr.pmk_len, ev->cr.pmkid,
ev->cr.status,
ev->cr.status == WLAN_STATUS_SUCCESS,
ev->cr.bss, ev->cr.timeout_reason);
--
2.7.4
^ permalink raw reply related
* [RFCv2 1/2] mac80211: Add provision for 802.11 encap offload
From: mpubbise @ 2017-03-03 11:33 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Vasanthakumar Thiagarajan
In-Reply-To: <1488540807-27415-1-git-send-email-mpubbise@qti.qualcomm.com>
From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
Drivers can have the capability to offload 802.11 encap
to firmware or hardware for data frames. This patch adds a new
hw_flag for driver to advertise the offload support.
Transmit path offloading 802.11 header (including cipher headers)
encap for data frames will be implemented in a separate patch.
Drivers advertising this capability should also implement other
functionalities which deal with 802.11 frame format like below
- Hardware encryption
- Aggregation of A-MSDU offload
- Fragmentation offload
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
Signed-off-by: Manikanta Pubbisetty <mpubbise@qti.qualcomm.com>
---
include/net/mac80211.h | 4 ++++
net/mac80211/debugfs.c | 1 +
2 files changed, 5 insertions(+)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 3edb469..0239b7d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2049,6 +2049,9 @@ struct ieee80211_txq {
* The stack will not do fragmentation.
* The callback for @set_frag_threshold should be set as well.
*
+ * @IEEE80211_HW_SUPPORTS_80211_ENCAP: Hardware/driver supports 802.11
+ * encap for data frames.
+ *
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
*/
enum ieee80211_hw_flags {
@@ -2091,6 +2094,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_TX_FRAG_LIST,
IEEE80211_HW_REPORTS_LOW_ACK,
IEEE80211_HW_SUPPORTS_TX_FRAG,
+ IEEE80211_HW_SUPPORTS_80211_ENCAP,
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 5fae001..b97ffb4 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -211,6 +211,7 @@ static ssize_t reset_write(struct file *file, const char __user *user_buf,
FLAG(TX_FRAG_LIST),
FLAG(REPORTS_LOW_ACK),
FLAG(SUPPORTS_TX_FRAG),
+ FLAG(SUPPORTS_80211_ENCAP),
#undef FLAG
};
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK
From: Johannes Berg @ 2017-03-03 12:21 UTC (permalink / raw)
To: Arend Van Spriel, linux-wireless
Cc: Eliad Peller, Andrei Otcheretianski, Avraham Stern
In-Reply-To: <96cd71c3-c279-b298-3876-68bac7297dc4@broadcom.com>
On Tue, 2017-02-28 at 12:06 +0100, Arend Van Spriel wrote:
> On 21-2-2017 12:46, Johannes Berg wrote:
> >
> > > > > Would this work for you? We should have wpa_supplicant
> > > > > support
> > > > > too, but need to ask Andrei to look at that.
> > >
> > > Forgot to reply to this. Yes, this will work. Can come up with
> > > wpa_supp changes.
> >
> > No, we have them. Just need to see where they are :)
>
> Found anything ? :-p
Sorry, got too busy with other stuff.
+Andrei, can you send out the patches from Avi in wpa_s for doing the
4-way-HS offload (as an RFC)?
Arend, wait a bit - he's travelling now I think.
Thanks,
johannes
^ permalink raw reply
* Re: [PATCH 00/26] bring back stack frame warning with KASAN
From: Alexander Potapenko @ 2017-03-03 12:25 UTC (permalink / raw)
To: Arnd Bergmann
Cc: kasan-dev, Andrey Ryabinin, Dmitry Vyukov, netdev, LKML,
linux-media, linux-wireless, kernel-build-reports,
David S . Miller
In-Reply-To: <20170302163834.2273519-1-arnd@arndb.de>
On Thu, Mar 2, 2017 at 5:38 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> It took a long while to get this done, but I'm finally ready
> to send the first half of the KASAN stack size patches that
> I did in response to the kernelci.org warnings.
>
> As before, it's worth mentioning that things are generally worse
> with gcc-7.0.1 because of the addition of -fsanitize-address-use-after-sc=
ope
> that are not present on kernelci, so my randconfig testing found
> a lot more than kernelci did.
>
> The main areas are:
>
> - READ_ONCE/WRITE_ONCE cause problems in lots of code
> - typecheck() causes huge problems in a few places
> - I'm introducing "noinline_for_kasan" and use it in a lot
> of places that suffer from inline functions with local variables
> - netlink, as used in various parts of the kernel
> - a number of drivers/media drivers
> - a handful of wireless network drivers
> - kmemcheck conflicts with -fsanitize-address-use-after-scope
>
> This series lets us add back a stack frame warning for 3072 bytes
> with -fsanitize-address-use-after-scope, or 2048 bytes without it.
>
> I have a follow-up series that further reduces the stack frame
> warning limit to 1280 bytes for all 64-bit architectures, and
> 1536 bytes with basic KASAN support (no -fsanitize-address-use-after-scop=
e).
> For now, I'm only posting the first half, in order to keep
> it (barely) reviewable.
Can you please elaborate on why do you need this? Are you trying to
squeeze KASAN into some embedded device?
Noinlines sprayed over the codebase are hard to maintain, and certain
compiler changes may cause bloated stack frames in other places.
Maybe it should be enough to just increase the stack frame limit in
KASAN builds, as Dmitry suggested previously?
> Both series are tested with many hundred randconfig builds on both
> x86 and arm64, which are the only architectures supporting KASAN.
>
> Arnd
>
> [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
> [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
> [PATCH 03/26] typecheck.h: avoid local variables in typecheck() macro
> [PATCH 04/26] tty: kbd: reduce stack size with KASAN
> [PATCH 05/26] netlink: mark nla_put_{u8,u16,u32} noinline_for_kasan
> [PATCH 06/26] rocker: mark rocker_tlv_put_* functions as
> [PATCH 07/26] brcmsmac: reduce stack size with KASAN
> [PATCH 08/26] brcmsmac: make some local variables 'static const' to
> [PATCH 09/26] brcmsmac: split up wlc_phy_workarounds_nphy
> [PATCH 10/26] brcmsmac: reindent split functions
> [PATCH 11/26] rtlwifi: reduce stack usage for KASAN
> [PATCH 12/26] wl3501_cs: reduce stack size for KASAN
> [PATCH 13/26] rtl8180: reduce stack size for KASAN
> [PATCH 14/26] [media] dvb-frontends: reduce stack size in i2c access
> [PATCH 15/26] [media] tuners: i2c: reduce stack usage for
> [PATCH 16/26] [media] i2c: adv7604: mark register access as
> [PATCH 17/26] [media] i2c: ks0127: reduce stack frame size for KASAN
> [PATCH 18/26] [media] i2c: cx25840: avoid stack overflow with KASAN
> [PATCH 19/26] [media] r820t: mark register functions as
> [PATCH 20/26] [media] em28xx: split up em28xx_dvb_init to reduce
> [PATCH 21/26] drm/bridge: ps8622: reduce stack size for KASAN
> [PATCH 22/26] drm/i915/gvt: don't overflow the kernel stack with
> [PATCH 23/26] mtd: cfi: reduce stack size with KASAN
> [PATCH 24/26] ocfs2: reduce stack size with KASAN
> [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan
> [PATCH 26/26] kasan: rework Kconfig settings
>
> arch/x86/include/asm/switch_to.h | 2 =
+-
> drivers/gpu/drm/bridge/parade-ps8622.c | 2 =
+-
> drivers/gpu/drm/i915/gvt/mmio.h | 17 =
+-
> drivers/isdn/hardware/eicon/Kconfig | 1 =
+
> drivers/media/dvb-frontends/ascot2e.c | 3 =
+-
> drivers/media/dvb-frontends/cxd2841er.c | 4 =
+-
> drivers/media/dvb-frontends/drx39xyj/drxj.c | 14 =
+-
> drivers/media/dvb-frontends/helene.c | 4 =
+-
> drivers/media/dvb-frontends/horus3a.c | 2 =
+-
> drivers/media/dvb-frontends/itd1000.c | 2 =
+-
> drivers/media/dvb-frontends/mt312.c | 2 =
+-
> drivers/media/dvb-frontends/si2165.c | 14 =
+-
> drivers/media/dvb-frontends/stb0899_drv.c | 2 =
+-
> drivers/media/dvb-frontends/stb6100.c | 2 =
+-
> drivers/media/dvb-frontends/stv0367.c | 2 =
+-
> drivers/media/dvb-frontends/stv090x.c | 2 =
+-
> drivers/media/dvb-frontends/stv6110.c | 2 =
+-
> drivers/media/dvb-frontends/stv6110x.c | 2 =
+-
> drivers/media/dvb-frontends/tda8083.c | 2 =
+-
> drivers/media/dvb-frontends/zl10039.c | 2 =
+-
> drivers/media/i2c/adv7604.c | 4 =
+-
> drivers/media/i2c/cx25840/cx25840-core.c | 4 =
+-
> drivers/media/i2c/ks0127.c | 2 =
+-
> drivers/media/tuners/r820t.c | 4 =
+-
> drivers/media/tuners/tuner-i2c.h | 15 =
+-
> drivers/media/usb/em28xx/em28xx-dvb.c | 947 =
+++++++++++++++++++++------------------
> drivers/mtd/chips/cfi_cmdset_0020.c | 8 =
+-
> drivers/net/ethernet/rocker/rocker_tlv.h | 24 =
+-
> drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c | 1860 =
+++++++++++++++++++++++++++++++++++++--------------------------------------=
--
> drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225se.c | 4 =
+-
> drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8192e2ant.c | 41 =
+-
> drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c | 26 =
+-
> drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c | 34 =
+-
> drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c | 36 =
+-
> drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a2ant.c | 38 =
+-
> drivers/net/wireless/wl3501_cs.c | 10 =
+-
> drivers/tty/vt/keyboard.c | 6 =
+-
> fs/ocfs2/cluster/masklog.c | 10 =
+-
> fs/ocfs2/cluster/masklog.h | 4 =
+-
> fs/overlayfs/util.c | 6 =
+-
> include/linux/compiler.h | 58 =
++-
> include/linux/mtd/map.h | 8 =
+-
> include/linux/typecheck.h | 7 =
+-
> include/net/netlink.h | 36 =
+-
> lib/Kconfig.debug | 9 =
+-
> lib/Kconfig.kasan | 11 =
+-
> lib/Kconfig.kmemcheck | 1 =
+
> scripts/Makefile.kasan | 3 =
+
> 48 files changed, 1670 insertions(+), 1629 deletions(-)
>
--=20
Alexander Potapenko
Software Engineer
Google Germany GmbH
Erika-Mann-Stra=C3=9Fe, 33
80636 M=C3=BCnchen
Gesch=C3=A4ftsf=C3=BChrer: Matthew Scott Sucherman, Paul Terence Manicle
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
^ permalink raw reply
* Re: [PATCH 02/26] rewrite READ_ONCE/WRITE_ONCE
From: Christian Borntraeger @ 2017-03-03 8:26 UTC (permalink / raw)
To: Arnd Bergmann
Cc: kasan-dev, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
Networking, Linux Kernel Mailing List, linux-media,
linux-wireless, kernel-build-reports, David S . Miller,
Paul McKenney
In-Reply-To: <CAK8P3a2mepCjPfM9Ychk7CHFHi0UW8RBzK4skJKMSOjw3gKoYg@mail.gmail.com>
On 03/02/2017 10:45 PM, Arnd Bergmann wrote:
> On Thu, Mar 2, 2017 at 8:00 PM, Christian Borntraeger
> <borntraeger@de.ibm.com> wrote:
>> On 03/02/2017 06:55 PM, Arnd Bergmann wrote:
>>> On Thu, Mar 2, 2017 at 5:51 PM, Christian Borntraeger
>>> <borntraeger@de.ibm.com> wrote:
>>>> On 03/02/2017 05:38 PM, Arnd Bergmann wrote:
>>>>>
>>>>> This attempts a rewrite of the two macros, using a simpler implementation
>>>>> for the most common case of having a naturally aligned 1, 2, 4, or (on
>>>>> 64-bit architectures) 8 byte object that can be accessed with a single
>>>>> instruction. For these, we go back to a volatile pointer dereference
>>>>> that we had with the ACCESS_ONCE macro.
>>>>
>>>> We had changed that back then because gcc 4.6 and 4.7 had a bug that could
>>>> removed the volatile statement on aggregate types like the following one
>>>>
>>>> union ipte_control {
>>>> unsigned long val;
>>>> struct {
>>>> unsigned long k : 1;
>>>> unsigned long kh : 31;
>>>> unsigned long kg : 32;
>>>> };
>>>> };
>>>>
>>>> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145
>>>>
>>>> If I see that right, your __ALIGNED_WORD(x)
>>>> macro would say that for above structure sizeof(x) == sizeof(long)) is true,
>>>> so it would fall back to the old volatile cast and might reintroduce the
>>>> old compiler bug?
>>
>> Oh dear, I should double check my sentences in emails before sending...anyway
>> the full story is referenced in
>>
>> commit 60815cf2e05057db5b78e398d9734c493560b11e
>> Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/borntraeger/linux
>> which has a pointer to
>> http://marc.info/?i=54611D86.4040306%40de.ibm.com
>> which contains the full story.
>
> Ok, got it. So I guess the behavior of forcing aligned accesses on aligned
> data is accidental, and allowing non-power-of-two arguments is also not
> the main purpose.
Right. The main purpose is to read/write _ONCE_. You can assume a somewhat
atomic access for sizes <= word size. And there are certainly places that
rely on that. But the *ONCE thing is mostly used for things where we used
barrier() 10 years ago.
Maybe we could just bail out on new compilers if we get
> either of those? That might catch code that accidentally does something
> that is inherently non-atomic or that causes a trap when the intention was
> to have a simple atomic access.
I think Linus stated that its ok to assume that the compiler is smart enough
to uses a single instruction to access aligned and properly sized scalar types
for *ONCE.
Back then when I changed ACCESS_ONCE there were many places that did use it
for non-atomic, > word size accesses. For example on some architectures a pmd_t
is a typedef to an array, for which there is no way to read that atomically.
So the focus must be on the "ONCE" part.
If some code uses a properly aligned, word sized object we can also assume
atomic access. If the access is not properly sized/aligned we do not get
atomicity, but we do get the "ONCE".
But adding a check for alignment/size would break the compilation of some
code.
^ permalink raw reply
* [PATCH] mac80211: Use setup_timer instead of init_timer
From: Jiri Slaby @ 2017-03-03 12:45 UTC (permalink / raw)
To: johannes
Cc: linux-kernel, Ondřej Lysoněk, Jiri Slaby,
David S. Miller, linux-wireless, netdev
From: Ondřej Lysoněk <ondrej.lysonek@seznam.cz>
Use setup_timer() and setup_deferrable_timer() to set the data and
function timer fields. It makes the code cleaner and will allow for
easier change of the timer struct internals.
Signed-off-by: Ondřej Lysoněk <ondrej.lysonek@seznam.cz>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: <linux-wireless@vger.kernel.org>
Cc: <netdev@vger.kernel.org>
---
net/mac80211/agg-rx.c | 12 ++++++------
net/mac80211/agg-tx.c | 12 ++++++------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 4456559cb056..1b7a4daf283c 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -357,14 +357,14 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
spin_lock_init(&tid_agg_rx->reorder_lock);
/* rx timer */
- tid_agg_rx->session_timer.function = sta_rx_agg_session_timer_expired;
- tid_agg_rx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid];
- init_timer_deferrable(&tid_agg_rx->session_timer);
+ setup_deferrable_timer(&tid_agg_rx->session_timer,
+ sta_rx_agg_session_timer_expired,
+ (unsigned long)&sta->timer_to_tid[tid]);
/* rx reorder timer */
- tid_agg_rx->reorder_timer.function = sta_rx_agg_reorder_timer_expired;
- tid_agg_rx->reorder_timer.data = (unsigned long)&sta->timer_to_tid[tid];
- init_timer(&tid_agg_rx->reorder_timer);
+ setup_timer(&tid_agg_rx->reorder_timer,
+ sta_rx_agg_reorder_timer_expired,
+ (unsigned long)&sta->timer_to_tid[tid]);
/* prepare reordering buffer */
tid_agg_rx->reorder_buf =
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 45319cc01121..60e2a62f7bef 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -670,14 +670,14 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
tid_tx->timeout = timeout;
/* response timer */
- tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired;
- tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid];
- init_timer(&tid_tx->addba_resp_timer);
+ setup_timer(&tid_tx->addba_resp_timer,
+ sta_addba_resp_timer_expired,
+ (unsigned long)&sta->timer_to_tid[tid]);
/* tx timer */
- tid_tx->session_timer.function = sta_tx_agg_session_timer_expired;
- tid_tx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid];
- init_timer_deferrable(&tid_tx->session_timer);
+ setup_deferrable_timer(&tid_tx->session_timer,
+ sta_tx_agg_session_timer_expired,
+ (unsigned long)&sta->timer_to_tid[tid]);
/* assign a dialog token */
sta->ampdu_mlme.dialog_token_allocator++;
--
2.12.0
^ permalink raw reply related
* Re: [PATCH 00/26] bring back stack frame warning with KASAN
From: Arnd Bergmann @ 2017-03-03 12:54 UTC (permalink / raw)
To: Alexander Potapenko
Cc: kasan-dev, Andrey Ryabinin, Dmitry Vyukov, Networking, LKML,
linux-media, linux-wireless, kernel-build-reports,
David S . Miller
In-Reply-To: <CAG_fn=UVcLhP8mH6tvzqZUn4u9T4pnQw8bMf=qccNro59VcABw@mail.gmail.com>
On Fri, Mar 3, 2017 at 1:25 PM, Alexander Potapenko <glider@google.com> wrote:
> On Thu, Mar 2, 2017 at 5:38 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>> It took a long while to get this done, but I'm finally ready
>> to send the first half of the KASAN stack size patches that
>> I did in response to the kernelci.org warnings.
>>
>> As before, it's worth mentioning that things are generally worse
>> with gcc-7.0.1 because of the addition of -fsanitize-address-use-after-scope
>> that are not present on kernelci, so my randconfig testing found
>> a lot more than kernelci did.
>>
>> The main areas are:
>>
>> - READ_ONCE/WRITE_ONCE cause problems in lots of code
>> - typecheck() causes huge problems in a few places
>> - I'm introducing "noinline_for_kasan" and use it in a lot
>> of places that suffer from inline functions with local variables
>> - netlink, as used in various parts of the kernel
>> - a number of drivers/media drivers
>> - a handful of wireless network drivers
>> - kmemcheck conflicts with -fsanitize-address-use-after-scope
>>
>> This series lets us add back a stack frame warning for 3072 bytes
>> with -fsanitize-address-use-after-scope, or 2048 bytes without it.
>>
>> I have a follow-up series that further reduces the stack frame
>> warning limit to 1280 bytes for all 64-bit architectures, and
>> 1536 bytes with basic KASAN support (no -fsanitize-address-use-after-scope).
>> For now, I'm only posting the first half, in order to keep
>> it (barely) reviewable.
>
> Can you please elaborate on why do you need this? Are you trying to
> squeeze KASAN into some embedded device?
> Noinlines sprayed over the codebase are hard to maintain, and certain
> compiler changes may cause bloated stack frames in other places.
> Maybe it should be enough to just increase the stack frame limit in
> KASAN builds, as Dmitry suggested previously?
The current state of mainline has doubled the kernel stack size with
KASAN, and completely turned off the warning for per-function
stack frames. In some cases, this is completely broken as we have
functions that exceed even the 32kb per-thread stacks by themselves,
so I want to turn on the warning again and fix all the outliers.
The hard part is deciding what size is reasonable for a given function,
as smaller limits cause more harmless warnings while larger limits
can hide more actual problems. Before running into the KASAN
problem, I had already determined that we can lower the warning
limit for 64-bit architectures from 2048 bytes to 1280 with just
a handful of patches that are generally a good cleanup anyway.
This led me to picking three separate warning limits, based on
what I found reasonable to work around in the code:
3072 bytes with -fsanitize-address-use-after-scope
1536 bytes with KASAN but without -fsanitize-address-use-after-scope
1280 bytes on 64-bit without KASAN
1024 bytes on 32-bit architectures
If we use higher limits, the patch series will get a bit shorter. For
the limits above, I needed a total of 51 patches, while this shorter
series of 26 patches has slightly laxer limits:
3072 bytes with -fsanitize-address-use-after-scope
2048 bytes on 64-bit architectures with or without KASAN, but
without -fsanitize-address-use-after-scope
1024 bytes on 32-bit architectures
The individual patches should list the highest frame size I ran
into, so I can try to reduce the number of patches if you have
a suggestion for a different set of limits.
Arnd
^ permalink raw reply
* Re: [PATCH v2] mac80211: mesh - always do every discovery retry
From: Chun-Yeow Yeoh @ 2017-03-03 10:39 UTC (permalink / raw)
To: Jesse Jones; +Cc: linux-wireless@vger.kernel.org, Alexis Green, Alexis Green
In-Reply-To: <b285e11810b612a6a156693f34e232ac@mail.gmail.com>
>
> Yes, that is a real issue. We are planning on doing some further work in
> this area to try to minimize the explosions that can be seen with PREQs in
> larger networks while balancing the need for reliability.
>
> Path discovery
>> should stop once the path is established. By attempting 2nd, 3rd or 4th
>> doesn't guarantee the next path will be "good".
>
> It doesn't guarantee anything of course but it does raise the probability
> that the right path will be found. For example take four nodes in a ring
> where the A-B, B-C, C-D links are all good but the A-D link is poor. Poor
> enough that the higher data rates are hosed for that link but the basic rate
> used by management frames is relatively unaffected. If we assume that the
> reliability of management frames is 90% then in order for A to route to D it
> needs to get a PREQ to D and a PREP back. It has two options 1) for A-D the
> reliability will be 0.9^2 = 81% 2) for A-B-C-D the reliability will be 0.9^6
> = 53%.
What is round trip delay between A-D compared to A-B-C-D? 1 hop away
the throughput is reduced by half. Also if you have more nodes using
longer path, you consume more airtime leads to really bad network
performance, especially when B, C, or even D wants to start initial
data transmission.
> This isn't a good situation because it makes it much too easy for routing to
> pick a *really* bad path. And we have seen reliability improvements with
> this patch.
>
> We have already made changes to dial way back on the number of PREQs sent
> out so this patch made quite a bit of sense for us. In the default
> configuration where PREQs go out every 4s I don't think we have a good
> solution: picking a bad path, even for 4s, can be a horrible user experience
Reduce dot11MeshHWMPpreqMinInterval to send out more PREQ in your network.
> but PREQ volumes quickly start consuming too much airtime as network sizes
> increase.
One way of improving the path is either enhancing the airtime link
metric by considering the factor that you mentioned in or else
introducing vendor-specific path metric. Sending more broadcast frames
over the network won't be a good solution.
---
Chun-Yeow
^ permalink raw reply
* Re: [RFC] cfg80211: Add support for FILS shared key authentication offload
From: Johannes Berg @ 2017-03-03 12:28 UTC (permalink / raw)
To: Jouni Malinen; +Cc: linux-wireless, Kanchanapally, Vidyullatha
In-Reply-To: <1488542006-11776-1-git-send-email-jouni@qca.qualcomm.com>
> struct cfg80211_pmksa {
> const u8 *bssid;
> const u8 *pmkid;
> + const u8 *pmk;
> + size_t pmk_len;
> + const u8 *ssid;
> + size_t ssid_len;
> + u16 cache_id;
> };
So how does that work - from a flow perspective?
> +void cfg80211_connect_done(struct net_device *dev, const u8 *bssid,
> + struct cfg80211_bss *bss, const u8
> *req_ie,
> + size_t req_ie_len, const u8 *resp_ie,
> + size_t resp_ie_len, const u8 *fils_kek,
> + size_t fils_kek_len, bool
> update_erp_seq_num,
> + u16 fils_erp_seq_num, const u8 *pmk,
> size_t pmk_len,
> + const u8 *pmkid, int status, gfp_t gfp,
> + enum nl80211_timeout_reason
> timeout_reason);
Ouch. Please declare most of those (perhaps other than dev) as a
structure and pass a pointer here.
Also, why require the BSSID when BSS is set? Seems you could say one or
the other.
Also, what do you need the PMK for? If you have all of this stuff
offloaded, why does the host need to know the PMK?
> @@ -227,6 +227,13 @@ struct cfg80211_event {
> size_t req_ie_len;
> size_t resp_ie_len;
> struct cfg80211_bss *bss;
> + const u8 *kek;
> + size_t kek_len;
> + bool update_erp_seq_num;
> + u16 fils_erp_seq_num;
> + const u8 *pmk;
> + size_t pmk_len;
> + const u8 *pmkid;
> int status; /* -1 = failed; 0..65535 =
> status code */
> enum nl80211_timeout_reason timeout_reason;
> } cr;
Could probably use the new struct from cfg80211.h that I asked to add
here then.
Other than that, most of the patch seems mechanical - I think it'd be
good to have a DOC: section or so somewhere (nl80211.h?) that explains
how this is intended to be used? I've already migrated the
documentation to the new rst/sphinx format so we can generate it nicely
and that would be a good addition - I'll probably do some more
additions too.
johannes
^ permalink raw reply
* Re: [RFCv2 2/2] mac80211: Implement data xmit for 802.11 encap offload
From: Johannes Berg @ 2017-03-03 12:39 UTC (permalink / raw)
To: mpubbise; +Cc: linux-wireless, Vasanthakumar Thiagarajan
In-Reply-To: <1488540807-27415-3-git-send-email-mpubbise@qti.qualcomm.com>
> There is a field, no_80211_encap, added to ieee80211_tx_info:control
> to mark if the 802.11 encapsulation is offloaded to driver.
Why is that needed? Since you have a separate TX path (ndo_start_xmit),
wouldn't it make more sense to call into a drv_tx_8023() or something
like that instead?
> There is also a new callback for tx completion status indication
> to handle data frames using 802.11 encap offload.
Maybe you could just use _noskb?
Haven't really looked at the rest all that much, few comments:
* not sure you're handling non-linear frames right, are you assuming
the driver can handle them? probably a fair assumption, but should
be documented
* you seem to also be assuming that the driver not only does all
encryption in HW (which is obviously needed) but also does all the
key lookups etc. - also seems fair, but also should be documented
* similarly for a lot of other (all?) fields in tx_info
* you seem to be assuming that if encap offload is supported then it's
also *desired* for AP/VLAN and client interfaces, if not 4-addr.
This seems ... probably about right, but if drivers don't always
support it? Or support it in more cases? Perhaps we can move the
SUPPORTS_80211_ENCAP flag into a VIF flag instead, so they can do it
more fine-grained?
johannes
^ permalink raw reply
* Re: [RFCv2 1/2] mac80211: Add provision for 802.11 encap offload
From: Johannes Berg @ 2017-03-03 12:29 UTC (permalink / raw)
To: mpubbise; +Cc: linux-wireless, Vasanthakumar Thiagarajan
In-Reply-To: <1488540807-27415-2-git-send-email-mpubbise@qti.qualcomm.com>
On Fri, 2017-03-03 at 17:03 +0530, mpubbise@qti.qualcomm.com wrote:
> From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
>
> Drivers can have the capability to offload 802.11 encap
> to firmware or hardware for data frames. This patch adds a new
> hw_flag for driver to advertise the offload support.
> Transmit path offloading 802.11 header (including cipher headers)
> encap for data frames will be implemented in a separate patch.
>
> Drivers advertising this capability should also implement other
> functionalities which deal with 802.11 frame format like below
>
> - Hardware encryption
> - Aggregation of A-MSDU offload
> - Fragmentation offload
Not much point in having this as a separate patch, but this
documentation paragraph should move into the documentation for the new
flag in mac80211.h
johannes
^ permalink raw reply
* Re: [PATCH] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK
From: Johannes Berg @ 2017-03-03 12:20 UTC (permalink / raw)
To: Jithu Jance, Arend Van Spriel
Cc: linux-wireless, Eliad Peller, Jouni Malinen, Avraham Stern
In-Reply-To: <CA+gyVQ24qDqpOBKPjVaZ_BFAJa9kLMjA=nD8FF8V7HvxUkWb=w@mail.gmail.com>
On Thu, 2017-02-23 at 16:26 +0530, Jithu Jance wrote:
> On Thu, Feb 23, 2017 at 4:10 PM, Arend Van Spriel
> <arend.vanspriel@broadcom.com> wrote:
> >
> > Ehm. Looking at the code in wpa_supplicant_event_assoc() it would
> > be
> > better to use NL80211_CMD_EAPOL_PORT_VALID event to cover both
> > WPA/WPA2-PSK and 8021X.
>
> Yes. IMHO, the assoc/reassoc ind should move the state to
> WPA_ASSOCIATED and a separate event like
> NL80211_CMD_EAPOL_PORT_VALID/AUTHORIZED should move the connection
> state to WPA_COMPLETED.
That seems reasonable.
Avi just looked also at distinguishing if/when fresh 1X authentication
is required, particularly with roaming. For that, he's suggesting to
add a flag AUTHORIZED to the ROAMED event.
We could, possibly, have a PORT_AUTHORIZED event for that as well, but
it'd be more complicated, since then you'd have to wait for that and if
it doesn't come time out - or we'd need a "PORT_UNAUTHORIZED" or
"PLEASE_START_1X" instead? None of that really seems like such a great
idea.
Perhaps instead it'd make sense to instead include the new AUTHORIZED
flag in the CONNECT_RESULT as well, if authorized? I basically see 3
valid cases:
* connection successful with authorized port
* connection successful with need for 1X handshake (non-offloaded)
* connection failed
Why should we have the case of
* association successful but 4-way-HS failed
separately?
johannes
^ permalink raw reply
* Re: [PATCH 4.12] bcma: drop unneeded check for CONFIG_OF_IRQ
From: Arnd Bergmann @ 2017-03-03 10:46 UTC (permalink / raw)
To: Rafał Miłecki
Cc: Kalle Valo, linux-wireless, Hauke Mehrtens,
Rafał Miłecki
In-Reply-To: <20170303103330.4914-1-zajec5@gmail.com>
On Fri, Mar 3, 2017 at 11:33 AM, Rafa=C5=82 Mi=C5=82ecki <zajec5@gmail.com>=
wrote:
> From: Rafa=C5=82 Mi=C5=82ecki <rafal@milecki.pl>
>
> We already have the same check in bcma_of_get_irq which really calls
> symbols available with CONFIG_OF_IRQ only. It appears this duplicated
> check was accidentally added in commit c58d900cc96a ("bcma: fix building
> without OF_IRQ"). The rest of code in bcma_of_fill_device should work
> fine without CONFIG_OF_IRQ.
>
> Signed-off-by: Rafa=C5=82 Mi=C5=82ecki <rafal@milecki.pl>
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* Re: [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
From: Alexander Potapenko @ 2017-03-03 13:55 UTC (permalink / raw)
To: Andrey Ryabinin
Cc: Arnd Bergmann, kasan-dev, Dmitry Vyukov, netdev, LKML,
linux-media, linux-wireless, kernel-build-reports,
David S . Miller
In-Reply-To: <7e7a62de-3b79-6044-72fa-4ade418953d1@virtuozzo.com>
On Fri, Mar 3, 2017 at 2:50 PM, Andrey Ryabinin <aryabinin@virtuozzo.com> w=
rote:
>
>
> On 03/02/2017 07:38 PM, Arnd Bergmann wrote:
>> When CONFIG_KASAN is set, we can run into some code that uses incredible
>> amounts of kernel stack:
>>
>> drivers/staging/dgnc/dgnc_neo.c:1056:1: error: the frame size of 11112 b=
ytes is larger than 2048 bytes [-Werror=3Dframe-larger-than=3D]
>> drivers/media/i2c/cx25840/cx25840-core.c:4960:1: error: the frame size o=
f 94000 bytes is larger than 2048 bytes [-Werror=3Dframe-larger-than=3D]
>> drivers/media/dvb-frontends/stv090x.c:3430:1: error: the frame size of 5=
312 bytes is larger than 3072 bytes [-Werror=3Dframe-larger-than=3D]
>>
>> This happens when a sanitizer uses stack memory each time an inline func=
tion
>> gets called. This introduces a new annotation for those functions to mak=
e
>> them either 'inline' or 'noinline' dependning on the CONFIG_KASAN symbol=
.
>>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> ---
>> include/linux/compiler.h | 11 +++++++++++
>> 1 file changed, 11 insertions(+)
>>
>> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
>> index f8110051188f..56b90897a459 100644
>> --- a/include/linux/compiler.h
>> +++ b/include/linux/compiler.h
>> @@ -416,6 +416,17 @@ static __always_inline void __write_once_size(volat=
ile void *p, void *res, int s
>> */
>> #define noinline_for_stack noinline
>>
>> +/*
>> + * CONFIG_KASAN can lead to extreme stack usage with certain patterns w=
hen
>> + * one function gets inlined many times and each instance requires a st=
ack
>> + * ckeck.
>> + */
>> +#ifdef CONFIG_KASAN
>> +#define noinline_for_kasan noinline __maybe_unused
>
>
> noinline_iff_kasan might be a better name. noinline_for_kasan gives the =
impression
> that we always noinline function for the sake of kasan, while noinline_if=
f_kasan
> clearly indicates that function is noinline only if kasan is used.
FWIW we may be facing the same problem with other compiler-based
tools, e.g. KMSAN (which isn't there yet).
So it might be better to choose a macro name that doesn't use the name "KAS=
AN".
E.g. noinline_iff_memtool (or noinline_iff_memory_tool if that's not too lo=
ng).
WDYT?
>> +#else
>> +#define noinline_for_kasan inline
>> +#endif
>> +
>> #ifndef __always_inline
>> #define __always_inline inline
>> #endif
>>
>
> --
> You received this message because you are subscribed to the Google Groups=
"kasan-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
email to kasan-dev+unsubscribe@googlegroups.com.
> To post to this group, send email to kasan-dev@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgi=
d/kasan-dev/7e7a62de-3b79-6044-72fa-4ade418953d1%40virtuozzo.com.
> For more options, visit https://groups.google.com/d/optout.
--=20
Alexander Potapenko
Software Engineer
Google Germany GmbH
Erika-Mann-Stra=C3=9Fe, 33
80636 M=C3=BCnchen
Gesch=C3=A4ftsf=C3=BChrer: Matthew Scott Sucherman, Paul Terence Manicle
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
^ permalink raw reply
* Re: [PATCH 25/26] isdn: eicon: mark divascapi incompatible with kasan
From: Andrey Ryabinin @ 2017-03-03 14:20 UTC (permalink / raw)
To: Arnd Bergmann, kasan-dev
Cc: Alexander Potapenko, Dmitry Vyukov, netdev, linux-kernel,
linux-media, linux-wireless, kernel-build-reports,
David S . Miller
In-Reply-To: <20170302163834.2273519-26-arnd@arndb.de>
On 03/02/2017 07:38 PM, Arnd Bergmann wrote:
> When CONFIG_KASAN is enabled, we have several functions that use rather
> large kernel stacks, e.g.
>
> drivers/isdn/hardware/eicon/message.c: In function 'group_optimization':
> drivers/isdn/hardware/eicon/message.c:14841:1: warning: the frame size of 864 bytes is larger than 500 bytes [-Wframe-larger-than=]
> drivers/isdn/hardware/eicon/message.c: In function 'add_b1':
> drivers/isdn/hardware/eicon/message.c:7925:1: warning: the frame size of 1008 bytes is larger than 500 bytes [-Wframe-larger-than=]
> drivers/isdn/hardware/eicon/message.c: In function 'add_b23':
> drivers/isdn/hardware/eicon/message.c:8551:1: warning: the frame size of 928 bytes is larger than 500 bytes [-Wframe-larger-than=]
> drivers/isdn/hardware/eicon/message.c: In function 'sig_ind':
> drivers/isdn/hardware/eicon/message.c:6113:1: warning: the frame size of 2112 bytes is larger than 500 bytes [-Wframe-larger-than=]
>
> To be on the safe side, and to enable a lower frame size warning limit, let's
> just mark this driver as broken when KASAN is in use. I have tried to reduce
> the stack size as I did with dozens of other drivers, but failed to come up
> with a good solution for this one.
>
This is kinda radical solution.
Wouldn't be better to just increase -Wframe-larger-than for this driver through Makefile?
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> drivers/isdn/hardware/eicon/Kconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/isdn/hardware/eicon/Kconfig b/drivers/isdn/hardware/eicon/Kconfig
> index 6082b6a5ced3..b64496062421 100644
> --- a/drivers/isdn/hardware/eicon/Kconfig
> +++ b/drivers/isdn/hardware/eicon/Kconfig
> @@ -31,6 +31,7 @@ config ISDN_DIVAS_PRIPCI
>
> config ISDN_DIVAS_DIVACAPI
> tristate "DIVA CAPI2.0 interface support"
> + depends on !KASAN || BROKEN
> help
> You need this to provide the CAPI interface
> for DIVA Server cards.
>
^ permalink raw reply
* Re: [PATCH 01/26] compiler: introduce noinline_for_kasan annotation
From: Arnd Bergmann @ 2017-03-03 14:30 UTC (permalink / raw)
To: Alexander Potapenko
Cc: Andrey Ryabinin, kasan-dev, Dmitry Vyukov, Networking, LKML,
linux-media, linux-wireless, kernel-build-reports,
David S . Miller
In-Reply-To: <CAG_fn=WayMEnBO4pzuxQ5jgn-ii6vrALuOex5Ei1ZhzMR7_tjg@mail.gmail.com>
On Fri, Mar 3, 2017 at 2:55 PM, Alexander Potapenko <glider@google.com> wrote:
> On Fri, Mar 3, 2017 at 2:50 PM, Andrey Ryabinin <aryabinin@virtuozzo.com> wrote:
>>> @@ -416,6 +416,17 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
>>> */
>>> #define noinline_for_stack noinline
>>>
>>> +/*
>>> + * CONFIG_KASAN can lead to extreme stack usage with certain patterns when
>>> + * one function gets inlined many times and each instance requires a stack
>>> + * ckeck.
>>> + */
>>> +#ifdef CONFIG_KASAN
>>> +#define noinline_for_kasan noinline __maybe_unused
>>
>>
>> noinline_iff_kasan might be a better name. noinline_for_kasan gives the impression
>> that we always noinline function for the sake of kasan, while noinline_iff_kasan
>> clearly indicates that function is noinline only if kasan is used.
Fine with me. I actually tried to come up with a name that implies that the
symbol is actually "inline" (or even __always_inline_ without KASAN, but
couldn't think of any good name for it.
> FWIW we may be facing the same problem with other compiler-based
> tools, e.g. KMSAN (which isn't there yet).
> So it might be better to choose a macro name that doesn't use the name "KASAN".
> E.g. noinline_iff_memtool (or noinline_iff_memory_tool if that's not too long).
> WDYT?
Would KMSAN also force local variables to be non-overlapping the way that
asan-stack=1 and -fsanitize-address-use-after-scope do? As I understood it,
KMSAN would add extra code for maintaining the uninit bits, but in an example
like this
int f(int *);
static inline __attribute__((always_inline)) int g(void)
{
int i;
f(&i);
return i;
}
int f(void)
{
return g()+g()+g()+g();
}
each of the four copies of 'i' could have the same location on the stack
and get marked uninitialized again before calling f(). We only need
noinline_for_kasan (whatever we end up calling that) for compiler
features that force each instance of 'i' to have its own stack redzone.
Arnd
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox