1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk_cunit.h" 35 36 #include "spdk/env.h" 37 38 #include "common/lib/test_env.c" 39 40 #include "env_dpdk/pci_event.c" 41 42 #ifdef __linux__ 43 44 enum pci_parse_event_return_type { 45 uevent_normal_exit = 0, 46 uevent_expected_continue = 1 47 }; 48 49 static void 50 test_pci_parse_event(void) 51 { 52 char *commands; 53 struct spdk_pci_event event = {}; 54 struct spdk_pci_addr addr = {}; 55 int rc = uevent_normal_exit; 56 57 /* Simulate commands to check expected behaviors */ 58 /* Linux kernel puts null characters after every uevent */ 59 spdk_pci_addr_parse(&addr, "0000:81:00.0"); 60 61 /* Case 1: Add wrong non-uio or vfio-pci /devices/pci0000:80/0000:80:01.0/0000:81:00.0/uio/uio0 */ 62 commands = 63 "ACTION=add\0DEVPATH=/devices/pci0000:80/0000:80:01.0/0000:81:00.0/uio/uio0\0SUBSYSTEM= \0DRIVER= \0PCI_SLOT_NAME= \0"; 64 65 rc = parse_subsystem_event(commands, &event); 66 CU_ASSERT(rc == uevent_normal_exit); 67 68 /* Case 2: Add pci event /devices/pci0000:80/0000:80:01.0/0000:81:00.0/uio/uio0 */ 69 commands = 70 "ACTION=bind\0DEVPATH=/devices/pci0000:80/0000:80:01.0/0000:81:00.0\0SUBSYSTEM=pci\0DRIVER=uio_pci_generic\0PCI_SLOT_NAME=0000:81:00.0\0"; 71 72 memset(&event, 0, sizeof(event)); 73 rc = parse_subsystem_event(commands, &event); 74 CU_ASSERT(rc == uevent_normal_exit); 75 76 /* Case 3: Add wrong uio addr 000000 */ 77 commands = 78 "ACTION=add \0DEVPATH=/devices/pci0000:80/0000/0000/uio/uio0\0SUBSYSTEM=uio\0DRIVER=\0PCI_SLOT_NAME= \0"; 79 80 memset(&event, 0, sizeof(event)); 81 rc = parse_subsystem_event(commands, &event); 82 CU_ASSERT(rc < 0); 83 84 /* Case 3: Add uio /devices/pci0000:80/0000:80:01.0/0000:81:00.0/uio/uio0 */ 85 commands = 86 "ACTION=add \0DEVPATH=/devices/pci0000:80/0000:80:01.0/0000:81:00.0/uio/uio0\0SUBSYSTEM=uio\0DRIVER=\0PCI_SLOT_NAME= \0"; 87 88 memset(&event, 0, sizeof(event)); 89 rc = parse_subsystem_event(commands, &event); 90 CU_ASSERT(rc == uevent_expected_continue); 91 CU_ASSERT(event.action == SPDK_UEVENT_ADD); 92 CU_ASSERT(spdk_pci_addr_compare(&addr, &event.traddr) == 0); 93 94 /* Case 4: Remove uio /devices/pci0000:80/0000:80:01.0/0000:81:00.0/uio/uio0 */ 95 commands = 96 "ACTION=remove\0DEVPATH=/devices/pci0000:80/0000:80:01.0/0000:81:00.0/uio/uio0\0SUBSYSTEM=uio\0DRIVER=\0PCI_SLOT_NAME= \0"; 97 98 memset(&event, 0, sizeof(event)); 99 rc = parse_subsystem_event(commands, &event); 100 CU_ASSERT(rc == uevent_expected_continue); 101 CU_ASSERT(event.action == SPDK_UEVENT_REMOVE); 102 CU_ASSERT(spdk_pci_addr_compare(&addr, &event.traddr) == 0); 103 104 /* Case 5: Add vfio-pci 0000:81:00.0 */ 105 commands = "ACTION=bind\0DEVPATH=\0SUBSYSTEM= \0DRIVER=vfio-pci\0PCI_SLOT_NAME=0000:81:00.0\0"; 106 107 memset(&event, 0, sizeof(event)); 108 rc = parse_subsystem_event(commands, &event); 109 CU_ASSERT(rc == uevent_expected_continue); 110 CU_ASSERT(event.action == SPDK_UEVENT_ADD); 111 CU_ASSERT(spdk_pci_addr_compare(&addr, &event.traddr) == 0); 112 memset(&event, 0, sizeof(event)); 113 114 /* Case 6: Remove vfio-pci 0000:81:00.0 but We don't parse vfio-pci remove uevent */ 115 commands = "ACTION=remove\0DEVPATH= \0SUBSYSTEM= \0DRIVER=vfio-pci \0PCI_SLOT_NAME=0000:81:00.0\0"; 116 117 memset(&event, 0, sizeof(event)); 118 rc = parse_subsystem_event(commands, &event); 119 CU_ASSERT(rc == uevent_normal_exit); 120 121 /* Case 7: Add wrong vfio-pci addr 000000 */ 122 commands = "ACTION=bind\0DEVPATH= \0SUBSYSTEM= \0DRIVER=vfio-pci \0PCI_SLOT_NAME=000000\0"; 123 124 memset(&event, 0, sizeof(event)); 125 rc = parse_subsystem_event(commands, &event); 126 CU_ASSERT(rc < 0); 127 128 /* Case 8: Add wrong driver vfio 0000:81:00.0 */ 129 commands = "ACTION=bind\0DEVPATH= \0SUBSYSTEM= \0DRIVER=vfio \0PCI_SLOT_NAME=0000:81:00.0\0"; 130 131 memset(&event, 0, sizeof(event)); 132 rc = parse_subsystem_event(commands, &event); 133 CU_ASSERT(rc == uevent_normal_exit); 134 } 135 136 #else 137 138 static void 139 test_pci_parse_event(void) 140 { 141 CU_ASSERT(1); 142 } 143 144 #endif 145 146 int main(int argc, char **argv) 147 { 148 CU_pSuite suite = NULL; 149 unsigned int num_failures; 150 151 CU_set_error_action(CUEA_ABORT); 152 CU_initialize_registry(); 153 154 suite = CU_add_suite("pci_event", NULL, NULL); 155 156 CU_ADD_TEST(suite, test_pci_parse_event); 157 158 CU_basic_set_mode(CU_BRM_VERBOSE); 159 CU_basic_run_tests(); 160 num_failures = CU_get_number_of_failures(); 161 CU_cleanup_registry(); 162 return num_failures; 163 } 164