1 #include "kvm/pci.h" 2 #include "kvm/ioport.h" 3 #include "kvm/util.h" 4 #include "kvm/kvm.h" 5 6 #include <linux/err.h> 7 #include <assert.h> 8 9 #define PCI_BAR_OFFSET(b) (offsetof(struct pci_device_header, bar[b])) 10 11 static struct pci_device_header *pci_devices[PCI_MAX_DEVICES]; 12 13 static union pci_config_address pci_config_address; 14 15 /* This is within our PCI gap - in an unused area. 16 * Note this is a PCI *bus address*, is used to assign BARs etc.! 17 * (That's why it can still 32bit even with 64bit guests-- 64bit 18 * PCI isn't currently supported.) 19 */ 20 static u32 io_space_blocks = KVM_PCI_MMIO_AREA; 21 22 u32 pci_get_io_space_block(u32 size) 23 { 24 u32 block = io_space_blocks; 25 io_space_blocks += size; 26 27 return block; 28 } 29 30 static void *pci_config_address_ptr(u16 port) 31 { 32 unsigned long offset; 33 void *base; 34 35 offset = port - PCI_CONFIG_ADDRESS; 36 base = &pci_config_address; 37 38 return base + offset; 39 } 40 41 static bool pci_config_address_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size) 42 { 43 void *p = pci_config_address_ptr(port); 44 45 memcpy(p, data, size); 46 47 return true; 48 } 49 50 static bool pci_config_address_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size) 51 { 52 void *p = pci_config_address_ptr(port); 53 54 memcpy(data, p, size); 55 56 return true; 57 } 58 59 static struct ioport_operations pci_config_address_ops = { 60 .io_in = pci_config_address_in, 61 .io_out = pci_config_address_out, 62 }; 63 64 static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_number) 65 { 66 struct pci_device_header *dev; 67 68 if (pci_config_address.bus_number != bus_number) 69 return false; 70 71 if (pci_config_address.function_number != function_number) 72 return false; 73 74 if (device_number >= PCI_MAX_DEVICES) 75 return false; 76 77 dev = pci_devices[device_number]; 78 79 return dev != NULL; 80 } 81 82 static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size) 83 { 84 /* 85 * If someone accesses PCI configuration space offsets that are not 86 * aligned to 4 bytes, it uses ioports to signify that. 87 */ 88 pci_config_address.reg_offset = port - PCI_CONFIG_DATA; 89 90 pci__config_wr(kvm, pci_config_address, data, size); 91 92 return true; 93 } 94 95 static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size) 96 { 97 /* 98 * If someone accesses PCI configuration space offsets that are not 99 * aligned to 4 bytes, it uses ioports to signify that. 100 */ 101 pci_config_address.reg_offset = port - PCI_CONFIG_DATA; 102 103 pci__config_rd(kvm, pci_config_address, data, size); 104 105 return true; 106 } 107 108 static struct ioport_operations pci_config_data_ops = { 109 .io_in = pci_config_data_in, 110 .io_out = pci_config_data_out, 111 }; 112 113 void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size) 114 { 115 u8 dev_num; 116 117 dev_num = addr.device_number; 118 119 if (pci_device_exists(0, dev_num, 0)) { 120 unsigned long offset; 121 122 offset = addr.w & 0xff; 123 if (offset < sizeof(struct pci_device_header)) { 124 void *p = pci_devices[dev_num]; 125 u8 bar = (offset - PCI_BAR_OFFSET(0)) / (sizeof(u32)); 126 u32 sz = PCI_IO_SIZE; 127 128 if (bar < 6 && pci_devices[dev_num]->bar_size[bar]) 129 sz = pci_devices[dev_num]->bar_size[bar]; 130 131 /* 132 * If the kernel masks the BAR it would expect to find the 133 * size of the BAR there next time it reads from it. 134 * When the kernel got the size it would write the address 135 * back. 136 */ 137 if (*(u32 *)(p + offset)) { 138 /* See if kernel tries to mask one of the BARs */ 139 if ((offset >= PCI_BAR_OFFSET(0)) && 140 (offset <= PCI_BAR_OFFSET(6)) && 141 (ioport__read32(data) == 0xFFFFFFFF)) 142 memcpy(p + offset, &sz, sizeof(sz)); 143 else 144 memcpy(p + offset, data, size); 145 } 146 } 147 } 148 } 149 150 void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size) 151 { 152 u8 dev_num; 153 154 dev_num = addr.device_number; 155 156 if (pci_device_exists(0, dev_num, 0)) { 157 unsigned long offset; 158 159 offset = addr.w & 0xff; 160 if (offset < sizeof(struct pci_device_header)) { 161 void *p = pci_devices[dev_num]; 162 163 memcpy(data, p + offset, size); 164 } else { 165 memset(data, 0x00, size); 166 } 167 } else { 168 memset(data, 0xff, size); 169 } 170 } 171 172 int pci__register(struct pci_device_header *dev, u8 dev_num) 173 { 174 if (dev_num >= PCI_MAX_DEVICES) 175 return -ENOSPC; 176 177 pci_devices[dev_num] = dev; 178 179 return 0; 180 } 181 182 struct pci_device_header *pci__find_dev(u8 dev_num) 183 { 184 if (dev_num >= PCI_MAX_DEVICES) 185 return ERR_PTR(-EOVERFLOW); 186 187 return pci_devices[dev_num]; 188 } 189 190 int pci__init(struct kvm *kvm) 191 { 192 int r; 193 194 r = ioport__register(kvm, PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4, NULL); 195 if (r < 0) 196 return r; 197 198 r = ioport__register(kvm, PCI_CONFIG_ADDRESS + 0, &pci_config_address_ops, 4, NULL); 199 if (r < 0) { 200 ioport__unregister(kvm, PCI_CONFIG_DATA); 201 return r; 202 } 203 204 return 0; 205 } 206 dev_base_init(pci__init); 207 208 int pci__exit(struct kvm *kvm) 209 { 210 ioport__unregister(kvm, PCI_CONFIG_DATA); 211 ioport__unregister(kvm, PCI_CONFIG_ADDRESS); 212 213 return 0; 214 } 215 dev_base_exit(pci__exit); 216