aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAshutosh Dixit <ashutosh.dixit@intel.com>2013-09-05 19:42:18 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-09-26 16:50:56 -0400
commitf69bcbf3b4c4b333dcd7a48eaf868bf0c88edab5 (patch)
tree82edf895c9db652788945faafb8d4301f79cb5f8
parentaa27badd8972adb731f05d49ab74ec63e0826935 (diff)
Intel MIC Host Driver Changes for Virtio Devices.
This patch introduces the host "Virtio over PCIe" interface for Intel MIC. It allows creating user space backends on the host and instantiating virtio devices for them on the Intel MIC card. It uses the existing VRINGH infrastructure in the kernel to access virtio rings from the host. A character device per MIC is exposed with IOCTL, mmap and poll callbacks. This allows the user space backend to: (a) add/remove a virtio device via a device page. (b) map (R/O) virtio rings and device page to user space. (c) poll for availability of data. (d) copy a descriptor or entire descriptor chain to/from the card. (e) modify virtio configuration. (f) handle virtio device reset. The buffers are copied over using CPU copies for this initial patch and host initiated MIC DMA support is planned for future patches. The avail and desc virtio rings are in host memory and the used ring is in card memory to maximize writes across PCIe for performance. Co-author: Sudeep Dutt <sudeep.dutt@intel.com> Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Signed-off-by: Caz Yokoyama <Caz.Yokoyama@intel.com> Signed-off-by: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com> Signed-off-by: Nikhil Rao <nikhil.rao@intel.com> Signed-off-by: Harshavardhan R Kharche <harshavardhan.r.kharche@intel.com> Signed-off-by: Sudeep Dutt <sudeep.dutt@intel.com> Acked-by: Yaozu (Eddie) Dong <eddie.dong@intel.com> Reviewed-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/misc/mic/Kconfig1
-rw-r--r--drivers/misc/mic/common/mic_device.h7
-rw-r--r--drivers/misc/mic/host/Makefile2
-rw-r--r--drivers/misc/mic/host/mic_boot.c3
-rw-r--r--drivers/misc/mic/host/mic_debugfs.c140
-rw-r--r--drivers/misc/mic/host/mic_device.h5
-rw-r--r--drivers/misc/mic/host/mic_fops.c221
-rw-r--r--drivers/misc/mic/host/mic_fops.h32
-rw-r--r--drivers/misc/mic/host/mic_main.c26
-rw-r--r--drivers/misc/mic/host/mic_virtio.c703
-rw-r--r--drivers/misc/mic/host/mic_virtio.h138
-rw-r--r--include/uapi/linux/Kbuild1
-rw-r--r--include/uapi/linux/mic_common.h166
-rw-r--r--include/uapi/linux/mic_ioctl.h74
14 files changed, 1517 insertions, 2 deletions
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
index 279a2e649059..01f1a4a84c63 100644
--- a/drivers/misc/mic/Kconfig
+++ b/drivers/misc/mic/Kconfig
@@ -3,6 +3,7 @@ comment "Intel MIC Host Driver"
3config INTEL_MIC_HOST 3config INTEL_MIC_HOST
4 tristate "Intel MIC Host Driver" 4 tristate "Intel MIC Host Driver"
5 depends on 64BIT && PCI 5 depends on 64BIT && PCI
6 select VHOST_RING
6 default N 7 default N
7 help 8 help
8 This enables Host Driver support for the Intel Many Integrated 9 This enables Host Driver support for the Intel Many Integrated
diff --git a/drivers/misc/mic/common/mic_device.h b/drivers/misc/mic/common/mic_device.h
index 6440e9d58d3a..01eb74faae6b 100644
--- a/drivers/misc/mic/common/mic_device.h
+++ b/drivers/misc/mic/common/mic_device.h
@@ -41,4 +41,11 @@ struct mic_mw {
41#define MIC_DPLO_SPAD 14 41#define MIC_DPLO_SPAD 14
42#define MIC_DPHI_SPAD 15 42#define MIC_DPHI_SPAD 15
43 43
44/*
45 * These values are supposed to be in the config_change field of the
46 * device page when the host sends a config change interrupt to the card.
47 */
48#define MIC_VIRTIO_PARAM_DEV_REMOVE 0x1
49#define MIC_VIRTIO_PARAM_CONFIG_CHANGED 0x2
50
44#endif 51#endif
diff --git a/drivers/misc/mic/host/Makefile b/drivers/misc/mic/host/Makefile
index a375dd32c3e2..c2197f999394 100644
--- a/drivers/misc/mic/host/Makefile
+++ b/drivers/misc/mic/host/Makefile
@@ -10,3 +10,5 @@ mic_host-objs += mic_smpt.o
10mic_host-objs += mic_intr.o 10mic_host-objs += mic_intr.o
11mic_host-objs += mic_boot.o 11mic_host-objs += mic_boot.o
12mic_host-objs += mic_debugfs.o 12mic_host-objs += mic_debugfs.o
13mic_host-objs += mic_fops.o
14mic_host-objs += mic_virtio.o
diff --git a/drivers/misc/mic/host/mic_boot.c b/drivers/misc/mic/host/mic_boot.c
index 936fc58084f3..fd9ff6d3784e 100644
--- a/drivers/misc/mic/host/mic_boot.c
+++ b/drivers/misc/mic/host/mic_boot.c
@@ -20,12 +20,12 @@
20 */ 20 */
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/firmware.h> 22#include <linux/firmware.h>
23#include <linux/interrupt.h>
24 23
25#include <linux/mic_common.h> 24#include <linux/mic_common.h>
26#include "../common/mic_device.h" 25#include "../common/mic_device.h"
27#include "mic_device.h" 26#include "mic_device.h"
28#include "mic_smpt.h" 27#include "mic_smpt.h"
28#include "mic_virtio.h"
29 29
30/** 30/**
31 * mic_reset - Reset the MIC device. 31 * mic_reset - Reset the MIC device.
@@ -117,6 +117,7 @@ void mic_stop(struct mic_device *mdev, bool force)
117{ 117{
118 mutex_lock(&mdev->mic_mutex); 118 mutex_lock(&mdev->mic_mutex);
119 if (MIC_OFFLINE != mdev->state || force) { 119 if (MIC_OFFLINE != mdev->state || force) {
120 mic_virtio_reset_devices(mdev);
120 mic_bootparam_init(mdev); 121 mic_bootparam_init(mdev);
121 mic_reset(mdev); 122 mic_reset(mdev);
122 if (MIC_RESET_FAILED == mdev->state) 123 if (MIC_RESET_FAILED == mdev->state)
diff --git a/drivers/misc/mic/host/mic_debugfs.c b/drivers/misc/mic/host/mic_debugfs.c
index 78541d42aaf9..e22fb7bbbb98 100644
--- a/drivers/misc/mic/host/mic_debugfs.c
+++ b/drivers/misc/mic/host/mic_debugfs.c
@@ -26,6 +26,7 @@
26#include "../common/mic_device.h" 26#include "../common/mic_device.h"
27#include "mic_device.h" 27#include "mic_device.h"
28#include "mic_smpt.h" 28#include "mic_smpt.h"
29#include "mic_virtio.h"
29 30
30/* Debugfs parent dir */ 31/* Debugfs parent dir */
31static struct dentry *mic_dbg; 32static struct dentry *mic_dbg;
@@ -193,7 +194,13 @@ static const struct file_operations post_code_ops = {
193static int mic_dp_show(struct seq_file *s, void *pos) 194static int mic_dp_show(struct seq_file *s, void *pos)
194{ 195{
195 struct mic_device *mdev = s->private; 196 struct mic_device *mdev = s->private;
197 struct mic_device_desc *d;
198 struct mic_device_ctrl *dc;
199 struct mic_vqconfig *vqconfig;
200 __u32 *features;
201 __u8 *config;
196 struct mic_bootparam *bootparam = mdev->dp; 202 struct mic_bootparam *bootparam = mdev->dp;
203 int i, j;
197 204
198 seq_printf(s, "Bootparam: magic 0x%x\n", 205 seq_printf(s, "Bootparam: magic 0x%x\n",
199 bootparam->magic); 206 bootparam->magic);
@@ -208,6 +215,53 @@ static int mic_dp_show(struct seq_file *s, void *pos)
208 seq_printf(s, "Bootparam: shutdown_card %d\n", 215 seq_printf(s, "Bootparam: shutdown_card %d\n",
209 bootparam->shutdown_card); 216 bootparam->shutdown_card);
210 217
218 for (i = sizeof(*bootparam); i < MIC_DP_SIZE;
219 i += mic_total_desc_size(d)) {
220 d = mdev->dp + i;
221 dc = (void *)d + mic_aligned_desc_size(d);
222
223 /* end of list */
224 if (d->type == 0)
225 break;
226
227 if (d->type == -1)
228 continue;
229
230 seq_printf(s, "Type %d ", d->type);
231 seq_printf(s, "Num VQ %d ", d->num_vq);
232 seq_printf(s, "Feature Len %d\n", d->feature_len);
233 seq_printf(s, "Config Len %d ", d->config_len);
234 seq_printf(s, "Shutdown Status %d\n", d->status);
235
236 for (j = 0; j < d->num_vq; j++) {
237 vqconfig = mic_vq_config(d) + j;
238 seq_printf(s, "vqconfig[%d]: ", j);
239 seq_printf(s, "address 0x%llx ", vqconfig->address);
240 seq_printf(s, "num %d ", vqconfig->num);
241 seq_printf(s, "used address 0x%llx\n",
242 vqconfig->used_address);
243 }
244
245 features = (__u32 *) mic_vq_features(d);
246 seq_printf(s, "Features: Host 0x%x ", features[0]);
247 seq_printf(s, "Guest 0x%x\n", features[1]);
248
249 config = mic_vq_configspace(d);
250 for (j = 0; j < d->config_len; j++)
251 seq_printf(s, "config[%d]=%d\n", j, config[j]);
252
253 seq_puts(s, "Device control:\n");
254 seq_printf(s, "Config Change %d ", dc->config_change);
255 seq_printf(s, "Vdev reset %d\n", dc->vdev_reset);
256 seq_printf(s, "Guest Ack %d ", dc->guest_ack);
257 seq_printf(s, "Host ack %d\n", dc->host_ack);
258 seq_printf(s, "Used address updated %d ",
259 dc->used_address_updated);
260 seq_printf(s, "Vdev 0x%llx\n", dc->vdev);
261 seq_printf(s, "c2h doorbell %d ", dc->c2h_vdev_db);
262 seq_printf(s, "h2c doorbell %d\n", dc->h2c_vdev_db);
263 }
264
211 return 0; 265 return 0;
212} 266}
213 267
@@ -229,6 +283,89 @@ static const struct file_operations dp_ops = {
229 .release = mic_dp_debug_release 283 .release = mic_dp_debug_release
230}; 284};
231 285
286static int mic_vdev_info_show(struct seq_file *s, void *unused)
287{
288 struct mic_device *mdev = s->private;
289 struct list_head *pos, *tmp;
290 struct mic_vdev *mvdev;