From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from perceval.ideasonboard.com ([213.167.242.64]:40716 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1031950AbeEZQSb (ORCPT ); Sat, 26 May 2018 12:18:31 -0400 From: Laurent Pinchart To: Dmitry Osipenko Cc: Laurent Pinchart , Ville =?ISO-8859-1?Q?Syrj=E4l=E4?= , Thierry Reding , Neil Armstrong , Maxime Ripard , dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Alexandru Gheorghe , Russell King , Ben Skeggs , Sinclair Yeh , Thomas Hellstrom , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [RFC PATCH v2 1/2] drm: Add generic colorkey properties Date: Sat, 26 May 2018 19:18:28 +0300 Message-ID: <1762515.PDM3oOmb9k@avalon> In-Reply-To: <4468833.XY6THhPN9R@avalon> References: <20180526155623.12610-1-digetx@gmail.com> <20180526155623.12610-2-digetx@gmail.com> <4468833.XY6THhPN9R@avalon> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Sender: linux-renesas-soc-owner@vger.kernel.org List-ID: On Saturday, 26 May 2018 19:16:54 EEST Laurent Pinchart wrote: > Hi Dimitri, And sorry for the spelling mistake :-/ > Thank you for the patch. > > I'll review this in details, but as this patch is based on the "[PATCH/RFC > 1/4] drm: Add colorkey properties" patch I've submitted, please retain the > authorship, both in the Signed-off-by line, and in the patch author in git. > > On Saturday, 26 May 2018 18:56:22 EEST Dmitry Osipenko wrote: > > Color keying is the action of replacing pixels matching a given color > > (or range of colors) with transparent pixels in an overlay when > > performing blitting. Depending on the hardware capabilities, the > > matching pixel can either become fully transparent or gain adjustment > > of the pixels component values. > > > > Color keying is found in a large number of devices whose capabilities > > often differ, but they still have enough common features in range to > > standardize color key properties. This commit adds nine generic DRM plane > > properties related to the color keying to cover various HW capabilities. > > > > This patch is based on the initial work done by Laurent Pinchart, most of > > credits for this patch goes to him. > > > > Signed-off-by: Dmitry Osipenko > > --- > > > > drivers/gpu/drm/drm_atomic.c | 36 ++++++ > > drivers/gpu/drm/drm_blend.c | 229 +++++++++++++++++++++++++++++++++++ > > include/drm/drm_blend.h | 3 + > > include/drm/drm_plane.h | 77 ++++++++++++ > > 4 files changed, 345 insertions(+) > > > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > > index 895741e9cd7d..5b808cb68654 100644 > > --- a/drivers/gpu/drm/drm_atomic.c > > +++ b/drivers/gpu/drm/drm_atomic.c > > @@ -799,6 +799,24 @@ static int drm_atomic_plane_set_property(struct > > drm_plane *plane, state->rotation = val; > > > > } else if (property == plane->zpos_property) { > > > > state->zpos = val; > > > > + } else if (property == plane->colorkey.mode_property) { > > + state->colorkey.mode = val; > > + } else if (property == plane->colorkey.min_property) { > > + state->colorkey.min = val; > > + } else if (property == plane->colorkey.max_property) { > > + state->colorkey.max = val; > > + } else if (property == plane->colorkey.format_property) { > > + state->colorkey.format = val; > > + } else if (property == plane->colorkey.mask_property) { > > + state->colorkey.mask = val; > > + } else if (property == plane->colorkey.inverted_match_property) { > > + state->colorkey.inverted_match = val; > > + } else if (property == plane->colorkey.replacement_mask_property) { > > + state->colorkey.replacement_mask = val; > > + } else if (property == plane->colorkey.replacement_value_property) { > > + state->colorkey.replacement_value = val; > > + } else if (property == plane->colorkey.replacement_format_property) { > > + state->colorkey.replacement_format = val; > > > > } else if (property == plane->color_encoding_property) { > > > > state->color_encoding = val; > > > > } else if (property == plane->color_range_property) { > > > > @@ -864,6 +882,24 @@ drm_atomic_plane_get_property(struct drm_plane > > *plane, > > > > *val = state->rotation; > > > > } else if (property == plane->zpos_property) { > > > > *val = state->zpos; > > > > + } else if (property == plane->colorkey.mode_property) { > > + *val = state->colorkey.mode; > > + } else if (property == plane->colorkey.min_property) { > > + *val = state->colorkey.min; > > + } else if (property == plane->colorkey.max_property) { > > + *val = state->colorkey.max; > > + } else if (property == plane->colorkey.format_property) { > > + *val = state->colorkey.format; > > + } else if (property == plane->colorkey.mask_property) { > > + *val = state->colorkey.mask; > > + } else if (property == plane->colorkey.inverted_match_property) { > > + *val = state->colorkey.inverted_match; > > + } else if (property == plane->colorkey.replacement_mask_property) { > > + *val = state->colorkey.replacement_mask; > > + } else if (property == plane->colorkey.replacement_value_property) { > > + *val = state->colorkey.replacement_value; > > + } else if (property == plane->colorkey.replacement_format_property) { > > + *val = state->colorkey.replacement_format; > > > > } else if (property == plane->color_encoding_property) { > > > > *val = state->color_encoding; > > > > } else if (property == plane->color_range_property) { > > > > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c > > index a16a74d7e15e..05e5632ce375 100644 > > --- a/drivers/gpu/drm/drm_blend.c > > +++ b/drivers/gpu/drm/drm_blend.c > > @@ -107,6 +107,11 @@ > > > > * planes. Without this property the primary plane is always below the > > > > cursor * plane, and ordering between all other planes is undefined. > > > > * > > > > + * colorkey: > > + * Color keying is set up with drm_plane_create_colorkey_properties(). > > + * It adds support for replacing a range of colors with a transparent > > + * color in the plane. > > + * > > > > * Note that all the property extensions described here apply either to > > the > > > > * plane or the CRTC (e.g. for the background color, which currently is not > > * exposed and assumed to be black). > > @@ -448,3 +453,227 @@ int drm_atomic_normalize_zpos(struct drm_device > > *dev, > > > > return 0; > > > > } > > EXPORT_SYMBOL(drm_atomic_normalize_zpos); > > > > + > > +static const char * const plane_colorkey_mode_name[] = { > > + [DRM_PLANE_COLORKEY_MODE_DISABLED] = "disabled", > > + [DRM_PLANE_COLORKEY_MODE_SRC] = "src-match-src-replace", > > + [DRM_PLANE_COLORKEY_MODE_DST] = "dst-match-src-replace", > > +}; > > + > > +/** > > + * drm_plane_create_colorkey_properties - create colorkey properties > > + * @plane: drm plane > > + * @supported_modes: bitmask of supported color keying modes > > + * > > + * This function creates the generic color keying properties and attach > > them to + * the plane to enable color keying control for blending > > operations. + * > > + * Color keying is controlled through nine properties: > > + * > > + * colorkey.mode: > > + * The mode is an enumerated property that controls how color keying > > + * operates. The "disabled" mode that disables color keying and is > > + * very likely to exist if color keying is supported, it should be the > > + * default mode. > > + * > > + * colorkey.min, colorkey.max: > > + * These two properties specify the colors that are treated as the color > > + * key. Pixel whose value is in the [min, max] range is the color key > > + * matching pixel. The minimum and maximum values are expressed as a > > + * 64-bit integer in AXYZ16161616 format, where A is the alpha value and > > + * X, Y and Z correspond to the color components of the colorkey.format. > > + * In most cases XYZ will be either RGB or YUV. > > + * > > + * When a single color key is desired instead of a range, userspace shall > > + * set the min and max properties to the same value. > > + * > > + * Drivers return an error from their plane atomic check if range can't > > be > > + * handled. > > + * > > + * colorkey.format: > > + * This property specifies the pixel format for the colorkey.min / max > > + * properties. The format is given in a form of DRM fourcc code. > > + * > > + * Drivers return an error from their plane atomic check if pixel format > > + * is unsupported. > > + * > > + * colorkey.mask: > > + * This property specifies the pixel components mask. Unmasked pixel > > + * components are not participating in the matching. This mask value is > > + * applied to colorkey.min / max values. The mask value is given in a > > + * form of DRM fourcc code corresponding to the colorkey.format property. > > + * > > + * For example: userspace shall set the colorkey.mask to 0x0000ff00 > > + * to match only the green component if colorkey.format is set to > > + * DRM_FORMAT_XRGB8888. > > + * > > + * Drivers return an error from their plane atomic check if mask value > > + * can't be handled. > > + * > > + * colorkey.inverted-match: > > + * This property specifies whether the matching min-max range should > > + * be inverted, i.e. pixels outside of the given color range become > > + * the color key match. > > + * > > + * Drivers return an error from their plane atomic check if inversion > > + * mode can't be handled. > > + * > > + * colorkey.replacement-value: > > + * This property specifies the color value that replaces pixels matching > > + * the color key. The value is expressed in AXYZ16161616 format, where A > > + * is the alpha value and X, Y and Z correspond to the color components > > + * of the colorkey.replacement-format. > > + * > > + * Drivers return an error from their plane atomic check if replacement > > + * value can't be handled. > > + * > > + * colorkey.replacement-format: > > + * This property specifies the pixel format for the > > + * colorkey.replacement-value property. The format is given in a form of > > + * DRM fourcc code. > > + * > > + * Drivers return an error from their plane atomic check if replacement > > + * pixel format is unsupported. > > + * > > + * colorkey.replacement-mask: > > + * This property specifies the pixel components mask that defines > > + * what components of the colorkey.replacement-value will participate in > > + * replacement of the pixels color. Unmasked pixel components are not > > + * participating in the replacement. The mask value is given in a form of > > + * DRM fourcc code corresponding to the colorkey.replacement-format > > + * property. > > + * > > + * For example: userspace shall set the colorkey.replacement-mask to > > + * 0x0000ff00 to replace only the green component if > > + * colorkey.replacement-format is set to DRM_FORMAT_XRGB8888. > > + * > > + * Userspace shall set colorkey.replacement-mask to 0 to disable the > > color > > + * replacement. In this case matching pixels become transparent. > > + * > > + * Drivers return an error from their plane atomic check if replacement > > + * mask value can't be handled. > > + * > > + * Returns: > > + * Zero on success, negative errno on failure. > > + */ > > +int drm_plane_create_colorkey_properties(struct drm_plane *plane, > > + u32 supported_modes) > > +{ > > + struct drm_prop_enum_list modes_list[DRM_PLANE_COLORKEY_MODES_NUM]; > > + struct drm_property *replacement_format_prop; > > + struct drm_property *replacement_value_prop; > > + struct drm_property *replacement_mask_prop; > > + struct drm_property *inverted_match_prop; > > + struct drm_property *format_prop; > > + struct drm_property *mask_prop; > > + struct drm_property *mode_prop; > > + struct drm_property *min_prop; > > + struct drm_property *max_prop; > > + unsigned int modes_num = 0; > > + unsigned int i; > > + > > + /* at least two modes should be supported */ > > + if (!supported_modes) > > + return -EINVAL; > > + > > + /* modes are driver-specific, build the list of supported modes */ > > + for (i = 0; i < DRM_PLANE_COLORKEY_MODES_NUM; i++) { > > + if (!(supported_modes & BIT(i))) > > + continue; > > + > > + modes_list[modes_num].name = plane_colorkey_mode_name[i]; > > + modes_list[modes_num].type = i; > > + modes_num++; > > + } > > + > > + mode_prop = drm_property_create_enum(plane->dev, 0, "colorkey.mode", > > + modes_list, modes_num); > > + if (!mode_prop) > > + return -ENOMEM; > > + > > + mask_prop = drm_property_create_range(plane->dev, 0, "colorkey.mask", > > + 0, U64_MAX); > > + if (!mask_prop) > > + goto err_destroy_mode_prop; > > + > > + min_prop = drm_property_create_range(plane->dev, 0, "colorkey.min", > > + 0, U64_MAX); > > + if (!min_prop) > > + goto err_destroy_mask_prop; > > + > > + max_prop = drm_property_create_range(plane->dev, 0, "colorkey.max", > > + 0, U64_MAX); > > + if (!max_prop) > > + goto err_destroy_min_prop; > > + > > + format_prop = drm_property_create_range(plane->dev, 0, > > + "colorkey.format", > > + 0, U32_MAX); > > + if (!format_prop) > > + goto err_destroy_max_prop; > > + > > + inverted_match_prop = drm_property_create_bool(plane->dev, 0, > > + "colorkey.inverted-match"); > > + if (!inverted_match_prop) > > + goto err_destroy_format_prop; > > + > > + replacement_mask_prop = drm_property_create_range(plane->dev, 0, > > + "colorkey.replacement-mask", > > + 0, U64_MAX); > > + if (!replacement_mask_prop) > > + goto err_destroy_inverted_match_prop; > > + > > + replacement_value_prop = drm_property_create_range(plane->dev, 0, > > + "colorkey.replacement-value", > > + 0, U64_MAX); > > + if (!replacement_value_prop) > > + goto err_destroy_replacement_mask_prop; > > + > > + replacement_format_prop = drm_property_create_range(plane->dev, 0, > > + "colorkey.replacement-format", > > + 0, U64_MAX); > > + if (!replacement_format_prop) > > + goto err_destroy_replacement_value_prop; > > + > > + drm_object_attach_property(&plane->base, min_prop, 0); > > + drm_object_attach_property(&plane->base, max_prop, 0); > > + drm_object_attach_property(&plane->base, mode_prop, 0); > > + drm_object_attach_property(&plane->base, mask_prop, 0); > > + drm_object_attach_property(&plane->base, format_prop, 0); > > + drm_object_attach_property(&plane->base, inverted_match_prop, 0); > > + drm_object_attach_property(&plane->base, replacement_mask_prop, 0); > > + drm_object_attach_property(&plane->base, replacement_value_prop, 0); > > + drm_object_attach_property(&plane->base, replacement_format_prop, 0); > > + > > + plane->colorkey.min_property = min_prop; > > + plane->colorkey.max_property = max_prop; > > + plane->colorkey.mode_property = mode_prop; > > + plane->colorkey.mask_property = mask_prop; > > + plane->colorkey.format_property = format_prop; > > + plane->colorkey.inverted_match_property = inverted_match_prop; > > + plane->colorkey.replacement_mask_property = replacement_mask_prop; > > + plane->colorkey.replacement_value_property = replacement_value_prop; > > + plane->colorkey.replacement_format_property = replacement_format_prop; > > + > > + return 0; > > + > > +err_destroy_replacement_value_prop: > > + drm_property_destroy(plane->dev, replacement_value_prop); > > +err_destroy_replacement_mask_prop: > > + drm_property_destroy(plane->dev, replacement_mask_prop); > > +err_destroy_inverted_match_prop: > > + drm_property_destroy(plane->dev, inverted_match_prop); > > +err_destroy_format_prop: > > + drm_property_destroy(plane->dev, format_prop); > > +err_destroy_max_prop: > > + drm_property_destroy(plane->dev, max_prop); > > +err_destroy_min_prop: > > + drm_property_destroy(plane->dev, min_prop); > > +err_destroy_mask_prop: > > + drm_property_destroy(plane->dev, mask_prop); > > +err_destroy_mode_prop: > > + drm_property_destroy(plane->dev, mode_prop); > > + > > + return -ENOMEM; > > +} > > +EXPORT_SYMBOL(drm_plane_create_colorkey_properties); > > diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h > > index 330c561c4c11..8e80d33b643e 100644 > > --- a/include/drm/drm_blend.h > > +++ b/include/drm/drm_blend.h > > @@ -52,4 +52,7 @@ int drm_plane_create_zpos_immutable_property(struct > > drm_plane *plane, unsigned int zpos); > > > > int drm_atomic_normalize_zpos(struct drm_device *dev, > > > > struct drm_atomic_state *state); > > > > + > > +int drm_plane_create_colorkey_properties(struct drm_plane *plane, > > + u32 supported_modes); > > > > #endif > > > > diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h > > index 26fa50c2a50e..ff7f5ebe2b79 100644 > > --- a/include/drm/drm_plane.h > > +++ b/include/drm/drm_plane.h > > @@ -32,6 +32,42 @@ struct drm_crtc; > > > > struct drm_printer; > > struct drm_modeset_acquire_ctx; > > > > +/** > > + * enum drm_plane_colorkey_mode - uapi plane colorkey mode enumeration > > + */ > > +enum drm_plane_colorkey_mode { > > + /** > > + * @DRM_PLANE_COLORKEY_MODE_DISABLED: > > + * > > + * No color matching performed in this mode. This is the default > > + * common mode. > > + */ > > + DRM_PLANE_COLORKEY_MODE_DISABLED, > > + > > + /** > > + * @DRM_PLANE_COLORKEY_MODE_SRC: > > + * > > + * In this mode color matching is performed with the pixels of > > + * the given plane and the matched pixels are fully (or partially) > > + * replaced with the replacement color or become completely > > + * transparent. > > + */ > > + DRM_PLANE_COLORKEY_MODE_SRC, > > + > > + /** > > + * @DRM_PLANE_COLORKEY_MODE_DST: > > + * > > + * In this mode color matching is performed with the pixels of the > > + * planes z-positioned under the given plane and the pixels of the > > + * hovering plane that are xy-positioned as the underlying > > + * color-matched pixels are fully (or partially) replaced with the > > + * replacement color or become completely transparent. > > + */ > > + DRM_PLANE_COLORKEY_MODE_DST, > > + > > + DRM_PLANE_COLORKEY_MODES_NUM, > > +}; > > + > > > > /** > > > > * struct drm_plane_state - mutable plane state > > * @plane: backpointer to the plane > > > > @@ -54,6 +90,21 @@ struct drm_modeset_acquire_ctx; > > > > * where N is the number of active planes for given crtc. Note that > > * the driver must set drm_mode_config.normalize_zpos or call > > * drm_atomic_normalize_zpos() to update this before it can be trusted. > > > > + * @colorkey.mode: color key mode > > + * @colorkey.min: color key range minimum. The value is stored in > > AXYZ16161616 + * format, where A is the alpha value and X, Y and Z > > correspond to the + * color components of the plane's pixel format > > (usually > > RGB or YUV) + * @colorkey.max: color key range maximum (in AXYZ16161616 > > format) + * @colorkey.mask: color key mask value (in AXYZ16161616 format) > > + * @colorkey.format: color key min/max/mask values pixel format (in > > + * DRM_FORMAT_AXYZ16161616 form) > > + * @colorkey.inverted_match: color key min-max matching range is inverted > > + * @colorkey.replacement_mask: color key replacement mask value (in > > + * AXYZ16161616 format) > > + * @colorkey.replacement_value: color key replacement value (in > > + * AXYZ16161616 format) > > + * @colorkey.replacement_format: color key replacement value / mask > > + * pixel format (in DRM_FORMAT_AXYZ16161616 form) > > > > * @src: clipped source coordinates of the plane (in 16.16) > > * @dst: clipped destination coordinates of the plane > > * @state: backpointer to global drm_atomic_state > > > > @@ -124,6 +175,19 @@ struct drm_plane_state { > > > > unsigned int zpos; > > unsigned int normalized_zpos; > > > > + /* Plane colorkey */ > > + struct { > > + enum drm_plane_colorkey_mode mode; > > + u64 min; > > + u64 max; > > + u64 mask; > > + u32 format; > > + bool inverted_match; > > + u64 replacement_mask; > > + u64 replacement_value; > > + u32 replacement_format; > > + } colorkey; > > + > > > > /** > > > > * @color_encoding: > > * > > > > @@ -510,6 +574,7 @@ enum drm_plane_type { > > > > * @alpha_property: alpha property for this plane > > * @zpos_property: zpos property for this plane > > * @rotation_property: rotation property for this plane > > > > + * @colorkey: colorkey properties for this plane > > > > * @helper_private: mid-layer private data > > */ > > > > struct drm_plane { > > > > @@ -587,6 +652,18 @@ struct drm_plane { > > > > struct drm_property *zpos_property; > > struct drm_property *rotation_property; > > > > + struct { > > + struct drm_property *min_property; > > + struct drm_property *max_property; > > + struct drm_property *mode_property; > > + struct drm_property *mask_property; > > + struct drm_property *format_property; > > + struct drm_property *inverted_match_property; > > + struct drm_property *replacement_mask_property; > > + struct drm_property *replacement_value_property; > > + struct drm_property *replacement_format_property; > > + } colorkey; > > + > > > > /** > > > > * @color_encoding_property: > > * -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: Re: [RFC PATCH v2 1/2] drm: Add generic colorkey properties Date: Sat, 26 May 2018 19:18:28 +0300 Message-ID: <1762515.PDM3oOmb9k@avalon> References: <20180526155623.12610-1-digetx@gmail.com> <20180526155623.12610-2-digetx@gmail.com> <4468833.XY6THhPN9R@avalon> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <4468833.XY6THhPN9R@avalon> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Dmitry Osipenko Cc: Thomas Hellstrom , Laurent Pinchart , Neil Armstrong , Russell King , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-tegra@vger.kernel.org, Thierry Reding , Ben Skeggs , Rodrigo Vivi , Maxime Ripard , Alexandru Gheorghe , linux-media@vger.kernel.org List-Id: linux-tegra@vger.kernel.org T24gU2F0dXJkYXksIDI2IE1heSAyMDE4IDE5OjE2OjU0IEVFU1QgTGF1cmVudCBQaW5jaGFydCB3 cm90ZToKPiBIaSBEaW1pdHJpLAoKQW5kIHNvcnJ5IGZvciB0aGUgc3BlbGxpbmcgbWlzdGFrZSA6 LS8KCj4gVGhhbmsgeW91IGZvciB0aGUgcGF0Y2guCj4gCj4gSSdsbCByZXZpZXcgdGhpcyBpbiBk ZXRhaWxzLCBidXQgYXMgdGhpcyBwYXRjaCBpcyBiYXNlZCBvbiB0aGUgIltQQVRDSC9SRkMKPiAx LzRdIGRybTogQWRkIGNvbG9ya2V5IHByb3BlcnRpZXMiIHBhdGNoIEkndmUgc3VibWl0dGVkLCBw bGVhc2UgcmV0YWluIHRoZQo+IGF1dGhvcnNoaXAsIGJvdGggaW4gdGhlIFNpZ25lZC1vZmYtYnkg bGluZSwgYW5kIGluIHRoZSBwYXRjaCBhdXRob3IgaW4gZ2l0Lgo+IAo+IE9uIFNhdHVyZGF5LCAy NiBNYXkgMjAxOCAxODo1NjoyMiBFRVNUIERtaXRyeSBPc2lwZW5rbyB3cm90ZToKPiA+IENvbG9y IGtleWluZyBpcyB0aGUgYWN0aW9uIG9mIHJlcGxhY2luZyBwaXhlbHMgbWF0Y2hpbmcgYSBnaXZl biBjb2xvcgo+ID4gKG9yIHJhbmdlIG9mIGNvbG9ycykgd2l0aCB0cmFuc3BhcmVudCBwaXhlbHMg aW4gYW4gb3ZlcmxheSB3aGVuCj4gPiBwZXJmb3JtaW5nIGJsaXR0aW5nLiBEZXBlbmRpbmcgb24g dGhlIGhhcmR3YXJlIGNhcGFiaWxpdGllcywgdGhlCj4gPiBtYXRjaGluZyBwaXhlbCBjYW4gZWl0 aGVyIGJlY29tZSBmdWxseSB0cmFuc3BhcmVudCBvciBnYWluIGFkanVzdG1lbnQKPiA+IG9mIHRo ZSBwaXhlbHMgY29tcG9uZW50IHZhbHVlcy4KPiA+IAo+ID4gQ29sb3Iga2V5aW5nIGlzIGZvdW5k IGluIGEgbGFyZ2UgbnVtYmVyIG9mIGRldmljZXMgd2hvc2UgY2FwYWJpbGl0aWVzCj4gPiBvZnRl biBkaWZmZXIsIGJ1dCB0aGV5IHN0aWxsIGhhdmUgZW5vdWdoIGNvbW1vbiBmZWF0dXJlcyBpbiBy YW5nZSB0bwo+ID4gc3RhbmRhcmRpemUgY29sb3Iga2V5IHByb3BlcnRpZXMuIFRoaXMgY29tbWl0 IGFkZHMgbmluZSBnZW5lcmljIERSTSBwbGFuZQo+ID4gcHJvcGVydGllcyByZWxhdGVkIHRvIHRo ZSBjb2xvciBrZXlpbmcgdG8gY292ZXIgdmFyaW91cyBIVyBjYXBhYmlsaXRpZXMuCj4gPiAKPiA+ IFRoaXMgcGF0Y2ggaXMgYmFzZWQgb24gdGhlIGluaXRpYWwgd29yayBkb25lIGJ5IExhdXJlbnQg UGluY2hhcnQsIG1vc3Qgb2YKPiA+IGNyZWRpdHMgZm9yIHRoaXMgcGF0Y2ggZ29lcyB0byBoaW0u Cj4gPiAKPiA+IFNpZ25lZC1vZmYtYnk6IERtaXRyeSBPc2lwZW5rbyA8ZGlnZXR4QGdtYWlsLmNv bT4KPiA+IC0tLQo+ID4gCj4gPiAgZHJpdmVycy9ncHUvZHJtL2RybV9hdG9taWMuYyB8ICAzNiAr KysrKysKPiA+ICBkcml2ZXJzL2dwdS9kcm0vZHJtX2JsZW5kLmMgIHwgMjI5ICsrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrCj4gPiAgaW5jbHVkZS9kcm0vZHJtX2JsZW5kLmggICAg ICB8ICAgMyArCj4gPiAgaW5jbHVkZS9kcm0vZHJtX3BsYW5lLmggICAgICB8ICA3NyArKysrKysr KysrKysKPiA+ICA0IGZpbGVzIGNoYW5nZWQsIDM0NSBpbnNlcnRpb25zKCspCj4gPiAKPiA+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vZHJtX2F0b21pYy5jIGIvZHJpdmVycy9ncHUvZHJt L2RybV9hdG9taWMuYwo+ID4gaW5kZXggODk1NzQxZTljZDdkLi41YjgwOGNiNjg2NTQgMTAwNjQ0 Cj4gPiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vZHJtX2F0b21pYy5jCj4gPiArKysgYi9kcml2ZXJz L2dwdS9kcm0vZHJtX2F0b21pYy5jCj4gPiBAQCAtNzk5LDYgKzc5OSwyNCBAQCBzdGF0aWMgaW50 IGRybV9hdG9taWNfcGxhbmVfc2V0X3Byb3BlcnR5KHN0cnVjdAo+ID4gZHJtX3BsYW5lICpwbGFu ZSwgc3RhdGUtPnJvdGF0aW9uID0gdmFsOwo+ID4gCj4gPiAgCX0gZWxzZSBpZiAocHJvcGVydHkg PT0gcGxhbmUtPnpwb3NfcHJvcGVydHkpIHsKPiA+ICAJCj4gPiAgCQlzdGF0ZS0+enBvcyA9IHZh bDsKPiA+IAo+ID4gKwl9IGVsc2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT5jb2xvcmtleS5tb2Rl X3Byb3BlcnR5KSB7Cj4gPiArCQlzdGF0ZS0+Y29sb3JrZXkubW9kZSA9IHZhbDsKPiA+ICsJfSBl bHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXkubWluX3Byb3BlcnR5KSB7Cj4gPiAr CQlzdGF0ZS0+Y29sb3JrZXkubWluID0gdmFsOwo+ID4gKwl9IGVsc2UgaWYgKHByb3BlcnR5ID09 IHBsYW5lLT5jb2xvcmtleS5tYXhfcHJvcGVydHkpIHsKPiA+ICsJCXN0YXRlLT5jb2xvcmtleS5t YXggPSB2YWw7Cj4gPiArCX0gZWxzZSBpZiAocHJvcGVydHkgPT0gcGxhbmUtPmNvbG9ya2V5LmZv cm1hdF9wcm9wZXJ0eSkgewo+ID4gKwkJc3RhdGUtPmNvbG9ya2V5LmZvcm1hdCA9IHZhbDsKPiA+ ICsJfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXkubWFza19wcm9wZXJ0eSkg ewo+ID4gKwkJc3RhdGUtPmNvbG9ya2V5Lm1hc2sgPSB2YWw7Cj4gPiArCX0gZWxzZSBpZiAocHJv cGVydHkgPT0gcGxhbmUtPmNvbG9ya2V5LmludmVydGVkX21hdGNoX3Byb3BlcnR5KSB7Cj4gPiAr CQlzdGF0ZS0+Y29sb3JrZXkuaW52ZXJ0ZWRfbWF0Y2ggPSB2YWw7Cj4gPiArCX0gZWxzZSBpZiAo cHJvcGVydHkgPT0gcGxhbmUtPmNvbG9ya2V5LnJlcGxhY2VtZW50X21hc2tfcHJvcGVydHkpIHsK PiA+ICsJCXN0YXRlLT5jb2xvcmtleS5yZXBsYWNlbWVudF9tYXNrID0gdmFsOwo+ID4gKwl9IGVs c2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT5jb2xvcmtleS5yZXBsYWNlbWVudF92YWx1ZV9wcm9w ZXJ0eSkgewo+ID4gKwkJc3RhdGUtPmNvbG9ya2V5LnJlcGxhY2VtZW50X3ZhbHVlID0gdmFsOwo+ ID4gKwl9IGVsc2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT5jb2xvcmtleS5yZXBsYWNlbWVudF9m b3JtYXRfcHJvcGVydHkpIHsKPiA+ICsJCXN0YXRlLT5jb2xvcmtleS5yZXBsYWNlbWVudF9mb3Jt YXQgPSB2YWw7Cj4gPiAKPiA+ICAJfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29sb3Jf ZW5jb2RpbmdfcHJvcGVydHkpIHsKPiA+ICAJCj4gPiAgCQlzdGF0ZS0+Y29sb3JfZW5jb2Rpbmcg PSB2YWw7Cj4gPiAgCQo+ID4gIAl9IGVsc2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT5jb2xvcl9y YW5nZV9wcm9wZXJ0eSkgewo+ID4gCj4gPiBAQCAtODY0LDYgKzg4MiwyNCBAQCBkcm1fYXRvbWlj X3BsYW5lX2dldF9wcm9wZXJ0eShzdHJ1Y3QgZHJtX3BsYW5lCj4gPiAqcGxhbmUsCj4gPiAKPiA+ ICAJCSp2YWwgPSBzdGF0ZS0+cm90YXRpb247Cj4gPiAgCQo+ID4gIAl9IGVsc2UgaWYgKHByb3Bl cnR5ID09IHBsYW5lLT56cG9zX3Byb3BlcnR5KSB7Cj4gPiAgCQo+ID4gIAkJKnZhbCA9IHN0YXRl LT56cG9zOwo+ID4gCj4gPiArCX0gZWxzZSBpZiAocHJvcGVydHkgPT0gcGxhbmUtPmNvbG9ya2V5 Lm1vZGVfcHJvcGVydHkpIHsKPiA+ICsJCSp2YWwgPSBzdGF0ZS0+Y29sb3JrZXkubW9kZTsKPiA+ ICsJfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXkubWluX3Byb3BlcnR5KSB7 Cj4gPiArCQkqdmFsID0gc3RhdGUtPmNvbG9ya2V5Lm1pbjsKPiA+ICsJfSBlbHNlIGlmIChwcm9w ZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXkubWF4X3Byb3BlcnR5KSB7Cj4gPiArCQkqdmFsID0gc3Rh dGUtPmNvbG9ya2V5Lm1heDsKPiA+ICsJfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29s b3JrZXkuZm9ybWF0X3Byb3BlcnR5KSB7Cj4gPiArCQkqdmFsID0gc3RhdGUtPmNvbG9ya2V5LmZv cm1hdDsKPiA+ICsJfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXkubWFza19w cm9wZXJ0eSkgewo+ID4gKwkJKnZhbCA9IHN0YXRlLT5jb2xvcmtleS5tYXNrOwo+ID4gKwl9IGVs c2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT5jb2xvcmtleS5pbnZlcnRlZF9tYXRjaF9wcm9wZXJ0 eSkgewo+ID4gKwkJKnZhbCA9IHN0YXRlLT5jb2xvcmtleS5pbnZlcnRlZF9tYXRjaDsKPiA+ICsJ fSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXkucmVwbGFjZW1lbnRfbWFza19w cm9wZXJ0eSkgewo+ID4gKwkJKnZhbCA9IHN0YXRlLT5jb2xvcmtleS5yZXBsYWNlbWVudF9tYXNr Owo+ID4gKwl9IGVsc2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT5jb2xvcmtleS5yZXBsYWNlbWVu dF92YWx1ZV9wcm9wZXJ0eSkgewo+ID4gKwkJKnZhbCA9IHN0YXRlLT5jb2xvcmtleS5yZXBsYWNl bWVudF92YWx1ZTsKPiA+ICsJfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXku cmVwbGFjZW1lbnRfZm9ybWF0X3Byb3BlcnR5KSB7Cj4gPiArCQkqdmFsID0gc3RhdGUtPmNvbG9y a2V5LnJlcGxhY2VtZW50X2Zvcm1hdDsKPiA+IAo+ID4gIAl9IGVsc2UgaWYgKHByb3BlcnR5ID09 IHBsYW5lLT5jb2xvcl9lbmNvZGluZ19wcm9wZXJ0eSkgewo+ID4gIAkKPiA+ICAJCSp2YWwgPSBz dGF0ZS0+Y29sb3JfZW5jb2Rpbmc7Cj4gPiAgCQo+ID4gIAl9IGVsc2UgaWYgKHByb3BlcnR5ID09 IHBsYW5lLT5jb2xvcl9yYW5nZV9wcm9wZXJ0eSkgewo+ID4gCj4gPiBkaWZmIC0tZ2l0IGEvZHJp dmVycy9ncHUvZHJtL2RybV9ibGVuZC5jIGIvZHJpdmVycy9ncHUvZHJtL2RybV9ibGVuZC5jCj4g PiBpbmRleCBhMTZhNzRkN2UxNWUuLjA1ZTU2MzJjZTM3NSAxMDA2NDQKPiA+IC0tLSBhL2RyaXZl cnMvZ3B1L2RybS9kcm1fYmxlbmQuYwo+ID4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2RybV9ibGVu ZC5jCj4gPiBAQCAtMTA3LDYgKzEwNywxMSBAQAo+ID4gCj4gPiAgICoJcGxhbmVzLiBXaXRob3V0 IHRoaXMgcHJvcGVydHkgdGhlIHByaW1hcnkgcGxhbmUgaXMgYWx3YXlzIGJlbG93IHRoZQo+ID4g Cj4gPiBjdXJzb3IgKglwbGFuZSwgYW5kIG9yZGVyaW5nIGJldHdlZW4gYWxsIG90aGVyIHBsYW5l cyBpcyB1bmRlZmluZWQuCj4gPiAKPiA+ICAgKgo+ID4gCj4gPiArICogY29sb3JrZXk6Cj4gPiAr ICoJQ29sb3Iga2V5aW5nIGlzIHNldCB1cCB3aXRoIGRybV9wbGFuZV9jcmVhdGVfY29sb3JrZXlf cHJvcGVydGllcygpLgo+ID4gKyAqCUl0IGFkZHMgc3VwcG9ydCBmb3IgcmVwbGFjaW5nIGEgcmFu Z2Ugb2YgY29sb3JzIHdpdGggYSB0cmFuc3BhcmVudAo+ID4gKyAqCWNvbG9yIGluIHRoZSBwbGFu ZS4KPiA+ICsgKgo+ID4gCj4gPiAgICogTm90ZSB0aGF0IGFsbCB0aGUgcHJvcGVydHkgZXh0ZW5z aW9ucyBkZXNjcmliZWQgaGVyZSBhcHBseSBlaXRoZXIgdG8KPiA+ICAgdGhlCj4gPiAKPiA+ICog cGxhbmUgb3IgdGhlIENSVEMgKGUuZy4gZm9yIHRoZSBiYWNrZ3JvdW5kIGNvbG9yLCB3aGljaCBj dXJyZW50bHkgaXMgbm90Cj4gPiAqIGV4cG9zZWQgYW5kIGFzc3VtZWQgdG8gYmUgYmxhY2spLgo+ ID4gQEAgLTQ0OCwzICs0NTMsMjI3IEBAIGludCBkcm1fYXRvbWljX25vcm1hbGl6ZV96cG9zKHN0 cnVjdCBkcm1fZGV2aWNlCj4gPiAqZGV2LAo+ID4gCj4gPiAgCXJldHVybiAwOwo+ID4gIAo+ID4g IH0KPiA+ICBFWFBPUlRfU1lNQk9MKGRybV9hdG9taWNfbm9ybWFsaXplX3pwb3MpOwo+ID4gCj4g PiArCj4gPiArc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCBwbGFuZV9jb2xvcmtleV9tb2RlX25h bWVbXSA9IHsKPiA+ICsJW0RSTV9QTEFORV9DT0xPUktFWV9NT0RFX0RJU0FCTEVEXSA9ICJkaXNh YmxlZCIsCj4gPiArCVtEUk1fUExBTkVfQ09MT1JLRVlfTU9ERV9TUkNdID0gInNyYy1tYXRjaC1z cmMtcmVwbGFjZSIsCj4gPiArCVtEUk1fUExBTkVfQ09MT1JLRVlfTU9ERV9EU1RdID0gImRzdC1t YXRjaC1zcmMtcmVwbGFjZSIsCj4gPiArfTsKPiA+ICsKPiA+ICsvKioKPiA+ICsgKiBkcm1fcGxh bmVfY3JlYXRlX2NvbG9ya2V5X3Byb3BlcnRpZXMgLSBjcmVhdGUgY29sb3JrZXkgcHJvcGVydGll cwo+ID4gKyAqIEBwbGFuZTogZHJtIHBsYW5lCj4gPiArICogQHN1cHBvcnRlZF9tb2RlczogYml0 bWFzayBvZiBzdXBwb3J0ZWQgY29sb3Iga2V5aW5nIG1vZGVzCj4gPiArICoKPiA+ICsgKiBUaGlz IGZ1bmN0aW9uIGNyZWF0ZXMgdGhlIGdlbmVyaWMgY29sb3Iga2V5aW5nIHByb3BlcnRpZXMgYW5k IGF0dGFjaAo+ID4gdGhlbSB0byArICogdGhlIHBsYW5lIHRvIGVuYWJsZSBjb2xvciBrZXlpbmcg Y29udHJvbCBmb3IgYmxlbmRpbmcKPiA+IG9wZXJhdGlvbnMuICsgKgo+ID4gKyAqIENvbG9yIGtl eWluZyBpcyBjb250cm9sbGVkIHRocm91Z2ggbmluZSBwcm9wZXJ0aWVzOgo+ID4gKyAqCj4gPiAr ICogY29sb3JrZXkubW9kZToKPiA+ICsgKglUaGUgbW9kZSBpcyBhbiBlbnVtZXJhdGVkIHByb3Bl cnR5IHRoYXQgY29udHJvbHMgaG93IGNvbG9yIGtleWluZwo+ID4gKyAqCW9wZXJhdGVzLiBUaGUg ImRpc2FibGVkIiBtb2RlIHRoYXQgZGlzYWJsZXMgY29sb3Iga2V5aW5nIGFuZCBpcwo+ID4gKyAq CXZlcnkgbGlrZWx5IHRvIGV4aXN0IGlmIGNvbG9yIGtleWluZyBpcyBzdXBwb3J0ZWQsIGl0IHNo b3VsZCBiZSB0aGUKPiA+ICsgKglkZWZhdWx0IG1vZGUuCj4gPiArICoKPiA+ICsgKiBjb2xvcmtl eS5taW4sIGNvbG9ya2V5Lm1heDoKPiA+ICsgKglUaGVzZSB0d28gcHJvcGVydGllcyBzcGVjaWZ5 IHRoZSBjb2xvcnMgdGhhdCBhcmUgdHJlYXRlZCBhcyB0aGUgCmNvbG9yCj4gPiArICoJa2V5LiBQ aXhlbCB3aG9zZSB2YWx1ZSBpcyBpbiB0aGUgW21pbiwgbWF4XSByYW5nZSBpcyB0aGUgY29sb3Ig a2V5Cj4gPiArICoJbWF0Y2hpbmcgcGl4ZWwuIFRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVl cyBhcmUgZXhwcmVzc2VkIGFzIGEKPiA+ICsgKgk2NC1iaXQgaW50ZWdlciBpbiBBWFlaMTYxNjE2 MTYgZm9ybWF0LCB3aGVyZSBBIGlzIHRoZSBhbHBoYSB2YWx1ZSAKYW5kCj4gPiArICoJWCwgWSBh bmQgWiBjb3JyZXNwb25kIHRvIHRoZSBjb2xvciBjb21wb25lbnRzIG9mIHRoZSAKY29sb3JrZXku Zm9ybWF0Lgo+ID4gKyAqCUluIG1vc3QgY2FzZXMgWFlaIHdpbGwgYmUgZWl0aGVyIFJHQiBvciBZ VVYuCj4gPiArICoKPiA+ICsgKglXaGVuIGEgc2luZ2xlIGNvbG9yIGtleSBpcyBkZXNpcmVkIGlu c3RlYWQgb2YgYSByYW5nZSwgdXNlcnNwYWNlIApzaGFsbAo+ID4gKyAqCXNldCB0aGUgbWluIGFu ZCBtYXggcHJvcGVydGllcyB0byB0aGUgc2FtZSB2YWx1ZS4KPiA+ICsgKgo+ID4gKyAqCURyaXZl cnMgcmV0dXJuIGFuIGVycm9yIGZyb20gdGhlaXIgcGxhbmUgYXRvbWljIGNoZWNrIGlmIHJhbmdl IGNhbid0Cj4gPiBiZQo+ID4gKyAqCWhhbmRsZWQuCj4gPiArICoKPiA+ICsgKiBjb2xvcmtleS5m b3JtYXQ6Cj4gPiArICoJVGhpcyBwcm9wZXJ0eSBzcGVjaWZpZXMgdGhlIHBpeGVsIGZvcm1hdCBm b3IgdGhlIGNvbG9ya2V5Lm1pbiAvIG1heAo+ID4gKyAqCXByb3BlcnRpZXMuIFRoZSBmb3JtYXQg aXMgZ2l2ZW4gaW4gYSBmb3JtIG9mIERSTSBmb3VyY2MgY29kZS4KPiA+ICsgKgo+ID4gKyAqCURy aXZlcnMgcmV0dXJuIGFuIGVycm9yIGZyb20gdGhlaXIgcGxhbmUgYXRvbWljIGNoZWNrIGlmIHBp eGVsIApmb3JtYXQKPiA+ICsgKglpcyB1bnN1cHBvcnRlZC4KPiA+ICsgKgo+ID4gKyAqIGNvbG9y a2V5Lm1hc2s6Cj4gPiArICoJVGhpcyBwcm9wZXJ0eSBzcGVjaWZpZXMgdGhlIHBpeGVsIGNvbXBv bmVudHMgbWFzay4gVW5tYXNrZWQgcGl4ZWwKPiA+ICsgKgljb21wb25lbnRzIGFyZSBub3QgcGFy dGljaXBhdGluZyBpbiB0aGUgbWF0Y2hpbmcuIFRoaXMgbWFzayB2YWx1ZSBpcwo+ID4gKyAqCWFw cGxpZWQgdG8gY29sb3JrZXkubWluIC8gbWF4IHZhbHVlcy4gVGhlIG1hc2sgdmFsdWUgaXMgZ2l2 ZW4gaW4gYQo+ID4gKyAqCWZvcm0gb2YgRFJNIGZvdXJjYyBjb2RlIGNvcnJlc3BvbmRpbmcgdG8g dGhlIGNvbG9ya2V5LmZvcm1hdCAKcHJvcGVydHkuCj4gPiArICoKPiA+ICsgKglGb3IgZXhhbXBs ZTogdXNlcnNwYWNlIHNoYWxsIHNldCB0aGUgY29sb3JrZXkubWFzayB0byAweDAwMDBmZjAwCj4g PiArICoJdG8gbWF0Y2ggb25seSB0aGUgZ3JlZW4gY29tcG9uZW50IGlmIGNvbG9ya2V5LmZvcm1h dCBpcyBzZXQgdG8KPiA+ICsgKglEUk1fRk9STUFUX1hSR0I4ODg4Lgo+ID4gKyAqCj4gPiArICoJ RHJpdmVycyByZXR1cm4gYW4gZXJyb3IgZnJvbSB0aGVpciBwbGFuZSBhdG9taWMgY2hlY2sgaWYg bWFzayB2YWx1ZQo+ID4gKyAqCWNhbid0IGJlIGhhbmRsZWQuCj4gPiArICoKPiA+ICsgKiBjb2xv cmtleS5pbnZlcnRlZC1tYXRjaDoKPiA+ICsgKglUaGlzIHByb3BlcnR5IHNwZWNpZmllcyB3aGV0 aGVyIHRoZSBtYXRjaGluZyBtaW4tbWF4IHJhbmdlIHNob3VsZAo+ID4gKyAqCWJlIGludmVydGVk LCBpLmUuIHBpeGVscyBvdXRzaWRlIG9mIHRoZSBnaXZlbiBjb2xvciByYW5nZSBiZWNvbWUKPiA+ ICsgKgl0aGUgY29sb3Iga2V5IG1hdGNoLgo+ID4gKyAqCj4gPiArICoJRHJpdmVycyByZXR1cm4g YW4gZXJyb3IgZnJvbSB0aGVpciBwbGFuZSBhdG9taWMgY2hlY2sgaWYgaW52ZXJzaW9uCj4gPiAr ICoJbW9kZSBjYW4ndCBiZSBoYW5kbGVkLgo+ID4gKyAqCj4gPiArICogY29sb3JrZXkucmVwbGFj ZW1lbnQtdmFsdWU6Cj4gPiArICoJVGhpcyBwcm9wZXJ0eSBzcGVjaWZpZXMgdGhlIGNvbG9yIHZh bHVlIHRoYXQgcmVwbGFjZXMgcGl4ZWxzIAptYXRjaGluZwo+ID4gKyAqCXRoZSBjb2xvciBrZXku IFRoZSB2YWx1ZSBpcyBleHByZXNzZWQgaW4gQVhZWjE2MTYxNjE2IGZvcm1hdCwgd2hlcmUgCkEK PiA+ICsgKglpcyB0aGUgYWxwaGEgdmFsdWUgYW5kIFgsIFkgYW5kIFogY29ycmVzcG9uZCB0byB0 aGUgY29sb3IgY29tcG9uZW50cwo+ID4gKyAqCW9mIHRoZSBjb2xvcmtleS5yZXBsYWNlbWVudC1m b3JtYXQuCj4gPiArICoKPiA+ICsgKglEcml2ZXJzIHJldHVybiBhbiBlcnJvciBmcm9tIHRoZWly IHBsYW5lIGF0b21pYyBjaGVjayBpZiByZXBsYWNlbWVudAo+ID4gKyAqCXZhbHVlIGNhbid0IGJl IGhhbmRsZWQuCj4gPiArICoKPiA+ICsgKiBjb2xvcmtleS5yZXBsYWNlbWVudC1mb3JtYXQ6Cj4g PiArICoJVGhpcyBwcm9wZXJ0eSBzcGVjaWZpZXMgdGhlIHBpeGVsIGZvcm1hdCBmb3IgdGhlCj4g PiArICoJY29sb3JrZXkucmVwbGFjZW1lbnQtdmFsdWUgcHJvcGVydHkuIFRoZSBmb3JtYXQgaXMg Z2l2ZW4gaW4gYSBmb3JtIApvZgo+ID4gKyAqCURSTSBmb3VyY2MgY29kZS4KPiA+ICsgKgo+ID4g KyAqCURyaXZlcnMgcmV0dXJuIGFuIGVycm9yIGZyb20gdGhlaXIgcGxhbmUgYXRvbWljIGNoZWNr IGlmIHJlcGxhY2VtZW50Cj4gPiArICoJcGl4ZWwgZm9ybWF0IGlzIHVuc3VwcG9ydGVkLgo+ID4g KyAqCj4gPiArICogY29sb3JrZXkucmVwbGFjZW1lbnQtbWFzazoKPiA+ICsgKglUaGlzIHByb3Bl cnR5IHNwZWNpZmllcyB0aGUgcGl4ZWwgY29tcG9uZW50cyBtYXNrIHRoYXQgZGVmaW5lcwo+ID4g KyAqCXdoYXQgY29tcG9uZW50cyBvZiB0aGUgY29sb3JrZXkucmVwbGFjZW1lbnQtdmFsdWUgd2ls bCBwYXJ0aWNpcGF0ZSAKaW4KPiA+ICsgKglyZXBsYWNlbWVudCBvZiB0aGUgcGl4ZWxzIGNvbG9y LiBVbm1hc2tlZCBwaXhlbCBjb21wb25lbnRzIGFyZSBub3QKPiA+ICsgKglwYXJ0aWNpcGF0aW5n IGluIHRoZSByZXBsYWNlbWVudC4gVGhlIG1hc2sgdmFsdWUgaXMgZ2l2ZW4gaW4gYSBmb3JtIApv Zgo+ID4gKyAqCURSTSBmb3VyY2MgY29kZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBjb2xvcmtleS5y ZXBsYWNlbWVudC1mb3JtYXQKPiA+ICsgKglwcm9wZXJ0eS4KPiA+ICsgKgo+ID4gKyAqCUZvciBl eGFtcGxlOiB1c2Vyc3BhY2Ugc2hhbGwgc2V0IHRoZSBjb2xvcmtleS5yZXBsYWNlbWVudC1tYXNr IHRvCj4gPiArICoJMHgwMDAwZmYwMCB0byByZXBsYWNlIG9ubHkgdGhlIGdyZWVuIGNvbXBvbmVu dCBpZgo+ID4gKyAqCWNvbG9ya2V5LnJlcGxhY2VtZW50LWZvcm1hdCBpcyBzZXQgdG8gRFJNX0ZP Uk1BVF9YUkdCODg4OC4KPiA+ICsgKgo+ID4gKyAqCVVzZXJzcGFjZSBzaGFsbCBzZXQgY29sb3Jr ZXkucmVwbGFjZW1lbnQtbWFzayB0byAwIHRvIGRpc2FibGUgdGhlCj4gPiBjb2xvcgo+ID4gKyAq CXJlcGxhY2VtZW50LiBJbiB0aGlzIGNhc2UgbWF0Y2hpbmcgcGl4ZWxzIGJlY29tZSB0cmFuc3Bh cmVudC4KPiA+ICsgKgo+ID4gKyAqCURyaXZlcnMgcmV0dXJuIGFuIGVycm9yIGZyb20gdGhlaXIg cGxhbmUgYXRvbWljIGNoZWNrIGlmIHJlcGxhY2VtZW50Cj4gPiArICoJbWFzayB2YWx1ZSBjYW4n dCBiZSBoYW5kbGVkLgo+ID4gKyAqCj4gPiArICogUmV0dXJuczoKPiA+ICsgKiBaZXJvIG9uIHN1 Y2Nlc3MsIG5lZ2F0aXZlIGVycm5vIG9uIGZhaWx1cmUuCj4gPiArICovCj4gPiAraW50IGRybV9w bGFuZV9jcmVhdGVfY29sb3JrZXlfcHJvcGVydGllcyhzdHJ1Y3QgZHJtX3BsYW5lICpwbGFuZSwK PiA+ICsJCQkJCSB1MzIgc3VwcG9ydGVkX21vZGVzKQo+ID4gK3sKPiA+ICsJc3RydWN0IGRybV9w cm9wX2VudW1fbGlzdCBtb2Rlc19saXN0W0RSTV9QTEFORV9DT0xPUktFWV9NT0RFU19OVU1dOwo+ ID4gKwlzdHJ1Y3QgZHJtX3Byb3BlcnR5ICpyZXBsYWNlbWVudF9mb3JtYXRfcHJvcDsKPiA+ICsJ c3RydWN0IGRybV9wcm9wZXJ0eSAqcmVwbGFjZW1lbnRfdmFsdWVfcHJvcDsKPiA+ICsJc3RydWN0 IGRybV9wcm9wZXJ0eSAqcmVwbGFjZW1lbnRfbWFza19wcm9wOwo+ID4gKwlzdHJ1Y3QgZHJtX3By b3BlcnR5ICppbnZlcnRlZF9tYXRjaF9wcm9wOwo+ID4gKwlzdHJ1Y3QgZHJtX3Byb3BlcnR5ICpm b3JtYXRfcHJvcDsKPiA+ICsJc3RydWN0IGRybV9wcm9wZXJ0eSAqbWFza19wcm9wOwo+ID4gKwlz dHJ1Y3QgZHJtX3Byb3BlcnR5ICptb2RlX3Byb3A7Cj4gPiArCXN0cnVjdCBkcm1fcHJvcGVydHkg Km1pbl9wcm9wOwo+ID4gKwlzdHJ1Y3QgZHJtX3Byb3BlcnR5ICptYXhfcHJvcDsKPiA+ICsJdW5z aWduZWQgaW50IG1vZGVzX251bSA9IDA7Cj4gPiArCXVuc2lnbmVkIGludCBpOwo+ID4gKwo+ID4g KwkvKiBhdCBsZWFzdCB0d28gbW9kZXMgc2hvdWxkIGJlIHN1cHBvcnRlZCAqLwo+ID4gKwlpZiAo IXN1cHBvcnRlZF9tb2RlcykKPiA+ICsJCXJldHVybiAtRUlOVkFMOwo+ID4gKwo+ID4gKwkvKiBt b2RlcyBhcmUgZHJpdmVyLXNwZWNpZmljLCBidWlsZCB0aGUgbGlzdCBvZiBzdXBwb3J0ZWQgbW9k ZXMgKi8KPiA+ICsJZm9yIChpID0gMDsgaSA8IERSTV9QTEFORV9DT0xPUktFWV9NT0RFU19OVU07 IGkrKykgewo+ID4gKwkJaWYgKCEoc3VwcG9ydGVkX21vZGVzICYgQklUKGkpKSkKPiA+ICsJCQlj b250aW51ZTsKPiA+ICsKPiA+ICsJCW1vZGVzX2xpc3RbbW9kZXNfbnVtXS5uYW1lID0gcGxhbmVf Y29sb3JrZXlfbW9kZV9uYW1lW2ldOwo+ID4gKwkJbW9kZXNfbGlzdFttb2Rlc19udW1dLnR5cGUg PSBpOwo+ID4gKwkJbW9kZXNfbnVtKys7Cj4gPiArCX0KPiA+ICsKPiA+ICsJbW9kZV9wcm9wID0g ZHJtX3Byb3BlcnR5X2NyZWF0ZV9lbnVtKHBsYW5lLT5kZXYsIDAsICJjb2xvcmtleS5tb2RlIiwK PiA+ICsJCQkJCSAgICAgbW9kZXNfbGlzdCwgbW9kZXNfbnVtKTsKPiA+ICsJaWYgKCFtb2RlX3By b3ApCj4gPiArCQlyZXR1cm4gLUVOT01FTTsKPiA+ICsKPiA+ICsJbWFza19wcm9wID0gZHJtX3By b3BlcnR5X2NyZWF0ZV9yYW5nZShwbGFuZS0+ZGV2LCAwLCAiY29sb3JrZXkubWFzayIsCj4gPiAr CQkJCQkgICAgICAwLCBVNjRfTUFYKTsKPiA+ICsJaWYgKCFtYXNrX3Byb3ApCj4gPiArCQlnb3Rv IGVycl9kZXN0cm95X21vZGVfcHJvcDsKPiA+ICsKPiA+ICsJbWluX3Byb3AgPSBkcm1fcHJvcGVy dHlfY3JlYXRlX3JhbmdlKHBsYW5lLT5kZXYsIDAsICJjb2xvcmtleS5taW4iLAo+ID4gKwkJCQkJ ICAgICAwLCBVNjRfTUFYKTsKPiA+ICsJaWYgKCFtaW5fcHJvcCkKPiA+ICsJCWdvdG8gZXJyX2Rl c3Ryb3lfbWFza19wcm9wOwo+ID4gKwo+ID4gKwltYXhfcHJvcCA9IGRybV9wcm9wZXJ0eV9jcmVh dGVfcmFuZ2UocGxhbmUtPmRldiwgMCwgImNvbG9ya2V5Lm1heCIsCj4gPiArCQkJCQkgICAgIDAs IFU2NF9NQVgpOwo+ID4gKwlpZiAoIW1heF9wcm9wKQo+ID4gKwkJZ290byBlcnJfZGVzdHJveV9t aW5fcHJvcDsKPiA+ICsKPiA+ICsJZm9ybWF0X3Byb3AgPSBkcm1fcHJvcGVydHlfY3JlYXRlX3Jh bmdlKHBsYW5lLT5kZXYsIDAsCj4gPiArCQkJCQkiY29sb3JrZXkuZm9ybWF0IiwKPiA+ICsJCQkJ CTAsIFUzMl9NQVgpOwo+ID4gKwlpZiAoIWZvcm1hdF9wcm9wKQo+ID4gKwkJZ290byBlcnJfZGVz dHJveV9tYXhfcHJvcDsKPiA+ICsKPiA+ICsJaW52ZXJ0ZWRfbWF0Y2hfcHJvcCA9IGRybV9wcm9w ZXJ0eV9jcmVhdGVfYm9vbChwbGFuZS0+ZGV2LCAwLAo+ID4gKwkJCQkJImNvbG9ya2V5LmludmVy dGVkLW1hdGNoIik7Cj4gPiArCWlmICghaW52ZXJ0ZWRfbWF0Y2hfcHJvcCkKPiA+ICsJCWdvdG8g ZXJyX2Rlc3Ryb3lfZm9ybWF0X3Byb3A7Cj4gPiArCj4gPiArCXJlcGxhY2VtZW50X21hc2tfcHJv cCA9IGRybV9wcm9wZXJ0eV9jcmVhdGVfcmFuZ2UocGxhbmUtPmRldiwgMCwKPiA+ICsJCQkJCSJj b2xvcmtleS5yZXBsYWNlbWVudC1tYXNrIiwKPiA+ICsJCQkJCTAsIFU2NF9NQVgpOwo+ID4gKwlp ZiAoIXJlcGxhY2VtZW50X21hc2tfcHJvcCkKPiA+ICsJCWdvdG8gZXJyX2Rlc3Ryb3lfaW52ZXJ0 ZWRfbWF0Y2hfcHJvcDsKPiA+ICsKPiA+ICsJcmVwbGFjZW1lbnRfdmFsdWVfcHJvcCA9IGRybV9w cm9wZXJ0eV9jcmVhdGVfcmFuZ2UocGxhbmUtPmRldiwgMCwKPiA+ICsJCQkJCSJjb2xvcmtleS5y ZXBsYWNlbWVudC12YWx1ZSIsCj4gPiArCQkJCQkwLCBVNjRfTUFYKTsKPiA+ICsJaWYgKCFyZXBs YWNlbWVudF92YWx1ZV9wcm9wKQo+ID4gKwkJZ290byBlcnJfZGVzdHJveV9yZXBsYWNlbWVudF9t YXNrX3Byb3A7Cj4gPiArCj4gPiArCXJlcGxhY2VtZW50X2Zvcm1hdF9wcm9wID0gZHJtX3Byb3Bl cnR5X2NyZWF0ZV9yYW5nZShwbGFuZS0+ZGV2LCAwLAo+ID4gKwkJCQkJImNvbG9ya2V5LnJlcGxh Y2VtZW50LWZvcm1hdCIsCj4gPiArCQkJCQkwLCBVNjRfTUFYKTsKPiA+ICsJaWYgKCFyZXBsYWNl bWVudF9mb3JtYXRfcHJvcCkKPiA+ICsJCWdvdG8gZXJyX2Rlc3Ryb3lfcmVwbGFjZW1lbnRfdmFs dWVfcHJvcDsKPiA+ICsKPiA+ICsJZHJtX29iamVjdF9hdHRhY2hfcHJvcGVydHkoJnBsYW5lLT5i YXNlLCBtaW5fcHJvcCwgMCk7Cj4gPiArCWRybV9vYmplY3RfYXR0YWNoX3Byb3BlcnR5KCZwbGFu ZS0+YmFzZSwgbWF4X3Byb3AsIDApOwo+ID4gKwlkcm1fb2JqZWN0X2F0dGFjaF9wcm9wZXJ0eSgm cGxhbmUtPmJhc2UsIG1vZGVfcHJvcCwgMCk7Cj4gPiArCWRybV9vYmplY3RfYXR0YWNoX3Byb3Bl cnR5KCZwbGFuZS0+YmFzZSwgbWFza19wcm9wLCAwKTsKPiA+ICsJZHJtX29iamVjdF9hdHRhY2hf cHJvcGVydHkoJnBsYW5lLT5iYXNlLCBmb3JtYXRfcHJvcCwgMCk7Cj4gPiArCWRybV9vYmplY3Rf YXR0YWNoX3Byb3BlcnR5KCZwbGFuZS0+YmFzZSwgaW52ZXJ0ZWRfbWF0Y2hfcHJvcCwgMCk7Cj4g PiArCWRybV9vYmplY3RfYXR0YWNoX3Byb3BlcnR5KCZwbGFuZS0+YmFzZSwgcmVwbGFjZW1lbnRf bWFza19wcm9wLCAwKTsKPiA+ICsJZHJtX29iamVjdF9hdHRhY2hfcHJvcGVydHkoJnBsYW5lLT5i YXNlLCByZXBsYWNlbWVudF92YWx1ZV9wcm9wLCAwKTsKPiA+ICsJZHJtX29iamVjdF9hdHRhY2hf cHJvcGVydHkoJnBsYW5lLT5iYXNlLCByZXBsYWNlbWVudF9mb3JtYXRfcHJvcCwgMCk7Cj4gPiAr Cj4gPiArCXBsYW5lLT5jb2xvcmtleS5taW5fcHJvcGVydHkgPSBtaW5fcHJvcDsKPiA+ICsJcGxh bmUtPmNvbG9ya2V5Lm1heF9wcm9wZXJ0eSA9IG1heF9wcm9wOwo+ID4gKwlwbGFuZS0+Y29sb3Jr ZXkubW9kZV9wcm9wZXJ0eSA9IG1vZGVfcHJvcDsKPiA+ICsJcGxhbmUtPmNvbG9ya2V5Lm1hc2tf cHJvcGVydHkgPSBtYXNrX3Byb3A7Cj4gPiArCXBsYW5lLT5jb2xvcmtleS5mb3JtYXRfcHJvcGVy dHkgPSBmb3JtYXRfcHJvcDsKPiA+ICsJcGxhbmUtPmNvbG9ya2V5LmludmVydGVkX21hdGNoX3By b3BlcnR5ID0gaW52ZXJ0ZWRfbWF0Y2hfcHJvcDsKPiA+ICsJcGxhbmUtPmNvbG9ya2V5LnJlcGxh Y2VtZW50X21hc2tfcHJvcGVydHkgPSByZXBsYWNlbWVudF9tYXNrX3Byb3A7Cj4gPiArCXBsYW5l LT5jb2xvcmtleS5yZXBsYWNlbWVudF92YWx1ZV9wcm9wZXJ0eSA9IHJlcGxhY2VtZW50X3ZhbHVl X3Byb3A7Cj4gPiArCXBsYW5lLT5jb2xvcmtleS5yZXBsYWNlbWVudF9mb3JtYXRfcHJvcGVydHkg PSByZXBsYWNlbWVudF9mb3JtYXRfcHJvcDsKPiA+ICsKPiA+ICsJcmV0dXJuIDA7Cj4gPiArCj4g PiArZXJyX2Rlc3Ryb3lfcmVwbGFjZW1lbnRfdmFsdWVfcHJvcDoKPiA+ICsJZHJtX3Byb3BlcnR5 X2Rlc3Ryb3kocGxhbmUtPmRldiwgcmVwbGFjZW1lbnRfdmFsdWVfcHJvcCk7Cj4gPiArZXJyX2Rl c3Ryb3lfcmVwbGFjZW1lbnRfbWFza19wcm9wOgo+ID4gKwlkcm1fcHJvcGVydHlfZGVzdHJveShw bGFuZS0+ZGV2LCByZXBsYWNlbWVudF9tYXNrX3Byb3ApOwo+ID4gK2Vycl9kZXN0cm95X2ludmVy dGVkX21hdGNoX3Byb3A6Cj4gPiArCWRybV9wcm9wZXJ0eV9kZXN0cm95KHBsYW5lLT5kZXYsIGlu dmVydGVkX21hdGNoX3Byb3ApOwo+ID4gK2Vycl9kZXN0cm95X2Zvcm1hdF9wcm9wOgo+ID4gKwlk cm1fcHJvcGVydHlfZGVzdHJveShwbGFuZS0+ZGV2LCBmb3JtYXRfcHJvcCk7Cj4gPiArZXJyX2Rl c3Ryb3lfbWF4X3Byb3A6Cj4gPiArCWRybV9wcm9wZXJ0eV9kZXN0cm95KHBsYW5lLT5kZXYsIG1h eF9wcm9wKTsKPiA+ICtlcnJfZGVzdHJveV9taW5fcHJvcDoKPiA+ICsJZHJtX3Byb3BlcnR5X2Rl c3Ryb3kocGxhbmUtPmRldiwgbWluX3Byb3ApOwo+ID4gK2Vycl9kZXN0cm95X21hc2tfcHJvcDoK PiA+ICsJZHJtX3Byb3BlcnR5X2Rlc3Ryb3kocGxhbmUtPmRldiwgbWFza19wcm9wKTsKPiA+ICtl cnJfZGVzdHJveV9tb2RlX3Byb3A6Cj4gPiArCWRybV9wcm9wZXJ0eV9kZXN0cm95KHBsYW5lLT5k ZXYsIG1vZGVfcHJvcCk7Cj4gPiArCj4gPiArCXJldHVybiAtRU5PTUVNOwo+ID4gK30KPiA+ICtF WFBPUlRfU1lNQk9MKGRybV9wbGFuZV9jcmVhdGVfY29sb3JrZXlfcHJvcGVydGllcyk7Cj4gPiBk aWZmIC0tZ2l0IGEvaW5jbHVkZS9kcm0vZHJtX2JsZW5kLmggYi9pbmNsdWRlL2RybS9kcm1fYmxl bmQuaAo+ID4gaW5kZXggMzMwYzU2MWM0YzExLi44ZTgwZDMzYjY0M2UgMTAwNjQ0Cj4gPiAtLS0g YS9pbmNsdWRlL2RybS9kcm1fYmxlbmQuaAo+ID4gKysrIGIvaW5jbHVkZS9kcm0vZHJtX2JsZW5k LmgKPiA+IEBAIC01Miw0ICs1Miw3IEBAIGludCBkcm1fcGxhbmVfY3JlYXRlX3pwb3NfaW1tdXRh YmxlX3Byb3BlcnR5KHN0cnVjdAo+ID4gZHJtX3BsYW5lICpwbGFuZSwgdW5zaWduZWQgaW50IHpw b3MpOwo+ID4gCj4gPiAgaW50IGRybV9hdG9taWNfbm9ybWFsaXplX3pwb3Moc3RydWN0IGRybV9k ZXZpY2UgKmRldiwKPiA+ICAKPiA+ICAJCQkgICAgICBzdHJ1Y3QgZHJtX2F0b21pY19zdGF0ZSAq c3RhdGUpOwo+ID4gCj4gPiArCj4gPiAraW50IGRybV9wbGFuZV9jcmVhdGVfY29sb3JrZXlfcHJv cGVydGllcyhzdHJ1Y3QgZHJtX3BsYW5lICpwbGFuZSwKPiA+ICsJCQkJCSB1MzIgc3VwcG9ydGVk X21vZGVzKTsKPiA+IAo+ID4gICNlbmRpZgo+ID4gCj4gPiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9k cm0vZHJtX3BsYW5lLmggYi9pbmNsdWRlL2RybS9kcm1fcGxhbmUuaAo+ID4gaW5kZXggMjZmYTUw YzJhNTBlLi5mZjdmNWViZTJiNzkgMTAwNjQ0Cj4gPiAtLS0gYS9pbmNsdWRlL2RybS9kcm1fcGxh bmUuaAo+ID4gKysrIGIvaW5jbHVkZS9kcm0vZHJtX3BsYW5lLmgKPiA+IEBAIC0zMiw2ICszMiw0 MiBAQCBzdHJ1Y3QgZHJtX2NydGM7Cj4gPiAKPiA+ICBzdHJ1Y3QgZHJtX3ByaW50ZXI7Cj4gPiAg c3RydWN0IGRybV9tb2Rlc2V0X2FjcXVpcmVfY3R4Owo+ID4gCj4gPiArLyoqCj4gPiArICogZW51 bSBkcm1fcGxhbmVfY29sb3JrZXlfbW9kZSAtIHVhcGkgcGxhbmUgY29sb3JrZXkgbW9kZSBlbnVt ZXJhdGlvbgo+ID4gKyAqLwo+ID4gK2VudW0gZHJtX3BsYW5lX2NvbG9ya2V5X21vZGUgewo+ID4g KwkvKioKPiA+ICsJICogQERSTV9QTEFORV9DT0xPUktFWV9NT0RFX0RJU0FCTEVEOgo+ID4gKwkg Kgo+ID4gKwkgKiBObyBjb2xvciBtYXRjaGluZyBwZXJmb3JtZWQgaW4gdGhpcyBtb2RlLiBUaGlz IGlzIHRoZSBkZWZhdWx0Cj4gPiArCSAqIGNvbW1vbiBtb2RlLgo+ID4gKwkgKi8KPiA+ICsJRFJN X1BMQU5FX0NPTE9SS0VZX01PREVfRElTQUJMRUQsCj4gPiArCj4gPiArCS8qKgo+ID4gKwkgKiBA RFJNX1BMQU5FX0NPTE9SS0VZX01PREVfU1JDOgo+ID4gKwkgKgo+ID4gKwkgKiBJbiB0aGlzIG1v ZGUgY29sb3IgbWF0Y2hpbmcgaXMgcGVyZm9ybWVkIHdpdGggdGhlIHBpeGVscyBvZgo+ID4gKwkg KiB0aGUgZ2l2ZW4gcGxhbmUgYW5kIHRoZSBtYXRjaGVkIHBpeGVscyBhcmUgZnVsbHkgKG9yIHBh cnRpYWxseSkKPiA+ICsJICogcmVwbGFjZWQgd2l0aCB0aGUgcmVwbGFjZW1lbnQgY29sb3Igb3Ig YmVjb21lIGNvbXBsZXRlbHkKPiA+ICsJICogdHJhbnNwYXJlbnQuCj4gPiArCSAqLwo+ID4gKwlE Uk1fUExBTkVfQ09MT1JLRVlfTU9ERV9TUkMsCj4gPiArCj4gPiArCS8qKgo+ID4gKwkgKiBARFJN X1BMQU5FX0NPTE9SS0VZX01PREVfRFNUOgo+ID4gKwkgKgo+ID4gKwkgKiBJbiB0aGlzIG1vZGUg Y29sb3IgbWF0Y2hpbmcgaXMgcGVyZm9ybWVkIHdpdGggdGhlIHBpeGVscyBvZiB0aGUKPiA+ICsJ ICogcGxhbmVzIHotcG9zaXRpb25lZCB1bmRlciB0aGUgZ2l2ZW4gcGxhbmUgYW5kIHRoZSBwaXhl bHMgb2YgdGhlCj4gPiArCSAqIGhvdmVyaW5nIHBsYW5lIHRoYXQgYXJlIHh5LXBvc2l0aW9uZWQg YXMgdGhlIHVuZGVybHlpbmcKPiA+ICsJICogY29sb3ItbWF0Y2hlZCBwaXhlbHMgYXJlIGZ1bGx5 IChvciBwYXJ0aWFsbHkpIHJlcGxhY2VkIHdpdGggdGhlCj4gPiArCSAqIHJlcGxhY2VtZW50IGNv bG9yIG9yIGJlY29tZSBjb21wbGV0ZWx5IHRyYW5zcGFyZW50Lgo+ID4gKwkgKi8KPiA+ICsJRFJN X1BMQU5FX0NPTE9SS0VZX01PREVfRFNULAo+ID4gKwo+ID4gKwlEUk1fUExBTkVfQ09MT1JLRVlf TU9ERVNfTlVNLAo+ID4gK307Cj4gPiArCj4gPiAKPiA+ICAvKioKPiA+ICAKPiA+ICAgKiBzdHJ1 Y3QgZHJtX3BsYW5lX3N0YXRlIC0gbXV0YWJsZSBwbGFuZSBzdGF0ZQo+ID4gICAqIEBwbGFuZTog YmFja3BvaW50ZXIgdG8gdGhlIHBsYW5lCj4gPiAKPiA+IEBAIC01NCw2ICs5MCwyMSBAQCBzdHJ1 Y3QgZHJtX21vZGVzZXRfYWNxdWlyZV9jdHg7Cj4gPiAKPiA+ICAgKgl3aGVyZSBOIGlzIHRoZSBu dW1iZXIgb2YgYWN0aXZlIHBsYW5lcyBmb3IgZ2l2ZW4gY3J0Yy4gTm90ZSB0aGF0Cj4gPiAgICoJ dGhlIGRyaXZlciBtdXN0IHNldCBkcm1fbW9kZV9jb25maWcubm9ybWFsaXplX3pwb3Mgb3IgY2Fs bAo+ID4gICAqCWRybV9hdG9taWNfbm9ybWFsaXplX3pwb3MoKSB0byB1cGRhdGUgdGhpcyBiZWZv cmUgaXQgY2FuIGJlIHRydXN0ZWQuCj4gPiAKPiA+ICsgKiBAY29sb3JrZXkubW9kZTogY29sb3Ig a2V5IG1vZGUKPiA+ICsgKiBAY29sb3JrZXkubWluOiBjb2xvciBrZXkgcmFuZ2UgbWluaW11bS4g VGhlIHZhbHVlIGlzIHN0b3JlZCBpbgo+ID4gQVhZWjE2MTYxNjE2ICsgKglmb3JtYXQsIHdoZXJl IEEgaXMgdGhlIGFscGhhIHZhbHVlIGFuZCBYLCBZIGFuZCBaCj4gPiBjb3JyZXNwb25kIHRvIHRo ZSArICoJY29sb3IgY29tcG9uZW50cyBvZiB0aGUgcGxhbmUncyBwaXhlbCBmb3JtYXQKPiA+ICh1 c3VhbGx5Cj4gPiBSR0Igb3IgWVVWKSArICogQGNvbG9ya2V5Lm1heDogY29sb3Iga2V5IHJhbmdl IG1heGltdW0gKGluIEFYWVoxNjE2MTYxNgo+ID4gZm9ybWF0KSArICogQGNvbG9ya2V5Lm1hc2s6 IGNvbG9yIGtleSBtYXNrIHZhbHVlIChpbiBBWFlaMTYxNjE2MTYgZm9ybWF0KQo+ID4gKyAqIEBj b2xvcmtleS5mb3JtYXQ6IGNvbG9yIGtleSBtaW4vbWF4L21hc2sgdmFsdWVzIHBpeGVsIGZvcm1h dCAoaW4KPiA+ICsgKiAJRFJNX0ZPUk1BVF9BWFlaMTYxNjE2MTYgZm9ybSkKPiA+ICsgKiBAY29s b3JrZXkuaW52ZXJ0ZWRfbWF0Y2g6IGNvbG9yIGtleSBtaW4tbWF4IG1hdGNoaW5nIHJhbmdlIGlz IGludmVydGVkCj4gPiArICogQGNvbG9ya2V5LnJlcGxhY2VtZW50X21hc2s6IGNvbG9yIGtleSBy ZXBsYWNlbWVudCBtYXNrIHZhbHVlIChpbgo+ID4gKyAqIAlBWFlaMTYxNjE2MTYgZm9ybWF0KQo+ ID4gKyAqIEBjb2xvcmtleS5yZXBsYWNlbWVudF92YWx1ZTogY29sb3Iga2V5IHJlcGxhY2VtZW50 IHZhbHVlIChpbgo+ID4gKyAqIAlBWFlaMTYxNjE2MTYgZm9ybWF0KQo+ID4gKyAqIEBjb2xvcmtl eS5yZXBsYWNlbWVudF9mb3JtYXQ6IGNvbG9yIGtleSByZXBsYWNlbWVudCB2YWx1ZSAvIG1hc2sK PiA+ICsgKglwaXhlbCBmb3JtYXQgKGluIERSTV9GT1JNQVRfQVhZWjE2MTYxNjE2IGZvcm0pCj4g PiAKPiA+ICAgKiBAc3JjOiBjbGlwcGVkIHNvdXJjZSBjb29yZGluYXRlcyBvZiB0aGUgcGxhbmUg KGluIDE2LjE2KQo+ID4gICAqIEBkc3Q6IGNsaXBwZWQgZGVzdGluYXRpb24gY29vcmRpbmF0ZXMg b2YgdGhlIHBsYW5lCj4gPiAgICogQHN0YXRlOiBiYWNrcG9pbnRlciB0byBnbG9iYWwgZHJtX2F0 b21pY19zdGF0ZQo+ID4gCj4gPiBAQCAtMTI0LDYgKzE3NSwxOSBAQCBzdHJ1Y3QgZHJtX3BsYW5l X3N0YXRlIHsKPiA+IAo+ID4gIAl1bnNpZ25lZCBpbnQgenBvczsKPiA+ICAJdW5zaWduZWQgaW50 IG5vcm1hbGl6ZWRfenBvczsKPiA+IAo+ID4gKwkvKiBQbGFuZSBjb2xvcmtleSAqLwo+ID4gKwlz dHJ1Y3Qgewo+ID4gKwkJZW51bSBkcm1fcGxhbmVfY29sb3JrZXlfbW9kZSBtb2RlOwo+ID4gKwkJ dTY0IG1pbjsKPiA+ICsJCXU2NCBtYXg7Cj4gPiArCQl1NjQgbWFzazsKPiA+ICsJCXUzMiBmb3Jt YXQ7Cj4gPiArCQlib29sIGludmVydGVkX21hdGNoOwo+ID4gKwkJdTY0IHJlcGxhY2VtZW50X21h c2s7Cj4gPiArCQl1NjQgcmVwbGFjZW1lbnRfdmFsdWU7Cj4gPiArCQl1MzIgcmVwbGFjZW1lbnRf Zm9ybWF0Owo+ID4gKwl9IGNvbG9ya2V5Owo+ID4gKwo+ID4gCj4gPiAgCS8qKgo+ID4gIAkKPiA+ ICAJICogQGNvbG9yX2VuY29kaW5nOgo+ID4gIAkgKgo+ID4gCj4gPiBAQCAtNTEwLDYgKzU3NCw3 IEBAIGVudW0gZHJtX3BsYW5lX3R5cGUgewo+ID4gCj4gPiAgICogQGFscGhhX3Byb3BlcnR5OiBh bHBoYSBwcm9wZXJ0eSBmb3IgdGhpcyBwbGFuZQo+ID4gICAqIEB6cG9zX3Byb3BlcnR5OiB6cG9z IHByb3BlcnR5IGZvciB0aGlzIHBsYW5lCj4gPiAgICogQHJvdGF0aW9uX3Byb3BlcnR5OiByb3Rh dGlvbiBwcm9wZXJ0eSBmb3IgdGhpcyBwbGFuZQo+ID4gCj4gPiArICogQGNvbG9ya2V5OiBjb2xv cmtleSBwcm9wZXJ0aWVzIGZvciB0aGlzIHBsYW5lCj4gPiAKPiA+ICAgKiBAaGVscGVyX3ByaXZh dGU6IG1pZC1sYXllciBwcml2YXRlIGRhdGEKPiA+ICAgKi8KPiA+ICAKPiA+ICBzdHJ1Y3QgZHJt X3BsYW5lIHsKPiA+IAo+ID4gQEAgLTU4Nyw2ICs2NTIsMTggQEAgc3RydWN0IGRybV9wbGFuZSB7 Cj4gPiAKPiA+ICAJc3RydWN0IGRybV9wcm9wZXJ0eSAqenBvc19wcm9wZXJ0eTsKPiA+ICAJc3Ry dWN0IGRybV9wcm9wZXJ0eSAqcm90YXRpb25fcHJvcGVydHk7Cj4gPiAKPiA+ICsJc3RydWN0IHsK PiA+ICsJCXN0cnVjdCBkcm1fcHJvcGVydHkgKm1pbl9wcm9wZXJ0eTsKPiA+ICsJCXN0cnVjdCBk cm1fcHJvcGVydHkgKm1heF9wcm9wZXJ0eTsKPiA+ICsJCXN0cnVjdCBkcm1fcHJvcGVydHkgKm1v ZGVfcHJvcGVydHk7Cj4gPiArCQlzdHJ1Y3QgZHJtX3Byb3BlcnR5ICptYXNrX3Byb3BlcnR5Owo+ ID4gKwkJc3RydWN0IGRybV9wcm9wZXJ0eSAqZm9ybWF0X3Byb3BlcnR5Owo+ID4gKwkJc3RydWN0 IGRybV9wcm9wZXJ0eSAqaW52ZXJ0ZWRfbWF0Y2hfcHJvcGVydHk7Cj4gPiArCQlzdHJ1Y3QgZHJt X3Byb3BlcnR5ICpyZXBsYWNlbWVudF9tYXNrX3Byb3BlcnR5Owo+ID4gKwkJc3RydWN0IGRybV9w cm9wZXJ0eSAqcmVwbGFjZW1lbnRfdmFsdWVfcHJvcGVydHk7Cj4gPiArCQlzdHJ1Y3QgZHJtX3By b3BlcnR5ICpyZXBsYWNlbWVudF9mb3JtYXRfcHJvcGVydHk7Cj4gPiArCX0gY29sb3JrZXk7Cj4g PiArCj4gPiAKPiA+ICAJLyoqCj4gPiAgCQo+ID4gIAkgKiBAY29sb3JfZW5jb2RpbmdfcHJvcGVy dHk6Cj4gPiAgCSAqCgoKLS0gClJlZ2FyZHMsCgpMYXVyZW50IFBpbmNoYXJ0CgoKCl9fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5n IGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVk ZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=