From: Jeremy Fitzhardinge <jeremy@goop.org>
To: "H. Peter Anvin" <hpa@zytor.com>
Cc: the arch/x86 maintainers <x86@kernel.org>,
Ingo Molnar <mingo@elte.hu>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Xen-devel <xen-devel@lists.xensource.com>,
Christophe Saout <chtephan@leto.intern.saout.de>,
Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Subject: [PATCH 14/15] paravirtualize IO permission bitmap
Date: Mon, 23 Mar 2009 11:09:58 -0700 [thread overview]
Message-ID: <1237831799-6568-15-git-send-email-jeremy@goop.org> (raw)
In-Reply-To: <49C45238.7050007@zytor.com>
From: Christophe Saout <chtephan@leto.intern.saout.de>
Impact: make ioperm bitmap work under Xen
A PV Xen guest kernel has no TSS of its own, so the IO permission
bitmap must be paravirtualized. This patch adds set_io_bitmap
as a paravirt op, and defines a native version which updates the tss,
and a Xen version which uses a hypercall.
This is much easier now that 32 and 64-bit use the same code to
manage the IO bitmap.
Signed-off-by: Christophe Saout <chtephan@leto.intern.saout.de>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
---
arch/x86/include/asm/paravirt.h | 9 +++++++++
arch/x86/include/asm/processor.h | 4 ++++
arch/x86/kernel/ioport.c | 34 ++++++++++++++++++++++++++--------
arch/x86/kernel/paravirt.c | 1 +
arch/x86/kernel/process.c | 27 +++++++--------------------
arch/x86/xen/enlighten.c | 16 ++++++++++++++++
6 files changed, 63 insertions(+), 28 deletions(-)
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index bc384be..fd2c31b 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -156,6 +156,8 @@ struct pv_cpu_ops {
void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t);
void (*set_iopl_mask)(unsigned mask);
+ void (*set_io_bitmap)(struct thread_struct *thread,
+ int changed, unsigned long bytes_updated);
void (*wbinvd)(void);
void (*io_delay)(void);
@@ -996,11 +998,18 @@ static inline void write_idt_entry(gate_desc *dt, int entry, const gate_desc *g)
{
PVOP_VCALL3(pv_cpu_ops.write_idt_entry, dt, entry, g);
}
+
static inline void set_iopl_mask(unsigned mask)
{
PVOP_VCALL1(pv_cpu_ops.set_iopl_mask, mask);
}
+static inline void set_io_bitmap(struct thread_struct *thread,
+ int changed, unsigned long bytes_updated)
+{
+ PVOP_VCALL3(pv_cpu_ops.set_io_bitmap, thread, changed, bytes_updated);
+}
+
/* The paravirtualized I/O functions */
static inline void slow_down_io(void)
{
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 34c5237..0ed4cba 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -538,6 +538,9 @@ static inline void native_set_iopl_mask(unsigned mask)
#endif
}
+extern void native_set_io_bitmap(struct thread_struct *thread,
+ int changed, unsigned long updated_bytes);
+
static inline void
native_load_sp0(struct tss_struct *tss, struct thread_struct *thread)
{
@@ -579,6 +582,7 @@ static inline void load_sp0(struct tss_struct *tss,
}
#define set_iopl_mask native_set_iopl_mask
+#define set_io_bitmap native_set_io_bitmap
#endif /* CONFIG_PARAVIRT */
/*
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
index 99c4d30..5a12c9f 100644
--- a/arch/x86/kernel/ioport.c
+++ b/arch/x86/kernel/ioport.c
@@ -30,14 +30,31 @@ static void set_bitmap(unsigned long *bitmap, unsigned int base,
}
}
+void native_set_io_bitmap(struct thread_struct *t,
+ int changed, unsigned long bytes_updated)
+{
+ struct tss_struct *tss;
+
+ if (!bytes_updated)
+ return;
+
+ tss = &__get_cpu_var(init_tss);
+
+ /* Update the TSS: */
+ if (t->io_bitmap_ptr)
+ memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated);
+ else
+ memset(tss->io_bitmap, 0xff, bytes_updated);
+}
+
/*
* this changes the io permissions bitmap in the current task.
*/
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{
struct thread_struct *t = ¤t->thread;
- struct tss_struct *tss;
unsigned int i, max_long, bytes, bytes_updated;
+ int changed;
if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
return -EINVAL;
@@ -58,16 +75,18 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
memset(bitmap, 0xff, IO_BITMAP_BYTES);
t->io_bitmap_ptr = bitmap;
set_thread_flag(TIF_IO_BITMAP);
- }
+ changed = 1;
+ } else
+ changed = 0;
/*
- * do it in the per-thread copy and in the TSS ...
+ * do it in the per-thread copy
*
- * Disable preemption via get_cpu() - we must not switch away
+ * Disable preemption - we must not switch away
* because the ->io_bitmap_max value must match the bitmap
* contents:
*/
- tss = &per_cpu(init_tss, get_cpu());
+ preempt_disable();
set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
@@ -85,10 +104,9 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
t->io_bitmap_max = bytes;
- /* Update the TSS: */
- memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated);
+ set_io_bitmap(t, changed, bytes_updated);
- put_cpu();
+ preempt_enable();
return 0;
}
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index aa34423..1c15178 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -398,6 +398,7 @@ struct pv_cpu_ops pv_cpu_ops = {
.swapgs = native_swapgs,
.set_iopl_mask = native_set_iopl_mask,
+ .set_io_bitmap = native_set_io_bitmap,
.io_delay = native_io_delay,
.start_context_switch = paravirt_nop,
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index ac25491..174ab04 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -71,16 +71,12 @@ void exit_thread(void)
unsigned long *bp = t->io_bitmap_ptr;
if (bp) {
- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
-
+ preempt_disable();
t->io_bitmap_ptr = NULL;
clear_thread_flag(TIF_IO_BITMAP);
- /*
- * Careful, clear this in the TSS too:
- */
- memset(tss->io_bitmap, 0xff, t->io_bitmap_max);
+ set_io_bitmap(t, 1, t->io_bitmap_max);
t->io_bitmap_max = 0;
- put_cpu();
+ preempt_enable();
kfree(bp);
}
@@ -211,19 +207,10 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
hard_enable_TSC();
}
- if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
- /*
- * Copy the relevant range of the IO bitmap.
- * Normally this is 128 bytes or less:
- */
- memcpy(tss->io_bitmap, next->io_bitmap_ptr,
- max(prev->io_bitmap_max, next->io_bitmap_max));
- } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) {
- /*
- * Clear any possible leftover bits:
- */
- memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
- }
+ if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP) ||
+ test_tsk_thread_flag(prev_p, TIF_IO_BITMAP))
+ set_io_bitmap(next, 1,
+ max(prev->io_bitmap_max, next->io_bitmap_max));
}
int sys_fork(struct pt_regs *regs)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 213e1ba..61ce3ae 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -568,6 +568,21 @@ static void xen_set_iopl_mask(unsigned mask)
HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
}
+static void xen_set_io_bitmap(struct thread_struct *thread,
+ int changed, unsigned long bytes_updated)
+{
+ struct physdev_set_iobitmap set_iobitmap;
+
+ if (!changed)
+ return;
+
+ set_xen_guest_handle(set_iobitmap.bitmap,
+ (char *)thread->io_bitmap_ptr);
+ set_iobitmap.nr_ports = thread->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
+ WARN_ON(HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap,
+ &set_iobitmap));
+}
+
static void xen_io_delay(void)
{
}
@@ -861,6 +876,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
.load_sp0 = xen_load_sp0,
.set_iopl_mask = xen_set_iopl_mask,
+ .set_io_bitmap = xen_set_io_bitmap,
.io_delay = xen_io_delay,
/* Xen takes care of %gs when switching to usermode for us */
--
1.6.0.6
next prev parent reply other threads:[~2009-03-23 18:14 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <49C28AC2.4010407@goop.org>
[not found] ` <49C29381.9050201@zytor.com>
[not found] ` <49C29983.3040305@goop.org>
[not found] ` <49C2ABCA.6010009@zytor.com>
[not found] ` <49C43D31.7040805@goop.org>
[not found] ` <49C45238.7050007@zytor.com>
2009-03-23 17:38 ` [GIT PULL] x86/paravirt: allow preemption while doing lazy mmu update Jeremy Fitzhardinge
2009-03-23 17:38 ` Jeremy Fitzhardinge
2009-03-23 17:45 ` [GIT PULL] core Xen updates for 2.6.30 Jeremy Fitzhardinge
2009-03-23 17:55 ` [GIT PULL] xen domU control interfaces Jeremy Fitzhardinge
2009-03-23 17:55 ` [PATCH 01/11] xen: add irq_from_evtchn Jeremy Fitzhardinge
2009-03-23 17:55 ` [PATCH 02/11] xen: add /dev/xen/evtchn driver Jeremy Fitzhardinge
2009-03-23 17:55 ` [PATCH 03/11] xen: export ioctl headers to userspace Jeremy Fitzhardinge
2009-03-23 17:55 ` [PATCH 04/11] xen/dev-evtchn: clean up locking in evtchn Jeremy Fitzhardinge
2009-03-23 17:55 ` [PATCH 05/11] xen: add "capabilities" file Jeremy Fitzhardinge
2009-03-23 17:55 ` [PATCH 06/11] xen: add /sys/hypervisor support Jeremy Fitzhardinge
2009-03-23 17:55 ` [PATCH 07/11] xen/sys/hypervisor: change writable_pt to features Jeremy Fitzhardinge
2009-03-23 17:55 ` [PATCH 08/11] xen: drop kexec bits from /sys/hypervisor since kexec isn't implemented yet Jeremy Fitzhardinge
2009-03-23 17:55 ` [PATCH 09/11] xen: remove suspend_cancel hook Jeremy Fitzhardinge
2009-03-23 17:55 ` [PATCH 10/11] xen: use device model for suspending xenbus devices Jeremy Fitzhardinge
2009-03-23 17:55 ` [PATCH 11/11] xen/xenbus: export xenbus_dev_changed Jeremy Fitzhardinge
2009-03-23 18:09 ` [GIT PULL] xen/dom0: core dom0 support Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 01/15] xen dom0: Make hvc_xen console work for dom0 Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 02/15] xen dom0: Initialize xenbus " Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 03/15] xen dom0: Set up basic IO permissions " Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 04/15] xen dom0: Add support for the platform_ops hypercall Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 05/15] xen mtrr: Add mtrr_ops support for Xen mtrr Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 06/15] xen: disable PAT Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 07/15] xen/dom0: use _PAGE_IOMAP in ioremap to do machine mappings Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 08/15] xen/dom0: Use host E820 map Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 09/15] xen: implement XENMEM_machphys_mapping Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 10/15] xen: clear reserved bits in l3 entries given in the initial pagetables Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 11/15] xen: allow enable use of VGA console on dom0 Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 12/15] xen/dom0: add XEN_DOM0 config option Jeremy Fitzhardinge
2009-03-23 18:09 ` [PATCH 13/15] x86: make /dev/mem mappings _PAGE_IOMAP Jeremy Fitzhardinge
2009-03-23 18:09 ` Jeremy Fitzhardinge [this message]
2009-03-23 18:09 ` [PATCH 15/15] x86: don't need "changed" parameter for set_io_bitmap() Jeremy Fitzhardinge
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=1237831799-6568-15-git-send-email-jeremy@goop.org \
--to=jeremy@goop.org \
--cc=chtephan@leto.intern.saout.de \
--cc=hpa@zytor.com \
--cc=jeremy.fitzhardinge@citrix.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=x86@kernel.org \
--cc=xen-devel@lists.xensource.com \
/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.