Re: [PATCH v3 15/17] x86/hyperv: implement an MSI domain for root partition

kernel test robot
2020-11-24T20:11:38Z

[-- Attachment #1: Type: text/plain, Size: 16230 bytes --]

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 <lkp@intel.com>

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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33882 bytes --]