diff options
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/i386/apic_vector.s | 19 | ||||
-rw-r--r-- | sys/i386/i386/machdep.c | 17 | ||||
-rw-r--r-- | sys/i386/i386/mp_machdep.c | 9 | ||||
-rw-r--r-- | sys/i386/include/apicvar.h | 1 | ||||
-rw-r--r-- | sys/i386/include/intr_machdep.h | 24 | ||||
-rw-r--r-- | sys/i386/include/pcpu.h | 16 | ||||
-rw-r--r-- | sys/i386/include/pmap.h | 4 | ||||
-rw-r--r-- | sys/i386/include/xen/xen-os.h | 168 | ||||
-rw-r--r-- | sys/i386/include/xen/xenfunc.h | 6 | ||||
-rw-r--r-- | sys/i386/include/xen/xenvar.h | 3 | ||||
-rw-r--r-- | sys/i386/isa/npx.c | 2 | ||||
-rw-r--r-- | sys/i386/xen/clock.c | 58 | ||||
-rw-r--r-- | sys/i386/xen/exception.s | 2 | ||||
-rw-r--r-- | sys/i386/xen/mp_machdep.c | 89 | ||||
-rw-r--r-- | sys/i386/xen/mptable.c | 2 | ||||
-rw-r--r-- | sys/i386/xen/xen_clock_util.c | 3 | ||||
-rw-r--r-- | sys/i386/xen/xen_machdep.c | 48 | ||||
-rw-r--r-- | sys/i386/xen/xen_rtc.c | 10 |
18 files changed, 252 insertions, 229 deletions
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index 618436d..adedbc4 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -138,6 +138,25 @@ IDTVEC(errorint) MEXITCOUNT jmp doreti +#ifdef XENHVM +/* + * Xen event channel upcall interrupt handler. + * Only used when the hypervisor supports direct vector callbacks. + */ + .text + SUPERALIGN_TEXT +IDTVEC(xen_intr_upcall) + PUSH_FRAME + SET_KERNEL_SREGS + cld + FAKE_MCOUNT(TF_EIP(%esp)) + pushl %esp + call xen_intr_handle_upcall + add $4, %esp + MEXITCOUNT + jmp doreti +#endif + #ifdef SMP /* * Global address space TLB shootdown. diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 9a710e5..c430316 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -160,9 +160,8 @@ uint32_t arch_i386_xbox_memsize = 0; #ifdef XEN /* XEN includes */ -#include <machine/xen/xen-os.h> +#include <xen/xen-os.h> #include <xen/hypervisor.h> -#include <machine/xen/xen-os.h> #include <machine/xen/xenvar.h> #include <machine/xen/xenfunc.h> #include <xen/xen_intr.h> @@ -1216,6 +1215,13 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate) #ifdef XEN +static void +idle_block(void) +{ + + HYPERVISOR_sched_op(SCHEDOP_block, 0); +} + void cpu_halt(void) { @@ -1960,6 +1966,9 @@ extern inthand_t #ifdef KDTRACE_HOOKS IDTVEC(dtrace_ret), #endif +#ifdef XENHVM + IDTVEC(xen_intr_upcall), +#endif IDTVEC(lcall_syscall), IDTVEC(int0x80_syscall); #ifdef DDB @@ -2948,6 +2957,10 @@ init386(first) setidt(IDT_DTRACE_RET, &IDTVEC(dtrace_ret), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); #endif +#ifdef XENHVM + setidt(IDT_EVTCHN, &IDTVEC(xen_intr_upcall), SDT_SYS386IGT, SEL_UPL, + GSEL(GCODE_SEL, SEL_KPL)); +#endif r_idt.rd_limit = sizeof(idt0) - 1; r_idt.rd_base = (int) idt; diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 19e67cf..479168b 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -82,6 +82,10 @@ __FBSDID("$FreeBSD$"); #include <machine/smp.h> #include <machine/specialreg.h> +#ifdef XENHVM +#include <xen/hvm.h> +#endif + #define WARMBOOT_TARGET 0 #define WARMBOOT_OFF (KERNBASE + 0x0467) #define WARMBOOT_SEG (KERNBASE + 0x0469) @@ -747,6 +751,11 @@ init_secondary(void) /* set up SSE registers */ enable_sse(); +#ifdef XENHVM + /* register vcpu_info area */ + xen_hvm_init_cpu(); +#endif + #ifdef PAE /* Enable the PTE no-execute bit. */ if ((amd_feature & AMDID_NX) != 0) { diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h index a0e622e..5d1f522 100644 --- a/sys/i386/include/apicvar.h +++ b/sys/i386/include/apicvar.h @@ -226,6 +226,7 @@ int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger); void lapic_set_tpr(u_int vector); void lapic_setup(int boot); +void xen_intr_handle_upcall(struct trapframe *frame); #endif /* !LOCORE */ #endif /* _MACHINE_APICVAR_H_ */ diff --git a/sys/i386/include/intr_machdep.h b/sys/i386/include/intr_machdep.h index b3dd122..6bbe378 100644 --- a/sys/i386/include/intr_machdep.h +++ b/sys/i386/include/intr_machdep.h @@ -44,12 +44,30 @@ * allocate IDT vectors. * * The first 255 IRQs (0 - 254) are reserved for ISA IRQs and PCI intline IRQs. - * IRQ values beyond 256 are used by MSI. We leave 255 unused to avoid - * confusion since 255 is used in PCI to indicate an invalid IRQ. + * IRQ values from 256 to 767 are used by MSI. When running under the Xen + * Hypervisor, IRQ values from 768 to 4863 are available for binding to + * event channel events. We leave 255 unused to avoid confusion since 255 is + * used in PCI to indicate an invalid IRQ. */ #define NUM_MSI_INTS 512 #define FIRST_MSI_INT 256 -#define NUM_IO_INTS (FIRST_MSI_INT + NUM_MSI_INTS) +#ifdef XENHVM +#include <xen/xen-os.h> +#define NUM_EVTCHN_INTS NR_EVENT_CHANNELS +#define FIRST_EVTCHN_INT \ + (FIRST_MSI_INT + NUM_MSI_INTS) +#define LAST_EVTCHN_INT \ + (FIRST_EVTCHN_INT + NUM_EVTCHN_INTS - 1) +#elif defined(XEN) +#include <xen/xen-os.h> +#define NUM_EVTCHN_INTS NR_EVENT_CHANNELS +#define FIRST_EVTCHN_INT 0 +#define LAST_EVTCHN_INT \ + (FIRST_EVTCHN_INT + NUM_EVTCHN_INTS - 1) +#else /* !XEN && !XENHVM */ +#define NUM_EVTCHN_INTS 0 +#endif +#define NUM_IO_INTS (FIRST_MSI_INT + NUM_MSI_INTS + NUM_EVTCHN_INTS) /* * Default base address for MSI messages on x86 platforms. diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h index 3606d12..3a684bf 100644 --- a/sys/i386/include/pcpu.h +++ b/sys/i386/include/pcpu.h @@ -71,21 +71,9 @@ struct shadow_time_info { vm_paddr_t *pc_pdir_shadow; \ uint64_t pc_processed_system_time; \ struct shadow_time_info pc_shadow_time; \ - int pc_resched_irq; \ - int pc_callfunc_irq; \ - int pc_virq_to_irq[NR_VIRQS]; \ - int pc_ipi_to_irq[NR_IPIS]; \ - char __pad[77] + char __pad[189] -#elif defined(XENHVM) - -#define PCPU_XEN_FIELDS \ - ; \ - unsigned int pc_last_processed_l1i; \ - unsigned int pc_last_processed_l2i; \ - char __pad[229] - -#else /* !XEN && !XENHVM */ +#else /* !XEN */ #define PCPU_XEN_FIELDS \ ; \ diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h index 94b63ca..0303c60 100644 --- a/sys/i386/include/pmap.h +++ b/sys/i386/include/pmap.h @@ -213,7 +213,9 @@ extern pd_entry_t *IdlePTD; /* physical address of "Idle" state directory */ #if defined(XEN) #include <sys/param.h> -#include <machine/xen/xen-os.h> + +#include <xen/xen-os.h> + #include <machine/xen/xenvar.h> #include <machine/xen/xenpmap.h> diff --git a/sys/i386/include/xen/xen-os.h b/sys/i386/include/xen/xen-os.h index 257202e..e15d668 100644 --- a/sys/i386/include/xen/xen-os.h +++ b/sys/i386/include/xen/xen-os.h @@ -1,52 +1,64 @@ -/****************************************************************************** - * os.h +/***************************************************************************** + * i386/xen/xen-os.h * - * random collection of macros and definition + * Random collection of macros and definition + * + * Copyright (c) 2003, 2004 Keir Fraser (on behalf of the Xen team) + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * $FreeBSD$ */ -#ifndef _XEN_OS_H_ -#define _XEN_OS_H_ -#include <machine/param.h> +#ifndef _MACHINE_XEN_XEN_OS_H_ +#define _MACHINE_XEN_XEN_OS_H_ #ifdef PAE #define CONFIG_X86_PAE #endif -#ifdef LOCORE -#define __ASSEMBLY__ -#endif - -#if !defined(__XEN_INTERFACE_VERSION__) -#define __XEN_INTERFACE_VERSION__ 0x00030208 -#endif - -#define GRANT_REF_INVALID 0xffffffff - -#include <xen/interface/xen.h> - /* Everything below this point is not included by assembler (.S) files. */ #ifndef __ASSEMBLY__ /* Force a proper event-channel callback from Xen. */ void force_evtchn_callback(void); -#define likely(x) __builtin_expect((x),1) -#define unlikely(x) __builtin_expect((x),0) +/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ +static inline void rep_nop(void) +{ + __asm__ __volatile__ ( "rep;nop" : : : "memory" ); +} +#define cpu_relax() rep_nop() -#ifndef vtophys -#include <vm/vm.h> -#include <vm/vm_param.h> -#include <vm/pmap.h> -#endif +#ifndef XENHVM +void xc_printf(const char *fmt, ...); -extern int gdtset; #ifdef SMP +extern int gdtset; + #include <sys/time.h> /* XXX for pcpu.h */ #include <sys/pcpu.h> /* XXX for PCPU_GET */ static inline int smp_processor_id(void) { - if (likely(gdtset)) + if (__predict_true(gdtset)) return PCPU_GET(cpuid); return 0; } @@ -55,50 +67,16 @@ smp_processor_id(void) #define smp_processor_id() 0 #endif -#ifndef NULL -#define NULL (void *)0 -#endif - #ifndef PANIC_IF -#define PANIC_IF(exp) if (unlikely(exp)) {printk("panic - %s: %s:%d\n",#exp, __FILE__, __LINE__); panic("%s: %s:%d", #exp, __FILE__, __LINE__);} -#endif - -extern shared_info_t *HYPERVISOR_shared_info; - -/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented - a mechanism by which the user can annotate likely branch directions and - expect the blocks to be reordered appropriately. Define __builtin_expect - to nothing for earlier compilers. */ - -/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ -static inline void rep_nop(void) -{ - __asm__ __volatile__ ( "rep;nop" : : : "memory" ); -} -#define cpu_relax() rep_nop() - - -#if __GNUC__ == 2 && __GNUC_MINOR__ < 96 -#define __builtin_expect(x, expected_value) (x) +#define PANIC_IF(exp) if (__predict_false(exp)) {printf("panic - %s: %s:%d\n",#exp, __FILE__, __LINE__); panic("%s: %s:%d", #exp, __FILE__, __LINE__);} #endif -#define per_cpu(var, cpu) (pcpu_find((cpu))->pc_ ## var) - -/* crude memory allocator for memory allocation early in - * boot +/* + * Crude memory allocator for memory allocation early in boot. */ void *bootmem_alloc(unsigned int size); void bootmem_free(void *ptr, unsigned int size); -#include <sys/types.h> - -void printk(const char *fmt, ...); - -/* some function prototypes */ -void trap_init(void); - -#ifndef XENHVM - /* * STI/CLI equivalents. These basically set and clear the virtual * event_enable flag in the shared_info structure. Note that when @@ -106,7 +84,6 @@ void trap_init(void); * We may therefore call into do_hypervisor_callback() directly. */ - #define __cli() \ do { \ vcpu_info_t *_vcpu; \ @@ -122,7 +99,7 @@ do { \ _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ _vcpu->evtchn_upcall_mask = 0; \ barrier(); /* unmask then check (avoid races) */ \ - if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ + if (__predict_false(_vcpu->evtchn_upcall_pending)) \ force_evtchn_callback(); \ } while (0) @@ -133,7 +110,7 @@ do { \ _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \ barrier(); /* unmask then check (avoid races) */ \ - if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ + if (__predict_false(_vcpu->evtchn_upcall_pending)) \ force_evtchn_callback(); \ } \ } while (0) @@ -168,31 +145,7 @@ do { \ #define spin_lock_irqsave mtx_lock_irqsave #define spin_unlock_irqrestore mtx_unlock_irqrestore -#endif - -#ifndef xen_mb -#define xen_mb() mb() -#endif -#ifndef xen_rmb -#define xen_rmb() rmb() -#endif -#ifndef xen_wmb -#define xen_wmb() wmb() -#endif -#ifdef SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { xchg(&var, value); } while (0) -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while(0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) -#endif - +#endif /* !XENHVM */ /* This is a barrier for the compiler only, NOT the processor! */ #define barrier() __asm__ __volatile__("": : :"memory") @@ -207,8 +160,6 @@ do { \ */ typedef struct { volatile int counter; } atomic_t; - - #define xen_xchg(ptr,v) \ ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr)))) struct __xchg_dummy { unsigned long a[100]; }; @@ -335,33 +286,6 @@ static __inline__ void atomic_inc(atomic_t *v) #define rdtscll(val) \ __asm__ __volatile__("rdtsc" : "=A" (val)) - - -/* - * Kernel pointers have redundant information, so we can use a - * scheme where we can return either an error code or a dentry - * pointer with the same return value. - * - * This should be a per-architecture thing, to allow different - * error and pointer decisions. - */ -#define IS_ERR_VALUE(x) unlikely((x) > (unsigned long)-1000L) - -static inline void *ERR_PTR(long error) -{ - return (void *) error; -} - -static inline long PTR_ERR(const void *ptr) -{ - return (long) ptr; -} - -static inline long IS_ERR(const void *ptr) -{ - return IS_ERR_VALUE((unsigned long)ptr); -} - #endif /* !__ASSEMBLY__ */ -#endif /* _OS_H_ */ +#endif /* _MACHINE_XEN_XEN_OS_H_ */ diff --git a/sys/i386/include/xen/xenfunc.h b/sys/i386/include/xen/xenfunc.h index 47f0405..f02ee12 100644 --- a/sys/i386/include/xen/xenfunc.h +++ b/sys/i386/include/xen/xenfunc.h @@ -29,10 +29,14 @@ #ifndef _XEN_XENFUNC_H_ #define _XEN_XENFUNC_H_ -#include <machine/xen/xen-os.h> +#include <xen/xen-os.h> #include <xen/hypervisor.h> + +#include <vm/pmap.h> + #include <machine/xen/xenpmap.h> #include <machine/segments.h> + #include <sys/pcpu.h> #define BKPT __asm__("int3"); #define XPQ_CALL_DEPTH 5 diff --git a/sys/i386/include/xen/xenvar.h b/sys/i386/include/xen/xenvar.h index b1a0a4d..2742613 100644 --- a/sys/i386/include/xen/xenvar.h +++ b/sys/i386/include/xen/xenvar.h @@ -37,7 +37,8 @@ #define XPMAP 0x2 extern int xendebug_flags; #ifndef NOXENDEBUG -#define XENPRINTF printk +/* Print directly to the Xen console during debugging. */ +#define XENPRINTF xc_printf #else #define XENPRINTF printf #endif diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c index 3b86d84..622e5b7 100644 --- a/sys/i386/isa/npx.c +++ b/sys/i386/isa/npx.c @@ -69,7 +69,7 @@ __FBSDID("$FreeBSD$"); #include <machine/intr_machdep.h> #ifdef XEN -#include <machine/xen/xen-os.h> +#include <xen/xen-os.h> #include <xen/hypervisor.h> #endif diff --git a/sys/i386/xen/clock.c b/sys/i386/xen/clock.c index a10b546..524fa14 100644 --- a/sys/i386/xen/clock.c +++ b/sys/i386/xen/clock.c @@ -84,7 +84,7 @@ __FBSDID("$FreeBSD$"); #include <vm/pmap.h> #include <machine/pmap.h> #include <xen/hypervisor.h> -#include <machine/xen/xen-os.h> +#include <xen/xen-os.h> #include <machine/xen/xenfunc.h> #include <xen/interface/vcpu.h> #include <machine/cpu.h> @@ -133,6 +133,8 @@ static uint64_t processed_system_time; /* stime (ns) at last processing. */ static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; +int ap_cpu_initclocks(int cpu); + SYSCTL_INT(_machdep, OID_AUTO, independent_wallclock, CTLFLAG_RW, &independent_wallclock, 0, ""); SYSCTL_INT(_machdep, OID_AUTO, xen_disable_rtc_set, @@ -257,9 +259,11 @@ static void __get_time_values_from_xen(void) struct vcpu_time_info *src; struct shadow_time_info *dst; uint32_t pre_version, post_version; + struct pcpu *pc; + pc = pcpu_find(smp_processor_id()); src = &s->vcpu_info[smp_processor_id()].time; - dst = &per_cpu(shadow_time, smp_processor_id()); + dst = &pc->pc_shadow_time; spinlock_enter(); do { @@ -283,9 +287,11 @@ static inline int time_values_up_to_date(int cpu) { struct vcpu_time_info *src; struct shadow_time_info *dst; + struct pcpu *pc; src = &HYPERVISOR_shared_info->vcpu_info[cpu].time; - dst = &per_cpu(shadow_time, cpu); + pc = pcpu_find(cpu); + dst = &pc->pc_shadow_time; rmb(); return (dst->version == src->version); @@ -320,7 +326,8 @@ clkintr(void *arg) { int64_t now; int cpu = smp_processor_id(); - struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu); + struct pcpu *pc = pcpu_find(cpu); + struct shadow_time_info *shadow = &pc->pc_shadow_time; struct xen_et_state *state = DPCPU_PTR(et_state); do { @@ -364,8 +371,10 @@ getit(void) struct shadow_time_info *shadow; uint64_t time; uint32_t local_time_version; + struct pcpu *pc; - shadow = &per_cpu(shadow_time, smp_processor_id()); + pc = pcpu_find(smp_processor_id()); + shadow = &pc->pc_shadow_time; do { local_time_version = shadow->version; @@ -492,12 +501,14 @@ void timer_restore(void) { struct xen_et_state *state = DPCPU_PTR(et_state); + struct pcpu *pc; /* Get timebases for new environment. */ __get_time_values_from_xen(); /* Reset our own concept of passage of system time. */ - processed_system_time = per_cpu(shadow_time, 0).system_timestamp; + pc = pcpu_find(0); + processed_system_time = pc->pc_shadow_time.system_timestamp; state->next = processed_system_time; } @@ -508,10 +519,13 @@ startrtclock() uint64_t __cpu_khz; uint32_t cpu_khz; struct vcpu_time_info *info; + struct pcpu *pc; + + pc = pcpu_find(0); /* initialize xen values */ __get_time_values_from_xen(); - processed_system_time = per_cpu(shadow_time, 0).system_timestamp; + processed_system_time = pc->pc_shadow_time.system_timestamp; __cpu_khz = 1000000ULL << 32; info = &HYPERVISOR_shared_info->vcpu_info[0].time; @@ -594,8 +608,10 @@ domu_resettodr(void) int s; dom0_op_t op; struct shadow_time_info *shadow; + struct pcpu *pc; - shadow = &per_cpu(shadow_time, smp_processor_id()); + pc = pcpu_find(smp_processor_id()); + shadow = &pc->pc_shadow_time; if (xen_disable_rtc_set) return; @@ -773,6 +789,7 @@ xen_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period) struct xen_et_state *state = DPCPU_PTR(et_state); struct shadow_time_info *shadow; int64_t fperiod; + struct pcpu *pc; __get_time_values_from_xen(); @@ -788,7 +805,8 @@ xen_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period) else fperiod = state->period; - shadow = &per_cpu(shadow_time, smp_processor_id()); + pc = pcpu_find(smp_processor_id()); + shadow = &pc->pc_shadow_time; state->next = shadow->system_timestamp + get_nsec_offset(shadow); state->next += fperiod; HYPERVISOR_set_timer_op(state->next + 50000); @@ -811,11 +829,11 @@ xen_et_stop(struct eventtimer *et) void cpu_initclocks(void) { - unsigned int time_irq; + xen_intr_handle_t time_irq; int error; HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, 0, NULL); - error = bind_virq_to_irqhandler(VIRQ_TIMER, 0, "cpu0:timer", + error = xen_intr_bind_virq(root_bus, VIRQ_TIMER, 0, clkintr, NULL, NULL, INTR_TYPE_CLK, &time_irq); if (error) panic("failed to register clock interrupt\n"); @@ -840,13 +858,11 @@ cpu_initclocks(void) int ap_cpu_initclocks(int cpu) { - char buf[MAXCOMLEN + 1]; - unsigned int time_irq; + xen_intr_handle_t time_irq; int error; HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL); - snprintf(buf, sizeof(buf), "cpu%d:timer", cpu); - error = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, buf, + error = xen_intr_bind_virq(root_bus, VIRQ_TIMER, cpu, clkintr, NULL, NULL, INTR_TYPE_CLK, &time_irq); if (error) panic("failed to register clock interrupt\n"); @@ -859,7 +875,10 @@ xen_get_timecount(struct timecounter *tc) { uint64_t clk; struct shadow_time_info *shadow; - shadow = &per_cpu(shadow_time, smp_processor_id()); + struct pcpu *pc; + + pc = pcpu_find(smp_processor_id()); + shadow = &pc->pc_shadow_time; __get_time_values_from_xen(); @@ -876,13 +895,6 @@ get_system_time(int ticks) return processed_system_time + (ticks * NS_PER_TICK); } -void -idle_block(void) -{ - - HYPERVISOR_sched_op(SCHEDOP_block, 0); -} - int timer_spkr_acquire(void) { diff --git a/sys/i386/xen/exception.s b/sys/i386/xen/exception.s index e965ffd..95f1c0e 100644 --- a/sys/i386/xen/exception.s +++ b/sys/i386/xen/exception.s @@ -168,7 +168,7 @@ call_evtchn_upcall: jb critical_region_fixup 10: pushl %esp - call evtchn_do_upcall + call xen_intr_handle_upcall addl $4,%esp /* diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c index 05531cb..407731a 100644 --- a/sys/i386/xen/mp_machdep.c +++ b/sys/i386/xen/mp_machdep.c @@ -87,7 +87,7 @@ __FBSDID("$FreeBSD$"); -#include <machine/xen/xen-os.h> +#include <xen/xen-os.h> #include <xen/evtchn.h> #include <xen/xen_intr.h> #include <xen/hypervisor.h> @@ -102,9 +102,6 @@ extern struct pcpu __pcpu[]; static int bootAP; static union descriptor *bootAPgdt; -static char resched_name[NR_CPUS][15]; -static char callfunc_name[NR_CPUS][15]; - /* Free these after use */ void *bootstacks[MAXCPU]; @@ -156,6 +153,10 @@ static cpuset_t hyperthreading_cpus_mask; extern void Xhypervisor_callback(void); extern void failsafe_callback(void); extern void pmap_lazyfix_action(void); +extern int ap_cpu_initclocks(int cpu); + +DPCPU_DEFINE(xen_intr_handle_t, ipi_port[NR_IPIS]); +DPCPU_DEFINE(struct vcpu_info *, vcpu_info); struct cpu_group * cpu_topo(void) @@ -461,49 +462,49 @@ cpu_mp_announce(void) } static int -xen_smp_intr_init(unsigned int cpu) +xen_smp_cpu_init(unsigned int cpu) { int rc; - unsigned int irq; - - per_cpu(resched_irq, cpu) = per_cpu(callfunc_irq, cpu) = -1; + xen_intr_handle_t irq_handle; - sprintf(resched_name[cpu], "resched%u", cpu); - rc = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR, - cpu, - resched_name[cpu], - smp_reschedule_interrupt, - INTR_TYPE_TTY, &irq); + DPCPU_ID_SET(cpu, ipi_port[RESCHEDULE_VECTOR], NULL); + DPCPU_ID_SET(cpu, ipi_port[CALL_FUNCTION_VECTOR], NULL); - printf("[XEN] IPI cpu=%d irq=%d vector=RESCHEDULE_VECTOR (%d)\n", - cpu, irq, RESCHEDULE_VECTOR); - - per_cpu(resched_irq, cpu) = irq; - - sprintf(callfunc_name[cpu], "callfunc%u", cpu); - rc = bind_ipi_to_irqhandler(CALL_FUNCTION_VECTOR, - cpu, - callfunc_name[cpu], - smp_call_function_interrupt, - INTR_TYPE_TTY, &irq); + /* + * The PCPU variable pc_device is not initialized on i386 PV, + * so we have to use the root_bus device in order to setup + * the IPIs. + */ + rc = xen_intr_bind_ipi(root_bus, RESCHEDULE_VECTOR, + cpu, smp_reschedule_interrupt, INTR_TYPE_TTY, &irq_handle); if (rc < 0) goto fail; - per_cpu(callfunc_irq, cpu) = irq; + xen_intr_describe(irq_handle, "resched%u", cpu); + DPCPU_ID_SET(cpu, ipi_port[RESCHEDULE_VECTOR], irq_handle); - printf("[XEN] IPI cpu=%d irq=%d vector=CALL_FUNCTION_VECTOR (%d)\n", - cpu, irq, CALL_FUNCTION_VECTOR); + printf("[XEN] IPI cpu=%d port=%d vector=RESCHEDULE_VECTOR (%d)\n", + cpu, xen_intr_port(irq_handle), RESCHEDULE_VECTOR); + + rc = xen_intr_bind_ipi(root_bus, CALL_FUNCTION_VECTOR, + cpu, smp_call_function_interrupt, INTR_TYPE_TTY, &irq_handle); + if (rc < 0) + goto fail; + xen_intr_describe(irq_handle, "callfunc%u", cpu); + DPCPU_ID_SET(cpu, ipi_port[CALL_FUNCTION_VECTOR], irq_handle); + + printf("[XEN] IPI cpu=%d port=%d vector=CALL_FUNCTION_VECTOR (%d)\n", + cpu, xen_intr_port(irq_handle), CALL_FUNCTION_VECTOR); - 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)); - if (per_cpu(callfunc_irq, cpu) >= 0) - unbind_from_irqhandler(per_cpu(callfunc_irq, cpu)); + xen_intr_unbind(DPCPU_ID_GET(cpu, ipi_port[RESCHEDULE_VECTOR])); + DPCPU_ID_SET(cpu, ipi_port[RESCHEDULE_VECTOR], NULL); + xen_intr_unbind(DPCPU_ID_GET(cpu, ipi_port[CALL_FUNCTION_VECTOR])); + DPCPU_ID_SET(cpu, ipi_port[CALL_FUNCTION_VECTOR], NULL); return rc; } @@ -513,7 +514,17 @@ xen_smp_intr_init_cpus(void *unused) int i; for (i = 0; i < mp_ncpus; i++) - xen_smp_intr_init(i); + xen_smp_cpu_init(i); +} + +static void +xen_smp_intr_setup_cpus(void *unused) +{ + int i; + + for (i = 0; i < mp_ncpus; i++) + DPCPU_ID_SET(i, vcpu_info, + &HYPERVISOR_shared_info->vcpu_info[i]); } #define MTOPSIZE (1<<(14 + PAGE_SHIFT)) @@ -959,6 +970,13 @@ start_ap(int apic_id) return 0; /* return FAILURE */ } +static void +ipi_pcpu(int cpu, u_int ipi) +{ + KASSERT((ipi <= NR_IPIS), ("invalid IPI")); + xen_intr_signal(DPCPU_ID_GET(cpu, ipi_port[ipi])); +} + /* * send an IPI to a specific CPU. */ @@ -1246,5 +1264,6 @@ release_aps(void *dummy __unused) ia32_pause(); } SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL); -SYSINIT(start_ipis, SI_SUB_INTR, SI_ORDER_ANY, xen_smp_intr_init_cpus, NULL); +SYSINIT(start_ipis, SI_SUB_SMP, SI_ORDER_ANY, xen_smp_intr_init_cpus, NULL); +SYSINIT(start_cpu, SI_SUB_INTR, SI_ORDER_ANY, xen_smp_intr_setup_cpus, NULL); diff --git a/sys/i386/xen/mptable.c b/sys/i386/xen/mptable.c index 0c1efe8..74cb9ab 100644 --- a/sys/i386/xen/mptable.c +++ b/sys/i386/xen/mptable.c @@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$"); #include <machine/apicvar.h> #include <xen/hypervisor.h> -#include <machine/xen/xen-os.h> +#include <xen/xen-os.h> #include <machine/smp.h> #include <xen/interface/vcpu.h> diff --git a/sys/i386/xen/xen_clock_util.c b/sys/i386/xen/xen_clock_util.c index c14a627..c124515 100644 --- a/sys/i386/xen/xen_clock_util.c +++ b/sys/i386/xen/xen_clock_util.c @@ -39,12 +39,13 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/time.h> +#include <xen/xen-os.h> #include <xen/xen_intr.h> + #include <vm/vm.h> #include <vm/pmap.h> #include <machine/pmap.h> #include <xen/hypervisor.h> -#include <machine/xen/xen-os.h> #include <machine/xen/xenfunc.h> #include <xen/interface/io/xenbus.h> #include <xen/interface/vcpu.h> diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c index 9b5edd3..7049be6 100644 --- a/sys/i386/xen/xen_machdep.c +++ b/sys/i386/xen/xen_machdep.c @@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$"); #include <sys/rwlock.h> #include <sys/sysproto.h> -#include <machine/xen/xen-os.h> +#include <xen/xen-os.h> #include <vm/vm.h> #include <vm/pmap.h> @@ -96,6 +96,8 @@ xen_pfn_t *xen_pfn_to_mfn_frame_list[16]; xen_pfn_t *xen_pfn_to_mfn_frame_list_list; int preemptable, init_first; extern unsigned int avail_space; +int xen_vector_callback_enabled = 0; +enum xen_domain_type xen_domain_type = XEN_PV_DOMAIN; void ni_cli(void); void ni_sti(void); @@ -129,6 +131,12 @@ ni_sti(void) ); } +void +force_evtchn_callback(void) +{ + (void)HYPERVISOR_xen_version(0, NULL); +} + /* * Modify the cmd_line by converting ',' to NULLs so that it is in a format * suitable for the static env vars. @@ -141,7 +149,7 @@ xen_setbootenv(char *cmd_line) /* Skip leading spaces */ for (; *cmd_line == ' '; cmd_line++); - printk("xen_setbootenv(): cmd_line='%s'\n", cmd_line); + xc_printf("xen_setbootenv(): cmd_line='%s'\n", cmd_line); for (cmd_line_next = cmd_line; strsep(&cmd_line_next, ",") != NULL;); return cmd_line; @@ -177,16 +185,16 @@ xen_boothowto(char *envp) return howto; } -#define PRINTK_BUFSIZE 1024 +#define XC_PRINTF_BUFSIZE 1024 void -printk(const char *fmt, ...) +xc_printf(const char *fmt, ...) { __va_list ap; int retval; - static char buf[PRINTK_BUFSIZE]; + static char buf[XC_PRINTF_BUFSIZE]; va_start(ap, fmt); - retval = vsnprintf(buf, PRINTK_BUFSIZE - 1, fmt, ap); + retval = vsnprintf(buf, XC_PRINTF_BUFSIZE - 1, fmt, ap); va_end(ap); buf[retval] = 0; (void)HYPERVISOR_console_write(buf, retval); @@ -239,9 +247,10 @@ xen_dump_queue(void) if (_xpq_idx <= 1) return; - printk("xen_dump_queue(): %u entries\n", _xpq_idx); + xc_printf("xen_dump_queue(): %u entries\n", _xpq_idx); for (i = 0; i < _xpq_idx; i++) { - printk(" val: %llx ptr: %llx\n", XPQ_QUEUE[i].val, XPQ_QUEUE[i].ptr); + xc_printf(" val: %llx ptr: %llx\n", XPQ_QUEUE[i].val, + XPQ_QUEUE[i].ptr); } } #endif @@ -955,9 +964,10 @@ initvalues(start_info_t *startinfo) cur_space = xen_start_info->pt_base + (l3_pages + l2_pages + l1_pages + 1)*PAGE_SIZE; - printk("initvalues(): wooh - availmem=%x,%x\n", avail_space, cur_space); + xc_printf("initvalues(): wooh - availmem=%x,%x\n", avail_space, + cur_space); - printk("KERNBASE=%x,pt_base=%x, VTOPFN(base)=%x, nr_pt_frames=%x\n", + xc_printf("KERNBASE=%x,pt_base=%x, VTOPFN(base)=%x, nr_pt_frames=%x\n", KERNBASE,xen_start_info->pt_base, VTOPFN(xen_start_info->pt_base), xen_start_info->nr_pt_frames); xendebug_flags = 0; /* 0xffffffff; */ @@ -1007,7 +1017,7 @@ initvalues(start_info_t *startinfo) /* Map proc0's KSTACK */ proc0kstack = cur_space; cur_space += (KSTACK_PAGES * PAGE_SIZE); - printk("proc0kstack=%u\n", proc0kstack); + xc_printf("proc0kstack=%u\n", proc0kstack); /* vm86/bios stack */ cur_space += PAGE_SIZE; @@ -1106,18 +1116,18 @@ initvalues(start_info_t *startinfo) shinfo = xen_start_info->shared_info; PT_SET_MA(HYPERVISOR_shared_info, shinfo | PG_KERNEL); - printk("#4\n"); + xc_printf("#4\n"); xen_store_ma = (((vm_paddr_t)xen_start_info->store_mfn) << PAGE_SHIFT); PT_SET_MA(xen_store, xen_store_ma | PG_KERNEL); console_page_ma = (((vm_paddr_t)xen_start_info->console.domU.mfn) << PAGE_SHIFT); PT_SET_MA(console_page, console_page_ma | PG_KERNEL); - printk("#5\n"); + xc_printf("#5\n"); set_iopl.iopl = 1; PANIC_IF(HYPERVISOR_physdev_op(PHYSDEVOP_SET_IOPL, &set_iopl)); - printk("#6\n"); + xc_printf("#6\n"); #if 0 /* add page table for KERNBASE */ xen_queue_pt_update(IdlePTDma + KPTDI*sizeof(vm_paddr_t), @@ -1132,7 +1142,7 @@ initvalues(start_info_t *startinfo) #endif xen_flush_queue(); cur_space += PAGE_SIZE; - printk("#6\n"); + xc_printf("#6\n"); #endif /* 0 */ #ifdef notyet if (xen_start_info->flags & SIF_INITDOMAIN) { @@ -1150,13 +1160,13 @@ initvalues(start_info_t *startinfo) i < (((vm_offset_t)&etext) & ~PAGE_MASK); i += PAGE_SIZE) PT_SET_MA(i, VTOM(i) | PG_V | PG_A); - printk("#7\n"); + xc_printf("#7\n"); physfree = VTOP(cur_space); init_first = physfree >> PAGE_SHIFT; IdlePTD = (pd_entry_t *)VTOP(IdlePTD); IdlePDPT = (pd_entry_t *)VTOP(IdlePDPT); setup_xen_features(); - printk("#8, proc0kstack=%u\n", proc0kstack); + xc_printf("#8, proc0kstack=%u\n", proc0kstack); } @@ -1200,9 +1210,9 @@ HYPERVISOR_multicall(struct multicall_entry * call_list, int nr_calls) /* Check the results of individual hypercalls. */ for (i = 0; i < nr_calls; i++) - if (unlikely(call_list[i].result < 0)) + if (__predict_false(call_list[i].result < 0)) ret++; - if (unlikely(ret > 0)) + if (__predict_false(ret > 0)) panic("%d multicall(s) failed: cpu %d\n", ret, smp_processor_id()); diff --git a/sys/i386/xen/xen_rtc.c b/sys/i386/xen/xen_rtc.c index 8e1e017..8dc3ecb 100644 --- a/sys/i386/xen/xen_rtc.c +++ b/sys/i386/xen/xen_rtc.c @@ -39,15 +39,17 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/time.h> +#include <xen/xen-os.h> #include <xen/xen_intr.h> +#include <xen/hypervisor.h> +#include <xen/interface/io/xenbus.h> +#include <xen/interface/vcpu.h> + #include <vm/vm.h> #include <vm/pmap.h> + #include <machine/pmap.h> -#include <xen/hypervisor.h> -#include <machine/xen/xen-os.h> #include <machine/xen/xenfunc.h> -#include <xen/interface/io/xenbus.h> -#include <xen/interface/vcpu.h> #include <machine/cpu.h> #include <machine/xen/xen_clock_util.h> |