summaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/genwqe/card_base.h1
-rw-r--r--drivers/misc/genwqe/card_utils.c12
-rw-r--r--drivers/misc/lkdtm_perms.c7
-rw-r--r--drivers/misc/mei/amthif.c2
-rw-r--r--drivers/misc/mei/bus-fixup.c98
-rw-r--r--drivers/misc/mei/bus.c18
-rw-r--r--drivers/misc/mei/client.c6
-rw-r--r--drivers/misc/mei/client.h2
-rw-r--r--drivers/misc/mei/main.c45
-rw-r--r--drivers/misc/mei/mei_dev.h15
10 files changed, 175 insertions, 31 deletions
diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h
index cb851c14ca4b..5813b5f25006 100644
--- a/drivers/misc/genwqe/card_base.h
+++ b/drivers/misc/genwqe/card_base.h
@@ -41,7 +41,6 @@
#include "genwqe_driver.h"
#define GENWQE_MSI_IRQS 4 /* Just one supported, no MSIx */
-#define GENWQE_FLAG_MSI_ENABLED (1 << 0)
#define GENWQE_MAX_VFS 15 /* maximum 15 VFs are possible */
#define GENWQE_MAX_FUNCS 16 /* 1 PF and 15 VFs */
diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c
index fc2794b513fa..147b83011b58 100644
--- a/drivers/misc/genwqe/card_utils.c
+++ b/drivers/misc/genwqe/card_utils.c
@@ -740,13 +740,10 @@ int genwqe_read_softreset(struct genwqe_dev *cd)
int genwqe_set_interrupt_capability(struct genwqe_dev *cd, int count)
{
int rc;
- struct pci_dev *pci_dev = cd->pci_dev;
- rc = pci_enable_msi_range(pci_dev, 1, count);
+ rc = pci_alloc_irq_vectors(cd->pci_dev, 1, count, PCI_IRQ_MSI);
if (rc < 0)
return rc;
-
- cd->flags |= GENWQE_FLAG_MSI_ENABLED;
return 0;
}
@@ -756,12 +753,7 @@ int genwqe_set_interrupt_capability(struct genwqe_dev *cd, int count)
*/
void genwqe_reset_interrupt_capability(struct genwqe_dev *cd)
{
- struct pci_dev *pci_dev = cd->pci_dev;
-
- if (cd->flags & GENWQE_FLAG_MSI_ENABLED) {
- pci_disable_msi(pci_dev);
- cd->flags &= ~GENWQE_FLAG_MSI_ENABLED;
- }
+ pci_free_irq_vectors(cd->pci_dev);
}
/**
diff --git a/drivers/misc/lkdtm_perms.c b/drivers/misc/lkdtm_perms.c
index 45f1c0f96612..c7635a79341f 100644
--- a/drivers/misc/lkdtm_perms.c
+++ b/drivers/misc/lkdtm_perms.c
@@ -60,15 +60,18 @@ static noinline void execute_location(void *dst, bool write)
static void execute_user_location(void *dst)
{
+ int copied;
+
/* Intentionally crossing kernel/user memory boundary. */
void (*func)(void) = dst;
pr_info("attempting ok execution at %p\n", do_nothing);
do_nothing();
- if (copy_to_user((void __user *)dst, do_nothing, EXEC_SIZE))
+ copied = access_process_vm(current, (unsigned long)dst, do_nothing,
+ EXEC_SIZE, FOLL_WRITE);
+ if (copied < EXEC_SIZE)
return;
- flush_icache_range((unsigned long)dst, (unsigned long)dst + EXEC_SIZE);
pr_info("attempting bad execution at %p\n", func);
func();
}
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 7ae89b4a21d5..466afb2611c6 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -144,7 +144,7 @@ int mei_amthif_run_next_cmd(struct mei_device *dev)
dev->iamthif_state = MEI_IAMTHIF_WRITING;
cl->fp = cb->fp;
- ret = mei_cl_write(cl, cb, false);
+ ret = mei_cl_write(cl, cb);
if (ret < 0)
return ret;
diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
index 75b9d4ac8b1e..7f2cef9011ae 100644
--- a/drivers/misc/mei/bus-fixup.c
+++ b/drivers/misc/mei/bus-fixup.c
@@ -38,6 +38,9 @@ static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO;
#define MEI_UUID_WD UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, \
0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB)
+#define MEI_UUID_MKHIF_FIX UUID_LE(0x55213584, 0x9a29, 0x4916, \
+ 0xba, 0xdf, 0xf, 0xb7, 0xed, 0x68, 0x2a, 0xeb)
+
#define MEI_UUID_ANY NULL_UUID_LE
/**
@@ -69,6 +72,97 @@ static void blacklist(struct mei_cl_device *cldev)
cldev->do_match = 0;
}
+#define OSTYPE_LINUX 2
+struct mei_os_ver {
+ __le16 build;
+ __le16 reserved1;
+ u8 os_type;
+ u8 major;
+ u8 minor;
+ u8 reserved2;
+} __packed;
+
+#define MKHI_FEATURE_PTT 0x10
+
+struct mkhi_rule_id {
+ __le16 rule_type;
+ u8 feature_id;
+ u8 reserved;
+} __packed;
+
+struct mkhi_fwcaps {
+ struct mkhi_rule_id id;
+ u8 len;
+ u8 data[0];
+} __packed;
+
+#define MKHI_FWCAPS_GROUP_ID 0x3
+#define MKHI_FWCAPS_SET_OS_VER_APP_RULE_CMD 6
+struct mkhi_msg_hdr {
+ u8 group_id;
+ u8 command;
+ u8 reserved;
+ u8 result;
+} __packed;
+
+struct mkhi_msg {
+ struct mkhi_msg_hdr hdr;
+ u8 data[0];
+} __packed;
+
+static int mei_osver(struct mei_cl_device *cldev)
+{
+ int ret;
+ const size_t size = sizeof(struct mkhi_msg_hdr) +
+ sizeof(struct mkhi_fwcaps) +
+ sizeof(struct mei_os_ver);
+ size_t length = 8;
+ char buf[size];
+ struct mkhi_msg *req;
+ struct mkhi_fwcaps *fwcaps;
+ struct mei_os_ver *os_ver;
+ unsigned int mode = MEI_CL_IO_TX_BLOCKING | MEI_CL_IO_TX_INTERNAL;
+
+ memset(buf, 0, size);
+
+ req = (struct mkhi_msg *)buf;
+ req->hdr.group_id = MKHI_FWCAPS_GROUP_ID;
+ req->hdr.command = MKHI_FWCAPS_SET_OS_VER_APP_RULE_CMD;
+
+ fwcaps = (struct mkhi_fwcaps *)req->data;
+
+ fwcaps->id.rule_type = 0x0;
+ fwcaps->id.feature_id = MKHI_FEATURE_PTT;
+ fwcaps->len = sizeof(*os_ver);
+ os_ver = (struct mei_os_ver *)fwcaps->data;
+ os_ver->os_type = OSTYPE_LINUX;
+
+ ret = __mei_cl_send(cldev->cl, buf, size, mode);
+ if (ret < 0)
+ return ret;
+
+ ret = __mei_cl_recv(cldev->cl, buf, length);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static void mei_mkhi_fix(struct mei_cl_device *cldev)
+{
+ int ret;
+
+ ret = mei_cldev_enable(cldev);
+ if (ret)
+ return;
+
+ ret = mei_osver(cldev);
+ if (ret)
+ dev_err(&cldev->dev, "OS version command failed %d\n", ret);
+
+ mei_cldev_disable(cldev);
+}
+
/**
* mei_wd - wd client on the bus, change protocol version
* as the API has changed.
@@ -162,7 +256,8 @@ static int mei_nfc_if_version(struct mei_cl *cl,
WARN_ON(mutex_is_locked(&bus->device_lock));
- ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(struct mei_nfc_cmd), 1);
+ ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(struct mei_nfc_cmd),
+ MEI_CL_IO_TX_BLOCKING);
if (ret < 0) {
dev_err(bus->dev, "Could not send IF version cmd\n");
return ret;
@@ -309,6 +404,7 @@ static struct mei_fixup {
MEI_FIXUP(MEI_UUID_NFC_INFO, blacklist),
MEI_FIXUP(MEI_UUID_NFC_HCI, mei_nfc),
MEI_FIXUP(MEI_UUID_WD, mei_wd),
+ MEI_FIXUP(MEI_UUID_MKHIF_FIX, mei_mkhi_fix),
};
/**
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 8cac7ef9ad0d..7c075e9b25e5 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -36,12 +36,12 @@
* @cl: host client
* @buf: buffer to send
* @length: buffer length
- * @blocking: wait for write completion
+ * @mode: sending mode
*
* Return: written size bytes or < 0 on error
*/
ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
- bool blocking)
+ unsigned int mode)
{
struct mei_device *bus;
struct mei_cl_cb *cb;
@@ -80,9 +80,11 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
goto out;
}
+ cb->internal = !!(mode & MEI_CL_IO_TX_INTERNAL);
+ cb->blocking = !!(mode & MEI_CL_IO_TX_BLOCKING);
memcpy(cb->buf.data, buf, length);
- rets = mei_cl_write(cl, cb, blocking);
+ rets = mei_cl_write(cl, cb);
out:
mutex_unlock(&bus->device_lock);
@@ -188,7 +190,7 @@ ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
if (cl == NULL)
return -ENODEV;
- return __mei_cl_send(cl, buf, length, 1);
+ return __mei_cl_send(cl, buf, length, MEI_CL_IO_TX_BLOCKING);
}
EXPORT_SYMBOL_GPL(mei_cldev_send);
@@ -228,7 +230,7 @@ static void mei_cl_bus_event_work(struct work_struct *work)
bus = cldev->bus;
if (cldev->event_cb)
- cldev->event_cb(cldev, cldev->events, cldev->event_context);
+ cldev->event_cb(cldev, cldev->events);
cldev->events = 0;
@@ -301,7 +303,6 @@ bool mei_cl_bus_rx_event(struct mei_cl *cl)
* @cldev: me client devices
* @event_cb: callback function
* @events_mask: requested events bitmask
- * @context: driver context data
*
* Return: 0 on success
* -EALREADY if an callback is already registered
@@ -309,7 +310,7 @@ bool mei_cl_bus_rx_event(struct mei_cl *cl)
*/
int mei_cldev_register_event_cb(struct mei_cl_device *cldev,
unsigned long events_mask,
- mei_cldev_event_cb_t event_cb, void *context)
+ mei_cldev_event_cb_t event_cb)
{
struct mei_device *bus = cldev->bus;
int ret;
@@ -320,7 +321,6 @@ int mei_cldev_register_event_cb(struct mei_cl_device *cldev,
cldev->events = 0;
cldev->events_mask = events_mask;
cldev->event_cb = event_cb;
- cldev->event_context = context;
INIT_WORK(&cldev->event_work, mei_cl_bus_event_work);
if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
@@ -483,7 +483,7 @@ int mei_cldev_disable(struct mei_cl_device *cldev)
mutex_lock(&bus->device_lock);
if (!mei_cl_is_connected(cl)) {
- dev_err(bus->dev, "Already disconnected");
+ dev_dbg(bus->dev, "Already disconnected");
err = 0;
goto out;
}
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 6fe02350578d..beb942e6c248 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -1598,18 +1598,17 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
*
* @cl: host client
* @cb: write callback with filled data
- * @blocking: block until completed
*
* Return: number of bytes sent on success, <0 on failure.
*/
-int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
+int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb)
{
struct mei_device *dev;
struct mei_msg_data *buf;
struct mei_msg_hdr mei_hdr;
int size;
int rets;
-
+ bool blocking;
if (WARN_ON(!cl || !cl->dev))
return -ENODEV;
@@ -1621,6 +1620,7 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
buf = &cb->buf;
size = buf->size;
+ blocking = cb->blocking;
cl_dbg(dev, cl, "size=%d\n", size);
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index d2bfabecd882..f2545af9be7b 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -219,7 +219,7 @@ int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb,
int mei_cl_read_start(struct mei_cl *cl, size_t length, const struct file *fp);
int mei_cl_irq_read_msg(struct mei_cl *cl, struct mei_msg_hdr *hdr,
struct mei_cl_cb *cmpl_list);
-int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
+int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb);
int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
struct mei_cl_cb *cmpl_list);
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index fa50635512e8..e1bf54481fd6 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -322,7 +322,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
goto out;
}
- rets = mei_cl_write(cl, cb, false);
+ rets = mei_cl_write(cl, cb);
out:
mutex_unlock(&dev->device_lock);
return rets;
@@ -653,7 +653,7 @@ static int mei_fasync(int fd, struct file *file, int band)
}
/**
- * fw_status_show - mei device attribute show method
+ * fw_status_show - mei device fw_status attribute show method
*
* @device: device pointer
* @attr: attribute pointer
@@ -684,8 +684,49 @@ static ssize_t fw_status_show(struct device *device,
}
static DEVICE_ATTR_RO(fw_status);
+/**
+ * hbm_ver_show - display HBM protocol version negotiated with FW
+ *
+ * @device: device pointer
+ * @attr: attribute pointer
+ * @buf: char out buffer
+ *
+ * Return: number of the bytes printed into buf or error
+ */
+static ssize_t hbm_ver_show(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ struct mei_device *dev = dev_get_drvdata(device);
+ struct hbm_version ver;
+
+ mutex_lock(&dev->device_lock);
+ ver = dev->version;
+ mutex_unlock(&dev->device_lock);
+
+ return sprintf(buf, "%u.%u\n", ver.major_version, ver.minor_version);
+}
+static DEVICE_ATTR_RO(hbm_ver);
+
+/**
+ * hbm_ver_drv_show - display HBM protocol version advertised by driver
+ *
+ * @device: device pointer
+ * @attr: attribute pointer
+ * @buf: char out buffer
+ *
+ * Return: number of the bytes printed into buf or error
+ */
+static ssize_t hbm_ver_drv_show(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u.%u\n", HBM_MAJOR_VERSION, HBM_MINOR_VERSION);
+}
+static DEVICE_ATTR_RO(hbm_ver_drv);
+
static struct attribute *mei_attrs[] = {
&dev_attr_fw_status.attr,
+ &dev_attr_hbm_ver.attr,
+ &dev_attr_hbm_ver_drv.attr,
NULL
};
ATTRIBUTE_GROUPS(mei);
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 1169fd9e7d02..d50f70b4a05e 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -109,6 +109,17 @@ enum mei_cb_file_ops {
MEI_FOP_NOTIFY_STOP,
};
+/**
+ * enum mei_cl_io_mode - io mode between driver and fw
+ *
+ * @MEI_CL_IO_TX_BLOCKING: send is blocking
+ * @MEI_CL_IO_TX_INTERNAL: internal communication between driver and FW
+ */
+enum mei_cl_io_mode {
+ MEI_CL_IO_TX_BLOCKING = BIT(0),
+ MEI_CL_IO_TX_INTERNAL = BIT(1),
+};
+
/*
* Intel MEI message data struct
*/
@@ -169,6 +180,7 @@ struct mei_cl;
* @fp: pointer to file structure
* @status: io status of the cb
* @internal: communication between driver and FW flag
+ * @blocking: transmission blocking mode
* @completed: the transfer or reception has completed
*/
struct mei_cl_cb {
@@ -180,6 +192,7 @@ struct mei_cl_cb {
const struct file *fp;
int status;
u32 internal:1;
+ u32 blocking:1;
u32 completed:1;
};
@@ -304,7 +317,7 @@ void mei_cl_bus_rescan(struct mei_device *bus);
void mei_cl_bus_rescan_work(struct work_struct *work);
void mei_cl_bus_dev_fixup(struct mei_cl_device *dev);
ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
- bool blocking);
+ unsigned int mode);
ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length);
bool mei_cl_bus_rx_event(struct mei_cl *cl);
bool mei_cl_bus_notify_event(struct mei_cl *cl);