Re: [PATCH v6 14/14] platform/x86: dell-smbios-wmi: introduce userspace interface
From: kbuild test robot
Date: Wed Oct 11 2017 - 21:17:19 EST
Hi Mario,
[auto build test WARNING on platform-drivers-x86/for-next]
[also build test WARNING on next-20171009]
[cannot apply to v4.14-rc4]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Mario-Limonciello/Introduce-support-for-Dell-SMBIOS-over-WMI/20171012-082742
base: git://git.infradead.org/users/dvhart/linux-platform-drivers-x86.git for-next
config: x86_64-randconfig-x018-201741 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
In file included from include/linux/kobject.h:21:0,
from include/linux/dmi.h:5,
from drivers/platform/x86/dell-smbios-wmi.c:12:
drivers/platform/x86/dell-smbios-wmi.c: In function 'dell_smbios_wmi_probe':
include/linux/sysfs.h:54:8: error: 'struct device_attribute' has no member named 'key'
(attr)->key = &__key; \
^
>> drivers/platform/x86/dell-smbios-wmi.c:207:2: note: in expansion of macro 'sysfs_attr_init'
sysfs_attr_init(&priv->req_buf_size_attr);
^~~~~~~~~~~~~~~
vim +/sysfs_attr_init +207 drivers/platform/x86/dell-smbios-wmi.c
11
> 12 #include <linux/dmi.h>
13 #include <linux/list.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/uaccess.h>
17 #include <linux/wmi.h>
18 #include <uapi/linux/dell-smbios.h>
19 #include "dell-smbios.h"
20 #include "dell-wmi-descriptor.h"
21 static DEFINE_MUTEX(call_mutex);
22 static DEFINE_MUTEX(list_mutex);
23 static int wmi_supported;
24
25 struct misc_bios_flags_structure {
26 struct dmi_header header;
27 u16 flags0;
28 } __packed;
29 #define FLAG_HAS_ACPI_WMI 0x02
30
31 #define DELL_WMI_SMBIOS_GUID "A80593CE-A997-11DA-B012-B622A1EF5492"
32
33 struct wmi_smbios_priv {
34 struct wmi_smbios_buffer *buf;
35 struct device_attribute req_buf_size_attr;
36 struct list_head list;
37 struct wmi_device *wdev;
38 struct device *child;
39 u32 req_buf_size;
40 };
41 static LIST_HEAD(wmi_list);
42
43 static inline struct wmi_smbios_priv *get_first_smbios_priv(void)
44 {
45 return list_first_entry_or_null(&wmi_list,
46 struct wmi_smbios_priv,
47 list);
48 }
49
50 static int run_smbios_call(struct wmi_device *wdev)
51 {
52 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
53 struct wmi_smbios_priv *priv;
54 struct acpi_buffer input;
55 union acpi_object *obj;
56 acpi_status status;
57
58 priv = dev_get_drvdata(&wdev->dev);
59 input.length = priv->req_buf_size;
60 input.pointer = &priv->buf->std;
61
62 dev_dbg(&wdev->dev, "evaluating: %x/%x [%x,%x,%x,%x]\n",
63 priv->buf->std.class, priv->buf->std.select,
64 priv->buf->std.input[0], priv->buf->std.input[1],
65 priv->buf->std.input[2], priv->buf->std.input[3]);
66
67 status = wmidev_evaluate_method(wdev, 0, 1, &input, &output);
68 if (ACPI_FAILURE(status))
69 return -EIO;
70 obj = (union acpi_object *)output.pointer;
71 if (obj->type != ACPI_TYPE_BUFFER) {
72 dev_dbg(&wdev->dev, "received type: %d\n", obj->type);
73 if (obj->type == ACPI_TYPE_INTEGER)
74 dev_dbg(&wdev->dev, "SMBIOS call failed: %llu\n",
75 obj->integer.value);
76 return -EIO;
77 }
78 memcpy(&priv->buf->std, obj->buffer.pointer, obj->buffer.length);
79
80 return 0;
81 }
82
83 int dell_smbios_wmi_call(struct calling_interface_buffer *buffer)
84 {
85 struct wmi_smbios_priv *priv;
86 size_t difference;
87 size_t size;
88 int ret;
89
90 priv = get_first_smbios_priv();
91 if (!priv)
92 return -ENODEV;
93
94 size = sizeof(struct calling_interface_buffer);
95 difference = priv->req_buf_size - sizeof(u64) - size;
96
97 mutex_lock(&call_mutex);
98 memset(&priv->buf->ext, 0, difference);
99 memcpy(&priv->buf->std, buffer, size);
100 ret = run_smbios_call(priv->wdev);
101 memcpy(buffer, &priv->buf->std, size);
102 mutex_unlock(&call_mutex);
103
104 return ret;
105 }
106
107 static long dell_smbios_wmi_ioctl(struct wmi_device *wdev, unsigned int cmd,
108 unsigned long arg)
109 {
110 struct wmi_smbios_buffer __user *input =
111 (struct wmi_smbios_buffer __user *) arg;
112 struct wmi_smbios_priv *priv;
113 int ret = 0;
114 u64 size;
115
116 switch (cmd) {
117 case DELL_WMI_SMBIOS_CMD:
118 priv = dev_get_drvdata(&wdev->dev);
119 if (!priv)
120 return -ENODEV;
121 mutex_lock(&call_mutex);
122 /* read the size that userspace is sending */
123 if (get_user(size, &input->length)) {
124 dev_dbg(&wdev->dev, "Read length from user failed\n");
125 ret = -EFAULT;
126 goto fail_smbios_cmd;
127 }
128 /* if it's too big, this is OK, we'll only use what we need */
129 if (size > priv->req_buf_size)
130 dev_warn(&wdev->dev,
131 "Buffer %lld is bigger than required %d\n",
132 size, priv->req_buf_size);
133 /* if it's too small, abort */
134 if (size < priv->req_buf_size) {
135 dev_err(&wdev->dev,
136 "Buffer %lld too small, need at least %d\n",
137 size, priv->req_buf_size);
138 ret = -EINVAL;
139 goto fail_smbios_cmd;
140 }
141 /* read the structure from userspace */
142 if (copy_from_user(priv->buf, input, priv->req_buf_size)) {
143 dev_dbg(&wdev->dev, "Copy %llu from user failed\n",
144 size);
145 ret = -EFAULT;
146 goto fail_smbios_cmd;
147 }
148 /* check for any calls we should avoid */
149 if (dell_smbios_call_filter(&wdev->dev, &priv->buf->std)) {
150 dev_err(&wdev->dev, "Invalid call %d/%d:%8x\n",
151 priv->buf->std.class, priv->buf->std.select,
152 priv->buf->std.input[0]);
153 ret = -EFAULT;
154 goto fail_smbios_cmd;
155 }
156 ret = run_smbios_call(priv->wdev);
157 if (ret != 0)
158 goto fail_smbios_cmd;
159 /* return the result (only up to our internal buffer size) */
160 if (copy_to_user(input, priv->buf, priv->req_buf_size)) {
161 dev_dbg(&wdev->dev, "Copy %d to user failed\n",
162 priv->req_buf_size);
163 ret = -EFAULT;
164 }
165 fail_smbios_cmd:
166 mutex_unlock(&call_mutex);
167 break;
168 default:
169 dev_dbg(&wdev->dev, "unsupported ioctl: %d [%d, %d, %d, %d].\n",
170 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd),
171 _IOC_SIZE(cmd));
172 ret = -ENOIOCTLCMD;
173 }
174 return ret;
175 }
176
177 static ssize_t req_buf_size_show(struct device *dev,
178 struct device_attribute *attr, char *buf)
179 {
180 struct wmi_smbios_priv *priv = dev_get_drvdata(dev);
181
182 return sprintf(buf, "%d\n", priv->req_buf_size);
183 }
184
185 static int dell_smbios_wmi_probe(struct wmi_device *wdev)
186 {
187 struct wmi_smbios_priv *priv;
188 int count;
189 int ret;
190
191 priv = devm_kzalloc(&wdev->dev, sizeof(struct wmi_smbios_priv),
192 GFP_KERNEL);
193 if (!priv)
194 return -ENOMEM;
195
196 /* WMI buffer size will be either 4k or 32k depending on machine */
197 if (!dell_wmi_get_size(&priv->req_buf_size))
198 return -EINVAL;
199 /* add in the length object we will use internally with ioctl */
200 priv->req_buf_size += sizeof(u64);
201
202 count = get_order(priv->req_buf_size);
203 priv->buf = (void *)__get_free_pages(GFP_KERNEL, count);
204 if (!priv->buf)
205 return -ENOMEM;
206
> 207 sysfs_attr_init(&priv->req_buf_size_attr);
208 priv->req_buf_size_attr.attr.name = "required_buffer_size";
209 priv->req_buf_size_attr.attr.mode = 0444;
210 priv->req_buf_size_attr.show = req_buf_size_show;
211
212 ret = device_create_file(&wdev->dev, &priv->req_buf_size_attr);
213 if (ret)
214 goto fail_create_sysfs;
215
216 /* ID is used by dell-smbios to set priority of drivers */
217 wdev->dev.id = 1;
218 ret = dell_smbios_register_device(&wdev->dev, &dell_smbios_wmi_call);
219 if (ret)
220 goto fail_register;
221
222 priv->wdev = wdev;
223 dev_set_drvdata(&wdev->dev, priv);
224 mutex_lock(&list_mutex);
225 list_add_tail(&priv->list, &wmi_list);
226 mutex_unlock(&list_mutex);
227
228 return 0;
229
230 fail_register:
231 device_remove_file(&wdev->dev, &priv->req_buf_size_attr);
232
233 fail_create_sysfs:
234 free_pages((unsigned long)priv->buf, count);
235 return ret;
236 }
237
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Attachment:
.config.gz
Description: application/gzip