aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-11-19 09:20:24 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-11-19 09:20:24 +0000
commit2f6c44762518809219acd1d4fcc576ca6e57204b (patch)
treef7b93783c1e160257a843514cf224e18a720d31a
parentb19bc47c416b16f320e82cf82ece6b2074c94665 (diff)
downloadxen-2f6c44762518809219acd1d4fcc576ca6e57204b.tar.gz
xen-2f6c44762518809219acd1d4fcc576ca6e57204b.tar.bz2
xen-2f6c44762518809219acd1d4fcc576ca6e57204b.zip
bitkeeper revision 1.1159.180.1 (419dbad8-u4Z8SxMk3S7dzh4pdErPg)
I/O bitmap cleanups.
-rw-r--r--xen/arch/x86/domain.c67
-rw-r--r--xen/arch/x86/setup.c2
-rw-r--r--xen/arch/x86/traps.c2
-rw-r--r--xen/common/physdev.c17
-rw-r--r--xen/include/asm-x86/processor.h21
-rw-r--r--xen/include/xen/sched.h8
6 files changed, 34 insertions, 83 deletions
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 0ba36df0c0..69e1506a02 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -389,60 +389,23 @@ void switch_to(struct domain *prev_p, struct domain *next_p)
write_ptbase(&next_p->mm);
}
- if ( unlikely(prev_p->io_bitmap != NULL) ||
- unlikely(next_p->io_bitmap != NULL) )
+ if ( unlikely(prev_p->thread.io_bitmap != NULL) )
{
- if ( next_p->io_bitmap != NULL )
- {
- /* Copy in the appropriate parts of the IO bitmap. We use the
- * selector to copy only the interesting parts of the bitmap. */
-
- u64 old_sel = ~0ULL; /* IO bitmap selector for previous task. */
-
- if ( prev_p->io_bitmap != NULL)
- {
- old_sel = prev_p->io_bitmap_sel;
-
- /* Replace any areas of the IO bitmap that had bits cleared. */
- for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
- if ( !test_bit(i, &prev_p->io_bitmap_sel) )
- memcpy(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
- &next_p->io_bitmap[i * IOBMP_SELBIT_LWORDS],
- IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
- }
-
- /* Copy in any regions of the new task's bitmap that have bits
- * clear and we haven't already dealt with. */
- for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
- {
- if ( test_bit(i, &old_sel)
- && !test_bit(i, &next_p->io_bitmap_sel) )
- memcpy(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
- &next_p->io_bitmap[i * IOBMP_SELBIT_LWORDS],
- IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
- }
-
- tss->bitmap = IO_BITMAP_OFFSET;
-
- }
- else
- {
- /* In this case, we're switching FROM a task with IO port access,
- * to a task that doesn't use the IO bitmap. We set any TSS bits
- * that might have been cleared, ready for future use. */
- for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
- if ( !test_bit(i, &prev_p->io_bitmap_sel) )
- memset(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
- 0xFF, IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
+ for ( i = 0; i < sizeof(prev_p->thread.io_bitmap_sel) * 8; i++ )
+ if ( !test_bit(i, &prev_p->thread.io_bitmap_sel) )
+ memset(&tss->io_bitmap[i * IOBMP_BYTES_PER_SELBIT],
+ ~0U, IOBMP_BYTES_PER_SELBIT);
+ tss->bitmap = IOBMP_INVALID_OFFSET;
+ }
- /*
- * a bitmap offset pointing outside of the TSS limit
- * causes a nicely controllable SIGSEGV if a process
- * tries to use a port IO instruction. The first
- * sys_ioperm() call sets up the bitmap properly.
- */
- tss->bitmap = INVALID_IO_BITMAP_OFFSET;
- }
+ if ( unlikely(next_p->thread.io_bitmap != NULL) )
+ {
+ for ( i = 0; i < sizeof(next_p->thread.io_bitmap_sel) * 8; i++ )
+ if ( !test_bit(i, &next_p->thread.io_bitmap_sel) )
+ memcpy(&tss->io_bitmap[i * IOBMP_BYTES_PER_SELBIT],
+ &next_p->thread.io_bitmap[i * IOBMP_BYTES_PER_SELBIT],
+ IOBMP_BYTES_PER_SELBIT);
+ tss->bitmap = IOBMP_OFFSET;
}
set_current(next_p);
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index b565bbd083..7ed4bf0744 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -268,7 +268,7 @@ void __init cpu_init(void)
panic("CPU#%d already initialized!!!\n", nr);
printk("Initializing CPU#%d\n", nr);
- t->bitmap = INVALID_IO_BITMAP_OFFSET;
+ t->bitmap = IOBMP_INVALID_OFFSET;
memset(t->io_bitmap, ~0, sizeof(t->io_bitmap));
/* Set up GDT and IDT. */
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 3d11210dac..7b7c07142c 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -721,7 +721,7 @@ void __init trap_init(void)
tss->cs = __HYPERVISOR_CS;
tss->eip = (unsigned long)do_double_fault;
tss->eflags = 2;
- tss->bitmap = INVALID_IO_BITMAP_OFFSET;
+ tss->bitmap = IOBMP_INVALID_OFFSET;
_set_tssldt_desc(gdt_table+__DOUBLEFAULT_TSS_ENTRY,
(int)tss, 235, 0x89);
diff --git a/xen/common/physdev.c b/xen/common/physdev.c
index b1c16d00b3..728a8fe07f 100644
--- a/xen/common/physdev.c
+++ b/xen/common/physdev.c
@@ -169,16 +169,16 @@ int physdev_pci_access_modify(
/* Now, setup access to the IO ports and memory regions for the device. */
- if ( p->io_bitmap == NULL )
+ if ( p->thread.io_bitmap == NULL )
{
- if ( (p->io_bitmap = xmalloc(IO_BITMAP_BYTES)) == NULL )
+ if ( (p->thread.io_bitmap = xmalloc(IOBMP_BYTES)) == NULL )
{
rc = -ENOMEM;
goto out;
}
- memset(p->io_bitmap, 0xFF, IO_BITMAP_BYTES);
+ memset(p->thread.io_bitmap, 0xFF, IOBMP_BYTES);
- p->io_bitmap_sel = ~0ULL;
+ p->thread.io_bitmap_sel = ~0ULL;
}
for ( i = 0; i < DEVICE_COUNT_RESOURCE; i++ )
@@ -195,13 +195,8 @@ int physdev_pci_access_modify(
"for device %s\n", dom, r->start, r->end, pdev->slot_name);
for ( j = r->start; j < r->end + 1; j++ )
{
- clear_bit(j, p->io_bitmap);
- /* Record that we cleared a bit using bit n of the selector:
- * n = (j / (4 bytes in a word * 8 bits in a byte))
- * / number of words per selector bit
- */
- clear_bit((j / (8 * 4)) / IOBMP_SELBIT_LWORDS,
- &p->io_bitmap_sel);
+ clear_bit(j, p->thread.io_bitmap);
+ clear_bit(j / IOBMP_BITS_PER_SELBIT, &p->thread.io_bitmap_sel);
}
}
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index e8dde063e8..81d35ad324 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -244,15 +244,11 @@ static inline void clear_in_cr4 (unsigned long mask)
:"ax");
}
-/*
- * Size of io_bitmap in longwords:
- * For Xen we support the full 8kbyte IO bitmap but use the io_bitmap_sel field
- * to avoid a full 8kbyte copy when switching to domains with bits cleared.
- */
-#define IO_BITMAP_SIZE 2048
-#define IO_BITMAP_BYTES (IO_BITMAP_SIZE * 4)
-#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
-#define INVALID_IO_BITMAP_OFFSET 0x8000
+#define IOBMP_BYTES 8192
+#define IOBMP_BYTES_PER_SELBIT (IOBMP_BYTES / 64)
+#define IOBMP_BITS_PER_SELBIT (IOBMP_BYTES_PER_SELBIT * 8)
+#define IOBMP_OFFSET offsetof(struct tss_struct,io_bitmap)
+#define IOBMP_INVALID_OFFSET 0x8000
struct i387_state {
u8 state[512]; /* big enough for FXSAVE */
@@ -293,7 +289,7 @@ struct tss_struct {
u16 trace;
#endif
u16 bitmap;
- u32 io_bitmap[IO_BITMAP_SIZE+1];
+ u8 io_bitmap[IOBMP_BYTES];
/* Pads the TSS to be cacheline-aligned (total size is 0x2080). */
u32 __cacheline_filler[5];
};
@@ -335,6 +331,11 @@ struct thread_struct {
/* Bounce information for propagating an exception to guest OS. */
struct trap_bounce trap_bounce;
+ /* I/O-port access bitmap. */
+ u64 io_bitmap_sel; /* Selector to tell us which part of the IO bitmap are
+ * "interesting" (i.e. have clear bits) */
+ u8 *io_bitmap; /* Pointer to task's IO bitmap or NULL */
+
/* Trap info. */
#ifdef __i386__
int fast_trap_idx;
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index d7c8824d0a..d449f6bfaa 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -104,14 +104,6 @@ struct domain
spinlock_t pcidev_lock;
struct list_head pcidev_list;
- /* The following IO bitmap stuff is x86-dependent. */
- u64 io_bitmap_sel; /* Selector to tell us which part of the IO bitmap are
- * "interesting" (i.e. have clear bits) */
-
- /* Handy macro - number of bytes of the IO bitmap, per selector bit. */
-#define IOBMP_SELBIT_LWORDS (IO_BITMAP_SIZE / 64)
- unsigned long *io_bitmap; /* Pointer to task's IO bitmap or NULL */
-
unsigned long flags;
unsigned long vm_assist;