From mboxrd@z Thu Jan 1 00:00:00 1970 From: miquel.raynal@bootlin.com (Miquel Raynal) Date: Mon, 24 Sep 2018 18:01:33 +0200 Subject: [PATCH v5 07/14] irqchip/irq-mvebu-sei: add new driver for Marvell SEI In-Reply-To: <86pnx7x5pz.wl-marc.zyngier@arm.com> References: <20180830073535.10710-1-miquel.raynal@bootlin.com> <20180830073535.10710-8-miquel.raynal@bootlin.com> <86pnx7x5pz.wl-marc.zyngier@arm.com> Message-ID: <20180924180133.2ea93762@xps13> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Marc, > > + > > +static int mvebu_sei_cp_domain_alloc(struct mvebu_sei *sei) > > +{ > > + int hwirq; > > + > > + mutex_lock(&sei->cp_msi_lock); > > + hwirq = find_first_zero_bit(sei->cp_msi_bitmap, > > + sei->caps->cp_range.size); > > + set_bit(hwirq, sei->cp_msi_bitmap); > > + mutex_unlock(&sei->cp_msi_lock); > > + > > + return hwirq; > > +} > > + > > +static void mvebu_sei_cp_domain_free(struct mvebu_sei *sei, int hwirq) > > +{ > > + mutex_lock(&sei->cp_msi_lock); > > + clear_bit(hwirq, sei->cp_msi_bitmap); > > + mutex_unlock(&sei->cp_msi_lock); > > +} > > + > > +static int mvebu_sei_irq_domain_alloc(struct irq_domain *domain, > > + unsigned int virq, unsigned int nr_irqs, > > + void *args) > > +{ > > + struct mvebu_sei *sei = domain->host_data; > > + struct irq_fwspec *fwspec = args; > > + int hwirq; > > + int ret; > > + > > + /* The software only supports single allocations for now */ > > + if (nr_irqs != 1) > > + return -ENOTSUPP; > > + > > + hwirq = mvebu_sei_cp_domain_alloc(sei); > > + if (hwirq < 0) > > + return -ENOSPC; > > + > > + fwspec->fwnode = domain->parent->fwnode; > > + fwspec->param_count = 3; > > + fwspec->param[0] = GIC_SPI; > > + fwspec->param[1] = 0; > > On first approximation, this deserves a good comment about 0 > representing INTID 32 at the GIC level. Then, another question is why > this doesn't come from DT. I bet that in the future, this block will > be reused and you'll find more than one is a single chip. About the 0, sure, if we maintain this code, I should probably derive the value from DT. > > But the real question is why you are constantly calling > irq_alloc_irqs_parent. I remember commenting about this in my previous > round of review, and I still see this. I really tried to remove it but I clearly failed. When there is no irq_alloc_irqs_parent() call in mvebu_sei_irq_domain_alloc() it looks like something is missing and I get a oops at probe time. This is the oops: [ 3.112148] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000e8 [ 3.120970] Mem abort info: [ 3.123775] ESR = 0x96000004 [ 3.126842] Exception class = DABT (current EL), IL = 32 bits [ 3.132787] SET = 0, FnV = 0 [ 3.135853] EA = 0, S1PTW = 0 [ 3.139006] Data abort info: [ 3.141897] ISV = 0, ISS = 0x00000004 [ 3.145749] CM = 0, WnR = 0 [ 3.148728] [00000000000000e8] user address but active_mm is swapper [ 3.155110] Internal error: Oops: 96000004 [#1] PREEMPT SMP [ 3.160705] Modules linked in: [ 3.163777] CPU: 0 PID: 35 Comm: kworker/0:1 Not tainted 4.19.0-rc1-00024-g1ff609093efd-dirty #1931 [ 3.172861] Hardware name: Marvell Armada 7040 DB board (DT) [ 3.178556] Workqueue: events deferred_probe_work_func [ 3.183719] pstate: 60000085 (nZCv daIf -PAN -UAO) [ 3.188535] pc : irq_set_irqchip_state+0x160/0x1a0 [ 3.193348] lr : irq_set_irqchip_state+0x160/0x1a0 [ 3.198158] sp : ffff000009d037f0 [ 3.201486] x29: ffff000009d037f0 x28: ffff000008e49d20 [ 3.206824] x27: ffff000008e49cb0 x26: 0000000000000000 [ 3.212161] x25: 0000000000000000 x24: ffff000008ad2570 [ 3.217498] x23: ffff8000e8f80c00 x22: ffff0000093e9000 [ 3.222835] x21: 0000000000000033 x20: 0000000000000000 [ 3.228172] x19: ffff8000e8bdf300 x18: ffffffffffffffff [ 3.233509] x17: 0000000000000000 x16: 0000000000000000 [ 3.238846] x15: ffff0000093e96c8 x14: ffff0000895436bf [ 3.244182] x13: ffff0000095436cd x12: ffff0000094010c8 [ 3.249519] x11: ffff000009401000 x10: 0000000005f5e0ff [ 3.254856] x9 : ffff000009d034f0 x8 : 325b206574617473 [ 3.260192] x7 : 5f70696863717269 x6 : ffff0000085cd238 [ 3.265529] x5 : 0000000000000000 x4 : 0000000000000000 [ 3.270866] x3 : ffffffffffffffff x2 : 337acc4b0d752600 [ 3.276202] x1 : 0000000000000000 x0 : 000000000000001c [ 3.281540] Process kworker/0:1 (pid: 35, stack limit = 0x(____ptrval____)) [ 3.288530] Call trace: [ 3.290987] irq_set_irqchip_state+0x160/0x1a0 [ 3.295452] mvebu_icu_irq_domain_alloc+0x180/0x208 [ 3.300351] __irq_domain_alloc_irqs+0x138/0x2a0 [ 3.304988] irq_create_fwspec_mapping+0x140/0x328 [ 3.309799] irq_create_of_mapping+0x78/0xa0 [ 3.314089] of_irq_get+0x88/0xf8 [ 3.317419] platform_get_irq+0x24/0x178 [ 3.321360] armada_thermal_probe+0x110/0x668 [ 3.325735] platform_drv_probe+0x50/0xb0 [ 3.329763] really_probe+0x1fc/0x290 [ 3.333441] driver_probe_device+0x58/0x100 [ 3.337643] __device_attach_driver+0x9c/0xf8 [ 3.342019] bus_for_each_drv+0x70/0xc8 [ 3.345872] __device_attach+0xe0/0x140 [ 3.349725] device_initial_probe+0x10/0x18 [ 3.353926] bus_probe_device+0x94/0xa0 [ 3.357779] deferred_probe_work_func+0x6c/0xa0 [ 3.362331] process_one_work+0x1dc/0x330 [ 3.366359] worker_thread+0x23c/0x430 [ 3.370124] kthread+0xf8/0x128 [ 3.373280] ret_from_fork+0x10/0x18 [ 3.376872] Code: aa1803e1 aa1c03e0 528119a2 97fff760 (f9407680) [ 3.382992] ---[ end trace f423829cb4b1c06c ]--- The faulty instruction is the if statement there: https://elixir.bootlin.com/linux/v4.19-rc5/source/kernel/irq/manage.c#L2243 I added traces to understand what is going on. The do-while loop gets an irq_data structure, derives the chip pointer, then look at its ->set_irqchip_state() callback. It it does not exist, it tries with its parent irq_data. Here are the traces that show why the oops happens when irq_alloc_irqs_parent() is not called: With irq_alloc_irqs_parent() (running exactly what I sent in the series): [ 2.993887] irq_set_irqchip_state [2244] irq_data ptr: 0xffff8000e8f80c28 [ 3.000703] irq_set_irqchip_state [2246] chip ptr: 0xffff000009401538 (name: none) [ 3.008480] irq_set_irqchip_state [2249] parent irq_data ptr ? 0xffff8000e8bdf200 [ 3.024045] irq_set_irqchip_state [2244] irq_data ptr: 0xffff8000e8bdf200 [ 3.030861] irq_set_irqchip_state [2246] chip ptr: 0xffff00000941b658 (name: SEI MSI controller) [ 3.039857] irq_set_irqchip_state [2249] parent irq_data ptr ? 0xffff8000e8bdf280 [ 3.055420] irq_set_irqchip_state [2244] irq_data ptr: 0xffff8000e8bdf280 [ 3.062236] irq_set_irqchip_state [2246] chip ptr: 0xffff00000941b3e8 (name: CP SEI) [ 3.070185] irq_set_irqchip_state [2249] parent irq_data ptr ? 0xffff8000e8bdf300 [ 3.085750] irq_set_irqchip_state [2244] irq_data ptr: 0xffff8000e8bdf300 [ 3.092566] irq_set_irqchip_state [2246] chip ptr: 0x0000000000000000 (name: (null)) [ 3.100515] irq_set_irqchip_state [2249] parent irq_data ptr ? 0x0000000000000000 Without irq_alloc_irqs_parent() (same code base, with the call to this function commented out): [ 2.992364] irq_set_irqchip_state [2244] irq_data: 0xffff8000e7cb7228 [ 2.999181] irq_set_irqchip_state [2246] chip: 0xffff000009401538 (name: none) [ 3.006956] irq_set_irqchip_state [2249] parent irq_data: 0xffff8000e93a9e00 [ 3.022520] irq_set_irqchip_state [2244] irq_data: 0xffff8000e93a9e00 [ 3.029337] irq_set_irqchip_state [2246] chip: 0xffff00000941b658 (name: SEI MSI controller) [ 3.038333] irq_set_irqchip_state [2249] parent irq_data: 0xffff8000e93a9e80 [ 3.053896] irq_set_irqchip_state [2244] irq_data: 0xffff8000e93a9e80 [ 3.060713] irq_set_irqchip_state [2246] chip: 0xffff00000941b3e8 (name: CP SEI) [ 3.068662] irq_set_irqchip_state [2249] parent irq_data: 0xffff8000e93a9f00 [ 3.084225] irq_set_irqchip_state [2244] irq_data: 0xffff8000e93a9f00 [ 3.091041] irq_set_irqchip_state [2246] chip: 0xffff0000093ec148 (name: GICv2) [ 3.098903] irq_set_irqchip_state [2249] parent irq_data: 0x0000000000000000 The difference is that at this stage, the irq_data->chip pointer of the SEI controller _parent_ (ie. the GIC's chip pointer) is not valid. I digged a lot in this direction during your vacations to find out what I missed, and I ended up calling back irq_alloc_irqs_parent(). If you have an idea of how to handle this properly, I am all ears! > > The whole SEI thing is a chained interrupt controller, a > multiplexer. The output interrupt is known at probe time, and never > change. You also have code to that effect in the probe routine. So > what is this exactly? Dead code? > > > + /* > > + * Assume edge rising for now, it will be properly set when > > + * ->set_type() is called > > + */ > > + fwspec->param[2] = IRQ_TYPE_EDGE_RISING; > > + ret = irq_domain_alloc_irqs_parent(domain, virq, 1, fwspec); > > + if (ret) > > + goto free_irq; > > + [...] > > + > > +struct mvebu_sei_caps mvebu_sei_ap806_caps = { > > + .ap_range = { > > + .first = 0, > > + .size = 21, > > + }, > > + .cp_range = { > > + .first = 21, > > + .size = 43, > > + }, > > I'd appreciate some symbolic constants instead of magic numbers. I can definitely use symbolic constants but these numbers are already quite meaningful, the constants could be named: SEI_AP806_FIRST_INT_IN_AP_RANGE SEI_AP806_SIZE_OF_AP_RANGE > > > +}; > > + > > +static const struct of_device_id mvebu_sei_of_match[] = { > > + { > > + .compatible = "marvell,ap806-sei", > > + .data = &mvebu_sei_ap806_caps, > > + }, > > + {}, > > +}; > > + > > +static struct platform_driver mvebu_sei_driver = { > > + .probe = mvebu_sei_probe, > > + .driver = { > > + .name = "mvebu-sei", > > + .of_match_table = mvebu_sei_of_match, > > + }, > > +}; > > +builtin_platform_driver(mvebu_sei_driver); > > -- > > 2.17.1 > > > > Thanks, > > M. > Thanks, Miqu?l From mboxrd@z Thu Jan 1 00:00:00 1970 From: Miquel Raynal Subject: Re: [PATCH v5 07/14] irqchip/irq-mvebu-sei: add new driver for Marvell SEI Date: Mon, 24 Sep 2018 18:01:33 +0200 Message-ID: <20180924180133.2ea93762@xps13> References: <20180830073535.10710-1-miquel.raynal@bootlin.com> <20180830073535.10710-8-miquel.raynal@bootlin.com> <86pnx7x5pz.wl-marc.zyngier@arm.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <86pnx7x5pz.wl-marc.zyngier@arm.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: Marc Zyngier Cc: Mark Rutland , Andrew Lunn , Jason Cooper , devicetree@vger.kernel.org, Antoine Tenart , Catalin Marinas , Gregory Clement , Haim Boot , Will Deacon , Maxime Chevallier , Nadav Haklai , Rob Herring , Thomas Petazzoni , Thomas Gleixner , Hanna Hawa , linux-arm-kernel@lists.infradead.org, Sebastian Hesselbarth List-Id: devicetree@vger.kernel.org SGkgTWFyYywKCj4gPiArCj4gPiArc3RhdGljIGludCBtdmVidV9zZWlfY3BfZG9tYWluX2FsbG9j KHN0cnVjdCBtdmVidV9zZWkgKnNlaSkKPiA+ICt7Cj4gPiArCWludCBod2lycTsKPiA+ICsKPiA+ ICsJbXV0ZXhfbG9jaygmc2VpLT5jcF9tc2lfbG9jayk7Cj4gPiArCWh3aXJxID0gZmluZF9maXJz dF96ZXJvX2JpdChzZWktPmNwX21zaV9iaXRtYXAsCj4gPiArCQkJCSAgICBzZWktPmNhcHMtPmNw X3JhbmdlLnNpemUpOwo+ID4gKwlzZXRfYml0KGh3aXJxLCBzZWktPmNwX21zaV9iaXRtYXApOwo+ ID4gKwltdXRleF91bmxvY2soJnNlaS0+Y3BfbXNpX2xvY2spOwo+ID4gKwo+ID4gKwlyZXR1cm4g aHdpcnE7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyB2b2lkIG12ZWJ1X3NlaV9jcF9kb21haW5f ZnJlZShzdHJ1Y3QgbXZlYnVfc2VpICpzZWksIGludCBod2lycSkKPiA+ICt7Cj4gPiArCW11dGV4 X2xvY2soJnNlaS0+Y3BfbXNpX2xvY2spOwo+ID4gKwljbGVhcl9iaXQoaHdpcnEsIHNlaS0+Y3Bf bXNpX2JpdG1hcCk7Cj4gPiArCW11dGV4X3VubG9jaygmc2VpLT5jcF9tc2lfbG9jayk7Cj4gPiAr fQo+ID4gKwo+ID4gK3N0YXRpYyBpbnQgbXZlYnVfc2VpX2lycV9kb21haW5fYWxsb2Moc3RydWN0 IGlycV9kb21haW4gKmRvbWFpbiwKPiA+ICsJCQkJICAgICAgdW5zaWduZWQgaW50IHZpcnEsIHVu c2lnbmVkIGludCBucl9pcnFzLAo+ID4gKwkJCQkgICAgICB2b2lkICphcmdzKQo+ID4gK3sKPiA+ ICsJc3RydWN0IG12ZWJ1X3NlaSAqc2VpID0gZG9tYWluLT5ob3N0X2RhdGE7Cj4gPiArCXN0cnVj dCBpcnFfZndzcGVjICpmd3NwZWMgPSBhcmdzOwo+ID4gKwlpbnQgaHdpcnE7Cj4gPiArCWludCBy ZXQ7Cj4gPiArCj4gPiArCS8qIFRoZSBzb2Z0d2FyZSBvbmx5IHN1cHBvcnRzIHNpbmdsZSBhbGxv Y2F0aW9ucyBmb3Igbm93ICovCj4gPiArCWlmIChucl9pcnFzICE9IDEpCj4gPiArCQlyZXR1cm4g LUVOT1RTVVBQOwo+ID4gKwo+ID4gKwlod2lycSA9IG12ZWJ1X3NlaV9jcF9kb21haW5fYWxsb2Mo c2VpKTsKPiA+ICsJaWYgKGh3aXJxIDwgMCkKPiA+ICsJCXJldHVybiAtRU5PU1BDOwo+ID4gKwo+ ID4gKwlmd3NwZWMtPmZ3bm9kZSA9IGRvbWFpbi0+cGFyZW50LT5md25vZGU7Cj4gPiArCWZ3c3Bl Yy0+cGFyYW1fY291bnQgPSAzOwo+ID4gKwlmd3NwZWMtPnBhcmFtWzBdID0gR0lDX1NQSTsKPiA+ ICsJZndzcGVjLT5wYXJhbVsxXSA9IDA7ICAKPiAKPiBPbiBmaXJzdCBhcHByb3hpbWF0aW9uLCB0 aGlzIGRlc2VydmVzIGEgZ29vZCBjb21tZW50IGFib3V0IDAKPiByZXByZXNlbnRpbmcgSU5USUQg MzIgYXQgdGhlIEdJQyBsZXZlbC4gVGhlbiwgYW5vdGhlciBxdWVzdGlvbiBpcyB3aHkKPiB0aGlz IGRvZXNuJ3QgY29tZSBmcm9tIERULiBJIGJldCB0aGF0IGluIHRoZSBmdXR1cmUsIHRoaXMgYmxv Y2sgd2lsbAo+IGJlIHJldXNlZCBhbmQgeW91J2xsIGZpbmQgbW9yZSB0aGFuIG9uZSBpcyBhIHNp bmdsZSBjaGlwLgoKQWJvdXQgdGhlIDAsIHN1cmUsIGlmIHdlIG1haW50YWluIHRoaXMgY29kZSwg SSBzaG91bGQgcHJvYmFibHkgZGVyaXZlCnRoZSB2YWx1ZSBmcm9tIERULgoKPiAKPiBCdXQgdGhl IHJlYWwgcXVlc3Rpb24gaXMgd2h5IHlvdSBhcmUgY29uc3RhbnRseSBjYWxsaW5nCj4gaXJxX2Fs bG9jX2lycXNfcGFyZW50LiBJIHJlbWVtYmVyIGNvbW1lbnRpbmcgYWJvdXQgdGhpcyBpbiBteSBw cmV2aW91cwo+IHJvdW5kIG9mIHJldmlldywgYW5kIEkgc3RpbGwgc2VlIHRoaXMuCgpJIHJlYWxs eSB0cmllZCB0byByZW1vdmUgaXQgYnV0IEkgY2xlYXJseSBmYWlsZWQuIFdoZW4gdGhlcmUgaXMK bm8gaXJxX2FsbG9jX2lycXNfcGFyZW50KCkgY2FsbCBpbiBtdmVidV9zZWlfaXJxX2RvbWFpbl9h bGxvYygpIGl0IGxvb2tzCmxpa2Ugc29tZXRoaW5nIGlzIG1pc3NpbmcgYW5kIEkgZ2V0IGEgb29w cyBhdCBwcm9iZSB0aW1lLgoKVGhpcyBpcyB0aGUgb29wczoKClsgICAgMy4xMTIxNDhdIFVuYWJs ZSB0byBoYW5kbGUga2VybmVsIE5VTEwgcG9pbnRlciBkZXJlZmVyZW5jZSBhdCB2aXJ0dWFsIGFk ZHJlc3MgMDAwMDAwMDAwMDAwMDBlOApbICAgIDMuMTIwOTcwXSBNZW0gYWJvcnQgaW5mbzoKWyAg ICAzLjEyMzc3NV0gICBFU1IgPSAweDk2MDAwMDA0ClsgICAgMy4xMjY4NDJdICAgRXhjZXB0aW9u IGNsYXNzID0gREFCVCAoY3VycmVudCBFTCksIElMID0gMzIgYml0cwpbICAgIDMuMTMyNzg3XSAg IFNFVCA9IDAsIEZuViA9IDAKWyAgICAzLjEzNTg1M10gICBFQSA9IDAsIFMxUFRXID0gMApbICAg IDMuMTM5MDA2XSBEYXRhIGFib3J0IGluZm86ClsgICAgMy4xNDE4OTddICAgSVNWID0gMCwgSVNT ID0gMHgwMDAwMDAwNApbICAgIDMuMTQ1NzQ5XSAgIENNID0gMCwgV25SID0gMApbICAgIDMuMTQ4 NzI4XSBbMDAwMDAwMDAwMDAwMDBlOF0gdXNlciBhZGRyZXNzIGJ1dCBhY3RpdmVfbW0gaXMgc3dh cHBlcgpbICAgIDMuMTU1MTEwXSBJbnRlcm5hbCBlcnJvcjogT29wczogOTYwMDAwMDQgWyMxXSBQ UkVFTVBUIFNNUApbICAgIDMuMTYwNzA1XSBNb2R1bGVzIGxpbmtlZCBpbjoKWyAgICAzLjE2Mzc3 N10gQ1BVOiAwIFBJRDogMzUgQ29tbToga3dvcmtlci8wOjEgTm90IHRhaW50ZWQgNC4xOS4wLXJj MS0wMDAyNC1nMWZmNjA5MDkzZWZkLWRpcnR5ICMxOTMxClsgICAgMy4xNzI4NjFdIEhhcmR3YXJl IG5hbWU6IE1hcnZlbGwgQXJtYWRhIDcwNDAgREIgYm9hcmQgKERUKQpbICAgIDMuMTc4NTU2XSBX b3JrcXVldWU6IGV2ZW50cyBkZWZlcnJlZF9wcm9iZV93b3JrX2Z1bmMKWyAgICAzLjE4MzcxOV0g cHN0YXRlOiA2MDAwMDA4NSAoblpDdiBkYUlmIC1QQU4gLVVBTykKWyAgICAzLjE4ODUzNV0gcGMg OiBpcnFfc2V0X2lycWNoaXBfc3RhdGUrMHgxNjAvMHgxYTAKWyAgICAzLjE5MzM0OF0gbHIgOiBp cnFfc2V0X2lycWNoaXBfc3RhdGUrMHgxNjAvMHgxYTAKWyAgICAzLjE5ODE1OF0gc3AgOiBmZmZm MDAwMDA5ZDAzN2YwClsgICAgMy4yMDE0ODZdIHgyOTogZmZmZjAwMDAwOWQwMzdmMCB4Mjg6IGZm ZmYwMDAwMDhlNDlkMjAgClsgICAgMy4yMDY4MjRdIHgyNzogZmZmZjAwMDAwOGU0OWNiMCB4MjY6 IDAwMDAwMDAwMDAwMDAwMDAgClsgICAgMy4yMTIxNjFdIHgyNTogMDAwMDAwMDAwMDAwMDAwMCB4 MjQ6IGZmZmYwMDAwMDhhZDI1NzAgClsgICAgMy4yMTc0OThdIHgyMzogZmZmZjgwMDBlOGY4MGMw MCB4MjI6IGZmZmYwMDAwMDkzZTkwMDAgClsgICAgMy4yMjI4MzVdIHgyMTogMDAwMDAwMDAwMDAw MDAzMyB4MjA6IDAwMDAwMDAwMDAwMDAwMDAgClsgICAgMy4yMjgxNzJdIHgxOTogZmZmZjgwMDBl OGJkZjMwMCB4MTg6IGZmZmZmZmZmZmZmZmZmZmYgClsgICAgMy4yMzM1MDldIHgxNzogMDAwMDAw MDAwMDAwMDAwMCB4MTY6IDAwMDAwMDAwMDAwMDAwMDAgClsgICAgMy4yMzg4NDZdIHgxNTogZmZm ZjAwMDAwOTNlOTZjOCB4MTQ6IGZmZmYwMDAwODk1NDM2YmYgClsgICAgMy4yNDQxODJdIHgxMzog ZmZmZjAwMDAwOTU0MzZjZCB4MTI6IGZmZmYwMDAwMDk0MDEwYzggClsgICAgMy4yNDk1MTldIHgx MTogZmZmZjAwMDAwOTQwMTAwMCB4MTA6IDAwMDAwMDAwMDVmNWUwZmYgClsgICAgMy4yNTQ4NTZd IHg5IDogZmZmZjAwMDAwOWQwMzRmMCB4OCA6IDMyNWIyMDY1NzQ2MTc0NzMgClsgICAgMy4yNjAx OTJdIHg3IDogNWY3MDY5Njg2MzcxNzI2OSB4NiA6IGZmZmYwMDAwMDg1Y2QyMzggClsgICAgMy4y NjU1MjldIHg1IDogMDAwMDAwMDAwMDAwMDAwMCB4NCA6IDAwMDAwMDAwMDAwMDAwMDAgClsgICAg My4yNzA4NjZdIHgzIDogZmZmZmZmZmZmZmZmZmZmZiB4MiA6IDMzN2FjYzRiMGQ3NTI2MDAgClsg ICAgMy4yNzYyMDJdIHgxIDogMDAwMDAwMDAwMDAwMDAwMCB4MCA6IDAwMDAwMDAwMDAwMDAwMWMg ClsgICAgMy4yODE1NDBdIFByb2Nlc3Mga3dvcmtlci8wOjEgKHBpZDogMzUsIHN0YWNrIGxpbWl0 ID0gMHgoX19fX3B0cnZhbF9fX18pKQpbICAgIDMuMjg4NTMwXSBDYWxsIHRyYWNlOgpbICAgIDMu MjkwOTg3XSAgaXJxX3NldF9pcnFjaGlwX3N0YXRlKzB4MTYwLzB4MWEwClsgICAgMy4yOTU0NTJd ICBtdmVidV9pY3VfaXJxX2RvbWFpbl9hbGxvYysweDE4MC8weDIwOApbICAgIDMuMzAwMzUxXSAg X19pcnFfZG9tYWluX2FsbG9jX2lycXMrMHgxMzgvMHgyYTAKWyAgICAzLjMwNDk4OF0gIGlycV9j cmVhdGVfZndzcGVjX21hcHBpbmcrMHgxNDAvMHgzMjgKWyAgICAzLjMwOTc5OV0gIGlycV9jcmVh dGVfb2ZfbWFwcGluZysweDc4LzB4YTAKWyAgICAzLjMxNDA4OV0gIG9mX2lycV9nZXQrMHg4OC8w eGY4ClsgICAgMy4zMTc0MTldICBwbGF0Zm9ybV9nZXRfaXJxKzB4MjQvMHgxNzgKWyAgICAzLjMy MTM2MF0gIGFybWFkYV90aGVybWFsX3Byb2JlKzB4MTEwLzB4NjY4ClsgICAgMy4zMjU3MzVdICBw bGF0Zm9ybV9kcnZfcHJvYmUrMHg1MC8weGIwClsgICAgMy4zMjk3NjNdICByZWFsbHlfcHJvYmUr MHgxZmMvMHgyOTAKWyAgICAzLjMzMzQ0MV0gIGRyaXZlcl9wcm9iZV9kZXZpY2UrMHg1OC8weDEw MApbICAgIDMuMzM3NjQzXSAgX19kZXZpY2VfYXR0YWNoX2RyaXZlcisweDljLzB4ZjgKWyAgICAz LjM0MjAxOV0gIGJ1c19mb3JfZWFjaF9kcnYrMHg3MC8weGM4ClsgICAgMy4zNDU4NzJdICBfX2Rl dmljZV9hdHRhY2grMHhlMC8weDE0MApbICAgIDMuMzQ5NzI1XSAgZGV2aWNlX2luaXRpYWxfcHJv YmUrMHgxMC8weDE4ClsgICAgMy4zNTM5MjZdICBidXNfcHJvYmVfZGV2aWNlKzB4OTQvMHhhMApb ICAgIDMuMzU3Nzc5XSAgZGVmZXJyZWRfcHJvYmVfd29ya19mdW5jKzB4NmMvMHhhMApbICAgIDMu MzYyMzMxXSAgcHJvY2Vzc19vbmVfd29yaysweDFkYy8weDMzMApbICAgIDMuMzY2MzU5XSAgd29y a2VyX3RocmVhZCsweDIzYy8weDQzMApbICAgIDMuMzcwMTI0XSAga3RocmVhZCsweGY4LzB4MTI4 ClsgICAgMy4zNzMyODBdICByZXRfZnJvbV9mb3JrKzB4MTAvMHgxOApbICAgIDMuMzc2ODcyXSBD b2RlOiBhYTE4MDNlMSBhYTFjMDNlMCA1MjgxMTlhMiA5N2ZmZjc2MCAoZjk0MDc2ODApIApbICAg IDMuMzgyOTkyXSAtLS1bIGVuZCB0cmFjZSBmNDIzODI5Y2I0YjFjMDZjIF0tLS0KCgpUaGUgZmF1 bHR5IGluc3RydWN0aW9uIGlzIHRoZSBpZiBzdGF0ZW1lbnQgdGhlcmU6IApodHRwczovL2VsaXhp ci5ib290bGluLmNvbS9saW51eC92NC4xOS1yYzUvc291cmNlL2tlcm5lbC9pcnEvbWFuYWdlLmMj TDIyNDMKCgpJIGFkZGVkIHRyYWNlcyB0byB1bmRlcnN0YW5kIHdoYXQgaXMgZ29pbmcgb24uIFRo ZSBkby13aGlsZSBsb29wIGdldHMKYW4gaXJxX2RhdGEgc3RydWN0dXJlLCBkZXJpdmVzIHRoZSBj aGlwIHBvaW50ZXIsIHRoZW4gbG9vayBhdCBpdHMKLT5zZXRfaXJxY2hpcF9zdGF0ZSgpIGNhbGxi YWNrLiBJdCBpdCBkb2VzIG5vdCBleGlzdCwgaXQgdHJpZXMgd2l0aCBpdHMKcGFyZW50IGlycV9k YXRhLgoKSGVyZSBhcmUgdGhlIHRyYWNlcyB0aGF0IHNob3cgd2h5IHRoZSBvb3BzIGhhcHBlbnMg d2hlbgppcnFfYWxsb2NfaXJxc19wYXJlbnQoKSBpcyBub3QgY2FsbGVkOgoKV2l0aCBpcnFfYWxs b2NfaXJxc19wYXJlbnQoKSAocnVubmluZyBleGFjdGx5IHdoYXQgSSBzZW50IGluIHRoZSBzZXJp ZXMpOgoKWyAgICAyLjk5Mzg4N10gaXJxX3NldF9pcnFjaGlwX3N0YXRlIFsyMjQ0XSBpcnFfZGF0 YSBwdHI6IDB4ZmZmZjgwMDBlOGY4MGMyOCBbICAgIDMuMDAwNzAzXSBpcnFfc2V0X2lycWNoaXBf c3RhdGUgWzIyNDZdICAgY2hpcCBwdHI6IDB4ZmZmZjAwMDAwOTQwMTUzOCAobmFtZTogbm9uZSkK WyAgICAzLjAwODQ4MF0gaXJxX3NldF9pcnFjaGlwX3N0YXRlIFsyMjQ5XSAgIHBhcmVudCBpcnFf ZGF0YSBwdHIgPyAweGZmZmY4MDAwZThiZGYyMDAKClsgICAgMy4wMjQwNDVdIGlycV9zZXRfaXJx Y2hpcF9zdGF0ZSBbMjI0NF0gaXJxX2RhdGEgcHRyOiAweGZmZmY4MDAwZThiZGYyMDAKWyAgICAz LjAzMDg2MV0gaXJxX3NldF9pcnFjaGlwX3N0YXRlIFsyMjQ2XSAgIGNoaXAgcHRyOiAweGZmZmYw MDAwMDk0MWI2NTggKG5hbWU6IFNFSSBNU0kgY29udHJvbGxlcikKWyAgICAzLjAzOTg1N10gaXJx X3NldF9pcnFjaGlwX3N0YXRlIFsyMjQ5XSAgIHBhcmVudCBpcnFfZGF0YSBwdHIgPyAweGZmZmY4 MDAwZThiZGYyODAKClsgICAgMy4wNTU0MjBdIGlycV9zZXRfaXJxY2hpcF9zdGF0ZSBbMjI0NF0g aXJxX2RhdGEgcHRyOiAweGZmZmY4MDAwZThiZGYyODAKWyAgICAzLjA2MjIzNl0gaXJxX3NldF9p cnFjaGlwX3N0YXRlIFsyMjQ2XSAgIGNoaXAgcHRyOiAweGZmZmYwMDAwMDk0MWIzZTggKG5hbWU6 IENQIFNFSSkKWyAgICAzLjA3MDE4NV0gaXJxX3NldF9pcnFjaGlwX3N0YXRlIFsyMjQ5XSAgIHBh cmVudCBpcnFfZGF0YSBwdHIgPyAweGZmZmY4MDAwZThiZGYzMDAKClsgICAgMy4wODU3NTBdIGly cV9zZXRfaXJxY2hpcF9zdGF0ZSBbMjI0NF0gaXJxX2RhdGEgcHRyOiAweGZmZmY4MDAwZThiZGYz MDAKWyAgICAzLjA5MjU2Nl0gaXJxX3NldF9pcnFjaGlwX3N0YXRlIFsyMjQ2XSAgIGNoaXAgcHRy OiAweDAwMDAwMDAwMDAwMDAwMDAgKG5hbWU6IChudWxsKSkKWyAgICAzLjEwMDUxNV0gaXJxX3Nl dF9pcnFjaGlwX3N0YXRlIFsyMjQ5XSAgIHBhcmVudCBpcnFfZGF0YSBwdHIgPyAweDAwMDAwMDAw MDAwMDAwMDAKCldpdGhvdXQgaXJxX2FsbG9jX2lycXNfcGFyZW50KCkgKHNhbWUgY29kZSBiYXNl LCB3aXRoIHRoZSBjYWxsIHRvIHRoaXMgZnVuY3Rpb24gY29tbWVudGVkIG91dCk6CgpbICAgIDIu OTkyMzY0XSBpcnFfc2V0X2lycWNoaXBfc3RhdGUgWzIyNDRdIGlycV9kYXRhOiAweGZmZmY4MDAw ZTdjYjcyMjgKWyAgICAyLjk5OTE4MV0gaXJxX3NldF9pcnFjaGlwX3N0YXRlIFsyMjQ2XSAgIGNo aXA6IDB4ZmZmZjAwMDAwOTQwMTUzOCAobmFtZTogbm9uZSkKWyAgICAzLjAwNjk1Nl0gaXJxX3Nl dF9pcnFjaGlwX3N0YXRlIFsyMjQ5XSAgIHBhcmVudCBpcnFfZGF0YTogMHhmZmZmODAwMGU5M2E5 ZTAwCgpbICAgIDMuMDIyNTIwXSBpcnFfc2V0X2lycWNoaXBfc3RhdGUgWzIyNDRdIGlycV9kYXRh OiAweGZmZmY4MDAwZTkzYTllMDAKWyAgICAzLjAyOTMzN10gaXJxX3NldF9pcnFjaGlwX3N0YXRl IFsyMjQ2XSAgIGNoaXA6IDB4ZmZmZjAwMDAwOTQxYjY1OCAobmFtZTogU0VJIE1TSSBjb250cm9s bGVyKQpbICAgIDMuMDM4MzMzXSBpcnFfc2V0X2lycWNoaXBfc3RhdGUgWzIyNDldICAgcGFyZW50 IGlycV9kYXRhOiAweGZmZmY4MDAwZTkzYTllODAKClsgICAgMy4wNTM4OTZdIGlycV9zZXRfaXJx Y2hpcF9zdGF0ZSBbMjI0NF0gaXJxX2RhdGE6IDB4ZmZmZjgwMDBlOTNhOWU4MApbICAgIDMuMDYw NzEzXSBpcnFfc2V0X2lycWNoaXBfc3RhdGUgWzIyNDZdICAgY2hpcDogMHhmZmZmMDAwMDA5NDFi M2U4IChuYW1lOiBDUCBTRUkpClsgICAgMy4wNjg2NjJdIGlycV9zZXRfaXJxY2hpcF9zdGF0ZSBb MjI0OV0gICBwYXJlbnQgaXJxX2RhdGE6IDB4ZmZmZjgwMDBlOTNhOWYwMAoKWyAgICAzLjA4NDIy NV0gaXJxX3NldF9pcnFjaGlwX3N0YXRlIFsyMjQ0XSBpcnFfZGF0YTogMHhmZmZmODAwMGU5M2E5 ZjAwClsgICAgMy4wOTEwNDFdIGlycV9zZXRfaXJxY2hpcF9zdGF0ZSBbMjI0Nl0gICBjaGlwOiAw eGZmZmYwMDAwMDkzZWMxNDggKG5hbWU6IEdJQ3YyKQpbICAgIDMuMDk4OTAzXSBpcnFfc2V0X2ly cWNoaXBfc3RhdGUgWzIyNDldICAgcGFyZW50IGlycV9kYXRhOiAweDAwMDAwMDAwMDAwMDAwMDAK CgpUaGUgZGlmZmVyZW5jZSBpcyB0aGF0IGF0IHRoaXMgc3RhZ2UsIHRoZSBpcnFfZGF0YS0+Y2hp cCBwb2ludGVyIG9mIHRoZQpTRUkgY29udHJvbGxlciBfcGFyZW50XyAoaWUuIHRoZSBHSUMncyBj aGlwIHBvaW50ZXIpIGlzIG5vdCB2YWxpZC4gSQpkaWdnZWQgYSBsb3QgaW4gdGhpcyBkaXJlY3Rp b24gZHVyaW5nIHlvdXIgdmFjYXRpb25zIHRvIGZpbmQgb3V0IHdoYXQgSQptaXNzZWQsIGFuZCBJ IGVuZGVkIHVwIGNhbGxpbmcgYmFjayBpcnFfYWxsb2NfaXJxc19wYXJlbnQoKS4KCklmIHlvdSBo YXZlIGFuIGlkZWEgb2YgaG93IHRvIGhhbmRsZSB0aGlzIHByb3Blcmx5LCBJIGFtIGFsbCBlYXJz IQoKPiAKPiBUaGUgd2hvbGUgU0VJIHRoaW5nIGlzIGEgY2hhaW5lZCBpbnRlcnJ1cHQgY29udHJv bGxlciwgYQo+IG11bHRpcGxleGVyLiBUaGUgb3V0cHV0IGludGVycnVwdCBpcyBrbm93biBhdCBw cm9iZSB0aW1lLCBhbmQgbmV2ZXIKPiBjaGFuZ2UuIFlvdSBhbHNvIGhhdmUgY29kZSB0byB0aGF0 IGVmZmVjdCBpbiB0aGUgcHJvYmUgcm91dGluZS4gU28KPiB3aGF0IGlzIHRoaXMgZXhhY3RseT8g RGVhZCBjb2RlPwo+IAo+ID4gKwkvKgo+ID4gKwkgKiBBc3N1bWUgZWRnZSByaXNpbmcgZm9yIG5v dywgaXQgd2lsbCBiZSBwcm9wZXJseSBzZXQgd2hlbgo+ID4gKwkgKiAtPnNldF90eXBlKCkgaXMg Y2FsbGVkCj4gPiArCSAqLwo+ID4gKwlmd3NwZWMtPnBhcmFtWzJdID0gSVJRX1RZUEVfRURHRV9S SVNJTkc7Cj4gPiArCXJldCA9IGlycV9kb21haW5fYWxsb2NfaXJxc19wYXJlbnQoZG9tYWluLCB2 aXJxLCAxLCBmd3NwZWMpOwo+ID4gKwlpZiAocmV0KQo+ID4gKwkJZ290byBmcmVlX2lycTsKPiA+ ICsKClsuLi5dCgo+ID4gKwo+ID4gK3N0cnVjdCBtdmVidV9zZWlfY2FwcyBtdmVidV9zZWlfYXA4 MDZfY2FwcyA9IHsKPiA+ICsJLmFwX3JhbmdlID0gewo+ID4gKwkJLmZpcnN0ID0gMCwKPiA+ICsJ CS5zaXplID0gMjEsCj4gPiArCX0sCj4gPiArCS5jcF9yYW5nZSA9IHsKPiA+ICsJCS5maXJzdCA9 IDIxLAo+ID4gKwkJLnNpemUgPSA0MywKPiA+ICsJfSwgIAo+IAo+IEknZCBhcHByZWNpYXRlIHNv bWUgc3ltYm9saWMgY29uc3RhbnRzIGluc3RlYWQgb2YgbWFnaWMgbnVtYmVycy4KCkkgY2FuIGRl ZmluaXRlbHkgdXNlIHN5bWJvbGljIGNvbnN0YW50cyBidXQgdGhlc2UgbnVtYmVycyBhcmUgYWxy ZWFkeQpxdWl0ZSBtZWFuaW5nZnVsLCB0aGUgY29uc3RhbnRzIGNvdWxkIGJlIG5hbWVkOgoKICAg IFNFSV9BUDgwNl9GSVJTVF9JTlRfSU5fQVBfUkFOR0UKICAgIFNFSV9BUDgwNl9TSVpFX09GX0FQ X1JBTkdFCgo+IAo+ID4gK307Cj4gPiArCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZp Y2VfaWQgbXZlYnVfc2VpX29mX21hdGNoW10gPSB7Cj4gPiArCXsKPiA+ICsJCS5jb21wYXRpYmxl ID0gIm1hcnZlbGwsYXA4MDYtc2VpIiwKPiA+ICsJCS5kYXRhID0gJm12ZWJ1X3NlaV9hcDgwNl9j YXBzLAo+ID4gKwl9LAo+ID4gKwl7fSwKPiA+ICt9Owo+ID4gKwo+ID4gK3N0YXRpYyBzdHJ1Y3Qg cGxhdGZvcm1fZHJpdmVyIG12ZWJ1X3NlaV9kcml2ZXIgPSB7Cj4gPiArCS5wcm9iZSAgPSBtdmVi dV9zZWlfcHJvYmUsCj4gPiArCS5kcml2ZXIgPSB7Cj4gPiArCQkubmFtZSA9ICJtdmVidS1zZWki LAo+ID4gKwkJLm9mX21hdGNoX3RhYmxlID0gbXZlYnVfc2VpX29mX21hdGNoLAo+ID4gKwl9LAo+ ID4gK307Cj4gPiArYnVpbHRpbl9wbGF0Zm9ybV9kcml2ZXIobXZlYnVfc2VpX2RyaXZlcik7Cj4g PiAtLSAKPiA+IDIuMTcuMQo+ID4gICAKPiAKPiBUaGFua3MsCj4gCj4gCU0uCj4gCgoKVGhhbmtz LApNaXF1w6hsCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f XwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmlu ZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9s aW51eC1hcm0ta2VybmVsCg==