[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, 11:52:36 AM, you wrote: > 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... Hrrrmm could it be due to the fact that in my case it actually shouldn't override a present IVRS entry, but add a extra one ? > -- > 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 |