[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [XEN PATCH v15 2/4] x86/irq: allow setting IRQ permissions from GSI instead of pIRQ
Hi Daniel, On 2024/9/11 14:58, Chen, Jiqian wrote: > Some domains are not aware of the pIRQ abstraction layer that maps > interrupt sources into Xen space interrupt numbers. pIRQs values are > only exposed to domains that have the option to route physical > interrupts over event channels. > > This creates issues for PCI-passthrough from a PVH domain, as some of > the passthrough related hypercalls use pIRQ as references to physical > interrupts on the system. One of such interfaces is > XEN_DOMCTL_irq_permission, used to grant or revoke access to > interrupts, takes a pIRQ as the reference to the interrupt to be > adjusted. > > Since PVH doesn't manage interrupts in terms of pIRQs, introduce a new > hypercall that allows setting interrupt permissions based on GSI value > rather than pIRQ. > > Note the GSI hypercall parameters is translated to an IRQ value (in > case there are ACPI overrides) before doing the checks. > > Signed-off-by: Jiqian Chen <Jiqian.Chen@xxxxxxx> > Signed-off-by: Huang Rui <ray.huang@xxxxxxx> > Signed-off-by: Jiqian Chen <Jiqian.Chen@xxxxxxx> > --- > CC: Daniel P . Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx> > Remaining comment @Daniel P . Smith: > + ret = -EPERM; > + if ( !irq_access_permitted(currd, irq) || > + xsm_irq_permission(XSM_HOOK, d, irq, flags) ) > + break; > Is it okay to issue the XSM check using the translated value(irq), > not the one(gsi) that was originally passed into the hypercall? Could you please take a time to answer at this question? > --- > v13->v15 changes: > Change to use the commit message wrote by Roger. > Change the code comment from "Check all bits are zero except lowest bit" to > "Check only valid bits are set". > Change the end return sentence of gsi_2_irq to "return irq ?: -EINVAL;" to > preserve the error code from apic_pin_2_gsi_irq(). > > v12->v13 changes: > For struct xen_domctl_gsi_permission, rename "access_flag" to "flags", change > its type from uint8_t to uint32_t, delete "pad", add XEN_DOMCTL_GSI_REVOKE > and XEN_DOMCTL_GSI_GRANT macros. > Move "gsi > highest_gsi()" into function gsi_2_irq. > Modify parameter gsi in function gsi_2_irq and mp_find_ioapic to unsigned int > type. > Delete unnecessary spaces and brackets around "~XEN_DOMCTL_GSI_ACTION_MASK". > Delete unnecessary goto statements and change to direct break. > Add description in commit message to explain how gsi to irq isconverted. > > v11->v12 changes: > Change nr_irqs_gsi to highest_gsi() to check gsi boundary, then need to > remove "__init" of highest_gsi function. > Change the check of irq boundary from <0 to <=0, and remove unnecessary space. > Add #define XEN_DOMCTL_GSI_PERMISSION_MASK 1 to get lowest bit. > > v10->v11 changes: > Extracted from patch#5 of v10 into a separate patch. > Add non-zero judgment for other bits of allow_access. > Delete unnecessary judgment "if ( is_pv_domain(currd) || has_pirq(currd) )". > Change the error exit path identifier "out" to "gsi_permission_out". > Use ARRAY_SIZE() instead of open coed. > > v9->v10 changes: > Modified the commit message to further describe the purpose of adding > XEN_DOMCTL_gsi_permission. > Added a check for all zeros in the padding field in > XEN_DOMCTL_gsi_permission, and used currd instead of current->domain. > In the function gsi_2_irq, apic_pin_2_gsi_irq was used instead of the > original new code, and error handling for irq0 was added. > Deleted the extra spaces in the upper and lower lines of the struct > xen_domctl_gsi_permission definition. > > v8->v9 changes: > Change the commit message to describe more why we need this new hypercall. > Add comment above "if ( is_pv_domain(current->domain) || > has_pirq(current->domain) )" to explain why we need this check. > Add gsi_2_irq to transform gsi to irq, instead of considering gsi == irq. > Add explicit padding to struct xen_domctl_gsi_permission. > > v5->v8 changes: > Nothing. > > v4->v5 changes: > New implementation to add new hypercall XEN_DOMCTL_gsi_permission to grant > gsi. > --- > xen/arch/x86/domctl.c | 29 +++++++++++++++++++++++++++++ > xen/arch/x86/include/asm/io_apic.h | 2 ++ > xen/arch/x86/io_apic.c | 19 +++++++++++++++++++ > xen/arch/x86/mpparse.c | 7 +++---- > xen/include/public/domctl.h | 10 ++++++++++ > xen/xsm/flask/hooks.c | 1 + > 6 files changed, 64 insertions(+), 4 deletions(-) > > diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c > index 68b5b46d1a83..939b1de0ee59 100644 > --- a/xen/arch/x86/domctl.c > +++ b/xen/arch/x86/domctl.c > @@ -36,6 +36,7 @@ > #include <asm/xstate.h> > #include <asm/psr.h> > #include <asm/cpu-policy.h> > +#include <asm/io_apic.h> > > static int update_domain_cpu_policy(struct domain *d, > xen_domctl_cpu_policy_t *xdpc) > @@ -237,6 +238,34 @@ long arch_do_domctl( > break; > } > > + case XEN_DOMCTL_gsi_permission: > + { > + int irq; > + unsigned int gsi = domctl->u.gsi_permission.gsi; > + uint32_t flags = domctl->u.gsi_permission.flags; > + > + /* Check only valid bits are set */ > + ret = -EINVAL; > + if ( flags & ~XEN_DOMCTL_GSI_ACTION_MASK ) > + break; > + > + ret = irq = gsi_2_irq(gsi); > + if ( ret <= 0 ) > + break; > + > + ret = -EPERM; > + if ( !irq_access_permitted(currd, irq) || > + xsm_irq_permission(XSM_HOOK, d, irq, flags) ) > + break; > + > + if ( flags ) > + ret = irq_permit_access(d, irq); > + else > + ret = irq_deny_access(d, irq); > + > + break; > + } > + > case XEN_DOMCTL_getpageframeinfo3: > { > unsigned int num = domctl->u.getpageframeinfo3.num; > diff --git a/xen/arch/x86/include/asm/io_apic.h > b/xen/arch/x86/include/asm/io_apic.h > index 78268ea8f666..62456806c7af 100644 > --- a/xen/arch/x86/include/asm/io_apic.h > +++ b/xen/arch/x86/include/asm/io_apic.h > @@ -213,5 +213,7 @@ unsigned highest_gsi(void); > > int ioapic_guest_read( unsigned long physbase, unsigned int reg, u32 *pval); > int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val); > +int mp_find_ioapic(unsigned int gsi); > +int gsi_2_irq(unsigned int gsi); > > #endif > diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c > index 772700584639..e40d2f7dbd75 100644 > --- a/xen/arch/x86/io_apic.c > +++ b/xen/arch/x86/io_apic.c > @@ -955,6 +955,25 @@ static int pin_2_irq(int idx, int apic, int pin) > return irq; > } > > +int gsi_2_irq(unsigned int gsi) > +{ > + int ioapic, irq; > + unsigned int pin; > + > + if ( gsi > highest_gsi() ) > + return -ERANGE; > + > + ioapic = mp_find_ioapic(gsi); > + if ( ioapic < 0 ) > + return -EINVAL; > + > + pin = gsi - io_apic_gsi_base(ioapic); > + > + irq = apic_pin_2_gsi_irq(ioapic, pin); > + > + return irq ?: -EINVAL; > +} > + > static inline int IO_APIC_irq_trigger(int irq) > { > int apic, idx, pin; > diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c > index 306d8ed97a83..e13b83bbe9dd 100644 > --- a/xen/arch/x86/mpparse.c > +++ b/xen/arch/x86/mpparse.c > @@ -842,8 +842,7 @@ static struct mp_ioapic_routing { > } mp_ioapic_routing[MAX_IO_APICS]; > > > -static int mp_find_ioapic ( > - int gsi) > +int mp_find_ioapic(unsigned int gsi) > { > unsigned int i; > > @@ -854,7 +853,7 @@ static int mp_find_ioapic ( > return i; > } > > - printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); > + printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %u\n", gsi); > > return -1; > } > @@ -915,7 +914,7 @@ void __init mp_register_ioapic ( > return; > } > > -unsigned __init highest_gsi(void) > +unsigned highest_gsi(void) > { > unsigned x, res = 0; > for (x = 0; x < nr_ioapics; x++) > diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h > index 2a49fe46ce25..e1028fc524cf 100644 > --- a/xen/include/public/domctl.h > +++ b/xen/include/public/domctl.h > @@ -464,6 +464,14 @@ struct xen_domctl_irq_permission { > uint8_t pad[3]; > }; > > +/* XEN_DOMCTL_gsi_permission */ > +struct xen_domctl_gsi_permission { > + uint32_t gsi; > +#define XEN_DOMCTL_GSI_REVOKE 0 > +#define XEN_DOMCTL_GSI_GRANT 1 > +#define XEN_DOMCTL_GSI_ACTION_MASK 1 > + uint32_t flags; > +}; > > /* XEN_DOMCTL_iomem_permission */ > struct xen_domctl_iomem_permission { > @@ -1306,6 +1314,7 @@ struct xen_domctl { > #define XEN_DOMCTL_get_paging_mempool_size 85 > #define XEN_DOMCTL_set_paging_mempool_size 86 > #define XEN_DOMCTL_dt_overlay 87 > +#define XEN_DOMCTL_gsi_permission 88 > #define XEN_DOMCTL_gdbsx_guestmemio 1000 > #define XEN_DOMCTL_gdbsx_pausevcpu 1001 > #define XEN_DOMCTL_gdbsx_unpausevcpu 1002 > @@ -1328,6 +1337,7 @@ struct xen_domctl { > struct xen_domctl_setdomainhandle setdomainhandle; > struct xen_domctl_setdebugging setdebugging; > struct xen_domctl_irq_permission irq_permission; > + struct xen_domctl_gsi_permission gsi_permission; > struct xen_domctl_iomem_permission iomem_permission; > struct xen_domctl_ioport_permission ioport_permission; > struct xen_domctl_hypercall_init hypercall_init; > diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c > index 278ad38c2af3..dfa23738cd8a 100644 > --- a/xen/xsm/flask/hooks.c > +++ b/xen/xsm/flask/hooks.c > @@ -695,6 +695,7 @@ static int cf_check flask_domctl(struct domain *d, > unsigned int cmd, > case XEN_DOMCTL_shadow_op: > case XEN_DOMCTL_ioport_permission: > case XEN_DOMCTL_ioport_mapping: > + case XEN_DOMCTL_gsi_permission: > #endif > #ifdef CONFIG_HAS_PASSTHROUGH > /* -- Best regards, Jiqian Chen.
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |