From patchwork Thu Dec 7 22:26:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Armin Wolf X-Patchwork-Id: 175458 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:bcd1:0:b0:403:3b70:6f57 with SMTP id r17csp5101047vqy; Thu, 7 Dec 2023 14:27:37 -0800 (PST) X-Google-Smtp-Source: AGHT+IGw+chU38KHYyw5tChcbfb9oLv74tDG6WGtFgr5pBtKOO6LhyiAkddWB+aZuEjCO2drwI0p X-Received: by 2002:a05:6a20:4308:b0:18f:97c:9269 with SMTP id h8-20020a056a20430800b0018f097c9269mr3296965pzk.78.1701988056925; Thu, 07 Dec 2023 14:27:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701988056; cv=none; d=google.com; s=arc-20160816; b=GiAMLa56rJofYlCefBCtDnUzlPFHo1L2LPdLBRZARGRzLbotWrmhzktDy5k5Nm0m4b 7szl6aptY+GJ5iEmuArEfcA50OJWYcNslHGCikHvutcoAevLsDrE6Ll83LuCxaXhkwET rTtxO2v5fN50zho2BafeIr1OrhVcbXBaUnBpF6Mn6ViHwvgRRThRyUEEhyAo7t5Bkg1g jy8T7N24bTrr1/STYe203oHtgCISYWIbWWt98qSl9oT5mw843hQmEOSIx33zq6lM0EMa Uuzy41wDy1tuDtAxwXo+NQ1Y8pL5VYtlyNc3YO4BmQwuahaiFnwnrutG8JRWnh11YbjN hO/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:ui-outboundreport:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=IxEcCdhwKE0K5SWUG6FXi6xzkVCAvu2qlIJhctthqTE=; fh=li8yxIESWfZR7lmBO8wCmgOg4WdXsWPyQvEuWPhaOvo=; b=E/ruk0IqTtNGOriHwH4ENfWjz8JacFkBCyDZ3Tod29QqcLlN0WHPdj6YaCLEoHg8qm Z+PzIYxgsDFdiACs9Qpe2u/BFx4i40bUplZKN9olDttDC9miJLcXqXj98HPSkqtoYX7v n2ItGyk85FbrnZhWp+aM07ttnrIjq3cakoF9OY1/vQxhx4xi/AuvoRq0XCNSacSFu9pP UwR2vsyAmm8QuUNdc2/fIvT24JD311epEg8LnCQRfoPabE/wvdSdeRtHalz1HM9Bdjm8 6zilcQxxznuuvc0NDYZAY+OUNWJ7RvX0nnZyRMUJ5xiiJgWggX+S7ytsUgjkgMdFBQF9 cMyQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmx.de header.s=s31663417 header.b=pBj4b30H; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=gmx.de Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id by26-20020a056a02059a00b005c6832282f7si412590pgb.304.2023.12.07.14.27.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Dec 2023 14:27:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@gmx.de header.s=s31663417 header.b=pBj4b30H; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=gmx.de Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id ACC8480CF547; Thu, 7 Dec 2023 14:27:08 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235331AbjLGW05 (ORCPT + 99 others); Thu, 7 Dec 2023 17:26:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232173AbjLGW0y (ORCPT ); Thu, 7 Dec 2023 17:26:54 -0500 Received: from mout.gmx.net (mout.gmx.net [212.227.15.19]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B56D9D4A; Thu, 7 Dec 2023 14:26:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.de; s=s31663417; t=1701988006; x=1702592806; i=w_armin@gmx.de; bh=MnUO2eCpHcRNIigISNlEI4luU9Ds7WfsIdhVMY51GBw=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To: References; b=pBj4b30HkNOjwopaKjz/TpjTXy/Y2S+mMH4Gs0lwRbojyJrI6+AHiDqzOEjO9fv0 QRQ5ytwH1n8MOMXU6Px3+LR7ib2OUIbbblz0/I0InXw1HCGmFgwmVGgRoUkS44jbr gS2IzxApthbrFW3oKJ/nH1jVcFSA1rHLWAGPJlrVq28vpopR3or125AXFuZK01lfA A4UIZoud+v4VVVELV/mafh7Ldkq+1gkOI3mq8XsxbwT2uzukPfRm5ss1Mp10C7su7 Tj9fbM/ooFtvT+UuhfX0Rwp++nEuLNIucx7/AhJe7QqTUFwLlxybkMfGEr+Pl/y2K wKc8kY2WDAMNvOkohA== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from mx-amd-b650.users.agdsn.de ([141.30.226.129]) by mail.gmx.net (mrgmx004 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MsHns-1rUgtr4AFW-00thG4; Thu, 07 Dec 2023 23:26:46 +0100 From: Armin Wolf To: hdegoede@redhat.com, ilpo.jarvinen@linux.intel.com, corbet@lwn.net Cc: Dell.Client.Kernel@dell.com, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/5] platform/x86: dell-smbios-wmi: Stop using WMI chardev Date: Thu, 7 Dec 2023 23:26:21 +0100 Message-Id: <20231207222623.232074-4-W_Armin@gmx.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231207222623.232074-1-W_Armin@gmx.de> References: <20231207222623.232074-1-W_Armin@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:uMW+ajDxQVUrTn75NdD8r7vsu6sJ0GR05zZ5AGuPswH/RdF0B64 i7Z+cedGKgj/tfuMT9D5V1imqW+EGmtN/UZmfYaYQbXPcTA9s4oflHxhSg4N1GUKNELNgo6 qnhh1imosWhOk8WTeDqJqbFxiFjOMyd3Ji8rIfwaJo8WtYo9lkONBrG6hx1xSXkfDOCyg3+ 3nE4S8F0uY9ONN9iflwzw== UI-OutboundReport: notjunk:1;M01:P0:vyVUJwqyVBQ=;o4t0zqpF4O/QIj1D1hpu8mLFA0I 5HnT/+40eWglt+OBtHXBDK6jTdfMZXoc4kF2zj/FbR4lm6cbE/6B2oiYzUB3EmH40dKc1XaFQ pNMJfFSLbNU3VIiOXxGJTEbKJ40QyIF33SsvQ+OUNzGw8uBnOkfBxarf1VFc789TvNxCt3Ry4 aB2SqhTBi6B6lN/kLERXs574aXjw64ncCu6jQj21RyFT4a8VAiFnzbUKrzYg5VzU+jpfrf8/e E+1Ev/jBZz2L6vhN3HY7VBGo0jXs+LdfFP3K3SYdUwKX4+QcIyIC9l7WxLIfK2JDgqgz3QIwN rBwZQ9MmJZQOXIMs2EgK8OQV5ZY47BwaOphwN17TSxl1YVCx8nTUovMEfkPCbVrNNMfkJVmW1 F012IMFeK2fO903f95A9mm3FbVwWac7TeZvr6aUxXy940WE0fJ4lz56gjlt38aM5xbpcPuo/j bJtIO7S0hLcuVDgE+QLFmNBC1byafbyLrbillHX1IP9xDN9FwOAJ3D6O+IorCJ6DeyREr/eFZ nWVV5rJyqNzXI/OVisHNDW28sCvGgswR6qEOLrqwxAJbwlE2KlNLswlFYiDnTUD0ujppMZFsn kHaw8phcKDebgJW2HT+uwyWqQnSNPWseaYFuudP2FIxBYBXu6Q6qMQBGdy/PNdGq7SUIGNNqr YD9F2N8JfPaFQVCluBqRrJ/9hLDbpNep+cUHwUAPGOlbNOO3mMB9mE17ez6kjhMDoy6EAMVqa 7DYMWx8fCdotoTyzb82woUBGdL0JnkdPgV+QizJzABqALi/mWdFT3+jipwCatbk4LjN0ByHxH 3taIsAVKV0Dg5EqJbhdouRTVXWty58PrL5InyC7phv1mqGvoOjBGe+k1dJK9d1qVdYLMmfks5 1J2eMZaEMOU9yIaD83Nk4n8ltGZD1VJQ2YIPAUq3+qLzI1daNSCFdSgKcePiVb3tYVZHaYrGv NPGdxKXLJc8APHUt9ACs7sVnXQ0= X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Thu, 07 Dec 2023 14:27:08 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1784663828544871113 X-GMAIL-MSGID: 1784663828544871113 The WMI chardev API will be removed in the near future. Reimplement the necessary bits used by this driver so that userspace software depending on it does no break. Signed-off-by: Armin Wolf --- drivers/platform/x86/dell/dell-smbios-wmi.c | 163 ++++++++++++++------ 1 file changed, 117 insertions(+), 46 deletions(-) -- 2.39.2 diff --git a/drivers/platform/x86/dell/dell-smbios-wmi.c b/drivers/platform/x86/dell/dell-smbios-wmi.c index 931cc50136de..61f40f462eca 100644 --- a/drivers/platform/x86/dell/dell-smbios-wmi.c +++ b/drivers/platform/x86/dell/dell-smbios-wmi.c @@ -7,11 +7,14 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include +#include #include #include #include #include +#include #include "dell-smbios.h" #include "dell-wmi-descriptor.h" @@ -32,7 +35,9 @@ struct wmi_smbios_priv { struct list_head list; struct wmi_device *wdev; struct device *child; - u32 req_buf_size; + u64 req_buf_size; + u32 hotfix; + struct miscdevice char_dev; }; static LIST_HEAD(wmi_list); @@ -108,48 +113,106 @@ static int dell_smbios_wmi_call(struct calling_interface_buffer *buffer) return ret; } -static long dell_smbios_wmi_filter(struct wmi_device *wdev, unsigned int cmd, - struct wmi_ioctl_buffer *arg) +static int dell_smbios_wmi_open(struct inode *inode, struct file *filp) { struct wmi_smbios_priv *priv; - int ret = 0; - - switch (cmd) { - case DELL_WMI_SMBIOS_CMD: - mutex_lock(&call_mutex); - priv = dev_get_drvdata(&wdev->dev); - if (!priv) { - ret = -ENODEV; - goto fail_smbios_cmd; - } - memcpy(priv->buf, arg, priv->req_buf_size); - if (dell_smbios_call_filter(&wdev->dev, &priv->buf->std)) { - dev_err(&wdev->dev, "Invalid call %d/%d:%8x\n", - priv->buf->std.cmd_class, - priv->buf->std.cmd_select, - priv->buf->std.input[0]); - ret = -EFAULT; - goto fail_smbios_cmd; - } - ret = run_smbios_call(priv->wdev); - if (ret) - goto fail_smbios_cmd; - memcpy(arg, priv->buf, priv->req_buf_size); -fail_smbios_cmd: - mutex_unlock(&call_mutex); - break; - default: - ret = -ENOIOCTLCMD; + + priv = container_of(filp->private_data, struct wmi_smbios_priv, char_dev); + filp->private_data = priv; + + return nonseekable_open(inode, filp); +} + +static ssize_t dell_smbios_wmi_read(struct file *filp, char __user *buffer, size_t length, + loff_t *offset) +{ + struct wmi_smbios_priv *priv = filp->private_data; + + return simple_read_from_buffer(buffer, length, offset, &priv->req_buf_size, + sizeof(priv->req_buf_size)); +} + +static long dell_smbios_wmi_do_ioctl(struct wmi_smbios_priv *priv, + struct dell_wmi_smbios_buffer __user *arg) +{ + long ret; + + if (get_user(priv->buf->length, &arg->length)) + return -EFAULT; + + if (priv->buf->length < priv->req_buf_size) + return -EINVAL; + + /* if it's too big, warn, driver will only use what is needed */ + if (priv->buf->length > priv->req_buf_size) + dev_err(&priv->wdev->dev, "Buffer %llu is bigger than required %llu\n", + priv->buf->length, priv->req_buf_size); + + if (copy_from_user(priv->buf, arg, priv->req_buf_size)) + return -EFAULT; + + if (dell_smbios_call_filter(&priv->wdev->dev, &priv->buf->std)) { + dev_err(&priv->wdev->dev, "Invalid call %d/%d:%8x\n", + priv->buf->std.cmd_class, + priv->buf->std.cmd_select, + priv->buf->std.input[0]); + + return -EINVAL; } + + ret = run_smbios_call(priv->wdev); + if (ret) + return ret; + + if (copy_to_user(arg, priv->buf, priv->req_buf_size)) + return -EFAULT; + + return 0; +} + +static long dell_smbios_wmi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct dell_wmi_smbios_buffer __user *input = (struct dell_wmi_smbios_buffer __user *)arg; + struct wmi_smbios_priv *priv = filp->private_data; + long ret; + + if (cmd != DELL_WMI_SMBIOS_CMD) + return -ENOIOCTLCMD; + + mutex_lock(&call_mutex); + ret = dell_smbios_wmi_do_ioctl(priv, input); + mutex_unlock(&call_mutex); + return ret; } +static const struct file_operations dell_smbios_wmi_fops = { + .owner = THIS_MODULE, + .open = dell_smbios_wmi_open, + .read = dell_smbios_wmi_read, + .unlocked_ioctl = dell_smbios_wmi_ioctl, + .compat_ioctl = compat_ptr_ioctl, +}; + +static int dell_smbios_wmi_register_chardev(struct wmi_smbios_priv *priv) +{ + priv->char_dev.minor = MISC_DYNAMIC_MINOR; + priv->char_dev.name = "wmi/dell-smbios"; + priv->char_dev.fops = &dell_smbios_wmi_fops; + priv->char_dev.mode = 0444; + + return misc_register(&priv->char_dev); +} + +static void dell_smbios_wmi_unregister_chardev(struct wmi_smbios_priv *priv) +{ + misc_deregister(&priv->char_dev); +} + static int dell_smbios_wmi_probe(struct wmi_device *wdev, const void *context) { - struct wmi_driver *wdriver = - container_of(wdev->dev.driver, struct wmi_driver, driver); struct wmi_smbios_priv *priv; - u32 hotfix; + u32 buffer_size; int count; int ret; @@ -162,39 +225,44 @@ static int dell_smbios_wmi_probe(struct wmi_device *wdev, const void *context) if (!priv) return -ENOMEM; + priv->wdev = wdev; + dev_set_drvdata(&wdev->dev, priv); + /* WMI buffer size will be either 4k or 32k depending on machine */ - if (!dell_wmi_get_size(&priv->req_buf_size)) + if (!dell_wmi_get_size(&buffer_size)) return -EPROBE_DEFER; + priv->req_buf_size = buffer_size; + /* some SMBIOS calls fail unless BIOS contains hotfix */ - if (!dell_wmi_get_hotfix(&hotfix)) + if (!dell_wmi_get_hotfix(&priv->hotfix)) return -EPROBE_DEFER; - if (!hotfix) { + + if (!priv->hotfix) dev_warn(&wdev->dev, "WMI SMBIOS userspace interface not supported(%u), try upgrading to a newer BIOS\n", - hotfix); - wdriver->filter_callback = NULL; - } + priv->hotfix); /* add in the length object we will use internally with ioctl */ priv->req_buf_size += sizeof(u64); - ret = set_required_buffer_size(wdev, priv->req_buf_size); - if (ret) - return ret; count = get_order(priv->req_buf_size); priv->buf = (void *)__get_free_pages(GFP_KERNEL, count); if (!priv->buf) return -ENOMEM; + if (priv->hotfix) { + ret = dell_smbios_wmi_register_chardev(priv); + if (ret) + goto fail_chardev; + } + /* ID is used by dell-smbios to set priority of drivers */ wdev->dev.id = 1; ret = dell_smbios_register_device(&wdev->dev, &dell_smbios_wmi_call); if (ret) goto fail_register; - priv->wdev = wdev; - dev_set_drvdata(&wdev->dev, priv); mutex_lock(&list_mutex); list_add_tail(&priv->list, &wmi_list); mutex_unlock(&list_mutex); @@ -202,6 +270,9 @@ static int dell_smbios_wmi_probe(struct wmi_device *wdev, const void *context) return 0; fail_register: + if (priv->hotfix) + dell_smbios_wmi_unregister_chardev(priv); +fail_chardev: free_pages((unsigned long)priv->buf, count); return ret; } @@ -211,6 +282,7 @@ static void dell_smbios_wmi_remove(struct wmi_device *wdev) struct wmi_smbios_priv *priv = dev_get_drvdata(&wdev->dev); int count; + dell_smbios_wmi_unregister_chardev(priv); mutex_lock(&call_mutex); mutex_lock(&list_mutex); list_del(&priv->list); @@ -256,7 +328,6 @@ static struct wmi_driver dell_smbios_wmi_driver = { .probe = dell_smbios_wmi_probe, .remove = dell_smbios_wmi_remove, .id_table = dell_smbios_wmi_id_table, - .filter_callback = dell_smbios_wmi_filter, }; int init_dell_smbios_wmi(void)