aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/pci-hyperv.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-18 15:34:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-18 15:34:53 -0400
commit81160dda9a7aad13c04e78bb2cfd3c4630e3afab (patch)
tree4bf79ffa9fc7dc5e2915ff978778c3402c491113 /drivers/pci/controller/pci-hyperv.c
parent8b53c76533aa4356602aea98f98a2f3b4051464c (diff)
parent1bab8d4c488be22d57f9dd09968c90a0ddc413bf (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from David Miller: 1) Support IPV6 RA Captive Portal Identifier, from Maciej Żenczykowski. 2) Use bio_vec in the networking instead of custom skb_frag_t, from Matthew Wilcox. 3) Make use of xmit_more in r8169 driver, from Heiner Kallweit. 4) Add devmap_hash to xdp, from Toke Høiland-Jørgensen. 5) Support all variants of 5750X bnxt_en chips, from Michael Chan. 6) More RTNL avoidance work in the core and mlx5 driver, from Vlad Buslov. 7) Add TCP syn cookies bpf helper, from Petar Penkov. 8) Add 'nettest' to selftests and use it, from David Ahern. 9) Add extack support to drop_monitor, add packet alert mode and support for HW drops, from Ido Schimmel. 10) Add VLAN offload to stmmac, from Jose Abreu. 11) Lots of devm_platform_ioremap_resource() conversions, from YueHaibing. 12) Add IONIC driver, from Shannon Nelson. 13) Several kTLS cleanups, from Jakub Kicinski. * git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1930 commits) mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer mlxsw: spectrum: Register CPU port with devlink mlxsw: spectrum_buffers: Prevent changing CPU port's configuration net: ena: fix incorrect update of intr_delay_resolution net: ena: fix retrieval of nonadaptive interrupt moderation intervals net: ena: fix update of interrupt moderation register net: ena: remove all old adaptive rx interrupt moderation code from ena_com net: ena: remove ena_restore_ethtool_params() and relevant fields net: ena: remove old adaptive interrupt moderation code from ena_netdev net: ena: remove code duplication in ena_com_update_nonadaptive_moderation_interval _*() net: ena: enable the interrupt_moderation in driver_supported_features net: ena: reimplement set/get_coalesce() net: ena: switch to dim algorithm for rx adaptive interrupt moderation net: ena: add intr_moder_rx_interval to struct ena_com_dev and use it net: phy: adin: implement Energy Detect Powerdown mode via phy-tunable ethtool: implement Energy Detect Powerdown support via phy-tunable xen-netfront: do not assume sk_buff_head list is empty in error handling s390/ctcm: Delete unnecessary checks before the macro call “dev_kfree_skb” net: ena: don't wake up tx queue when down drop_monitor: Better sanitize notified packets ...
Diffstat (limited to 'drivers/pci/controller/pci-hyperv.c')
-rw-r--r--drivers/pci/controller/pci-hyperv.c308
1 files changed, 308 insertions, 0 deletions
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index 97056f3dd317..0ca73c851e0f 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -365,6 +365,39 @@ struct pci_delete_interrupt {
365 struct tran_int_desc int_desc; 365 struct tran_int_desc int_desc;
366} __packed; 366} __packed;
367 367
368/*
369 * Note: the VM must pass a valid block id, wslot and bytes_requested.
370 */
371struct pci_read_block {
372 struct pci_message message_type;
373 u32 block_id;
374 union win_slot_encoding wslot;
375 u32 bytes_requested;
376} __packed;
377
378struct pci_read_block_response {
379 struct vmpacket_descriptor hdr;
380 u32 status;
381 u8 bytes[HV_CONFIG_BLOCK_SIZE_MAX];
382} __packed;
383
384/*
385 * Note: the VM must pass a valid block id, wslot and byte_count.
386 */
387struct pci_write_block {
388 struct pci_message message_type;
389 u32 block_id;
390 union win_slot_encoding wslot;
391 u32 byte_count;
392 u8 bytes[HV_CONFIG_BLOCK_SIZE_MAX];
393} __packed;
394
395struct pci_dev_inval_block {
396 struct pci_incoming_message incoming;
397 union win_slot_encoding wslot;
398 u64 block_mask;
399} __packed;
400
368struct pci_dev_incoming { 401struct pci_dev_incoming {
369 struct pci_incoming_message incoming; 402 struct pci_incoming_message incoming;
370 union win_slot_encoding wslot; 403 union win_slot_encoding wslot;
@@ -499,6 +532,9 @@ struct hv_pci_dev {
499 struct hv_pcibus_device *hbus; 532 struct hv_pcibus_device *hbus;
500 struct work_struct wrk; 533 struct work_struct wrk;
501 534
535 void (*block_invalidate)(void *context, u64 block_mask);
536 void *invalidate_context;
537
502 /* 538 /*
503 * What would be observed if one wrote 0xFFFFFFFF to a BAR and then 539 * What would be observed if one wrote 0xFFFFFFFF to a BAR and then
504 * read it back, for each of the BAR offsets within config space. 540 * read it back, for each of the BAR offsets within config space.
@@ -817,6 +853,253 @@ static struct pci_ops hv_pcifront_ops = {
817 .write = hv_pcifront_write_config, 853 .write = hv_pcifront_write_config,
818}; 854};
819 855
856/*
857 * Paravirtual backchannel
858 *
859 * Hyper-V SR-IOV provides a backchannel mechanism in software for
860 * communication between a VF driver and a PF driver. These
861 * "configuration blocks" are similar in concept to PCI configuration space,
862 * but instead of doing reads and writes in 32-bit chunks through a very slow
863 * path, packets of up to 128 bytes can be sent or received asynchronously.
864 *
865 * Nearly every SR-IOV device contains just such a communications channel in
866 * hardware, so using this one in software is usually optional. Using the
867 * software channel, however, allows driver implementers to leverage software
868 * tools that fuzz the communications channel looking for vulnerabilities.
869 *
870 * The usage model for these packets puts the responsibility for reading or
871 * writing on the VF driver. The VF driver sends a read or a write packet,
872 * indicating which "block" is being referred to by number.
873 *
874 * If the PF driver wishes to initiate communication, it can "invalidate" one or
875 * more of the first 64 blocks. This invalidation is delivered via a callback
876 * supplied by the VF driver by this driver.
877 *
878 * No protocol is implied, except that supplied by the PF and VF drivers.
879 */
880
881struct hv_read_config_compl {
882 struct hv_pci_compl comp_pkt;
883 void *buf;
884 unsigned int len;
885 unsigned int bytes_returned;
886};
887
888/**
889 * hv_pci_read_config_compl() - Invoked when a response packet
890 * for a read config block operation arrives.
891 * @context: Identifies the read config operation
892 * @resp: The response packet itself
893 * @resp_packet_size: Size in bytes of the response packet
894 */
895static void hv_pci_read_config_compl(void *context, struct pci_response *resp,
896 int resp_packet_size)
897{
898 struct hv_read_config_compl *comp = context;
899 struct pci_read_block_response *read_resp =
900 (struct pci_read_block_response *)resp;
901 unsigned int data_len, hdr_len;
902
903 hdr_len = offsetof(struct pci_read_block_response, bytes);
904 if (resp_packet_size < hdr_len) {
905 comp->comp_pkt.completion_status = -1;
906 goto out;
907 }
908
909 data_len = resp_packet_size - hdr_len;
910 if (data_len > 0 && read_resp->status == 0) {
911 comp->bytes_returned = min(comp->len, data_len);
912 memcpy(comp->buf, read_resp->bytes, comp->bytes_returned);
913 } else {
914 comp->bytes_returned = 0;
915 }
916
917 comp->comp_pkt.completion_status = read_resp->status;
918out:
919 complete(&comp->comp_pkt.host_event);
920}
921
922/**
923 * hv_read_config_block() - Sends a read config block request to
924 * the back-end driver running in the Hyper-V parent partition.
925 * @pdev: The PCI driver's representation for this device.
926 * @buf: Buffer into which the config block will be copied.
927 * @len: Size in bytes of buf.
928 * @block_id: Identifies the config block which has been requested.
929 * @bytes_returned: Size which came back from the back-end driver.
930 *
931 * Return: 0 on success, -errno on failure
932 */
933int hv_read_config_block(struct pci_dev *pdev, void *buf, unsigned int len,
934 unsigned int block_id, unsigned int *bytes_returned)
935{
936 struct hv_pcibus_device *hbus =
937 container_of(pdev->bus->sysdata, struct hv_pcibus_device,
938 sysdata);
939 struct {
940 struct pci_packet pkt;
941 char buf[sizeof(struct pci_read_block)];
942 } pkt;
943 struct hv_read_config_compl comp_pkt;
944 struct pci_read_block *read_blk;
945 int ret;
946
947 if (len == 0 || len > HV_CONFIG_BLOCK_SIZE_MAX)
948 return -EINVAL;
949
950 init_completion(&comp_pkt.comp_pkt.host_event);
951 comp_pkt.buf = buf;
952 comp_pkt.len = len;
953
954 memset(&pkt, 0, sizeof(pkt));
955 pkt.pkt.completion_func = hv_pci_read_config_compl;
956 pkt.pkt.compl_ctxt = &comp_pkt;
957 read_blk = (struct pci_read_block *)&pkt.pkt.message;
958 read_blk->message_type.type = PCI_READ_BLOCK;
959 read_blk->wslot.slot = devfn_to_wslot(pdev->devfn);
960 read_blk->block_id = block_id;
961 read_blk->bytes_requested = len;
962
963 ret = vmbus_sendpacket(hbus->hdev->channel, read_blk,
964 sizeof(*read_blk), (unsigned long)&pkt.pkt,
965 VM_PKT_DATA_INBAND,
966 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
967 if (ret)
968 return ret;
969
970 ret = wait_for_response(hbus->hdev, &comp_pkt.comp_pkt.host_event);
971 if (ret)
972 return ret;
973
974 if (comp_pkt.comp_pkt.completion_status != 0 ||
975 comp_pkt.bytes_returned == 0) {
976 dev_err(&hbus->hdev->device,
977 "Read Config Block failed: 0x%x, bytes_returned=%d\n",
978 comp_pkt.comp_pkt.completion_status,
979 comp_pkt.bytes_returned);
980 return -EIO;
981 }
982
983 *bytes_returned = comp_pkt.bytes_returned;
984 return 0;
985}
986
987/**
988 * hv_pci_write_config_compl() - Invoked when a response packet for a write
989 * config block operation arrives.
990 * @context: Identifies the write config operation
991 * @resp: The response packet itself
992 * @resp_packet_size: Size in bytes of the response packet
993 */
994static void hv_pci_write_config_compl(void *context, struct pci_response *resp,
995 int resp_packet_size)
996{
997 struct hv_pci_compl *comp_pkt = context;
998
999 comp_pkt->completion_status = resp->status;
1000 complete(&comp_pkt->host_event);
1001}
1002
1003/**
1004 * hv_write_config_block() - Sends a write config block request to the
1005 * back-end driver running in the Hyper-V parent partition.
1006 * @pdev: The PCI driver's representation for this device.
1007 * @buf: Buffer from which the config block will be copied.
1008 * @len: Size in bytes of buf.
1009 * @block_id: Identifies the config block which is being written.
1010 *
1011 * Return: 0 on success, -errno on failure
1012 */
1013int hv_write_config_block(struct pci_dev *pdev, void *buf, unsigned int len,
1014 unsigned int block_id)
1015{
1016 struct hv_pcibus_device *hbus =
1017 container_of(pdev->bus->sysdata, struct hv_pcibus_device,
1018 sysdata);
1019 struct {
1020 struct pci_packet pkt;
1021 char buf[sizeof(struct pci_write_block)];
1022 u32 reserved;
1023 } pkt;
1024 struct hv_pci_compl comp_pkt;
1025 struct pci_write_block *write_blk;
1026 u32 pkt_size;
1027 int ret;
1028
1029 if (len == 0 || len > HV_CONFIG_BLOCK_SIZE_MAX)
1030 return -EINVAL;
1031
1032 init_completion(&comp_pkt.host_event);
1033
1034 memset(&pkt, 0, sizeof(pkt));
1035 pkt.pkt.completion_func = hv_pci_write_config_compl;
1036 pkt.pkt.compl_ctxt = &comp_pkt;
1037 write_blk = (struct pci_write_block *)&pkt.pkt.message;
1038 write_blk->message_type.type = PCI_WRITE_BLOCK;
1039 write_blk->wslot.slot = devfn_to_wslot(pdev->devfn);
1040 write_blk->block_id = block_id;
1041 write_blk->byte_count = len;
1042 memcpy(write_blk->bytes, buf, len);
1043 pkt_size = offsetof(struct pci_write_block, bytes) + len;
1044 /*
1045 * This quirk is required on some hosts shipped around 2018, because
1046 * these hosts don't check the pkt_size correctly (new hosts have been
1047 * fixed since early 2019). The quirk is also safe on very old hosts
1048 * and new hosts, because, on them, what really matters is the length
1049 * specified in write_blk->byte_count.
1050 */
1051 pkt_size += sizeof(pkt.reserved);
1052
1053 ret = vmbus_sendpacket(hbus->hdev->channel, write_blk, pkt_size,
1054 (unsigned long)&pkt.pkt, VM_PKT_DATA_INBAND,
1055 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
1056 if (ret)
1057 return ret;
1058
1059 ret = wait_for_response(hbus->hdev, &comp_pkt.host_event);
1060 if (ret)
1061 return ret;
1062
1063 if (comp_pkt.completion_status != 0) {
1064 dev_err(&hbus->hdev->device,
1065 "Write Config Block failed: 0x%x\n",
1066 comp_pkt.completion_status);
1067 return -EIO;
1068 }
1069
1070 return 0;
1071}
1072
1073/**
1074 * hv_register_block_invalidate() - Invoked when a config block invalidation
1075 * arrives from the back-end driver.
1076 * @pdev: The PCI driver's representation for this device.
1077 * @context: Identifies the device.
1078 * @block_invalidate: Identifies all of the blocks being invalidated.
1079 *
1080 * Return: 0 on success, -errno on failure
1081 */
1082int hv_register_block_invalidate(struct pci_dev *pdev, void *context,
1083 void (*block_invalidate)(void *context,
1084 u64 block_mask))
1085{
1086 struct hv_pcibus_device *hbus =
1087 container_of(pdev->bus->sysdata, struct hv_pcibus_device,
1088 sysdata);
1089 struct hv_pci_dev *hpdev;
1090
1091 hpdev = get_pcichild_wslot(hbus, devfn_to_wslot(pdev->devfn));
1092 if (!hpdev)
1093 return -ENODEV;
1094
1095 hpdev->block_invalidate = block_invalidate;
1096 hpdev->invalidate_context = context;
1097
1098 put_pcichild(hpdev);
1099 return 0;
1100
1101}
1102
820/* Interrupt management hooks */ 1103/* Interrupt management hooks */
821static void hv_int_desc_free(struct hv_pci_dev *hpdev, 1104static void hv_int_desc_free(struct hv_pci_dev *hpdev,
822 struct tran_int_desc *int_desc) 1105 struct tran_int_desc *int_desc)
@@ -1968,6 +2251,7 @@ static void hv_pci_onchannelcallback(void *context)
1968 struct pci_response *response; 2251 struct pci_response *response;
1969 struct pci_incoming_message *new_message; 2252 struct pci_incoming_message *new_message;
1970 struct pci_bus_relations *bus_rel; 2253 struct pci_bus_relations *bus_rel;
2254 struct pci_dev_inval_block *inval;
1971 struct pci_dev_incoming *dev_message; 2255 struct pci_dev_incoming *dev_message;
1972 struct hv_pci_dev *hpdev; 2256 struct hv_pci_dev *hpdev;
1973 2257
@@ -2045,6 +2329,21 @@ static void hv_pci_onchannelcallback(void *context)
2045 } 2329 }
2046 break; 2330 break;
2047 2331
2332 case PCI_INVALIDATE_BLOCK:
2333
2334 inval = (struct pci_dev_inval_block *)buffer;
2335 hpdev = get_pcichild_wslot(hbus,
2336 inval->wslot.slot);
2337 if (hpdev) {
2338 if (hpdev->block_invalidate) {
2339 hpdev->block_invalidate(
2340 hpdev->invalidate_context,
2341 inval->block_mask);
2342 }
2343 put_pcichild(hpdev);
2344 }
2345 break;
2346
2048 default: 2347 default:
2049 dev_warn(&hbus->hdev->device, 2348 dev_warn(&hbus->hdev->device,
2050 "Unimplemented protocol message %x\n", 2349 "Unimplemented protocol message %x\n",
@@ -2751,10 +3050,19 @@ static struct hv_driver hv_pci_drv = {
2751static void __exit exit_hv_pci_drv(void) 3050static void __exit exit_hv_pci_drv(void)
2752{ 3051{
2753 vmbus_driver_unregister(&hv_pci_drv); 3052 vmbus_driver_unregister(&hv_pci_drv);
3053
3054 hvpci_block_ops.read_block = NULL;
3055 hvpci_block_ops.write_block = NULL;
3056 hvpci_block_ops.reg_blk_invalidate = NULL;
2754} 3057}
2755 3058
2756static int __init init_hv_pci_drv(void) 3059static int __init init_hv_pci_drv(void)
2757{ 3060{
3061 /* Initialize PCI block r/w interface */
3062 hvpci_block_ops.read_block = hv_read_config_block;
3063 hvpci_block_ops.write_block = hv_write_config_block;
3064 hvpci_block_ops.reg_blk_invalidate = hv_register_block_invalidate;
3065
2758 return vmbus_driver_register(&hv_pci_drv); 3066 return vmbus_driver_register(&hv_pci_drv);
2759} 3067}
2760 3068