All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@kernel.org>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: LKML <linux-kernel@vger.kernel.org>,
	x86@kernel.org, Stephen Hemminger <stephen@networkplumber.org>,
	Willy Tarreau <w@1wt.eu>, Juergen Gross <jgross@suse.com>,
	Sean Christopherson <sean.j.christopherson@intel.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	"H. Peter Anvin" <hpa@zytor.com>
Subject: Re: [patch 5/9] x86/ioport: Reduce ioperm impact for sane usage further
Date: Thu, 7 Nov 2019 09:16:35 +0100	[thread overview]
Message-ID: <20191107081635.GE30739@gmail.com> (raw)
In-Reply-To: <20191106202806.241007755@linutronix.de>


* Thomas Gleixner <tglx@linutronix.de> wrote:

> +	/* Update the bitmap */
> +	if (turn_on) {
> +		bitmap_clear(bitmap, from, num);
> +	} else {
> +		bitmap_set(bitmap, from, num);
> +	}
> +
> +	/* Get the new range */
> +	first = find_first_zero_bit(bitmap, IO_BITMAP_BITS);
> +
> +	for (last = next = first; next < IO_BITMAP_BITS; last = next) {
> +		/* Find the next set bit and update last */
> +		next = find_next_bit(bitmap, IO_BITMAP_BITS, last);
> +		last = next - 1;
> +		if (next == IO_BITMAP_BITS)
> +			break;
> +		/* Find the next zero bit and continue searching */
> +		next = find_next_zero_bit(bitmap, IO_BITMAP_BITS, next);
> +	}
> +
> +	/* Calculate the byte boundaries for the updated region */
> +	copy_start = from / 8;
> +	copy_len = (round_up(from + num, 8) / 8) - copy_start;

This might seem like a small detail, but since we do the range tracking 
and copying at byte granularity anyway, why not do the zero range search 
at byte granularity as well?

I bet it's faster and simpler as well than the bit-searching.

We could also change over the bitmap to a char or u8 based array and lose 
all the sizeof(long) indexing headaches, resulting type casts, for 
anything but the actual bitmap_set/clear() calls, etc.?

I.e. now that most of the logic is byte granular, the basic data 
structure might as well reflect that?

> +	/*
> +	 * Update the per thread storage and the TSS bitmap. This must be
> +	 * done with preemption disabled to prevent racing against a
> +	 * context switch.
> +	 */
> +	preempt_disable();
> +	tss = this_cpu_ptr(&cpu_tss_rw);
>  
> +	if (!t->io_bitmap_ptr) {
> +		unsigned int tss_start = tss->io_zerobits_start;
> +		/*
> +		 * If the task did not use the I/O bitmap yet then the
> +		 * perhaps stale content in the TSS needs to be taken into
> +		 * account. If tss start is out of bounds the TSS storage
> +		 * does not contain a zero bit and it's sufficient just to
> +		 * copy the new range over.
> +		 */

s/tss/TSS

> +		if (tss_start < IO_BITMAP_BYTES) {
> +			unsigned int tss_end =  tss->io_zerobits_end;
> +			unsigned int copy_end = copy_start + copy_len;
> +
> +			copy_start = min(tss_start, copy_start);
> +			copy_len = max(tss_end, copy_end) - copy_start;
> +		}
> +	}
> +
> +	/* Copy the changed range over to the TSS bitmap */
> +	dst = (char *)tss->io_bitmap;
> +	src = (char *)bitmap;
> +	memcpy(dst + copy_start, src + copy_start, copy_len);
> +
> +	if (first >= IO_BITMAP_BITS) {
> +		/*
> +		 * If the resulting bitmap has all permissions dropped, clear
> +		 * TIF_IO_BITMAP and set the IO bitmap offset in the TSS to
> +		 * invalid. Deallocate both the new and the thread's bitmap.
> +		 */
> +		clear_thread_flag(TIF_IO_BITMAP);
> +		tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET_INVALID;
> +		tofree = bitmap;
> +		bitmap = NULL;

BTW., wouldn't it be simpler to just say that if a thread uses IO ops 
even once, it gets a bitmap and that's it? I.e. we could further simplify 
this seldom used piece of code.

> +	} else {
>  		/*
> +		 * I/O bitmap contains zero bits. Set TIF_IO_BITMAP, make
> +		 * the bitmap offset valid and make sure that the TSS limit
> +		 * is correct. It might have been wreckaged by a VMEXiT.
>  		 */
> +		set_thread_flag(TIF_IO_BITMAP);
> +		tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET_VALID;
>  		refresh_tss_limit();
>  	}

I'm wondering, shouldn't we call refresh_tss_limit() in both branches, or 
is a VMEXIT-wreckaged TSS limit harmless if we otherwise have 
io_bitmap_base set to IO_BITMAP_OFFSET_INVALID?


>  	/*
> +	 * Update the range in the thread and the TSS
>  	 *
> +	 * Get the byte position of the first zero bit and calculate
> +	 * the length of the range in which zero bits exist.
>  	 */
> +	start = first / 8;
> +	end = first < IO_BITMAP_BITS ? round_up(last, 8) / 8 : 0;
> +	t->io_zerobits_start = tss->io_zerobits_start = start;
> +	t->io_zerobits_end = tss->io_zerobits_end = end;
>  
>  	/*
> +	 * Finally exchange the bitmap pointer in the thread.
>  	 */
> +	bitmap = xchg(&t->io_bitmap_ptr, bitmap);
> +	preempt_enable();
>  
> +	kfree(bitmap);
> +	kfree(tofree);
>  
>  	return 0;


