From 9bd97f28fa79a13ab5e3bb321955c3bf7953b329 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 28 Nov 2005 19:48:54 +0100 Subject: [PATCH 01/12] Bundle vcpu_time and vcpu_info structures together into a single structure that is 64 bytes on x86. This ensures that indexing into the array is fast (power-of-two size) and that accesses are cache friendly (cache line size is usually 32 or 64 bytes). Rename vcpu_data to vcpu_info, vcpu_time to vcpu_info.time. Signed-off-by: Keir Fraser --- .../arch/ia64/xen/drivers/evtchn_ia64.c | 4 +- .../arch/xen/i386/kernel/entry.S | 2 +- .../arch/xen/i386/kernel/time.c | 7 ++- linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c | 2 +- linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c | 2 +- .../arch/xen/x86_64/kernel/xen_entry.S | 2 +- .../arch/xen/x86_64/mm/fault.c | 2 +- .../include/asm-xen/asm-i386/system.h | 12 ++-- .../include/asm-xen/asm-x86_64/system.h | 12 ++-- linux-2.6-xen-sparse/include/asm-xen/evtchn.h | 2 +- tools/libxc/xc_linux_build.c | 2 +- tools/libxc/xc_linux_restore.c | 2 +- tools/libxc/xc_vmx_build.c | 2 +- xen/arch/ia64/vmx/vmx_hypercall.c | 2 +- xen/arch/ia64/xen/domain.c | 6 +- xen/arch/x86/domain.c | 2 +- xen/arch/x86/domain_build.c | 2 +- xen/arch/x86/setup.c | 2 +- xen/arch/x86/time.c | 9 ++- xen/common/schedule.c | 2 +- xen/include/public/arch-x86_32.h | 2 +- xen/include/public/arch-x86_64.h | 2 +- xen/include/public/trace.h | 4 +- xen/include/public/xen.h | 59 +++++++++---------- 24 files changed, 73 insertions(+), 72 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c index 26ad8c3395..e8f9f863e9 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c +++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c @@ -155,7 +155,7 @@ irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs) unsigned int l1i, l2i, port; irqreturn_t (*handler)(int, void *, struct pt_regs *); shared_info_t *s = HYPERVISOR_shared_info; - vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()]; + vcpu_info_t *vcpu_info = &s->vcpu_info[smp_processor_id()]; vcpu_info->evtchn_upcall_mask = 1; vcpu_info->evtchn_upcall_pending = 0; @@ -203,7 +203,7 @@ int evtchn_irq = 0xe9; void __init evtchn_init(void) { shared_info_t *s = HYPERVISOR_shared_info; - vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()]; + vcpu_info_t *vcpu_info = &s->vcpu_info[smp_processor_id()]; #if 0 int ret; diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S index ad38d736c7..6522f7a249 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S @@ -81,7 +81,7 @@ VM_MASK = 0x00020000 #define evtchn_upcall_pending /* 0 */ #define evtchn_upcall_mask 1 -#define sizeof_vcpu_shift 4 +#define sizeof_vcpu_shift 6 #ifdef CONFIG_SMP #define preempt_disable(reg) incl TI_preempt_count(reg) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c index 4e363e55a0..915f7f033a 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c @@ -204,7 +204,8 @@ static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift) void init_cpu_khz(void) { u64 __cpu_khz = 1000000ULL << 32; - struct vcpu_time_info *info = &HYPERVISOR_shared_info->vcpu_time[0]; + struct vcpu_time_info *info; + info = &HYPERVISOR_shared_info->vcpu_info[0].time; do_div(__cpu_khz, info->tsc_to_system_mul); if ( info->tsc_shift < 0 ) cpu_khz = __cpu_khz << -info->tsc_shift; @@ -284,7 +285,7 @@ static void get_time_values_from_xen(void) struct vcpu_time_info *src; struct shadow_time_info *dst; - src = &s->vcpu_time[smp_processor_id()]; + src = &s->vcpu_info[smp_processor_id()].time; dst = &per_cpu(shadow_time, smp_processor_id()); do { @@ -306,7 +307,7 @@ static inline int time_values_up_to_date(int cpu) struct vcpu_time_info *src; struct shadow_time_info *dst; - src = &HYPERVISOR_shared_info->vcpu_time[cpu]; + src = &HYPERVISOR_shared_info->vcpu_info[cpu].time; dst = &per_cpu(shadow_time, cpu); return (dst->version == src->version); diff --git a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c index df9b971c87..23b0556347 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c @@ -291,7 +291,7 @@ fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code) int write; siginfo_t info; - address = HYPERVISOR_shared_info->vcpu_data[ + address = HYPERVISOR_shared_info->vcpu_info[ smp_processor_id()].arch.cr2; /* Set the "privileged fault" bit to something sane. */ diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c index c5ddef540b..7ebe3f5e58 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c @@ -154,7 +154,7 @@ asmlinkage void evtchn_do_upcall(struct pt_regs *regs) unsigned int l1i, l2i, port; int irq, cpu = smp_processor_id(); shared_info_t *s = HYPERVISOR_shared_info; - vcpu_info_t *vcpu_info = &s->vcpu_data[cpu]; + vcpu_info_t *vcpu_info = &s->vcpu_info[cpu]; vcpu_info->evtchn_upcall_pending = 0; diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S index bba3950aed..9b42d15566 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S @@ -5,7 +5,7 @@ #define evtchn_upcall_pending 0 #define evtchn_upcall_mask 1 -#define sizeof_vcpu_shift 5 +#define sizeof_vcpu_shift 6 #ifdef CONFIG_SMP //#define preempt_disable(reg) incl threadinfo_preempt_count(reg) diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c index 1c76222721..97e6ea1895 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c @@ -344,7 +344,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) #endif /* get the address */ - address = HYPERVISOR_shared_info->vcpu_data[ + address = HYPERVISOR_shared_info->vcpu_info[ smp_processor_id()].arch.cr2; if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h index 592f20023e..0b6948437d 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h @@ -501,7 +501,7 @@ __asm__ __volatile__("6667:movl %1, %0\n6668:\n" \ do { \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ _vcpu->evtchn_upcall_mask = 1; \ preempt_enable_no_resched(); \ barrier(); \ @@ -512,7 +512,7 @@ do { \ vcpu_info_t *_vcpu; \ barrier(); \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ _vcpu->evtchn_upcall_mask = 0; \ barrier(); /* unmask then check (avoid races) */ \ if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ @@ -524,7 +524,7 @@ do { \ do { \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ (x) = _vcpu->evtchn_upcall_mask; \ preempt_enable(); \ } while (0) @@ -534,7 +534,7 @@ do { \ vcpu_info_t *_vcpu; \ barrier(); \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \ barrier(); /* unmask then check (avoid races) */ \ if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ @@ -550,7 +550,7 @@ do { \ do { \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ (x) = _vcpu->evtchn_upcall_mask; \ _vcpu->evtchn_upcall_mask = 1; \ preempt_enable_no_resched(); \ @@ -568,7 +568,7 @@ do { \ ({ int ___x; \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ ___x = (_vcpu->evtchn_upcall_mask != 0); \ preempt_enable_no_resched(); \ ___x; }) diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h index bbecfc56ed..0b485568ac 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h @@ -325,7 +325,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, do { \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ _vcpu->evtchn_upcall_mask = 1; \ preempt_enable_no_resched(); \ barrier(); \ @@ -336,7 +336,7 @@ do { \ vcpu_info_t *_vcpu; \ barrier(); \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ _vcpu->evtchn_upcall_mask = 0; \ barrier(); /* unmask then check (avoid races) */ \ if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ @@ -348,7 +348,7 @@ do { \ do { \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ (x) = _vcpu->evtchn_upcall_mask; \ preempt_enable(); \ } while (0) @@ -358,7 +358,7 @@ do { \ vcpu_info_t *_vcpu; \ barrier(); \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \ barrier(); /* unmask then check (avoid races) */ \ if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ @@ -374,7 +374,7 @@ do { \ do { \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ (x) = _vcpu->evtchn_upcall_mask; \ _vcpu->evtchn_upcall_mask = 1; \ preempt_enable_no_resched(); \ @@ -394,7 +394,7 @@ void cpu_idle_wait(void); ({ int ___x; \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ ___x = (_vcpu->evtchn_upcall_mask != 0); \ preempt_enable_no_resched(); \ ___x; }) diff --git a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h index 82b13cef54..788e8d7b5e 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h +++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h @@ -102,7 +102,7 @@ static inline void mask_evtchn(int port) static inline void unmask_evtchn(int port) { shared_info_t *s = HYPERVISOR_shared_info; - vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()]; + vcpu_info_t *vcpu_info = &s->vcpu_info[smp_processor_id()]; synch_clear_bit(port, &s->evtchn_mask[0]); diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index d61ecfa549..1afea3cb39 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -657,7 +657,7 @@ static int setup_guest(int xc_handle, memset(shared_info, 0, sizeof(shared_info_t)); /* Mask all upcalls... */ for ( i = 0; i < MAX_VIRT_CPUS; i++ ) - shared_info->vcpu_data[i].evtchn_upcall_mask = 1; + shared_info->vcpu_info[i].evtchn_upcall_mask = 1; munmap(shared_info, PAGE_SIZE); diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 674915904c..f25c185abc 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -671,7 +671,7 @@ int xc_linux_restore(int xc_handle, int io_fd, memset(&(shared_info->evtchn_pending[0]), 0, sizeof (shared_info->evtchn_pending)); for ( i = 0; i < MAX_VIRT_CPUS; i++ ) - shared_info->vcpu_data[i].evtchn_pending_sel = 0; + shared_info->vcpu_info[i].evtchn_pending_sel = 0; /* Copy saved contents of shared-info page. No checking needed. */ page = xc_map_foreign_range( diff --git a/tools/libxc/xc_vmx_build.c b/tools/libxc/xc_vmx_build.c index 47cc1271cb..2146c83fc8 100644 --- a/tools/libxc/xc_vmx_build.c +++ b/tools/libxc/xc_vmx_build.c @@ -524,7 +524,7 @@ static int setup_guest(int xc_handle, memset(shared_info, 0, sizeof(shared_info_t)); /* Mask all upcalls... */ for ( i = 0; i < MAX_VIRT_CPUS; i++ ) - shared_info->vcpu_data[i].evtchn_upcall_mask = 1; + shared_info->vcpu_info[i].evtchn_upcall_mask = 1; munmap(shared_info, PAGE_SIZE); diff --git a/xen/arch/ia64/vmx/vmx_hypercall.c b/xen/arch/ia64/vmx/vmx_hypercall.c index 26f924196e..020c3e933f 100644 --- a/xen/arch/ia64/vmx/vmx_hypercall.c +++ b/xen/arch/ia64/vmx/vmx_hypercall.c @@ -198,7 +198,7 @@ static int do_set_shared_page(VCPU *vcpu, u64 gpa) if (o_info) { memcpy((void*)d->shared_info, (void*)o_info, PAGE_SIZE); for_each_vcpu(d, v) { - v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id]; + v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id]; } /* If original page belongs to xen heap, then relinguish back * to xen heap. Or else, leave to domain itself to decide. diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index bca625d77b..52c62d6f24 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -205,7 +205,7 @@ void arch_do_createdomain(struct vcpu *v) printf("arch_vcpu_info=%p\n", d->vcpu[0].arch.privregs); memset(d->vcpu.arch.privregs, 0, PAGE_SIZE); #endif - v->vcpu_info = &(d->shared_info->vcpu_data[0]); + v->vcpu_info = &(d->shared_info->vcpu_info[0]); d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME @@ -867,7 +867,7 @@ int construct_dom0(struct domain *d, /* Mask all upcalls... */ for ( i = 1; i < MAX_VIRT_CPUS; i++ ) - d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1; + d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1; #ifdef VALIDATE_VT /* Construct a frame-allocation list for the initial domain, since these @@ -997,7 +997,7 @@ int construct_domU(struct domain *d, /* Mask all upcalls... */ for ( i = 0; i < MAX_VIRT_CPUS; i++ ) - d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1; + d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1; /* Copy the OS image. */ printk("calling loaddomainelfimage(%p,%p)\n",d,image_start); diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 54d166485c..b244323369 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -266,7 +266,7 @@ void arch_do_createdomain(struct vcpu *v) d->shared_info = alloc_xenheap_page(); memset(d->shared_info, 0, PAGE_SIZE); - v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id]; + v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id]; v->cpumap = CPUMAP_RUNANYWHERE; SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d); diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index b83ea2c47c..3f96396877 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -597,7 +597,7 @@ int construct_dom0(struct domain *d, /* Mask all upcalls... */ for ( i = 0; i < MAX_VIRT_CPUS; i++ ) - d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1; + d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1; for ( i = 1; i < num_online_cpus(); i++ ) (void)alloc_vcpu(d, i, i); diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 01ed11af3f..625a2a0d52 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -432,7 +432,7 @@ void __init __start_xen(multiboot_info_t *mbi) BUG_ON(sizeof(start_info_t) > PAGE_SIZE); BUG_ON(sizeof(shared_info_t) > PAGE_SIZE); - BUG_ON(sizeof(vcpu_info_t) != (sizeof(unsigned long) * 4)); + BUG_ON(sizeof(vcpu_info_t) != 64); init_frametable(); diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index b5f7023bd6..7e7c40fca1 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -683,8 +683,11 @@ static inline void version_update_end(u32 *version) static inline void __update_dom_time(struct vcpu *v) { - struct cpu_time *t = &cpu_time[smp_processor_id()]; - struct vcpu_time_info *u = &v->domain->shared_info->vcpu_time[v->vcpu_id]; + struct cpu_time *t; + struct vcpu_time_info *u; + + t = &cpu_time[smp_processor_id()]; + u = &v->domain->shared_info->vcpu_info[v->vcpu_id].time; version_update_begin(&u->version); @@ -698,7 +701,7 @@ static inline void __update_dom_time(struct vcpu *v) void update_dom_time(struct vcpu *v) { - if ( v->domain->shared_info->vcpu_time[v->vcpu_id].tsc_timestamp != + if ( v->domain->shared_info->vcpu_info[v->vcpu_id].time.tsc_timestamp != cpu_time[smp_processor_id()].local_tsc_stamp ) __update_dom_time(v); } diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 7a0b622373..d74b3c8370 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -115,7 +115,7 @@ struct vcpu *alloc_vcpu( if ( vcpu_id != 0 ) { - v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id]; + v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id]; d->vcpu[v->vcpu_id-1]->next_in_list = v; set_bit(_VCPUF_down, &v->vcpu_flags); } diff --git a/xen/include/public/arch-x86_32.h b/xen/include/public/arch-x86_32.h index b11c482118..9d7b69f694 100644 --- a/xen/include/public/arch-x86_32.h +++ b/xen/include/public/arch-x86_32.h @@ -134,7 +134,7 @@ typedef struct arch_shared_info { typedef struct { unsigned long cr2; - unsigned long pad; /* sizeof(vcpu_info_t) == 16 */ + unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */ } arch_vcpu_info_t; #endif diff --git a/xen/include/public/arch-x86_64.h b/xen/include/public/arch-x86_64.h index e53df602ea..5e3b6a7671 100644 --- a/xen/include/public/arch-x86_64.h +++ b/xen/include/public/arch-x86_64.h @@ -203,7 +203,7 @@ typedef struct arch_shared_info { typedef struct { unsigned long cr2; - unsigned long pad; /* sizeof(vcpu_info_t) == 32 */ + unsigned long pad; /* sizeof(vcpu_info_t) == 64 */ } arch_vcpu_info_t; #endif /* !__ASSEMBLY__ */ diff --git a/xen/include/public/trace.h b/xen/include/public/trace.h index b9f139444e..cba4b261ca 100644 --- a/xen/include/public/trace.h +++ b/xen/include/public/trace.h @@ -72,8 +72,8 @@ struct t_rec { * field, indexes into an array of struct t_rec's. */ struct t_buf { - unsigned int cons; /* Next item to be consumed by control tools. */ - unsigned int prod; /* Next item to be produced by Xen. */ + uint32_t cons; /* Next item to be consumed by control tools. */ + uint32_t prod; /* Next item to be produced by Xen. */ /* 'nr_recs' records follow immediately after the meta-data header. */ }; diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index 2259fc3ba0..b27206caff 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -266,10 +266,31 @@ typedef struct */ #define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64) -/* - * Per-VCPU information goes here. This will be cleaned up more when Xen - * actually supports multi-VCPU guests. - */ +typedef struct vcpu_time_info { + /* + * Updates to the following values are preceded and followed by an + * increment of 'version'. The guest can therefore detect updates by + * looking for changes to 'version'. If the least-significant bit of + * the version number is set then an update is in progress and the guest + * must wait to read a consistent set of values. + * The correct way to interact with the version number is similar to + * Linux's seqlock: see the implementations of read_seqbegin/read_seqretry. + */ + uint32_t version; + uint32_t pad0; + uint64_t tsc_timestamp; /* TSC at last update of time vals. */ + uint64_t system_time; /* Time, in nanosecs, since boot. */ + /* + * Current system time: + * system_time + ((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul + * CPU frequency (Hz): + * ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift + */ + uint32_t tsc_to_system_mul; + int8_t tsc_shift; + int8_t pad1[3]; +} vcpu_time_info_t; /* 32 bytes */ + typedef struct vcpu_info { /* * 'evtchn_upcall_pending' is written non-zero by Xen to indicate @@ -300,39 +321,15 @@ typedef struct vcpu_info { uint8_t evtchn_upcall_mask; unsigned long evtchn_pending_sel; arch_vcpu_info_t arch; -} vcpu_info_t; - -typedef struct vcpu_time_info { - /* - * Updates to the following values are preceded and followed by an - * increment of 'version'. The guest can therefore detect updates by - * looking for changes to 'version'. If the least-significant bit of - * the version number is set then an update is in progress and the guest - * must wait to read a consistent set of values. - * The correct way to interact with the version number is similar to - * Linux's seqlock: see the implementations of read_seqbegin/read_seqretry. - */ - uint32_t version; - uint64_t tsc_timestamp; /* TSC at last update of time vals. */ - uint64_t system_time; /* Time, in nanosecs, since boot. */ - /* - * Current system time: - * system_time + ((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul - * CPU frequency (Hz): - * ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift - */ - uint32_t tsc_to_system_mul; - int8_t tsc_shift; -} vcpu_time_info_t; + vcpu_time_info_t time; +} vcpu_info_t; /* 64 bytes (x86) */ /* * Xen/kernel shared data -- pointer provided in start_info. * NB. We expect that this struct is smaller than a page. */ typedef struct shared_info { - vcpu_info_t vcpu_data[MAX_VIRT_CPUS]; - - vcpu_time_info_t vcpu_time[MAX_VIRT_CPUS]; + vcpu_info_t vcpu_info[MAX_VIRT_CPUS]; /* * A domain can create "event channels" on which it can send and receive From 7376dc02043c2a8c289e70c3441852e426332dc9 Mon Sep 17 00:00:00 2001 From: "rread@ubuntu.eng.hq.xensource.com" Date: Mon, 28 Nov 2005 12:16:27 -0700 Subject: [PATCH 02/12] Make psmouse module builtin. Signed-off-by: Robert Read --- linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 index 5bfa138e80..cc37afd455 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.12.6-xen -# Wed Nov 23 21:01:11 2005 +# Mon Nov 28 11:04:51 2005 # CONFIG_XEN=y CONFIG_ARCH_XEN=y @@ -1629,7 +1629,7 @@ CONFIG_KEYBOARD_LKKBD=m CONFIG_KEYBOARD_XTKBD=m CONFIG_KEYBOARD_NEWTON=m CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2=y CONFIG_MOUSE_SERIAL=m CONFIG_MOUSE_INPORT=m # CONFIG_MOUSE_ATIXL is not set From b8ae09f01c2bf4696d17d7c46a1fb5d5f0c245a5 Mon Sep 17 00:00:00 2001 From: "rread@ubuntu.eng.hq.xensource.com" Date: Mon, 28 Nov 2005 15:34:00 -0700 Subject: [PATCH 03/12] The device sharing check races when more than one file backed vbd is configured. Both of the files pick the same free loop device in the for loop, and then one fails to losetup. This patch will now retry if losetup fails until it succeeds or no more devices are available. Signed-off-by: Robert Read --- tools/examples/block | 90 ++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/tools/examples/block b/tools/examples/block index 0a98344ca5..04a00432ff 100644 --- a/tools/examples/block +++ b/tools/examples/block @@ -202,59 +202,61 @@ case "$command" in mount it read-write in a guest domain." fi - loopdev='' - for dev in /dev/loop* - do - if [ ! -b "$dev" ] - then - continue - fi - - f=$(losetup "$dev" 2>/dev/null) || f='()' - f=$(echo "$f" | sed -e 's/.*(\(.*\)).*/\1/g') - - log err "$file $f $dev" - - if [ "$f" ] - then - # $dev is in use. Check sharing. - - if [ "$mode" == 'no' ] + while true + do + loopdev='' + for dev in /dev/loop* + do + if [ ! -b "$dev" ] then continue fi - f=$(readlink -f "$f") + f=$(losetup "$dev" 2>/dev/null) || f='()' + f=$(echo "$f" | sed -e 's/.*(\(.*\)).*/\1/g') - if [ "$f" == "$file" ] + log err "$file $f $dev" + + if [ "$f" ] then - check_file_sharing "$file" "$dev" "$mode" - fi - else - # $dev is not in use, so we'll remember it for use later; we want - # to finish the sharing check first. - - if [ "$loopdev" == '' ] - then - loopdev="$dev" + # $dev is in use. Check sharing. + if [ "$mode" == 'no' ] + then + continue + fi + + f=$(readlink -f "$f") + + if [ "$f" == "$file" ] + then + check_file_sharing "$file" "$dev" "$mode" + fi + else + # $dev is not in use, so we'll remember it for use later; we want + # to finish the sharing check first. + + if [ "$loopdev" == '' ] + then + loopdev="$dev" + fi fi + done + + if [ "$loopdev" == '' ] + then + fatal 'Failed to find an unused loop device' fi - done - - if [ "$loopdev" == '' ] - then - fatal 'Failed to find an unused loop device' - fi - - if losetup "$loopdev" "$file" - then - xenstore_write "$XENBUS_PATH/node" "$loopdev" - write_dev "$loopdev" - exit 0 - else - fatal "losetup $loopdev $file failed" - fi + if losetup "$loopdev" "$file" + then + log err "mapped $file using $loopdev" + xenstore_write "$XENBUS_PATH/node" "$loopdev" + write_dev "$loopdev" + exit 0 + else + log err "losetup $loopdev $file failed, retry" + fi + done ;; esac ;; From 0cf194e2b0bd456191dadd51fe7a0ab880183330 Mon Sep 17 00:00:00 2001 From: "pl@us.ibm.com" Date: Tue, 29 Nov 2005 01:00:10 +0000 Subject: [PATCH 04/12] Fix minor traceback in xen-bugtool when send fails --- tools/python/xen/util/bugtool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/util/bugtool.py b/tools/python/xen/util/bugtool.py index 5c4ffc87b0..06c924beef 100644 --- a/tools/python/xen/util/bugtool.py +++ b/tools/python/xen/util/bugtool.py @@ -162,7 +162,7 @@ def send(bug, conn, fd, filename, username, password): print >>sys.stderr, ( 'Attach failed: %s %s.' % (response.status, response.reason)) elif not m or m.group(1) != 'Changes Submitted': - print >>sys.syderr, ( + print >>sys.stderr, ( 'Attach failed: got a page titled %s.' % m.group(1)) else: print "Attaching %s to bug %d succeeded." % (filename, bug) From e9b54a136b4a75a5fa58a78121e6182463454abb Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 29 Nov 2005 11:38:53 +0100 Subject: [PATCH 05/12] Fix a race condition for multi-thread qemu dma, where vmx linux guests show warning "dma interrupt lost" and dma becomes very slow. root cause: In the time between set ide irq and set dma status, if guest receive the irq and query the status, it will find the status is not ready and therefore treat it as pseudo interrupt. Change the order of set irq and set dma status fixes this issue. Signed-off-by: Ke Yu --- tools/ioemu/hw/ide.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/ioemu/hw/ide.c b/tools/ioemu/hw/ide.c index 71ad561154..7c012cebcb 100644 --- a/tools/ioemu/hw/ide.c +++ b/tools/ioemu/hw/ide.c @@ -669,6 +669,8 @@ static int ide_read_dma_cb(IDEState *s, } if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) { s->status = READY_STAT | SEEK_STAT; + s->bmdma->status &= ~BM_STATUS_DMAING; + s->bmdma->status |= BM_STATUS_INT; ide_set_irq(s); #ifdef DEBUG_IDE_ATAPI printf("dma status=0x%x\n", s->status); @@ -736,6 +738,8 @@ static int ide_write_dma_cb(IDEState *s, if (n == 0) { /* end of transfer */ s->status = READY_STAT | SEEK_STAT; + s->bmdma->status &= ~BM_STATUS_DMAING; + s->bmdma->status |= BM_STATUS_INT; ide_set_irq(s); return 0; } @@ -983,6 +987,8 @@ static int ide_atapi_cmd_read_dma_cb(IDEState *s, if (s->packet_transfer_size <= 0) { s->status = READY_STAT; s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; + s->bmdma->status &= ~BM_STATUS_DMAING; + s->bmdma->status |= BM_STATUS_INT; ide_set_irq(s); #ifdef DEBUG_IDE_ATAPI printf("dma status=0x%x\n", s->status); @@ -2065,8 +2071,6 @@ static void ide_dma_loop(BMDMAState *bm) } /* end of transfer */ the_end: - bm->status &= ~BM_STATUS_DMAING; - bm->status |= BM_STATUS_INT; bm->dma_cb = NULL; bm->ide_if = NULL; } From cd197e9a16e2703d120fc35335e6561a02140b3b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 29 Nov 2005 11:40:16 +0100 Subject: [PATCH 06/12] Clean up a previous qemu workaround where we use /etc/xen/qemu-vgaram-bin as vgabios. Signed-off-by: Ke Yu --- tools/ioemu/hw/vga.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tools/ioemu/hw/vga.c b/tools/ioemu/hw/vga.c index a18039ef63..bd4b72ac90 100644 --- a/tools/ioemu/hw/vga.c +++ b/tools/ioemu/hw/vga.c @@ -1834,16 +1834,6 @@ void vga_bios_init(VGAState *s) /* TODO:add vbe support if enable it */ - FILE *qemuf = fopen("/etc/xen/qemu-vgaram-bin", "rb"); - if (!qemuf) { - fprintf(logfile, "open qemu vgaram binary failed!\n"); - } else { - /*load vram contents, else vga console can't boot */ - qemu_get_buffer(qemuf, s->vram_ptr, 256*1024); - - fclose(qemuf); - } - } void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, From 13f24179796f39a1b0f9d4cc0f3ec621a96e770f Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 29 Nov 2005 11:42:21 +0100 Subject: [PATCH 07/12] Small fix for shadow mode: fix a p.t. limit check. Signed-off-by:Xiaofeng Ling --- xen/arch/x86/shadow.c | 2 +- xen/arch/x86/shadow32.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c index 3009c6f9b0..8819071b04 100644 --- a/xen/arch/x86/shadow.c +++ b/xen/arch/x86/shadow.c @@ -1333,7 +1333,7 @@ static u32 remove_all_write_access_in_ptpage( i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask) >> PGT_va_shift; - if ( (i >= 0 && i <= L1_PAGETABLE_ENTRIES) && + if ( (i >= 0 && i < L1_PAGETABLE_ENTRIES) && !l1e_has_changed(pt[i], match, flags) && fix_entry(d, &pt[i], &found, is_l1_shadow, max_refs_to_find) && !prediction ) diff --git a/xen/arch/x86/shadow32.c b/xen/arch/x86/shadow32.c index d6591f586a..b733c2586c 100644 --- a/xen/arch/x86/shadow32.c +++ b/xen/arch/x86/shadow32.c @@ -2146,7 +2146,7 @@ static u32 remove_all_write_access_in_ptpage( i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask) >> PGT_va_shift; - if ( (i >= 0 && i <= L1_PAGETABLE_ENTRIES) && + if ( (i >= 0 && i < L1_PAGETABLE_ENTRIES) && !l1e_has_changed(pt[i], match, flags) && fix_entry(d, &pt[i], &found, is_l1_shadow, max_refs_to_find) && !prediction ) From 9cb8877a0e6eec0445d57ea9c48a3290aa2fb798 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 29 Nov 2005 11:48:33 +0100 Subject: [PATCH 08/12] Fix vmx guest issue of allowing accessing supervisor page from user level program. In shadow fault, we need to check U/S bit in error code. It is just a fix for shadow32.c, for x86_64 code and public code, it is already handled. Signed-off-by: Xiaofeng Ling --- xen/arch/x86/shadow32.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/xen/arch/x86/shadow32.c b/xen/arch/x86/shadow32.c index b733c2586c..237f44e95a 100644 --- a/xen/arch/x86/shadow32.c +++ b/xen/arch/x86/shadow32.c @@ -2680,6 +2680,16 @@ int shadow_fault(unsigned long va, struct cpu_user_regs *regs) domain_crash_synchronous(); } + /* User access violation in guest? */ + if ( unlikely((regs->error_code & 4) && + !(l1e_get_flags(gpte) & _PAGE_USER))) + { + SH_VVLOG("shadow_fault - EXIT: wr fault on super page (%" PRIpte ")", + l1e_get_intpte(gpte)); + goto fail; + + } + if ( unlikely(!l1pte_write_fault(v, &gpte, &spte, va)) ) { SH_VVLOG("shadow_fault - EXIT: l1pte_write_fault failed"); @@ -2693,6 +2703,16 @@ int shadow_fault(unsigned long va, struct cpu_user_regs *regs) } else { + /* Read-protection violation in guest? */ + if ( unlikely((regs->error_code & 1) )) + { + SH_VVLOG("shadow_fault - EXIT: read fault on super page (%" PRIpte ")", + l1e_get_intpte(gpte)); + goto fail; + + } + + if ( !l1pte_read_fault(d, &gpte, &spte) ) { SH_VVLOG("shadow_fault - EXIT: l1pte_read_fault failed"); From 5da1debbbdbdb14450c48f49a55a2b6955ad4a62 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 29 Nov 2005 14:37:24 +0100 Subject: [PATCH 09/12] Remove shadow32 dead code (it's never built for other than x86_32). Signed-off-by: Keir Fraser --- xen/arch/x86/shadow32.c | 21 +-------------------- xen/arch/x86/shadow_public.c | 2 +- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/xen/arch/x86/shadow32.c b/xen/arch/x86/shadow32.c index 237f44e95a..8669fa9c9a 100644 --- a/xen/arch/x86/shadow32.c +++ b/xen/arch/x86/shadow32.c @@ -342,14 +342,10 @@ free_shadow_hl2_table(struct domain *d, unsigned long smfn) SH_VVLOG("%s: smfn=%lx freed", __func__, smfn); -#ifdef __i386__ if ( shadow_mode_external(d) ) limit = L2_PAGETABLE_ENTRIES; else limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE; -#else - limit = 0; /* XXX x86/64 XXX */ -#endif for ( i = 0; i < limit; i++ ) { @@ -740,11 +736,9 @@ static void alloc_monitor_pagetable(struct vcpu *v) mpl2e = (l2_pgentry_t *)map_domain_page(mmfn); memset(mpl2e, 0, PAGE_SIZE); -#ifdef __i386__ /* XXX screws x86/64 build */ memcpy(&mpl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE], HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t)); -#endif mpl2e[l2_table_offset(PERDOMAIN_VIRT_START)] = l2e_from_paddr(__pa(d->arch.mm_perdomain_pt), @@ -1034,7 +1028,7 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode) free_shadow_pages(d); /* - * Tear down it's counts by disassembling its page-table-based ref counts. + * Tear down its counts by disassembling its page-table-based ref counts. * Also remove CR3's gcount/tcount. * That leaves things like GDTs and LDTs and external refs in tact. * @@ -3274,14 +3268,10 @@ int check_l2_table( l2e_get_intpte(match)); } -#ifdef __i386__ if ( shadow_mode_external(d) ) limit = L2_PAGETABLE_ENTRIES; else limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE; -#else - limit = 0; /* XXX x86/64 XXX */ -#endif /* Check the whole L2. */ for ( i = 0; i < limit; i++ ) @@ -3343,14 +3333,10 @@ int _check_pagetable(struct vcpu *v, char *s) spl2e = (l2_pgentry_t *) map_domain_page(smfn); /* Go back and recurse. */ -#ifdef __i386__ if ( shadow_mode_external(d) ) limit = L2_PAGETABLE_ENTRIES; else limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE; -#else - limit = 0; /* XXX x86/64 XXX */ -#endif for ( i = 0; i < limit; i++ ) { @@ -3367,11 +3353,6 @@ int _check_pagetable(struct vcpu *v, char *s) unmap_domain_page(spl2e); unmap_domain_page(gpl2e); -#if 0 - SH_VVLOG("PT verified : l2_present = %d, l1_present = %d", - sh_l2_present, sh_l1_present); -#endif - out: if ( errors ) BUG(); diff --git a/xen/arch/x86/shadow_public.c b/xen/arch/x86/shadow_public.c index c2f2afd9f3..90ee6f07d6 100644 --- a/xen/arch/x86/shadow_public.c +++ b/xen/arch/x86/shadow_public.c @@ -1078,7 +1078,7 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode) free_shadow_pages(d); /* - * Tear down it's counts by disassembling its page-table-based ref counts. + * Tear down its counts by disassembling its page-table-based ref counts. * Also remove CR3's gcount/tcount. * That leaves things like GDTs and LDTs and external refs in tact. * From 7086b5730be9ed931d84444e694ed84ae35a4628 Mon Sep 17 00:00:00 2001 From: "smh22@firebug.cl.cam.ac.uk" Date: Tue, 29 Nov 2005 14:50:30 +0100 Subject: [PATCH 10/12] Cleanup backend block device logic under save/restore; this should fix the issues some people have seen with segfaults in vbd_translate and/or user-space hangs. Signed-off-by: Steven Hand --- .../drivers/xen/blkback/common.h | 8 +++++++- .../drivers/xen/blkback/interface.c | 4 +++- .../drivers/xen/blkback/xenbus.c | 19 +++++++++++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h index bd22c40332..96eafda2fe 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h @@ -38,6 +38,8 @@ struct vbd { struct block_device *bdev; }; +struct backend_info; + typedef struct blkif_st { /* Unique identifier for this interface. */ domid_t domid; @@ -48,8 +50,10 @@ typedef struct blkif_st { /* Comms information. */ blkif_back_ring_t blk_ring; struct vm_struct *blk_ring_area; - /* VBDs attached to this interface. */ + /* The VBD attached to this interface. */ struct vbd vbd; + /* Back pointer to the backend_info. */ + struct backend_info *be; /* Private fields. */ enum { DISCONNECTED, CONNECTED } status; #ifdef CONFIG_XEN_BLKDEV_TAP_BE @@ -103,6 +107,8 @@ void blkif_xenbus_init(void); irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs); +void update_blkif_status(blkif_t *blkif); + #endif /* __BLKIF__BACKEND__COMMON_H__ */ /* diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c index fd8eccec8d..900b482719 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c @@ -112,7 +112,9 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) blkif->irq = bind_evtchn_to_irqhandler( blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif); - blkif->status = CONNECTED; + + /* We're potentially connected now */ + update_blkif_status(blkif); return 0; } diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c index b119efa697..a5a3113e44 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c @@ -50,6 +50,16 @@ static void backend_changed(struct xenbus_watch *, const char **, unsigned int); +void update_blkif_status(blkif_t *blkif) +{ + if(blkif->irq && blkif->vbd.bdev) { + blkif->status = CONNECTED; + (void)blkif_be_int(0, blkif, NULL); + } + maybe_connect(blkif->be); +} + + static ssize_t show_physical_device(struct device *_dev, char *buf) { struct xenbus_device *dev = to_xenbus_device(_dev); @@ -81,6 +91,7 @@ static int blkback_remove(struct xenbus_device *dev) be->backend_watch.node = NULL; } if (be->blkif) { + be->blkif->status = DISCONNECTED; blkif_put(be->blkif); be->blkif = NULL; } @@ -123,6 +134,9 @@ static int blkback_probe(struct xenbus_device *dev, goto fail; } + /* setup back pointer */ + be->blkif->be = be; + err = xenbus_watch_path2(dev, dev->nodename, "physical-device", &be->backend_watch, backend_changed); if (err) @@ -209,7 +223,8 @@ static void backend_changed(struct xenbus_watch *watch, device_create_file(&dev->dev, &dev_attr_physical_device); device_create_file(&dev->dev, &dev_attr_mode); - maybe_connect(be); + /* We're potentially connected now */ + update_blkif_status(be->blkif); } } @@ -235,7 +250,7 @@ static void frontend_changed(struct xenbus_device *dev, if (err) { return; } - maybe_connect(be); + update_blkif_status(be->blkif); break; case XenbusStateClosing: From 98a54f8733a2868590a5127681099beb775711a6 Mon Sep 17 00:00:00 2001 From: "smh22@firebug.cl.cam.ac.uk" Date: Tue, 29 Nov 2005 15:54:44 +0100 Subject: [PATCH 11/12] Tidy up audit code for PAE plus avoid its use during live migrate where it is not strictly required. Signed-off-by: Steven Hand --- xen/arch/x86/audit.c | 71 ++++++++++++++++++++++-------------- xen/arch/x86/shadow_public.c | 64 +++++++++++++++++--------------- 2 files changed, 77 insertions(+), 58 deletions(-) diff --git a/xen/arch/x86/audit.c b/xen/arch/x86/audit.c index 16fda1ef6f..5affca0e72 100644 --- a/xen/arch/x86/audit.c +++ b/xen/arch/x86/audit.c @@ -51,7 +51,30 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) int errors = 0; int shadow_refcounts = !!shadow_mode_refcounts(d); int shadow_enabled = !!shadow_mode_enabled(d); - int l2limit; + + int l2limit( unsigned long mfn ) + { + + if ( shadow_mode_external(d) ) + return L2_PAGETABLE_ENTRIES; + +#ifdef __i386__ +#ifdef CONFIG_X86_PAE + /* 32b PAE */ + if ( (( frame_table[mfn].u.inuse.type_info & PGT_va_mask ) + >> PGT_va_shift) == 3 ) + return l2_table_offset(HYPERVISOR_VIRT_START); + else + return L2_PAGETABLE_ENTRIES; +#else + /* 32b non-PAE */ + return DOMAIN_ENTRIES_PER_L2_PAGETABLE; +#endif +#else + /* 64b */ + return 0; /* XXX x86/64 XXX */ +#endif + } void _adjust(struct pfn_info *page, int adjtype ADJUST_EXTRA_ARGS) { @@ -121,15 +144,15 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) void adjust_l2_page(unsigned long mfn, int shadow) { - unsigned long *pt = map_domain_page(mfn); + l2_pgentry_t *pt = map_domain_page(mfn); int i; u32 page_type; - for ( i = 0; i < l2limit; i++ ) + for ( i = 0; i < l2limit(mfn); i++ ) { - if ( pt[i] & _PAGE_PRESENT ) + if ( l2e_get_flags(pt[i]) & _PAGE_PRESENT ) { - unsigned long l1mfn = pt[i] >> PAGE_SHIFT; + unsigned long l1mfn = l2e_get_pfn(pt[i]); struct pfn_info *l1page = pfn_to_page(l1mfn); if ( noisy ) @@ -199,7 +222,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) if ( shadow_mode_translate(d) && !shadow_mode_external(d) ) { unsigned long hl2mfn = - pt[l2_table_offset(LINEAR_PT_VIRT_START)] >> PAGE_SHIFT; + l2e_get_pfn(pt[l2_table_offset(LINEAR_PT_VIRT_START)]); struct pfn_info *hl2page = pfn_to_page(hl2mfn); adjust(hl2page, 0); } @@ -209,14 +232,14 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) void adjust_hl2_page(unsigned long hl2mfn) { - unsigned long *pt = map_domain_page(hl2mfn); + l2_pgentry_t *pt = map_domain_page(hl2mfn); int i; - for ( i = 0; i < l2limit; i++ ) + for ( i = 0; i < l2limit(hl2mfn); i++ ) { - if ( pt[i] & _PAGE_PRESENT ) + if ( l2e_get_flags(pt[i]) & _PAGE_PRESENT ) { - unsigned long gmfn = pt[i] >> PAGE_SHIFT; + unsigned long gmfn = l2e_get_pfn(pt[i]); struct pfn_info *gpage = pfn_to_page(gmfn); if ( gmfn < 0x100 ) @@ -256,14 +279,14 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) void adjust_l1_page(unsigned long l1mfn) { - unsigned long *pt = map_domain_page(l1mfn); + l1_pgentry_t *pt = map_domain_page(l1mfn); int i; for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) { - if ( pt[i] & _PAGE_PRESENT ) + if ( l1e_get_flags(pt[i]) & _PAGE_PRESENT ) { - unsigned long gmfn = pt[i] >> PAGE_SHIFT; + unsigned long gmfn = l1e_get_pfn(pt[i]); struct pfn_info *gpage = pfn_to_page(gmfn); if ( gmfn < 0x100 ) @@ -280,7 +303,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) if ( noisy ) { - if ( pt[i] & _PAGE_RW ) + if ( l1e_get_flags(pt[i]) & _PAGE_RW ) { // If it's not a writable page, complain. // @@ -320,7 +343,7 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) } } - adjust(gpage, (pt[i] & _PAGE_RW) ? 1 : 0); + adjust(gpage, (l1e_get_flags(pt[i]) & _PAGE_RW) ? 1 : 0); } } @@ -544,15 +567,6 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) } } -#ifdef __i386__ - if ( shadow_mode_external(d) ) - l2limit = L2_PAGETABLE_ENTRIES; - else - l2limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE; -#else - l2limit = 0; /* XXX x86/64 XXX */ -#endif - adjust_for_pgtbase(); adjust_guest_pages(); @@ -604,16 +618,17 @@ void _audit_domain(struct domain *d, int flags) unsigned long mfn) { struct pfn_info *page = &frame_table[mfn]; - unsigned long *pt = map_domain_page(mfn); + l1_pgentry_t *pt = map_domain_page(mfn); int i; for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) { - if ( (pt[i] & _PAGE_PRESENT) && ((pt[i] >> PAGE_SHIFT) == xmfn) ) + if ( (l1e_get_flags(pt[i]) & _PAGE_PRESENT) && + (l1e_get_pfn(pt[i]) == xmfn) ) printk(" found dom=%d mfn=%lx t=%" PRtype_info " c=%08x " - "pt[i=%x]=%lx\n", + "pt[i=%x]=%" PRIpte "\n", d->domain_id, mfn, page->u.inuse.type_info, - page->count_info, i, pt[i]); + page->count_info, i, l1e_get_intpte(pt[i])); } unmap_domain_page(pt); diff --git a/xen/arch/x86/shadow_public.c b/xen/arch/x86/shadow_public.c index 90ee6f07d6..53abd4c13c 100644 --- a/xen/arch/x86/shadow_public.c +++ b/xen/arch/x86/shadow_public.c @@ -1077,36 +1077,40 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode) // free_shadow_pages(d); - /* - * Tear down its counts by disassembling its page-table-based ref counts. - * Also remove CR3's gcount/tcount. - * That leaves things like GDTs and LDTs and external refs in tact. - * - * Most pages will be writable tcount=0. - * Some will still be L1 tcount=0 or L2 tcount=0. - * Maybe some pages will be type none tcount=0. - * Pages granted external writable refs (via grant tables?) will - * still have a non-zero tcount. That's OK. - * - * gcounts will generally be 1 for PGC_allocated. - * GDTs and LDTs will have additional gcounts. - * Any grant-table based refs will still be in the gcount. - * - * We attempt to grab writable refs to each page (thus setting its type). - * Immediately put back those type refs. - * - * Assert that no pages are left with L1/L2/L3/L4 type. - */ - audit_adjust_pgtables(d, -1, 1); - d->arch.shadow_mode = mode; if ( shadow_mode_refcounts(d) ) { - struct list_head *list_ent = d->page_list.next; - while ( list_ent != &d->page_list ) - { - struct pfn_info *page = list_entry(list_ent, struct pfn_info, list); + struct list_head *list_ent; + + /* + * Tear down its counts by disassembling its page-table-based refcounts + * Also remove CR3's gcount/tcount. + * That leaves things like GDTs and LDTs and external refs in tact. + * + * Most pages will be writable tcount=0. + * Some will still be L1 tcount=0 or L2 tcount=0. + * Maybe some pages will be type none tcount=0. + * Pages granted external writable refs (via grant tables?) will + * still have a non-zero tcount. That's OK. + * + * gcounts will generally be 1 for PGC_allocated. + * GDTs and LDTs will have additional gcounts. + * Any grant-table based refs will still be in the gcount. + * + * We attempt to grab writable refs to each page thus setting its type + * Immediately put back those type refs. + * + * Assert that no pages are left with L1/L2/L3/L4 type. + */ + audit_adjust_pgtables(d, -1, 1); + + + for (list_ent = d->page_list.next; list_ent != &d->page_list; + list_ent = page->list.next) { + + struct pfn_info *page = list_entry(list_ent, + struct pfn_info, list); if ( !get_page_type(page, PGT_writable_page) ) BUG(); put_page_type(page); @@ -1114,14 +1118,14 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode) * We use tlbflush_timestamp as back pointer to smfn, and need to * clean up it. */ - if ( shadow_mode_external(d) ) + if (shadow_mode_external(d)) page->tlbflush_timestamp = 0; - list_ent = page->list.next; } + + audit_adjust_pgtables(d, 1, 1); + } - audit_adjust_pgtables(d, 1, 1); - return 0; nomem: From 79d1eef3ba686f5bbb57c2af263222fe36083ef6 Mon Sep 17 00:00:00 2001 From: "smh22@firebug.cl.cam.ac.uk" Date: Tue, 29 Nov 2005 15:57:42 +0100 Subject: [PATCH 12/12] Avoid audit code during live migrate on 32bit since it's not required. Signed-off-by: Steven Hand --- xen/arch/x86/shadow32.c | 64 ++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/xen/arch/x86/shadow32.c b/xen/arch/x86/shadow32.c index 8669fa9c9a..c3136ead72 100644 --- a/xen/arch/x86/shadow32.c +++ b/xen/arch/x86/shadow32.c @@ -1027,36 +1027,40 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode) // free_shadow_pages(d); - /* - * Tear down its counts by disassembling its page-table-based ref counts. - * Also remove CR3's gcount/tcount. - * That leaves things like GDTs and LDTs and external refs in tact. - * - * Most pages will be writable tcount=0. - * Some will still be L1 tcount=0 or L2 tcount=0. - * Maybe some pages will be type none tcount=0. - * Pages granted external writable refs (via grant tables?) will - * still have a non-zero tcount. That's OK. - * - * gcounts will generally be 1 for PGC_allocated. - * GDTs and LDTs will have additional gcounts. - * Any grant-table based refs will still be in the gcount. - * - * We attempt to grab writable refs to each page (thus setting its type). - * Immediately put back those type refs. - * - * Assert that no pages are left with L1/L2/L3/L4 type. - */ - audit_adjust_pgtables(d, -1, 1); - d->arch.shadow_mode = mode; if ( shadow_mode_refcounts(d) ) { - struct list_head *list_ent = d->page_list.next; - while ( list_ent != &d->page_list ) - { - struct pfn_info *page = list_entry(list_ent, struct pfn_info, list); + struct list_head *list_ent; + + /* + * Tear down its counts by disassembling its page-table-based refcounts + * Also remove CR3's gcount/tcount. + * That leaves things like GDTs and LDTs and external refs in tact. + * + * Most pages will be writable tcount=0. + * Some will still be L1 tcount=0 or L2 tcount=0. + * Maybe some pages will be type none tcount=0. + * Pages granted external writable refs (via grant tables?) will + * still have a non-zero tcount. That's OK. + * + * gcounts will generally be 1 for PGC_allocated. + * GDTs and LDTs will have additional gcounts. + * Any grant-table based refs will still be in the gcount. + * + * We attempt to grab writable refs to each page thus setting its type + * Immediately put back those type refs. + * + * Assert that no pages are left with L1/L2/L3/L4 type. + */ + audit_adjust_pgtables(d, -1, 1); + + + for (list_ent = d->page_list.next; list_ent != &d->page_list; + list_ent = page->list.next) { + + struct pfn_info *page = list_entry(list_ent, + struct pfn_info, list); if ( !get_page_type(page, PGT_writable_page) ) BUG(); put_page_type(page); @@ -1064,14 +1068,14 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode) * We use tlbflush_timestamp as back pointer to smfn, and need to * clean up it. */ - if ( shadow_mode_external(d) ) + if (shadow_mode_external(d)) page->tlbflush_timestamp = 0; - list_ent = page->list.next; } + + audit_adjust_pgtables(d, 1, 1); + } - audit_adjust_pgtables(d, 1, 1); - return 0; nomem: