From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33022) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aQMmN-00028Y-7B for qemu-devel@nongnu.org; Mon, 01 Feb 2016 17:17:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aQMmI-0003Mn-SS for qemu-devel@nongnu.org; Mon, 01 Feb 2016 17:17:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52842) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aQMmI-0003MM-ER for qemu-devel@nongnu.org; Mon, 01 Feb 2016 17:16:58 -0500 Message-ID: <1454365016.10542.12.camel@redhat.com> From: Alex Williamson Date: Mon, 01 Feb 2016 15:16:56 -0700 In-Reply-To: <1454330962.10168.34.camel@redhat.com> References: <1451994098-6972-1-git-send-email-kraxel@redhat.com> <1454009759.7183.7.camel@redhat.com> <1454051359.28516.28.camel@redhat.com> <1454090373.23148.11.camel@redhat.com> <1454330962.10168.34.camel@redhat.com> Content-Type: text/plain; charset="UTF-8" Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [vfio-users] [PATCH v3 00/11] igd passthrough chipset tweaks List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Gerd Hoffmann Cc: igvt-g@ml01.01.org, xen-devel@lists.xensource.com, Eduardo Habkost , Stefano Stabellini , qemu-devel@nongnu.org, Cao jin , vfio-users@redhat.com On Mon, 2016-02-01 at 13:49 +0100, Gerd Hoffmann wrote: > > > Maybe we should define the interface as "guest writes 0xfc to pick > > > address, qemu takes care to place opregion there".=C2=A0=C2=A0That = gives us the > > > freedom to change the qemu implementation (either copy host opregio= n or > > > map the host opregion) without breaking things. > >=C2=A0 > > Ok, so seabios allocates two pages, writes the base address of those > > pages to 0xfc and looks to see whether the signature appears at that > > address due to qemu mapping.=C2=A0=C2=A0It verifies the size and does= a > > free/realloc if not the right size. >=C2=A0 > I think seabios first needs to reserve something big enough for a > temporary mapping, to check signature + size, otherwise the opregion > might scratch data structures beyond opregion in case it happens to be > larger than 8k. >=C2=A0 > How likely is it that the opregion size ever changes?=C2=A0=C2=A0Should= we better > be prepared to handle it?=C2=A0=C2=A0Or would it be ok to have a ... >=C2=A0 > =C2=A0=C2=A0=C2=A0if (opregion_size > 8k) > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0panic(); >=C2=A0 > ... style sanity check? >=C2=A0 The patch below is what I'm working with now, it assumes that the opregion is 8K, maps, verifies, and re-allocs if it's a different size. Maybe it is safer to abort if it is over 8K, but we're not actually clobbering anything with the mapping, we're just temporarily mapping over it.=C2=A0=C2=A0So if there's not another thread of execution that co= uld be accessing something there and we're not stepping on our own stack or data, it doesn't seem like there's a problem. diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index c31c2fa..4f3251e 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -257,6 +257,52 @@ static void ich9_smbus_setup(struct pci_device *dev,= void * =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0pci_config_writeb(bdf, ICH9_SMB_HOSTC, ICH9= _SMB_HOSTC_HST_EN); =C2=A0} =C2=A0 +static void intel_igd_opregion_setup(struct pci_device *dev, void *arg) +{ +=C2=A0=C2=A0=C2=A0=C2=A0u16 bdf =3D dev->bdf; +=C2=A0=C2=A0=C2=A0=C2=A0u32 orig; +=C2=A0=C2=A0=C2=A0=C2=A0void *opregion; +=C2=A0=C2=A0=C2=A0=C2=A0int size =3D 8; + +=C2=A0=C2=A0=C2=A0=C2=A0if (!CONFIG_QEMU) +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return; + +=C2=A0=C2=A0=C2=A0=C2=A0orig =3D pci_config_readl(bdf, 0xFC); + +realloc: +=C2=A0=C2=A0=C2=A0=C2=A0opregion =3D malloc_high(size * 1024); +=C2=A0=C2=A0=C2=A0=C2=A0if (!opregion) { +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0warn_noalloc(); +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return; +=C2=A0=C2=A0=C2=A0=C2=A0} + +=C2=A0=C2=A0=C2=A0=C2=A0/* +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0* QEMU maps the OpRegion into system memor= y at the address written here, +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0* this overlaps our malloc, which marks th= e range e820 reserved. +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*/ +=C2=A0=C2=A0=C2=A0=C2=A0pci_config_writel(bdf, 0xFC, cpu_to_le32((u32)op= region)); + +=C2=A0=C2=A0=C2=A0=C2=A0if (memcmp(opregion, "IntelGraphicsMem", 16)) { +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0pci_config_writel(bdf, 0= xFC, orig); +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0free(opregion); +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return; /* the opregion = didn't magically appear, not supported */ +=C2=A0=C2=A0=C2=A0=C2=A0} + +=C2=A0=C2=A0=C2=A0=C2=A0if (size =3D=3D le32_to_cpu(*(u32 *)(opregion + = 16))) { +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dprintf(1, "Intel IGD Op= Region enabled on %02x:%02x.%x\n", +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf= _to_fn(bdf)); +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return; /* success! */ +=C2=A0=C2=A0=C2=A0=C2=A0} + +=C2=A0=C2=A0=C2=A0=C2=A0pci_config_writel(bdf, 0xFC, orig); +=C2=A0=C2=A0=C2=A0=C2=A0free(opregion); + +=C2=A0=C2=A0=C2=A0=C2=A0if (size =3D=3D 8) { /* try once more with a new= size */ +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0size =3D le32_to_cpu(*(u= 32 *)(opregion + 16)); +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0goto realloc; +=C2=A0=C2=A0=C2=A0=C2=A0} +} + =C2=A0static const struct pci_device_id pci_device_tbl[] =3D { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0/* PIIX3/PIIX4 PCI to ISA bridge */ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_= ID_INTEL_82371SB_0, @@ -290,6 +336,10 @@ static const struct pci_device_id pci_device_tbl[] =3D= { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x001= 7, 0xff00, apple_macio_setup), =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x002= 2, 0xff00, apple_macio_setup), =C2=A0 +=C2=A0=C2=A0=C2=A0=C2=A0/* Intel IGD OpRegion setup */ +=C2=A0=C2=A0=C2=A0=C2=A0PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_ANY_ID= , PCI_CLASS_DISPLAY_VGA, +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0intel_igd_opregion_= setup), + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0PCI_DEVICE_END, =C2=A0}; =C2=A0 > > If the graphics signature does not > > appear, free those pages and assume no opregion support. >=C2=A0 > Yes. >=C2=A0 > > If we later > > decide to use a copy, we'd need to disable the 0xfc automagic mapping > > and probably pass the data via fw_cfg.=C2=A0=C2=A0Sound right? >=C2=A0 > I'd have qemu copy the data on 0xfc write then, so things continue to > work without updating seabios.=C2=A0=C2=A0So, the firmware has to alloc= ate space, > reserve it etc.,=C2=A0=C2=A0and programming the 0xfc register.=C2=A0=C2= =A0Qemu has to make > sure the opregion appears at the address written by the firmware, by > whatever method it prefers. Ah, so here is where we'd clobber data in firmware.=C2=A0=C2=A0I currentl= y do this in vfio's pci config write in QEMU: =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0orig =3D pci_get_long(pde= v->config + IGD_OPREGION); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0pci_default_write_config(= pdev, addr, val, len); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0cur =3D pci_get_long(pdev= ->config + IGD_OPREGION); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (cur !=3D orig) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0i= f (orig) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0memory_region_del_subregion(get_system_memory(), =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0vdev->igd_opregion->mem); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0} =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0i= f (cur) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0memory_region_add_subregion(get_system_memory(), =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0cur, vdev->igd_opregion->mem); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0} =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0} This means that fw can write 0x0 back to the ASL storage register and the mapping goes away, no firmware data is overwritten and the overlap was temporary.=C2=A0=C2=A0If we copy it into the firmware provided buffer= with firmware not knowing the actual size then yes, we've just clobbered something and it can't be recovered.=C2=A0=C2=A0I'll post my patches and = we can hash out whether there's a better approach over something a little more concrete.=C2=A0=C2=A0I can see the opregion gets exposed and the guest dr= iver does use it.=C2=A0=C2=A0I'm not entirely sure what functionality it's adding t= hough since a cursory test of booting an FC23 live iso image seems to initialize the display correctly with or without the opregion. > > > lpc bridge is no problem, only pci id fields are copied over and > > > unprivileged access is allowed for them. > > >=C2=A0 > > > Copying the gfx registers of the host bridge is a problem indeed. > >=C2=A0 > > I would argue that both are really a problem, libvirt wants to put QE= MU > > in a container that prevents access to any host system files other th= an > > those explicitly allowed.=C2=A0=C2=A0Therefore libvirt needs to grant= the process > > access to the lpc sysfs config file even though it only needs user > > visible register values. >=C2=A0 > Yes, correct.=C2=A0=C2=A0We want svirt be as strict as possible. So it might be a good idea to expose these through vfio.=C2=A0=C2=A0What = about stolen memory?=C2=A0=C2=A0I noted the IOMMU faults that I get when assign= ing IGD, the bulk of it seems to be to the memory reserved as stolen for the GPU. I can avoid those by clearing the guest view of the BDSM register, but I think then we're just leaving stolen memory unused, which seems rather wasteful.=C2=A0=C2=A0Trying to identity map that stolen memory into the V= M so that we don't need to reconfigure the GPU seems problematic, but if vfio exposed it as another region, we could do the same trick of mapping into the VM address space.=C2=A0=C2=A0The size of stolen memory is quite varia= ble, so we couldn't just assume a size.=C2=A0=C2=A0We'd also need to know how to reconfigure (and restore) the GPU for a new location, the BDSM register just reports it.=C2=A0=C2=A0Thanks, Alex From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alex Williamson Subject: Re: [PATCH v3 00/11] igd passthrough chipset tweaks Date: Mon, 01 Feb 2016 15:16:56 -0700 Message-ID: <1454365016.10542.12.camel@redhat.com> References: <1451994098-6972-1-git-send-email-kraxel@redhat.com> <1454009759.7183.7.camel@redhat.com> <1454051359.28516.28.camel@redhat.com> <1454090373.23148.11.camel@redhat.com> <1454330962.10168.34.camel@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1454330962.10168.34.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: vfio-users-bounces-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org Errors-To: vfio-users-bounces-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org To: Gerd Hoffmann Cc: igvt-g-y27Ovi1pjclAfugRpC6u6w@public.gmane.org, xen-devel-GuqFBffKawuULHF6PoxzQEEOCMrvLtNR@public.gmane.org, Eduardo Habkost , Stefano Stabellini , qemu-devel-qX2TKyscuCcdnm+yROfE0A@public.gmane.org, Cao jin , vfio-users-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org List-Id: xen-devel@lists.xenproject.org T24gTW9uLCAyMDE2LTAyLTAxIGF0IDEzOjQ5ICswMTAwLCBHZXJkIEhvZmZtYW5uIHdyb3RlOgo+ ID4gPiBNYXliZSB3ZSBzaG91bGQgZGVmaW5lIHRoZSBpbnRlcmZhY2UgYXMgImd1ZXN0IHdyaXRl cyAweGZjIHRvIHBpY2sKPiA+ID4gYWRkcmVzcywgcWVtdSB0YWtlcyBjYXJlIHRvIHBsYWNlIG9w cmVnaW9uIHRoZXJlIi7CoMKgVGhhdCBnaXZlcyB1cyB0aGUKPiA+ID4gZnJlZWRvbSB0byBjaGFu Z2UgdGhlIHFlbXUgaW1wbGVtZW50YXRpb24gKGVpdGhlciBjb3B5IGhvc3Qgb3ByZWdpb24gb3IK PiA+ID4gbWFwIHRoZSBob3N0IG9wcmVnaW9uKSB3aXRob3V0IGJyZWFraW5nIHRoaW5ncy4KPiA+ wqAKPiA+IE9rLCBzbyBzZWFiaW9zIGFsbG9jYXRlcyB0d28gcGFnZXMsIHdyaXRlcyB0aGUgYmFz ZSBhZGRyZXNzIG9mIHRob3NlCj4gPiBwYWdlcyB0byAweGZjIGFuZCBsb29rcyB0byBzZWUgd2hl dGhlciB0aGUgc2lnbmF0dXJlIGFwcGVhcnMgYXQgdGhhdAo+ID4gYWRkcmVzcyBkdWUgdG8gcWVt dSBtYXBwaW5nLsKgwqBJdCB2ZXJpZmllcyB0aGUgc2l6ZSBhbmQgZG9lcyBhCj4gPiBmcmVlL3Jl YWxsb2MgaWYgbm90IHRoZSByaWdodCBzaXplLgo+wqAKPiBJIHRoaW5rIHNlYWJpb3MgZmlyc3Qg bmVlZHMgdG8gcmVzZXJ2ZSBzb21ldGhpbmcgYmlnIGVub3VnaCBmb3IgYQo+IHRlbXBvcmFyeSBt YXBwaW5nLCB0byBjaGVjayBzaWduYXR1cmUgKyBzaXplLCBvdGhlcndpc2UgdGhlIG9wcmVnaW9u Cj4gbWlnaHQgc2NyYXRjaCBkYXRhIHN0cnVjdHVyZXMgYmV5b25kIG9wcmVnaW9uIGluIGNhc2Ug aXQgaGFwcGVucyB0byBiZQo+IGxhcmdlciB0aGFuIDhrLgo+wqAKPiBIb3cgbGlrZWx5IGlzIGl0 IHRoYXQgdGhlIG9wcmVnaW9uIHNpemUgZXZlciBjaGFuZ2VzP8KgwqBTaG91bGQgd2UgYmV0dGVy Cj4gYmUgcHJlcGFyZWQgdG8gaGFuZGxlIGl0P8KgwqBPciB3b3VsZCBpdCBiZSBvayB0byBoYXZl IGEgLi4uCj7CoAo+IMKgwqDCoGlmIChvcHJlZ2lvbl9zaXplID4gOGspCj4gwqDCoMKgwqDCoMKg cGFuaWMoKTsKPsKgCj4gLi4uIHN0eWxlIHNhbml0eSBjaGVjaz8KPsKgCgpUaGUgcGF0Y2ggYmVs b3cgaXMgd2hhdCBJJ20gd29ya2luZyB3aXRoIG5vdywgaXQgYXNzdW1lcyB0aGF0IHRoZQpvcHJl Z2lvbiBpcyA4SywgbWFwcywgdmVyaWZpZXMsIGFuZCByZS1hbGxvY3MgaWYgaXQncyBhIGRpZmZl cmVudCBzaXplLgpNYXliZSBpdCBpcyBzYWZlciB0byBhYm9ydCBpZiBpdCBpcyBvdmVyIDhLLCBi dXQgd2UncmUgbm90IGFjdHVhbGx5CmNsb2JiZXJpbmcgYW55dGhpbmcgd2l0aCB0aGUgbWFwcGlu Zywgd2UncmUganVzdCB0ZW1wb3JhcmlseSBtYXBwaW5nCm92ZXIgaXQuwqDCoFNvIGlmIHRoZXJl J3Mgbm90IGFub3RoZXIgdGhyZWFkIG9mIGV4ZWN1dGlvbiB0aGF0IGNvdWxkIGJlCmFjY2Vzc2lu ZyBzb21ldGhpbmcgdGhlcmUgYW5kIHdlJ3JlIG5vdCBzdGVwcGluZyBvbiBvdXIgb3duIHN0YWNr IG9yCmRhdGEsIGl0IGRvZXNuJ3Qgc2VlbSBsaWtlIHRoZXJlJ3MgYSBwcm9ibGVtLgoKZGlmZiAt LWdpdCBhL3NyYy9mdy9wY2lpbml0LmMgYi9zcmMvZncvcGNpaW5pdC5jCmluZGV4IGMzMWMyZmEu LjRmMzI1MWUgMTAwNjQ0Ci0tLSBhL3NyYy9mdy9wY2lpbml0LmMKKysrIGIvc3JjL2Z3L3BjaWlu aXQuYwpAQCAtMjU3LDYgKzI1Nyw1MiBAQCBzdGF0aWMgdm9pZCBpY2g5X3NtYnVzX3NldHVwKHN0 cnVjdCBwY2lfZGV2aWNlICpkZXYsIHZvaWQgKgrCoMKgwqDCoMKgcGNpX2NvbmZpZ193cml0ZWIo YmRmLCBJQ0g5X1NNQl9IT1NUQywgSUNIOV9TTUJfSE9TVENfSFNUX0VOKTsKwqB9CsKgCitzdGF0 aWMgdm9pZCBpbnRlbF9pZ2Rfb3ByZWdpb25fc2V0dXAoc3RydWN0IHBjaV9kZXZpY2UgKmRldiwg dm9pZCAqYXJnKQoreworwqDCoMKgwqB1MTYgYmRmID0gZGV2LT5iZGY7CivCoMKgwqDCoHUzMiBv cmlnOworwqDCoMKgwqB2b2lkICpvcHJlZ2lvbjsKK8KgwqDCoMKgaW50IHNpemUgPSA4OworCivC oMKgwqDCoGlmICghQ09ORklHX1FFTVUpCivCoMKgwqDCoMKgwqDCoMKgcmV0dXJuOworCivCoMKg wqDCoG9yaWcgPSBwY2lfY29uZmlnX3JlYWRsKGJkZiwgMHhGQyk7CisKK3JlYWxsb2M6CivCoMKg wqDCoG9wcmVnaW9uID0gbWFsbG9jX2hpZ2goc2l6ZSAqIDEwMjQpOworwqDCoMKgwqBpZiAoIW9w cmVnaW9uKSB7CivCoMKgwqDCoMKgwqDCoMKgd2Fybl9ub2FsbG9jKCk7CivCoMKgwqDCoMKgwqDC oMKgcmV0dXJuOworwqDCoMKgwqB9CisKK8KgwqDCoMKgLyoKK8KgwqDCoMKgwqAqIFFFTVUgbWFw cyB0aGUgT3BSZWdpb24gaW50byBzeXN0ZW0gbWVtb3J5IGF0IHRoZSBhZGRyZXNzIHdyaXR0ZW4g aGVyZSwKK8KgwqDCoMKgwqAqIHRoaXMgb3ZlcmxhcHMgb3VyIG1hbGxvYywgd2hpY2ggbWFya3Mg dGhlIHJhbmdlIGU4MjAgcmVzZXJ2ZWQuCivCoMKgwqDCoMKgKi8KK8KgwqDCoMKgcGNpX2NvbmZp Z193cml0ZWwoYmRmLCAweEZDLCBjcHVfdG9fbGUzMigodTMyKW9wcmVnaW9uKSk7CisKK8KgwqDC oMKgaWYgKG1lbWNtcChvcHJlZ2lvbiwgIkludGVsR3JhcGhpY3NNZW0iLCAxNikpIHsKK8KgwqDC oMKgwqDCoMKgwqBwY2lfY29uZmlnX3dyaXRlbChiZGYsIDB4RkMsIG9yaWcpOworwqDCoMKgwqDC oMKgwqDCoGZyZWUob3ByZWdpb24pOworwqDCoMKgwqDCoMKgwqDCoHJldHVybjsgLyogdGhlIG9w cmVnaW9uIGRpZG4ndCBtYWdpY2FsbHkgYXBwZWFyLCBub3Qgc3VwcG9ydGVkICovCivCoMKgwqDC oH0KKworwqDCoMKgwqBpZiAoc2l6ZSA9PSBsZTMyX3RvX2NwdSgqKHUzMiAqKShvcHJlZ2lvbiAr IDE2KSkpIHsKK8KgwqDCoMKgwqDCoMKgwqBkcHJpbnRmKDEsICJJbnRlbCBJR0QgT3BSZWdpb24g ZW5hYmxlZCBvbiAlMDJ4OiUwMnguJXhcbiIsCivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoHBjaV9iZGZfdG9fYnVzKGJkZiksIHBjaV9iZGZfdG9fZGV2KGJkZiksIHBjaV9iZGZfdG9f Zm4oYmRmKSk7CivCoMKgwqDCoMKgwqDCoMKgcmV0dXJuOyAvKiBzdWNjZXNzISAqLworwqDCoMKg wqB9CisKK8KgwqDCoMKgcGNpX2NvbmZpZ193cml0ZWwoYmRmLCAweEZDLCBvcmlnKTsKK8KgwqDC oMKgZnJlZShvcHJlZ2lvbik7CisKK8KgwqDCoMKgaWYgKHNpemUgPT0gOCkgeyAvKiB0cnkgb25j ZSBtb3JlIHdpdGggYSBuZXcgc2l6ZSAqLworwqDCoMKgwqDCoMKgwqDCoHNpemUgPSBsZTMyX3Rv X2NwdSgqKHUzMiAqKShvcHJlZ2lvbiArIDE2KSk7CivCoMKgwqDCoMKgwqDCoMKgZ290byByZWFs bG9jOworwqDCoMKgwqB9Cit9CisKwqBzdGF0aWMgY29uc3Qgc3RydWN0IHBjaV9kZXZpY2VfaWQg cGNpX2RldmljZV90YmxbXSA9IHsKwqDCoMKgwqDCoC8qIFBJSVgzL1BJSVg0IFBDSSB0byBJU0Eg YnJpZGdlICovCsKgwqDCoMKgwqBQQ0lfREVWSUNFKFBDSV9WRU5ET1JfSURfSU5URUwsIFBDSV9E RVZJQ0VfSURfSU5URUxfODIzNzFTQl8wLApAQCAtMjkwLDYgKzMzNiwxMCBAQCBzdGF0aWMgY29u c3Qgc3RydWN0IHBjaV9kZXZpY2VfaWQgcGNpX2RldmljZV90YmxbXSA9IHsKwqDCoMKgwqDCoFBD SV9ERVZJQ0VfQ0xBU1MoUENJX1ZFTkRPUl9JRF9BUFBMRSwgMHgwMDE3LCAweGZmMDAsIGFwcGxl X21hY2lvX3NldHVwKSwKwqDCoMKgwqDCoFBDSV9ERVZJQ0VfQ0xBU1MoUENJX1ZFTkRPUl9JRF9B UFBMRSwgMHgwMDIyLCAweGZmMDAsIGFwcGxlX21hY2lvX3NldHVwKSwKwqAKK8KgwqDCoMKgLyog SW50ZWwgSUdEIE9wUmVnaW9uIHNldHVwICovCivCoMKgwqDCoFBDSV9ERVZJQ0VfQ0xBU1MoUENJ X1ZFTkRPUl9JRF9JTlRFTCwgUENJX0FOWV9JRCwgUENJX0NMQVNTX0RJU1BMQVlfVkdBLAorwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgaW50ZWxfaWdkX29wcmVnaW9u X3NldHVwKSwKKwrCoMKgwqDCoMKgUENJX0RFVklDRV9FTkQsCsKgfTsKwqAKCj4gPiBJZiB0aGUg Z3JhcGhpY3Mgc2lnbmF0dXJlIGRvZXMgbm90Cj4gPiBhcHBlYXIsIGZyZWUgdGhvc2UgcGFnZXMg YW5kIGFzc3VtZSBubyBvcHJlZ2lvbiBzdXBwb3J0Lgo+wqAKPiBZZXMuCj7CoAo+ID4gSWYgd2Ug bGF0ZXIKPiA+IGRlY2lkZSB0byB1c2UgYSBjb3B5LCB3ZSdkIG5lZWQgdG8gZGlzYWJsZSB0aGUg MHhmYyBhdXRvbWFnaWMgbWFwcGluZwo+ID4gYW5kIHByb2JhYmx5IHBhc3MgdGhlIGRhdGEgdmlh IGZ3X2NmZy7CoMKgU291bmQgcmlnaHQ/Cj7CoAo+IEknZCBoYXZlIHFlbXUgY29weSB0aGUgZGF0 YSBvbiAweGZjIHdyaXRlIHRoZW4sIHNvIHRoaW5ncyBjb250aW51ZSB0bwo+IHdvcmsgd2l0aG91 dCB1cGRhdGluZyBzZWFiaW9zLsKgwqBTbywgdGhlIGZpcm13YXJlIGhhcyB0byBhbGxvY2F0ZSBz cGFjZSwKPiByZXNlcnZlIGl0IGV0Yy4swqDCoGFuZCBwcm9ncmFtbWluZyB0aGUgMHhmYyByZWdp c3Rlci7CoMKgUWVtdSBoYXMgdG8gbWFrZQo+IHN1cmUgdGhlIG9wcmVnaW9uIGFwcGVhcnMgYXQg dGhlIGFkZHJlc3Mgd3JpdHRlbiBieSB0aGUgZmlybXdhcmUsIGJ5Cj4gd2hhdGV2ZXIgbWV0aG9k IGl0IHByZWZlcnMuCgpBaCwgc28gaGVyZSBpcyB3aGVyZSB3ZSdkIGNsb2JiZXIgZGF0YSBpbiBm aXJtd2FyZS7CoMKgSSBjdXJyZW50bHkgZG8KdGhpcyBpbiB2ZmlvJ3MgcGNpIGNvbmZpZyB3cml0 ZSBpbiBRRU1VOgoKwqDCoMKgwqDCoMKgwqDCoG9yaWcgPSBwY2lfZ2V0X2xvbmcocGRldi0+Y29u ZmlnICsgSUdEX09QUkVHSU9OKTsKwqDCoMKgwqDCoMKgwqDCoHBjaV9kZWZhdWx0X3dyaXRlX2Nv bmZpZyhwZGV2LCBhZGRyLCB2YWwsIGxlbik7CsKgwqDCoMKgwqDCoMKgwqBjdXIgPSBwY2lfZ2V0 X2xvbmcocGRldi0+Y29uZmlnICsgSUdEX09QUkVHSU9OKTsKCsKgwqDCoMKgwqDCoMKgwqBpZiAo Y3VyICE9IG9yaWcpIHsKwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgaWYgKG9yaWcpIHsKwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBtZW1vcnlfcmVnaW9uX2RlbF9zdWJyZWdpb24oZ2V0 X3N5c3RlbV9tZW1vcnkoKSwKwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHZkZXYtPmln ZF9vcHJlZ2lvbi0+bWVtKTsKwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfQoKwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgaWYgKGN1cikgewrCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoG1l bW9yeV9yZWdpb25fYWRkX3N1YnJlZ2lvbihnZXRfc3lzdGVtX21lbW9yeSgpLArCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgY3VyLCB2ZGV2LT5pZ2Rfb3ByZWdpb24tPm1lbSk7CsKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoH0KwqDCoMKgwqDCoMKgwqDCoH0KClRoaXMgbWVhbnMgdGhhdCBm dyBjYW4gd3JpdGUgMHgwIGJhY2sgdG8gdGhlIEFTTCBzdG9yYWdlIHJlZ2lzdGVyIGFuZAp0aGUg bWFwcGluZyBnb2VzIGF3YXksIG5vIGZpcm13YXJlIGRhdGEgaXMgb3ZlcndyaXR0ZW4gYW5kIHRo ZSBvdmVybGFwCndhcyB0ZW1wb3JhcnkuwqDCoElmIHdlIGNvcHkgaXQgaW50byB0aGUgZmlybXdh cmUgcHJvdmlkZWQgYnVmZmVyIHdpdGgKZmlybXdhcmUgbm90IGtub3dpbmcgdGhlIGFjdHVhbCBz aXplIHRoZW4geWVzLCB3ZSd2ZSBqdXN0IGNsb2JiZXJlZApzb21ldGhpbmcgYW5kIGl0IGNhbid0 IGJlIHJlY292ZXJlZC7CoMKgSSdsbCBwb3N0IG15IHBhdGNoZXMgYW5kIHdlIGNhbgpoYXNoIG91 dCB3aGV0aGVyIHRoZXJlJ3MgYSBiZXR0ZXIgYXBwcm9hY2ggb3ZlciBzb21ldGhpbmcgYSBsaXR0 bGUgbW9yZQpjb25jcmV0ZS7CoMKgSSBjYW4gc2VlIHRoZSBvcHJlZ2lvbiBnZXRzIGV4cG9zZWQg YW5kIHRoZSBndWVzdCBkcml2ZXIgZG9lcwp1c2UgaXQuwqDCoEknbSBub3QgZW50aXJlbHkgc3Vy ZSB3aGF0IGZ1bmN0aW9uYWxpdHkgaXQncyBhZGRpbmcgdGhvdWdoCnNpbmNlIGEgY3Vyc29yeSB0 ZXN0IG9mIGJvb3RpbmcgYW4gRkMyMyBsaXZlIGlzbyBpbWFnZSBzZWVtcyB0bwppbml0aWFsaXpl IHRoZSBkaXNwbGF5IGNvcnJlY3RseSB3aXRoIG9yIHdpdGhvdXQgdGhlIG9wcmVnaW9uLgoKPiA+ ID4gbHBjIGJyaWRnZSBpcyBubyBwcm9ibGVtLCBvbmx5IHBjaSBpZCBmaWVsZHMgYXJlIGNvcGll ZCBvdmVyIGFuZAo+ID4gPiB1bnByaXZpbGVnZWQgYWNjZXNzIGlzIGFsbG93ZWQgZm9yIHRoZW0u Cj4gPiA+wqAKPiA+ID4gQ29weWluZyB0aGUgZ2Z4IHJlZ2lzdGVycyBvZiB0aGUgaG9zdCBicmlk Z2UgaXMgYSBwcm9ibGVtIGluZGVlZC4KPiA+wqAKPiA+IEkgd291bGQgYXJndWUgdGhhdCBib3Ro IGFyZSByZWFsbHkgYSBwcm9ibGVtLCBsaWJ2aXJ0IHdhbnRzIHRvIHB1dCBRRU1VCj4gPiBpbiBh IGNvbnRhaW5lciB0aGF0IHByZXZlbnRzIGFjY2VzcyB0byBhbnkgaG9zdCBzeXN0ZW0gZmlsZXMg b3RoZXIgdGhhbgo+ID4gdGhvc2UgZXhwbGljaXRseSBhbGxvd2VkLsKgwqBUaGVyZWZvcmUgbGli dmlydCBuZWVkcyB0byBncmFudCB0aGUgcHJvY2Vzcwo+ID4gYWNjZXNzIHRvIHRoZSBscGMgc3lz ZnMgY29uZmlnIGZpbGUgZXZlbiB0aG91Z2ggaXQgb25seSBuZWVkcyB1c2VyCj4gPiB2aXNpYmxl IHJlZ2lzdGVyIHZhbHVlcy4KPsKgCj4gWWVzLCBjb3JyZWN0LsKgwqBXZSB3YW50IHN2aXJ0IGJl IGFzIHN0cmljdCBhcyBwb3NzaWJsZS4KClNvIGl0IG1pZ2h0IGJlIGEgZ29vZCBpZGVhIHRvIGV4 cG9zZSB0aGVzZSB0aHJvdWdoIHZmaW8uwqDCoFdoYXQgYWJvdXQKc3RvbGVuIG1lbW9yeT/CoMKg SSBub3RlZCB0aGUgSU9NTVUgZmF1bHRzIHRoYXQgSSBnZXQgd2hlbiBhc3NpZ25pbmcgSUdELAp0 aGUgYnVsayBvZiBpdCBzZWVtcyB0byBiZSB0byB0aGUgbWVtb3J5IHJlc2VydmVkIGFzIHN0b2xl biBmb3IgdGhlIEdQVS4KSSBjYW4gYXZvaWQgdGhvc2UgYnkgY2xlYXJpbmcgdGhlIGd1ZXN0IHZp ZXcgb2YgdGhlIEJEU00gcmVnaXN0ZXIsIGJ1dCBJCnRoaW5rIHRoZW4gd2UncmUganVzdCBsZWF2 aW5nIHN0b2xlbiBtZW1vcnkgdW51c2VkLCB3aGljaCBzZWVtcyByYXRoZXIKd2FzdGVmdWwuwqDC oFRyeWluZyB0byBpZGVudGl0eSBtYXAgdGhhdCBzdG9sZW4gbWVtb3J5IGludG8gdGhlIFZNIHNv IHRoYXQKd2UgZG9uJ3QgbmVlZCB0byByZWNvbmZpZ3VyZSB0aGUgR1BVIHNlZW1zIHByb2JsZW1h dGljLCBidXQgaWYgdmZpbwpleHBvc2VkIGl0IGFzIGFub3RoZXIgcmVnaW9uLCB3ZSBjb3VsZCBk byB0aGUgc2FtZSB0cmljayBvZiBtYXBwaW5nIGludG8KdGhlIFZNIGFkZHJlc3Mgc3BhY2UuwqDC oFRoZSBzaXplIG9mIHN0b2xlbiBtZW1vcnkgaXMgcXVpdGUgdmFyaWFibGUsIHNvCndlIGNvdWxk bid0IGp1c3QgYXNzdW1lIGEgc2l6ZS7CoMKgV2UnZCBhbHNvIG5lZWQgdG8ga25vdyBob3cgdG8K cmVjb25maWd1cmUgKGFuZCByZXN0b3JlKSB0aGUgR1BVIGZvciBhIG5ldyBsb2NhdGlvbiwgdGhl IEJEU00gcmVnaXN0ZXIKanVzdCByZXBvcnRzIGl0LsKgwqBUaGFua3MsCgpBbGV4CgpfX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwp2ZmlvLXVzZXJzIG1haWxp bmcgbGlzdAp2ZmlvLXVzZXJzQHJlZGhhdC5jb20KaHR0cHM6Ly93d3cucmVkaGF0LmNvbS9tYWls bWFuL2xpc3RpbmZvL3ZmaW8tdXNlcnMK