Thanks,

	Ingo

  parent reply	other threads:[~2019-11-07  8:16 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-06 19:34 [patch 0/9] x86/iopl: Prevent user space from using CLI/STI with iopl(3) Thomas Gleixner
2019-11-06 19:35 ` [patch 1/9] x86/ptrace: Prevent truncation of bitmap size Thomas Gleixner
2019-11-07  7:31   ` Ingo Molnar
2019-11-06 19:35 ` [patch 2/9] x86/process: Unify copy_thread_tls() Thomas Gleixner
2019-11-08 22:31   ` Andy Lutomirski
2019-11-08 23:43     ` Thomas Gleixner
2019-11-10 12:36       ` Thomas Gleixner
2019-11-10 16:56         ` Andy Lutomirski
2019-11-11  8:52           ` Peter Zijlstra
2019-11-06 19:35 ` [patch 3/9] x86/cpu: Unify cpu_init() Thomas Gleixner
2019-11-08 22:34   ` Andy Lutomirski
2019-11-11  4:22   ` kbuild test robot
2019-11-06 19:35 ` [patch 4/9] x86/io: Speedup schedule out of I/O bitmap user Thomas Gleixner
2019-11-07  9:12   ` Peter Zijlstra
2019-11-07 14:04     ` Thomas Gleixner
2019-11-07 14:08       ` Thomas Gleixner
2019-11-08 22:41         ` Andy Lutomirski
2019-11-08 23:45           ` Thomas Gleixner
2019-11-09  3:32             ` Andy Lutomirski
2019-11-10 12:43               ` Thomas Gleixner
2019-11-09  0:24   ` Andy Lutomirski
2019-11-09  1:18   ` kbuild test robot
2019-11-06 19:35 ` [patch 5/9] x86/ioport: Reduce ioperm impact for sane usage further Thomas Gleixner
2019-11-07  1:11   ` Linus Torvalds
2019-11-07  7:44     ` Thomas Gleixner
2019-11-07  8:25     ` Ingo Molnar
2019-11-07  9:17       ` Willy Tarreau
2019-11-07 10:00         ` Thomas Gleixner
2019-11-07 10:13           ` Willy Tarreau
2019-11-07 10:19           ` hpa
2019-11-07 10:27             ` Willy Tarreau
2019-11-07 10:50               ` hpa
2019-11-07 12:56                 ` Willy Tarreau
2019-11-07 16:45                   ` Eric W. Biederman
2019-11-07 16:53                     ` Linus Torvalds
2019-11-07 16:57                     ` Willy Tarreau
2019-11-10 17:17       ` Andy Lutomirski
2019-11-07  7:37   ` Ingo Molnar
2019-11-07  7:45     ` Thomas Gleixner
2019-11-07  8:16   ` Ingo Molnar [this message]
2019-11-07 18:02     ` Thomas Gleixner
2019-11-07 19:24   ` Brian Gerst
2019-11-07 19:54     ` Linus Torvalds
2019-11-07 21:00       ` Brian Gerst
2019-11-07 21:32         ` Thomas Gleixner
2019-11-07 23:20           ` hpa
2019-11-07 21:44         ` Linus Torvalds
2019-11-08  1:12           ` H. Peter Anvin
2019-11-08  2:12             ` Brian Gerst
2019-11-10 17:21           ` Andy Lutomirski
2019-11-06 19:35 ` [patch 6/9] x86/iopl: Fixup misleading comment Thomas Gleixner
2019-11-06 19:35 ` [patch 7/9] x86/iopl: Restrict iopl() permission scope Thomas Gleixner
2019-11-07  9:09   ` Peter Zijlstra
2019-11-10 17:26   ` Andy Lutomirski
2019-11-10 20:31     ` Thomas Gleixner
2019-11-10 21:05       ` Andy Lutomirski
2019-11-10 21:21         ` Thomas Gleixner
2019-11-11  4:27   ` kbuild test robot
2019-11-06 19:35 ` [patch 8/9] x86/iopl: Remove legacy IOPL option Thomas Gleixner
2019-11-07  6:11   ` Jürgen Groß
2019-11-07  6:26     ` hpa
2019-11-07 16:44     ` Stephen Hemminger
2019-11-07  9:13   ` Peter Zijlstra
2019-11-06 19:35 ` [patch 9/9] selftests/x86/iopl: Verify that CLI/STI result in #GP Thomas Gleixner
2019-11-07  7:28 ` [patch] x86/iopl: Remove unused local variable, update comments in ksys_ioperm() Ingo Molnar

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=20191107081635.GE30739@gmail.com \
    --to=mingo@kernel.org \
    --cc=hpa@zytor.com \
    --cc=jgross@suse.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sean.j.christopherson@intel.com \
    --cc=stephen@networkplumber.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=w@1wt.eu \
    --cc=x86@kernel.org \
    /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.