History

PCI: hv: Add a Hyper-V PCI interface driver for software backchannel interface

This interface driver is a helper driver allows other drivers to have a common interface with the Hyper-V PCI frontend driver.

Haiyang Zhang committed 7 years ago

Commit 348dd931 parent e5d2f917 files · +108 −11Browse files

Unified · Split

7 files
  1. MAINTAINERS +1 −0
  2. drivers/pci/Kconfig +1 −0
  3. drivers/pci/controller/Kconfig +7 −0
  4. drivers/pci/controller/Makefile +1 −0
  5. drivers/pci/controller/pci-hyperv-intf.c +67 −0
  6. drivers/pci/controller/pci-hyperv.c +9 −3
  7. include/linux/hyperv.h +22 −8
MAINTAINERS+1−0
@@ -7469,6 +7469,7 @@ F: drivers/hid/hid-hyperv.c · 7468 unmodified lines
7469F: drivers/hv/7469F: drivers/hv/
7470F: drivers/input/serio/hyperv-keyboard.c7470F: drivers/input/serio/hyperv-keyboard.c
7471F: drivers/pci/controller/pci-hyperv.c7471F: drivers/pci/controller/pci-hyperv.c
7472F: drivers/pci/controller/pci-hyperv-intf.c
7472F: drivers/net/hyperv/7473F: drivers/net/hyperv/
7473F: drivers/scsi/storvsc_drv.c7474F: drivers/scsi/storvsc_drv.c
7474F: drivers/uio/uio_hv_generic.c7475F: drivers/uio/uio_hv_generic.c
drivers/pci/Kconfig+1−0
@@ -182,6 +182,7 @@ config PCI_LABEL · 181 unmodified lines
182config PCI_HYPERV182config PCI_HYPERV
183 tristate "Hyper-V PCI Frontend"183 tristate "Hyper-V PCI Frontend"
184 depends on X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && X86_64184 depends on X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && X86_64
185 select PCI_HYPERV_INTERFACE
185 help186 help
186 The PCI device frontend driver allows the kernel to import arbitrary187 The PCI device frontend driver allows the kernel to import arbitrary
187 PCI devices from a PCI backend to support PCI driver domains.188 PCI devices from a PCI backend to support PCI driver domains.
drivers/pci/controller/Kconfig+7−0
@@ -281,5 +281,12 @@ config VMD · 280 unmodified lines
281 To compile this driver as a module, choose M here: the281 To compile this driver as a module, choose M here: the
282 module will be called vmd.282 module will be called vmd.
283 283
284config PCI_HYPERV_INTERFACE
285 tristate "Hyper-V PCI Interface"
286 depends on X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && X86_64
287 help
288 The Hyper-V PCI Interface is a helper driver allows other drivers to
289 have a common interface with the Hyper-V PCI frontend driver.
290
284source "drivers/pci/controller/dwc/Kconfig"291source "drivers/pci/controller/dwc/Kconfig"
285endmenu292endmenu
drivers/pci/controller/Makefile+1−0
@@ -4,6 +4,7 @@ obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o · 3 unmodified lines
4obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o4obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
5obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o5obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o
6obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o6obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
7obj-$(CONFIG_PCI_HYPERV_INTERFACE) += pci-hyperv-intf.o
7obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o8obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
8obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o9obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
9obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o10obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
drivers/pci/controller/pci-hyperv-intf.c+67−0
@@ -0,0 +1,67 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) Microsoft Corporation.
4 *
5 * Author:
6 * Haiyang Zhang <haiyangz@microsoft.com>
7 *
8 * This small module is a helper driver allows other drivers to
9 * have a common interface with the Hyper-V PCI frontend driver.
10 */
11
12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/hyperv.h>
17
18struct hyperv_pci_block_ops hvpci_block_ops;
19EXPORT_SYMBOL_GPL(hvpci_block_ops);
20
21int hyperv_read_cfg_blk(struct pci_dev *dev, void *buf, unsigned int buf_len,
22 unsigned int block_id, unsigned int *bytes_returned)
23{
24 if (!hvpci_block_ops.read_block)
25 return -EOPNOTSUPP;
26
27 return hvpci_block_ops.read_block(dev, buf, buf_len, block_id,
28 bytes_returned);
29}
30EXPORT_SYMBOL_GPL(hyperv_read_cfg_blk);
31
32int hyperv_write_cfg_blk(struct pci_dev *dev, void *buf, unsigned int len,
33 unsigned int block_id)
34{
35 if (!hvpci_block_ops.write_block)
36 return -EOPNOTSUPP;
37
38 return hvpci_block_ops.write_block(dev, buf, len, block_id);
39}
40EXPORT_SYMBOL_GPL(hyperv_write_cfg_blk);
41
42int hyperv_reg_block_invalidate(struct pci_dev *dev, void *context,
43 void (*block_invalidate)(void *context,
44 u64 block_mask))
45{
46 if (!hvpci_block_ops.reg_blk_invalidate)
47 return -EOPNOTSUPP;
48
49 return hvpci_block_ops.reg_blk_invalidate(dev, context,
50 block_invalidate);
51}
52EXPORT_SYMBOL_GPL(hyperv_reg_block_invalidate);
53
54static void __exit exit_hv_pci_intf(void)
55{
56}
57
58static int __init init_hv_pci_intf(void)
59{
60 return 0;
61}
62
63module_init(init_hv_pci_intf);
64module_exit(exit_hv_pci_intf);
65
66MODULE_DESCRIPTION("Hyper-V PCI Interface");
67MODULE_LICENSE("GPL v2");
drivers/pci/controller/pci-hyperv.c+9−3
@@ -983,7 +983,6 @@ int hv_read_config_block(struct pci_dev *pdev, void *buf, unsigned int len, · 982 unmodified lines
983 *bytes_returned = comp_pkt.bytes_returned;983 *bytes_returned = comp_pkt.bytes_returned;
984 return 0;984 return 0;
985}985}
986EXPORT_SYMBOL(hv_read_config_block);
987 986
988/**987/**
989 * hv_pci_write_config_compl() - Invoked when a response packet for a write988 * hv_pci_write_config_compl() - Invoked when a response packet for a write
@@ -1070,7 +1069,6 @@ int hv_write_config_block(struct pci_dev *pdev, void *buf, unsigned int len, · 80 unmodified lines
1070 1069
1071 return 0;1070 return 0;
1072}1071}
1073EXPORT_SYMBOL(hv_write_config_block);
1074 1072
1075/**1073/**
1076 * hv_register_block_invalidate() - Invoked when a config block invalidation1074 * hv_register_block_invalidate() - Invoked when a config block invalidation
@@ -1101,7 +1099,6 @@ int hv_register_block_invalidate(struct pci_dev *pdev, void *context, · 24 unmodified lines
1101 return 0;1099 return 0;
1102 1100
1103}1101}
1104EXPORT_SYMBOL(hv_register_block_invalidate);
1105 1102
1106/* Interrupt management hooks */1103/* Interrupt management hooks */
1107static void hv_int_desc_free(struct hv_pci_dev *hpdev,1104static void hv_int_desc_free(struct hv_pci_dev *hpdev,
@@ -3045,10 +3042,19 @@ static struct hv_driver hv_pci_drv = { · 1937 unmodified lines
3045static void __exit exit_hv_pci_drv(void)3042static void __exit exit_hv_pci_drv(void)
3046{3043{
3047 vmbus_driver_unregister(&hv_pci_drv);3044 vmbus_driver_unregister(&hv_pci_drv);
3045
3046 hvpci_block_ops.read_block = NULL;
3047 hvpci_block_ops.write_block = NULL;
3048 hvpci_block_ops.reg_blk_invalidate = NULL;
3048}3049}
3049 3050
3050static int __init init_hv_pci_drv(void)3051static int __init init_hv_pci_drv(void)
3051{3052{
3053 /* Initialize PCI block r/w interface */
3054 hvpci_block_ops.read_block = hv_read_config_block;
3055 hvpci_block_ops.write_block = hv_write_config_block;
3056 hvpci_block_ops.reg_blk_invalidate = hv_register_block_invalidate;
3057
3052 return vmbus_driver_register(&hv_pci_drv);3058 return vmbus_driver_register(&hv_pci_drv);
3053}3059}
3054 3060
include/linux/hyperv.h+22−8
@@ -1579,18 +1579,32 @@ hv_pkt_iter_next(struct vmbus_channel *channel, · 1578 unmodified lines
1579 pkt = hv_pkt_iter_next(channel, pkt))1579 pkt = hv_pkt_iter_next(channel, pkt))
1580 1580
1581/*1581/*
1582 * Functions for passing data between SR-IOV PF and VF drivers. The VF driver1582 * Interface for passing data between SR-IOV PF and VF drivers. The VF driver
1583 * sends requests to read and write blocks. Each block must be 128 bytes or1583 * sends requests to read and write blocks. Each block must be 128 bytes or
1584 * smaller. Optionally, the VF driver can register a callback function which1584 * smaller. Optionally, the VF driver can register a callback function which
1585 * will be invoked when the host says that one or more of the first 64 block1585 * will be invoked when the host says that one or more of the first 64 block
1586 * IDs is "invalid" which means that the VF driver should reread them.1586 * IDs is "invalid" which means that the VF driver should reread them.
1587 */1587 */
1588#define HV_CONFIG_BLOCK_SIZE_MAX 1281588#define HV_CONFIG_BLOCK_SIZE_MAX 128
1589int hv_read_config_block(struct pci_dev *dev, void *buf, unsigned int buf_len,1589
1590 unsigned int block_id, unsigned int *bytes_returned);1590int hyperv_read_cfg_blk(struct pci_dev *dev, void *buf, unsigned int buf_len,
1591int hv_write_config_block(struct pci_dev *dev, void *buf, unsigned int len,1591 unsigned int block_id, unsigned int *bytes_returned);
1592 unsigned int block_id);1592int hyperv_write_cfg_blk(struct pci_dev *dev, void *buf, unsigned int len,
1593int hv_register_block_invalidate(struct pci_dev *dev, void *context,1593 unsigned int block_id);
1594 void (*block_invalidate)(void *context,1594int hyperv_reg_block_invalidate(struct pci_dev *dev, void *context,
1595 u64 block_mask));1595 void (*block_invalidate)(void *context,
1596 u64 block_mask));
1597
1598struct hyperv_pci_block_ops {
1599 int (*read_block)(struct pci_dev *dev, void *buf, unsigned int buf_len,
1600 unsigned int block_id, unsigned int *bytes_returned);
1601 int (*write_block)(struct pci_dev *dev, void *buf, unsigned int len,
1602 unsigned int block_id);
1603 int (*reg_blk_invalidate)(struct pci_dev *dev, void *context,
1604 void (*block_invalidate)(void *context,
1605 u64 block_mask));
1606};
1607
1608extern struct hyperv_pci_block_ops hvpci_block_ops;
1609
1596#endif /* _HYPERV_H */1610#endif /* _HYPERV_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t