From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753222AbdLEP17 (ORCPT ); Tue, 5 Dec 2017 10:27:59 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:46070 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752605AbdLEP1z (ORCPT ); Tue, 5 Dec 2017 10:27:55 -0500 X-Google-Smtp-Source: AGs4zMZ1vuID7KEyjoOosWAQUpBhHiCES6/2EnsWkGPijXQitOfJWGRCzZPh2O7WsXxYPRBzGjsDyA== Date: Tue, 5 Dec 2017 16:27:50 +0100 From: Daniel Vetter To: Hans Verkuil Cc: Sean Paul , dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, David Airlie , daniel.vetter@intel.com, linux-kernel@vger.kernel.org, seanpaul@google.com Subject: Re: [Intel-gfx] [PATCH v3 3/9] drm: Add Content Protection property Message-ID: <20171205152750.qcxxrzk65czqae4h@phenom.ffwll.local> Mail-Followup-To: Hans Verkuil , Sean Paul , dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, David Airlie , daniel.vetter@intel.com, linux-kernel@vger.kernel.org, seanpaul@google.com References: <20171205051513.8603-1-seanpaul@chromium.org> <20171205051513.8603-4-seanpaul@chromium.org> <423fd809-e7a4-f13b-a379-e1efb7f4c746@xs4all.nl> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <423fd809-e7a4-f13b-a379-e1efb7f4c746@xs4all.nl> X-Operating-System: Linux phenom 4.13.0-1-amd64 User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Dec 05, 2017 at 09:07:58AM +0100, Hans Verkuil wrote: > On 12/05/2017 06:15 AM, Sean Paul wrote: > > This patch adds a new optional connector property to allow userspace to enable > > protection over the content it is displaying. This will typically be implemented > > by the driver using HDCP. > > > > The property is a tri-state with the following values: > > - OFF: Self explanatory, no content protection > > - DESIRED: Userspace requests that the driver enable protection > > - ENABLED: Once the driver has authenticated the link, it sets this value > > > > The driver is responsible for downgrading ENABLED to DESIRED if the link becomes > > unprotected. The driver should also maintain the desiredness of protection > > across hotplug/dpms/suspend. > > > > If this looks familiar, I posted [1] this 3 years ago. We have been using this > > in ChromeOS across exynos, mediatek, and rockchip over that time. > > > > Changes in v2: > > - Pimp kerneldoc for content_protection_property (Daniel) > > - Drop sysfs attribute > > Changes in v3: > > - None > > > > Cc: Daniel Vetter > > Signed-off-by: Sean Paul > > > > [1] https://lists.freedesktop.org/archives/dri-devel/2014-December/073336.html > > --- > > drivers/gpu/drm/drm_atomic.c | 8 +++++ > > drivers/gpu/drm/drm_connector.c | 71 +++++++++++++++++++++++++++++++++++++++++ > > drivers/gpu/drm/drm_sysfs.c | 1 + > > include/drm/drm_connector.h | 16 ++++++++++ > > include/uapi/drm/drm_mode.h | 4 +++ > > 5 files changed, 100 insertions(+) > > > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > > index c2da5585e201..676025d755b2 100644 > > --- a/drivers/gpu/drm/drm_atomic.c > > +++ b/drivers/gpu/drm/drm_atomic.c > > @@ -1196,6 +1196,12 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, > > state->picture_aspect_ratio = val; > > } else if (property == connector->scaling_mode_property) { > > state->scaling_mode = val; > > + } else if (property == connector->content_protection_property) { > > + if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) { > > + DRM_DEBUG_KMS("only drivers can set CP Enabled\n"); > > + return -EINVAL; > > + } > > + state->content_protection = val; > > } else if (connector->funcs->atomic_set_property) { > > return connector->funcs->atomic_set_property(connector, > > state, property, val); > > @@ -1275,6 +1281,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, > > *val = state->picture_aspect_ratio; > > } else if (property == connector->scaling_mode_property) { > > *val = state->scaling_mode; > > + } else if (property == connector->content_protection_property) { > > + *val = state->content_protection; > > } else if (connector->funcs->atomic_get_property) { > > return connector->funcs->atomic_get_property(connector, > > state, property, val); > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c > > index f14b48e6e839..8626aa8f485e 100644 > > --- a/drivers/gpu/drm/drm_connector.c > > +++ b/drivers/gpu/drm/drm_connector.c > > @@ -698,6 +698,13 @@ static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = { > > DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, > > drm_tv_subconnector_enum_list) > > > > +static struct drm_prop_enum_list drm_cp_enum_list[] = { > > + { DRM_MODE_CONTENT_PROTECTION_OFF, "Off" }, > > + { DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" }, > > + { DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" }, > > +}; > > +DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list) > > + > > /** > > * DOC: standard connector properties > > * > > @@ -764,6 +771,34 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, > > * after modeset, the kernel driver may set this to "BAD" and issue a > > * hotplug uevent. Drivers should update this value using > > * drm_mode_connector_set_link_status_property(). > > + * Content Protection: > > + * This property is used by userspace to request the kernel protect future > > + * content communicated over the link. When requested, kernel will apply > > + * the appropriate means of protection (most often HDCP), and use the > > + * property to tell userspace the protection is active. > > + * > > + * The value of this property can be one of the following: > > + * > > + * - DRM_MODE_CONTENT_PROTECTION_OFF = 0 > > + * The link is not protected, content is transmitted in the clear. > > + * - DRM_MODE_CONTENT_PROTECTION_DESIRED = 1 > > + * Userspace has requested content protection, but the link is not > > + * currently protected. When in this state, kernel should enable > > + * Content Protection as soon as possible. > > + * - DRM_MODE_CONTENT_PROTECTION_ENABLED = 2 > > + * Userspace has requested content protection, and the link is > > + * protected. Only the driver can set the property to this value. > > + * If userspace attempts to set to ENABLED, kernel will return > > + * -EINVAL. > > + * > > + * A few guidelines: > > + * > > + * - DESIRED state should be preserved until userspace de-asserts it by > > + * setting the property to OFF. This means ENABLED should only transition > > + * to OFF when the user explicitly requests it. > > + * - If the state is DESIRED, kernel should attempt to re-authenticate the > > + * link whenever possible. This includes across disable/enable, dpms, > > + * hotplug, downstream device changes, link status failures, etc.. > > * > > * Connectors also have one standardized atomic property: > > * > > @@ -1047,6 +1082,42 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, > > } > > EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property); > > > > +/** > > + * drm_connector_attach_content_protection_property - attach content protection > > + * property > > + * > > + * @connector: connector to attach CP property on. > > + * > > + * This is used to add support for content protection on select connectors. > > + * Content Protection is intentionally vague to allow for different underlying > > + * technologies, however it is most implemented by HDCP. > > + * > > + * The content protection will be set to &drm_connector_state.content_protection > > + * > > + * Returns: > > + * Zero on success, negative errno on failure. > > + */ > > +int drm_connector_attach_content_protection_property( > > + struct drm_connector *connector) > > +{ > > + struct drm_device *dev = connector->dev; > > + struct drm_property *prop; > > + > > + prop = drm_property_create_enum(dev, 0, "Content Protection", > > + drm_cp_enum_list, > > + ARRAY_SIZE(drm_cp_enum_list)); > > + if (!prop) > > + return -ENOMEM; > > + > > + drm_object_attach_property(&connector->base, prop, > > + DRM_MODE_CONTENT_PROTECTION_OFF); > > + > > + connector->content_protection_property = prop; > > + > > + return 0; > > +} > > +EXPORT_SYMBOL(drm_connector_attach_content_protection_property); > > + > > /** > > * drm_mode_create_aspect_ratio_property - create aspect ratio property > > * @dev: DRM device > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c > > index 1c5b5ce1fd7f..2385c7e0bef5 100644 > > --- a/drivers/gpu/drm/drm_sysfs.c > > +++ b/drivers/gpu/drm/drm_sysfs.c > > @@ -21,6 +21,7 @@ > > #include > > #include > > #include "drm_internal.h" > > +#include "drm_crtc_internal.h" > > > > #define to_drm_minor(d) dev_get_drvdata(d) > > #define to_drm_connector(d) dev_get_drvdata(d) > > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h > > index 7a7140543012..828878addd03 100644 > > --- a/include/drm/drm_connector.h > > +++ b/include/drm/drm_connector.h > > @@ -370,6 +370,12 @@ struct drm_connector_state { > > * upscaling, mostly used for built-in panels. > > */ > > unsigned int scaling_mode; > > + > > + /** > > + * @content_protection: Connector property to request content > > + * protection. This is most commonly used for HDCP. > > + */ > > + unsigned int content_protection; > > }; > > > > /** > > @@ -718,6 +724,7 @@ struct drm_cmdline_mode { > > * @tile_h_size: horizontal size of this tile. > > * @tile_v_size: vertical size of this tile. > > * @scaling_mode_property: Optional atomic property to control the upscaling. > > + * @content_protection_property: Optional property to control content protection > > * > > * Each connector may be connected to one or more CRTCs, or may be clonable by > > * another connector if they can share a CRTC. Each connector also has a specific > > @@ -808,6 +815,12 @@ struct drm_connector { > > > > struct drm_property *scaling_mode_property; > > > > + /** > > + * @content_protection_property: DRM ENUM property for content > > + * protection > > + */ > > + struct drm_property *content_protection_property; > > + > > /** > > * @path_blob_ptr: > > * > > @@ -1002,6 +1015,7 @@ const char *drm_get_dvi_i_subconnector_name(int val); > > const char *drm_get_dvi_i_select_name(int val); > > const char *drm_get_tv_subconnector_name(int val); > > const char *drm_get_tv_select_name(int val); > > +const char *drm_get_content_protection_name(int val); > > > > int drm_mode_create_dvi_i_properties(struct drm_device *dev); > > int drm_mode_create_tv_properties(struct drm_device *dev, > > @@ -1010,6 +1024,8 @@ int drm_mode_create_tv_properties(struct drm_device *dev, > > int drm_mode_create_scaling_mode_property(struct drm_device *dev); > > int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, > > u32 scaling_mode_mask); > > +int drm_connector_attach_content_protection_property( > > + struct drm_connector *connector); > > int drm_mode_create_aspect_ratio_property(struct drm_device *dev); > > int drm_mode_create_suggested_offset_properties(struct drm_device *dev); > > > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h > > index 5597a87154e5..03f4d22305c2 100644 > > --- a/include/uapi/drm/drm_mode.h > > +++ b/include/uapi/drm/drm_mode.h > > @@ -173,6 +173,10 @@ extern "C" { > > DRM_MODE_REFLECT_X | \ > > DRM_MODE_REFLECT_Y) > > > > +/* Content Protection Flags */ > > +#define DRM_MODE_CONTENT_PROTECTION_OFF 0 > > +#define DRM_MODE_CONTENT_PROTECTION_DESIRED 1 > > +#define DRM_MODE_CONTENT_PROTECTION_ENABLED 2 > > What about HDCP 1.4 and HDCP 2.2? Userspace would need to know which version > was negotiated since content protected 4k videos require HDCP 2.2. Perhaps > provide a property with the HDCP version? > > I'm also missing a method for userspace to read the BKSV from the transmitter. Atm the only open source userspace we have is chrome os, which doesn't care about either. That's why these two pieces have been left out, which just need open source userspace for this stuff. The rough idea for hdcp2 was to add a desired_type2 and enabled_type2, which will guarantee hdcp2. _desired alone could give you either. Or we try the most we can automatically, and publish the type1 vs. type2 stuff in a 2nd property. Either way, not having that from the start doesn't prevent us from adding it later on in a backwards compatible way. Properties are rather nice this way :-) -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Vetter Subject: Re: [PATCH v3 3/9] drm: Add Content Protection property Date: Tue, 5 Dec 2017 16:27:50 +0100 Message-ID: <20171205152750.qcxxrzk65czqae4h@phenom.ffwll.local> References: <20171205051513.8603-1-seanpaul@chromium.org> <20171205051513.8603-4-seanpaul@chromium.org> <423fd809-e7a4-f13b-a379-e1efb7f4c746@xs4all.nl> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Content-Disposition: inline In-Reply-To: <423fd809-e7a4-f13b-a379-e1efb7f4c746@xs4all.nl> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: Hans Verkuil Cc: seanpaul@google.com, David Airlie , intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, daniel.vetter@intel.com List-Id: dri-devel@lists.freedesktop.org T24gVHVlLCBEZWMgMDUsIDIwMTcgYXQgMDk6MDc6NThBTSArMDEwMCwgSGFucyBWZXJrdWlsIHdy b3RlOgo+IE9uIDEyLzA1LzIwMTcgMDY6MTUgQU0sIFNlYW4gUGF1bCB3cm90ZToKPiA+IFRoaXMg cGF0Y2ggYWRkcyBhIG5ldyBvcHRpb25hbCBjb25uZWN0b3IgcHJvcGVydHkgdG8gYWxsb3cgdXNl cnNwYWNlIHRvIGVuYWJsZQo+ID4gcHJvdGVjdGlvbiBvdmVyIHRoZSBjb250ZW50IGl0IGlzIGRp c3BsYXlpbmcuIFRoaXMgd2lsbCB0eXBpY2FsbHkgYmUgaW1wbGVtZW50ZWQKPiA+IGJ5IHRoZSBk cml2ZXIgdXNpbmcgSERDUC4KPiA+IAo+ID4gVGhlIHByb3BlcnR5IGlzIGEgdHJpLXN0YXRlIHdp dGggdGhlIGZvbGxvd2luZyB2YWx1ZXM6Cj4gPiAtIE9GRjogU2VsZiBleHBsYW5hdG9yeSwgbm8g Y29udGVudCBwcm90ZWN0aW9uCj4gPiAtIERFU0lSRUQ6IFVzZXJzcGFjZSByZXF1ZXN0cyB0aGF0 IHRoZSBkcml2ZXIgZW5hYmxlIHByb3RlY3Rpb24KPiA+IC0gRU5BQkxFRDogT25jZSB0aGUgZHJp dmVyIGhhcyBhdXRoZW50aWNhdGVkIHRoZSBsaW5rLCBpdCBzZXRzIHRoaXMgdmFsdWUKPiA+IAo+ ID4gVGhlIGRyaXZlciBpcyByZXNwb25zaWJsZSBmb3IgZG93bmdyYWRpbmcgRU5BQkxFRCB0byBE RVNJUkVEIGlmIHRoZSBsaW5rIGJlY29tZXMKPiA+IHVucHJvdGVjdGVkLiBUaGUgZHJpdmVyIHNo b3VsZCBhbHNvIG1haW50YWluIHRoZSBkZXNpcmVkbmVzcyBvZiBwcm90ZWN0aW9uCj4gPiBhY3Jv c3MgaG90cGx1Zy9kcG1zL3N1c3BlbmQuCj4gPiAKPiA+IElmIHRoaXMgbG9va3MgZmFtaWxpYXIs IEkgcG9zdGVkIFsxXSB0aGlzIDMgeWVhcnMgYWdvLiBXZSBoYXZlIGJlZW4gdXNpbmcgdGhpcwo+ ID4gaW4gQ2hyb21lT1MgYWNyb3NzIGV4eW5vcywgbWVkaWF0ZWssIGFuZCByb2NrY2hpcCBvdmVy IHRoYXQgdGltZS4KPiA+IAo+ID4gQ2hhbmdlcyBpbiB2MjoKPiA+ICAtIFBpbXAga2VybmVsZG9j IGZvciBjb250ZW50X3Byb3RlY3Rpb25fcHJvcGVydHkgKERhbmllbCkKPiA+ICAtIERyb3Agc3lz ZnMgYXR0cmlidXRlCj4gPiBDaGFuZ2VzIGluIHYzOgo+ID4gIC0gTm9uZQo+ID4gCj4gPiBDYzog RGFuaWVsIFZldHRlciA8ZGFuaWVsLnZldHRlckBpbnRlbC5jb20+Cj4gPiBTaWduZWQtb2ZmLWJ5 OiBTZWFuIFBhdWwgPHNlYW5wYXVsQGNocm9taXVtLm9yZz4KPiA+IAo+ID4gWzFdIGh0dHBzOi8v bGlzdHMuZnJlZWRlc2t0b3Aub3JnL2FyY2hpdmVzL2RyaS1kZXZlbC8yMDE0LURlY2VtYmVyLzA3 MzMzNi5odG1sCj4gPiAtLS0KPiA+ICBkcml2ZXJzL2dwdS9kcm0vZHJtX2F0b21pYy5jICAgIHwg IDggKysrKysKPiA+ICBkcml2ZXJzL2dwdS9kcm0vZHJtX2Nvbm5lY3Rvci5jIHwgNzEgKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKPiA+ICBkcml2ZXJzL2dwdS9kcm0v ZHJtX3N5c2ZzLmMgICAgIHwgIDEgKwo+ID4gIGluY2x1ZGUvZHJtL2RybV9jb25uZWN0b3IuaCAg ICAgfCAxNiArKysrKysrKysrCj4gPiAgaW5jbHVkZS91YXBpL2RybS9kcm1fbW9kZS5oICAgICB8 ICA0ICsrKwo+ID4gIDUgZmlsZXMgY2hhbmdlZCwgMTAwIGluc2VydGlvbnMoKykKPiA+IAo+ID4g ZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fYXRvbWljLmMgYi9kcml2ZXJzL2dwdS9k cm0vZHJtX2F0b21pYy5jCj4gPiBpbmRleCBjMmRhNTU4NWUyMDEuLjY3NjAyNWQ3NTViMiAxMDA2 NDQKPiA+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fYXRvbWljLmMKPiA+ICsrKyBiL2RyaXZl cnMvZ3B1L2RybS9kcm1fYXRvbWljLmMKPiA+IEBAIC0xMTk2LDYgKzExOTYsMTIgQEAgc3RhdGlj IGludCBkcm1fYXRvbWljX2Nvbm5lY3Rvcl9zZXRfcHJvcGVydHkoc3RydWN0IGRybV9jb25uZWN0 b3IgKmNvbm5lY3RvciwKPiA+ICAJCXN0YXRlLT5waWN0dXJlX2FzcGVjdF9yYXRpbyA9IHZhbDsK PiA+ICAJfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBjb25uZWN0b3ItPnNjYWxpbmdfbW9kZV9wcm9w ZXJ0eSkgewo+ID4gIAkJc3RhdGUtPnNjYWxpbmdfbW9kZSA9IHZhbDsKPiA+ICsJfSBlbHNlIGlm IChwcm9wZXJ0eSA9PSBjb25uZWN0b3ItPmNvbnRlbnRfcHJvdGVjdGlvbl9wcm9wZXJ0eSkgewo+ ID4gKwkJaWYgKHZhbCA9PSBEUk1fTU9ERV9DT05URU5UX1BST1RFQ1RJT05fRU5BQkxFRCkgewo+ ID4gKwkJCURSTV9ERUJVR19LTVMoIm9ubHkgZHJpdmVycyBjYW4gc2V0IENQIEVuYWJsZWRcbiIp Owo+ID4gKwkJCXJldHVybiAtRUlOVkFMOwo+ID4gKwkJfQo+ID4gKwkJc3RhdGUtPmNvbnRlbnRf cHJvdGVjdGlvbiA9IHZhbDsKPiA+ICAJfSBlbHNlIGlmIChjb25uZWN0b3ItPmZ1bmNzLT5hdG9t aWNfc2V0X3Byb3BlcnR5KSB7Cj4gPiAgCQlyZXR1cm4gY29ubmVjdG9yLT5mdW5jcy0+YXRvbWlj X3NldF9wcm9wZXJ0eShjb25uZWN0b3IsCj4gPiAgCQkJCXN0YXRlLCBwcm9wZXJ0eSwgdmFsKTsK PiA+IEBAIC0xMjc1LDYgKzEyODEsOCBAQCBkcm1fYXRvbWljX2Nvbm5lY3Rvcl9nZXRfcHJvcGVy dHkoc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvciwKPiA+ICAJCSp2YWwgPSBzdGF0ZS0+ cGljdHVyZV9hc3BlY3RfcmF0aW87Cj4gPiAgCX0gZWxzZSBpZiAocHJvcGVydHkgPT0gY29ubmVj dG9yLT5zY2FsaW5nX21vZGVfcHJvcGVydHkpIHsKPiA+ICAJCSp2YWwgPSBzdGF0ZS0+c2NhbGlu Z19tb2RlOwo+ID4gKwl9IGVsc2UgaWYgKHByb3BlcnR5ID09IGNvbm5lY3Rvci0+Y29udGVudF9w cm90ZWN0aW9uX3Byb3BlcnR5KSB7Cj4gPiArCQkqdmFsID0gc3RhdGUtPmNvbnRlbnRfcHJvdGVj dGlvbjsKPiA+ICAJfSBlbHNlIGlmIChjb25uZWN0b3ItPmZ1bmNzLT5hdG9taWNfZ2V0X3Byb3Bl cnR5KSB7Cj4gPiAgCQlyZXR1cm4gY29ubmVjdG9yLT5mdW5jcy0+YXRvbWljX2dldF9wcm9wZXJ0 eShjb25uZWN0b3IsCj4gPiAgCQkJCXN0YXRlLCBwcm9wZXJ0eSwgdmFsKTsKPiA+IGRpZmYgLS1n aXQgYS9kcml2ZXJzL2dwdS9kcm0vZHJtX2Nvbm5lY3Rvci5jIGIvZHJpdmVycy9ncHUvZHJtL2Ry bV9jb25uZWN0b3IuYwo+ID4gaW5kZXggZjE0YjQ4ZTZlODM5Li44NjI2YWE4ZjQ4NWUgMTAwNjQ0 Cj4gPiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vZHJtX2Nvbm5lY3Rvci5jCj4gPiArKysgYi9kcml2 ZXJzL2dwdS9kcm0vZHJtX2Nvbm5lY3Rvci5jCj4gPiBAQCAtNjk4LDYgKzY5OCwxMyBAQCBzdGF0 aWMgY29uc3Qgc3RydWN0IGRybV9wcm9wX2VudW1fbGlzdCBkcm1fdHZfc3ViY29ubmVjdG9yX2Vu dW1fbGlzdFtdID0gewo+ID4gIERSTV9FTlVNX05BTUVfRk4oZHJtX2dldF90dl9zdWJjb25uZWN0 b3JfbmFtZSwKPiA+ICAJCSBkcm1fdHZfc3ViY29ubmVjdG9yX2VudW1fbGlzdCkKPiA+ICAKPiA+ ICtzdGF0aWMgc3RydWN0IGRybV9wcm9wX2VudW1fbGlzdCBkcm1fY3BfZW51bV9saXN0W10gPSB7 Cj4gPiArICAgICAgICB7IERSTV9NT0RFX0NPTlRFTlRfUFJPVEVDVElPTl9PRkYsICJPZmYiIH0s Cj4gPiArICAgICAgICB7IERSTV9NT0RFX0NPTlRFTlRfUFJPVEVDVElPTl9ERVNJUkVELCAiRGVz aXJlZCIgfSwKPiA+ICsgICAgICAgIHsgRFJNX01PREVfQ09OVEVOVF9QUk9URUNUSU9OX0VOQUJM RUQsICJFbmFibGVkIiB9LAo+ID4gK307Cj4gPiArRFJNX0VOVU1fTkFNRV9GTihkcm1fZ2V0X2Nv bnRlbnRfcHJvdGVjdGlvbl9uYW1lLCBkcm1fY3BfZW51bV9saXN0KQo+ID4gKwo+ID4gIC8qKgo+ ID4gICAqIERPQzogc3RhbmRhcmQgY29ubmVjdG9yIHByb3BlcnRpZXMKPiA+ICAgKgo+ID4gQEAg LTc2NCw2ICs3NzEsMzQgQEAgRFJNX0VOVU1fTkFNRV9GTihkcm1fZ2V0X3R2X3N1YmNvbm5lY3Rv cl9uYW1lLAo+ID4gICAqICAgICAgYWZ0ZXIgbW9kZXNldCwgdGhlIGtlcm5lbCBkcml2ZXIgbWF5 IHNldCB0aGlzIHRvICJCQUQiIGFuZCBpc3N1ZSBhCj4gPiAgICogICAgICBob3RwbHVnIHVldmVu dC4gRHJpdmVycyBzaG91bGQgdXBkYXRlIHRoaXMgdmFsdWUgdXNpbmcKPiA+ICAgKiAgICAgIGRy bV9tb2RlX2Nvbm5lY3Rvcl9zZXRfbGlua19zdGF0dXNfcHJvcGVydHkoKS4KPiA+ICsgKiBDb250 ZW50IFByb3RlY3Rpb246Cj4gPiArICoJVGhpcyBwcm9wZXJ0eSBpcyB1c2VkIGJ5IHVzZXJzcGFj ZSB0byByZXF1ZXN0IHRoZSBrZXJuZWwgcHJvdGVjdCBmdXR1cmUKPiA+ICsgKgljb250ZW50IGNv bW11bmljYXRlZCBvdmVyIHRoZSBsaW5rLiBXaGVuIHJlcXVlc3RlZCwga2VybmVsIHdpbGwgYXBw bHkKPiA+ICsgKgl0aGUgYXBwcm9wcmlhdGUgbWVhbnMgb2YgcHJvdGVjdGlvbiAobW9zdCBvZnRl biBIRENQKSwgYW5kIHVzZSB0aGUKPiA+ICsgKglwcm9wZXJ0eSB0byB0ZWxsIHVzZXJzcGFjZSB0 aGUgcHJvdGVjdGlvbiBpcyBhY3RpdmUuCj4gPiArICoKPiA+ICsgKglUaGUgdmFsdWUgb2YgdGhp cyBwcm9wZXJ0eSBjYW4gYmUgb25lIG9mIHRoZSBmb2xsb3dpbmc6Cj4gPiArICoKPiA+ICsgKgkt IERSTV9NT0RFX0NPTlRFTlRfUFJPVEVDVElPTl9PRkYgPSAwCj4gPiArICoJCVRoZSBsaW5rIGlz IG5vdCBwcm90ZWN0ZWQsIGNvbnRlbnQgaXMgdHJhbnNtaXR0ZWQgaW4gdGhlIGNsZWFyLgo+ID4g KyAqCS0gRFJNX01PREVfQ09OVEVOVF9QUk9URUNUSU9OX0RFU0lSRUQgPSAxCj4gPiArICoJCVVz ZXJzcGFjZSBoYXMgcmVxdWVzdGVkIGNvbnRlbnQgcHJvdGVjdGlvbiwgYnV0IHRoZSBsaW5rIGlz IG5vdAo+ID4gKyAqCQljdXJyZW50bHkgcHJvdGVjdGVkLiBXaGVuIGluIHRoaXMgc3RhdGUsIGtl cm5lbCBzaG91bGQgZW5hYmxlCj4gPiArICoJCUNvbnRlbnQgUHJvdGVjdGlvbiBhcyBzb29uIGFz IHBvc3NpYmxlLgo+ID4gKyAqCS0gRFJNX01PREVfQ09OVEVOVF9QUk9URUNUSU9OX0VOQUJMRUQg PSAyCj4gPiArICoJCVVzZXJzcGFjZSBoYXMgcmVxdWVzdGVkIGNvbnRlbnQgcHJvdGVjdGlvbiwg YW5kIHRoZSBsaW5rIGlzCj4gPiArICoJCXByb3RlY3RlZC4gT25seSB0aGUgZHJpdmVyIGNhbiBz ZXQgdGhlIHByb3BlcnR5IHRvIHRoaXMgdmFsdWUuCj4gPiArICoJCUlmIHVzZXJzcGFjZSBhdHRl bXB0cyB0byBzZXQgdG8gRU5BQkxFRCwga2VybmVsIHdpbGwgcmV0dXJuCj4gPiArICoJCS1FSU5W QUwuCj4gPiArICoKPiA+ICsgKglBIGZldyBndWlkZWxpbmVzOgo+ID4gKyAqCj4gPiArICoJLSBE RVNJUkVEIHN0YXRlIHNob3VsZCBiZSBwcmVzZXJ2ZWQgdW50aWwgdXNlcnNwYWNlIGRlLWFzc2Vy dHMgaXQgYnkKPiA+ICsgKgkgIHNldHRpbmcgdGhlIHByb3BlcnR5IHRvIE9GRi4gVGhpcyBtZWFu cyBFTkFCTEVEIHNob3VsZCBvbmx5IHRyYW5zaXRpb24KPiA+ICsgKgkgIHRvIE9GRiB3aGVuIHRo ZSB1c2VyIGV4cGxpY2l0bHkgcmVxdWVzdHMgaXQuCj4gPiArICoJLSBJZiB0aGUgc3RhdGUgaXMg REVTSVJFRCwga2VybmVsIHNob3VsZCBhdHRlbXB0IHRvIHJlLWF1dGhlbnRpY2F0ZSB0aGUKPiA+ ICsgKgkgIGxpbmsgd2hlbmV2ZXIgcG9zc2libGUuIFRoaXMgaW5jbHVkZXMgYWNyb3NzIGRpc2Fi bGUvZW5hYmxlLCBkcG1zLAo+ID4gKyAqCSAgaG90cGx1ZywgZG93bnN0cmVhbSBkZXZpY2UgY2hh bmdlcywgbGluayBzdGF0dXMgZmFpbHVyZXMsIGV0Yy4uCj4gPiAgICoKPiA+ICAgKiBDb25uZWN0 b3JzIGFsc28gaGF2ZSBvbmUgc3RhbmRhcmRpemVkIGF0b21pYyBwcm9wZXJ0eToKPiA+ICAgKgo+ ID4gQEAgLTEwNDcsNiArMTA4Miw0MiBAQCBpbnQgZHJtX2Nvbm5lY3Rvcl9hdHRhY2hfc2NhbGlu Z19tb2RlX3Byb3BlcnR5KHN0cnVjdCBkcm1fY29ubmVjdG9yICpjb25uZWN0b3IsCj4gPiAgfQo+ ID4gIEVYUE9SVF9TWU1CT0woZHJtX2Nvbm5lY3Rvcl9hdHRhY2hfc2NhbGluZ19tb2RlX3Byb3Bl cnR5KTsKPiA+ICAKPiA+ICsvKioKPiA+ICsgKiBkcm1fY29ubmVjdG9yX2F0dGFjaF9jb250ZW50 X3Byb3RlY3Rpb25fcHJvcGVydHkgLSBhdHRhY2ggY29udGVudCBwcm90ZWN0aW9uCj4gPiArICog cHJvcGVydHkKPiA+ICsgKgo+ID4gKyAqIEBjb25uZWN0b3I6IGNvbm5lY3RvciB0byBhdHRhY2gg Q1AgcHJvcGVydHkgb24uCj4gPiArICoKPiA+ICsgKiBUaGlzIGlzIHVzZWQgdG8gYWRkIHN1cHBv cnQgZm9yIGNvbnRlbnQgcHJvdGVjdGlvbiBvbiBzZWxlY3QgY29ubmVjdG9ycy4KPiA+ICsgKiBD b250ZW50IFByb3RlY3Rpb24gaXMgaW50ZW50aW9uYWxseSB2YWd1ZSB0byBhbGxvdyBmb3IgZGlm ZmVyZW50IHVuZGVybHlpbmcKPiA+ICsgKiB0ZWNobm9sb2dpZXMsIGhvd2V2ZXIgaXQgaXMgbW9z dCBpbXBsZW1lbnRlZCBieSBIRENQLgo+ID4gKyAqCj4gPiArICogVGhlIGNvbnRlbnQgcHJvdGVj dGlvbiB3aWxsIGJlIHNldCB0byAmZHJtX2Nvbm5lY3Rvcl9zdGF0ZS5jb250ZW50X3Byb3RlY3Rp b24KPiA+ICsgKgo+ID4gKyAqIFJldHVybnM6Cj4gPiArICogWmVybyBvbiBzdWNjZXNzLCBuZWdh dGl2ZSBlcnJubyBvbiBmYWlsdXJlLgo+ID4gKyAqLwo+ID4gK2ludCBkcm1fY29ubmVjdG9yX2F0 dGFjaF9jb250ZW50X3Byb3RlY3Rpb25fcHJvcGVydHkoCj4gPiArCQlzdHJ1Y3QgZHJtX2Nvbm5l Y3RvciAqY29ubmVjdG9yKQo+ID4gK3sKPiA+ICsJc3RydWN0IGRybV9kZXZpY2UgKmRldiA9IGNv bm5lY3Rvci0+ZGV2Owo+ID4gKwlzdHJ1Y3QgZHJtX3Byb3BlcnR5ICpwcm9wOwo+ID4gKwo+ID4g Kwlwcm9wID0gZHJtX3Byb3BlcnR5X2NyZWF0ZV9lbnVtKGRldiwgMCwgIkNvbnRlbnQgUHJvdGVj dGlvbiIsCj4gPiArCQkJCQlkcm1fY3BfZW51bV9saXN0LAo+ID4gKwkJCQkJQVJSQVlfU0laRShk cm1fY3BfZW51bV9saXN0KSk7Cj4gPiArCWlmICghcHJvcCkKPiA+ICsJCXJldHVybiAtRU5PTUVN Owo+ID4gKwo+ID4gKwlkcm1fb2JqZWN0X2F0dGFjaF9wcm9wZXJ0eSgmY29ubmVjdG9yLT5iYXNl LCBwcm9wLAo+ID4gKwkJCQkgICBEUk1fTU9ERV9DT05URU5UX1BST1RFQ1RJT05fT0ZGKTsKPiA+ ICsKPiA+ICsJY29ubmVjdG9yLT5jb250ZW50X3Byb3RlY3Rpb25fcHJvcGVydHkgPSBwcm9wOwo+ ID4gKwo+ID4gKwlyZXR1cm4gMDsKPiA+ICt9Cj4gPiArRVhQT1JUX1NZTUJPTChkcm1fY29ubmVj dG9yX2F0dGFjaF9jb250ZW50X3Byb3RlY3Rpb25fcHJvcGVydHkpOwo+ID4gKwo+ID4gIC8qKgo+ ID4gICAqIGRybV9tb2RlX2NyZWF0ZV9hc3BlY3RfcmF0aW9fcHJvcGVydHkgLSBjcmVhdGUgYXNw ZWN0IHJhdGlvIHByb3BlcnR5Cj4gPiAgICogQGRldjogRFJNIGRldmljZQo+ID4gZGlmZiAtLWdp dCBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fc3lzZnMuYyBiL2RyaXZlcnMvZ3B1L2RybS9kcm1fc3lz ZnMuYwo+ID4gaW5kZXggMWM1YjVjZTFmZDdmLi4yMzg1YzdlMGJlZjUgMTAwNjQ0Cj4gPiAtLS0g YS9kcml2ZXJzL2dwdS9kcm0vZHJtX3N5c2ZzLmMKPiA+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9k cm1fc3lzZnMuYwo+ID4gQEAgLTIxLDYgKzIxLDcgQEAKPiA+ICAjaW5jbHVkZSA8ZHJtL2RybV9z eXNmcy5oPgo+ID4gICNpbmNsdWRlIDxkcm0vZHJtUC5oPgo+ID4gICNpbmNsdWRlICJkcm1faW50 ZXJuYWwuaCIKPiA+ICsjaW5jbHVkZSAiZHJtX2NydGNfaW50ZXJuYWwuaCIKPiA+ICAKPiA+ICAj ZGVmaW5lIHRvX2RybV9taW5vcihkKSBkZXZfZ2V0X2RydmRhdGEoZCkKPiA+ICAjZGVmaW5lIHRv X2RybV9jb25uZWN0b3IoZCkgZGV2X2dldF9kcnZkYXRhKGQpCj4gPiBkaWZmIC0tZ2l0IGEvaW5j bHVkZS9kcm0vZHJtX2Nvbm5lY3Rvci5oIGIvaW5jbHVkZS9kcm0vZHJtX2Nvbm5lY3Rvci5oCj4g PiBpbmRleCA3YTcxNDA1NDMwMTIuLjgyODg3OGFkZGQwMyAxMDA2NDQKPiA+IC0tLSBhL2luY2x1 ZGUvZHJtL2RybV9jb25uZWN0b3IuaAo+ID4gKysrIGIvaW5jbHVkZS9kcm0vZHJtX2Nvbm5lY3Rv ci5oCj4gPiBAQCAtMzcwLDYgKzM3MCwxMiBAQCBzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9zdGF0ZSB7 Cj4gPiAgCSAqIHVwc2NhbGluZywgbW9zdGx5IHVzZWQgZm9yIGJ1aWx0LWluIHBhbmVscy4KPiA+ ICAJICovCj4gPiAgCXVuc2lnbmVkIGludCBzY2FsaW5nX21vZGU7Cj4gPiArCj4gPiArCS8qKgo+ ID4gKwkgKiBAY29udGVudF9wcm90ZWN0aW9uOiBDb25uZWN0b3IgcHJvcGVydHkgdG8gcmVxdWVz dCBjb250ZW50Cj4gPiArCSAqIHByb3RlY3Rpb24uIFRoaXMgaXMgbW9zdCBjb21tb25seSB1c2Vk IGZvciBIRENQLgo+ID4gKwkgKi8KPiA+ICsJdW5zaWduZWQgaW50IGNvbnRlbnRfcHJvdGVjdGlv bjsKPiA+ICB9Owo+ID4gIAo+ID4gIC8qKgo+ID4gQEAgLTcxOCw2ICs3MjQsNyBAQCBzdHJ1Y3Qg ZHJtX2NtZGxpbmVfbW9kZSB7Cj4gPiAgICogQHRpbGVfaF9zaXplOiBob3Jpem9udGFsIHNpemUg b2YgdGhpcyB0aWxlLgo+ID4gICAqIEB0aWxlX3Zfc2l6ZTogdmVydGljYWwgc2l6ZSBvZiB0aGlz IHRpbGUuCj4gPiAgICogQHNjYWxpbmdfbW9kZV9wcm9wZXJ0eTogIE9wdGlvbmFsIGF0b21pYyBw cm9wZXJ0eSB0byBjb250cm9sIHRoZSB1cHNjYWxpbmcuCj4gPiArICogQGNvbnRlbnRfcHJvdGVj dGlvbl9wcm9wZXJ0eTogT3B0aW9uYWwgcHJvcGVydHkgdG8gY29udHJvbCBjb250ZW50IHByb3Rl Y3Rpb24KPiA+ICAgKgo+ID4gICAqIEVhY2ggY29ubmVjdG9yIG1heSBiZSBjb25uZWN0ZWQgdG8g b25lIG9yIG1vcmUgQ1JUQ3MsIG9yIG1heSBiZSBjbG9uYWJsZSBieQo+ID4gICAqIGFub3RoZXIg Y29ubmVjdG9yIGlmIHRoZXkgY2FuIHNoYXJlIGEgQ1JUQy4gIEVhY2ggY29ubmVjdG9yIGFsc28g aGFzIGEgc3BlY2lmaWMKPiA+IEBAIC04MDgsNiArODE1LDEyIEBAIHN0cnVjdCBkcm1fY29ubmVj dG9yIHsKPiA+ICAKPiA+ICAJc3RydWN0IGRybV9wcm9wZXJ0eSAqc2NhbGluZ19tb2RlX3Byb3Bl cnR5Owo+ID4gIAo+ID4gKwkvKioKPiA+ICsJICogQGNvbnRlbnRfcHJvdGVjdGlvbl9wcm9wZXJ0 eTogRFJNIEVOVU0gcHJvcGVydHkgZm9yIGNvbnRlbnQKPiA+ICsJICogcHJvdGVjdGlvbgo+ID4g KwkgKi8KPiA+ICsJc3RydWN0IGRybV9wcm9wZXJ0eSAqY29udGVudF9wcm90ZWN0aW9uX3Byb3Bl cnR5Owo+ID4gKwo+ID4gIAkvKioKPiA+ICAJICogQHBhdGhfYmxvYl9wdHI6Cj4gPiAgCSAqCj4g PiBAQCAtMTAwMiw2ICsxMDE1LDcgQEAgY29uc3QgY2hhciAqZHJtX2dldF9kdmlfaV9zdWJjb25u ZWN0b3JfbmFtZShpbnQgdmFsKTsKPiA+ICBjb25zdCBjaGFyICpkcm1fZ2V0X2R2aV9pX3NlbGVj dF9uYW1lKGludCB2YWwpOwo+ID4gIGNvbnN0IGNoYXIgKmRybV9nZXRfdHZfc3ViY29ubmVjdG9y X25hbWUoaW50IHZhbCk7Cj4gPiAgY29uc3QgY2hhciAqZHJtX2dldF90dl9zZWxlY3RfbmFtZShp bnQgdmFsKTsKPiA+ICtjb25zdCBjaGFyICpkcm1fZ2V0X2NvbnRlbnRfcHJvdGVjdGlvbl9uYW1l KGludCB2YWwpOwo+ID4gIAo+ID4gIGludCBkcm1fbW9kZV9jcmVhdGVfZHZpX2lfcHJvcGVydGll cyhzdHJ1Y3QgZHJtX2RldmljZSAqZGV2KTsKPiA+ICBpbnQgZHJtX21vZGVfY3JlYXRlX3R2X3By b3BlcnRpZXMoc3RydWN0IGRybV9kZXZpY2UgKmRldiwKPiA+IEBAIC0xMDEwLDYgKzEwMjQsOCBA QCBpbnQgZHJtX21vZGVfY3JlYXRlX3R2X3Byb3BlcnRpZXMoc3RydWN0IGRybV9kZXZpY2UgKmRl diwKPiA+ICBpbnQgZHJtX21vZGVfY3JlYXRlX3NjYWxpbmdfbW9kZV9wcm9wZXJ0eShzdHJ1Y3Qg ZHJtX2RldmljZSAqZGV2KTsKPiA+ICBpbnQgZHJtX2Nvbm5lY3Rvcl9hdHRhY2hfc2NhbGluZ19t b2RlX3Byb3BlcnR5KHN0cnVjdCBkcm1fY29ubmVjdG9yICpjb25uZWN0b3IsCj4gPiAgCQkJCQkg ICAgICAgdTMyIHNjYWxpbmdfbW9kZV9tYXNrKTsKPiA+ICtpbnQgZHJtX2Nvbm5lY3Rvcl9hdHRh Y2hfY29udGVudF9wcm90ZWN0aW9uX3Byb3BlcnR5KAo+ID4gKwkJc3RydWN0IGRybV9jb25uZWN0 b3IgKmNvbm5lY3Rvcik7Cj4gPiAgaW50IGRybV9tb2RlX2NyZWF0ZV9hc3BlY3RfcmF0aW9fcHJv cGVydHkoc3RydWN0IGRybV9kZXZpY2UgKmRldik7Cj4gPiAgaW50IGRybV9tb2RlX2NyZWF0ZV9z dWdnZXN0ZWRfb2Zmc2V0X3Byb3BlcnRpZXMoc3RydWN0IGRybV9kZXZpY2UgKmRldik7Cj4gPiAg Cj4gPiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS91YXBpL2RybS9kcm1fbW9kZS5oIGIvaW5jbHVkZS91 YXBpL2RybS9kcm1fbW9kZS5oCj4gPiBpbmRleCA1NTk3YTg3MTU0ZTUuLjAzZjRkMjIzMDVjMiAx MDA2NDQKPiA+IC0tLSBhL2luY2x1ZGUvdWFwaS9kcm0vZHJtX21vZGUuaAo+ID4gKysrIGIvaW5j bHVkZS91YXBpL2RybS9kcm1fbW9kZS5oCj4gPiBAQCAtMTczLDYgKzE3MywxMCBAQCBleHRlcm4g IkMiIHsKPiA+ICAJCURSTV9NT0RFX1JFRkxFQ1RfWCB8IFwKPiA+ICAJCURSTV9NT0RFX1JFRkxF Q1RfWSkKPiA+ICAKPiA+ICsvKiBDb250ZW50IFByb3RlY3Rpb24gRmxhZ3MgKi8KPiA+ICsjZGVm aW5lIERSTV9NT0RFX0NPTlRFTlRfUFJPVEVDVElPTl9PRkYJCTAKPiA+ICsjZGVmaW5lIERSTV9N T0RFX0NPTlRFTlRfUFJPVEVDVElPTl9ERVNJUkVEICAgICAxCj4gPiArI2RlZmluZSBEUk1fTU9E RV9DT05URU5UX1BST1RFQ1RJT05fRU5BQkxFRCAgICAgMgo+IAo+IFdoYXQgYWJvdXQgSERDUCAx LjQgYW5kIEhEQ1AgMi4yPyBVc2Vyc3BhY2Ugd291bGQgbmVlZCB0byBrbm93IHdoaWNoIHZlcnNp b24KPiB3YXMgbmVnb3RpYXRlZCBzaW5jZSBjb250ZW50IHByb3RlY3RlZCA0ayB2aWRlb3MgcmVx dWlyZSBIRENQIDIuMi4gUGVyaGFwcwo+IHByb3ZpZGUgYSBwcm9wZXJ0eSB3aXRoIHRoZSBIRENQ IHZlcnNpb24/Cj4gCj4gSSdtIGFsc28gbWlzc2luZyBhIG1ldGhvZCBmb3IgdXNlcnNwYWNlIHRv IHJlYWQgdGhlIEJLU1YgZnJvbSB0aGUgdHJhbnNtaXR0ZXIuCgpBdG0gdGhlIG9ubHkgb3BlbiBz b3VyY2UgdXNlcnNwYWNlIHdlIGhhdmUgaXMgY2hyb21lIG9zLCB3aGljaCBkb2Vzbid0CmNhcmUg YWJvdXQgZWl0aGVyLiBUaGF0J3Mgd2h5IHRoZXNlIHR3byBwaWVjZXMgaGF2ZSBiZWVuIGxlZnQg b3V0LCB3aGljaApqdXN0IG5lZWQgb3BlbiBzb3VyY2UgdXNlcnNwYWNlIGZvciB0aGlzIHN0dWZm LgoKVGhlIHJvdWdoIGlkZWEgZm9yIGhkY3AyIHdhcyB0byBhZGQgYSBkZXNpcmVkX3R5cGUyIGFu ZCBlbmFibGVkX3R5cGUyLAp3aGljaCB3aWxsIGd1YXJhbnRlZSBoZGNwMi4gX2Rlc2lyZWQgYWxv bmUgY291bGQgZ2l2ZSB5b3UgZWl0aGVyLiBPciB3ZQp0cnkgdGhlIG1vc3Qgd2UgY2FuIGF1dG9t YXRpY2FsbHksIGFuZCBwdWJsaXNoIHRoZSB0eXBlMSB2cy4gdHlwZTIgc3R1ZmYKaW4gYSAybmQg cHJvcGVydHkuCgpFaXRoZXIgd2F5LCBub3QgaGF2aW5nIHRoYXQgZnJvbSB0aGUgc3RhcnQgZG9l c24ndCBwcmV2ZW50IHVzIGZyb20gYWRkaW5nCml0IGxhdGVyIG9uIGluIGEgYmFja3dhcmRzIGNv bXBhdGlibGUgd2F5LiBQcm9wZXJ0aWVzIGFyZSByYXRoZXIgbmljZSB0aGlzCndheSA6LSkKLURh bmllbAotLSAKRGFuaWVsIFZldHRlcgpTb2Z0d2FyZSBFbmdpbmVlciwgSW50ZWwgQ29ycG9yYXRp b24KaHR0cDovL2Jsb2cuZmZ3bGwuY2gKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX18KSW50ZWwtZ2Z4IG1haWxpbmcgbGlzdApJbnRlbC1nZnhAbGlzdHMuZnJl ZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGlu Zm8vaW50ZWwtZ2Z4Cg==