is for dom0. Changing the setting for domU has no impact on dom0 and vice
versa. For example to change dom0 without changing domU, use
`extra_guest_irqs=,512`. The default value for Dom0 and an eventual separate
-hardware domain is architecture dependent.
+hardware domain is architecture dependent. The upper limit for both values on
+x86 is such that the resulting total number of IRQs can't be higher than 32768.
Note that specifying zero as domU value means zero, while for dom0 it means
to use the default.
nr_irqs_gsi, nr_irqs - nr_irqs_gsi);
}
-unsigned int arch_hwdom_irqs(domid_t domid)
+unsigned int __hwdom_init arch_hwdom_irqs(const struct domain *d)
{
unsigned int n = fls(num_present_cpus());
+ /* Bounded by the domain pirq EOI bitmap gfn. */
+ const unsigned int max_irqs = PAGE_SIZE * BITS_PER_BYTE;
- if ( !domid )
- n = min(n, dom0_max_vcpus());
- n = min(nr_irqs_gsi + n * NR_DYNAMIC_VECTORS, nr_irqs);
+ if ( is_system_domain(d) )
+ return max_irqs;
- /* Bounded by the domain pirq eoi bitmap gfn. */
- n = min_t(unsigned int, n, PAGE_SIZE * BITS_PER_BYTE);
+ if ( !d->domain_id )
+ n = min(n, dom0_max_vcpus());
+ n = min(nr_irqs_gsi + n * NR_DYNAMIC_VECTORS, min(nr_irqs, max_irqs));
- printk("Dom%d has maximum %u PIRQs\n", domid, n);
+ printk("%pd has maximum %u PIRQs\n", d, n);
return n;
}
d->nr_pirqs = nr_static_irqs + extra_domU_irqs;
else
d->nr_pirqs = extra_hwdom_irqs ? nr_static_irqs + extra_hwdom_irqs
- : arch_hwdom_irqs(domid);
+ : arch_hwdom_irqs(d);
d->nr_pirqs = min(d->nr_pirqs, nr_irqs);
radix_tree_init(&d->pirq_tree);
if ( IS_ERR(dom_xen) )
panic("Failed to create d[XEN]: %ld\n", PTR_ERR(dom_xen));
+#ifdef CONFIG_HAS_PIRQ
+ /* Bound-check values passed via "extra_guest_irqs=". */
+ {
+ unsigned int n = max(arch_hwdom_irqs(dom_xen), nr_static_irqs);
+
+ if ( extra_hwdom_irqs > n - nr_static_irqs )
+ {
+ extra_hwdom_irqs = n - nr_static_irqs;
+ printk(XENLOG_WARNING "hwdom IRQs bounded to %u\n", n);
+ }
+ if ( extra_domU_irqs > max(32U, n - nr_static_irqs) )
+ {
+ extra_domU_irqs = n - nr_static_irqs;
+ printk(XENLOG_WARNING "domU IRQs bounded to %u\n", n);
+ }
+ }
+#endif
+
/*
* Initialise our DOMID_IO domain.
* This domain owns I/O pages that are within the range of the page_info
unsigned int set_desc_affinity(struct irq_desc *desc, const cpumask_t *mask);
+/* When passed a system domain, this returns the maximum permissible value. */
#ifndef arch_hwdom_irqs
-unsigned int arch_hwdom_irqs(domid_t domid);
+unsigned int arch_hwdom_irqs(const struct domain *d);
#endif
#ifndef arch_evtchn_bind_pirq