All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Michael S. Tsirkin" <mst@redhat.com>
Cc: kvm@vger.kernel.org, virtualization@lists.linux.dev,
	"Eugenio Perez" <eperezma@redhat.com>
Subject: Re: [PATCH RFC] vhost: set dirty log bits without pinning pages on x86
Date: Fri, 13 Nov 2026 10:54:01 +0000	[thread overview]
Message-ID: <sashiko-outbox-212640@kernel.org> (raw)
In-Reply-To: <af7f05bf637337d35fdd10f3e0dbb5e39d7780e7.1794480795.git.mst@redhat.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Critical] x86/uaccess, vhost: missing access_ok() check in
  set_bit_user()
- [High] x86/uaccess: set_bit_user() uses write-only =r constraint on
  __err
--

commit 508047a5899f1ab9b68b7a3a4c36fffabf6ab858
Author: Michael S. Tsirkin <mst@redhat.com>

vhost: set dirty log bits without pinning pages on x86

This commit introduces a set_bit_user() helper on x86 to atomically set a
bit in user memory using an exception table entry, and uses it in vhost's
set_bit_to_user() to avoid pinning user pages on the dirty-logging path.

Link: https://lore.kernel.org/all/20261112085631.128819-1-zhaoguohan@kylinos.cn/

> diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
> index 3a0dd3c2b233e..ba1e7c3f83c8e 100644
> --- a/arch/x86/include/asm/uaccess.h
> +++ b/arch/x86/include/asm/uaccess.h
> @@ -594,6 +594,24 @@ _label:									\
>  	__ret;								\
>  							})
>  
> +/* set_bit() on a byte of user memory; returns -EFAULT on fault. */
> +#define set_bit_user(nr, addr)					\
> +({									\
> +	int __err = 0;							\
> +	__uaccess_begin();						\
> +	asm volatile("\n"						\
> +		     "1: " LOCK_PREFIX "orb %[mask], %[ptr]\n"		\
> +		     "2:\n"						\
> +		     _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG,	\
> +					   %[errout])			\
> +		     : [errout] "=r" (__err),				\
> +		       [ptr] "+m" (*(u8 __user *)(addr))		\
> +		     : [mask] "q" ((unsigned char)BIT(nr))		\
> +		     : "memory", "cc");				\
> +	__uaccess_end();						\
> +	__err ? -EFAULT : 0;						\
> +})

[Severity: Critical]
Does set_bit_user() need an access_ok() check (or user_access_begin() /
scoped_user_rw_access()) before calling __uaccess_begin()?

Previously, set_bit_to_user() called pin_user_pages_fast(), which rejected
kernel addresses.  Not every vhost path validates vq->log_base with
access_ok() before reaching set_bit_to_user(): when vq->iotlb is non-NULL
and vq->log_used is set (with VHOST_F_LOG_ALL unset), vq_log_access_ok()
skips log_access_ok() because vq_log_used_access_ok() returns true early:

drivers/vhost/vhost.c:vq_log_used_access_ok() {
	if (vq->iotlb)
		return true;

	return !log_used || log_access_ok(log_base, log_addr,
					  vhost_get_used_size(vq, vq->num));
}

When log_used() then runs, it calls log_write_hva() ->
log_write(vq->log_base, ...) -> set_bit_to_user(), allowing userspace to
set bits in arbitrary kernel memory with SMAP disabled.

[Severity: High]
Should the [errout] constraint on __err be "+r" instead of "=r"?

%[errout] is only written by the exception handler when instruction 1b
faults.  With a write-only "=r" constraint, the compiler treats the
initial "__err = 0" assignment as dead and can reuse a register holding a
non-zero input (such as [mask]), causing set_bit_user() to return -EFAULT
even when the atomic orb succeeds and aborting vhost dirty-page logging.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/af7f05bf637337d35fdd10f3e0dbb5e39d7780e7.1794480795.git.mst@redhat.com?part=1

      parent reply	other threads:[~2026-11-13 10:54 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-12 10:53 [PATCH RFC] vhost: set dirty log bits without pinning pages on x86 Michael S. Tsirkin
2026-11-13  1:29 ` zhaoguohan
2026-11-13  5:47   ` Michael S. Tsirkin
2026-11-13  6:09   ` Michael S. Tsirkin
2026-11-13 10:54 ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-212640@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=eperezma@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=virtualization@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.