mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
cmdline: document and enforce "extra_guest_irqs" upper bounds
PHYSDEVOP_pirq_eoi_gmfn_v<N> accepting just a single GFN implies that no more than 32k pIRQ-s can be used by a domain on x86. Document this upper bound. To also enforce the limit, (ab)use both arch_hwdom_irqs() (changing its parameter type) and setup_system_domains(). This is primarily to avoid exposing the two static variables or introducing yet further arch hooks. While touching arch_hwdom_irqs() also mark it hwdom-init. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Roger Pau Monné <roger.pau@citrix.com> amend 'cmdline: document and enforce "extra_guest_irqs" upper bounds' Address late review comments for what is now commit17f6d398f7: - bound max_irqs right away against nr_irqs - introduce a #define for a constant used twice Requested-by: Roger Pau Monné <roger.pau@citrix.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com> master commit:17f6d398f7master date: 2024-07-02 12:00:27 +0200 master commit:1f56accba3master date: 2024-07-03 14:03:27 +0200
This commit is contained in:
1 parent
750475017d
commit
a626bfbcbb
4 files changed
+36
-11
No files matched your search
@@ -1141,7 +1141,8 @@ common for all domUs, while the optional second number (preceded by a comma)
|
||||
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.
|
||||
|
||||
|
||||
+10
-7
@@ -2661,18 +2661,21 @@ void __init ioapic_init(void)
|
||||
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());
|
||||
/* Bounding by the domain pirq EOI bitmap capacity. */
|
||||
const unsigned int max_irqs = min_t(unsigned int, nr_irqs,
|
||||
PAGE_SIZE * BITS_PER_BYTE);
|
||||
|
||||
if ( !domid )
|
||||
if ( is_system_domain(d) )
|
||||
return max_irqs;
|
||||
|
||||
if ( !d->domain_id )
|
||||
n = min(n, dom0_max_vcpus());
|
||||
n = min(nr_irqs_gsi + n * NR_DYNAMIC_VECTORS, nr_irqs);
|
||||
n = min(nr_irqs_gsi + n * NR_DYNAMIC_VECTORS, max_irqs);
|
||||
|
||||
/* Bounded by the domain pirq eoi bitmap gfn. */
|
||||
n = min_t(unsigned int, n, PAGE_SIZE * BITS_PER_BYTE);
|
||||
|
||||
printk("Dom%d has maximum %u PIRQs\n", domid, n);
|
||||
printk("%pd has maximum %u PIRQs\n", d, n);
|
||||
|
||||
return n;
|
||||
}
|
||||
+22
-2
@@ -351,7 +351,8 @@ static int late_hwdom_init(struct domain *d)
|
||||
}
|
||||
|
||||
static unsigned int __read_mostly extra_hwdom_irqs;
|
||||
static unsigned int __read_mostly extra_domU_irqs = 32;
|
||||
#define DEFAULT_EXTRA_DOMU_IRQS 32U
|
||||
static unsigned int __read_mostly extra_domU_irqs = DEFAULT_EXTRA_DOMU_IRQS;
|
||||
|
||||
static int __init cf_check parse_extra_guest_irqs(const char *s)
|
||||
{
|
||||
@@ -659,7 +660,7 @@ struct domain *domain_create(domid_t domid,
|
||||
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);
|
||||
@@ -783,6 +784,25 @@ void __init setup_system_domains(void)
|
||||
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(DEFAULT_EXTRA_DOMU_IRQS, 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
|
||||
|
||||
@@ -194,8 +194,9 @@ extern irq_desc_t *pirq_spin_lock_irq_desc(
|
||||
|
||||
unsigned int set_desc_affinity(struct irq_desc *, const cpumask_t *);
|
||||
|
||||
/* When passed a system domain, this returns the maximum permissible value. */
|
||||
#ifndef arch_hwdom_irqs
|
||||
unsigned int arch_hwdom_irqs(domid_t);
|
||||
unsigned int arch_hwdom_irqs(const struct domain *);
|
||||
#endif
|
||||
|
||||
#ifndef arch_evtchn_bind_pirq
|
||||
|
||||