diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-11-19 09:20:24 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-11-19 09:20:24 +0000 |
commit | 2f6c44762518809219acd1d4fcc576ca6e57204b (patch) | |
tree | f7b93783c1e160257a843514cf224e18a720d31a | |
parent | b19bc47c416b16f320e82cf82ece6b2074c94665 (diff) | |
download | xen-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.c | 67 | ||||
-rw-r--r-- | xen/arch/x86/setup.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/traps.c | 2 | ||||
-rw-r--r-- | xen/common/physdev.c | 17 | ||||
-rw-r--r-- | xen/include/asm-x86/processor.h | 21 | ||||
-rw-r--r-- | xen/include/xen/sched.h | 8 |
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; |