Hi Wei, I love your patch! Perhaps something to improve: [auto build test WARNING on tip/x86/core] [also build test WARNING on asm-generic/master iommu/next tip/timers/core pci/next linus/master v5.10-rc5] [cannot apply to next-20201124] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Wei-Liu/Introducing-Linux-root-partition-support-for-Microsoft-Hypervisor/20201125-011026 base: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 238c91115cd05c71447ea071624a4c9fe661f970 config: i386-randconfig-a015-20201124 (attached as .config) compiler: gcc-9 (Debian 9.3.0-15) 9.3.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/ae7533bcd9667c0f23b545d941d3c68460f91ea2 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Wei-Liu/Introducing-Linux-root-partition-support-for-Microsoft-Hypervisor/20201125-011026 git checkout ae7533bcd9667c0f23b545d941d3c68460f91ea2 # save the attached .config to linux build tree make W=1 ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): arch/x86/hyperv/irqdomain.c: In function 'hv_irq_compose_msi_msg': arch/x86/hyperv/irqdomain.c:146:8: error: implicit declaration of function 'msi_desc_to_pci_dev'; did you mean 'msi_desc_to_dev'? [-Werror=implicit-function-declaration] 146 | dev = msi_desc_to_pci_dev(msidesc); | ^~~~~~~~~~~~~~~~~~~ | msi_desc_to_dev >> arch/x86/hyperv/irqdomain.c:146:6: warning: assignment to 'struct pci_dev *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 146 | dev = msi_desc_to_pci_dev(msidesc); | ^ arch/x86/hyperv/irqdomain.c: In function 'hv_msi_domain_free_irqs': arch/x86/hyperv/irqdomain.c:277:2: error: implicit declaration of function 'for_each_pci_msi_entry'; did you mean 'for_each_msi_entry'? [-Werror=implicit-function-declaration] 277 | for_each_pci_msi_entry(entry, pdev) { | ^~~~~~~~~~~~~~~~~~~~~~ | for_each_msi_entry arch/x86/hyperv/irqdomain.c:277:37: error: expected ';' before '{' token 277 | for_each_pci_msi_entry(entry, pdev) { | ^~ | ; arch/x86/hyperv/irqdomain.c:268:6: warning: unused variable 'i' [-Wunused-variable] 268 | int i; | ^ arch/x86/hyperv/irqdomain.c: At top level: arch/x86/hyperv/irqdomain.c:298:22: error: 'msi_domain_set_affinity' undeclared here (not in a function); did you mean 'irq_can_set_affinity'? 298 | .irq_set_affinity = msi_domain_set_affinity, | ^~~~~~~~~~~~~~~~~~~~~~~ | irq_can_set_affinity arch/x86/hyperv/irqdomain.c:302:15: error: variable 'pci_msi_domain_ops' has initializer but incomplete type 302 | static struct msi_domain_ops pci_msi_domain_ops = { | ^~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:303:3: error: 'struct msi_domain_ops' has no member named 'domain_free_irqs' 303 | .domain_free_irqs = hv_msi_domain_free_irqs, | ^~~~~~~~~~~~~~~~ >> arch/x86/hyperv/irqdomain.c:303:22: warning: excess elements in struct initializer 303 | .domain_free_irqs = hv_msi_domain_free_irqs, | ^~~~~~~~~~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:303:22: note: (near initialization for 'pci_msi_domain_ops') arch/x86/hyperv/irqdomain.c:304:3: error: 'struct msi_domain_ops' has no member named 'msi_prepare' 304 | .msi_prepare = pci_msi_prepare, | ^~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:304:18: error: 'pci_msi_prepare' undeclared here (not in a function) 304 | .msi_prepare = pci_msi_prepare, | ^~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:304:18: warning: excess elements in struct initializer arch/x86/hyperv/irqdomain.c:304:18: note: (near initialization for 'pci_msi_domain_ops') arch/x86/hyperv/irqdomain.c:307:15: error: variable 'hv_pci_msi_domain_info' has initializer but incomplete type 307 | static struct msi_domain_info hv_pci_msi_domain_info = { | ^~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:308:3: error: 'struct msi_domain_info' has no member named 'flags' 308 | .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ^~~~~ arch/x86/hyperv/irqdomain.c:308:12: error: 'MSI_FLAG_USE_DEF_DOM_OPS' undeclared here (not in a function) 308 | .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:308:39: error: 'MSI_FLAG_USE_DEF_CHIP_OPS' undeclared here (not in a function) 308 | .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ^~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:309:6: error: 'MSI_FLAG_PCI_MSIX' undeclared here (not in a function) 309 | MSI_FLAG_PCI_MSIX, | ^~~~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:308:12: warning: excess elements in struct initializer 308 | .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:308:12: note: (near initialization for 'hv_pci_msi_domain_info') arch/x86/hyperv/irqdomain.c:310:3: error: 'struct msi_domain_info' has no member named 'ops' 310 | .ops = &pci_msi_domain_ops, | ^~~ arch/x86/hyperv/irqdomain.c:310:10: warning: excess elements in struct initializer 310 | .ops = &pci_msi_domain_ops, | ^ arch/x86/hyperv/irqdomain.c:310:10: note: (near initialization for 'hv_pci_msi_domain_info') arch/x86/hyperv/irqdomain.c:311:3: error: 'struct msi_domain_info' has no member named 'chip' 311 | .chip = &hv_pci_msi_controller, | ^~~~ arch/x86/hyperv/irqdomain.c:311:11: warning: excess elements in struct initializer 311 | .chip = &hv_pci_msi_controller, | ^ arch/x86/hyperv/irqdomain.c:311:11: note: (near initialization for 'hv_pci_msi_domain_info') arch/x86/hyperv/irqdomain.c:312:3: error: 'struct msi_domain_info' has no member named 'handler' 312 | .handler = handle_edge_irq, | ^~~~~~~ arch/x86/hyperv/irqdomain.c:312:13: warning: excess elements in struct initializer 312 | .handler = handle_edge_irq, | ^~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:312:13: note: (near initialization for 'hv_pci_msi_domain_info') arch/x86/hyperv/irqdomain.c:313:3: error: 'struct msi_domain_info' has no member named 'handler_name' 313 | .handler_name = "edge", | ^~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:313:18: warning: excess elements in struct initializer 313 | .handler_name = "edge", | ^~~~~~ arch/x86/hyperv/irqdomain.c:313:18: note: (near initialization for 'hv_pci_msi_domain_info') >> arch/x86/hyperv/irqdomain.c:316:28: warning: no previous prototype for 'hv_create_pci_msi_domain' [-Wmissing-prototypes] 316 | struct irq_domain * __init hv_create_pci_msi_domain(void) | ^~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c: In function 'hv_create_pci_msi_domain': arch/x86/hyperv/irqdomain.c:321:7: error: implicit declaration of function 'irq_domain_alloc_named_fwnode' [-Werror=implicit-function-declaration] 321 | fn = irq_domain_alloc_named_fwnode("HV-PCI-MSI"); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> arch/x86/hyperv/irqdomain.c:321:5: warning: assignment to 'struct fwnode_handle *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 321 | fn = irq_domain_alloc_named_fwnode("HV-PCI-MSI"); | ^ arch/x86/hyperv/irqdomain.c:323:7: error: implicit declaration of function 'pci_msi_create_irq_domain'; did you mean 'pci_msi_get_device_domain'? [-Werror=implicit-function-declaration] 323 | d = pci_msi_create_irq_domain(fn, &hv_pci_msi_domain_info, x86_vector_domain); | ^~~~~~~~~~~~~~~~~~~~~~~~~ | pci_msi_get_device_domain arch/x86/hyperv/irqdomain.c:323:62: error: 'x86_vector_domain' undeclared (first use in this function) 323 | d = pci_msi_create_irq_domain(fn, &hv_pci_msi_domain_info, x86_vector_domain); | ^~~~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:323:62: note: each undeclared identifier is reported only once for each function it appears in arch/x86/hyperv/irqdomain.c: At top level: arch/x86/hyperv/irqdomain.c:302:30: error: storage size of 'pci_msi_domain_ops' isn't known 302 | static struct msi_domain_ops pci_msi_domain_ops = { | ^~~~~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:307:31: error: storage size of 'hv_pci_msi_domain_info' isn't known 307 | static struct msi_domain_info hv_pci_msi_domain_info = { | ^~~~~~~~~~~~~~~~~~~~~~ arch/x86/hyperv/irqdomain.c:227:13: warning: 'hv_teardown_msi_irq_common' defined but not used [-Wunused-function] 227 | static void hv_teardown_msi_irq_common(struct pci_dev *dev, struct msi_desc *msidesc, int irq) | ^~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors vim +146 arch/x86/hyperv/irqdomain.c 133 134 static int hv_unmap_msi_interrupt(struct pci_dev *dev, struct hv_interrupt_entry *old_entry); 135 static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) 136 { 137 struct msi_desc *msidesc; 138 struct pci_dev *dev; 139 struct hv_interrupt_entry out_entry, *stored_entry; 140 struct irq_cfg *cfg = irqd_cfg(data); 141 struct cpumask *affinity; 142 int cpu, vcpu; 143 u16 status; 144 145 msidesc = irq_data_get_msi_desc(data); > 146 dev = msi_desc_to_pci_dev(msidesc); 147 148 if (!cfg) { 149 pr_debug("%s: cfg is NULL", __func__); 150 return; 151 } 152 153 affinity = irq_data_get_effective_affinity_mask(data); 154 cpu = cpumask_first_and(affinity, cpu_online_mask); 155 vcpu = hv_cpu_number_to_vp_number(cpu); 156 157 if (data->chip_data) { 158 /* 159 * This interrupt is already mapped. Let's unmap first. 160 * 161 * We don't use retarget interrupt hypercalls here because 162 * Microsoft Hypervisor doens't allow root to change the vector 163 * or specify VPs outside of the set that is initially used 164 * during mapping. 165 */ 166 stored_entry = data->chip_data; 167 data->chip_data = NULL; 168 169 status = hv_unmap_msi_interrupt(dev, stored_entry); 170 171 kfree(stored_entry); 172 173 if (status != HV_STATUS_SUCCESS) { 174 pr_debug("%s: failed to unmap, status %d", __func__, status); 175 return; 176 } 177 } 178 179 stored_entry = kzalloc(sizeof(*stored_entry), GFP_ATOMIC); 180 if (!stored_entry) { 181 pr_debug("%s: failed to allocate chip data\n", __func__); 182 return; 183 } 184 185 status = hv_map_msi_interrupt(dev, vcpu, cfg->vector, &out_entry); 186 if (status != HV_STATUS_SUCCESS) { 187 kfree(stored_entry); 188 return; 189 } 190 191 *stored_entry = out_entry; 192 data->chip_data = stored_entry; 193 entry_to_msi_msg(&out_entry, msg); 194 195 return; 196 } 197 198 static int hv_unmap_interrupt(u64 id, struct hv_interrupt_entry *old_entry) 199 { 200 unsigned long flags; 201 struct hv_input_unmap_device_interrupt *input; 202 struct hv_interrupt_entry *intr_entry; 203 u16 status; 204 205 local_irq_save(flags); 206 input = *this_cpu_ptr(hyperv_pcpu_input_arg); 207 208 memset(input, 0, sizeof(*input)); 209 intr_entry = &input->interrupt_entry; 210 input->partition_id = hv_current_partition_id; 211 input->device_id = id; 212 *intr_entry = *old_entry; 213 214 status = hv_do_rep_hypercall(HVCALL_UNMAP_DEVICE_INTERRUPT, 0, 0, input, NULL) & 215 HV_HYPERCALL_RESULT_MASK; 216 local_irq_restore(flags); 217 218 return status; 219 } 220 221 static int hv_unmap_msi_interrupt(struct pci_dev *dev, struct hv_interrupt_entry *old_entry) 222 { 223 return hv_unmap_interrupt(hv_build_pci_dev_id(dev).as_uint64, old_entry) 224 & HV_HYPERCALL_RESULT_MASK; 225 } 226 227 static void hv_teardown_msi_irq_common(struct pci_dev *dev, struct msi_desc *msidesc, int irq) 228 { 229 u16 status; 230 struct hv_interrupt_entry old_entry; 231 struct irq_desc *desc; 232 struct irq_data *data; 233 struct msi_msg msg; 234 235 desc = irq_to_desc(irq); 236 if (!desc) { 237 pr_debug("%s: no irq desc\n", __func__); 238 return; 239 } 240 241 data = &desc->irq_data; 242 if (!data) { 243 pr_debug("%s: no irq data\n", __func__); 244 return; 245 } 246 247 if (!data->chip_data) { 248 pr_debug("%s: no chip data\n!", __func__); 249 return; 250 } 251 252 old_entry = *(struct hv_interrupt_entry *)data->chip_data; 253 entry_to_msi_msg(&old_entry, &msg); 254 255 kfree(data->chip_data); 256 data->chip_data = NULL; 257 258 status = hv_unmap_msi_interrupt(dev, &old_entry); 259 260 if (status != HV_STATUS_SUCCESS) { 261 pr_err("%s: hypercall failed, status %d\n", __func__, status); 262 return; 263 } 264 } 265 266 static void hv_msi_domain_free_irqs(struct irq_domain *domain, struct device *dev) 267 { 268 int i; 269 struct msi_desc *entry; 270 struct pci_dev *pdev; 271 272 if (WARN_ON_ONCE(!dev_is_pci(dev))) 273 return; 274 275 pdev = to_pci_dev(dev); 276 277 for_each_pci_msi_entry(entry, pdev) { 278 if (entry->irq) { 279 for (i = 0; i < entry->nvec_used; i++) { 280 hv_teardown_msi_irq_common(pdev, entry, entry->irq + i); 281 irq_domain_free_irqs(entry->irq + i, 1); 282 } 283 } 284 } 285 } 286 287 /* 288 * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, 289 * which implement the MSI or MSI-X Capability Structure. 290 */ 291 static struct irq_chip hv_pci_msi_controller = { 292 .name = "HV-PCI-MSI", 293 .irq_unmask = pci_msi_unmask_irq, 294 .irq_mask = pci_msi_mask_irq, 295 .irq_ack = irq_chip_ack_parent, 296 .irq_retrigger = irq_chip_retrigger_hierarchy, 297 .irq_compose_msi_msg = hv_irq_compose_msi_msg, 298 .irq_set_affinity = msi_domain_set_affinity, 299 .flags = IRQCHIP_SKIP_SET_WAKE, 300 }; 301 302 static struct msi_domain_ops pci_msi_domain_ops = { > 303 .domain_free_irqs = hv_msi_domain_free_irqs, 304 .msi_prepare = pci_msi_prepare, 305 }; 306 307 static struct msi_domain_info hv_pci_msi_domain_info = { 308 .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 309 MSI_FLAG_PCI_MSIX, 310 .ops = &pci_msi_domain_ops, 311 .chip = &hv_pci_msi_controller, 312 .handler = handle_edge_irq, 313 .handler_name = "edge", 314 }; 315 > 316 struct irq_domain * __init hv_create_pci_msi_domain(void) 317 { 318 struct irq_domain *d = NULL; 319 struct fwnode_handle *fn; 320 > 321 fn = irq_domain_alloc_named_fwnode("HV-PCI-MSI"); 322 if (fn) 323 d = pci_msi_create_irq_domain(fn, &hv_pci_msi_domain_info, x86_vector_domain); 324 325 /* No point in going further if we can't get an irq domain */ 326 BUG_ON(!d); 327 328 return d; 329 } 330 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org