[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH RFC 2/2] AMD IOMMU: allow command line overrides for broken IVRS tables
Tuesday, August 27, 2013, 10:05:41 AM, you wrote: > With there being so many systems with broken ACPI tables, and with it > generally being known what's wrong with those tables, give people a > handle to overcome the resulting disabling of their IOMMUs. > Inspired by Linux side patches providing similar functionality. > TODO: documentation Hi Jan, Would the syntax be the same as linux ? f.e. ivrs_ioapic[6]=00:14.0 for my case ? I'm asking because using it on the command line seems to enable the iommu fine (which it shouldn't without the override), but i don't seem to see the "IVHD: Command line override present for IO-APIC %#x" in my xl dmesg... -- Sander > Suggested-by: Sander Eikelenboom <linux@xxxxxxxxxxxxxx> > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > --- a/xen/common/kernel.c > +++ b/xen/common/kernel.c > @@ -81,9 +81,15 @@ void __init cmdline_parse(const char *cm > /* Search for value part of a key=value option. */ > optval = strchr(opt, '='); > if ( optval != NULL ) > + { > *optval++ = '\0'; /* nul-terminate the option value */ > + q = strpbrk(opt, "([{<"); > + } > else > + { > optval = q; /* default option value is empty string */ > + q = NULL; > + } > > /* Boolean parameters can be inverted with 'no-' prefix. */ > bool_assert = !!strncmp("no-", optkey, 3); > @@ -93,7 +99,17 @@ void __init cmdline_parse(const char *cm > for ( param = &__setup_start; param < &__setup_end; param++ ) > { > if ( strcmp(param->name, optkey) ) > + { > + if ( param->type == OPT_CUSTOM && q && > + strlen(param->name) == q + 1 - opt && > + !strncmp(param->name, opt, q + 1 - opt) ) > + { > + optval[-1] = '='; > + ((void (*)(const char *))param->var)(q); > + optval[-1] = '\0'; > + } > continue; > + } > > switch ( param->type ) > { > --- a/xen/drivers/passthrough/amd/iommu_acpi.c > +++ b/xen/drivers/passthrough/amd/iommu_acpi.c > @@ -633,6 +633,50 @@ static u16 __init parse_ivhd_device_exte > return dev_length; > } > > +static __initdata DECLARE_BITMAP(ioapic_cmdline, ARRAY_SIZE(ioapic_sbdf)); > + > +static void __init parse_ivrs_ioapic(char *str) > +{ > + const char *s = str; > + unsigned long id; > + unsigned int seg, bus, dev, func; > + > + ASSERT(*s == '['); > + id = simple_strtoul(s + 1, &s, 0); + if ( id >>= ARRAY_SIZE(ioapic_sbdf) || *s != ']' || *++s != '=' ) > + return; > + > + s = parse_pci(s + 1, &seg, &bus, &dev, &func); > + if ( !s || *s ) > + return; > + > + ioapic_sbdf[id].bdf = PCI_BDF(bus, dev, func); > + ioapic_sbdf[id].seg = seg; > + __set_bit(id, ioapic_cmdline); > +} > +custom_param("ivrs_ioapic[", parse_ivrs_ioapic); > + > +static void __init parse_ivrs_hpet(char *str) > +{ > + const char *s = str; > + unsigned long id; > + unsigned int seg, bus, dev, func; > + > + ASSERT(*s == '['); > + id = simple_strtoul(s + 1, &s, 0); > + if ( id != (typeof(hpet_sbdf.id))id || *s != ']' || *++s != '=' ) > + return; > + > + s = parse_pci(s + 1, &seg, &bus, &dev, &func); > + if ( !s || *s ) > + return; > + > + hpet_sbdf.bdf = PCI_BDF(bus, dev, func); > + hpet_sbdf.seg = seg; > + hpet_sbdf.cmdline = 1; > +} > +custom_param("ivrs_hpet[", parse_ivrs_hpet); > + > static u16 __init parse_ivhd_device_special( > const struct acpi_ivrs_device8c *special, u16 seg, > u16 header_length, u16 block_length, struct amd_iommu *iommu) > @@ -674,7 +718,17 @@ static u16 __init parse_ivhd_device_spec > if ( IO_APIC_ID(apic) != special->handle ) > continue; > > - if ( ioapic_sbdf[special->handle].pin_2_idx ) > + if ( special->handle >= ARRAY_SIZE(ioapic_sbdf) ) > + { > + printk(XENLOG_ERR "IVHD Error: IO-APIC %#x entry beyond > bounds\n", > + special->handle); > + return 0; > + } > + > + if ( test_bit(special->handle, ioapic_cmdline) ) > + AMD_IOMMU_DEBUG("IVHD: Command line override present for > IO-APIC %#x\n", > + special->handle); > + else if ( ioapic_sbdf[special->handle].pin_2_idx ) > { > if ( ioapic_sbdf[special->handle].bdf == bdf && > ioapic_sbdf[special->handle].seg == seg ) > @@ -717,14 +771,18 @@ static u16 __init parse_ivhd_device_spec > break; > case ACPI_IVHD_HPET: > /* set device id of hpet */ > - if ( hpet_sbdf.iommu ) > + if ( hpet_sbdf.iommu || > + (hpet_sbdf.cmdline && hpet_sbdf.id != special->handle) ) > { > printk(XENLOG_WARNING "Only one IVHD HPET entry is supported\n"); > break; > } > hpet_sbdf.id = special->handle; > - hpet_sbdf.bdf = bdf; > - hpet_sbdf.seg = seg; > + if ( !hpet_sbdf.cmdline ) > + { > + hpet_sbdf.bdf = bdf; > + hpet_sbdf.seg = seg; > + } > hpet_sbdf.iommu = iommu; > break; > default: > @@ -935,21 +993,23 @@ static int __init parse_ivrs_table(struc > ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx ) > continue; > > - printk(XENLOG_ERR "IVHD Error: no information for IO-APIC %#x\n", > - IO_APIC_ID(apic)); > - if ( amd_iommu_perdev_intremap ) > - error = -ENXIO; > - else > + if ( !test_bit(IO_APIC_ID(apic), ioapic_cmdline) ) > { > - ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx = xmalloc_array( > - u16, nr_ioapic_entries[apic]); > - if ( !ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx ) > - { > - printk(XENLOG_ERR "IVHD Error: Out of memory\n"); > - error = -ENOMEM; > - } > + printk(XENLOG_ERR "IVHD Error: no information for IO-APIC %#x\n", > + IO_APIC_ID(apic)); > + if ( amd_iommu_perdev_intremap ) > + return -ENXIO; > + } > + > + ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx = xmalloc_array( > + u16, nr_ioapic_entries[apic]); > + if ( ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx ) > memset(ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx, -1, > nr_ioapic_entries[apic] * > sizeof(*ioapic_sbdf->pin_2_idx)); > + else > + { > + printk(XENLOG_ERR "IVHD Error: Out of memory\n"); > + error = -ENOMEM; > } > } > > --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h > +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h > @@ -108,6 +108,7 @@ extern struct ioapic_sbdf { > > extern struct hpet_sbdf { > u16 bdf, seg, id; > + bool_t cmdline; > struct amd_iommu *iommu; > } hpet_sbdf; > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |