Date: Tue, 21 Oct 2008 06:39:40 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r184112 - head/sys/i386/xen Message-ID: <200810210639.m9L6deef091360@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Tue Oct 21 06:39:40 2008 New Revision: 184112 URL: http://svn.freebsd.org/changeset/base/184112 Log: Implement infrastructure for gluing i386 ipi functions in to xen's infrastructure Modified: head/sys/i386/xen/exception.s head/sys/i386/xen/mp_machdep.c Modified: head/sys/i386/xen/exception.s ============================================================================== --- head/sys/i386/xen/exception.s Tue Oct 21 06:38:40 2008 (r184111) +++ head/sys/i386/xen/exception.s Tue Oct 21 06:39:40 2008 (r184112) @@ -184,14 +184,12 @@ call_evtchn_upcall: hypervisor_callback_pending: DISABLE_INTERRUPTS(%esi) /* cli */ jmp 10b - /* * alltraps entry point. Interrupts are enabled if this was a trap * gate (TGT), else disabled if this was an interrupt gate (IGT). * Note that int0x80_syscall is a trap gate. Only page faults * use an interrupt gate. */ - SUPERALIGN_TEXT .globl alltraps .type alltraps,@function Modified: head/sys/i386/xen/mp_machdep.c ============================================================================== --- head/sys/i386/xen/mp_machdep.c Tue Oct 21 06:38:40 2008 (r184111) +++ head/sys/i386/xen/mp_machdep.c Tue Oct 21 06:39:40 2008 (r184112) @@ -86,14 +86,10 @@ __FBSDID("$FreeBSD$"); #include <machine/xen/xen-os.h> #include <machine/xen/evtchn.h> +#include <machine/xen/xen_intr.h> #include <machine/xen/hypervisor.h> #include <xen/interface/vcpu.h> - -#define WARMBOOT_TARGET 0 -#define WARMBOOT_OFF (KERNBASE + 0x0467) -#define WARMBOOT_SEG (KERNBASE + 0x0469) - #define stop_cpus_with_nmi 0 @@ -105,6 +101,10 @@ extern struct pcpu __pcpu[]; static int bootAP; static union descriptor *bootAPgdt; +static DEFINE_PER_CPU(int, resched_irq); +static DEFINE_PER_CPU(int, callfunc_irq); +static char resched_name[NR_CPUS][15]; +static char callfunc_name[NR_CPUS][15]; /* Free these after use */ void *bootstacks[MAXCPU]; @@ -119,6 +119,8 @@ vm_offset_t smp_tlb_addr1; vm_offset_t smp_tlb_addr2; volatile int smp_tlb_wait; +typedef void call_data_func_t(uintptr_t , uintptr_t); + static u_int logical_cpus; /* used to hold the AP's until we are ready to release them */ @@ -141,8 +143,6 @@ int cpu_apic_ids[MAXCPU]; /* Holds pending bitmap based IPIs per CPU */ static volatile u_int cpu_ipi_pending[MAXCPU]; -static u_int boot_address; - static void assign_cpu_ids(void); static void set_interrupt_apic_ids(void); int start_all_aps(void); @@ -300,6 +300,105 @@ cpu_mp_start(void) } +static void +iv_rendezvous(uintptr_t a, uintptr_t b) +{ + +} + +static void +iv_invltlb(uintptr_t a, uintptr_t b) +{ + +} + +static void +iv_invlpg(uintptr_t a, uintptr_t b) +{ + +} + +static void +iv_invlrng(uintptr_t a, uintptr_t b) +{ + +} + +static void +iv_invlcache(uintptr_t a, uintptr_t b) +{ + +} + +static void +iv_lazypmap(uintptr_t a, uintptr_t b) +{ + +} + +static void +iv_bitmap_vector(uintptr_t a, uintptr_t b) +{ + +} + + +static call_data_func_t *ipi_vectors[IPI_BITMAP_VECTOR + 1] = +{ iv_rendezvous, + iv_invltlb, + iv_invlpg, + iv_invlrng, + iv_invlcache, + iv_lazypmap, + iv_bitmap_vector +}; + +/* + * Reschedule call back. Nothing to do, + * all the work is done automatically when + * we return from the interrupt. + */ +static void +smp_reschedule_interrupt(void *unused) +{ +} + +struct _call_data { + call_data_func_t *func; + uintptr_t arg1; + uintptr_t arg2; + atomic_t started; + atomic_t finished; + int wait; +}; + +static struct _call_data *call_data; + +static void +smp_call_function_interrupt(void *unused) +{ + call_data_func_t *func = call_data->func; + uintptr_t arg1 = call_data->arg1; + uintptr_t arg2 = call_data->arg2; + int wait = call_data->wait; + + /* + * Notify initiating CPU that I've grabbed the data and am + * about to execute the function + */ + mb(); + atomic_inc(&call_data->started); + /* + * At this point the info structure may be out of scope unless wait==1 + */ + (*func)(arg1, arg2); + + if (wait) { + mb(); + atomic_inc(&call_data->finished); + } +} + /* * Print various information about the SMP system hardware and setup. */ @@ -323,6 +422,46 @@ cpu_mp_announce(void) } } + +static int +xen_smp_intr_init(unsigned int cpu) +{ + int rc; + + per_cpu(resched_irq, cpu) = per_cpu(callfunc_irq, cpu) = -1; + + sprintf(resched_name[cpu], "resched%u", cpu); + rc = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR, + cpu, + resched_name[cpu], + smp_reschedule_interrupt, + INTR_FAST); + + per_cpu(resched_irq, cpu) = rc; + + sprintf(callfunc_name[cpu], "callfunc%u", cpu); + rc = bind_ipi_to_irqhandler(CALL_FUNCTION_VECTOR, + cpu, + callfunc_name[cpu], + smp_call_function_interrupt, + INTR_FAST); + if (rc < 0) + goto fail; + per_cpu(callfunc_irq, cpu) = rc; + + if ((cpu != 0) && ((rc = ap_cpu_initclocks(cpu)) != 0)) + goto fail; + + return 0; + + fail: + if (per_cpu(resched_irq, cpu) >= 0) + unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL); + if (per_cpu(callfunc_irq, cpu) >= 0) + unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL); + return rc; +} + #define MTOPSIZE (1<<(14 + PAGE_SHIFT)) /* @@ -336,8 +475,6 @@ init_secondary(void) /* bootAP is set in start_ap() to our ID. */ - - PCPU_SET(currentldt, _default_ldt); gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); #if 0 @@ -434,6 +571,7 @@ init_secondary(void) smp_active = 1; /* historic */ } + xen_smp_intr_init(bootAP); mtx_unlock_spin(&ap_boot_mtx); /* wait until all the AP's are up */ @@ -533,15 +671,11 @@ assign_cpu_ids(void) int start_all_aps(void) { - u_int32_t mpbioswarmvec; int x,apic_id, cpu; struct pcpu *pc; mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN); - /* save the current value of the warm-start vector */ - mpbioswarmvec = *((u_int32_t *) WARMBOOT_OFF); - /* set up temporary P==V mapping for AP boot */ /* XXX this is a hack, we should boot the AP on its own stack/PTD */ @@ -550,10 +684,6 @@ start_all_aps(void) apic_id = cpu_apic_ids[cpu]; - /* setup a vector to our boot code */ - *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; - *((volatile u_short *) WARMBOOT_SEG) = (boot_address >> 4); - bootAP = cpu; bootAPgdt = gdt + (512*cpu); @@ -600,9 +730,6 @@ start_all_aps(void) /* build our map of 'other' CPUs */ PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask)); - /* restore the warmstart vector */ - *(u_int32_t *) WARMBOOT_OFF = mpbioswarmvec; - pmap_invalidate_range(kernel_pmap, 0, NKPT * NBPDR - 1); /* number of APs actually started */ @@ -624,11 +751,8 @@ smp_trap_init(trap_info_t *trap_ctxt) } } -void -cpu_initialize_context(unsigned int cpu); extern int nkpt; - -void +static void cpu_initialize_context(unsigned int cpu) { /* vcpu_guest_context_t is too large to allocate on the stack. @@ -645,7 +769,6 @@ cpu_initialize_context(unsigned int cpu) * Page 0,[0-3] PTD * Page 1, [4] boot stack * Page [5] PDPT - * */ for (i = 0; i < NPGPTD + 2; i++) { @@ -796,8 +919,9 @@ smp_tlb_shootdown(u_int vector, vm_offse if (!(read_eflags() & PSL_I)) panic("%s: interrupts disabled", __func__); mtx_lock_spin(&smp_ipi_mtx); - smp_tlb_addr1 = addr1; - smp_tlb_addr2 = addr2; + call_data->func = ipi_vectors[vector]; + call_data->arg1 = addr1; + call_data->arg2 = addr2; atomic_store_rel_int(&smp_tlb_wait, 0); ipi_all_but_self(vector); while (smp_tlb_wait < ncpu)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810210639.m9L6deef091360>