diff options
| author | Ashutosh Dixit <ashutosh.dixit@intel.com> | 2013-09-05 19:42:18 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-09-26 16:50:56 -0400 |
| commit | f69bcbf3b4c4b333dcd7a48eaf868bf0c88edab5 (patch) | |
| tree | 82edf895c9db652788945faafb8d4301f79cb5f8 | |
| parent | aa27badd8972adb731f05d49ab74ec63e0826935 (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/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/misc/mic/common/mic_device.h | 7 | ||||
| -rw-r--r-- | drivers/misc/mic/host/Makefile | 2 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_boot.c | 3 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_debugfs.c | 140 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_device.h | 5 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_fops.c | 221 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_fops.h | 32 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_main.c | 26 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_virtio.c | 703 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_virtio.h | 138 | ||||
| -rw-r--r-- | include/uapi/linux/Kbuild | 1 | ||||
| -rw-r--r-- | include/uapi/linux/mic_common.h | 166 | ||||
| -rw-r--r-- | include/uapi/linux/mic_ioctl.h | 74 |
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" | |||
| 3 | config INTEL_MIC_HOST | 3 | config 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 | |||
| 10 | mic_host-objs += mic_intr.o | 10 | mic_host-objs += mic_intr.o |
| 11 | mic_host-objs += mic_boot.o | 11 | mic_host-objs += mic_boot.o |
| 12 | mic_host-objs += mic_debugfs.o | 12 | mic_host-objs += mic_debugfs.o |
| 13 | mic_host-objs += mic_fops.o | ||
| 14 | mic_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 */ |
| 31 | static struct dentry *mic_dbg; | 32 | static struct dentry *mic_dbg; |
| @@ -193,7 +194,13 @@ static const struct file_operations post_code_ops = { | |||
| 193 | static int mic_dp_show(struct seq_file *s, void *pos) | 194 | static 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 | ||
| 286 | static 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; | ||
