Message ID | 20231206150602.176574-2-ayushdevel1325@gmail.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:bcd1:0:b0:403:3b70:6f57 with SMTP id r17csp4166303vqy; Wed, 6 Dec 2023 07:06:56 -0800 (PST) X-Google-Smtp-Source: AGHT+IGpkMko5iHKurYOXHJ8hvaRiZaSZmXNPE8LzBbkiCFvHXiT/T1NJFvZ4u6hqmbAUPs5rcXg X-Received: by 2002:a17:902:e80c:b0:1d0:c332:8a7c with SMTP id u12-20020a170902e80c00b001d0c3328a7cmr770250plg.101.1701875216090; Wed, 06 Dec 2023 07:06:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701875216; cv=none; d=google.com; s=arc-20160816; b=modTy+LfC4aCNMsgioTv3sjBiloZDT6doTeGfqefaxyTqqfgDXA016fX8/+xNIuBrr 0nGQo+ZIzoc7jpyk0ftlL6KtvEpwCN0r5f/DR2ulyuXSwILxBWWhodEWwBNly8ux/kSi N5uigt8KCLDJZe0SHc6A8ZkOsM8dJ31vFlL3JFrSC0/YoykJNdR8r79QwGsVPNza4G95 NdVc9aZbZ8lOJlq5HMZaMt+x/NQ/7gSwVu4agkP646WcddpPRkVB687LYlxQK3+5uQQN Q7RJP7C4hFv3wu8KB8PaYpbyGGYDQ/bFVXY+SI7FiK+Wme00kAtqyu35pADJvan2fXAE kSVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=+wvGGeUhAcBlY5JsYq0v3hWMNXvHne0yXH5FlnUniu4=; fh=Qjn9V3WRZ8voNKTR0T2aDdpU9SDpV6npG0M5VoIf0Yo=; b=J/cgXQ7l5uCxfQq2ycBhh4HE/zl7Mm/8CfZJshQa+HiHr7InXwvLIA0GIXn0dH8ZBi ZFfzSTn9NLh04VVCrOACnrhj9rXO86CATlDvNbTLE7Qp1sHtrLwbeYWs5vx93nMKDZ1s Mqo2kVumllXuMn3GPtNwoZrPjh6OMZF3MwIRWPb7jrdKjlg0J0juLdnRlesgS3ObQN5S CEVbVe9PlyUSfIdf1fbHcxke7YPEoSxMH62XzYY0aubu9SKT/BlVvD6P0nfT+IwrbC14 iED+1pCUljxXLwfFEMMwKFjGBpyTo3SrhXY76vyz+t+3Uw+KToz/WaGfR99l2Zzox6tn SSmQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=U4elgeEY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from fry.vger.email (fry.vger.email. [23.128.96.38]) by mx.google.com with ESMTPS id e2-20020a170902d38200b001cf77931eb1si8061411pld.4.2023.12.06.07.06.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Dec 2023 07:06:56 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) client-ip=23.128.96.38; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=U4elgeEY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by fry.vger.email (Postfix) with ESMTP id C5A9D80324DD; Wed, 6 Dec 2023 07:06:42 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at fry.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1442225AbjLFPGS (ORCPT <rfc822;pusanteemu@gmail.com> + 99 others); Wed, 6 Dec 2023 10:06:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49330 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379084AbjLFPGM (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 6 Dec 2023 10:06:12 -0500 Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E34BD4D for <linux-kernel@vger.kernel.org>; Wed, 6 Dec 2023 07:06:15 -0800 (PST) Received: by mail-pf1-x42d.google.com with SMTP id d2e1a72fcca58-6ce9c8c45a7so329629b3a.0 for <linux-kernel@vger.kernel.org>; Wed, 06 Dec 2023 07:06:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701875174; x=1702479974; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+wvGGeUhAcBlY5JsYq0v3hWMNXvHne0yXH5FlnUniu4=; b=U4elgeEYIQUcvbzJNcMC76sY3cr1uj9UNeLapfAi9a3z50MM2f22dOsGvY6KskCxrt sFDkdkAba5ySC0Atb1/d3o/nQSaPVdHx+Qat4xNGwIu3U6i4t4eyXtirbv0sOlCIv7XC hRsOLrJgasDMWWn6c61RVBOe5xQCcfr2k4UcOi9UVgrAd1WBC0hAjfztFdpzkvoQpiQ4 yUIBUBLSazRAPzaIb8LTvdswlB37bLWAkBbWwktTjxj5HvFFlfNsHBKvX63tQkBjB39h rWppAu/qYM1rfd4/fKma3U9Q/uLpoctu0xy45lXgQBi29NggA0mPB2Hc9Nbdlhyg/7T2 rvHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701875174; x=1702479974; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+wvGGeUhAcBlY5JsYq0v3hWMNXvHne0yXH5FlnUniu4=; b=SYpoOCtzKnXGZxLWFtvRGSP1uJIE1FiKTeh6IdMMZRDY2q9uW3CSqiZlrqxzzEMwVB BEaOab+eVd4zUYLVelRcHZM85JEMQhLcmaXyaOSPFpyngnlPmplBMUxo2zGSGBS485Yz WXSo+dOvA3UsIqQBq/LmoTsAS60whtmZSOJIfoUfQUB5pjKmb8/SLTdcHvDb9HKXrNkh tl+J3d5MafOYa/suAxUk0oP5G2bZ0kS1n2Ccx9pNS6Q27E1VLEUyFvYGiu7tkQ05MSOY 3BAxTIpX4Rb37r3MgQ/D28d2VuV5IaA8T/4jraKT3GlyMOyl9VkgqwP2nDLuLpijz5Qr O3xQ== X-Gm-Message-State: AOJu0YxsZpbiUYkLqepTBS8APbLnv9u2ZSTePh5Ynlhjd+rH6ygxhsKQ rK6/7Qun9NfGsP0+G1r9pJ8= X-Received: by 2002:a05:6a20:5141:b0:18f:97c:4f6d with SMTP id b1-20020a056a20514100b0018f097c4f6dmr532514pzc.121.1701875174553; Wed, 06 Dec 2023 07:06:14 -0800 (PST) Received: from toolbox.. ([2401:4900:1f3e:53bf:50c7:2988:e019:4b97]) by smtp.gmail.com with ESMTPSA id s5-20020a625e05000000b006ce7ed5ba41sm96885pfb.55.2023.12.06.07.06.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Dec 2023 07:06:14 -0800 (PST) From: Ayush Singh <ayushdevel1325@gmail.com> To: greybus-dev@lists.linaro.org Cc: Ayush Singh <ayushdevel1325@gmail.com>, johan@kernel.org, elder@kernel.org, gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, jkridner@beagleboard.org, nm@ti.com, yujie.liu@intel.com Subject: [PATCH 1/1] greybus: gb-beagleplay: Remove use of pad bytes Date: Wed, 6 Dec 2023 20:36:00 +0530 Message-ID: <20231206150602.176574-2-ayushdevel1325@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231206150602.176574-1-ayushdevel1325@gmail.com> References: <20231206150602.176574-1-ayushdevel1325@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.6 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on fry.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (fry.vger.email [0.0.0.0]); Wed, 06 Dec 2023 07:06:43 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1784545506620020718 X-GMAIL-MSGID: 1784545506620020718 |
Series |
Make gb-beagleplay driver Greybus compliant
|
|
Commit Message
Ayush Singh
Dec. 6, 2023, 3:06 p.m. UTC
Make gb-beagleplay greybus spec compliant by using a wrapper around HDLC
payload to include cport information.
Fixes: ec558bbfea67 ("greybus: Add BeaglePlay Linux Driver")
Reported-by: kernel test robot <yujie.liu@intel.com>
Closes: https://lore.kernel.org/r/202311072329.Xogj7hGW-lkp@intel.com/
Signed-off-by: Ayush Singh <ayushdevel1325@gmail.com>
---
drivers/greybus/gb-beagleplay.c | 44 +++++++++++++++++++++++----------
1 file changed, 31 insertions(+), 13 deletions(-)
Comments
On Wed, Dec 06, 2023 at 08:36:00PM +0530, Ayush Singh wrote: > Make gb-beagleplay greybus spec compliant by using a wrapper around HDLC > payload to include cport information. "wrapper"? You just changed the data you send on your "wire", right? > Fixes: ec558bbfea67 ("greybus: Add BeaglePlay Linux Driver") > Reported-by: kernel test robot <yujie.liu@intel.com> > Closes: https://lore.kernel.org/r/202311072329.Xogj7hGW-lkp@intel.com/ > Signed-off-by: Ayush Singh <ayushdevel1325@gmail.com> > --- > drivers/greybus/gb-beagleplay.c | 44 +++++++++++++++++++++++---------- > 1 file changed, 31 insertions(+), 13 deletions(-) > > diff --git a/drivers/greybus/gb-beagleplay.c b/drivers/greybus/gb-beagleplay.c > index 1e70ff7e3da4..fb40ade9364f 100644 > --- a/drivers/greybus/gb-beagleplay.c > +++ b/drivers/greybus/gb-beagleplay.c > @@ -85,17 +85,35 @@ struct hdlc_payload { > void *buf; > }; > > +/** > + * struct hdlc_greybus_frame - Structure to represent greybus HDLC frame Represent it where? And where is this documented? > + * > + * @cport: cport id > + * @hdr: greybus operation header > + * @payload: greybus message payload > + */ > +struct hdlc_greybus_frame { > + __le16 cport; > + struct gb_operation_msg_hdr hdr; > + u8 payload[]; > +} __packed; > + > static void hdlc_rx_greybus_frame(struct gb_beagleplay *bg, u8 *buf, u16 len) > { > - u16 cport_id; > - struct gb_operation_msg_hdr *hdr = (struct gb_operation_msg_hdr *)buf; > + struct hdlc_greybus_frame *gb_frame = (struct hdlc_greybus_frame *)buf; > + u16 cport_id = le16_to_cpu(gb_frame->cport); > > - memcpy(&cport_id, hdr->pad, sizeof(cport_id)); > + /* Ensure that the greybus message is valid */ > + if (le16_to_cpu(gb_frame->hdr.size) > len - sizeof(cport_id)) { > + dev_warn_ratelimited(&bg->sd->dev, "Invalid/Incomplete greybus message"); Don't spam the kernel log for corrupted data on the line, that would be a mess. Use a tracepoint? > + return; > + } > > dev_dbg(&bg->sd->dev, "Greybus Operation %u type %X cport %u status %u received", > - hdr->operation_id, hdr->type, le16_to_cpu(cport_id), hdr->result); > + gb_frame->hdr.operation_id, gb_frame->hdr.type, cport_id, gb_frame->hdr.result); Better yet, put the error in the debug message? > > - greybus_data_rcvd(bg->gb_hd, le16_to_cpu(cport_id), buf, len); > + greybus_data_rcvd(bg->gb_hd, cport_id, &buf[sizeof(cport_id)], Fun with pointer math. This feels really fragile, why not just point to the field instead? > + le16_to_cpu(gb_frame->hdr.size)); You convert the size twice, might as well do it once up above, right? Also, it's best to use the same value you checked as the value you pass in here, odds are you can't change the data underneath you (like you could if this came from userspace), but it's best to not get in the habit of coding like this. > } > > static void hdlc_rx_dbg_frame(const struct gb_beagleplay *bg, const char *buf, u16 len) > @@ -339,7 +357,7 @@ static struct serdev_device_ops gb_beagleplay_ops = { > static int gb_message_send(struct gb_host_device *hd, u16 cport, struct gb_message *msg, gfp_t mask) > { > struct gb_beagleplay *bg = dev_get_drvdata(&hd->dev); > - struct hdlc_payload payloads[2]; > + struct hdlc_payload payloads[3]; why 3? It's ok to put this on the stack? > __le16 cport_id = le16_to_cpu(cport); > > dev_dbg(&hd->dev, "Sending greybus message with Operation %u, Type: %X on Cport %u", > @@ -348,14 +366,14 @@ static int gb_message_send(struct gb_host_device *hd, u16 cport, struct gb_messa > if (le16_to_cpu(msg->header->size) > RX_HDLC_PAYLOAD) > return dev_err_probe(&hd->dev, -E2BIG, "Greybus message too big"); > > - memcpy(msg->header->pad, &cport_id, sizeof(cport_id)); > - > - payloads[0].buf = msg->header; > - payloads[0].len = sizeof(*msg->header); > - payloads[1].buf = msg->payload; > - payloads[1].len = msg->payload_size; > + payloads[0].buf = &cport_id; > + payloads[0].len = sizeof(cport_id); > + payloads[1].buf = msg->header; > + payloads[1].len = sizeof(*msg->header); > + payloads[2].buf = msg->payload; > + payloads[2].len = msg->payload_size; So you send the cport number as the first message? Don't you need to document this somewhere? thanks, greg k-h
>> + * >> + * @cport: cport id >> + * @hdr: greybus operation header >> + * @payload: greybus message payload >> + */ >> +struct hdlc_greybus_frame { >> + __le16 cport; >> + struct gb_operation_msg_hdr hdr; >> + u8 payload[]; >> +} __packed; >> + >> static void hdlc_rx_greybus_frame(struct gb_beagleplay *bg, u8 *buf, u16 len) >> { >> - u16 cport_id; >> - struct gb_operation_msg_hdr *hdr = (struct gb_operation_msg_hdr *)buf; >> + struct hdlc_greybus_frame *gb_frame = (struct hdlc_greybus_frame *)buf; >> + u16 cport_id = le16_to_cpu(gb_frame->cport); >> >> - memcpy(&cport_id, hdr->pad, sizeof(cport_id)); >> + /* Ensure that the greybus message is valid */ >> + if (le16_to_cpu(gb_frame->hdr.size) > len - sizeof(cport_id)) { >> + dev_warn_ratelimited(&bg->sd->dev, "Invalid/Incomplete greybus message"); > Don't spam the kernel log for corrupted data on the line, that would be > a mess. Use a tracepoint? > >> + return; >> + } >> >> dev_dbg(&bg->sd->dev, "Greybus Operation %u type %X cport %u status %u received", >> - hdr->operation_id, hdr->type, le16_to_cpu(cport_id), hdr->result); >> + gb_frame->hdr.operation_id, gb_frame->hdr.type, cport_id, gb_frame->hdr.result); > Better yet, put the error in the debug message? Shouldn't corrupt data be a warning rather than debug message, since it indicates something wrong with the transport? >> >> - greybus_data_rcvd(bg->gb_hd, le16_to_cpu(cport_id), buf, len); >> + greybus_data_rcvd(bg->gb_hd, cport_id, &buf[sizeof(cport_id)], > Fun with pointer math. This feels really fragile, why not just point to > the field instead? It seems that taking address of members of packed structures is not valid. I get the `address-of-packed-member` warnings. Is it fine to ignore those in kernel? >> } >> >> static void hdlc_rx_dbg_frame(const struct gb_beagleplay *bg, const char *buf, u16 len) >> @@ -339,7 +357,7 @@ static struct serdev_device_ops gb_beagleplay_ops = { >> static int gb_message_send(struct gb_host_device *hd, u16 cport, struct gb_message *msg, gfp_t mask) >> { >> struct gb_beagleplay *bg = dev_get_drvdata(&hd->dev); >> - struct hdlc_payload payloads[2]; >> + struct hdlc_payload payloads[3]; > why 3? > > It's ok to put this on the stack? Well, the HDLC payload is just to store the length of the payload along with a pointer to its data. (kind of emulate a fat pointer). The reason for doing it this way is to avoid having to create a temp buffer for each message when sending data over UART (which was done in the initial version of the driver). Ayush Singh
On Thu, Dec 07, 2023 at 10:33:54PM +0530, Ayush Singh wrote: > > > + * > > > + * @cport: cport id > > > + * @hdr: greybus operation header > > > + * @payload: greybus message payload > > > + */ > > > +struct hdlc_greybus_frame { > > > + __le16 cport; > > > + struct gb_operation_msg_hdr hdr; > > > + u8 payload[]; > > > +} __packed; > > > + > > > static void hdlc_rx_greybus_frame(struct gb_beagleplay *bg, u8 *buf, u16 len) > > > { > > > - u16 cport_id; > > > - struct gb_operation_msg_hdr *hdr = (struct gb_operation_msg_hdr *)buf; > > > + struct hdlc_greybus_frame *gb_frame = (struct hdlc_greybus_frame *)buf; > > > + u16 cport_id = le16_to_cpu(gb_frame->cport); > > > - memcpy(&cport_id, hdr->pad, sizeof(cport_id)); > > > + /* Ensure that the greybus message is valid */ > > > + if (le16_to_cpu(gb_frame->hdr.size) > len - sizeof(cport_id)) { > > > + dev_warn_ratelimited(&bg->sd->dev, "Invalid/Incomplete greybus message"); > > Don't spam the kernel log for corrupted data on the line, that would be > > a mess. Use a tracepoint? > > > > > + return; > > > + } > > > dev_dbg(&bg->sd->dev, "Greybus Operation %u type %X cport %u status %u received", > > > - hdr->operation_id, hdr->type, le16_to_cpu(cport_id), hdr->result); > > > + gb_frame->hdr.operation_id, gb_frame->hdr.type, cport_id, gb_frame->hdr.result); > > Better yet, put the error in the debug message? > Shouldn't corrupt data be a warning rather than debug message, since it > indicates something wrong with the transport? Do you want messages like that spamming the kernel log all the time if a network connection is corrupted? Just handle the error and let the upper layers deal with it when the problem is eventually reported to userspace, that's all that is needed. > > > - greybus_data_rcvd(bg->gb_hd, le16_to_cpu(cport_id), buf, len); > > > + greybus_data_rcvd(bg->gb_hd, cport_id, &buf[sizeof(cport_id)], > > Fun with pointer math. This feels really fragile, why not just point to > > the field instead? > It seems that taking address of members of packed structures is not valid. That feels really odd. > I get the `address-of-packed-member` warnings. Is it fine to ignore > those in kernel? What error exactly are you getting? Packed or not does not mean anything to the address of a member. If it does, perhaps you are doing something wrong as you are really doing the same thing here, right? Don't ignore the warning by open-coding it. > > > } > > > static void hdlc_rx_dbg_frame(const struct gb_beagleplay *bg, const char *buf, u16 len) > > > @@ -339,7 +357,7 @@ static struct serdev_device_ops gb_beagleplay_ops = { > > > static int gb_message_send(struct gb_host_device *hd, u16 cport, struct gb_message *msg, gfp_t mask) > > > { > > > struct gb_beagleplay *bg = dev_get_drvdata(&hd->dev); > > > - struct hdlc_payload payloads[2]; > > > + struct hdlc_payload payloads[3]; > > why 3? > > > > It's ok to put this on the stack? > > Well, the HDLC payload is just to store the length of the payload along with > a pointer to its data. (kind of emulate a fat pointer). The reason for doing > it this way is to avoid having to create a temp buffer for each message when > sending data over UART (which was done in the initial version of the > driver). Be careful, are you SURE you are allowed to send stack-allocated data? I know that many busses forbid this (like USB). So please check to be sure that this is ok to do, and that these are not huge structures that you are putting on the very-limited kernel-stack. thanks, greg k-h
On 12/8/23 11:03, Greg KH wrote: > On Thu, Dec 07, 2023 at 10:33:54PM +0530, Ayush Singh wrote: >>>> + * >>>> + * @cport: cport id >>>> + * @hdr: greybus operation header >>>> + * @payload: greybus message payload >>>> + */ >>>> +struct hdlc_greybus_frame { >>>> + __le16 cport; >>>> + struct gb_operation_msg_hdr hdr; >>>> + u8 payload[]; >>>> +} __packed; >>>> + >>>> static void hdlc_rx_greybus_frame(struct gb_beagleplay *bg, u8 *buf, u16 len) >>>> { >>>> - u16 cport_id; >>>> - struct gb_operation_msg_hdr *hdr = (struct gb_operation_msg_hdr *)buf; >>>> + struct hdlc_greybus_frame *gb_frame = (struct hdlc_greybus_frame *)buf; >>>> + u16 cport_id = le16_to_cpu(gb_frame->cport); >>>> - memcpy(&cport_id, hdr->pad, sizeof(cport_id)); >>>> + /* Ensure that the greybus message is valid */ >>>> + if (le16_to_cpu(gb_frame->hdr.size) > len - sizeof(cport_id)) { >>>> + dev_warn_ratelimited(&bg->sd->dev, "Invalid/Incomplete greybus message"); >>> Don't spam the kernel log for corrupted data on the line, that would be >>> a mess. Use a tracepoint? >>> >>>> + return; >>>> + } >>>> dev_dbg(&bg->sd->dev, "Greybus Operation %u type %X cport %u status %u received", >>>> - hdr->operation_id, hdr->type, le16_to_cpu(cport_id), hdr->result); >>>> + gb_frame->hdr.operation_id, gb_frame->hdr.type, cport_id, gb_frame->hdr.result); >>> Better yet, put the error in the debug message? >> Shouldn't corrupt data be a warning rather than debug message, since it >> indicates something wrong with the transport? > Do you want messages like that spamming the kernel log all the time if a > network connection is corrupted? > > Just handle the error and let the upper layers deal with it when the > problem is eventually reported to userspace, that's all that is needed. Ok >>>> - greybus_data_rcvd(bg->gb_hd, le16_to_cpu(cport_id), buf, len); >>>> + greybus_data_rcvd(bg->gb_hd, cport_id, &buf[sizeof(cport_id)], >>> Fun with pointer math. This feels really fragile, why not just point to >>> the field instead? >> It seems that taking address of members of packed structures is not valid. > That feels really odd. > >> I get the `address-of-packed-member` warnings. Is it fine to ignore >> those in kernel? > What error exactly are you getting? Packed or not does not mean > anything to the address of a member. If it does, perhaps you are doing > something wrong as you are really doing the same thing here, right? > Don't ignore the warning by open-coding it. So, the error I was getting was `taking address of packed member of 'gb_frame' may result in an unaligned pointer value`. I can no longer reproduce the warning, though. I think I accidentally fixed the reason somewhere along the line. >>>> } >>>> static void hdlc_rx_dbg_frame(const struct gb_beagleplay *bg, const char *buf, u16 len) >>>> @@ -339,7 +357,7 @@ static struct serdev_device_ops gb_beagleplay_ops = { >>>> static int gb_message_send(struct gb_host_device *hd, u16 cport, struct gb_message *msg, gfp_t mask) >>>> { >>>> struct gb_beagleplay *bg = dev_get_drvdata(&hd->dev); >>>> - struct hdlc_payload payloads[2]; >>>> + struct hdlc_payload payloads[3]; >>> why 3? >>> >>> It's ok to put this on the stack? >> Well, the HDLC payload is just to store the length of the payload along with >> a pointer to its data. (kind of emulate a fat pointer). The reason for doing >> it this way is to avoid having to create a temp buffer for each message when >> sending data over UART (which was done in the initial version of the >> driver). > Be careful, are you SURE you are allowed to send stack-allocated data? > I know that many busses forbid this (like USB). So please check to be > sure that this is ok to do, and that these are not huge structures that > you are putting on the very-limited kernel-stack. Well, the greybus operation header and greybus message are not on the stack (as far as I know, since they are inputs to the function). The memory that is stack allocated for hdlc_payload array is `3 * (sizeof(u16) + sizeof(void *))`, i.e. 30 bytes for 64 bit pointers (ignoring any padding). So I don't think the size of hdlc_payload array should be an issue. The function `hdlc_tx_frames(bg, ADDRESS_GREYBUS, 0x03, payloads, 3);` actually copies the data to a different circ_buf, which is sent later by workqueue. So the final data sent is not stack allocated. In fact, none of the data from this function is going to be referenced after the call to `hdlc_tx_frames`. Ayush Singh
diff --git a/drivers/greybus/gb-beagleplay.c b/drivers/greybus/gb-beagleplay.c index 1e70ff7e3da4..fb40ade9364f 100644 --- a/drivers/greybus/gb-beagleplay.c +++ b/drivers/greybus/gb-beagleplay.c @@ -85,17 +85,35 @@ struct hdlc_payload { void *buf; }; +/** + * struct hdlc_greybus_frame - Structure to represent greybus HDLC frame + * + * @cport: cport id + * @hdr: greybus operation header + * @payload: greybus message payload + */ +struct hdlc_greybus_frame { + __le16 cport; + struct gb_operation_msg_hdr hdr; + u8 payload[]; +} __packed; + static void hdlc_rx_greybus_frame(struct gb_beagleplay *bg, u8 *buf, u16 len) { - u16 cport_id; - struct gb_operation_msg_hdr *hdr = (struct gb_operation_msg_hdr *)buf; + struct hdlc_greybus_frame *gb_frame = (struct hdlc_greybus_frame *)buf; + u16 cport_id = le16_to_cpu(gb_frame->cport); - memcpy(&cport_id, hdr->pad, sizeof(cport_id)); + /* Ensure that the greybus message is valid */ + if (le16_to_cpu(gb_frame->hdr.size) > len - sizeof(cport_id)) { + dev_warn_ratelimited(&bg->sd->dev, "Invalid/Incomplete greybus message"); + return; + } dev_dbg(&bg->sd->dev, "Greybus Operation %u type %X cport %u status %u received", - hdr->operation_id, hdr->type, le16_to_cpu(cport_id), hdr->result); + gb_frame->hdr.operation_id, gb_frame->hdr.type, cport_id, gb_frame->hdr.result); - greybus_data_rcvd(bg->gb_hd, le16_to_cpu(cport_id), buf, len); + greybus_data_rcvd(bg->gb_hd, cport_id, &buf[sizeof(cport_id)], + le16_to_cpu(gb_frame->hdr.size)); } static void hdlc_rx_dbg_frame(const struct gb_beagleplay *bg, const char *buf, u16 len) @@ -339,7 +357,7 @@ static struct serdev_device_ops gb_beagleplay_ops = { static int gb_message_send(struct gb_host_device *hd, u16 cport, struct gb_message *msg, gfp_t mask) { struct gb_beagleplay *bg = dev_get_drvdata(&hd->dev); - struct hdlc_payload payloads[2]; + struct hdlc_payload payloads[3]; __le16 cport_id = le16_to_cpu(cport); dev_dbg(&hd->dev, "Sending greybus message with Operation %u, Type: %X on Cport %u", @@ -348,14 +366,14 @@ static int gb_message_send(struct gb_host_device *hd, u16 cport, struct gb_messa if (le16_to_cpu(msg->header->size) > RX_HDLC_PAYLOAD) return dev_err_probe(&hd->dev, -E2BIG, "Greybus message too big"); - memcpy(msg->header->pad, &cport_id, sizeof(cport_id)); - - payloads[0].buf = msg->header; - payloads[0].len = sizeof(*msg->header); - payloads[1].buf = msg->payload; - payloads[1].len = msg->payload_size; + payloads[0].buf = &cport_id; + payloads[0].len = sizeof(cport_id); + payloads[1].buf = msg->header; + payloads[1].len = sizeof(*msg->header); + payloads[2].buf = msg->payload; + payloads[2].len = msg->payload_size; - hdlc_tx_frames(bg, ADDRESS_GREYBUS, 0x03, payloads, 2); + hdlc_tx_frames(bg, ADDRESS_GREYBUS, 0x03, payloads, 3); greybus_message_sent(bg->gb_hd, msg, 0); return 0;