[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [IA64] SMP-guest
# HG changeset patch # User awilliam@xxxxxxxxxxx # Node ID de0c04ed4ab7b9c4572c42df2de838e2b243a8e2 # Parent bbf325d767687745c6838ac43fe48692b6792e54 [IA64] SMP-guest Final SMP-guest patch: add IPI and boot rendez-vous support. Signed-off-by: Tristan Gingold <tristan.gingold@xxxxxxxx> diff -r bbf325d76768 -r de0c04ed4ab7 linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c --- a/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c Fri Apr 21 09:20:13 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c Fri Apr 21 10:40:17 2006 -0600 @@ -265,6 +265,14 @@ ia64_send_ipi (int cpu, int vector, int unsigned long ipi_data; unsigned long phys_cpu_id; +#ifdef CONFIG_XEN + if (running_on_xen) { + extern void xen_send_ipi (int cpu, int vec); + xen_send_ipi (cpu, vector); + return; + } +#endif /* CONFIG_XEN */ + #ifdef CONFIG_SMP phys_cpu_id = cpu_physical_id(cpu); #else diff -r bbf325d76768 -r de0c04ed4ab7 linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S Fri Apr 21 09:20:13 2006 -0600 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S Fri Apr 21 10:40:17 2006 -0600 @@ -341,3 +341,13 @@ GLOBAL_ENTRY(xen_set_eflag) br.ret.sptk.many rp END(xen_set_eflag) #endif + +GLOBAL_ENTRY(xen_send_ipi) + mov r14=r32 + mov r15=r33 + mov r2=0x380 + break 0x1000 + ;; + br.ret.sptk.many rp + ;; +END(xen_send_ipi) diff -r bbf325d76768 -r de0c04ed4ab7 xen/arch/ia64/xen/dom_fw.c --- a/xen/arch/ia64/xen/dom_fw.c Fri Apr 21 09:20:13 2006 -0600 +++ b/xen/arch/ia64/xen/dom_fw.c Fri Apr 21 10:40:17 2006 -0600 @@ -94,9 +94,24 @@ unsigned long dom_fw_setup(struct domain /* the following heavily leveraged from linux/arch/ia64/hp/sim/fw-emu.c */ -#define NUM_EFI_SYS_TABLES 6 -# define NUM_MEM_DESCS 5 - +/* Set IP and GR1 of not yet initialized vcpu. */ +static void +set_os_boot_rendez (struct domain *d, unsigned long pc, unsigned long gr1) +{ + struct vcpu *v; + int i; + + printf ("set_os_boot_rendez: %lx %lx\n", pc, gr1); + for (i = 1; i < MAX_VIRT_CPUS; i++) { + v = d->vcpu[i]; + if (v != NULL + && !test_bit(_VCPUF_initialised, &v->vcpu_flags)) { + struct pt_regs *regs = vcpu_regs (v); + regs->cr_iip = pc; + regs->r1 = gr1; + } + } +} struct sal_ret_values sal_emulator (long index, unsigned long in1, unsigned long in2, @@ -155,7 +170,18 @@ sal_emulator (long index, unsigned long printf("NON-PRIV DOMAIN CALLED SAL_PCI_CONFIG_WRITE\n"); break; case SAL_SET_VECTORS: - printf("*** CALLED SAL_SET_VECTORS. IGNORED...\n"); + if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) { + if (in4 != 0 || in5 != 0 || in6 != 0 || in7 != 0) { + /* Sanity check: cs_length1 must be 0, + second vector is reserved. */ + status = -2; + } + else + set_os_boot_rendez (current->domain, in2, in3); + } + else + printf("*** CALLED SAL_SET_VECTORS %lu. IGNORED...\n", + in1); break; case SAL_GET_STATE_INFO: /* No more info. */ @@ -618,6 +644,9 @@ dom_fw_fake_acpi(struct domain *d, struc return; } +#define NUM_EFI_SYS_TABLES 6 +#define NUM_MEM_DESCS 5 + static struct ia64_boot_param * dom_fw_init (struct domain *d, const char *args, int arglen, char *fw_mem, int fw_mem_size) { @@ -625,8 +654,9 @@ dom_fw_init (struct domain *d, const cha efi_runtime_services_t *efi_runtime; efi_config_table_t *efi_tables; struct ia64_sal_systab *sal_systab; + struct ia64_sal_desc_entry_point *sal_ed; + struct ia64_sal_desc_ap_wakeup *sal_wakeup; efi_memory_desc_t *efi_memmap, *md; - struct ia64_sal_desc_entry_point *sal_ed; struct ia64_boot_param *bp; unsigned long *pfn; unsigned char checksum = 0; @@ -662,6 +692,7 @@ dom_fw_init (struct domain *d, const cha efi_tables = (void *) cp; cp += NUM_EFI_SYS_TABLES * sizeof(*efi_tables); sal_systab = (void *) cp; cp += sizeof(*sal_systab); sal_ed = (void *) cp; cp += sizeof(*sal_ed); + sal_wakeup = (void *) cp; cp += sizeof(*sal_wakeup); efi_memmap = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap); bp = (void *) cp; cp += sizeof(*bp); pfn = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn); @@ -779,7 +810,7 @@ dom_fw_init (struct domain *d, const cha sal_systab->size = sizeof(*sal_systab); sal_systab->sal_rev_minor = 1; sal_systab->sal_rev_major = 0; - sal_systab->entry_count = 1; + sal_systab->entry_count = 2; strcpy((char *)sal_systab->oem_id, "Xen/ia64"); strcpy((char *)sal_systab->product_id, "Xen/ia64"); @@ -791,6 +822,11 @@ dom_fw_init (struct domain *d, const cha sal_ed->sal_proc = FW_HYPERCALL_SAL_CALL_PADDR + start_mpaddr; dom_fw_hypercall_patch (d, sal_ed->sal_proc, FW_HYPERCALL_SAL_CALL, 1); sal_ed->gp = 0; // will be ignored + + /* Fill an AP wakeup descriptor. */ + sal_wakeup->type = SAL_DESC_AP_WAKEUP; + sal_wakeup->mechanism = IA64_SAL_AP_EXTERNAL_INT; + sal_wakeup->vector = XEN_SAL_BOOT_RENDEZ_VEC; for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp) checksum += *cp; diff -r bbf325d76768 -r de0c04ed4ab7 xen/arch/ia64/xen/hypercall.c --- a/xen/arch/ia64/xen/hypercall.c Fri Apr 21 09:20:13 2006 -0600 +++ b/xen/arch/ia64/xen/hypercall.c Fri Apr 21 10:40:17 2006 -0600 @@ -132,6 +132,65 @@ xen_hypercall (struct pt_regs *regs) } +static void +fw_hypercall_ipi (struct pt_regs *regs) +{ + int cpu = regs->r14; + int vector = regs->r15; + struct vcpu *targ; + + if (0 && vector == 254) + printf ("send_ipi from %d to %d vector=%d\n", + current->vcpu_id, cpu, vector); + + if (cpu > MAX_VIRT_CPUS) + return; + + targ = current->domain->vcpu[cpu]; + if (targ == NULL) + return; + + if (vector == XEN_SAL_BOOT_RENDEZ_VEC + && !test_bit(_VCPUF_initialised, &targ->vcpu_flags)) { + struct pt_regs *targ_regs = vcpu_regs (targ); + struct vcpu_guest_context c; + + printf ("arch_boot_vcpu: %p %p\n", + (void *)targ_regs->cr_iip, + (void *)targ_regs->r1); + memset (&c, 0, sizeof (c)); + /* Copy regs. */ + c.regs.cr_iip = targ_regs->cr_iip; + c.regs.r1 = targ_regs->r1; + + /* Copy from vcpu 0. */ + c.vcpu.evtchn_vector = + current->domain->vcpu[0]->vcpu_info->arch.evtchn_vector; + if (arch_set_info_guest (targ, &c) != 0) { + printf ("arch_boot_vcpu: failure\n"); + return; + } + if (test_and_clear_bit(_VCPUF_down, + &targ->vcpu_flags)) { + vcpu_wake(targ); + printf ("arch_boot_vcpu: vcpu %d awaken %016lx!\n", + targ->vcpu_id, targ_regs->cr_iip); + } + else + printf ("arch_boot_vcpu: huu, already awaken!"); + } + else { + int running = test_bit(_VCPUF_running, + &targ->vcpu_flags); + + vcpu_pend_interrupt(targ, vector); + vcpu_unblock(targ); + if (running) + smp_send_event_check_cpu(targ->processor); + } + return; +} + static int fw_hypercall (struct pt_regs *regs) { @@ -232,6 +291,9 @@ fw_hypercall (struct pt_regs *regs) // FIXME: need fixes in efi.h from 2.6.9 regs->r8 = EFI_UNSUPPORTED; break; + case FW_HYPERCALL_IPI: + fw_hypercall_ipi (regs); + break; default: printf("unknown ia64 fw hypercall %lx\n", regs->r2); regs->r8 = do_ni_hypercall(); diff -r bbf325d76768 -r de0c04ed4ab7 xen/include/asm-ia64/dom_fw.h --- a/xen/include/asm-ia64/dom_fw.h Fri Apr 21 09:20:13 2006 -0600 +++ b/xen/include/asm-ia64/dom_fw.h Fri Apr 21 10:40:17 2006 -0600 @@ -125,8 +125,13 @@ extern unsigned long dom_fw_setup(struct */ #define FW_HYPERCALL_FIRST_ARCH 0x300UL +#define FW_HYPERCALL_IPI 0x380UL + /* Xen/ia64 user hypercalls. Only used for debugging. */ #define FW_HYPERCALL_FIRST_USER 0xff00UL + +/* Interrupt vector used for os boot rendez vous. */ +#define XEN_SAL_BOOT_RENDEZ_VEC 0xF3 extern struct ia64_pal_retval xen_pal_emulator(UINT64, u64, u64, u64); extern struct sal_ret_values sal_emulator (long index, unsigned long in1, unsigned long in2, unsigned long in3, unsigned long in4, unsigned long in5, unsigned long in6, unsigned long in7); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |