From f9709a1e43bbefc3396c47c411ad11d5cfb8ffc1 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Wed, 12 Oct 2005 09:26:23 -0600 Subject: [PATCH 01/36] Minor change needed for types rearrangement in xen-unstable 7339 --- xen/arch/ia64/vmx/mm.c | 2 +- xen/arch/ia64/vmx/vmx_hypercall.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/ia64/vmx/mm.c b/xen/arch/ia64/vmx/mm.c index 4d3ed238fa..cb69559462 100644 --- a/xen/arch/ia64/vmx/mm.c +++ b/xen/arch/ia64/vmx/mm.c @@ -87,7 +87,7 @@ */ #include -#include +//#include #include #include #include diff --git a/xen/arch/ia64/vmx/vmx_hypercall.c b/xen/arch/ia64/vmx/vmx_hypercall.c index 727a145033..26f924196e 100644 --- a/xen/arch/ia64/vmx/vmx_hypercall.c +++ b/xen/arch/ia64/vmx/vmx_hypercall.c @@ -22,7 +22,7 @@ #include #include #include -#include +//#include #include #include #include From 87b3b5b34a4d827047b612c7ef9647b07bd13114 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Wed, 12 Oct 2005 10:56:14 -0600 Subject: [PATCH 02/36] Fast hyperprivop for itc.i and itc.d (works, but default off for stability) --- xen/arch/ia64/asm-offsets.c | 3 + xen/arch/ia64/xen/hyperprivop.S | 164 +++++++++++++++++++++++++++++++- 2 files changed, 162 insertions(+), 5 deletions(-) diff --git a/xen/arch/ia64/asm-offsets.c b/xen/arch/ia64/asm-offsets.c index d1a6893fdd..ed770ee725 100644 --- a/xen/arch/ia64/asm-offsets.c +++ b/xen/arch/ia64/asm-offsets.c @@ -82,10 +82,13 @@ void foo(void) DEFINE(IA64_TASK_THREAD_KSP_OFFSET, offsetof (struct vcpu, arch._thread.ksp)); DEFINE(IA64_TASK_THREAD_ON_USTACK_OFFSET, offsetof (struct vcpu, arch._thread.on_ustack)); + DEFINE(IA64_VCPU_DOMAIN_OFFSET, offsetof (struct vcpu, domain)); DEFINE(IA64_VCPU_META_RR0_OFFSET, offsetof (struct vcpu, arch.metaphysical_rr0)); DEFINE(IA64_VCPU_META_SAVED_RR0_OFFSET, offsetof (struct vcpu, arch.metaphysical_saved_rr0)); DEFINE(IA64_VCPU_BREAKIMM_OFFSET, offsetof (struct vcpu, arch.breakimm)); DEFINE(IA64_VCPU_IVA_OFFSET, offsetof (struct vcpu, arch.iva)); + DEFINE(IA64_VCPU_DTLB_PTE_OFFSET, offsetof (struct vcpu, arch.dtlb_pte)); + DEFINE(IA64_VCPU_ITLB_PTE_OFFSET, offsetof (struct vcpu, arch.itlb_pte)); DEFINE(IA64_VCPU_IRR0_OFFSET, offsetof (struct vcpu, arch.irr[0])); DEFINE(IA64_VCPU_IRR3_OFFSET, offsetof (struct vcpu, arch.irr[3])); DEFINE(IA64_VCPU_INSVC3_OFFSET, offsetof (struct vcpu, arch.insvc[3])); diff --git a/xen/arch/ia64/xen/hyperprivop.S b/xen/arch/ia64/xen/hyperprivop.S index cddfba7f69..e20b5d91e3 100644 --- a/xen/arch/ia64/xen/hyperprivop.S +++ b/xen/arch/ia64/xen/hyperprivop.S @@ -14,6 +14,10 @@ #include #include +#define _PAGE_PPN_MASK 0x0003fffffffff000 //asm/pgtable.h doesn't do assembly +#define PAGE_PHYS 0x0010000000000761 //__pgprot(__DIRTY_BITS|_PAGE_PL_2|_PAGE_AR_RWX) +#define _PAGE_PL_2 (2<<7) + #if 1 // change to 0 to turn off all fast paths #define FAST_HYPERPRIVOPS #define FAST_HYPERPRIVOP_CNT @@ -24,6 +28,7 @@ #define FAST_RFI #define FAST_SSM_I #define FAST_PTC_GA +#undef FAST_ITC // working but default off for now #undef RFI_TO_INTERRUPT // not working yet #endif @@ -1663,10 +1668,159 @@ ENTRY(hyper_ptc_ga) ;; END(hyper_ptc_ga) -ENTRY(hyper_itc_d) - br.spnt.many dispatch_break_fault ;; -END(hyper_itc_d) - +// Registers at entry +// r17 = break immediate (XEN_HYPER_ITC_D or I) +// r18 == XSI_PSR_IC_OFS +// r31 == pr +GLOBAL_ENTRY(hyper_itc) ENTRY(hyper_itc_i) + // fall through, hyper_itc_d handles both i and d +ENTRY(hyper_itc_d) +#ifndef FAST_ITC br.spnt.many dispatch_break_fault ;; -END(hyper_itc_i) +#endif + adds r23=XSI_ITIR_OFS-XSI_PSR_IC_OFS,r18 ;; + ld8 r23=[r23];; + extr.u r24=r23,2,6;; // r24==logps + cmp.gt p7,p0=PAGE_SHIFT,r24 +(p7) br.spnt.many dispatch_break_fault ;; + // translate_domain_pte(r8=pteval,PSCB(ifa)=address,r24=itir) + mov r19=1;; + shl r20=r19,r24;; + adds r20=-1,r20;; // r20 == mask + movl r19=_PAGE_PPN_MASK;; + and r22=r8,r19;; // r22 == pteval & _PAGE_PPN_MASK + andcm r19=r22,r20;; + adds r21=XSI_IFA_OFS-XSI_PSR_IC_OFS,r18 ;; + ld8 r21=[r21];; + and r20=r21,r20;; + or r19=r19,r20;; // r19 == mpaddr + movl r27=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; + ld8 r27=[r27];; + adds r27=IA64_VCPU_DOMAIN_OFFSET,r27;; + ld8 r27=[r27];; +// FIXME: is the global var dom0 always pinned? assume so for now + movl r28=dom0;; + ld8 r28=[r28];; +// FIXME: for now, only handle dom0 (see lookup_domain_mpa below) + cmp.ne p7,p0=r27,r28 +(p7) br.spnt.many dispatch_break_fault ;; + // if region 6, go slow way +#ifdef FAST_HYPERPRIVOP_CNT + cmp.eq p6,p7=XEN_HYPER_ITC_D,r17;; +(p6) movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_ITC_D);; +(p7) movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_ITC_I);; + ld8 r21=[r20];; + adds r21=1,r21;; + st8 [r20]=r21;; +#endif +// FIXME: for now, just do domain0 and skip mpaddr range checks + dep r20=r0,r19,0,PAGE_SHIFT + movl r21=PAGE_PHYS ;; + or r20=r20,r21 ;; // r20==return value from lookup_domain_mpa + // r8=pteval,r20=pteval2 + movl r19=_PAGE_PPN_MASK + movl r21=_PAGE_PL_2;; + andcm r25=r8,r19;; // r25==pteval & ~_PAGE_PPN_MASK + and r22=r20,r19;; + or r22=r22,r21;; + or r22=r22,r25;; // r22==return value from translate_domain_pte + // done with translate_domain_pte + // now do vcpu_itc_no_srlz(vcpu,IorD,ifa,r22=pte,r8=mppte,r24=logps) +// FIXME: for now, just domain0 and skip range check + // psr.ic already cleared + // NOTE: r24 still contains ps (from above) + shladd r24=r24,2,r0;; + mov cr.itir=r24;; + adds r23=XSI_IFA_OFS-XSI_PSR_IC_OFS,r18 ;; + ld8 r23=[r23];; + mov cr.ifa=r23;; + cmp.eq p6,p7=XEN_HYPER_ITC_D,r17;; +(p6) itc.d r22;; +(p7) itc.i r22;; + dv_serialize_data + // FIXME: how do I make assembler warnings go away here? + // vhpt_insert(r23=vaddr,r22=pte,r24=logps<<2) + thash r28=r23 + or r26=1,r22;; + ttag r21=r23 + adds r25=8,r28 + mov r19=r28;; + st8 [r25]=r24 + adds r20=16,r28;; + st8 [r19]=r26 + st8 [r20]=r21;; + // vcpu_set_tr_entry(trp,r22=pte|1,r24=itir,r23=ifa) + // TR_ENTRY = {page_flags,itir,addr,rid} + cmp.eq p6,p7=XEN_HYPER_ITC_D,r17 + movl r27=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; + ld8 r27=[r27];; + adds r28=IA64_VCPU_STARTING_RID_OFFSET,r27 +(p6) adds r27=IA64_VCPU_DTLB_OFFSET,r27 +(p7) adds r27=IA64_VCPU_ITLB_OFFSET,r27;; + st8 [r27]=r22,8;; // page_flags: already has pl >= 2 and p==1 + st8 [r27]=r24,8;; // itir + mov r19=-4096;; + and r23=r23,r19;; + st8 [r27]=r23,8;; // ifa & ~0xfff +// ?? is virtualize_rid(v,get_rr(ifa))==vcpu_get_rr(ifa)?? YES!! + adds r29 = XSI_RR0_OFS-XSI_PSR_IC_OFS,r18 + extr.u r25=r23,61,3;; + shladd r29=r25,3,r29;; + ld8 r29=[r29];; + movl r20=0xffffff00;; + and r29=r29,r20;; + st8 [r27]=r29,-8;; // rid + //if ps > 12 + cmp.eq p7,p0=12<<2,r24 +(p7) br.cond.sptk.many 1f;; + // if (ps > 12) { + // trp->ppn &= ~((1UL<<(ps-12))-1); trp->vadr &= ~((1UL< Date: Wed, 12 Oct 2005 17:12:59 -0600 Subject: [PATCH 03/36] Initial SMP support Signed-off by: Tristan Gingold --- xen/arch/ia64/linux-xen/head.S | 6 +- xen/arch/ia64/linux-xen/irq_ia64.c | 3 + xen/arch/ia64/linux-xen/mm_contig.c | 4 +- xen/arch/ia64/linux-xen/setup.c | 44 +++++++++----- xen/arch/ia64/linux-xen/smp.c | 27 ++++++--- xen/arch/ia64/linux-xen/smpboot.c | 16 +++++ xen/arch/ia64/xen/acpi.c | 21 +++++-- xen/arch/ia64/xen/domain.c | 60 +++++++++---------- xen/arch/ia64/xen/process.c | 12 ++++ xen/arch/ia64/xen/xenirq.c | 18 +++--- xen/arch/ia64/xen/xenmisc.c | 5 +- xen/arch/ia64/xen/xensetup.c | 31 ++++++---- xen/arch/ia64/xen/xentime.c | 6 +- xen/include/asm-ia64/config.h | 12 ++-- xen/include/asm-ia64/linux-xen/asm/spinlock.h | 9 +++ .../asm-ia64/linux-xen/linux/hardirq.h | 4 -- .../asm-ia64/linux-xen/linux/interrupt.h | 2 + 17 files changed, 184 insertions(+), 96 deletions(-) diff --git a/xen/arch/ia64/linux-xen/head.S b/xen/arch/ia64/linux-xen/head.S index 9da143d979..14e919ddf0 100644 --- a/xen/arch/ia64/linux-xen/head.S +++ b/xen/arch/ia64/linux-xen/head.S @@ -324,6 +324,9 @@ start_ap: mov r16=-1 (isBP) br.cond.dpnt .load_current // BP stack is on region 5 --- no need to map it +#ifndef XEN + // XEN: stack is allocated in xenheap, which is currently always + // mapped. // load mapping for stack (virtaddr in r2, physaddr in r3) rsm psr.ic movl r17=PAGE_KERNEL @@ -353,7 +356,8 @@ start_ap: ssm psr.ic srlz.d ;; - +#endif + .load_current: // load the "current" pointer (r13) and ar.k6 with the current task #if defined(XEN) && defined(VALIDATE_VT) diff --git a/xen/arch/ia64/linux-xen/irq_ia64.c b/xen/arch/ia64/linux-xen/irq_ia64.c index 5436ef8694..c036ed08ee 100644 --- a/xen/arch/ia64/linux-xen/irq_ia64.c +++ b/xen/arch/ia64/linux-xen/irq_ia64.c @@ -281,5 +281,8 @@ ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect) ipi_data = (delivery_mode << 8) | (vector & 0xff); ipi_addr = ipi_base_addr + ((phys_cpu_id << 4) | ((redirect & 1) << 3)); +#ifdef XEN + printf ("send_ipi to %d (%x)\n", cpu, phys_cpu_id); +#endif writeq(ipi_data, ipi_addr); } diff --git a/xen/arch/ia64/linux-xen/mm_contig.c b/xen/arch/ia64/linux-xen/mm_contig.c index 6b9ee53aca..896a871c3b 100644 --- a/xen/arch/ia64/linux-xen/mm_contig.c +++ b/xen/arch/ia64/linux-xen/mm_contig.c @@ -193,8 +193,8 @@ per_cpu_init (void) */ if (smp_processor_id() == 0) { #ifdef XEN - cpu_data = alloc_xenheap_pages(PERCPU_PAGE_SHIFT - - PAGE_SHIFT + get_order(NR_CPUS)); + cpu_data = alloc_xenheap_pages(get_order(NR_CPUS + * PERCPU_PAGE_SIZE)); #else cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS, PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); diff --git a/xen/arch/ia64/linux-xen/setup.c b/xen/arch/ia64/linux-xen/setup.c index ba7f91098d..7f351dd05c 100644 --- a/xen/arch/ia64/linux-xen/setup.c +++ b/xen/arch/ia64/linux-xen/setup.c @@ -366,6 +366,7 @@ check_for_logical_procs (void) } #endif +void __init #ifdef XEN early_setup_arch (char **cmdline_p) #else @@ -377,14 +378,12 @@ setup_arch (char **cmdline_p) ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist); *cmdline_p = __va(ia64_boot_param->command_line); -#ifdef XEN - efi_init(); -#else +#ifndef XEN strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE); +#endif efi_init(); io_port_init(); -#endif #ifdef CONFIG_IA64_GENERIC { @@ -414,11 +413,17 @@ setup_arch (char **cmdline_p) #ifdef XEN early_cmdline_parse(cmdline_p); cmdline_parse(*cmdline_p); -#undef CONFIG_ACPI_BOOT #endif if (early_console_setup(*cmdline_p) == 0) mark_bsp_online(); +#ifdef XEN +} + +void __init +late_setup_arch (char **cmdline_p) +{ +#endif #ifdef CONFIG_ACPI_BOOT /* Initialize the ACPI boot-time table parser */ acpi_table_init(); @@ -433,20 +438,16 @@ setup_arch (char **cmdline_p) #ifndef XEN find_memory(); -#else - io_port_init(); -} - -void __init -late_setup_arch (char **cmdline_p) -{ -#undef CONFIG_ACPI_BOOT - acpi_table_init(); #endif + /* process SAL system table: */ ia64_sal_init(efi.sal_systab); #ifdef CONFIG_SMP +#ifdef XEN + init_smp_config (); +#endif + cpu_physical_id(0) = hard_smp_processor_id(); cpu_set(0, cpu_sibling_map[0]); @@ -768,6 +769,11 @@ cpu_init (void) cpu_data = per_cpu_init(); +#ifdef XEN + printf ("cpu_init: current=%p, current->domain->arch.mm=%p\n", + current, current->domain->arch.mm); +#endif + /* * We set ar.k3 so that assembly code in MCA handler can compute * physical addresses of per cpu variables with a simple: @@ -887,6 +893,16 @@ cpu_init (void) #ifndef XEN pm_idle = default_idle; #endif + +#ifdef XEN + /* surrender usage of kernel registers to domain, use percpu area instead */ + __get_cpu_var(cpu_kr)._kr[IA64_KR_IO_BASE] = ia64_get_kr(IA64_KR_IO_BASE); + __get_cpu_var(cpu_kr)._kr[IA64_KR_PER_CPU_DATA] = ia64_get_kr(IA64_KR_PER_CPU_DATA); + __get_cpu_var(cpu_kr)._kr[IA64_KR_CURRENT_STACK] = ia64_get_kr(IA64_KR_CURRENT_STACK); + __get_cpu_var(cpu_kr)._kr[IA64_KR_FPU_OWNER] = ia64_get_kr(IA64_KR_FPU_OWNER); + __get_cpu_var(cpu_kr)._kr[IA64_KR_CURRENT] = ia64_get_kr(IA64_KR_CURRENT); + __get_cpu_var(cpu_kr)._kr[IA64_KR_PT_BASE] = ia64_get_kr(IA64_KR_PT_BASE); +#endif } void diff --git a/xen/arch/ia64/linux-xen/smp.c b/xen/arch/ia64/linux-xen/smp.c index 28c294a247..74f932137e 100644 --- a/xen/arch/ia64/linux-xen/smp.c +++ b/xen/arch/ia64/linux-xen/smp.c @@ -63,9 +63,18 @@ void flush_tlb_mask(cpumask_t mask) //Huh? This seems to be used on ia64 even if !CONFIG_SMP void smp_send_event_check_mask(cpumask_t mask) { - printf("smp_send_event_check_mask called\n"); - //dummy(); - //send_IPI_mask(cpu_mask, EVENT_CHECK_VECTOR); + int cpu; + + /* Not for me. */ + cpu_clear(smp_processor_id(), mask); + if (cpus_empty(mask)) + return; + + printf("smp_send_event_check_mask called\n"); + + for (cpu = 0; cpu < NR_CPUS; ++cpu) + if (cpu_isset(cpu, mask)) + platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0); } @@ -249,6 +258,7 @@ send_IPI_self (int op) send_IPI_single(smp_processor_id(), op); } +#ifndef XEN /* * Called with preeemption disabled. */ @@ -257,6 +267,7 @@ smp_send_reschedule (int cpu) { platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0); } +#endif void smp_flush_tlb_all (void) @@ -395,15 +406,14 @@ smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wai if (wait) atomic_set(&data.finished, 0); - printk("smp_call_function: about to spin_lock \n"); spin_lock(&call_lock); - printk("smp_call_function: done with spin_lock \n"); +#if 0 //def XEN + printk("smp_call_function: %d lock\n", smp_processor_id ()); +#endif call_data = &data; mb(); /* ensure store to call_data precedes setting of IPI_CALL_FUNC */ - printk("smp_call_function: about to send_IPI \n"); send_IPI_allbutself(IPI_CALL_FUNC); - printk("smp_call_function: done with send_IPI \n"); /* Wait for response */ while (atomic_read(&data.started) != cpus) @@ -414,9 +424,10 @@ smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wai cpu_relax(); call_data = NULL; - printk("smp_call_function: about to spin_unlock \n"); spin_unlock(&call_lock); +#if 0 //def XEN printk("smp_call_function: DONE WITH spin_unlock, returning \n"); +#endif return 0; } EXPORT_SYMBOL(smp_call_function); diff --git a/xen/arch/ia64/linux-xen/smpboot.c b/xen/arch/ia64/linux-xen/smpboot.c index 1c0e84e31d..89f6829648 100644 --- a/xen/arch/ia64/linux-xen/smpboot.c +++ b/xen/arch/ia64/linux-xen/smpboot.c @@ -477,6 +477,22 @@ do_boot_cpu (int sapicid, int cpu) do_rest: task_for_booting_cpu = c_idle.idle; +#else + struct domain *idle; + struct vcpu *v; + void *stack; + + if ( (idle = do_createdomain(IDLE_DOMAIN_ID, cpu)) == NULL ) + panic("failed 'createdomain' for CPU %d", cpu); + set_bit(_DOMF_idle_domain, &idle->domain_flags); + v = idle->vcpu[0]; + + printf ("do_boot_cpu: cpu=%d, domain=%p, vcpu=%p\n", cpu, idle, v); + + task_for_booting_cpu = v; + + /* Set cpu number. */ + get_thread_info(v)->cpu = cpu; #endif Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid); diff --git a/xen/arch/ia64/xen/acpi.c b/xen/arch/ia64/xen/acpi.c index 6dbc687b8b..f0eab76870 100644 --- a/xen/arch/ia64/xen/acpi.c +++ b/xen/arch/ia64/xen/acpi.c @@ -121,6 +121,7 @@ acpi_get_sysname (void) #ifdef CONFIG_ACPI_BOOT #define ACPI_MAX_PLATFORM_INTERRUPTS 256 +#define NR_IOSAPICS 4 #if 0 /* Array to record platform interrupt vectors for generic interrupt routing. */ @@ -162,7 +163,6 @@ static int available_cpus __initdata; struct acpi_table_madt * acpi_madt __initdata; static u8 has_8259; -#if 0 static int __init acpi_parse_lapic_addr_ovr ( acpi_table_entry_header *header, const unsigned long end) @@ -247,12 +247,13 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end) acpi_table_print_madt_entry(header); +#if 0 iosapic_init(iosapic->address, iosapic->global_irq_base); +#endif return 0; } - static int __init acpi_parse_plat_int_src ( acpi_table_entry_header *header, const unsigned long end) @@ -267,6 +268,7 @@ acpi_parse_plat_int_src ( acpi_table_print_madt_entry(header); +#if 0 /* * Get vector assignment for this interrupt, set attributes, * and program the IOSAPIC routing table. @@ -280,6 +282,7 @@ acpi_parse_plat_int_src ( (plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); platform_intr_list[plintsrc->type] = vector; +#endif return 0; } @@ -297,13 +300,14 @@ acpi_parse_int_src_ovr ( acpi_table_print_madt_entry(header); +#if 0 iosapic_override_isa_irq(p->bus_irq, p->global_irq, (p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, (p->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); +#endif return 0; } - static int __init acpi_parse_nmi_src (acpi_table_entry_header *header, const unsigned long end) { @@ -331,8 +335,10 @@ void __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) */ sal_platform_features |= IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT; +#if 0 /*Start cyclone clock*/ cyclone_setup(0); +#endif } } @@ -350,7 +356,9 @@ acpi_parse_madt (unsigned long phys_addr, unsigned long size) #else has_8259 = acpi_madt->flags.pcat_compat; #endif +#if 0 iosapic_system_init(has_8259); +#endif /* Get base address of IPI Message Block */ @@ -364,7 +372,6 @@ acpi_parse_madt (unsigned long phys_addr, unsigned long size) return 0; } -#endif #ifdef CONFIG_ACPI_NUMA @@ -529,6 +536,7 @@ acpi_register_gsi (u32 gsi, int polarity, int trigger) return acpi_register_irq(gsi, polarity, trigger); } EXPORT_SYMBOL(acpi_register_gsi); +#endif static int __init acpi_parse_fadt (unsigned long phys_addr, unsigned long size) { @@ -550,10 +558,11 @@ acpi_parse_fadt (unsigned long phys_addr, unsigned long size) if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES) acpi_legacy_devices = 1; +#if 0 acpi_register_gsi(fadt->sci_int, ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE); +#endif return 0; } -#endif unsigned long __init acpi_find_rsdp (void) @@ -567,7 +576,6 @@ acpi_find_rsdp (void) return rsdp_phys; } -#if 0 int __init acpi_boot_init (void) { @@ -646,6 +654,7 @@ acpi_boot_init (void) printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); return 0; } +#if 0 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq) { diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 4cd54a0b8c..7c9b0ddc11 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -23,6 +23,7 @@ #include #include #include +#include //#include #include #include @@ -75,35 +76,21 @@ void free_perdomain_pt(struct domain *d) //free_page((unsigned long)d->mm.perdomain_pt); } -int hlt_counter; - -void disable_hlt(void) -{ - hlt_counter++; -} - -void enable_hlt(void) -{ - hlt_counter--; -} - static void default_idle(void) { - if ( hlt_counter == 0 ) - { + int cpu = smp_processor_id(); local_irq_disable(); - if ( !softirq_pending(smp_processor_id()) ) + if ( !softirq_pending(cpu)) safe_halt(); - //else - local_irq_enable(); - } + local_irq_enable(); } -void continue_cpu_idle_loop(void) +static void continue_cpu_idle_loop(void) { int cpu = smp_processor_id(); for ( ; ; ) { + printf ("idle%dD\n", cpu); #ifdef IA64 // __IRQ_STAT(cpu, idle_timestamp) = jiffies #else @@ -111,23 +98,32 @@ void continue_cpu_idle_loop(void) #endif while ( !softirq_pending(cpu) ) default_idle(); + add_preempt_count(SOFTIRQ_OFFSET); raise_softirq(SCHEDULE_SOFTIRQ); do_softirq(); + sub_preempt_count(SOFTIRQ_OFFSET); } } void startup_cpu_idle_loop(void) { + int cpu = smp_processor_id (); /* Just some sanity to ensure that the scheduler is set up okay. */ ASSERT(current->domain == IDLE_DOMAIN_ID); + printf ("idle%dA\n", cpu); raise_softirq(SCHEDULE_SOFTIRQ); +#if 0 /* All this work is done within continue_cpu_idle_loop */ + printf ("idle%dB\n", cpu); + asm volatile ("mov ar.k2=r0"); do_softirq(); + printf ("idle%dC\n", cpu); /* * Declares CPU setup done to the boot processor. * Therefore memory barrier to ensure state is visible. */ smp_mb(); +#endif #if 0 //do we have to ensure the idle task has a shared page so that, for example, //region registers can be loaded from it. Apparently not... @@ -229,17 +225,21 @@ void arch_do_createdomain(struct vcpu *v) v->arch.breakimm = d->arch.breakimm; d->arch.sys_pgnr = 0; - d->arch.mm = xmalloc(struct mm_struct); - if (unlikely(!d->arch.mm)) { - printk("Can't allocate mm_struct for domain %d\n",d->domain_id); - return -ENOMEM; - } - memset(d->arch.mm, 0, sizeof(*d->arch.mm)); - d->arch.mm->pgd = pgd_alloc(d->arch.mm); - if (unlikely(!d->arch.mm->pgd)) { - printk("Can't allocate pgd for domain %d\n",d->domain_id); - return -ENOMEM; - } + if (d->domain_id != IDLE_DOMAIN_ID) { + d->arch.mm = xmalloc(struct mm_struct); + if (unlikely(!d->arch.mm)) { + printk("Can't allocate mm_struct for domain %d\n",d->domain_id); + return -ENOMEM; + } + memset(d->arch.mm, 0, sizeof(*d->arch.mm)); + d->arch.mm->pgd = pgd_alloc(d->arch.mm); + if (unlikely(!d->arch.mm->pgd)) { + printk("Can't allocate pgd for domain %d\n",d->domain_id); + return -ENOMEM; + } + } else + d->arch.mm = NULL; + printf ("arch_do_create_domain: domain=%p\n", d); } void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c) diff --git a/xen/arch/ia64/xen/process.c b/xen/arch/ia64/xen/process.c index b49a94d8a8..1432002032 100644 --- a/xen/arch/ia64/xen/process.c +++ b/xen/arch/ia64/xen/process.c @@ -62,11 +62,23 @@ long do_iopl(domid_t domain, unsigned int new_io_pl) return 0; } +#include + +extern struct schedule_data schedule_data[NR_CPUS]; + void schedule_tail(struct vcpu *next) { unsigned long rr7; //printk("current=%lx,shared_info=%lx\n",current,current->vcpu_info); //printk("next=%lx,shared_info=%lx\n",next,next->vcpu_info); + + // TG: Real HACK FIXME. + // This is currently necessary because when a new domain is started, + // the context_switch function of xen/common/schedule.c(__enter_scheduler) + // never returns. Therefore, the lock must be released. + // schedule_tail is only called when a domain is started. + spin_unlock_irq(&schedule_data[current->processor].schedule_lock); + /* rr7 will be postponed to last point when resuming back to guest */ if(VMX_DOMAIN(current)){ vmx_load_all_rr(current); diff --git a/xen/arch/ia64/xen/xenirq.c b/xen/arch/ia64/xen/xenirq.c index bf4778e01e..e66b8ac057 100644 --- a/xen/arch/ia64/xen/xenirq.c +++ b/xen/arch/ia64/xen/xenirq.c @@ -35,7 +35,7 @@ xen_debug_irq(ia64_vector vector, struct pt_regs *regs) int xen_do_IRQ(ia64_vector vector) { - if (vector != 0xef) { + if (vector != IA64_TIMER_VECTOR && vector != IA64_IPI_VECTOR) { extern void vcpu_pend_interrupt(void *, int); #if 0 if (firsttime[vector]) { @@ -57,22 +57,18 @@ xen_do_IRQ(ia64_vector vector) return(0); } -/* From linux/kernel/softirq.c */ -#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED -# define invoke_softirq() __do_softirq() -#else -# define invoke_softirq() do_softirq() -#endif - /* * Exit an interrupt context. Process softirqs if needed and possible: */ void irq_exit(void) { //account_system_vtime(current); - //sub_preempt_count(IRQ_EXIT_OFFSET); - if (!in_interrupt() && local_softirq_pending()) - invoke_softirq(); + sub_preempt_count(IRQ_EXIT_OFFSET); + if (!in_interrupt() && local_softirq_pending()) { + add_preempt_count(SOFTIRQ_OFFSET); + do_softirq(); + sub_preempt_count(SOFTIRQ_OFFSET); + } //preempt_enable_no_resched(); } /* end from linux/kernel/softirq.c */ diff --git a/xen/arch/ia64/xen/xenmisc.c b/xen/arch/ia64/xen/xenmisc.c index e25a8fa1f0..e62115ebbd 100644 --- a/xen/arch/ia64/xen/xenmisc.c +++ b/xen/arch/ia64/xen/xenmisc.c @@ -280,6 +280,8 @@ void cs01foo(void) {} unsigned long context_switch_count = 0; +#include + void context_switch(struct vcpu *prev, struct vcpu *next) { //printk("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); @@ -287,7 +289,8 @@ void context_switch(struct vcpu *prev, struct vcpu *next) //prev->domain->domain_id,(long)prev&0xffffff,next->domain->domain_id,(long)next&0xffffff); //if (prev->domain->domain_id == 1 && next->domain->domain_id == 0) cs10foo(); //if (prev->domain->domain_id == 0 && next->domain->domain_id == 1) cs01foo(); -//printk("@@sw %d->%d\n",prev->domain->domain_id,next->domain->domain_id); +printk("@@sw%d/%x %d->%d\n",smp_processor_id(), hard_smp_processor_id (), + prev->domain->domain_id,next->domain->domain_id); if(VMX_DOMAIN(prev)){ vtm_domain_out(prev); } diff --git a/xen/arch/ia64/xen/xensetup.c b/xen/arch/ia64/xen/xensetup.c index 8b56f9817e..49d11862a5 100644 --- a/xen/arch/ia64/xen/xensetup.c +++ b/xen/arch/ia64/xen/xensetup.c @@ -253,11 +253,11 @@ void start_kernel(void) printk("About to call scheduler_init()\n"); scheduler_init(); local_irq_disable(); + init_IRQ (); printk("About to call init_xen_time()\n"); init_xen_time(); /* initialise the time */ printk("About to call ac_timer_init()\n"); ac_timer_init(); -// init_xen_time(); ??? #ifdef CONFIG_SMP if ( opt_nosmp ) @@ -276,6 +276,9 @@ printk("About to call ac_timer_init()\n"); //BUG_ON(!local_irq_is_enabled()); + /* Enable IRQ to receive IPI (needed for ITC sync). */ + local_irq_enable(); + printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus); for_each_present_cpu ( i ) { @@ -287,24 +290,16 @@ printk("About to call __cpu_up(%d)\n",i); } } + local_irq_disable(); + printk("Brought up %ld CPUs\n", (long)num_online_cpus()); smp_cpus_done(max_cpus); #endif - - // FIXME: Should the following be swapped and moved later? - schedulers_start(); do_initcalls(); printk("About to call sort_main_extable()\n"); sort_main_extable(); - /* surrender usage of kernel registers to domain, use percpu area instead */ - __get_cpu_var(cpu_kr)._kr[IA64_KR_IO_BASE] = ia64_get_kr(IA64_KR_IO_BASE); - __get_cpu_var(cpu_kr)._kr[IA64_KR_PER_CPU_DATA] = ia64_get_kr(IA64_KR_PER_CPU_DATA); - __get_cpu_var(cpu_kr)._kr[IA64_KR_CURRENT_STACK] = ia64_get_kr(IA64_KR_CURRENT_STACK); - __get_cpu_var(cpu_kr)._kr[IA64_KR_FPU_OWNER] = ia64_get_kr(IA64_KR_FPU_OWNER); - __get_cpu_var(cpu_kr)._kr[IA64_KR_CURRENT] = ia64_get_kr(IA64_KR_CURRENT); - __get_cpu_var(cpu_kr)._kr[IA64_KR_PT_BASE] = ia64_get_kr(IA64_KR_PT_BASE); /* Create initial domain 0. */ printk("About to call do_createdomain()\n"); @@ -342,6 +337,11 @@ printk("About to call construct_dom0()\n"); 0, 0) != 0) panic("Could not set up DOM0 guest OS\n"); + + /* PIN domain0 on CPU 0. */ + dom0->vcpu[0]->cpumap=1; + set_bit(_VCPUF_cpu_pinned, &dom0->vcpu[0]->vcpu_flags); + #ifdef CLONE_DOMAIN0 { int i; @@ -379,9 +379,16 @@ printk("About to call init_trace_bufs()\n"); domain_unpause_by_systemcontroller(clones[i]); } #endif - domain_unpause_by_systemcontroller(dom0); domain0_ready = 1; + local_irq_enable(); + + printf("About to call schedulers_start dom0=%p, idle0_dom=%p\n", + dom0, &idle0_domain); + schedulers_start(); + + domain_unpause_by_systemcontroller(dom0); + printk("About to call startup_cpu_idle_loop()\n"); startup_cpu_idle_loop(); } diff --git a/xen/arch/ia64/xen/xentime.c b/xen/arch/ia64/xen/xentime.c index 30f3c111ce..75a454b0ed 100644 --- a/xen/arch/ia64/xen/xentime.c +++ b/xen/arch/ia64/xen/xentime.c @@ -103,10 +103,10 @@ xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) #ifdef HEARTBEAT_FREQ static long count = 0; if (!(++count & ((HEARTBEAT_FREQ*1024)-1))) { - printf("Heartbeat... iip=%p,psr.i=%d,pend=%d\n", - regs->cr_iip, + printf("Heartbeat... iip=%p\n", /*",psr.i=%d,pend=%d\n", */ + regs->cr_iip /*, VCPU(current,interrupt_delivery_enabled), - VCPU(current,pending_interruption)); + VCPU(current,pending_interruption) */); count = 0; } #endif diff --git a/xen/include/asm-ia64/config.h b/xen/include/asm-ia64/config.h index 1d3ba8dabd..10a9b38739 100644 --- a/xen/include/asm-ia64/config.h +++ b/xen/include/asm-ia64/config.h @@ -28,8 +28,8 @@ #ifdef CONFIG_XEN_SMP #define CONFIG_SMP 1 -#define NR_CPUS 2 -#define CONFIG_NR_CPUS 2 +#define NR_CPUS 8 +#define CONFIG_NR_CPUS 8 #else #undef CONFIG_SMP #define NR_CPUS 1 @@ -123,8 +123,7 @@ extern char _end[]; /* standard ELF symbol */ #ifdef CONFIG_SMP #warning "Lots of things to fix to enable CONFIG_SMP!" #endif -// FIXME SMP -#define get_cpu() 0 +#define get_cpu() smp_processor_id() #define put_cpu() do {} while(0) // needed for common/dom0_ops.c until hyperthreading is supported @@ -140,6 +139,7 @@ struct page; // function calls; see decl in xen/include/xen/sched.h #undef free_task_struct #undef alloc_task_struct +#define get_thread_info(v) alloc_thread_info(v) // initial task has a different name in Xen //#define idle0_task init_task @@ -299,7 +299,11 @@ extern int ht_per_core; #endif /* __XEN_IA64_CONFIG_H__ */ // needed for include/xen/smp.h +#ifdef CONFIG_SMP +#define __smp_processor_id() current_thread_info()->cpu +#else #define __smp_processor_id() 0 +#endif // FOLLOWING ADDED FOR XEN POST-NGIO and/or LINUX 2.6.7 diff --git a/xen/include/asm-ia64/linux-xen/asm/spinlock.h b/xen/include/asm-ia64/linux-xen/asm/spinlock.h index c2d32e7a48..1c2034c80d 100644 --- a/xen/include/asm-ia64/linux-xen/asm/spinlock.h +++ b/xen/include/asm-ia64/linux-xen/asm/spinlock.h @@ -17,11 +17,16 @@ #include #include +#define DEBUG_SPINLOCK + typedef struct { volatile unsigned int lock; #ifdef CONFIG_PREEMPT unsigned int break_lock; #endif +#ifdef DEBUG_SPINLOCK + void *locker; +#endif #ifdef XEN unsigned char recurse_cpu; unsigned char recurse_cnt; @@ -96,6 +101,10 @@ _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags) : "=r"(ptr) : "r"(ptr), "r" (flags) : IA64_SPINLOCK_CLOBBERS); # endif /* CONFIG_MCKINLEY */ #endif + +#ifdef DEBUG_SPINLOCK + asm volatile ("mov %0=ip" : "=r" (lock->locker)); +#endif } #define _raw_spin_lock(lock) _raw_spin_lock_flags(lock, 0) #else /* !ASM_SUPPORTED */ diff --git a/xen/include/asm-ia64/linux-xen/linux/hardirq.h b/xen/include/asm-ia64/linux-xen/linux/hardirq.h index 2431491726..b076644e24 100644 --- a/xen/include/asm-ia64/linux-xen/linux/hardirq.h +++ b/xen/include/asm-ia64/linux-xen/linux/hardirq.h @@ -67,11 +67,7 @@ */ #define in_irq() (hardirq_count()) #define in_softirq() (softirq_count()) -#ifdef XEN -#define in_interrupt() 0 // FIXME SMP LATER -#else #define in_interrupt() (irq_count()) -#endif #if defined(CONFIG_PREEMPT) && !defined(CONFIG_PREEMPT_BKL) # define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked()) diff --git a/xen/include/asm-ia64/linux-xen/linux/interrupt.h b/xen/include/asm-ia64/linux-xen/linux/interrupt.h index caea47d641..b88e9457f1 100644 --- a/xen/include/asm-ia64/linux-xen/linux/interrupt.h +++ b/xen/include/asm-ia64/linux-xen/linux/interrupt.h @@ -88,6 +88,7 @@ static inline void __deprecated save_and_cli(unsigned long *x) #define save_and_cli(x) save_and_cli(&x) #endif /* CONFIG_SMP */ +#ifndef XEN /* SoftIRQ primitives. */ #define local_bh_disable() \ do { add_preempt_count(SOFTIRQ_OFFSET); barrier(); } while (0) @@ -95,6 +96,7 @@ static inline void __deprecated save_and_cli(unsigned long *x) do { barrier(); sub_preempt_count(SOFTIRQ_OFFSET); } while (0) extern void local_bh_enable(void); +#endif /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high frequency threaded job scheduling. For almost all the purposes From 4284a039387c3509320e9265bf800ae551fb32b7 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Thu, 13 Oct 2005 14:24:45 -0600 Subject: [PATCH 04/36] Some outstanding bug fixes found in VT merge - Consistence of region id mangling algrithm: - Metaphysical RID is not mangled, which may conflict with other domain's virtual RID - Sometimes rr0 is mangled, but sometimes not - Sometimes only rid value is saved to saved_rr0_metaphysical, but sometimes the whole value. - Nat bit comsumption happens but handled as priv_emulate to forward progress. But this is definitely wrong. We found reason of nat consumption from fast_rfi, which doesn't save unat again after spill guest states, and then use guest unat to fill guest states when return. - In some corner case, timer interrupt handler won't update itm and then return directly. When that happens, machine timer interrupt disappears until guest timer interrupt sets v_itm actively. But vti domain depends on ac_timer while the latter will stop when above condition happens. Then if current context is vti domain, context switch disappears and machine halt. Also many compatibility issues to support non-vti and vti domain are solved,eg: - Changing lazy PAL mapping switch to eager switch per domain switch, since vti domain always depends on pal call. - evtchn_notify should also vcpu_wake target domain, since vti domain may block for io emulation. Xenolinux is free of this issue, since it's always runnable. Signed-off-by Kevin Tian Signed-off-by Anthony Xu --- xen/Rules.mk | 1 + xen/arch/ia64/Rules.mk | 2 +- xen/arch/ia64/asm-offsets.c | 3 + xen/arch/ia64/linux-xen/entry.S | 9 +- xen/arch/ia64/vmx/vmx_entry.S | 4 +- xen/arch/ia64/vmx/vmx_init.c | 142 ++++++++++++----------------- xen/arch/ia64/vmx/vmx_irq_ia64.c | 5 +- xen/arch/ia64/vmx/vmx_process.c | 8 +- xen/arch/ia64/vmx/vmx_support.c | 2 +- xen/arch/ia64/vmx/vtlb.c | 9 ++ xen/arch/ia64/xen/dom0_ops.c | 9 +- xen/arch/ia64/xen/dom_fw.c | 2 +- xen/arch/ia64/xen/domain.c | 16 +++- xen/arch/ia64/xen/hyperprivop.S | 3 + xen/arch/ia64/xen/ivt.S | 21 +++++ xen/arch/ia64/xen/process.c | 2 + xen/arch/ia64/xen/regionreg.c | 21 ++++- xen/arch/ia64/xen/vcpu.c | 2 + xen/arch/ia64/xen/xenasm.S | 27 +++++- xen/arch/ia64/xen/xenmisc.c | 7 +- xen/arch/ia64/xen/xentime.c | 19 ++-- xen/include/asm-ia64/config.h | 2 +- xen/include/asm-ia64/event.h | 15 +++ xen/include/asm-ia64/mm.h | 7 +- xen/include/asm-ia64/vmx.h | 1 + xen/include/asm-ia64/xenkregs.h | 3 +- xen/include/public/arch-ia64.h | 27 ++++++ xen/include/public/io/ioreq.h | 14 ++- xen/include/public/io/vmx_vlapic.h | 44 ++------- 29 files changed, 260 insertions(+), 167 deletions(-) diff --git a/xen/Rules.mk b/xen/Rules.mk index d57ca65e51..a1ae2c31b5 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -47,6 +47,7 @@ test-gcc-flag = $(shell $(CC) -v --help 2>&1 | grep -q " $(1) " && echo $(1)) include $(BASEDIR)/arch/$(TARGET_ARCH)/Rules.mk +CFLAGS += -D__HYPERVISOR__ ifneq ($(debug),y) CFLAGS += -DNDEBUG ifeq ($(verbose),y) diff --git a/xen/arch/ia64/Rules.mk b/xen/arch/ia64/Rules.mk index 8eb31cc674..279761d893 100644 --- a/xen/arch/ia64/Rules.mk +++ b/xen/arch/ia64/Rules.mk @@ -24,7 +24,7 @@ CFLAGS += -I$(BASEDIR)/include/asm-ia64 -I$(BASEDIR)/include/asm-ia64/linux \ -I$(BASEDIR)/include/asm-ia64/linux-null \ -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen CFLAGS += -Wno-pointer-arith -Wredundant-decls -CFLAGS += -DIA64 -DXEN -DLINUX_2_6 +CFLAGS += -DIA64 -DXEN -DLINUX_2_6 -DV_IOSAPIC_READY CFLAGS += -ffixed-r13 -mfixed-range=f12-f15,f32-f127 CFLAGS += -w -g ifeq ($(VALIDATE_VT),y) diff --git a/xen/arch/ia64/asm-offsets.c b/xen/arch/ia64/asm-offsets.c index ed770ee725..e1703d09fe 100644 --- a/xen/arch/ia64/asm-offsets.c +++ b/xen/arch/ia64/asm-offsets.c @@ -59,6 +59,8 @@ void foo(void) DEFINE(XSI_BANKNUM_OFS, offsetof(mapped_regs_t, banknum)); DEFINE(XSI_BANK0_OFS, offsetof(mapped_regs_t, bank0_regs[0])); DEFINE(XSI_BANK1_OFS, offsetof(mapped_regs_t, bank1_regs[0])); + DEFINE(XSI_B0NATS_OFS, offsetof(mapped_regs_t, vbnat)); + DEFINE(XSI_B1NATS_OFS, offsetof(mapped_regs_t, vnat)); DEFINE(XSI_RR0_OFS, offsetof(mapped_regs_t, rrs[0])); DEFINE(XSI_METAPHYS_OFS, offsetof(mapped_regs_t, metaphysical_mode)); DEFINE(XSI_PRECOVER_IFS_OFS, offsetof(mapped_regs_t, precover_ifs)); @@ -79,6 +81,7 @@ void foo(void) //DEFINE(IA64_TASK_SIGHAND_OFFSET,offsetof (struct task_struct, sighand)); //DEFINE(IA64_TASK_SIGNAL_OFFSET,offsetof (struct task_struct, signal)); //DEFINE(IA64_TASK_TGID_OFFSET, offsetof (struct task_struct, tgid)); + DEFINE(IA64_PGD, offsetof(struct domain, arch.mm)); DEFINE(IA64_TASK_THREAD_KSP_OFFSET, offsetof (struct vcpu, arch._thread.ksp)); DEFINE(IA64_TASK_THREAD_ON_USTACK_OFFSET, offsetof (struct vcpu, arch._thread.on_ustack)); diff --git a/xen/arch/ia64/linux-xen/entry.S b/xen/arch/ia64/linux-xen/entry.S index c4f2448942..32aebf984e 100644 --- a/xen/arch/ia64/linux-xen/entry.S +++ b/xen/arch/ia64/linux-xen/entry.S @@ -900,10 +900,17 @@ GLOBAL_ENTRY(ia64_leave_kernel) adds r7 = PT(EML_UNAT)+16,r12 ;; ld8 r7 = [r7] + ;; +#if 0 +leave_kernel_self: + cmp.ne p8,p0 = r0, r7 +(p8) br.sptk.few leave_kernel_self + ;; +#endif (p6) br.call.sptk.many b0=deliver_pending_interrupt ;; mov ar.pfs=loc0 - mov ar.unat=r7 /* load eml_unat */ + mov ar.unat=r7 /* load eml_unat */ mov r31=r0 diff --git a/xen/arch/ia64/vmx/vmx_entry.S b/xen/arch/ia64/vmx/vmx_entry.S index 4eda79cc9d..da5cb215f9 100644 --- a/xen/arch/ia64/vmx/vmx_entry.S +++ b/xen/arch/ia64/vmx/vmx_entry.S @@ -720,11 +720,11 @@ GLOBAL_ENTRY(vmx_switch_rr7) // re-pin mappings for guest_vhpt - mov r24=IA64_TR_VHPT + mov r24=IA64_TR_PERVP_VHPT movl r25=PAGE_KERNEL ;; or loc5 = r25,loc5 // construct PA | page properties - mov r23 = VCPU_TLB_SHIFT<<2 + mov r23 = IA64_GRANULE_SHIFT <<2 ;; ptr.d in3,r23 ;; diff --git a/xen/arch/ia64/vmx/vmx_init.c b/xen/arch/ia64/vmx/vmx_init.c index d6b9d24f03..452a96e093 100644 --- a/xen/arch/ia64/vmx/vmx_init.c +++ b/xen/arch/ia64/vmx/vmx_init.c @@ -47,6 +47,7 @@ #include #include #include +#include /* Global flag to identify whether Intel vmx feature is on */ u32 vmx_enabled = 0; @@ -136,39 +137,6 @@ vmx_init_env(void) #endif } -void vmx_setup_platform(struct vcpu *v, struct vcpu_guest_context *c) -{ - struct domain *d = v->domain; - shared_iopage_t *sp; - - ASSERT(d != dom0); /* only for non-privileged vti domain */ - d->arch.vmx_platform.shared_page_va = __va(c->share_io_pg); - sp = get_sp(d); - memset((char *)sp,0,PAGE_SIZE); - /* FIXME: temp due to old CP */ - sp->sp_global.eport = 2; -#ifdef V_IOSAPIC_READY - sp->vcpu_number = 1; -#endif - /* TEMP */ - d->arch.vmx_platform.pib_base = 0xfee00000UL; - - /* One more step to enable interrupt assist */ - set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags); - /* Only open one port for I/O and interrupt emulation */ - if (v == d->vcpu[0]) { - memset(&d->shared_info->evtchn_mask[0], 0xff, - sizeof(d->shared_info->evtchn_mask)); - clear_bit(iopacket_port(d), &d->shared_info->evtchn_mask[0]); - } - - /* FIXME: only support PMT table continuously by far */ -// d->arch.pmt = __va(c->pt_base); - - - vmx_final_setup_domain(d); -} - typedef union { u64 value; struct { @@ -376,40 +344,6 @@ vmx_final_setup_domain(struct domain *d) /* Other vmx specific initialization work */ } -/* - * Following stuff should really move to domain builder. However currently - * XEN/IA64 doesn't export physical -> machine page table to domain builder, - * instead only the copy. Also there's no hypercall to notify hypervisor - * IO ranges by far. Let's enhance it later. - */ - -#define MEM_G (1UL << 30) -#define MEM_M (1UL << 20) - -#define MMIO_START (3 * MEM_G) -#define MMIO_SIZE (512 * MEM_M) - -#define VGA_IO_START 0xA0000UL -#define VGA_IO_SIZE 0x20000 - -#define LEGACY_IO_START (MMIO_START + MMIO_SIZE) -#define LEGACY_IO_SIZE (64*MEM_M) - -#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE) -#define IO_PAGE_SIZE PAGE_SIZE - -#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE) -#define STORE_PAGE_SIZE PAGE_SIZE - -#define IO_SAPIC_START 0xfec00000UL -#define IO_SAPIC_SIZE 0x100000 - -#define PIB_START 0xfee00000UL -#define PIB_SIZE 0x100000 - -#define GFW_START (4*MEM_G -16*MEM_M) -#define GFW_SIZE (16*MEM_M) - typedef struct io_range { unsigned long start; unsigned long size; @@ -424,18 +358,26 @@ io_range_t io_ranges[] = { {PIB_START, PIB_SIZE, GPFN_PIB}, }; -#define VMX_SYS_PAGES (2 + GFW_SIZE >> PAGE_SHIFT) +#define VMX_SYS_PAGES (2 + (GFW_SIZE >> PAGE_SHIFT)) #define VMX_CONFIG_PAGES(d) ((d)->max_pages - VMX_SYS_PAGES) int vmx_alloc_contig_pages(struct domain *d) { - unsigned int order, i, j; - unsigned long start, end, pgnr, conf_nr; + unsigned int order; + unsigned long i, j, start, end, pgnr, conf_nr; struct pfn_info *page; struct vcpu *v = d->vcpu[0]; ASSERT(!test_bit(ARCH_VMX_CONTIG_MEM, &v->arch.arch_vmx.flags)); + /* Mark I/O ranges */ + for (i = 0; i < (sizeof(io_ranges) / sizeof(io_range_t)); i++) { + for (j = io_ranges[i].start; + j < io_ranges[i].start + io_ranges[i].size; + j += PAGE_SIZE) + map_domain_page(d, j, io_ranges[i].type); + } + conf_nr = VMX_CONFIG_PAGES(d); order = get_order_from_pages(conf_nr); if (unlikely((page = alloc_domheap_pages(d, order, 0)) == NULL)) { @@ -462,32 +404,64 @@ int vmx_alloc_contig_pages(struct domain *d) d->arch.max_pfn = end >> PAGE_SHIFT; - order = get_order_from_pages(VMX_SYS_PAGES); + order = get_order_from_pages(GFW_SIZE >> PAGE_SHIFT); if (unlikely((page = alloc_domheap_pages(d, order, 0)) == NULL)) { printk("Could not allocate order=%d pages for vmx contig alloc\n", order); return -1; } + /* Map guest firmware */ + pgnr = page_to_pfn(page); + for (i = GFW_START; i < GFW_START + GFW_SIZE; i += PAGE_SIZE, pgnr++) + map_domain_page(d, i, pgnr << PAGE_SHIFT); + + if (unlikely((page = alloc_domheap_pages(d, 1, 0)) == NULL)) { + printk("Could not allocate order=1 pages for vmx contig alloc\n"); + return -1; + } + /* Map for shared I/O page and xenstore */ pgnr = page_to_pfn(page); map_domain_page(d, IO_PAGE_START, pgnr << PAGE_SHIFT); pgnr++; map_domain_page(d, STORE_PAGE_START, pgnr << PAGE_SHIFT); - pgnr++; - - /* Map guest firmware */ - for (i = GFW_START; i < GFW_START + GFW_SIZE; i += PAGE_SIZE, pgnr++) - map_domain_page(d, i, pgnr << PAGE_SHIFT); - - /* Mark I/O ranges */ - for (i = 0; i < (sizeof(io_ranges) / sizeof(io_range_t)); i++) { - for (j = io_ranges[i].start; - j < io_ranges[i].start + io_ranges[i].size; - j += PAGE_SIZE) - map_domain_page(d, j, io_ranges[i].type); - } set_bit(ARCH_VMX_CONTIG_MEM, &v->arch.arch_vmx.flags); return 0; } + +void vmx_setup_platform(struct vcpu *v, struct vcpu_guest_context *c) +{ + struct domain *d = v->domain; + shared_iopage_t *sp; + + ASSERT(d != dom0); /* only for non-privileged vti domain */ + d->arch.vmx_platform.shared_page_va = + __va(__gpa_to_mpa(d, IO_PAGE_START)); + sp = get_sp(d); + //memset((char *)sp,0,PAGE_SIZE); + //sp->sp_global.eport = 2; +#ifdef V_IOSAPIC_READY + sp->vcpu_number = 1; +#endif + /* TEMP */ + d->arch.vmx_platform.pib_base = 0xfee00000UL; + + /* One more step to enable interrupt assist */ + set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags); + /* Only open one port for I/O and interrupt emulation */ + if (v == d->vcpu[0]) { + memset(&d->shared_info->evtchn_mask[0], 0xff, + sizeof(d->shared_info->evtchn_mask)); + clear_bit(iopacket_port(d), &d->shared_info->evtchn_mask[0]); + } + + /* FIXME: only support PMT table continuously by far */ +// d->arch.pmt = __va(c->pt_base); + + + vmx_final_setup_domain(d); +} + + diff --git a/xen/arch/ia64/vmx/vmx_irq_ia64.c b/xen/arch/ia64/vmx/vmx_irq_ia64.c index 84af87da41..0bceaa82fd 100644 --- a/xen/arch/ia64/vmx/vmx_irq_ia64.c +++ b/xen/arch/ia64/vmx/vmx_irq_ia64.c @@ -101,7 +101,10 @@ vmx_ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) if (vector != IA64_TIMER_VECTOR) { /* FIXME: Leave IRQ re-route later */ - vmx_vcpu_pend_interrupt(dom0->vcpu[0],vector); + if (!VMX_DOMAIN(dom0->vcpu[0])) + vcpu_pend_interrupt(dom0->vcpu[0],vector); + else + vmx_vcpu_pend_interrupt(dom0->vcpu[0],vector); wake_dom0 = 1; } else { // FIXME: Handle Timer only now diff --git a/xen/arch/ia64/vmx/vmx_process.c b/xen/arch/ia64/vmx/vmx_process.c index 0f9566e7b8..2d7d889733 100644 --- a/xen/arch/ia64/vmx/vmx_process.c +++ b/xen/arch/ia64/vmx/vmx_process.c @@ -271,7 +271,7 @@ void vmx_hpw_miss(u64 vadr , u64 vec, REGS* regs) { IA64_PSR vpsr; CACHE_LINE_TYPE type; - u64 vhpt_adr; + u64 vhpt_adr, gppa; ISR misr; ia64_rr vrr; REGS *regs; @@ -314,9 +314,9 @@ void vmx_hpw_miss(u64 vadr , u64 vec, REGS* regs) // prepare_if_physical_mode(v); if(data=vtlb_lookup_ex(vtlb, vrr.rid, vadr,type)){ - if(v->domain!=dom0&&type==DSIDE_TLB && __gpfn_is_io(v->domain,data->ppn>>(PAGE_SHIFT-12))){ - vadr=(vadr&((1UL<ps)-1))+(data->ppn>>(data->ps-12)<ps); - emulate_io_inst(v, vadr, data->ma); + gppa = (vadr&((1UL<ps)-1))+(data->ppn>>(data->ps-12)<ps); + if(v->domain!=dom0&&type==DSIDE_TLB && __gpfn_is_io(v->domain,gppa>>PAGE_SHIFT)){ + emulate_io_inst(v, gppa, data->ma); return IA64_FAULT; } diff --git a/xen/arch/ia64/vmx/vmx_support.c b/xen/arch/ia64/vmx/vmx_support.c index afd0f650d0..5bf06c8c71 100644 --- a/xen/arch/ia64/vmx/vmx_support.c +++ b/xen/arch/ia64/vmx/vmx_support.c @@ -158,7 +158,7 @@ void vmx_intr_assist(struct vcpu *v) #ifdef V_IOSAPIC_READY vlapic_update_ext_irq(v); #else - panic("IOSAPIC model is missed in qemu\n"); + //panic("IOSAPIC model is missed in qemu\n"); #endif return; } diff --git a/xen/arch/ia64/vmx/vtlb.c b/xen/arch/ia64/vmx/vtlb.c index 78e0b897cb..2d726efe21 100644 --- a/xen/arch/ia64/vmx/vtlb.c +++ b/xen/arch/ia64/vmx/vtlb.c @@ -387,6 +387,15 @@ void vtlb_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va) thash_insert(hcb->ts->vhpt, entry, va); return; } + +#if 1 + vrr=vmx_vcpu_rr(current, va); + if (vrr.ps != entry->ps) { + printk("not preferred ps with va: 0x%lx\n", va); + return; + } +#endif + flag = 1; gppn = (POFFSET(va,entry->ps)|PAGEALIGN((entry->ppn<<12),entry->ps))>>PAGE_SHIFT; ppns = PAGEALIGN((entry->ppn<<12),entry->ps); diff --git a/xen/arch/ia64/xen/dom0_ops.c b/xen/arch/ia64/xen/dom0_ops.c index 48517604f7..540e09caa4 100644 --- a/xen/arch/ia64/xen/dom0_ops.c +++ b/xen/arch/ia64/xen/dom0_ops.c @@ -177,13 +177,8 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op) for ( i = start_page; i < (start_page + nr_pages); i++ ) { - page = map_new_domain_page(d, i << PAGE_SHIFT); - if ( page == NULL ) - { - ret = -ENOMEM; - break; - } - pfn = page_to_pfn(page); + pfn = __gpfn_to_mfn_foreign(d, i); + if ( put_user(pfn, buffer) ) { ret = -EFAULT; diff --git a/xen/arch/ia64/xen/dom_fw.c b/xen/arch/ia64/xen/dom_fw.c index ca22fafacc..eb9fbe8858 100644 --- a/xen/arch/ia64/xen/dom_fw.c +++ b/xen/arch/ia64/xen/dom_fw.c @@ -301,7 +301,7 @@ xen_pal_emulator(unsigned long index, unsigned long in1, // pal code must be mapped by a TR when pal is called, however // calls are rare enough that we will map it lazily rather than // at every context switch - efi_map_pal_code(); + //efi_map_pal_code(); switch (index) { case PAL_MEM_ATTRIB: status = ia64_pal_mem_attrib(&r9); diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 7c9b0ddc11..f48cdff759 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -59,6 +59,7 @@ unsigned long *domU_staging_area; // initialized by arch/ia64/setup.c:find_initrd() unsigned long initrd_start = 0, initrd_end = 0; +extern unsigned long running_on_sim; #define IS_XEN_ADDRESS(d,a) ((a >= d->xen_vastart) && (a <= d->xen_vaend)) @@ -190,6 +191,9 @@ void arch_do_createdomain(struct vcpu *v) while (1); } memset(d->shared_info, 0, PAGE_SIZE); + if (v == d->vcpu[0]) + memset(&d->shared_info->evtchn_mask[0], 0xff, + sizeof(d->shared_info->evtchn_mask)); #if 0 d->vcpu[0].arch.privregs = alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); @@ -271,6 +275,14 @@ int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c) if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) ) return 0; + /* Sync d/i cache conservatively */ + if (!running_on_sim) { + ret = ia64_pal_cache_flush(4, 0, &progress, NULL); + if (ret != PAL_STATUS_SUCCESS) + panic("PAL CACHE FLUSH failed for domain.\n"); + printk("Sync i/d cache for dom0 image SUCC\n"); + } + if (c->flags & VGCF_VMX_GUEST) { if (!vmx_enabled) { printk("No VMX hardware feature for vmx domain.\n"); @@ -547,7 +559,8 @@ tryagain: if (pte_present(*pte)) { //printk("lookup_domain_page: found mapping for %lx, pte=%lx\n",mpaddr,pte_val(*pte)); return *(unsigned long *)pte; - } + } else if (VMX_DOMAIN(d->vcpu[0])) + return GPFN_INV_MASK; } } } @@ -799,7 +812,6 @@ void physdev_init_dom0(struct domain *d) set_bit(_DOMF_physdev_access, &d->domain_flags); } -extern unsigned long running_on_sim; unsigned int vmx_dom0 = 0; int construct_dom0(struct domain *d, unsigned long image_start, unsigned long image_len, diff --git a/xen/arch/ia64/xen/hyperprivop.S b/xen/arch/ia64/xen/hyperprivop.S index e20b5d91e3..d472806a1e 100644 --- a/xen/arch/ia64/xen/hyperprivop.S +++ b/xen/arch/ia64/xen/hyperprivop.S @@ -807,8 +807,11 @@ just_do_rfi: // OK, now all set to go except for switch to virtual bank1 mov r22=1;; st4 [r20]=r22; mov r30=r2; mov r29=r3;; + adds r16=XSI_B1NATS_OFS-XSI_PSR_IC_OFS,r18 adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18; adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;; + ld8 r16=[r16];; + mov ar.unat=r16;; bsw.1;; // FIXME?: ar.unat is not really handled correctly, // but may not matter if the OS is NaT-clean diff --git a/xen/arch/ia64/xen/ivt.S b/xen/arch/ia64/xen/ivt.S index 5f7b4db205..1477bbe18e 100644 --- a/xen/arch/ia64/xen/ivt.S +++ b/xen/arch/ia64/xen/ivt.S @@ -1460,7 +1460,28 @@ END(general_exception) // 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35) ENTRY(disabled_fp_reg) #ifdef XEN +#if 0 + mov r20=pr + movl r16=0x2000000000000000 + movl r17=0x2000000000176b60 + mov r18=cr.iip + mov r19=rr[r16] + movl r22=0xe95d0439 + ;; + mov pr=r0,-1 + ;; + cmp.eq p6,p7=r22,r19 + ;; + (p6) cmp.eq p8,p9=r17,r18 + (p8) br.sptk.few floating_panic + ;; + mov pr=r20,-1 + ;; +#endif REFLECT(25) +//floating_panic: +// br.sptk.many floating_panic + ;; #endif DBG_FAULT(25) rsm psr.dfh // ensure we can access fph diff --git a/xen/arch/ia64/xen/process.c b/xen/arch/ia64/xen/process.c index 1432002032..c3eb890a8b 100644 --- a/xen/arch/ia64/xen/process.c +++ b/xen/arch/ia64/xen/process.c @@ -745,6 +745,8 @@ ia64_handle_reflection (unsigned long ifa, struct pt_regs *regs, unsigned long i case 26: printf("*** NaT fault... attempting to handle as privop\n"); printf("isr=%p, ifa=%p,iip=%p,ipsr=%p\n",isr,ifa,regs->cr_iip,psr); + regs->eml_unat = 0; + return; vector = priv_emulate(v,regs,isr); if (vector == IA64_NO_FAULT) { printf("*** Handled privop masquerading as NaT fault\n"); diff --git a/xen/arch/ia64/xen/regionreg.c b/xen/arch/ia64/xen/regionreg.c index 418ba8df23..2e0bb6425f 100644 --- a/xen/arch/ia64/xen/regionreg.c +++ b/xen/arch/ia64/xen/regionreg.c @@ -15,7 +15,8 @@ #include #include #include -extern void ia64_new_rr7(unsigned long rid,void *shared_info, void *shared_arch_info); +extern void ia64_new_rr7(unsigned long rid,void *shared_info, void *shared_arch_info, unsigned long p_vhpt, unsigned long v_pal); +extern void *pal_vaddr; #define IA64_MIN_IMPL_RID_BITS (IA64_MIN_IMPL_RID_MSB+1) @@ -66,9 +67,12 @@ unsigned long allocate_metaphysical_rr(void) { ia64_rr rrv; + rrv.rrval = 0; // Or else may see reserved bit fault rrv.rid = allocate_reserved_rid(); rrv.ps = PAGE_SHIFT; rrv.ve = 0; + /* Mangle metaphysical rid */ + rrv.rrval = vmMangleRID(rrv.rrval); return rrv.rrval; } @@ -213,6 +217,7 @@ int set_one_rr(unsigned long rr, unsigned long val) unsigned long rreg = REGION_NUMBER(rr); ia64_rr rrv, newrrv, memrrv; unsigned long newrid; + extern unsigned long vhpt_paddr; if (val == -1) return 1; @@ -250,9 +255,10 @@ int set_one_rr(unsigned long rr, unsigned long val) newrrv.rid = newrid; newrrv.ve = 1; // VHPT now enabled for region 7!! newrrv.ps = PAGE_SHIFT; - if (rreg == 0) v->arch.metaphysical_saved_rr0 = newrrv.rrval; + if (rreg == 0) v->arch.metaphysical_saved_rr0 = + vmMangleRID(newrrv.rrval); if (rreg == 7) ia64_new_rr7(vmMangleRID(newrrv.rrval),v->vcpu_info, - v->arch.privregs); + v->arch.privregs, vhpt_paddr, pal_vaddr); else set_rr(rr,newrrv.rrval); #endif return 1; @@ -265,7 +271,8 @@ int set_metaphysical_rr0(void) ia64_rr rrv; // rrv.ve = 1; FIXME: TURN ME BACK ON WHEN VHPT IS WORKING - set_rr(0,v->arch.metaphysical_rr0); + ia64_set_rr(0,v->arch.metaphysical_rr0); + ia64_srlz_d(); } // validates/changes region registers 0-6 in the currently executing domain @@ -290,7 +297,7 @@ void init_all_rr(struct vcpu *v) ia64_rr rrv; rrv.rrval = 0; - rrv.rrval = v->domain->arch.metaphysical_rr0; + //rrv.rrval = v->domain->arch.metaphysical_rr0; rrv.ps = PAGE_SHIFT; rrv.ve = 1; if (!v->vcpu_info) { printf("Stopping in init_all_rr\n"); dummy(); } @@ -343,12 +350,16 @@ unsigned long load_region_regs(struct vcpu *v) if (VCPU(v,metaphysical_mode)) { ia64_rr rrv; +#if 0 rrv.rrval = 0; rrv.rid = v->domain->arch.metaphysical_rr0; rrv.ps = PAGE_SHIFT; rrv.ve = 1; rr0 = rrv.rrval; set_rr_no_srlz(0x0000000000000000L, rr0); +#endif + rr0 = v->domain->arch.metaphysical_rr0; + ia64_set_rr(0x0000000000000000L, rr0); ia64_srlz_d(); } else { diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c index f3990a6cf5..15d897ef0d 100644 --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -775,6 +775,7 @@ IA64FAULT vcpu_get_ivr(VCPU *vcpu, UINT64 *pval) } #ifdef HEARTBEAT_FREQ if (domid >= N_DOMS) domid = N_DOMS-1; +#if 0 if (vector == (PSCB(vcpu,itv) & 0xff)) { if (!(++count[domid] & ((HEARTBEAT_FREQ*1024)-1))) { printf("Dom%d heartbeat... ticks=%lx,nonticks=%lx\n", @@ -783,6 +784,7 @@ IA64FAULT vcpu_get_ivr(VCPU *vcpu, UINT64 *pval) //dump_runq(); } } +#endif else nonclockcount[domid]++; #endif // now have an unmasked, pending, deliverable vector! diff --git a/xen/arch/ia64/xen/xenasm.S b/xen/arch/ia64/xen/xenasm.S index 92b47cc976..216aeefd7b 100644 --- a/xen/arch/ia64/xen/xenasm.S +++ b/xen/arch/ia64/xen/xenasm.S @@ -48,11 +48,11 @@ END(platform_is_hp_ski) // FIXME? Note that this turns off the DB bit (debug) #define PSR_BITS_TO_SET IA64_PSR_BN -//extern void ia64_new_rr7(unsigned long rid,void *shared_info, void *shared_arch_info); +//extern void ia64_new_rr7(unsigned long rid,void *shared_info, void *shared_arch_info, unsigned long p_vhpt, unsigned long v_pal); GLOBAL_ENTRY(ia64_new_rr7) // not sure this unwind statement is correct... .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(1) - alloc loc1 = ar.pfs, 3, 8, 0, 0 + alloc loc1 = ar.pfs, 5, 9, 0, 0 1: { mov r28 = in0 // copy procedure index mov r8 = ip // save ip to compute branch @@ -63,10 +63,12 @@ GLOBAL_ENTRY(ia64_new_rr7) ;; tpa loc2=loc2 // grab this BEFORE changing rr7 ;; -#if VHPT_ENABLED - movl loc6=VHPT_ADDR + dep loc8=0,in4,60,4 ;; - tpa loc6=loc6 // grab this BEFORE changing rr7 +#if VHPT_ENABLED + mov loc6=in3 + ;; + //tpa loc6=loc6 // grab this BEFORE changing rr7 ;; #endif mov loc5=in1 @@ -231,6 +233,21 @@ GLOBAL_ENTRY(ia64_new_rr7) itr.d dtr[r25]=r23 // wire in new mapping... ;; + //Purge/insert PAL TR + mov r24=IA64_TR_PALCODE + movl r25=PAGE_KERNEL + ;; + or loc8=r25,loc8 + mov r23=IA64_GRANULE_SHIFT<<2 + ;; + ptr.i in4,r23 + ;; + mov cr.itir=r23 + mov cr.ifa=in4 + ;; + itr.i itr[r24]=loc8 + ;; + // done, switch back to virtual and return mov r16=loc3 // r16= original psr br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode diff --git a/xen/arch/ia64/xen/xenmisc.c b/xen/arch/ia64/xen/xenmisc.c index e62115ebbd..a51059174c 100644 --- a/xen/arch/ia64/xen/xenmisc.c +++ b/xen/arch/ia64/xen/xenmisc.c @@ -17,6 +17,7 @@ #include #include #include +#include efi_memory_desc_t ia64_efi_io_md; EXPORT_SYMBOL(ia64_efi_io_md); @@ -310,9 +311,13 @@ if (!cnt[id]--) { printk("%x",id); cnt[id] = 500000; } if (!i--) { printk("+",id); i = 1000000; } } - if (VMX_DOMAIN(current)){ + if (VMX_DOMAIN(current)){ vmx_load_all_rr(current); }else{ + extern char ia64_ivt; + ia64_set_iva(&ia64_ivt); + ia64_set_pta(VHPT_ADDR | (1 << 8) | (VHPT_SIZE_LOG2 << 2) | + VHPT_ENABLED); if (!is_idle_task(current->domain)) { load_region_regs(current); if (vcpu_timer_expired(current)) vcpu_pend_timer(current); diff --git a/xen/arch/ia64/xen/xentime.c b/xen/arch/ia64/xen/xentime.c index 75a454b0ed..cdd17b0673 100644 --- a/xen/arch/ia64/xen/xentime.c +++ b/xen/arch/ia64/xen/xentime.c @@ -99,6 +99,7 @@ xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) { unsigned long new_itm, old_itc; +#if 0 #define HEARTBEAT_FREQ 16 // period in seconds #ifdef HEARTBEAT_FREQ static long count = 0; @@ -109,6 +110,7 @@ xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) VCPU(current,pending_interruption) */); count = 0; } +#endif #endif if (current->domain == dom0) { // FIXME: there's gotta be a better way of doing this... @@ -117,12 +119,14 @@ xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) //domain0_ready = 1; // moved to xensetup.c VCPU(current,pending_interruption) = 1; } - if (domain0_ready && vcpu_timer_expired(dom0->vcpu[0])) { - vcpu_pend_timer(dom0->vcpu[0]); - //vcpu_set_next_timer(dom0->vcpu[0]); - vcpu_wake(dom0->vcpu[0]); + if (domain0_ready && current->domain != dom0) { + if(vcpu_timer_expired(dom0->vcpu[0])) { + vcpu_pend_timer(dom0->vcpu[0]); + //vcpu_set_next_timer(dom0->vcpu[0]); + vcpu_wake(dom0->vcpu[0]); + } } - if (!is_idle_task(current->domain) && current->domain != dom0) { + if (!is_idle_task(current->domain)) { if (vcpu_timer_expired(current)) { vcpu_pend_timer(current); // ensure another timer interrupt happens even if domain doesn't @@ -132,9 +136,12 @@ xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) } new_itm = local_cpu_data->itm_next; - if (!time_after(ia64_get_itc(), new_itm)) + if (!VMX_DOMAIN(current) && !time_after(ia64_get_itc(), new_itm)) return; + if (VMX_DOMAIN(current)) + vcpu_wake(current); + while (1) { new_itm += local_cpu_data->itm_delta; diff --git a/xen/include/asm-ia64/config.h b/xen/include/asm-ia64/config.h index 10a9b38739..fec2d5bff3 100644 --- a/xen/include/asm-ia64/config.h +++ b/xen/include/asm-ia64/config.h @@ -102,7 +102,7 @@ extern char _end[]; /* standard ELF symbol */ #endif // xen/include/asm/config.h -#define HZ 100 +//#define HZ 1000 // FIXME SMP: leave SMP for a later time #define barrier() __asm__ __volatile__("": : :"memory") diff --git a/xen/include/asm-ia64/event.h b/xen/include/asm-ia64/event.h index d01111be7c..297351072d 100644 --- a/xen/include/asm-ia64/event.h +++ b/xen/include/asm-ia64/event.h @@ -14,6 +14,21 @@ static inline void evtchn_notify(struct vcpu *v) { + /* + * NB1. 'vcpu_flags' and 'processor' must be checked /after/ update of + * pending flag. These values may fluctuate (after all, we hold no + * locks) but the key insight is that each change will cause + * evtchn_upcall_pending to be polled. + * + * NB2. We save VCPUF_running across the unblock to avoid a needless + * IPI for domains that we IPI'd to unblock. + */ + int running = test_bit(_VCPUF_running, &v->vcpu_flags); + vcpu_unblock(v); + if ( running ) + smp_send_event_check_cpu(v->processor); + + if(!VMX_DOMAIN(v)) vcpu_pend_interrupt(v, v->vcpu_info->arch.evtchn_vector); } diff --git a/xen/include/asm-ia64/mm.h b/xen/include/asm-ia64/mm.h index 100400cb5c..7fac78db61 100644 --- a/xen/include/asm-ia64/mm.h +++ b/xen/include/asm-ia64/mm.h @@ -405,6 +405,7 @@ extern unsigned long totalram_pages; extern int nr_swap_pages; extern unsigned long *mpt_table; +extern unsigned long lookup_domain_mpa(struct domain *d, unsigned long mpaddr); #undef machine_to_phys_mapping #define machine_to_phys_mapping mpt_table @@ -433,10 +434,10 @@ extern unsigned long *mpt_table; #define __gpfn_is_mem(_d, gpfn) \ (__gpfn_valid(_d, gpfn) ? \ - (lookup_domain_mpa((_d), ((gpfn)<>PAGE_SHIFT)<>PAGE_SHIFT)< + extern void identify_vmx_feature(void); extern unsigned int vmx_enabled; extern void vmx_init_env(void); diff --git a/xen/include/asm-ia64/xenkregs.h b/xen/include/asm-ia64/xenkregs.h index 5a0c5c0bd6..3eb48d9ec2 100644 --- a/xen/include/asm-ia64/xenkregs.h +++ b/xen/include/asm-ia64/xenkregs.h @@ -6,7 +6,8 @@ */ #define IA64_TR_SHARED_INFO 3 /* dtr3: page shared with domain */ #define IA64_TR_VHPT 4 /* dtr4: vhpt */ -#define IA64_TR_ARCH_INFO 5 +#define IA64_TR_ARCH_INFO 5 +#define IA64_TR_PERVP_VHPT 6 /* Processor status register bits: */ #define IA64_PSR_VM_BIT 46 diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index e6e5c48f8e..f3bb61a932 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -38,6 +38,33 @@ typedef struct { #define INVALID_MFN (~0UL) +#define MEM_G (1UL << 30) +#define MEM_M (1UL << 20) + +#define MMIO_START (3 * MEM_G) +#define MMIO_SIZE (512 * MEM_M) + +#define VGA_IO_START 0xA0000UL +#define VGA_IO_SIZE 0x20000 + +#define LEGACY_IO_START (MMIO_START + MMIO_SIZE) +#define LEGACY_IO_SIZE (64*MEM_M) + +#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE) +#define IO_PAGE_SIZE PAGE_SIZE + +#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE) +#define STORE_PAGE_SIZE PAGE_SIZE + +#define IO_SAPIC_START 0xfec00000UL +#define IO_SAPIC_SIZE 0x100000 + +#define PIB_START 0xfee00000UL +#define PIB_SIZE 0x100000 + +#define GFW_START (4*MEM_G -16*MEM_M) +#define GFW_SIZE (16*MEM_M) + /* * NB. This may become a 64-bit count with no shift. If this happens then the * structure size will still be 8 bytes, so no other alignments will change. diff --git a/xen/include/public/io/ioreq.h b/xen/include/public/io/ioreq.h index 5e0b66e501..210810e6af 100644 --- a/xen/include/public/io/ioreq.h +++ b/xen/include/public/io/ioreq.h @@ -35,6 +35,13 @@ #define IOREQ_TYPE_OR 3 #define IOREQ_TYPE_XOR 4 +#ifdef __HYPERVISOR__ +#include +#else +#include +#endif + + /* * VMExit dispatcher should cooperate with instruction decoder to * prepare this structure and notify service OS and DM by sending @@ -55,10 +62,6 @@ typedef struct { u8 type; /* I/O type */ } ioreq_t; -#define MAX_VECTOR 256 -#define BITS_PER_BYTE 8 -#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(u64))) - typedef struct { u64 pic_intr[INTR_LEN]; u64 pic_mask[INTR_LEN]; @@ -67,10 +70,11 @@ typedef struct { typedef struct { ioreq_t vp_ioreq; - unsigned long vp_intr[INTR_LEN]; + vl_apic_info apic_intr; } vcpu_iodata_t; typedef struct { + int vcpu_number; global_iodata_t sp_global; vcpu_iodata_t vcpu_iodata[1]; } shared_iopage_t; diff --git a/xen/include/public/io/vmx_vlapic.h b/xen/include/public/io/vmx_vlapic.h index c414329628..c765bb0cc6 100644 --- a/xen/include/public/io/vmx_vlapic.h +++ b/xen/include/public/io/vmx_vlapic.h @@ -1,57 +1,29 @@ #ifndef _VMX_VLAPIC_H #define _VMX_VLAPIC_H -/* - We extended one bit for PIC type - */ #define VLAPIC_DELIV_MODE_FIXED 0x0 #define VLAPIC_DELIV_MODE_LPRI 0x1 #define VLAPIC_DELIV_MODE_SMI 0x2 +#define VLAPIC_DELIV_MODE_PMI 0x2 #define VLAPIC_DELIV_MODE_NMI 0x4 #define VLAPIC_DELIV_MODE_INIT 0x5 #define VLAPIC_DELIV_MODE_STARTUP 0x6 #define VLAPIC_DELIV_MODE_EXT 0x7 #define VLAPIC_DELIV_MODE_MASK 0x8 -#define VLAPIC_MSG_LEVEL 4 - -#define INTR_EXT 0 -#define INTR_APIC 1 -#define INTR_LAPIC 2 - -#define VL_STATE_EOI 1 -#define VL_STATE_EXT_LOCK 2 -#define VL_STATE_MSG_LOCK 3 -#define VL_STATE_EOI_LOCK 3 - -#define VLOCAL_APIC_MAX_INTS 256 -#define VLAPIC_INT_COUNT (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(u64))) -#define VLAPIC_INT_COUNT_32 (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(u32))) - -struct vapic_bus_message{ - u8 deliv_mode:4; /* deliver mode, including fixed, LPRI, etc */ - u8 level:1; /* level or edge */ - u8 trig_mod:1; /* assert or disassert */ - u8 reserved:2; - u8 vector; -}; +#define MAX_VECTOR 256 +#define BITS_PER_BYTE 8 +#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(u64))) +#define INTR_LEN_32 (MAX_VECTOR/(BITS_PER_BYTE * sizeof(u32))) typedef struct { - /* interrupt for PIC and ext type IOAPIC interrupt */ - u64 vl_ext_intr[VLAPIC_INT_COUNT]; - u64 vl_ext_intr_mask[VLAPIC_INT_COUNT]; - u64 vl_apic_intr[VLAPIC_INT_COUNT]; - u64 vl_apic_tmr[VLAPIC_INT_COUNT]; - u64 vl_eoi[VLAPIC_INT_COUNT]; u32 vl_lapic_id; - u32 direct_intr; u32 vl_apr; u32 vl_logical_dest; u32 vl_dest_format; u32 vl_arb_id; - u32 vl_state; - u32 apic_msg_count; - struct vapic_bus_message vl_apic_msg[24]; -} vlapic_info; + u64 irr[INTR_LEN]; + u64 tmr[INTR_LEN]; +}vl_apic_info; #endif /* _VMX_VLAPIC_H_ */ From 10c606b1feb6a56a70d76e69c1fc45fa23d0740b Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Thu, 13 Oct 2005 16:02:35 -0600 Subject: [PATCH 05/36] Modify printfs to be able to compile on ia64. Width arguments of printf ("%*") should be an int. --- tools/libxc/xc_ia64_stubs.c | 19 ++++++++----------- tools/xenstore/xs_tdb_dump.c | 6 +++--- tools/xenstore/xsls.c | 2 +- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/tools/libxc/xc_ia64_stubs.c b/tools/libxc/xc_ia64_stubs.c index 84e53b95fc..b67f83b26b 100644 --- a/tools/libxc/xc_ia64_stubs.c +++ b/tools/libxc/xc_ia64_stubs.c @@ -17,17 +17,14 @@ int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns, } int xc_vmx_build(int xc_handle, - u32 domid, - int memsize, - const char *image_name, - struct mem_map *mem_mapp, - const char *ramdisk_name, - const char *cmdline, - unsigned int control_evtchn, - unsigned long flags, - unsigned int vcpus, - unsigned int store_evtchn, - unsigned long *store_mfn) + uint32_t domid, + int memsize, + const char *image_name, + unsigned int control_evtchn, + unsigned long flags, + unsigned int vcpus, + unsigned int store_evtchn, + unsigned long *store_mfn) { PERROR("xc_vmx_build not implemented\n"); return -1; diff --git a/tools/xenstore/xs_tdb_dump.c b/tools/xenstore/xs_tdb_dump.c index a68f19fc2b..f7e54fbe75 100644 --- a/tools/xenstore/xs_tdb_dump.c +++ b/tools/xenstore/xs_tdb_dump.c @@ -53,17 +53,17 @@ int main(int argc, char *argv[]) hdr = (void *)data.dptr; if (data.dsize < sizeof(*hdr)) fprintf(stderr, "%.*s: BAD truncated\n", - key.dsize, key.dptr); + (int)key.dsize, key.dptr); else if (data.dsize != total_size(hdr)) fprintf(stderr, "%.*s: BAD length %i for %i/%i/%i (%i)\n", - key.dsize, key.dptr, data.dsize, + (int)key.dsize, key.dptr, (int)data.dsize, hdr->num_perms, hdr->datalen, hdr->childlen, total_size(hdr)); else { unsigned int i; char *p; - printf("%.*s: ", key.dsize, key.dptr); + printf("%.*s: ", (int)key.dsize, key.dptr); for (i = 0; i < hdr->num_perms; i++) printf("%s%c%i", i == 0 ? "" : ",", diff --git a/tools/xenstore/xsls.c b/tools/xenstore/xsls.c index f8cf24536a..6cfcbc1d11 100644 --- a/tools/xenstore/xsls.c +++ b/tools/xenstore/xsls.c @@ -25,7 +25,7 @@ void print_dir(struct xs_handle *h, char *path, int cur_depth) if (val == NULL) printf(":\n"); else if ((unsigned)len > (151 - strlen(e[i]))) - printf(" = \"%.*s...\"\n", 148 - strlen(e[i]), val); + printf(" = \"%.*s...\"\n", 148 - (int)strlen(e[i]), val); else printf(" = \"%s\"\n", val); free(val); From e092cf627200db9ab60856bac7c07b6052225524 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Fri, 14 Oct 2005 11:56:18 -0600 Subject: [PATCH 06/36] Fix itir bugs in vcpu_transalte and do some cleanup to avoid a gazillion unnecessary function calls. Signed-off-by: Dan Magenheimer --- xen/arch/ia64/xen/vcpu.c | 236 +++++++++++----------------------- xen/include/asm-ia64/domain.h | 2 + 2 files changed, 77 insertions(+), 161 deletions(-) diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c index 15d897ef0d..a068ab3e40 100644 --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -66,8 +66,16 @@ unsigned long phys_translate_count = 0; unsigned long vcpu_verbose = 0; #define verbose(a...) do {if (vcpu_verbose) printf(a);} while(0) -extern TR_ENTRY *match_tr(VCPU *vcpu, unsigned long ifa); -extern TR_ENTRY *match_dtlb(VCPU *vcpu, unsigned long ifa); +//#define vcpu_quick_region_check(_tr_regions,_ifa) 1 +#define vcpu_quick_region_check(_tr_regions,_ifa) \ + (_tr_regions & (1 << ((unsigned long)_ifa >> 61))) +#define vcpu_quick_region_set(_tr_regions,_ifa) \ + do {_tr_regions |= (1 << ((unsigned long)_ifa >> 61)); } while (0) + +// FIXME: also need to check && (!trp->key || vcpu_pkr_match(trp->key)) +#define vcpu_match_tr_entry(_trp,_ifa,_rid) \ + ((_trp->p && (_trp->rid==_rid) && (_ifa >= _trp->vadr) && \ + (_ifa < (_trp->vadr + (1L<< _trp->ps)) - 1))) /************************************************************************** VCPU general register access routines @@ -620,7 +628,7 @@ void vcpu_pend_interrupt(VCPU *vcpu, UINT64 vector) return; } if ( VMX_DOMAIN(vcpu) ) { - set_bit(vector,VCPU(vcpu,irr)); + set_bit(vector,VCPU(vcpu,irr)); } else { /* if (!test_bit(vector,PSCB(vcpu,delivery_mask))) return; */ @@ -630,16 +638,6 @@ void vcpu_pend_interrupt(VCPU *vcpu, UINT64 vector) set_bit(vector,PSCBX(vcpu,irr)); PSCB(vcpu,pending_interruption) = 1; } - -#if 0 - /* Keir: I think you should unblock when an interrupt is pending. */ - { - int running = test_bit(_VCPUF_running, &vcpu->vcpu_flags); - vcpu_unblock(vcpu); - if ( running ) - smp_send_event_check_cpu(vcpu->processor); - } -#endif } void early_tick(VCPU *vcpu) @@ -710,14 +708,6 @@ UINT64 vcpu_check_pending_interrupts(VCPU *vcpu) } //printf("returned to caller\n"); -#if 0 -if (vector == (PSCB(vcpu,itv) & 0xff)) { - UINT64 now = ia64_get_itc(); - UINT64 itm = PSCBX(vcpu,domain_itm); - if (now < itm) early_tick(vcpu); - -} -#endif return vector; } @@ -1070,23 +1060,6 @@ void vcpu_set_next_timer(VCPU *vcpu) /* gloss over the wraparound problem for now... we know it exists * but it doesn't matter right now */ -#if 0 - /* ensure at least next SP tick is in the future */ - if (!interval) PSCBX(vcpu,xen_itm) = now + -#if 0 - (running_on_sim() ? SIM_DEFAULT_CLOCK_RATE : - DEFAULT_CLOCK_RATE); -#else - 3000000; -//printf("vcpu_set_next_timer: HACK!\n"); -#endif -#if 0 - if (PSCBX(vcpu,xen_itm) < now) - while (PSCBX(vcpu,xen_itm) < now + (interval>>1)) - PSCBX(vcpu,xen_itm) += interval; -#endif -#endif - if (is_idle_task(vcpu->domain)) { // printf("****** vcpu_set_next_timer called during idle!!\n"); vcpu_safe_set_itm(s); @@ -1177,14 +1150,6 @@ void vcpu_pend_timer(VCPU *vcpu) // don't deliver another return; } -#if 0 - // attempt to flag "timer tick before its due" source - { - UINT64 itm = PSCBX(vcpu,domain_itm); - UINT64 now = ia64_get_itc(); - if (now < itm) printf("******* vcpu_pend_timer: pending before due!\n"); - } -#endif vcpu_pend_interrupt(vcpu, itv); } @@ -1199,33 +1164,6 @@ UINT64 vcpu_timer_pending_early(VCPU *vcpu) return (vcpu_deliverable_timer(vcpu) && (now < itm)); } -//FIXME: This is a hack because everything dies if a timer tick is lost -void vcpu_poke_timer(VCPU *vcpu) -{ - UINT64 itv = PSCB(vcpu,itv) & 0xff; - UINT64 now = ia64_get_itc(); - UINT64 itm = PSCBX(vcpu,domain_itm); - UINT64 irr; - - if (vcpu_timer_disabled(vcpu)) return; - if (!itm) return; - if (itv != 0xefL) { - printf("vcpu_poke_timer: unimplemented itv=%lx!\n",itv); - while(1); - } - // using 0xef instead of itv so can get real irr - if (now > itm && !test_bit(0xefL, PSCBX(vcpu,insvc))) { - if (!test_bit(0xefL,PSCBX(vcpu,irr))) { - irr = ia64_getreg(_IA64_REG_CR_IRR3); - if (irr & (1L<<(0xef-0xc0))) return; -if (now-itm>0x800000) -printf("*** poking timer: now=%lx,vitm=%lx,xitm=%lx,itm=%lx\n",now,itm,local_cpu_data->itm_next,ia64_get_itm()); - vcpu_pend_timer(vcpu); - } - } -} - - /************************************************************************** Privileged operation emulation routines **************************************************************************/ @@ -1318,13 +1256,6 @@ IA64FAULT vcpu_thash(VCPU *vcpu, UINT64 vadr, UINT64 *pval) UINT64 VHPT_addr = VHPT_addr1 | ((VHPT_addr2a | VHPT_addr2b) << 15) | VHPT_addr3; -#if 0 - if (VHPT_addr1 == 0xe000000000000000L) { - printf("vcpu_thash: thash unsupported with rr7 @%lx\n", - PSCB(vcpu,iip)); - return (IA64_ILLOP_FAULT); - } -#endif //verbose("vcpu_thash: vadr=%p, VHPT_addr=%p\n",vadr,VHPT_addr); *pval = VHPT_addr; return (IA64_NO_FAULT); @@ -1343,8 +1274,10 @@ unsigned long vhpt_translate_count = 0; IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pteval, UINT64 *itir, UINT64 *iha) { - unsigned long pta, pta_mask, pte, ps; + unsigned long pta, pta_mask, pte, ps, rid, itir_addr; + int i; TR_ENTRY *trp; + IA64FAULT fault; ia64_rr rr; if (!(address >> 61)) { @@ -1362,68 +1295,83 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pt phys_translate_count++; return IA64_NO_FAULT; } - - /* check translation registers */ - if ((trp = match_tr(vcpu,address))) { - tr_translate_count++; - *pteval = trp->page_flags; - *itir = trp->itir; - return IA64_NO_FAULT; + rid = virtualize_rid(vcpu,get_rr(address) & RR_RID_MASK); + if (is_data) { + if (vcpu_quick_region_check(vcpu->arch.dtr_regions,address)) { + for (trp = vcpu->arch.dtrs, i = NDTRS; i; i--, trp++) { + if (vcpu_match_tr_entry(trp,address,rid)) { + *pteval = trp->page_flags; + *itir = trp->itir; + tr_translate_count++; + return IA64_NO_FAULT; + } + } + } + } + // FIXME?: check itr's for data accesses too, else bad things happen? + /* else */ { + if (vcpu_quick_region_check(vcpu->arch.itr_regions,address)) { + for (trp = vcpu->arch.itrs, i = NITRS; i; i--, trp++) { + if (vcpu_match_tr_entry(trp,address,rid)) { + *pteval = trp->page_flags; + *itir = trp->itir; + tr_translate_count++; + return IA64_NO_FAULT; + } + } + } } /* check 1-entry TLB */ - if ((trp = match_dtlb(vcpu,address))) { - dtlb_translate_count++; + // FIXME?: check dtlb for inst accesses too, else bad things happen? + trp = &vcpu->arch.dtlb; + if (/* is_data && */ vcpu_match_tr_entry(trp,address,rid)) { if (vcpu->domain==dom0 && !in_tpa) *pteval = trp->page_flags; else *pteval = vcpu->arch.dtlb_pte; -// printf("DTLB MATCH... NEW, DOM%s, %s\n", vcpu->domain==dom0? -// "0":"U", in_tpa?"vcpu_tpa":"ia64_do_page_fault"); *itir = trp->itir; + dtlb_translate_count++; return IA64_NO_FAULT; } /* check guest VHPT */ pta = PSCB(vcpu,pta); - rr.rrval = PSCB(vcpu,rrs)[address>>61]; - if (!rr.ve || !(pta & IA64_PTA_VE)) { -// FIXME? does iha get set for alt faults? does xenlinux depend on it? - vcpu_thash(vcpu, address, iha); -// FIXME?: does itir get set for alt faults? - *itir = vcpu_get_itir_on_fault(vcpu,address); - return (is_data ? IA64_ALT_DATA_TLB_VECTOR : - IA64_ALT_INST_TLB_VECTOR); - } if (pta & IA64_PTA_VF) { /* long format VHPT - not implemented */ - // thash won't work right? panic_domain(vcpu_regs(vcpu),"can't do long format VHPT\n"); //return (is_data ? IA64_DATA_TLB_VECTOR:IA64_INST_TLB_VECTOR); } - /* avoid recursively walking (short format) VHPT */ - pta_mask = (itir_mask(pta) << 3) >> 3; - if (((address ^ pta) & pta_mask) == 0) - return (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR); - vcpu_thash(vcpu, address, iha); - if (__copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0) { -// FIXME?: does itir get set for vhpt faults? - *itir = vcpu_get_itir_on_fault(vcpu,*iha); - return IA64_VHPT_FAULT; + rr.rrval = PSCB(vcpu,rrs)[address>>61]; + fault = is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR; + if (!rr.ve || !(pta & IA64_PTA_VE)) { + // architecturally, iha is optionally set for alt faults but xenlinux + // depends on it so should document it as part of PV interface + fault += IA64_ALT_INST_TLB_VECTOR - IA64_INST_TLB_VECTOR; } - /* - * Optimisation: this VHPT walker aborts on not-present pages - * instead of inserting a not-present translation, this allows - * vectoring directly to the miss handler. - */ - if (pte & _PAGE_P) { - *pteval = pte; - *itir = vcpu_get_itir_on_fault(vcpu,address); - vhpt_translate_count++; - return IA64_NO_FAULT; + /* avoid recursively walking (short format) VHPT */ + else if (((address ^ pta) & ((itir_mask(pta) << 3) >> 3)) != 0) { + + if (__copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0) + // virtual VHPT walker "missed" in TLB + fault = IA64_VHPT_FAULT; + + /* + * Optimisation: this VHPT walker aborts on not-present pages + * instead of inserting a not-present translation, this allows + * vectoring directly to the miss handler. + */ + else if (pte & _PAGE_P) { + *pteval = pte; + vhpt_translate_count++; + return IA64_NO_FAULT; + } } - *itir = vcpu_get_itir_on_fault(vcpu,address); - return (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR); + + // for VHPT fault, use itir based on iha, not on fault address + itir_addr = (fault == IA64_VHPT_FAULT) ? *iha : address; + *itir = vcpu_get_itir_on_fault(vcpu,itir_addr); + return fault; } IA64FAULT vcpu_tpa(VCPU *vcpu, UINT64 vadr, UINT64 *padr) @@ -1738,33 +1686,6 @@ static void vcpu_set_tr_entry(TR_ENTRY *trp, UINT64 pte, UINT64 itir, UINT64 ifa } } -TR_ENTRY *vcpu_match_tr_entry(VCPU *vcpu, TR_ENTRY *trp, UINT64 ifa, int count) -{ - unsigned long rid = (get_rr(ifa) & RR_RID_MASK); - int i; - - for (i = 0; i < count; i++, trp++) { - if (!trp->p) continue; - if (physicalize_rid(vcpu,trp->rid) != rid) continue; - if (ifa < trp->vadr) continue; - if (ifa >= (trp->vadr + (1L << trp->ps)) - 1) continue; - //if (trp->key && !match_pkr(vcpu,trp->key)) continue; - return trp; - } - return 0; -} - -TR_ENTRY *match_tr(VCPU *vcpu, unsigned long ifa) -{ - TR_ENTRY *trp; - - trp = vcpu_match_tr_entry(vcpu,vcpu->arch.dtrs,ifa,NDTRS); - if (trp) return trp; - trp = vcpu_match_tr_entry(vcpu,vcpu->arch.itrs,ifa,NITRS); - if (trp) return trp; - return 0; -} - IA64FAULT vcpu_itr_d(VCPU *vcpu, UINT64 slot, UINT64 pte, UINT64 itir, UINT64 ifa) { @@ -1774,6 +1695,7 @@ IA64FAULT vcpu_itr_d(VCPU *vcpu, UINT64 slot, UINT64 pte, trp = &PSCBX(vcpu,dtrs[slot]); //printf("***** itr.d: setting slot %d: ifa=%p\n",slot,ifa); vcpu_set_tr_entry(trp,pte,itir,ifa); + vcpu_quick_region_set(PSCBX(vcpu,dtr_regions),ifa); return IA64_NO_FAULT; } @@ -1786,6 +1708,7 @@ IA64FAULT vcpu_itr_i(VCPU *vcpu, UINT64 slot, UINT64 pte, trp = &PSCBX(vcpu,itrs[slot]); //printf("***** itr.i: setting slot %d: ifa=%p\n",slot,ifa); vcpu_set_tr_entry(trp,pte,itir,ifa); + vcpu_quick_region_set(PSCBX(vcpu,itr_regions),ifa); return IA64_NO_FAULT; } @@ -1837,17 +1760,6 @@ void vcpu_itc_no_srlz(VCPU *vcpu, UINT64 IorD, UINT64 vaddr, UINT64 pte, UINT64 } } -// NOTE: returns a physical pte, NOT a "metaphysical" pte, so do not check -// the physical address contained for correctness -TR_ENTRY *match_dtlb(VCPU *vcpu, unsigned long ifa) -{ - TR_ENTRY *trp; - - if (trp = vcpu_match_tr_entry(vcpu,&vcpu->arch.dtlb,ifa,1)) - return (&vcpu->arch.dtlb); - return 0UL; -} - IA64FAULT vcpu_itc_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa) { unsigned long pteval, logps = (itir >> 2) & 0x3f; @@ -1954,12 +1866,14 @@ IA64FAULT vcpu_ptc_ga(VCPU *vcpu,UINT64 vadr,UINT64 addr_range) IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr,UINT64 addr_range) { printf("vcpu_ptr_d: Purging TLB is unsupported\n"); + // don't forget to recompute dtr_regions return (IA64_ILLOP_FAULT); } IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr,UINT64 addr_range) { printf("vcpu_ptr_i: Purging TLB is unsupported\n"); + // don't forget to recompute itr_regions return (IA64_ILLOP_FAULT); } diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h index 6904cf7d21..5d6aa93bf2 100644 --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -49,6 +49,8 @@ struct arch_vcpu { TR_ENTRY dtrs[NDTRS]; TR_ENTRY itlb; TR_ENTRY dtlb; + unsigned int itr_regions; + unsigned int dtr_regions; unsigned long itlb_pte; unsigned long dtlb_pte; unsigned long irr[4]; From 0dac9bd332fe1b13c69e3b0a2422ae6ff4b79ea0 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Fri, 14 Oct 2005 12:33:37 -0600 Subject: [PATCH 07/36] Add fault debug feature (assuming guest doesn't use kr2), by Tristan Gingold --- xen/arch/ia64/xen/ivt.S | 49 ++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/xen/arch/ia64/xen/ivt.S b/xen/arch/ia64/xen/ivt.S index 1477bbe18e..d01f276278 100644 --- a/xen/arch/ia64/xen/ivt.S +++ b/xen/arch/ia64/xen/ivt.S @@ -484,6 +484,7 @@ END(alt_dtlb_miss) ///////////////////////////////////////////////////////////////////////////////////////// // 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45) ENTRY(nested_dtlb_miss) + DBG_FAULT(5) /* * In the absence of kernel bugs, we get here when the virtually mapped linear * page table is accessed non-speculatively (e.g., in the Dirty-bit, Instruction @@ -552,10 +553,10 @@ END(nested_dtlb_miss) ///////////////////////////////////////////////////////////////////////////////////////// // 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24) ENTRY(ikey_miss) + DBG_FAULT(6) #ifdef XEN REFLECT(6) #endif - DBG_FAULT(6) FAULT(6) END(ikey_miss) @@ -597,10 +598,10 @@ END(page_fault) ///////////////////////////////////////////////////////////////////////////////////////// // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) ENTRY(dkey_miss) + DBG_FAULT(7) #ifdef XEN REFLECT(7) #endif - DBG_FAULT(7) FAULT(7) END(dkey_miss) @@ -608,10 +609,10 @@ END(dkey_miss) ///////////////////////////////////////////////////////////////////////////////////////// // 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54) ENTRY(dirty_bit) + DBG_FAULT(8) #ifdef XEN REFLECT(8) #endif - DBG_FAULT(8) /* * What we do here is to simply turn on the dirty bit in the PTE. We need to * update both the page-table and the TLB entry. To efficiently access the PTE, @@ -673,6 +674,7 @@ END(dirty_bit) ///////////////////////////////////////////////////////////////////////////////////////// // 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27) ENTRY(iaccess_bit) + DBG_FAULT(9) #ifdef XEN mov r31=pr; mov r16=cr.isr @@ -681,7 +683,6 @@ ENTRY(iaccess_bit) movl r20=0x2400 br.sptk.many fast_access_reflect;; #endif - DBG_FAULT(9) // Like Entry 8, except for instruction access mov r16=cr.ifa // get the address that caused the fault movl r30=1f // load continuation point in case of nested fault @@ -746,6 +747,7 @@ END(iaccess_bit) ///////////////////////////////////////////////////////////////////////////////////////// // 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55) ENTRY(daccess_bit) + DBG_FAULT(10) #ifdef XEN mov r31=pr; mov r16=cr.isr @@ -754,7 +756,6 @@ ENTRY(daccess_bit) movl r20=0x2800 br.sptk.many fast_access_reflect;; #endif - DBG_FAULT(10) // Like Entry 8, except for data access mov r16=cr.ifa // get the address that caused the fault movl r30=1f // load continuation point in case of nested fault @@ -971,8 +972,10 @@ slow_interrupt: mov out0=cr.ivr // pass cr.ivr as first arg #endif add out1=16,sp // pass pointer to pt_regs as second arg +#ifndef XEN ;; srlz.d // make sure we see the effect of cr.ivr +#endif movl r14=ia64_leave_kernel ;; mov rp=r14 @@ -1363,10 +1366,10 @@ END(dispatch_to_fault_handler) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49) ENTRY(page_not_present) + DBG_FAULT(20) #ifdef XEN REFLECT(20) #endif - DBG_FAULT(20) mov r16=cr.ifa rsm psr.dt /* @@ -1386,10 +1389,10 @@ END(page_not_present) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52) ENTRY(key_permission) + DBG_FAULT(21) #ifdef XEN REFLECT(21) #endif - DBG_FAULT(21) mov r16=cr.ifa rsm psr.dt mov r31=pr @@ -1402,10 +1405,10 @@ END(key_permission) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26) ENTRY(iaccess_rights) + DBG_FAULT(22) #ifdef XEN REFLECT(22) #endif - DBG_FAULT(22) mov r16=cr.ifa rsm psr.dt mov r31=pr @@ -1418,6 +1421,7 @@ END(iaccess_rights) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53) ENTRY(daccess_rights) + DBG_FAULT(23) #ifdef XEN mov r31=pr; mov r16=cr.isr @@ -1426,7 +1430,6 @@ ENTRY(daccess_rights) movl r20=0x5300 br.sptk.many fast_access_reflect;; #endif - DBG_FAULT(23) mov r16=cr.ifa rsm psr.dt mov r31=pr @@ -1459,6 +1462,7 @@ END(general_exception) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35) ENTRY(disabled_fp_reg) + DBG_FAULT(25) #ifdef XEN #if 0 mov r20=pr @@ -1483,7 +1487,6 @@ ENTRY(disabled_fp_reg) // br.sptk.many floating_panic ;; #endif - DBG_FAULT(25) rsm psr.dfh // ensure we can access fph ;; srlz.d @@ -1496,10 +1499,10 @@ END(disabled_fp_reg) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50) ENTRY(nat_consumption) + DBG_FAULT(26) #ifdef XEN REFLECT(26) #endif - DBG_FAULT(26) FAULT(26) END(nat_consumption) @@ -1507,11 +1510,11 @@ END(nat_consumption) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5700 Entry 27 (size 16 bundles) Speculation (40) ENTRY(speculation_vector) + DBG_FAULT(27) #ifdef XEN // this probably need not reflect... REFLECT(27) #endif - DBG_FAULT(27) /* * A [f]chk.[as] instruction needs to take the branch to the recovery code but * this part of the architecture is not implemented in hardware on some CPUs, such @@ -1554,10 +1557,10 @@ END(speculation_vector) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56) ENTRY(debug_vector) + DBG_FAULT(29) #ifdef XEN REFLECT(29) #endif - DBG_FAULT(29) FAULT(29) END(debug_vector) @@ -1565,10 +1568,10 @@ END(debug_vector) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57) ENTRY(unaligned_access) + DBG_FAULT(30) #ifdef XEN REFLECT(30) #endif - DBG_FAULT(30) mov r16=cr.ipsr mov r31=pr // prepare to save predicates ;; @@ -1579,10 +1582,10 @@ END(unaligned_access) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57) ENTRY(unsupported_data_reference) + DBG_FAULT(31) #ifdef XEN REFLECT(31) #endif - DBG_FAULT(31) FAULT(31) END(unsupported_data_reference) @@ -1590,10 +1593,10 @@ END(unsupported_data_reference) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64) ENTRY(floating_point_fault) + DBG_FAULT(32) #ifdef XEN REFLECT(32) #endif - DBG_FAULT(32) FAULT(32) END(floating_point_fault) @@ -1601,10 +1604,10 @@ END(floating_point_fault) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66) ENTRY(floating_point_trap) + DBG_FAULT(33) #ifdef XEN REFLECT(33) #endif - DBG_FAULT(33) FAULT(33) END(floating_point_trap) @@ -1612,10 +1615,10 @@ END(floating_point_trap) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66) ENTRY(lower_privilege_trap) + DBG_FAULT(34) #ifdef XEN REFLECT(34) #endif - DBG_FAULT(34) FAULT(34) END(lower_privilege_trap) @@ -1623,10 +1626,10 @@ END(lower_privilege_trap) ///////////////////////////////////////////////////////////////////////////////////////// // 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68) ENTRY(taken_branch_trap) + DBG_FAULT(35) #ifdef XEN REFLECT(35) #endif - DBG_FAULT(35) FAULT(35) END(taken_branch_trap) @@ -1634,10 +1637,10 @@ END(taken_branch_trap) ///////////////////////////////////////////////////////////////////////////////////////// // 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69) ENTRY(single_step_trap) + DBG_FAULT(36) #ifdef XEN REFLECT(36) #endif - DBG_FAULT(36) FAULT(36) END(single_step_trap) @@ -1693,10 +1696,10 @@ END(single_step_trap) ///////////////////////////////////////////////////////////////////////////////////////// // 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77) ENTRY(ia32_exception) + DBG_FAULT(45) #ifdef XEN REFLECT(45) #endif - DBG_FAULT(45) FAULT(45) END(ia32_exception) @@ -1704,10 +1707,10 @@ END(ia32_exception) ///////////////////////////////////////////////////////////////////////////////////////// // 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept (30,31,59,70,71) ENTRY(ia32_intercept) + DBG_FAULT(46) #ifdef XEN REFLECT(46) #endif - DBG_FAULT(46) #ifdef CONFIG_IA32_SUPPORT mov r31=pr mov r16=cr.isr @@ -1737,10 +1740,10 @@ END(ia32_intercept) ///////////////////////////////////////////////////////////////////////////////////////// // 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt (74) ENTRY(ia32_interrupt) + DBG_FAULT(47) #ifdef XEN REFLECT(47) #endif - DBG_FAULT(47) #ifdef CONFIG_IA32_SUPPORT mov r31=pr br.sptk.many dispatch_to_ia32_handler From a6d23361e36e0e409bd7692235d74d0bf4738467 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Fri, 14 Oct 2005 14:11:12 -0600 Subject: [PATCH 08/36] Fix reprogram_ac_timer corner case bug, by Tristan Gingold --- xen/arch/ia64/xen/xentime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/arch/ia64/xen/xentime.c b/xen/arch/ia64/xen/xentime.c index cdd17b0673..57e5dea2b6 100644 --- a/xen/arch/ia64/xen/xentime.c +++ b/xen/arch/ia64/xen/xentime.c @@ -240,7 +240,7 @@ int reprogram_ac_timer(s_time_t timeout) s_time_t expire; unsigned long seq, cur_itc, itm_next; - if (!domain0_ready) return 1; + if (!domain0_ready || timeout == 0) return 1; do { seq = read_seqbegin(&xtime_lock); From 8f6de3653ef6ab97e9ebb64cd9db3a24c3e465b4 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Fri, 14 Oct 2005 21:09:43 -0600 Subject: [PATCH 09/36] More itir fixes in vcpu_translate and cleanup --- xen/arch/ia64/xen/vcpu.c | 56 +++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c index a068ab3e40..bcb0428fab 100644 --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -1274,11 +1274,9 @@ unsigned long vhpt_translate_count = 0; IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pteval, UINT64 *itir, UINT64 *iha) { - unsigned long pta, pta_mask, pte, ps, rid, itir_addr; + unsigned long pta, pte, rid, rr; int i; TR_ENTRY *trp; - IA64FAULT fault; - ia64_rr rr; if (!(address >> 61)) { if (!PSCB(vcpu,metaphysical_mode)) { @@ -1295,7 +1293,9 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pt phys_translate_count++; return IA64_NO_FAULT; } - rid = virtualize_rid(vcpu,get_rr(address) & RR_RID_MASK); + + rr = PSCB(vcpu,rrs)[address>>61]; + rid = rr & RR_RID_MASK; if (is_data) { if (vcpu_quick_region_check(vcpu->arch.dtr_regions,address)) { for (trp = vcpu->arch.dtrs, i = NDTRS; i; i--, trp++) { @@ -1340,38 +1340,34 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pt //return (is_data ? IA64_DATA_TLB_VECTOR:IA64_INST_TLB_VECTOR); } + *itir = rr & (RR_RID_MASK | RR_PS_MASK); + // note: architecturally, iha is optionally set for alt faults but + // xenlinux depends on it so should document it as part of PV interface vcpu_thash(vcpu, address, iha); - rr.rrval = PSCB(vcpu,rrs)[address>>61]; - fault = is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR; - if (!rr.ve || !(pta & IA64_PTA_VE)) { - // architecturally, iha is optionally set for alt faults but xenlinux - // depends on it so should document it as part of PV interface - fault += IA64_ALT_INST_TLB_VECTOR - IA64_INST_TLB_VECTOR; - } + if (!(rr & RR_VE_MASK) || !(pta & IA64_PTA_VE)) + return (is_data ? IA64_ALT_DATA_TLB_VECTOR : IA64_ALT_INST_TLB_VECTOR); /* avoid recursively walking (short format) VHPT */ - else if (((address ^ pta) & ((itir_mask(pta) << 3) >> 3)) != 0) { + if (((address ^ pta) & ((itir_mask(pta) << 3) >> 3)) == 0) + return (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR); - if (__copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0) - // virtual VHPT walker "missed" in TLB - fault = IA64_VHPT_FAULT; + if (__copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0) + // virtual VHPT walker "missed" in TLB + return IA64_VHPT_FAULT; - /* - * Optimisation: this VHPT walker aborts on not-present pages - * instead of inserting a not-present translation, this allows - * vectoring directly to the miss handler. - */ - else if (pte & _PAGE_P) { - *pteval = pte; - vhpt_translate_count++; - return IA64_NO_FAULT; - } - } + /* + * Optimisation: this VHPT walker aborts on not-present pages + * instead of inserting a not-present translation, this allows + * vectoring directly to the miss handler. + */ + if (!(pte & _PAGE_P)) + return (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR); - // for VHPT fault, use itir based on iha, not on fault address - itir_addr = (fault == IA64_VHPT_FAULT) ? *iha : address; - *itir = vcpu_get_itir_on_fault(vcpu,itir_addr); - return fault; + /* found mapping in guest VHPT! */ + *itir = rr & RR_PS_MASK; + *pteval = pte; + vhpt_translate_count++; + return IA64_NO_FAULT; } IA64FAULT vcpu_tpa(VCPU *vcpu, UINT64 vadr, UINT64 *padr) From f4f64c70a2648574376d58275e7fd8a380516c1a Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Fri, 21 Oct 2005 13:58:39 -0600 Subject: [PATCH 10/36] Backout incautious public/io header changes --- xen/Rules.mk | 1 - xen/arch/ia64/Rules.mk | 2 +- xen/include/public/io/ioreq.h | 66 ++++++++++++++++-------------- xen/include/public/io/vmx_vlapic.h | 64 +++++++++++++++++++++++------ 4 files changed, 88 insertions(+), 45 deletions(-) diff --git a/xen/Rules.mk b/xen/Rules.mk index a1ae2c31b5..d57ca65e51 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -47,7 +47,6 @@ test-gcc-flag = $(shell $(CC) -v --help 2>&1 | grep -q " $(1) " && echo $(1)) include $(BASEDIR)/arch/$(TARGET_ARCH)/Rules.mk -CFLAGS += -D__HYPERVISOR__ ifneq ($(debug),y) CFLAGS += -DNDEBUG ifeq ($(verbose),y) diff --git a/xen/arch/ia64/Rules.mk b/xen/arch/ia64/Rules.mk index 279761d893..8eb31cc674 100644 --- a/xen/arch/ia64/Rules.mk +++ b/xen/arch/ia64/Rules.mk @@ -24,7 +24,7 @@ CFLAGS += -I$(BASEDIR)/include/asm-ia64 -I$(BASEDIR)/include/asm-ia64/linux \ -I$(BASEDIR)/include/asm-ia64/linux-null \ -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen CFLAGS += -Wno-pointer-arith -Wredundant-decls -CFLAGS += -DIA64 -DXEN -DLINUX_2_6 -DV_IOSAPIC_READY +CFLAGS += -DIA64 -DXEN -DLINUX_2_6 CFLAGS += -ffixed-r13 -mfixed-range=f12-f15,f32-f127 CFLAGS += -w -g ifeq ($(VALIDATE_VT),y) diff --git a/xen/include/public/io/ioreq.h b/xen/include/public/io/ioreq.h index 210810e6af..d502171bbf 100644 --- a/xen/include/public/io/ioreq.h +++ b/xen/include/public/io/ioreq.h @@ -29,18 +29,11 @@ #define STATE_IORESP_READY 3 #define STATE_IORESP_HOOK 4 -#define IOREQ_TYPE_PIO 0 /* pio */ -#define IOREQ_TYPE_COPY 1 /* mmio ops */ -#define IOREQ_TYPE_AND 2 -#define IOREQ_TYPE_OR 3 -#define IOREQ_TYPE_XOR 4 - -#ifdef __HYPERVISOR__ -#include -#else -#include -#endif - +#define IOREQ_TYPE_PIO 0 /* pio */ +#define IOREQ_TYPE_COPY 1 /* mmio ops */ +#define IOREQ_TYPE_AND 2 +#define IOREQ_TYPE_OR 3 +#define IOREQ_TYPE_XOR 4 /* * VMExit dispatcher should cooperate with instruction decoder to @@ -48,35 +41,48 @@ * virq */ typedef struct { - u64 addr; /* physical address */ - u64 size; /* size in bytes */ - u64 count; /* for rep prefixes */ + uint64_t addr; /* physical address */ + uint64_t size; /* size in bytes */ + uint64_t count; /* for rep prefixes */ union { - u64 data; /* data */ - void *pdata; /* pointer to data */ + uint64_t data; /* data */ + void *pdata; /* pointer to data */ } u; - u8 state:4; - u8 pdata_valid:1; /* if 1, use pdata above */ - u8 dir:1; /* 1=read, 0=write */ - u8 df:1; - u8 type; /* I/O type */ + uint8_t state:4; + uint8_t pdata_valid:1; /* if 1, use pdata above */ + uint8_t dir:1; /* 1=read, 0=write */ + uint8_t df:1; + uint8_t type; /* I/O type */ } ioreq_t; +#define MAX_VECTOR 256 +#define BITS_PER_BYTE 8 +#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint64_t))) + typedef struct { - u64 pic_intr[INTR_LEN]; - u64 pic_mask[INTR_LEN]; - int eport; /* Event channel port */ + uint64_t pic_intr[INTR_LEN]; + uint64_t pic_mask[INTR_LEN]; + int eport; /* Event channel port */ } global_iodata_t; typedef struct { - ioreq_t vp_ioreq; - vl_apic_info apic_intr; + ioreq_t vp_ioreq; + unsigned long vp_intr[INTR_LEN]; } vcpu_iodata_t; typedef struct { - int vcpu_number; - global_iodata_t sp_global; - vcpu_iodata_t vcpu_iodata[1]; + global_iodata_t sp_global; + vcpu_iodata_t vcpu_iodata[1]; } shared_iopage_t; #endif /* _IOREQ_H_ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/io/vmx_vlapic.h b/xen/include/public/io/vmx_vlapic.h index c765bb0cc6..5a8162b2e1 100644 --- a/xen/include/public/io/vmx_vlapic.h +++ b/xen/include/public/io/vmx_vlapic.h @@ -1,29 +1,67 @@ #ifndef _VMX_VLAPIC_H #define _VMX_VLAPIC_H +/* + We extended one bit for PIC type + */ #define VLAPIC_DELIV_MODE_FIXED 0x0 #define VLAPIC_DELIV_MODE_LPRI 0x1 #define VLAPIC_DELIV_MODE_SMI 0x2 -#define VLAPIC_DELIV_MODE_PMI 0x2 #define VLAPIC_DELIV_MODE_NMI 0x4 #define VLAPIC_DELIV_MODE_INIT 0x5 #define VLAPIC_DELIV_MODE_STARTUP 0x6 #define VLAPIC_DELIV_MODE_EXT 0x7 #define VLAPIC_DELIV_MODE_MASK 0x8 -#define MAX_VECTOR 256 -#define BITS_PER_BYTE 8 -#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(u64))) -#define INTR_LEN_32 (MAX_VECTOR/(BITS_PER_BYTE * sizeof(u32))) +#define VLAPIC_MSG_LEVEL 4 + +#define INTR_EXT 0 +#define INTR_APIC 1 +#define INTR_LAPIC 2 + +#define VL_STATE_EOI 1 +#define VL_STATE_EXT_LOCK 2 +#define VL_STATE_MSG_LOCK 3 +#define VL_STATE_EOI_LOCK 3 + +#define VLOCAL_APIC_MAX_INTS 256 +#define VLAPIC_INT_COUNT (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(uint64_t))) +#define VLAPIC_INT_COUNT_32 (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(uint32_t))) + +struct vapic_bus_message{ + uint8_t deliv_mode:4; /* deliver mode, including fixed, LPRI, etc */ + uint8_t level:1; /* level or edge */ + uint8_t trig_mod:1; /* assert or disassert */ + uint8_t reserved:2; + uint8_t vector; +}; typedef struct { - u32 vl_lapic_id; - u32 vl_apr; - u32 vl_logical_dest; - u32 vl_dest_format; - u32 vl_arb_id; - u64 irr[INTR_LEN]; - u64 tmr[INTR_LEN]; -}vl_apic_info; + /* interrupt for PIC and ext type IOAPIC interrupt */ + uint64_t vl_ext_intr[VLAPIC_INT_COUNT]; + uint64_t vl_ext_intr_mask[VLAPIC_INT_COUNT]; + uint64_t vl_apic_intr[VLAPIC_INT_COUNT]; + uint64_t vl_apic_tmr[VLAPIC_INT_COUNT]; + uint64_t vl_eoi[VLAPIC_INT_COUNT]; + uint32_t vl_lapic_id; + uint32_t direct_intr; + uint32_t vl_apr; + uint32_t vl_logical_dest; + uint32_t vl_dest_format; + uint32_t vl_arb_id; + uint32_t vl_state; + uint32_t apic_msg_count; + struct vapic_bus_message vl_apic_msg[24]; +} vlapic_info; #endif /* _VMX_VLAPIC_H_ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ From ee52af859ff75ed9391d497fdde37b60978fbca8 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Mon, 24 Oct 2005 09:15:53 -0600 Subject: [PATCH 11/36] Necessary change to make ia64 dom0 rework: - All even channels on xen/ia64 shares one common interrupt vector - xen_start_info is initialized only after xen_init, so adjust sequence to avoid access before initialization Signed-off-by Kevin Tian --- .../arch/ia64/xen/drivers/evtchn_ia64.c | 8 ++++++-- linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c | 2 +- .../drivers/xen/xenbus/xenbus_probe.c | 11 ++++++----- 3 files changed, 13 insertions(+), 8 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 0027b82a62..ac8ff9ec4c 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 @@ -29,7 +29,7 @@ unsigned int bind_virq_to_evtchn(int virq) return op.u.bind_virq.port; } -int bind_virq_to_irq(int virq) +int bind_virq_to_irq(int virq, int cpu) { printk("bind_virq_to_irq called... FIXME??\n"); while(1); @@ -66,7 +66,11 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn, evtchns[evtchn].handler = handler; evtchns[evtchn].dev_id = dev_id; unmask_evtchn(evtchn); - return 0; + //return 0; + /* On ia64, there's only one irq vector allocated for all event channels, + * so let's just return evtchn as handle for later communication + */ + return evtchn; } void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id) diff --git a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c index b13f22a771..db954ca768 100644 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c @@ -25,8 +25,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index e5c9de1139..74d42f6d8d 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -714,11 +714,7 @@ static int xsd_port_read(char *page, char **start, off_t off, static int __init xenbus_probe_init(void) { - int err = 0; - /* - ** Domain0 doesn't have a store_evtchn or store_mfn yet. - */ - int dom0 = (xen_start_info->store_evtchn == 0); + int err = 0, dom0; printk("xenbus_probe_init\n"); @@ -733,6 +729,11 @@ static int __init xenbus_probe_init(void) device_register(&xenbus_frontend.dev); device_register(&xenbus_backend.dev); + /* + ** Domain0 doesn't have a store_evtchn or store_mfn yet. + */ + dom0 = (xen_start_info->store_evtchn == 0); + if (dom0) { unsigned long page; From b92c88b84702ad40305932e4cfba366f0e07b307 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Mon, 24 Oct 2005 10:46:39 -0600 Subject: [PATCH 12/36] Need additional include for ia64 --- linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c index c8d1204fc2..7e22cc0c30 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c @@ -28,6 +28,7 @@ * IN THE SOFTWARE. */ +#include #include #include #include From c845fe6a331ce0713ba9dd45351b55c54cfc2fa8 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Mon, 24 Oct 2005 11:31:09 -0600 Subject: [PATCH 13/36] Define VHPT constants from VHPT_SIZE_LOG2. Prototypes added. --- xen/include/asm-ia64/vhpt.h | 40 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/xen/include/asm-ia64/vhpt.h b/xen/include/asm-ia64/vhpt.h index 8402d878b4..d4dfce6b8a 100644 --- a/xen/include/asm-ia64/vhpt.h +++ b/xen/include/asm-ia64/vhpt.h @@ -5,27 +5,16 @@ #define VHPT_ENABLED_REGION_0_TO_6 1 #define VHPT_ENABLED_REGION_7 0 +/* Size of the VHPT. */ +#define VHPT_SIZE_LOG2 24 -#if 0 +/* Number of entries in the VHPT. The size of an entry is 4*8B == 32B */ +#define VHPT_NUM_ENTRIES (1 << (VHPT_SIZE_LOG2 - 5)) + +#define VHPT_CACHE_MASK (VHPT_NUM_ENTRIES - 1) #define VHPT_CACHE_ENTRY_SIZE 64 -#define VHPT_CACHE_MASK 2097151 -#define VHPT_CACHE_NUM_ENTRIES 32768 -#define VHPT_NUM_ENTRIES 2097152 -#define VHPT_CACHE_ENTRY_SIZE_LOG2 6 -#define VHPT_SIZE_LOG2 26 //???? -#define VHPT_PAGE_SHIFT 26 //???? -#else -//#define VHPT_CACHE_NUM_ENTRIES 2048 -//#define VHPT_NUM_ENTRIES 131072 -//#define VHPT_CACHE_MASK 131071 -//#define VHPT_SIZE_LOG2 22 //???? -#define VHPT_CACHE_ENTRY_SIZE 64 -#define VHPT_CACHE_NUM_ENTRIES 8192 -#define VHPT_NUM_ENTRIES 524288 -#define VHPT_CACHE_MASK 524287 -#define VHPT_SIZE_LOG2 24 //???? -#define VHPT_PAGE_SHIFT 24 //???? -#endif + +#define VHPT_PAGE_SHIFT VHPT_SIZE_LOG2 // FIXME: These should be automatically generated @@ -52,7 +41,7 @@ // VHPT collison chain entry (part of the "V-Cache") // DO NOT CHANGE THE SIZE OF THIS STRUCTURE (see vhpt.S banked regs calculations) // -typedef struct vcache_entry { +struct vcache_entry { union { struct { unsigned long tag : 63; // 0-62 @@ -123,12 +112,21 @@ struct vhpt_lf_entry { #define INVALID_TI_TAG 0x8000000000000000L +extern void vhpt_init (void); +extern void zero_vhpt_stats(void); +extern int dump_vhpt_stats(char *buf); +extern void vhpt_flush_address(unsigned long vadr, unsigned long addr_range); +extern void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte, + unsigned long logps); +extern void vhpt_insert (unsigned long vadr, unsigned long ptr, + unsigned logps); +extern void vhpt_flush(void); #endif /* !__ASSEMBLY */ #if !VHPT_ENABLED #define VHPT_CCHAIN_LOOKUP(Name, i_or_d) #else -#ifdef CONFIG_SMP +#if 0 /* One VHPT per cpu! def CONFIG_SMP */ #warning "FIXME SMP: VHPT_CCHAIN_LOOKUP needs a semaphore on the VHPT!" #endif From e74b8e24602a5e9e7163777616658c81353063f2 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Mon, 24 Oct 2005 11:32:45 -0600 Subject: [PATCH 14/36] Remove dup prologue lines --- linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S | 2 -- 1 file changed, 2 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S index a7b33a932f..8d701f3284 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S @@ -46,8 +46,6 @@ GLOBAL_ENTRY(ia64_switch_to) .prologue alloc r16=ar.pfs,1,0,0,0 #endif - .prologue - alloc r16=ar.pfs,1,0,0,0 DO_SAVE_SWITCH_STACK .body From 3901f5a33067a64b5682cf7741b805581e39f949 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Mon, 24 Oct 2005 11:41:27 -0600 Subject: [PATCH 15/36] Code reordering for (partial) gcc3.4 compatibility Signed-off-by Akio Takabe --- xen/arch/ia64/vmx/vmx_phy_mode.c | 14 +++---- xen/arch/ia64/vmx/vmx_process.c | 65 ++++++++++++++++---------------- xen/arch/ia64/xen/xentime.c | 27 ++++++------- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/xen/arch/ia64/vmx/vmx_phy_mode.c b/xen/arch/ia64/vmx/vmx_phy_mode.c index 7ba3b0b837..47e3abb597 100644 --- a/xen/arch/ia64/vmx/vmx_phy_mode.c +++ b/xen/arch/ia64/vmx/vmx_phy_mode.c @@ -156,13 +156,6 @@ physical_itlb_miss_domn(VCPU *vcpu, u64 vadr) } #endif -void -physical_itlb_miss(VCPU *vcpu, u64 vadr) -{ - physical_itlb_miss_dom0(vcpu, vadr); -} - - void physical_itlb_miss_dom0(VCPU *vcpu, u64 vadr) { @@ -186,6 +179,13 @@ physical_itlb_miss_dom0(VCPU *vcpu, u64 vadr) } +void +physical_itlb_miss(VCPU *vcpu, u64 vadr) +{ + physical_itlb_miss_dom0(vcpu, vadr); +} + + void physical_dtlb_miss(VCPU *vcpu, u64 vadr) { diff --git a/xen/arch/ia64/vmx/vmx_process.c b/xen/arch/ia64/vmx/vmx_process.c index 2d7d889733..170a24f6b5 100644 --- a/xen/arch/ia64/vmx/vmx_process.c +++ b/xen/arch/ia64/vmx/vmx_process.c @@ -56,6 +56,38 @@ extern struct ia64_sal_retval pal_emulator_static(UINT64); extern struct ia64_sal_retval sal_emulator(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64); extern void rnat_consumption (VCPU *vcpu); #define DOMN_PAL_REQUEST 0x110000 + +static UINT64 vec2off[68] = {0x0,0x400,0x800,0xc00,0x1000, 0x1400,0x1800, + 0x1c00,0x2000,0x2400,0x2800,0x2c00,0x3000,0x3400,0x3800,0x3c00,0x4000, + 0x4400,0x4800,0x4c00,0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600, + 0x5700,0x5800,0x5900,0x5a00,0x5b00,0x5c00,0x5d00,0x5e00,0x5f00,0x6000, + 0x6100,0x6200,0x6300,0x6400,0x6500,0x6600,0x6700,0x6800,0x6900,0x6a00, + 0x6b00,0x6c00,0x6d00,0x6e00,0x6f00,0x7000,0x7100,0x7200,0x7300,0x7400, + 0x7500,0x7600,0x7700,0x7800,0x7900,0x7a00,0x7b00,0x7c00,0x7d00,0x7e00, + 0x7f00, +}; + + + +void vmx_reflect_interruption(UINT64 ifa,UINT64 isr,UINT64 iim, + UINT64 vector,REGS *regs) +{ + VCPU *vcpu = current; + UINT64 viha,vpsr = vmx_vcpu_get_psr(vcpu); + if(!(vpsr&IA64_PSR_IC)&&(vector!=5)){ + panic("Guest nested fault!"); + } + VCPU(vcpu,isr)=isr; + VCPU(vcpu,iipa) = regs->cr_iip; + vector=vec2off[vector]; + if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR) + VCPU(vcpu,iim) = iim; + else { + set_ifa_itir_iha(vcpu,ifa,1,1,1); + } + inject_guest_interruption(vcpu, vector); +} + IA64FAULT vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, unsigned long iim) { @@ -157,37 +189,6 @@ vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long is vmx_reflect_interruption(ifa,isr,iim,11,regs); } -static UINT64 vec2off[68] = {0x0,0x400,0x800,0xc00,0x1000, 0x1400,0x1800, - 0x1c00,0x2000,0x2400,0x2800,0x2c00,0x3000,0x3400,0x3800,0x3c00,0x4000, - 0x4400,0x4800,0x4c00,0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600, - 0x5700,0x5800,0x5900,0x5a00,0x5b00,0x5c00,0x5d00,0x5e00,0x5f00,0x6000, - 0x6100,0x6200,0x6300,0x6400,0x6500,0x6600,0x6700,0x6800,0x6900,0x6a00, - 0x6b00,0x6c00,0x6d00,0x6e00,0x6f00,0x7000,0x7100,0x7200,0x7300,0x7400, - 0x7500,0x7600,0x7700,0x7800,0x7900,0x7a00,0x7b00,0x7c00,0x7d00,0x7e00, - 0x7f00, -}; - - - -void vmx_reflect_interruption(UINT64 ifa,UINT64 isr,UINT64 iim, - UINT64 vector,REGS *regs) -{ - VCPU *vcpu = current; - UINT64 viha,vpsr = vmx_vcpu_get_psr(vcpu); - if(!(vpsr&IA64_PSR_IC)&&(vector!=5)){ - panic("Guest nested fault!"); - } - VCPU(vcpu,isr)=isr; - VCPU(vcpu,iipa) = regs->cr_iip; - vector=vec2off[vector]; - if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR) - VCPU(vcpu,iim) = iim; - else { - set_ifa_itir_iha(vcpu,ifa,1,1,1); - } - inject_guest_interruption(vcpu, vector); -} - void save_banked_regs_to_vpd(VCPU *v, REGS *regs) { @@ -274,7 +275,7 @@ void vmx_hpw_miss(u64 vadr , u64 vec, REGS* regs) u64 vhpt_adr, gppa; ISR misr; ia64_rr vrr; - REGS *regs; +// REGS *regs; thash_cb_t *vtlb, *vhpt; thash_data_t *data, me; VCPU *v = current; diff --git a/xen/arch/ia64/xen/xentime.c b/xen/arch/ia64/xen/xentime.c index 57e5dea2b6..1b15fb12c7 100644 --- a/xen/arch/ia64/xen/xentime.c +++ b/xen/arch/ia64/xen/xentime.c @@ -38,6 +38,20 @@ static s_time_t stime_irq = 0x0; /* System time at last 'time updat unsigned long itc_scale, ns_scale; unsigned long itc_at_irq; +/* We don't expect an absolute cycle value here, since then no way + * to prevent overflow for large norminator. Normally this conversion + * is used for relative offset. + */ +u64 cycle_to_ns(u64 cycle) +{ + return (cycle * itc_scale) >> 32; +} + +u64 ns_to_cycle(u64 ns) +{ + return (ns * ns_scale) >> 32; +} + static inline u64 get_time_delta(void) { s64 delta_itc; @@ -52,19 +66,6 @@ static inline u64 get_time_delta(void) return cycle_to_ns(delta_itc); } -/* We don't expect an absolute cycle value here, since then no way - * to prevent overflow for large norminator. Normally this conversion - * is used for relative offset. - */ -u64 cycle_to_ns(u64 cycle) -{ - return (cycle * itc_scale) >> 32; -} - -u64 ns_to_cycle(u64 ns) -{ - return (ns * ns_scale) >> 32; -} s_time_t get_s_time(void) { From 9f69bceba2e35d4d993536b5256b6009ae4bf43c Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Mon, 24 Oct 2005 20:56:53 -0600 Subject: [PATCH 16/36] Image builder for ia64/vti domain, together with a example config file. Signed-off-by Ke Yu Signed-off-by Anthony Xu Signed-off-by Kevin Tian --- tools/examples/Makefile | 1 + tools/libxc/xc_ia64_stubs.c | 667 +++++++++++++++++++++++++++++++++++- 2 files changed, 654 insertions(+), 14 deletions(-) diff --git a/tools/examples/Makefile b/tools/examples/Makefile index f58f75e092..2431eb0bf6 100644 --- a/tools/examples/Makefile +++ b/tools/examples/Makefile @@ -16,6 +16,7 @@ XEN_CONFIGS = xend-config.sxp XEN_CONFIGS += xmexample1 XEN_CONFIGS += xmexample2 XEN_CONFIGS += xmexample.vmx +XEN_CONFIGS += xmexample.vti # Xen script dir and scripts to go there. XEN_SCRIPT_DIR = /etc/xen/scripts diff --git a/tools/libxc/xc_ia64_stubs.c b/tools/libxc/xc_ia64_stubs.c index 97dedba5b3..b21959b8d2 100644 --- a/tools/libxc/xc_ia64_stubs.c +++ b/tools/libxc/xc_ia64_stubs.c @@ -1,5 +1,11 @@ #include "xg_private.h" #include "xenguest.h" +#include "xc_private.h" +#include "xc_elf.h" +#include +#include +#include "xen/arch-ia64.h" +#include int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, uint32_t max_factor, uint32_t flags) @@ -16,20 +22,6 @@ int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long nr_pf return -1; } -int xc_vmx_build(int xc_handle, - uint32_t domid, - int memsize, - const char *image_name, - unsigned int control_evtchn, - unsigned long flags, - unsigned int vcpus, - unsigned int store_evtchn, - unsigned long *store_mfn) -{ - PERROR("xc_vmx_build not implemented\n"); - return -1; -} - int xc_plan9_build(int xc_handle, uint32_t domid, @@ -41,6 +33,653 @@ xc_plan9_build(int xc_handle, return -1; } +int xc_ia64_get_pfn_list(int xc_handle, + uint32_t domid, + unsigned long *pfn_buf, + unsigned int start_page, + unsigned int nr_pages) +{ + dom0_op_t op; + int ret; + unsigned long max_pfns = ((unsigned long)start_page << 32) | nr_pages; + + op.cmd = DOM0_GETMEMLIST; + op.u.getmemlist.domain = (domid_t)domid; + op.u.getmemlist.max_pfns = max_pfns; + op.u.getmemlist.buffer = pfn_buf; + + if ( (max_pfns != -1UL) + && mlock(pfn_buf, nr_pages * sizeof(unsigned long)) != 0 ) + { + PERROR("Could not lock pfn list buffer"); + return -1; + } + + ret = do_dom0_op(xc_handle, &op); + + if (max_pfns != -1UL) + (void)munlock(pfn_buf, nr_pages * sizeof(unsigned long)); + + return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; +} + +long xc_get_max_pages(int xc_handle, uint32_t domid) +{ + dom0_op_t op; + op.cmd = DOM0_GETDOMAININFO; + op.u.getdomaininfo.domain = (domid_t)domid; + return (do_dom0_op(xc_handle, &op) < 0) ? + -1 : op.u.getdomaininfo.max_pages; +} + +int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, + void* src_page, unsigned long dst_pfn, int nr_pages) +{ + // N.B. gva should be page aligned + + unsigned long *page_array=NULL; + int i; + + if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ){ + PERROR("Could not allocate memory"); + goto error_out; + } + if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, + dst_pfn>>PAGE_SHIFT, nr_pages) != nr_pages ){ + PERROR("Could not get the page frame list"); + goto error_out; + } + + for ( i=0; i< nr_pages; i++ ){ + if (xc_copy_to_domain_page(xc_handle, domid, page_array[i], + src_page + (i << PAGE_SHIFT))) + goto error_out; + } + free(page_array); + return 0; + +error_out: + if (page_array) + free(page_array); + return -1; +} + + +#define HOB_SIGNATURE 0x3436474953424f48 // "HOBSIG64" +#define GFW_HOB_START ((4UL<<30)-(14UL<<20)) //4G -14M +#define GFW_HOB_SIZE (1UL<<20) //1M +#define MEM_G (1UL << 30) +#define MEM_M (1UL << 20) + +typedef struct { + unsigned long signature; + unsigned int type; + unsigned int length; +} HOB_GENERIC_HEADER; + +/* + * INFO HOB is the first data data in one HOB list + * it contains the control information of the HOB list + */ +typedef struct { + HOB_GENERIC_HEADER header; + unsigned long length; // current length of hob + unsigned long cur_pos; // current poisiton of hob + unsigned long buf_size; // size of hob buffer +}HOB_INFO; + +typedef struct{ + unsigned long start; + unsigned long size; +}hob_mem_t; + +typedef enum { + HOB_TYPE_INFO=0, + HOB_TYPE_TERMINAL, + HOB_TYPE_MEM, + HOB_TYPE_PAL_BUS_GET_FEATURES_DATA, + HOB_TYPE_PAL_CACHE_SUMMARY, + HOB_TYPE_PAL_MEM_ATTRIB, + HOB_TYPE_PAL_CACHE_INFO, + HOB_TYPE_PAL_CACHE_PROT_INFO, + HOB_TYPE_PAL_DEBUG_INFO, + HOB_TYPE_PAL_FIXED_ADDR, + HOB_TYPE_PAL_FREQ_BASE, + HOB_TYPE_PAL_FREQ_RATIOS, + HOB_TYPE_PAL_HALT_INFO, + HOB_TYPE_PAL_PERF_MON_INFO, + HOB_TYPE_PAL_PROC_GET_FEATURES, + HOB_TYPE_PAL_PTCE_INFO, + HOB_TYPE_PAL_REGISTER_INFO, + HOB_TYPE_PAL_RSE_INFO, + HOB_TYPE_PAL_TEST_INFO, + HOB_TYPE_PAL_VM_SUMMARY, + HOB_TYPE_PAL_VM_INFO, + HOB_TYPE_PAL_VM_PAGE_SIZE, + HOB_TYPE_MAX +}hob_type_t; + +static int hob_init( void *buffer ,unsigned long buf_size); +static int add_pal_hob(void* hob_buf); +static int add_mem_hob(void* hob_buf, unsigned long dom_mem_size); +static int build_hob (void* hob_buf, unsigned long hob_buf_size, + unsigned long dom_mem_size); +static int load_hob(int xc_handle,uint32_t dom, void *hob_buf); + +int xc_ia64_build_hob(int xc_handle, uint32_t dom, unsigned long memsize){ + + char hob_buf[GFW_HOB_SIZE]; + + if ( build_hob( hob_buf, GFW_HOB_SIZE, memsize<<20) < 0){ + PERROR("Could not build hob"); + return -1; + } + + if ( load_hob( xc_handle, dom, hob_buf) <0){ + PERROR("Could not load hob"); + return -1; + } + + return 0; + +} +static int +hob_init( void *buffer ,unsigned long buf_size) +{ + HOB_INFO *phit; + HOB_GENERIC_HEADER *terminal; + + if (sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER) > buf_size){ + // buffer too small + return -1; + } + + phit = (HOB_INFO*)buffer; + phit->header.signature = HOB_SIGNATURE; + phit->header.type = HOB_TYPE_INFO; + phit->header.length = sizeof(HOB_INFO); + phit->length = sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER); + phit->cur_pos = 0; + phit->buf_size = buf_size; + + terminal = (HOB_GENERIC_HEADER*) (buffer + sizeof(HOB_INFO)); + terminal->signature= HOB_SIGNATURE; + terminal->type = HOB_TYPE_TERMINAL; + terminal->length = sizeof(HOB_GENERIC_HEADER); + + return 0; +} + +/* + * Add a new HOB to the HOB List. + * + * hob_start - start address of hob buffer + * type - type of the hob to be added + * data - data of the hob to be added + * data_size - size of the data + */ +static int +hob_add( + void* hob_start, + int type, + void* data, + int data_size +) +{ + HOB_INFO *phit; + HOB_GENERIC_HEADER *newhob,*tail; + + phit = (HOB_INFO*)hob_start; + + if (phit->length + data_size > phit->buf_size){ + // no space for new hob + return -1; + } + + //append new HOB + newhob = (HOB_GENERIC_HEADER*) + (hob_start + phit->length - sizeof(HOB_GENERIC_HEADER)); + newhob->signature = HOB_SIGNATURE; + newhob->type = type; + newhob->length = data_size + sizeof(HOB_GENERIC_HEADER); + memcpy((void*)newhob + sizeof(HOB_GENERIC_HEADER), data, data_size); + + // append terminal HOB + tail = (HOB_GENERIC_HEADER*) ( hob_start + phit->length + data_size); + tail->signature = HOB_SIGNATURE; + tail->type = HOB_TYPE_TERMINAL; + tail->length = sizeof(HOB_GENERIC_HEADER); + + // adjust HOB list length + phit->length += sizeof(HOB_GENERIC_HEADER)+ data_size; + + return 0; + +} + +int get_hob_size(void* hob_buf){ + + HOB_INFO *phit = (HOB_INFO*)hob_buf; + + if (phit->header.signature != HOB_SIGNATURE){ + PERROR("xc_get_hob_size:Incorrect signature"); + return -1; + } + return phit->length; +} + +int build_hob (void* hob_buf, unsigned long hob_buf_size, + unsigned long dom_mem_size) +{ + //Init HOB List + if (hob_init (hob_buf, hob_buf_size)<0){ + PERROR("buffer too small"); + goto err_out; + } + + if ( add_mem_hob( hob_buf,dom_mem_size) < 0){ + PERROR("Add memory hob failed, buffer too small"); + goto err_out; + } + + if ( add_pal_hob( hob_buf ) < 0 ){ + PERROR("Add PAL hob failed, buffer too small"); + goto err_out; + } + + return 0; + +err_out: + return -1; +} + +static int +load_hob(int xc_handle, uint32_t dom, void *hob_buf) +{ + // hob_buf should be page aligned + int hob_size; + int nr_pages; + + if ((hob_size = get_hob_size(hob_buf)) < 0){ + PERROR("Invalid hob data"); + return -1; + } + + if (hob_size > GFW_HOB_SIZE){ + PERROR("No enough memory for hob data"); + return -1; + } + + nr_pages = (hob_size + PAGE_SIZE -1) >> PAGE_SHIFT; + + return xc_ia64_copy_to_domain_pages(xc_handle, dom, + hob_buf, GFW_HOB_START, nr_pages ); +} + +#define MIN(x, y) ((x) < (y)) ? (x) : (y) +static int +add_mem_hob(void* hob_buf, unsigned long dom_mem_size){ + hob_mem_t memhob; + + // less than 3G + memhob.start = 0; + memhob.size = MIN(dom_mem_size, 0xC0000000); + + if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0){ + return -1; + } + + if (dom_mem_size > 0xC0000000) { + // 4G ~ 4G+remain + memhob.start = 0x100000000; //4G + memhob.size = dom_mem_size - 0xC0000000; + if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0) + return -1; + } + return 0; +} + +unsigned char config_pal_bus_get_features_data[24] = { + 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_cache_summary[16] = { + 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0}; +unsigned char config_pal_mem_attrib[8] = { + 241, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_cache_info[152] = { + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12, + 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1, + 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0, + 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7, + 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255, + 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9, + 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0 +}; +unsigned char config_pal_cache_prot_info[200] = { + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, + 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, + 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, + 32, 0, 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 160, + 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; +unsigned char config_pal_debug_info[16] = { + 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_fixed_addr[8] = { + 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_freq_base[8] = { + 109, 219, 182, 13, 0, 0, 0, 0 +}; +unsigned char config_pal_freq_ratios[24] = { + 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 7, 0, 0, 0 +}; +unsigned char config_pal_halt_info[64] = { + 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_perf_mon_info[136] = { + 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_proc_get_features[104] = { + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_ptce_info[24] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_register_info[64] = { + 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3, + 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4, + 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255 +}; +unsigned char config_pal_rse_info[16] = { + 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_test_info[48] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_vm_summary[16] = { + 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_vm_info[104] = { + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, + 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0, + 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_vm_page_size[16] = { + 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0 +}; + +typedef struct{ + hob_type_t type; + void* data; + unsigned long size; +}hob_batch_t; + +hob_batch_t hob_batch[]={ + { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA, + &config_pal_bus_get_features_data, + sizeof(config_pal_bus_get_features_data) + }, + { HOB_TYPE_PAL_CACHE_SUMMARY, + &config_pal_cache_summary, + sizeof(config_pal_cache_summary) + }, + { HOB_TYPE_PAL_MEM_ATTRIB, + &config_pal_mem_attrib, + sizeof(config_pal_mem_attrib) + }, + { HOB_TYPE_PAL_CACHE_INFO, + &config_pal_cache_info, + sizeof(config_pal_cache_info) + }, + { HOB_TYPE_PAL_CACHE_PROT_INFO, + &config_pal_cache_prot_info, + sizeof(config_pal_cache_prot_info) + }, + { HOB_TYPE_PAL_DEBUG_INFO, + &config_pal_debug_info, + sizeof(config_pal_debug_info) + }, + { HOB_TYPE_PAL_FIXED_ADDR, + &config_pal_fixed_addr, + sizeof(config_pal_fixed_addr) + }, + { HOB_TYPE_PAL_FREQ_BASE, + &config_pal_freq_base, + sizeof(config_pal_freq_base) + }, + { HOB_TYPE_PAL_FREQ_RATIOS, + &config_pal_freq_ratios, + sizeof(config_pal_freq_ratios) + }, + { HOB_TYPE_PAL_HALT_INFO, + &config_pal_halt_info, + sizeof(config_pal_halt_info) + }, + { HOB_TYPE_PAL_PERF_MON_INFO, + &config_pal_perf_mon_info, + sizeof(config_pal_perf_mon_info) + }, + { HOB_TYPE_PAL_PROC_GET_FEATURES, + &config_pal_proc_get_features, + sizeof(config_pal_proc_get_features) + }, + { HOB_TYPE_PAL_PTCE_INFO, + &config_pal_ptce_info, + sizeof(config_pal_ptce_info) + }, + { HOB_TYPE_PAL_REGISTER_INFO, + &config_pal_register_info, + sizeof(config_pal_register_info) + }, + { HOB_TYPE_PAL_RSE_INFO, + &config_pal_rse_info, + sizeof(config_pal_rse_info) + }, + { HOB_TYPE_PAL_TEST_INFO, + &config_pal_test_info, + sizeof(config_pal_test_info) + }, + { HOB_TYPE_PAL_VM_SUMMARY, + &config_pal_vm_summary, + sizeof(config_pal_vm_summary) + }, + { HOB_TYPE_PAL_VM_INFO, + &config_pal_vm_info, + sizeof(config_pal_vm_info) + }, + { HOB_TYPE_PAL_VM_PAGE_SIZE, + &config_pal_vm_page_size, + sizeof(config_pal_vm_page_size) + }, +}; + +static int add_pal_hob(void* hob_buf){ + int i; + for (i=0; i 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) { + PERROR("Guest firmware size is incorrect [%ld]?", image_size); + return -1; + } + + /* Load guest firmware */ + if( xc_ia64_copy_to_domain_pages( xc_handle, dom, + image, 4*MEM_G-image_size, image_size>>PAGE_SHIFT)) { + PERROR("Could not load guest firmware into domain"); + goto error_out; + } + + /* Hand-off state passed to guest firmware */ + if (xc_ia64_build_hob(xc_handle, dom, memsize) < 0){ + PERROR("Could not build hob\n"); + goto error_out; + } + + /* Retrieve special pages like io, xenstore, etc. */ + if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array, IO_PAGE_START>>PAGE_SHIFT, 2) != 2 ) + { + PERROR("Could not get the page frame list"); + goto error_out; + } + + *store_mfn = page_array[1]; + if ((sp = (shared_iopage_t *) xc_map_foreign_range( + xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, + page_array[0])) == 0) + goto error_out; + memset(sp, 0, PAGE_SIZE); + sp->sp_global.eport = control_evtchn; + munmap(sp, PAGE_SIZE); + + return 0; + + error_out: + return -1; +} + +int xc_vmx_build(int xc_handle, + uint32_t domid, + int memsize, + const char *image_name, + unsigned int control_evtchn, + unsigned int vcpus, + unsigned int store_evtchn, + unsigned long *store_mfn) +{ + dom0_op_t launch_op, op; + int rc ; + vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt; + char *image = NULL; + unsigned long image_size; + unsigned long nr_pages; + + if ( (nr_pages = xc_get_max_pages(xc_handle, domid)) < 0 ) + { + PERROR("Could not find total pages for domain"); + goto error_out; + } + + if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL ){ + PERROR("Could not read guest firmware image %s",image_name); + goto error_out; + } + + image_size = (image_size + PAGE_SIZE - 1) & PAGE_MASK; + + if ( mlock(&st_ctxt, sizeof(st_ctxt) ) ){ + PERROR("Unable to mlock ctxt"); + return 1; + } + + op.cmd = DOM0_GETDOMAININFO; + op.u.getdomaininfo.domain = (domid_t)domid; + if ( (do_dom0_op(xc_handle, &op) < 0) || + ((uint16_t)op.u.getdomaininfo.domain != domid) ) { + PERROR("Could not get info on domain"); + goto error_out; + } + + if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) ){ + PERROR("Could not get vcpu context"); + goto error_out; + } + + if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ) { + ERROR("Domain is already constructed"); + goto error_out; + } + + if ( setup_guest(xc_handle, domid, (unsigned long)memsize, image, image_size, + control_evtchn, store_evtchn, store_mfn ) < 0 ){ + ERROR("Error constructing guest OS"); + goto error_out; + } + + if ( image != NULL ) + free(image); + + ctxt->flags = VGCF_VMX_GUEST; + ctxt->regs.cr_iip = 0x80000000ffffffb0UL; + ctxt->vcpu.privregs = 0; + + memset( &launch_op, 0, sizeof(launch_op) ); + + launch_op.u.setdomaininfo.domain = (domid_t)domid; + launch_op.u.setdomaininfo.vcpu = 0; + launch_op.u.setdomaininfo.ctxt = ctxt; + + launch_op.cmd = DOM0_SETDOMAININFO; + rc = do_dom0_op(xc_handle, &launch_op); + return rc; + + error_out: + if ( image != NULL ) + free(image); + + return -1; +} + /* * Local variables: * mode: C From 8620f56614194f72a7b439d588ca60a8e53edf90 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Mon, 24 Oct 2005 20:57:47 -0600 Subject: [PATCH 17/36] Necessary change to support ia64/vti domain build in common code. Signed-off-by Ke Yu Signed-off-by Anthony Xu Signed-off-by Kevin Tian --- tools/libxc/xc_private.c | 40 ---------------------------------- tools/libxc/xenctrl.h | 6 +++++ tools/python/xen/xend/image.py | 17 +++++++++------ 3 files changed, 16 insertions(+), 47 deletions(-) diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index ea3798ebca..75e179a7c7 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -313,46 +313,6 @@ int xc_get_pfn_list(int xc_handle, return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; } -#ifdef __ia64__ -int xc_ia64_get_pfn_list(int xc_handle, - uint32_t domid, - unsigned long *pfn_buf, - unsigned int start_page, - unsigned int nr_pages) -{ - dom0_op_t op; - int ret; - - op.cmd = DOM0_GETMEMLIST; - op.u.getmemlist.domain = (domid_t)domid; - op.u.getmemlist.max_pfns = ((unsigned long)start_page << 32) | nr_pages; - op.u.getmemlist.buffer = pfn_buf; - - if ( mlock(pfn_buf, nr_pages * sizeof(unsigned long)) != 0 ) - { - PERROR("Could not lock pfn list buffer"); - return -1; - } - - /* XXX Hack to put pages in TLB, hypervisor should be able to handle this */ - memset(pfn_buf, 0, nr_pages * sizeof(unsigned long)); - ret = do_dom0_op(xc_handle, &op); - - (void)munlock(pfn_buf, nr_pages * sizeof(unsigned long)); - - return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; -} - -long xc_get_max_pages(int xc_handle, uint32_t domid) -{ - dom0_op_t op; - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)domid; - return (do_dom0_op(xc_handle, &op) < 0) ? - -1 : op.u.getdomaininfo.max_pages; -} -#endif - long xc_get_tot_pages(int xc_handle, uint32_t domid) { dom0_op_t op; diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 98408f25bf..ffbe4fdfff 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -414,6 +414,12 @@ int xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, unsigned long *pfn_buf, unsigned int start_page, unsigned int nr_pages); +int xc_copy_to_domain_page(int xc_handle, uint32_t domid, + unsigned long dst_pfn, void *src_page); + +int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, + void* src_page, unsigned long dst_pfn, int nr_pages); + long xc_get_max_pages(int xc_handle, uint32_t domid); int xc_mmuext_op(int xc_handle, struct mmuext_op *op, unsigned int nr_ops, diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 6cd9f540f3..b6c8209056 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -342,12 +342,15 @@ class VmxImageHandler(ImageHandler): def getDomainMemory(self, mem): """@see ImageHandler.getDomainMemory""" + page_kb = 4 + if os.uname()[4] == 'ia64': + page_kb = 16 # for ioreq_t and xenstore static_pages = 2 - return mem + self.getPageTableSize(mem / 1024) + 4 * static_pages + return mem + (self.getPageTableSize(mem / 1024) + static_pages) * page_kb def getPageTableSize(self, mem_mb): - """Return the size of memory needed for 1:1 page tables for physical + """Return the pages of memory needed for 1:1 page tables for physical mode. @param mem_mb: size in MB @@ -355,13 +358,13 @@ class VmxImageHandler(ImageHandler): """ # 1 page for the PGD + 1 pte page for 4MB of memory (rounded) if os.uname()[4] == 'x86_64': - return (5 + ((mem_mb + 1) >> 1)) * 4 + return 5 + ((mem_mb + 1) >> 1) elif os.uname()[4] == 'ia64': - # XEN/IA64 has p2m table allocated on demand, so only return - # guest firmware size here. - return 16 * 1024 + # 1:1 pgtable is allocated on demand ia64, so just return rom size + # for guest firmware + return 1024 else: - return (1 + ((mem_mb + 3) >> 2)) * 4 + return 1 + ((mem_mb + 3) >> 2) """Table of image handler classes for virtual machine images. Indexed by From 6a106a03b089d9f6153d29188497adc150cb2eeb Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Mon, 24 Oct 2005 21:00:35 -0600 Subject: [PATCH 18/36] Oops, missed hg add of vti example file --- tools/examples/xmexample.vti | 100 +++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 tools/examples/xmexample.vti diff --git a/tools/examples/xmexample.vti b/tools/examples/xmexample.vti new file mode 100644 index 0000000000..63bdc25d3a --- /dev/null +++ b/tools/examples/xmexample.vti @@ -0,0 +1,100 @@ +# -*- mode: python; -*- +#============================================================================ +# Python configuration setup for 'xm create'. +# This script sets the parameters used when a domain is created using 'xm create'. +# You use a separate script for each domain you want to create, or +# you can set the parameters for the domain on the xm command line. +#============================================================================ + +import os, re +arch = os.uname()[4] +arch_libdir = 'lib' + +#---------------------------------------------------------------------------- +# Kernel image file. +kernel = "/boot/Flash.fd" + +# The domain build function. VMX domain uses 'vmx'. +builder='vmx' + +# Initial memory allocation (in megabytes) for the new domain. +memory = 256 + +# A name for your domain. All domains must have different names. +name = "ExampleVMXDomain" + +# Which CPU to start domain on? +#cpu = -1 # leave to Xen to pick + +# Optionally define mac and/or bridge for the network interfaces. +# Random MACs are assigned if not given. +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ] + +#---------------------------------------------------------------------------- +# Define the disk devices you want the domain to have access to, and +# what you want them accessible as. +# Each disk entry is of the form phy:UNAME,DEV,MODE +# where UNAME is the device, DEV is the device name the domain will see, +# and MODE is r for read-only, w for read-write. + +#disk = [ 'phy:hda1,hda1,r' ] +disk = [ 'file:/var/images/xenia64.img,ioemu:hda,w' ] + +#---------------------------------------------------------------------------- +# Set according to whether you want the domain restarted when it exits. +# The default is 'onreboot', which restarts the domain when it shuts down +# with exit code reboot. +# Other values are 'always', and 'never'. + +#restart = 'onreboot' + +#============================================================================ + +# New stuff +device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm.debug' + +# Advanced users only. Don't touch if you don't know what you're doing +memmap = '/usr/lib/xen/boot/mem-map.sxp' + +#----------------------------------------------------------------------------- +# Disk image for +#cdrom= + +#----------------------------------------------------------------------------- +# boot on floppy (a), hard disk (c) or CD-ROM (d) +#boot=[a|c|d] +#----------------------------------------------------------------------------- +# write to temporary files instead of disk image files +#snapshot=1 + +#---------------------------------------------------------------------------- +# enable SDL library for graphics, default = 0 +sdl=1 + +stdvga=1 +#---------------------------------------------------------------------------- +# enable VNC library for graphics, default = 1 +vnc=0 + +#---------------------------------------------------------------------------- +# enable spawning vncviewer(only valid when vnc=1), default = 1 +vncviewer=0 + +#---------------------------------------------------------------------------- +# no graphics, use serial port +#nographic=0 + + +#----------------------------------------------------------------------------- +# enable audio support +#enable-audio=1 + + +#----------------------------------------------------------------------------- +# set the real time clock to local time [default=0 i.e. set to utc] +#localtime=1 + + +#----------------------------------------------------------------------------- +# start in full screen +#full-screen=1 diff -r 42cab8724273 tools/libxc/xc_ia64_stubs.c From 650fa32a005d49cdec715a3cdd4d1955d57036a8 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 27 Oct 2005 17:09:01 +0100 Subject: [PATCH 19/36] BUG_ON() is a macro very very similar to assert(), and it's a really bad idea in general to put statements with side-effects inside such a construct (for example the BUG_ON() could be compiled away for non-debug builds). The patch below fixes this for the drivers/xen tree. I chose the general construct to store the respective return values in a local var instead of an if (...) BUG(); because it looks like most of these BUG_ON()'s need to be replaced by real error handling when going towards production releases anyway, and then the local variable is going to be needed anyway. (and besides the if construct tends to get unreable due to the unlikely() etc). Please apply. Greetings, Arjan van de Ven --- .../drivers/xen/balloon/balloon.c | 37 ++++++++++++------- .../drivers/xen/blkback/blkback.c | 15 +++++--- .../drivers/xen/blkback/interface.c | 8 +++- .../drivers/xen/blkfront/blkfront.c | 6 ++- .../drivers/xen/blktap/blktap.c | 13 ++++--- .../drivers/xen/blktap/interface.c | 8 +++- .../drivers/xen/evtchn/evtchn.c | 8 +++- .../drivers/xen/netback/interface.c | 14 +++++-- .../drivers/xen/netback/netback.c | 31 +++++++++++----- .../drivers/xen/tpmback/interface.c | 8 +++- linux-2.6-xen-sparse/drivers/xen/util.c | 4 +- .../drivers/xen/xenbus/xenbus_probe.c | 4 +- 12 files changed, 106 insertions(+), 50 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c index f630d4bf71..fab1ea6bc3 100644 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c @@ -191,12 +191,13 @@ static int increase_reservation(unsigned long nr_pages) rc = HYPERVISOR_memory_op( XENMEM_increase_reservation, &reservation); if (rc < nr_pages) { + int ret; /* We hit the Xen hard limit: reprobe. */ reservation.extent_start = mfn_list; reservation.nr_extents = rc; - BUG_ON(HYPERVISOR_memory_op( - XENMEM_decrease_reservation, - &reservation) != rc); + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation); + BUG_ON(ret != rc); hard_limit = current_pages + rc - driver_pages; goto out; } @@ -213,11 +214,14 @@ static int increase_reservation(unsigned long nr_pages) xen_machphys_update(mfn_list[i], pfn); /* Link back into the page tables if not highmem. */ - if (pfn < max_low_pfn) - BUG_ON(HYPERVISOR_update_va_mapping( + if (pfn < max_low_pfn) { + int ret; + ret = HYPERVISOR_update_va_mapping( (unsigned long)__va(pfn << PAGE_SHIFT), pfn_pte_ma(mfn_list[i], PAGE_KERNEL), - 0)); + 0); + BUG_ON(ret); + } /* Relinquish the page back to the allocator. */ ClearPageReserved(page); @@ -242,6 +246,7 @@ static int decrease_reservation(unsigned long nr_pages) struct page *page; void *v; int need_sleep = 0; + int ret; struct xen_memory_reservation reservation = { .address_bits = 0, .extent_order = 0, @@ -268,8 +273,9 @@ static int decrease_reservation(unsigned long nr_pages) if (!PageHighMem(page)) { v = phys_to_virt(pfn << PAGE_SHIFT); scrub_pages(v, 1); - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)v, __pte_ma(0), 0)); + ret = HYPERVISOR_update_va_mapping( + (unsigned long)v, __pte_ma(0), 0); + BUG_ON(ret); } #ifdef CONFIG_XEN_SCRUB_PAGES else { @@ -295,8 +301,8 @@ static int decrease_reservation(unsigned long nr_pages) reservation.extent_start = mfn_list; reservation.nr_extents = nr_pages; - BUG_ON(HYPERVISOR_memory_op( - XENMEM_decrease_reservation, &reservation) != nr_pages); + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); + BUG_ON(ret != nr_pages); current_pages -= nr_pages; totalram_pages = current_pages; @@ -501,6 +507,7 @@ static int dealloc_pte_fn( pte_t *pte, struct page *pte_page, unsigned long addr, void *data) { unsigned long mfn = pte_mfn(*pte); + int ret; struct xen_memory_reservation reservation = { .extent_start = &mfn, .nr_extents = 1, @@ -510,8 +517,8 @@ static int dealloc_pte_fn( set_pte_at(&init_mm, addr, pte, __pte_ma(0)); phys_to_machine_mapping[__pa(addr) >> PAGE_SHIFT] = INVALID_P2M_ENTRY; - BUG_ON(HYPERVISOR_memory_op( - XENMEM_decrease_reservation, &reservation) != 1); + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); + BUG_ON(ret != 1); return 0; } @@ -519,6 +526,7 @@ struct page *balloon_alloc_empty_page_range(unsigned long nr_pages) { unsigned long vstart, flags; unsigned int order = get_order(nr_pages * PAGE_SIZE); + int ret; vstart = __get_free_pages(GFP_KERNEL, order); if (vstart == 0) @@ -527,8 +535,9 @@ struct page *balloon_alloc_empty_page_range(unsigned long nr_pages) scrub_pages(vstart, 1 << order); balloon_lock(flags); - BUG_ON(generic_page_range( - &init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL)); + ret = generic_page_range( + &init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL); + BUG_ON(ret); current_pages -= 1UL << order; balloon_unlock(flags); diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c index c9d812695e..3dc929f0a7 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c @@ -108,6 +108,7 @@ static void fast_flush_area(int idx, int nr_pages) struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int i, invcount = 0; u16 handle; + int ret; for (i = 0; i < nr_pages; i++) { handle = pending_handle(idx, i); @@ -120,8 +121,9 @@ static void fast_flush_area(int idx, int nr_pages) invcount++; } - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_unmap_grant_ref, unmap, invcount)); + ret = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, unmap, invcount); + BUG_ON(ret); } @@ -338,6 +340,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) struct bio *bio = NULL, *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST]; int nbio = 0; request_queue_t *q; + int ret; /* Check that number of segments is sane. */ nseg = req->nr_segments; @@ -367,8 +370,8 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) map[i].flags |= GNTMAP_readonly; } - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_map_grant_ref, map, nseg)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); + BUG_ON(ret); for (i = 0; i < nseg; i++) { if (unlikely(map[i].handle < 0)) { @@ -493,6 +496,7 @@ static int __init blkif_init(void) { int i; struct page *page; + int ret; blkif_interface_init(); @@ -509,7 +513,8 @@ static int __init blkif_init(void) spin_lock_init(&blkio_schedule_list_lock); INIT_LIST_HEAD(&blkio_schedule_list); - BUG_ON(kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES) < 0); + ret = kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES); + BUG_ON(ret < 0); blkif_xenbus_init(); 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 ee1889a09a..be6f935191 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c @@ -31,6 +31,7 @@ blkif_t *alloc_blkif(domid_t domid) static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) { struct gnttab_map_grant_ref op; + int ret; op.host_addr = (unsigned long)blkif->blk_ring_area->addr; op.flags = GNTMAP_host_map; @@ -38,8 +39,9 @@ static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) op.dom = blkif->domid; lock_vm_area(blkif->blk_ring_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); unlock_vm_area(blkif->blk_ring_area); + BUG_ON(ret); if (op.handle < 0) { DPRINTK(" Grant table operation failure !\n"); @@ -55,14 +57,16 @@ static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) static void unmap_frontend_page(blkif_t *blkif) { struct gnttab_unmap_grant_ref op; + int ret; op.host_addr = (unsigned long)blkif->blk_ring_area->addr; op.handle = blkif->shmem_handle; op.dev_bus_addr = 0; lock_vm_area(blkif->blk_ring_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); unlock_vm_area(blkif->blk_ring_area); + BUG_ON(ret); } int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) diff --git a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c index 671f16038c..3485d84424 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -305,6 +305,7 @@ static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs) for (i = info->ring.rsp_cons; i != rp; i++) { unsigned long id; + int ret; bret = RING_GET_RESPONSE(&info->ring, i); id = bret->id; @@ -321,9 +322,10 @@ static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs) DPRINTK("Bad return from blkdev data " "request: %x\n", bret->status); - BUG_ON(end_that_request_first( + ret = end_that_request_first( req, (bret->status == BLKIF_RSP_OKAY), - req->hard_nr_sectors)); + req->hard_nr_sectors); + BUG_ON(ret); end_that_request_last(req); break; default: diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c index dacedfc227..03a4fcb970 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c @@ -413,6 +413,7 @@ static void fast_flush_area(int idx, int nr_pages) unsigned int i, op = 0; struct grant_handle_pair *handle; unsigned long ptep; + int ret; for ( i = 0; i < nr_pages; i++) { @@ -440,8 +441,8 @@ static void fast_flush_area(int idx, int nr_pages) BLKTAP_INVALIDATE_HANDLE(handle); } - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_unmap_grant_ref, unmap, op)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap, op); + BUG_ON(ret); if (blktap_vma != NULL) zap_page_range(blktap_vma, @@ -673,6 +674,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2]; int op, ret; unsigned int nseg; + int retval; /* Check that number of segments is sane. */ nseg = req->nr_segments; @@ -740,8 +742,8 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) op++; } - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_map_grant_ref, map, op)); + retval = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op); + BUG_ON(retval); op = 0; for (i = 0; i < (req->nr_segments*2); i += 2) { @@ -877,7 +879,8 @@ static int __init blkif_init(void) spin_lock_init(&blkio_schedule_list_lock); INIT_LIST_HEAD(&blkio_schedule_list); - BUG_ON(kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES) < 0); + i = kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES); + BUG_ON(i<0); blkif_xenbus_init(); diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c index 1394922ac7..dcaedf875e 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c @@ -31,6 +31,7 @@ blkif_t *alloc_blkif(domid_t domid) static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) { struct gnttab_map_grant_ref op; + int ret; op.host_addr = (unsigned long)blkif->blk_ring_area->addr; op.flags = GNTMAP_host_map; @@ -38,8 +39,9 @@ static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) op.dom = blkif->domid; lock_vm_area(blkif->blk_ring_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); unlock_vm_area(blkif->blk_ring_area); + BUG_ON(ret); if (op.handle < 0) { DPRINTK(" Grant table operation failure !\n"); @@ -55,14 +57,16 @@ static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) static void unmap_frontend_page(blkif_t *blkif) { struct gnttab_unmap_grant_ref op; + int ret; op.host_addr = (unsigned long)blkif->blk_ring_area->addr; op.handle = blkif->shmem_handle; op.dev_bus_addr = 0; lock_vm_area(blkif->blk_ring_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); unlock_vm_area(blkif->blk_ring_area); + BUG_ON(ret); } int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) diff --git a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c index d3a805fb72..42f4a8f70a 100644 --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c @@ -282,6 +282,7 @@ static int evtchn_ioctl(struct inode *inode, struct file *file, case IOCTL_EVTCHN_UNBIND: { struct ioctl_evtchn_unbind unbind; + int ret; rc = -EFAULT; if (copy_from_user(&unbind, (void *)arg, sizeof(unbind))) @@ -306,7 +307,8 @@ static int evtchn_ioctl(struct inode *inode, struct file *file, op.cmd = EVTCHNOP_close; op.u.close.port = unbind.port; - BUG_ON(HYPERVISOR_event_channel_op(&op)); + ret = HYPERVISOR_event_channel_op(&op); + BUG_ON(ret); rc = 0; break; @@ -399,6 +401,7 @@ static int evtchn_release(struct inode *inode, struct file *filp) for (i = 0; i < NR_EVENT_CHANNELS; i++) { + int ret; if (port_user[i] != u) continue; @@ -407,7 +410,8 @@ static int evtchn_release(struct inode *inode, struct file *filp) op.cmd = EVTCHNOP_close; op.u.close.port = i; - BUG_ON(HYPERVISOR_event_channel_op(&op)); + ret = HYPERVISOR_event_channel_op(&op); + BUG_ON(ret); } spin_unlock_irq(&port_user_lock); diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c index 404eb98831..7cfd3c944c 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c @@ -115,6 +115,7 @@ static int map_frontend_pages( netif_t *netif, grant_ref_t tx_ring_ref, grant_ref_t rx_ring_ref) { struct gnttab_map_grant_ref op; + int ret; op.host_addr = (unsigned long)netif->comms_area->addr; op.flags = GNTMAP_host_map; @@ -122,8 +123,9 @@ static int map_frontend_pages( op.dom = netif->domid; lock_vm_area(netif->comms_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); unlock_vm_area(netif->comms_area); + BUG_ON(ret); if (op.handle < 0) { DPRINTK(" Gnttab failure mapping tx_ring_ref!\n"); @@ -139,8 +141,9 @@ static int map_frontend_pages( op.dom = netif->domid; lock_vm_area(netif->comms_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); unlock_vm_area(netif->comms_area); + BUG_ON(ret); if (op.handle < 0) { DPRINTK(" Gnttab failure mapping rx_ring_ref!\n"); @@ -156,22 +159,25 @@ static int map_frontend_pages( static void unmap_frontend_pages(netif_t *netif) { struct gnttab_unmap_grant_ref op; + int ret; op.host_addr = (unsigned long)netif->comms_area->addr; op.handle = netif->tx_shmem_handle; op.dev_bus_addr = 0; lock_vm_area(netif->comms_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); unlock_vm_area(netif->comms_area); + BUG_ON(ret); op.host_addr = (unsigned long)netif->comms_area->addr + PAGE_SIZE; op.handle = netif->rx_shmem_handle; op.dev_bus_addr = 0; lock_vm_area(netif->comms_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); unlock_vm_area(netif->comms_area); + BUG_ON(ret); } int netif_map(netif_t *netif, unsigned long tx_ring_ref, diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c index 656ed94ded..2eee002ec6 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c @@ -112,9 +112,12 @@ static void free_mfn(unsigned long mfn) spin_lock_irqsave(&mfn_lock, flags); if ( alloc_index != MAX_MFN_ALLOC ) mfn_list[alloc_index++] = mfn; - else - BUG_ON(HYPERVISOR_memory_op(XENMEM_decrease_reservation, - &reservation) != 1); + else { + int ret; + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation); + BUG_ON(ret != 1); + } spin_unlock_irqrestore(&mfn_lock, flags); } #endif @@ -159,13 +162,15 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) */ if (skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb)) { int hlen = skb->data - skb->head; + int ret; struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len); if ( unlikely(nskb == NULL) ) goto drop; skb_reserve(nskb, hlen); __skb_put(nskb, skb->len); - BUG_ON(skb_copy_bits(skb, -hlen, nskb->data - hlen, - skb->len + hlen)); + ret = skb_copy_bits(skb, -hlen, nskb->data - hlen, + skb->len + hlen); + BUG_ON(ret); nskb->dev = skb->dev; nskb->proto_csum_valid = skb->proto_csum_valid; dev_kfree_skb(skb); @@ -218,6 +223,7 @@ static void net_rx_action(unsigned long unused) struct sk_buff *skb; u16 notify_list[NETIF_RX_RING_SIZE]; int notify_nr = 0; + int ret; skb_queue_head_init(&rxq); @@ -279,7 +285,8 @@ static void net_rx_action(unsigned long unused) mcl++; mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; - BUG_ON(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0); + ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); + BUG_ON(ret != 0); mcl = rx_mcl; if( HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, @@ -421,6 +428,7 @@ inline static void net_tx_action_dealloc(void) u16 pending_idx; PEND_RING_IDX dc, dp; netif_t *netif; + int ret; dc = dealloc_cons; dp = dealloc_prod; @@ -436,8 +444,9 @@ inline static void net_tx_action_dealloc(void) gop->handle = grant_tx_ref[pending_idx]; gop++; } - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops)); + ret = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops); + BUG_ON(ret); while (dealloc_cons != dp) { pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)]; @@ -477,6 +486,7 @@ static void net_tx_action(unsigned long unused) NETIF_RING_IDX i; gnttab_map_grant_ref_t *mop; unsigned int data_len; + int ret; if (dealloc_cons != dealloc_prod) net_tx_action_dealloc(); @@ -599,8 +609,9 @@ static void net_tx_action(unsigned long unused) if (mop == tx_map_ops) return; - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops)); + ret = HYPERVISOR_grant_table_op( + GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops); + BUG_ON(ret); mop = tx_map_ops; while ((skb = __skb_dequeue(&tx_queue)) != NULL) { diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c index 98db181306..6dc05d217b 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c @@ -78,6 +78,7 @@ tpmif_find(domid_t domid, long int instance) static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page) { + int ret; struct gnttab_map_grant_ref op = { .host_addr = (unsigned long)tpmif->tx_area->addr, .flags = GNTMAP_host_map, @@ -86,8 +87,9 @@ map_frontend_page(tpmif_t *tpmif, unsigned long shared_page) }; lock_vm_area(tpmif->tx_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); unlock_vm_area(tpmif->tx_area); + BUG_ON(ret); if (op.handle < 0) { DPRINTK(" Grant table operation failure !\n"); @@ -104,14 +106,16 @@ static void unmap_frontend_page(tpmif_t *tpmif) { struct gnttab_unmap_grant_ref op; + int ret; op.host_addr = (unsigned long)tpmif->tx_area->addr; op.handle = tpmif->shmem_handle; op.dev_bus_addr = 0; lock_vm_area(tpmif->tx_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); unlock_vm_area(tpmif->tx_area); + BUG_ON(ret); } int diff --git a/linux-2.6-xen-sparse/drivers/xen/util.c b/linux-2.6-xen-sparse/drivers/xen/util.c index 8df067f29e..be2b155cf1 100644 --- a/linux-2.6-xen-sparse/drivers/xen/util.c +++ b/linux-2.6-xen-sparse/drivers/xen/util.c @@ -34,7 +34,9 @@ struct vm_struct *alloc_vm_area(unsigned long size) void free_vm_area(struct vm_struct *area) { - BUG_ON(remove_vm_area(area->addr) != area); + struct vm_struct *ret; + ret = remove_vm_area(area->addr); + BUG_ON(ret != area); kfree(area); } diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index e5c9de1139..c3d349b385 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -737,6 +737,7 @@ static int __init xenbus_probe_init(void) unsigned long page; evtchn_op_t op = { 0 }; + int ret; /* Allocate page. */ @@ -757,7 +758,8 @@ static int __init xenbus_probe_init(void) op.u.alloc_unbound.dom = DOMID_SELF; op.u.alloc_unbound.remote_dom = 0; - BUG_ON(HYPERVISOR_event_channel_op(&op)); + ret = HYPERVISOR_event_channel_op(&op); + BUG_ON(ret); xen_start_info->store_evtchn = op.u.alloc_unbound.port; /* And finally publish the above info in /proc/xen */ From 9485da60b740e61f97167db212bf4344cc61a45d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 27 Oct 2005 17:16:12 +0100 Subject: [PATCH 20/36] Use standard int typedefs. Signed-off-by: John Levon --- tools/libxc/xc_elf.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tools/libxc/xc_elf.h b/tools/libxc/xc_elf.h index e0d0c26131..da5e7b3bc8 100644 --- a/tools/libxc/xc_elf.h +++ b/tools/libxc/xc_elf.h @@ -24,26 +24,26 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -typedef u_int8_t Elf_Byte; +typedef uint8_t Elf_Byte; -typedef u_int32_t Elf32_Addr; /* Unsigned program address */ -typedef u_int32_t Elf32_Off; /* Unsigned file offset */ +typedef uint32_t Elf32_Addr; /* Unsigned program address */ +typedef uint32_t Elf32_Off; /* Unsigned file offset */ typedef int32_t Elf32_Sword; /* Signed large integer */ -typedef u_int32_t Elf32_Word; /* Unsigned large integer */ -typedef u_int16_t Elf32_Half; /* Unsigned medium integer */ +typedef uint32_t Elf32_Word; /* Unsigned large integer */ +typedef uint16_t Elf32_Half; /* Unsigned medium integer */ -typedef u_int64_t Elf64_Addr; -typedef u_int64_t Elf64_Off; +typedef uint64_t Elf64_Addr; +typedef uint64_t Elf64_Off; typedef int32_t Elf64_Shalf; typedef int32_t Elf64_Sword; -typedef u_int32_t Elf64_Word; +typedef uint32_t Elf64_Word; typedef int64_t Elf64_Sxword; -typedef u_int64_t Elf64_Xword; +typedef uint64_t Elf64_Xword; -typedef u_int32_t Elf64_Half; -typedef u_int16_t Elf64_Quarter; +typedef uint32_t Elf64_Half; +typedef uint16_t Elf64_Quarter; /* * e_ident[] identification indexes From ce57ab29ffbb14413dc6add66ef5955ab108532b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 27 Oct 2005 17:16:48 +0100 Subject: [PATCH 21/36] Remove a non-portable and unused error.h, and use signal.h not sys/signal.h (in tools/misc). --- tools/misc/cpuperf/cpuperf.c | 1 - tools/misc/miniterm/miniterm.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/misc/cpuperf/cpuperf.c b/tools/misc/cpuperf/cpuperf.c index 999c04891a..5047780532 100644 --- a/tools/misc/cpuperf/cpuperf.c +++ b/tools/misc/cpuperf/cpuperf.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/tools/misc/miniterm/miniterm.c b/tools/misc/miniterm/miniterm.c index 0dc4143b4e..92f8462781 100644 --- a/tools/misc/miniterm/miniterm.c +++ b/tools/misc/miniterm/miniterm.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include From 41ae27972e997eee406be536e15956fe1d9f56b0 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 27 Oct 2005 17:20:33 +0100 Subject: [PATCH 22/36] Remove all binaries on make clean. --- tools/xenstore/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index 32194309d1..6fc3992d21 100644 --- a/tools/xenstore/Makefile +++ b/tools/xenstore/Makefile @@ -77,7 +77,7 @@ libxenstore.so: xs.opic xs_lib.opic clean: testsuite-clean rm -f *.o *.opic *.so rm -f xenstored xs_random xs_stress xs_crashme - rm -f xs_test xenstored_test + rm -f xs_test xenstored_test xs_tdb_dump $(RM) $(PROG_DEP) print-dir: From 2b41ca6037ed6642e61c5d05e94e8646d257289a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 27 Oct 2005 17:24:06 +0100 Subject: [PATCH 23/36] This patch * adapts the Xen access control module to recent changes in the "unbound event channel" interface and its usage * adds checks that became necessary because of domain structures "hanging around" in the domain list after domain destruction This patch is tested on today's xen-unstable with Null, CHWALL, STE, CHWALL_STE policies. Signed-off by: Reiner Sailer --- xen/acm/acm_simple_type_enforcement_hooks.c | 106 ++++++++++++-------- xen/common/acm_ops.c | 13 ++- xen/include/acm/acm_hooks.h | 50 +++++---- 3 files changed, 110 insertions(+), 59 deletions(-) diff --git a/xen/acm/acm_simple_type_enforcement_hooks.c b/xen/acm/acm_simple_type_enforcement_hooks.c index de08f46c2a..41bb1b393c 100644 --- a/xen/acm/acm_simple_type_enforcement_hooks.c +++ b/xen/acm/acm_simple_type_enforcement_hooks.c @@ -392,8 +392,11 @@ check_cache(struct domain *dom, domid_t rdom) { int i; printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom); + + if (dom->ssid == NULL) + return 0; ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(dom)->ssid); + (struct acm_ssid_domain *)(dom->ssid)); for(i=0; i< ACM_TE_CACHE_SIZE; i++) { if ((ste_ssid->ste_cache[i].valid == VALID) && @@ -412,6 +415,8 @@ cache_result(struct domain *subj, struct domain *obj) { struct ste_ssid *ste_ssid; int i; printkd("caching from doms: %x --> %x.\n", subj->domain_id, obj->domain_id); + if (subj->ssid == NULL) + return; ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)(subj)->ssid); for(i=0; i< ACM_TE_CACHE_SIZE; i++) @@ -431,26 +436,34 @@ clean_id_from_cache(domid_t id) struct ste_ssid *ste_ssid; int i; struct domain **pd; + struct acm_ssid_domain *ssid; printkd("deleting cache for dom %x.\n", id); - read_lock(&domlist_lock); /* look through caches of all domains */ pd = &domain_list; for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(*pd)->ssid); + ssid = (struct acm_ssid_domain *)((*pd)->ssid); + + if (ssid == NULL) + continue; /* hanging domain structure, no ssid any more ... */ + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssid); + if (!ste_ssid) { + printk("%s: deleting ID from cache ERROR (no ste_ssid)!\n", + __func__); + goto out; + } for (i=0; iste_cache[i].valid == VALID) && - (ste_ssid->ste_cache[i].id = id)) + (ste_ssid->ste_cache[i].id == id)) ste_ssid->ste_cache[i].valid = FREE; } + out: read_unlock(&domlist_lock); } /*************************** * Authorization functions **************************/ - static int ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref) { @@ -484,44 +497,13 @@ ste_post_domain_destroy(void *subject_ssid, domid_t id) /* -------- EVENTCHANNEL OPERATIONS -----------*/ static int -ste_pre_eventchannel_unbound(domid_t id) { - struct domain *subj, *obj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", - __func__, current->domain->domain_id, id); - - if (check_cache(current->domain, id)) { - atomic_inc(&ste_bin_pol.ec_cachehit_count); - return ACM_ACCESS_PERMITTED; - } - atomic_inc(&ste_bin_pol.ec_eval_count); - subj = current->domain; - obj = find_domain_by_id(id); - - if (share_common_type(subj, obj)) { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } else { - atomic_inc(&ste_bin_pol.ec_denied_count); - ret = ACM_ACCESS_DENIED; - } - if (obj != NULL) - put_domain(obj); - return ret; -} - -static int -ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2) -{ +ste_pre_eventchannel_unbound(domid_t id1, domid_t id2) { struct domain *subj, *obj; int ret; traceprintk("%s: dom%x-->dom%x.\n", __func__, (id1 == DOMID_SELF) ? current->domain->domain_id : id1, (id2 == DOMID_SELF) ? current->domain->domain_id : id2); - /* following is a bit longer but ensures that we - * "put" only domains that we where "find"-ing - */ if (id1 == DOMID_SELF) id1 = current->domain->domain_id; if (id2 == DOMID_SELF) id2 = current->domain->domain_id; @@ -531,7 +513,7 @@ ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2) ret = ACM_ACCESS_DENIED; goto out; } - /* cache check late, but evtchn is not on performance critical path */ + /* cache check late */ if (check_cache(subj, obj->domain_id)) { atomic_inc(&ste_bin_pol.ec_cachehit_count); ret = ACM_ACCESS_PERMITTED; @@ -546,7 +528,7 @@ ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2) atomic_inc(&ste_bin_pol.ec_denied_count); ret = ACM_ACCESS_DENIED; } - out: + out: if (obj != NULL) put_domain(obj); if (subj != NULL) @@ -554,6 +536,50 @@ ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2) return ret; } +static int +ste_pre_eventchannel_interdomain(domid_t id) +{ + struct domain *subj=NULL, *obj=NULL; + int ret; + + traceprintk("%s: dom%x-->dom%x.\n", __func__, + current->domain->domain_id, + (id == DOMID_SELF) ? current->domain->domain_id : id); + + /* following is a bit longer but ensures that we + * "put" only domains that we where "find"-ing + */ + if (id == DOMID_SELF) id = current->domain->domain_id; + + subj = current->domain; + obj = find_domain_by_id(id); + if (obj == NULL) { + ret = ACM_ACCESS_DENIED; + goto out; + } + + /* cache check late, but evtchn is not on performance critical path */ + if (check_cache(subj, obj->domain_id)) { + atomic_inc(&ste_bin_pol.ec_cachehit_count); + ret = ACM_ACCESS_PERMITTED; + goto out; + } + + atomic_inc(&ste_bin_pol.ec_eval_count); + + if (share_common_type(subj, obj)) { + cache_result(subj, obj); + ret = ACM_ACCESS_PERMITTED; + } else { + atomic_inc(&ste_bin_pol.ec_denied_count); + ret = ACM_ACCESS_DENIED; + } + out: + if (obj != NULL) + put_domain(obj); + return ret; +} + /* -------- SHARED MEMORY OPERATIONS -----------*/ static int diff --git a/xen/common/acm_ops.c b/xen/common/acm_ops.c index 4f0d46c3e5..d290b40de6 100644 --- a/xen/common/acm_ops.c +++ b/xen/common/acm_ops.c @@ -133,7 +133,10 @@ long do_acm_op(struct acm_op * u_acm_op) struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid); if (!subj) return -ESRCH; /* domain not found */ - + if (subj->ssid == NULL) { + put_domain(subj); + return -ESRCH; + } ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; put_domain(subj); } else @@ -167,6 +170,10 @@ long do_acm_op(struct acm_op * u_acm_op) ret = -ESRCH; /* domain not found */ goto out; } + if (subj->ssid == NULL) { + put_domain(subj); + ret = -ESRCH; + } ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; put_domain(subj); } else { @@ -182,6 +189,10 @@ long do_acm_op(struct acm_op * u_acm_op) ret = -ESRCH; /* domain not found */ goto out; } + if (subj->ssid == NULL) { + put_domain(subj); + return -ESRCH; + } ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; put_domain(subj); } else { diff --git a/xen/include/acm/acm_hooks.h b/xen/include/acm/acm_hooks.h index a79acf2952..011669373d 100644 --- a/xen/include/acm/acm_hooks.h +++ b/xen/include/acm/acm_hooks.h @@ -100,10 +100,10 @@ struct acm_operations { void (*fail_domain_create) (void *subject_ssid, ssidref_t ssidref); void (*post_domain_destroy) (void *object_ssid, domid_t id); /* event channel control hooks (can be NULL) */ - int (*pre_eventchannel_unbound) (domid_t id); - void (*fail_eventchannel_unbound) (domid_t id); - int (*pre_eventchannel_interdomain) (domid_t id1, domid_t id2); - int (*fail_eventchannel_interdomain) (domid_t id1, domid_t id2); + int (*pre_eventchannel_unbound) (domid_t id1, domid_t id2); + void (*fail_eventchannel_unbound) (domid_t id1, domid_t id2); + int (*pre_eventchannel_interdomain) (domid_t id); + void (*fail_eventchannel_interdomain) (domid_t id); /* grant table control hooks (can be NULL) */ int (*pre_grant_map_ref) (domid_t id); void (*fail_grant_map_ref) (domid_t id); @@ -193,31 +193,31 @@ static inline void acm_post_domain_destroy(void *object_ssid, domid_t id) return; } -static inline int acm_pre_eventchannel_unbound(domid_t id) +static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2) { if ((acm_primary_ops->pre_eventchannel_unbound != NULL) && - acm_primary_ops->pre_eventchannel_unbound(id)) + acm_primary_ops->pre_eventchannel_unbound(id1, id2)) return ACM_ACCESS_DENIED; else if ((acm_secondary_ops->pre_eventchannel_unbound != NULL) && - acm_secondary_ops->pre_eventchannel_unbound(id)) { + acm_secondary_ops->pre_eventchannel_unbound(id1, id2)) { /* roll-back primary */ if (acm_primary_ops->fail_eventchannel_unbound != NULL) - acm_primary_ops->fail_eventchannel_unbound(id); + acm_primary_ops->fail_eventchannel_unbound(id1, id2); return ACM_ACCESS_DENIED; } else return ACM_ACCESS_PERMITTED; } -static inline int acm_pre_eventchannel_interdomain(domid_t id1, domid_t id2) +static inline int acm_pre_eventchannel_interdomain(domid_t id) { if ((acm_primary_ops->pre_eventchannel_interdomain != NULL) && - acm_primary_ops->pre_eventchannel_interdomain(id1, id2)) + acm_primary_ops->pre_eventchannel_interdomain(id)) return ACM_ACCESS_DENIED; else if ((acm_secondary_ops->pre_eventchannel_interdomain != NULL) && - acm_secondary_ops->pre_eventchannel_interdomain(id1, id2)) { + acm_secondary_ops->pre_eventchannel_interdomain(id)) { /* roll-back primary */ if (acm_primary_ops->fail_eventchannel_interdomain != NULL) - acm_primary_ops->fail_eventchannel_interdomain(id1, id2); + acm_primary_ops->fail_eventchannel_interdomain(id); return ACM_ACCESS_DENIED; } else return ACM_ACCESS_PERMITTED; @@ -234,10 +234,22 @@ static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid) current->domain->ssid, op->u.createdomain.ssidref); break; case DOM0_DESTROYDOMAIN: + if (*ssid != NULL) { + printkd("%s: Warning. Overlapping destruction.\n", + __func__); + return -EACCES; + } d = find_domain_by_id(op->u.destroydomain.domain); if (d != NULL) { *ssid = d->ssid; /* save for post destroy when d is gone */ - /* no policy-specific hook */ + if (*ssid == NULL) { + printk("%s: Warning. Destroying domain without ssid pointer.\n", + __func__); + put_domain(d); + return -EACCES; + } + d->ssid = NULL; /* make sure it's not used any more */ + /* no policy-specific hook */ put_domain(d); ret = 0; } @@ -248,7 +260,7 @@ static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid) return ret; } -static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid) +static inline void acm_post_dom0_op(dom0_op_t *op, void **ssid) { switch(op->cmd) { case DOM0_CREATEDOMAIN: @@ -261,7 +273,8 @@ static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid) case DOM0_DESTROYDOMAIN: acm_post_domain_destroy(ssid, op->u.destroydomain.domain); /* free security ssid for the destroyed domain (also if null policy */ - acm_free_domain_ssid((struct acm_ssid_domain *)ssid); + acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid)); + *ssid = NULL; break; } } @@ -282,12 +295,13 @@ static inline int acm_pre_event_channel(evtchn_op_t *op) switch(op->cmd) { case EVTCHNOP_alloc_unbound: - ret = acm_pre_eventchannel_unbound(op->u.alloc_unbound.dom); + ret = acm_pre_eventchannel_unbound( + op->u.alloc_unbound.dom, + op->u.alloc_unbound.remote_dom); break; case EVTCHNOP_bind_interdomain: ret = acm_pre_eventchannel_interdomain( - current->domain->domain_id, - op->u.bind_interdomain.remote_dom); + op->u.bind_interdomain.remote_dom); break; default: ret = 0; /* ok */ From a7da7a4ecb25ebcf3fe7fdd9fbda4bd6bd8e04d1 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 27 Oct 2005 17:27:04 +0100 Subject: [PATCH 24/36] The attached patch fixes 2 issues with the scripts written for the Xen access control module and makes the tools more self-explanatory. Signed-off-by: Stefan Berger --- tools/security/getlabel.sh | 27 +++++++++++--------- tools/security/setlabel.sh | 40 ++++++++++++++++------------- tools/security/updategrub.sh | 49 ++++++++++++++++++++++++++++-------- 3 files changed, 76 insertions(+), 40 deletions(-) diff --git a/tools/security/getlabel.sh b/tools/security/getlabel.sh index ee1fcba199..40c5c195d5 100644 --- a/tools/security/getlabel.sh +++ b/tools/security/getlabel.sh @@ -36,18 +36,21 @@ source labelfuncs.sh usage () { - echo "Usage: $0 -sid [] or" - echo " $0 -dom [] " - echo "" - echo "policy name : the name of the policy, i.e. 'chwall'" - echo " If the policy name is omitted, the grub.conf" - echo " entry of the running system is tried to be read" - echo " and the policy name determined from there." - echo "ssidref : an ssidref in hex or decimal format, i.e., '0x00010002'" - echo " or '65538'" - echo "domid : id of the domain, i.e., '1'; Use numbers from the 2nd" - echo " column shown when invoking 'xm list'" - echo "" +echo "Use this tool to display the label of a domain or the label that is +corresponding to an ssidref given the name of the running policy. + +Usage: $0 -sid [] or + $0 -dom [] + +policy name : the name of the policy, i.e. 'chwall' + If the policy name is omitted, the grub.conf + entry of the running system is tried to be read + and the policy name determined from there. +ssidref : an ssidref in hex or decimal format, i.e., '0x00010002' + or '65538' +domid : id of the domain, i.e., '1'; Use numbers from the 2nd + column shown when invoking 'xm list' +" } diff --git a/tools/security/setlabel.sh b/tools/security/setlabel.sh index 9e0ec34482..fcc08fc4aa 100644 --- a/tools/security/setlabel.sh +++ b/tools/security/setlabel.sh @@ -39,21 +39,27 @@ source labelfuncs.sh usage () { - echo "Usage: $0 [Option]