[PATCH v9 04/19] amd64: introduce hook for custom preload metadata parsers
--- sys/amd64/amd64/machdep.c | 41 -- sys/amd64/include/sysarch.h | 12 ++ sys/x86/xen/pv.c| 82 +++ 3 files changed, 124 insertions(+), 11 deletions(-) diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index eae657b..e073eea 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -126,6 +126,7 @@ __FBSDID($FreeBSD$); #include machine/reg.h #include machine/sigframe.h #include machine/specialreg.h +#include machine/sysarch.h #ifdef PERFMON #include machine/perfmon.h #endif @@ -165,6 +166,14 @@ static int set_fpcontext(struct thread *td, const mcontext_t *mcp, char *xfpustate, size_t xfpustate_len); SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); +/* Preload data parse function */ +static caddr_t native_parse_preload_data(u_int64_t); + +/* Default init_ops implementation. */ +struct init_ops init_ops = { + .parse_preload_data = native_parse_preload_data, +}; + /* * The file conf/ldscript.amd64 defines the symbol kernphys. Its value is * the physical address at which the kernel is loaded. @@ -1683,6 +1692,26 @@ do_next: msgbufp = (struct msgbuf *)PHYS_TO_DMAP(phys_avail[pa_indx]); } +static caddr_t +native_parse_preload_data(u_int64_t modulep) +{ + caddr_t kmdp; + + preload_metadata = (caddr_t)(uintptr_t)(modulep + KERNBASE); + preload_bootstrap_relocate(KERNBASE); + kmdp = preload_search_by_type(elf kernel); + if (kmdp == NULL) + kmdp = preload_search_by_type(elf64 kernel); + boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); + kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *) + KERNBASE; +#ifdef DDB + ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); + ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); +#endif + + return (kmdp); +} + u_int64_t hammer_time(u_int64_t modulep, u_int64_t physfree) { @@ -1707,17 +1736,7 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) */ proc_linkup0(proc0, thread0); - preload_metadata = (caddr_t)(uintptr_t)(modulep + KERNBASE); - preload_bootstrap_relocate(KERNBASE); - kmdp = preload_search_by_type(elf kernel); - if (kmdp == NULL) - kmdp = preload_search_by_type(elf64 kernel); - boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); - kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *) + KERNBASE; -#ifdef DDB - ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); - ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); -#endif + kmdp = init_ops.parse_preload_data(modulep); /* Init basic tunables, hz etc */ init_param1(); diff --git a/sys/amd64/include/sysarch.h b/sys/amd64/include/sysarch.h index cd380d4..58ac8cd 100644 --- a/sys/amd64/include/sysarch.h +++ b/sys/amd64/include/sysarch.h @@ -4,3 +4,15 @@ /* $FreeBSD$ */ #include x86/sysarch.h + +/* + * Struct containing pointers to init functions whose + * implementation is run time selectable. Selection can be made, + * for example, based on detection of a BIOS variant or + * hypervisor environment. + */ +struct init_ops { + caddr_t (*parse_preload_data)(u_int64_t); +}; + +extern struct init_ops init_ops; diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c index db3b7a3..908b50b 100644 --- a/sys/x86/xen/pv.c +++ b/sys/x86/xen/pv.c @@ -46,6 +46,8 @@ __FBSDID($FreeBSD$); #include vm/vm_pager.h #include vm/vm_param.h +#include machine/sysarch.h + #include xen/xen-os.h #include xen/hypervisor.h @@ -54,6 +56,36 @@ extern u_int64_t hammer_time(u_int64_t, u_int64_t); /* Xen initial function */ extern u_int64_t hammer_time_xen(start_info_t *, u_int64_t); +/*--- Forward Declarations ---*/ +static caddr_t xen_pv_parse_preload_data(u_int64_t); + +static void xen_pv_set_init_ops(void); + +/* Global Data ---*/ +/* Xen init_ops implementation. */ +struct init_ops xen_init_ops = { + .parse_preload_data = xen_pv_parse_preload_data, +}; + +static struct +{ + const char *ev; + int mask; +} howto_names[] = { + {boot_askname,RB_ASKNAME}, + {boot_single, RB_SINGLE}, + {boot_nosync, RB_NOSYNC}, + {boot_halt, RB_ASKNAME}, + {boot_serial, RB_SERIAL}, + {boot_cdrom, RB_CDROM}, + {boot_gdb,RB_GDB}, + {boot_gdb_pause, RB_RESERVED1}, + {boot_verbose,RB_VERBOSE}, + {boot_multicons, RB_MULTIPLE}, + {NULL, 0} +}; + +/* Xen PV init ---*/ /* * First function called by the Xen PVH boot sequence. * @@ -118,6 +150,56 @@ hammer_time_xen(start_info_t *si, u_int64_t xenstack) } load_cr3(((u_int64_t)PT4[0]) -
[PATCH v9 00/19] FreeBSD PVH DomU support
This series is a split of the previous patch Xen x86 DomU PVH support, with the aim to make the review of the code easier. The series can also be found on my git repo: git://xenbits.xen.org/people/royger/freebsd.git pvh_v9 or http://xenbits.xen.org/gitweb/?p=people/royger/freebsd.git;a=shortlog;h=refs/heads/pvh_v9 PVH mode is basically a PV guest inside an HVM container, and shares a great amount of code with PVHVM. The main difference is the way the guest is started, PVH uses the PV start sequence, jumping directly into the kernel entry point in long mode and with page tables set. The main work of this patch consists in setting the environment as similar as possible to what native FreeBSD expects, and then adding hooks to the PV ops when necessary. This new version of the series (v9) addresses the comments from the previous posted version (v7). ___ freebsd-xen@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-xen To unsubscribe, send any mail to freebsd-xen-unsubscr...@freebsd.org
[PATCH v9 05/19] xen: rework xen timer so it can be used early in boot process
This should not introduce any functional change, and makes the functions suitable to be called before we have actually mapped the vcpu_info struct on a per-cpu basis. --- sys/dev/xen/timer/timer.c | 29 - 1 files changed, 20 insertions(+), 9 deletions(-) diff --git a/sys/dev/xen/timer/timer.c b/sys/dev/xen/timer/timer.c index 354085b..b2f6bcd 100644 --- a/sys/dev/xen/timer/timer.c +++ b/sys/dev/xen/timer/timer.c @@ -230,22 +230,22 @@ xen_fetch_vcpu_tinfo(struct vcpu_time_info *dst, struct vcpu_time_info *src) /** * \brief Get the current time, in nanoseconds, since the hypervisor booted. * + * \param vcpu vcpu_info structure to fetch the time from. + * * \note This function returns the current CPU's idea of this value, unless * it happens to be less than another CPU's previously determined value. */ static uint64_t -xen_fetch_vcpu_time(void) +xen_fetch_vcpu_time(struct vcpu_info *vcpu) { struct vcpu_time_info dst; struct vcpu_time_info *src; uint32_t pre_version; uint64_t now; volatile uint64_t last; - struct vcpu_info *vcpu = DPCPU_GET(vcpu_info); src = vcpu-time; - critical_enter(); do { pre_version = xen_fetch_vcpu_tinfo(dst, src); barrier(); @@ -266,16 +266,19 @@ xen_fetch_vcpu_time(void) } } while (!atomic_cmpset_64(xen_timer_last_time, last, now)); - critical_exit(); - return (now); } static uint32_t xentimer_get_timecount(struct timecounter *tc) { + uint32_t xen_time; - return ((uint32_t)xen_fetch_vcpu_time() UINT_MAX); + critical_enter(); + xen_time = (uint32_t)xen_fetch_vcpu_time(DPCPU_GET(vcpu_info)) UINT_MAX; + critical_exit(); + + return (xen_time); } /** @@ -305,7 +308,12 @@ xen_fetch_wallclock(struct timespec *ts) static void xen_fetch_uptime(struct timespec *ts) { - uint64_t uptime = xen_fetch_vcpu_time(); + uint64_t uptime; + + critical_enter(); + uptime = xen_fetch_vcpu_time(DPCPU_GET(vcpu_info)); + critical_exit(); + ts-tv_sec = uptime / NSEC_IN_SEC; ts-tv_nsec = uptime % NSEC_IN_SEC; } @@ -354,7 +362,7 @@ xentimer_intr(void *arg) struct xentimer_softc *sc = (struct xentimer_softc *)arg; struct xentimer_pcpu_data *pcpu = DPCPU_PTR(xentimer_pcpu); - pcpu-last_processed = xen_fetch_vcpu_time(); + pcpu-last_processed = xen_fetch_vcpu_time(DPCPU_GET(vcpu_info)); if (pcpu-timer != 0 sc-et.et_active) sc-et.et_event_cb(sc-et, sc-et.et_arg); @@ -415,7 +423,10 @@ xentimer_et_start(struct eventtimer *et, do { if (++i == 60) panic(can't schedule timer); - next_time = xen_fetch_vcpu_time() + first_in_ns; + critical_enter(); + next_time = xen_fetch_vcpu_time(DPCPU_GET(vcpu_info)) + + first_in_ns; + critical_exit(); error = xentimer_vcpu_start_timer(cpu, next_time); } while (error == -ETIME); -- 1.7.7.5 (Apple Git-26) ___ freebsd-xen@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-xen To unsubscribe, send any mail to freebsd-xen-unsubscr...@freebsd.org
[PATCH v9 02/19] xen: add macro to detect if running as Dom0
--- sys/xen/xen-os.h |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/sys/xen/xen-os.h b/sys/xen/xen-os.h index c7474d8..e8a5a99 100644 --- a/sys/xen/xen-os.h +++ b/sys/xen/xen-os.h @@ -82,6 +82,13 @@ xen_hvm_domain(void) return (xen_domain_type == XEN_HVM_DOMAIN); } +static inline int +xen_initial_domain(void) +{ + return (xen_domain() HYPERVISOR_start_info + HYPERVISOR_start_info-flags SIF_INITDOMAIN); +} + #ifndef xen_mb #define xen_mb() mb() #endif -- 1.7.7.5 (Apple Git-26) ___ freebsd-xen@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-xen To unsubscribe, send any mail to freebsd-xen-unsubscr...@freebsd.org
[PATCH v9 06/19] xen: implement an early timer for Xen PVH
When running as a PVH guest, there's no emulated i8254, so we need to use the Xen PV timer as the early source for DELAY. This change allows for different implementations of the early DELAY function and implements a Xen variant for it. --- sys/amd64/amd64/machdep.c |6 ++- sys/amd64/include/clock.h |5 ++ sys/amd64/include/sysarch.h |2 + sys/conf/files.amd64|1 + sys/conf/files.i386 |1 + sys/dev/xen/timer/timer.c | 33 + sys/i386/include/clock.h|5 ++ sys/x86/isa/clock.c | 53 + sys/x86/x86/delay.c | 112 +++ sys/x86/xen/pv.c|3 + 10 files changed, 167 insertions(+), 54 deletions(-) create mode 100644 sys/x86/x86/delay.c diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index e073eea..178d8b3 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -172,6 +172,8 @@ static caddr_t native_parse_preload_data(u_int64_t); /* Default init_ops implementation. */ struct init_ops init_ops = { .parse_preload_data = native_parse_preload_data, + .early_delay_init = i8254_init, + .early_delay = i8254_delay, }; /* @@ -1820,10 +1822,10 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) lidt(r_idt); /* -* Initialize the i8254 before the console so that console +* Initialize the early delay before the console so that console * initialization can use DELAY(). */ - i8254_init(); + init_ops.early_delay_init(); /* * Initialize the console before we print anything out. diff --git a/sys/amd64/include/clock.h b/sys/amd64/include/clock.h index d7f7d82..ac8818f 100644 --- a/sys/amd64/include/clock.h +++ b/sys/amd64/include/clock.h @@ -25,6 +25,11 @@ extern int smp_tsc; #endif void i8254_init(void); +void i8254_delay(int); +#ifdef XENHVM +void xen_delay_init(void); +void xen_delay(int); +#endif /* * Driver to clock driver interface. diff --git a/sys/amd64/include/sysarch.h b/sys/amd64/include/sysarch.h index 58ac8cd..60fa635 100644 --- a/sys/amd64/include/sysarch.h +++ b/sys/amd64/include/sysarch.h @@ -13,6 +13,8 @@ */ struct init_ops { caddr_t (*parse_preload_data)(u_int64_t); + void(*early_delay_init)(void); + void(*early_delay)(int); }; extern struct init_ops init_ops; diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 16029d8..109a796 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -565,6 +565,7 @@ x86/x86/mptable_pci.c optionalmptable pci x86/x86/msi.c optionalpci x86/x86/nexus.cstandard x86/x86/tsc.c standard +x86/x86/delay.cstandard x86/xen/hvm.c optionalxenhvm x86/xen/xen_intr.c optionalxen | xenhvm x86/xen/pv.c optionalxenhvm diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index eb8697c..790296d 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -600,5 +600,6 @@ x86/x86/mptable_pci.c optional apic native pci x86/x86/msi.c optional apic pci x86/x86/nexus.cstandard x86/x86/tsc.c standard +x86/x86/delay.cstandard x86/xen/hvm.c optional xenhvm x86/xen/xen_intr.c optional xen | xenhvm diff --git a/sys/dev/xen/timer/timer.c b/sys/dev/xen/timer/timer.c index b2f6bcd..96372ab 100644 --- a/sys/dev/xen/timer/timer.c +++ b/sys/dev/xen/timer/timer.c @@ -59,6 +59,9 @@ __FBSDID($FreeBSD$); #include machine/_inttypes.h #include machine/smp.h +/* For the declaration of clock_lock */ +#include isa/rtc.h + #include clock_if.h static devclass_t xentimer_devclass; @@ -584,6 +587,36 @@ xentimer_suspend(device_t dev) return (0); } +/* + * Xen delay early init + */ +void xen_delay_init(void) +{ + /* Init the clock lock */ + mtx_init(clock_lock, clk, NULL, MTX_SPIN | MTX_NOPROFILE); +} +/* + * Xen PV DELAY function + * + * When running on PVH mode we don't have an emulated i8524, so + * make use of the Xen time info in order to code a simple DELAY + * function that can be used during early boot. + */ +void xen_delay(int n) +{ + uint64_t end_ns; + uint64_t current; + + end_ns = xen_fetch_vcpu_time(HYPERVISOR_shared_info-vcpu_info[0]); + end_ns += n * NSEC_IN_USEC; + + for (;;) { + current = xen_fetch_vcpu_time(HYPERVISOR_shared_info-vcpu_info[0]); + if (current = end_ns) + break; + } +} + static device_method_t xentimer_methods[] = { DEVMETHOD(device_identify, xentimer_identify), DEVMETHOD(device_probe, xentimer_probe), diff --git a/sys/i386/include/clock.h b/sys/i386/include/clock.h
[PATCH v9 07/19] xen: implement hook to fetch e820 memory map
--- sys/amd64/amd64/machdep.c | 50 ++ sys/amd64/include/pc/bios.h |2 + sys/amd64/include/sysarch.h |1 + sys/x86/xen/pv.c| 25 + 4 files changed, 59 insertions(+), 19 deletions(-) diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 178d8b3..f6eef50 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -169,11 +169,15 @@ SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); /* Preload data parse function */ static caddr_t native_parse_preload_data(u_int64_t); +/* Native function to fetch and parse the e820 map */ +static void native_parse_memmap(caddr_t, vm_paddr_t *, int *); + /* Default init_ops implementation. */ struct init_ops init_ops = { .parse_preload_data = native_parse_preload_data, .early_delay_init = i8254_init, .early_delay = i8254_delay, + .parse_memmap = native_parse_memmap, }; /* @@ -1401,21 +1405,12 @@ add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap, return (1); } -static void -add_smap_entries(struct bios_smap *smapbase, vm_paddr_t *physmap, -int *physmap_idx) +void +bios_add_smap_entries(struct bios_smap *smapbase, u_int32_t smapsize, + vm_paddr_t *physmap, int *physmap_idx) { struct bios_smap *smap, *smapend; - u_int32_t smapsize; - /* -* Memory map from INT 15:E820. -* -* subr_module.c says: -* Consumer may safely assume that size value precedes data. -* ie: an int32_t immediately precedes smap. -*/ - smapsize = *((u_int32_t *)smapbase - 1); smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize); for (smap = smapbase; smap smapend; smap++) { @@ -1432,6 +1427,29 @@ add_smap_entries(struct bios_smap *smapbase, vm_paddr_t *physmap, } } +static void +native_parse_memmap(caddr_t kmdp, vm_paddr_t *physmap, int *physmap_idx) +{ + struct bios_smap *smap; + u_int32_t size; + + /* +* Memory map from INT 15:E820. +* +* subr_module.c says: +* Consumer may safely assume that size value precedes data. +* ie: an int32_t immediately precedes smap. +*/ + + smap = (struct bios_smap *)preload_search_info(kmdp, + MODINFO_METADATA | MODINFOMD_SMAP); + if (smap == NULL) + panic(No BIOS smap info from loader!); + size = *((u_int32_t *)smap - 1); + + bios_add_smap_entries(smap, size, physmap, physmap_idx); +} + /* * Populate the (physmap) array with base/bound pairs describing the * available physical memory in the system, then test this memory and @@ -1449,19 +1467,13 @@ getmemsize(caddr_t kmdp, u_int64_t first) vm_paddr_t pa, physmap[PHYSMAP_SIZE]; u_long physmem_start, physmem_tunable, memtest; pt_entry_t *pte; - struct bios_smap *smapbase; quad_t dcons_addr, dcons_size; bzero(physmap, sizeof(physmap)); basemem = 0; physmap_idx = 0; - smapbase = (struct bios_smap *)preload_search_info(kmdp, - MODINFO_METADATA | MODINFOMD_SMAP); - if (smapbase == NULL) - panic(No BIOS smap info from loader!); - - add_smap_entries(smapbase, physmap, physmap_idx); + init_ops.parse_memmap(kmdp, physmap, physmap_idx); /* * Find the 'base memory' segment for SMP diff --git a/sys/amd64/include/pc/bios.h b/sys/amd64/include/pc/bios.h index e7d568e..95ef703 100644 --- a/sys/amd64/include/pc/bios.h +++ b/sys/amd64/include/pc/bios.h @@ -106,6 +106,8 @@ struct bios_oem { intbios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen); uint32_t bios_sigsearch(uint32_t start, u_char *sig, int siglen, int paralen, int sigofs); +void bios_add_smap_entries(struct bios_smap *smapbase, u_int32_t smapsize, + vm_paddr_t *physmap, int *physmap_idx); #endif #endif /* _MACHINE_PC_BIOS_H_ */ diff --git a/sys/amd64/include/sysarch.h b/sys/amd64/include/sysarch.h index 60fa635..084223e 100644 --- a/sys/amd64/include/sysarch.h +++ b/sys/amd64/include/sysarch.h @@ -15,6 +15,7 @@ struct init_ops { caddr_t (*parse_preload_data)(u_int64_t); void(*early_delay_init)(void); void(*early_delay)(int); + void(*parse_memmap)(caddr_t, vm_paddr_t *, int *); }; extern struct init_ops init_ops; diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c index 0ec4b54..d11bc1a 100644 --- a/sys/x86/xen/pv.c +++ b/sys/x86/xen/pv.c @@ -48,6 +48,7 @@ __FBSDID($FreeBSD$); #include machine/sysarch.h #include machine/clock.h +#include machine/pc/bios.h #include xen/xen-os.h #include xen/hypervisor.h @@ -57,8 +58,11 @@ extern u_int64_t hammer_time(u_int64_t, u_int64_t); /* Xen initial function */ extern u_int64_t hammer_time_xen(start_info_t *, u_int64_t); +#define
[PATCH v9 03/19] xen: add and enable Xen console for PVH guests
This adds and enables the console used on XEN kernels. --- sys/conf/files |4 +- sys/dev/xen/console/console.c | 37 +-- sys/dev/xen/console/xencons_ring.c | 15 + sys/i386/include/xen/xen-os.h |1 - sys/i386/xen/xen_machdep.c | 17 sys/x86/xen/pv.c |4 +++ sys/xen/xen-os.h |4 +++ 7 files changed, 50 insertions(+), 32 deletions(-) diff --git a/sys/conf/files b/sys/conf/files index a73d31e..f55479d 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2523,8 +2523,8 @@ dev/xe/if_xe_pccard.c optional xe pccard dev/xen/balloon/balloon.c optional xen | xenhvm dev/xen/blkfront/blkfront.coptional xen | xenhvm dev/xen/blkback/blkback.c optional xen | xenhvm -dev/xen/console/console.c optional xen -dev/xen/console/xencons_ring.c optional xen +dev/xen/console/console.c optional xen | xenhvm +dev/xen/console/xencons_ring.c optional xen | xenhvm dev/xen/control/control.c optional xen | xenhvm dev/xen/netback/netback.c optional xen | xenhvm dev/xen/netfront/netfront.coptional xen | xenhvm diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c index 23eaee2..899dffc 100644 --- a/sys/dev/xen/console/console.c +++ b/sys/dev/xen/console/console.c @@ -69,11 +69,14 @@ struct mtx cn_mtx; static char wbuf[WBUF_SIZE]; static char rbuf[RBUF_SIZE]; static int rc, rp; -static unsigned int cnsl_evt_reg; +unsigned int cnsl_evt_reg; static unsigned int wc, wp; /* write_cons, write_prod */ xen_intr_handle_t xen_intr_handle; device_t xencons_dev; +/* Virtual address of the shared console page */ +char *console_page; + #ifdef KDB static int xc_altbrk; #endif @@ -110,9 +113,26 @@ static struct ttydevsw xc_ttydevsw = { .tsw_outwakeup = xcoutwakeup, }; +/*- Debug function ---*/ +#define XC_PRINTF_BUFSIZE 1024 +void +xc_printf(const char *fmt, ...) +{ + static char buf[XC_PRINTF_BUFSIZE]; + __va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + HYPERVISOR_console_write(buf, strlen(buf)); +} + static void xc_cnprobe(struct consdev *cp) { + if (!xen_pv_domain()) + return; + cp-cn_pri = CN_REMOTE; sprintf(cp-cn_name, %s0, driver_name); } @@ -175,7 +195,7 @@ static void xc_cnputc(struct consdev *dev, int c) { - if (xen_start_info-flags SIF_INITDOMAIN) + if (xen_initial_domain()) xc_cnputc_dom0(dev, c); else xc_cnputc_domu(dev, c); @@ -206,8 +226,7 @@ xcons_putc(int c) xcons_force_flush(); #endif } - if (cnsl_evt_reg) - __xencons_tx_flush(); + __xencons_tx_flush(); /* inform start path that we're pretty full */ return ((wp - wc) = WBUF_SIZE - 100) ? TRUE : FALSE; @@ -217,6 +236,10 @@ static void xc_identify(driver_t *driver, device_t parent) { device_t child; + + if (!xen_pv_domain()) + return; + child = BUS_ADD_CHILD(parent, 0, driver_name, 0); device_set_driver(child, driver); device_set_desc(child, Xen Console); @@ -245,7 +268,7 @@ xc_attach(device_t dev) cnsl_evt_reg = 1; callout_reset(xc_callout, XC_POLLTIME, xc_timeout, xccons); - if (xen_start_info-flags SIF_INITDOMAIN) { + if (xen_initial_domain()) { error = xen_intr_bind_virq(dev, VIRQ_CONSOLE, 0, NULL, xencons_priv_interrupt, NULL, INTR_TYPE_TTY, xen_intr_handle); @@ -309,7 +332,7 @@ __xencons_tx_flush(void) sz = wp - wc; if (sz (WBUF_SIZE - WBUF_MASK(wc))) sz = WBUF_SIZE - WBUF_MASK(wc); - if (xen_start_info-flags SIF_INITDOMAIN) { + if (xen_initial_domain()) { HYPERVISOR_console_io(CONSOLEIO_write, sz, wbuf[WBUF_MASK(wc)]); wc += sz; } else { @@ -424,7 +447,7 @@ xcons_force_flush(void) { intsz; - if (xen_start_info-flags SIF_INITDOMAIN) + if (xen_initial_domain()) return; /* Spin until console data is flushed through to the domain controller. */ diff --git a/sys/dev/xen/console/xencons_ring.c b/sys/dev/xen/console/xencons_ring.c index 3701551..d826363 100644 --- a/sys/dev/xen/console/xencons_ring.c +++ b/sys/dev/xen/console/xencons_ring.c @@ -32,9 +32,9 @@ __FBSDID($FreeBSD$); #define console_evtchn console.domU.evtchn xen_intr_handle_t console_handle; -extern char *console_page; extern struct mtx cn_mtx; extern device_t xencons_dev; +extern int cnsl_evt_reg; static inline struct
[PATCH v9 10/19] xen: add hook for AP bootstrap memory reservation
This hook will only be implemented for bare metal, Xen doesn't require any bootstrap code since APs are started in long mode with paging enabled. --- sys/amd64/amd64/machdep.c |6 +- sys/amd64/include/sysarch.h |1 + 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index f6eef50..babf16d 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -178,6 +178,9 @@ struct init_ops init_ops = { .early_delay_init = i8254_init, .early_delay = i8254_delay, .parse_memmap = native_parse_memmap, +#ifdef SMP + .mp_bootaddress = mp_bootaddress, +#endif }; /* @@ -1490,7 +1493,8 @@ getmemsize(caddr_t kmdp, u_int64_t first) #ifdef SMP /* make hole for AP bootstrap code */ - physmap[1] = mp_bootaddress(physmap[1] / 1024); + if (init_ops.mp_bootaddress) + physmap[1] = init_ops.mp_bootaddress(physmap[1] / 1024); #endif /* diff --git a/sys/amd64/include/sysarch.h b/sys/amd64/include/sysarch.h index 084223e..7696064 100644 --- a/sys/amd64/include/sysarch.h +++ b/sys/amd64/include/sysarch.h @@ -16,6 +16,7 @@ struct init_ops { void(*early_delay_init)(void); void(*early_delay)(int); void(*parse_memmap)(caddr_t, vm_paddr_t *, int *); + u_int (*mp_bootaddress)(u_int); }; extern struct init_ops init_ops; -- 1.7.7.5 (Apple Git-26) ___ freebsd-xen@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-xen To unsubscribe, send any mail to freebsd-xen-unsubscr...@freebsd.org
[PATCH v9 17/19] xen: xenstore changes to support PVH
--- sys/xen/xenstore/xenstore.c | 18 +- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sys/xen/xenstore/xenstore.c b/sys/xen/xenstore/xenstore.c index b5cf413..7fa08cc 100644 --- a/sys/xen/xenstore/xenstore.c +++ b/sys/xen/xenstore/xenstore.c @@ -229,13 +229,11 @@ struct xs_softc { */ struct sx xenwatch_mutex; -#ifdef XENHVM /** * The HVM guest pseudo-physical frame number. This is Xen's mapping * of the true machine frame number into our physical address space. */ unsigned long gpfn; -#endif /** * The event channel for communicating with the @@ -1147,13 +1145,15 @@ xs_attach(device_t dev) /* Initialize the interface to xenstore. */ struct proc *p; -#ifdef XENHVM - xs.evtchn = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN); - xs.gpfn = hvm_get_parameter(HVM_PARAM_STORE_PFN); - xen_store = pmap_mapdev(xs.gpfn * PAGE_SIZE, PAGE_SIZE); -#else - xs.evtchn = xen_start_info-store_evtchn; -#endif + if (xen_hvm_domain()) { + xs.evtchn = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN); + xs.gpfn = hvm_get_parameter(HVM_PARAM_STORE_PFN); + xen_store = pmap_mapdev(xs.gpfn * PAGE_SIZE, PAGE_SIZE); + } else if (xen_pv_domain()) { + xs.evtchn = HYPERVISOR_start_info-store_evtchn; + } else { + panic(Unknown domain type, cannot initialize xenstore\n); + } TAILQ_INIT(xs.reply_list); TAILQ_INIT(xs.watch_events); -- 1.7.7.5 (Apple Git-26) ___ freebsd-xen@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-xen To unsubscribe, send any mail to freebsd-xen-unsubscr...@freebsd.org
[PATCH v9 18/19] xen: changes to gnttab for PVH
--- sys/xen/gnttab.c | 26 +- 1 files changed, 21 insertions(+), 5 deletions(-) diff --git a/sys/xen/gnttab.c b/sys/xen/gnttab.c index 03c32b7..6949be5 100644 --- a/sys/xen/gnttab.c +++ b/sys/xen/gnttab.c @@ -25,6 +25,7 @@ __FBSDID($FreeBSD$); #include sys/lock.h #include sys/malloc.h #include sys/mman.h +#include sys/limits.h #include xen/xen-os.h #include xen/hypervisor.h @@ -607,6 +608,7 @@ gnttab_resume(void) { int error; unsigned int max_nr_gframes, nr_gframes; + void *alloc_mem; nr_gframes = nr_grant_frames; max_nr_gframes = max_nr_grant_frames(); @@ -614,11 +616,25 @@ gnttab_resume(void) return (ENOSYS); if (!resume_frames) { - error = xenpci_alloc_space(PAGE_SIZE * max_nr_gframes, - resume_frames); - if (error) { - printf(error mapping gnttab share frames\n); - return (error); + if (xen_pv_domain()) { + /* +* This is a waste of physical memory, +* we should use ballooned pages instead, +* but it will do for now. +*/ + alloc_mem = contigmalloc(max_nr_gframes * PAGE_SIZE, +M_DEVBUF, M_NOWAIT, 0, +ULONG_MAX, PAGE_SIZE, 0); + KASSERT((alloc_mem != NULL), + (unable to alloc memory for gnttab)); + resume_frames = vtophys(alloc_mem); + } else { + error = xenpci_alloc_space(PAGE_SIZE * max_nr_gframes, + resume_frames); + if (error) { + printf(error mapping gnttab share frames\n); + return (error); + } } } -- 1.7.7.5 (Apple Git-26) ___ freebsd-xen@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-xen To unsubscribe, send any mail to freebsd-xen-unsubscr...@freebsd.org
[PATCH v9 13/19] xen: introduce flag to disable the local apic
PVH guests don't have an emulated lapic. --- sys/amd64/amd64/mp_machdep.c | 10 ++ sys/amd64/include/apicvar.h |1 + sys/i386/include/apicvar.h |1 + sys/i386/xen/xen_machdep.c |2 ++ sys/x86/x86/local_apic.c |8 +--- sys/x86/xen/pv.c |3 +++ 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 0738a37..fd6eace 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -707,7 +707,8 @@ init_secondary(void) wrmsr(MSR_SF_MASK, PSL_NT|PSL_T|PSL_I|PSL_C|PSL_D); /* Disable local APIC just to be sure. */ - lapic_disable(); + if (lapic_valid) + lapic_disable(); /* signal our startup to the BSP. */ mp_naps++; @@ -733,7 +734,7 @@ init_secondary(void) /* A quick check from sanity claus */ cpuid = PCPU_GET(cpuid); - if (PCPU_GET(apic_id) != lapic_id()) { + if (lapic_valid (PCPU_GET(apic_id) != lapic_id())) { printf(SMP: cpuid = %d\n, cpuid); printf(SMP: actual apic_id = %d\n, lapic_id()); printf(SMP: correct apic_id = %d\n, PCPU_GET(apic_id)); @@ -749,7 +750,8 @@ init_secondary(void) mtx_lock_spin(ap_boot_mtx); /* Init local apic for irq's */ - lapic_setup(1); + if (lapic_valid) + lapic_setup(1); /* Set memory range attributes for this CPU to match the BSP */ mem_range_AP_init(); @@ -764,7 +766,7 @@ init_secondary(void) if (cpu_logical 1 PCPU_GET(apic_id) % cpu_logical != 0) CPU_SET(cpuid, logical_cpus_mask); - if (bootverbose) + if (lapic_valid bootverbose) lapic_dump(AP); if (smp_cpus == mp_ncpus) { diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h index e7423a3..c04a238 100644 --- a/sys/amd64/include/apicvar.h +++ b/sys/amd64/include/apicvar.h @@ -169,6 +169,7 @@ inthand_t extern vm_paddr_t lapic_paddr; extern int apic_cpuids[]; +extern bool lapic_valid; u_int apic_alloc_vector(u_int apic_id, u_int irq); u_int apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h index df99ebe..ea8a3c3 100644 --- a/sys/i386/include/apicvar.h +++ b/sys/i386/include/apicvar.h @@ -168,6 +168,7 @@ inthand_t extern vm_paddr_t lapic_paddr; extern int apic_cpuids[]; +extern bool lapic_valid; u_int apic_alloc_vector(u_int apic_id, u_int irq); u_int apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c index 09c01f1..25b9cfc 100644 --- a/sys/i386/xen/xen_machdep.c +++ b/sys/i386/xen/xen_machdep.c @@ -59,6 +59,7 @@ __FBSDID($FreeBSD$); #include machine/intr_machdep.h #include machine/md_var.h #include machine/asmacros.h +#include machine/apicvar.h @@ -912,6 +913,7 @@ initvalues(start_info_t *startinfo) #endif xen_start_info = startinfo; HYPERVISOR_start_info = startinfo; + lapic_valid = false; xen_phys_machine = (xen_pfn_t *)startinfo-mfn_list; IdlePTD = (pd_entry_t *)((uint8_t *)startinfo-pt_base + PAGE_SIZE); diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c index 41bd602..fddf1fb 100644 --- a/sys/x86/x86/local_apic.c +++ b/sys/x86/x86/local_apic.c @@ -156,6 +156,7 @@ extern inthand_t IDTVEC(rsvd); volatile lapic_t *lapic; vm_paddr_t lapic_paddr; +bool lapic_valid = true; static u_long lapic_timer_divisor; static struct eventtimer lapic_et; @@ -1367,9 +1368,10 @@ apic_setup_io(void *dummy __unused) if (retval != 0) printf(%s: Failed to setup I/O APICs: returned %d\n, best_enum-apic_name, retval); -#ifdef XEN - return; -#endif + + if (!lapic_valid) + return; + /* * Finish setting up the local APIC on the BSP once we know how to * properly program the LINT pins. diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c index 22fd6a6..6ea1e2a 100644 --- a/sys/x86/xen/pv.c +++ b/sys/x86/xen/pv.c @@ -53,6 +53,7 @@ __FBSDID($FreeBSD$); #include machine/clock.h #include machine/pc/bios.h #include machine/smp.h +#include machine/apicvar.h #include xen/xen-os.h #include xen/hypervisor.h @@ -315,4 +316,6 @@ xen_pv_set_init_ops(void) { /* Init ops for Xen PV */ init_ops = xen_init_ops; + /* Disable lapic */ + lapic_valid = false; } -- 1.7.7.5 (Apple Git-26) ___ freebsd-xen@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-xen To unsubscribe, send any mail to freebsd-xen-unsubscr...@freebsd.org
[PATCH v9 12/19] xen: add a hook to perform AP startup
AP startup on PVH follows the PV method, so we need to add a hook in order to diverge from bare metal. --- sys/amd64/amd64/mp_machdep.c | 14 +++--- sys/amd64/include/cpu.h |1 + sys/amd64/include/smp.h |1 + sys/x86/xen/hvm.c| 12 +- sys/x86/xen/pv.c | 85 ++ sys/xen/pv.h | 32 6 files changed, 137 insertions(+), 8 deletions(-) create mode 100644 sys/xen/pv.h diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 4ef4b3d..0738a37 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -90,7 +90,7 @@ extern struct pcpu __pcpu[]; /* AP uses this during bootstrap. Do not staticize. */ char *bootSTK; -static int bootAP; +int bootAP; /* Free these after use */ void *bootstacks[MAXCPU]; @@ -124,7 +124,8 @@ static u_long *ipi_hardclock_counts[MAXCPU]; /* Default cpu_ops implementation. */ struct cpu_ops cpu_ops = { - .ipi_vectored = lapic_ipi_vectored + .ipi_vectored = lapic_ipi_vectored, + .start_all_aps = native_start_all_aps, }; extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32); @@ -138,7 +139,7 @@ extern int pmap_pcid_enabled; static volatile cpuset_t ipi_nmi_pending; /* used to hold the AP's until we are ready to release them */ -static struct mtx ap_boot_mtx; +struct mtx ap_boot_mtx; /* Set to 1 once we're ready to let the APs out of the pen. */ static volatile int aps_ready = 0; @@ -165,7 +166,6 @@ static int cpu_cores; /* cores per package */ static voidassign_cpu_ids(void); static voidset_interrupt_apic_ids(void); -static int start_all_aps(void); static int start_ap(int apic_id); static voidrelease_aps(void *dummy); @@ -569,7 +569,7 @@ cpu_mp_start(void) assign_cpu_ids(); /* Start each Application Processor */ - start_all_aps(); + cpu_ops.start_all_aps(); set_interrupt_apic_ids(); } @@ -908,8 +908,8 @@ assign_cpu_ids(void) /* * start each AP in our list */ -static int -start_all_aps(void) +int +native_start_all_aps(void) { vm_offset_t va = boot_address + KERNBASE; u_int64_t *pt4, *pt3, *pt2; diff --git a/sys/amd64/include/cpu.h b/sys/amd64/include/cpu.h index 3d9ff531..ed9f1db 100644 --- a/sys/amd64/include/cpu.h +++ b/sys/amd64/include/cpu.h @@ -64,6 +64,7 @@ struct cpu_ops { void (*cpu_init)(void); void (*cpu_resume)(void); void (*ipi_vectored)(u_int, int); + int (*start_all_aps)(void); }; extern struct cpu_ops cpu_ops; diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index d1b366b..15bc823 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -79,6 +79,7 @@ void smp_masked_invlpg_range(cpuset_t mask, struct pmap *pmap, vm_offset_t startva, vm_offset_t endva); void smp_invltlb(struct pmap *pmap); void smp_masked_invltlb(cpuset_t mask, struct pmap *pmap); +intnative_start_all_aps(void); #endif /* !LOCORE */ #endif /* SMP */ diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c index fb1ed79..49caacf 100644 --- a/sys/x86/xen/hvm.c +++ b/sys/x86/xen/hvm.c @@ -53,6 +53,9 @@ __FBSDID($FreeBSD$); #include xen/hypervisor.h #include xen/hvm.h #include xen/xen_intr.h +#ifdef __amd64__ +#include xen/pv.h +#endif #include xen/interface/hvm/params.h #include xen/interface/vcpu.h @@ -119,7 +122,10 @@ enum xen_domain_type xen_domain_type = XEN_NATIVE; struct cpu_ops xen_hvm_cpu_ops = { .ipi_vectored = lapic_ipi_vectored, .cpu_init = xen_hvm_cpu_init, - .cpu_resume = xen_hvm_cpu_resume + .cpu_resume = xen_hvm_cpu_resume, +#ifdef __amd64__ + .start_all_aps = native_start_all_aps, +#endif }; static MALLOC_DEFINE(M_XENHVM, xen_hvm, Xen HVM PV Support); @@ -698,6 +704,10 @@ xen_hvm_init(enum xen_hvm_init_type init_type) setup_xen_features(); cpu_ops = xen_hvm_cpu_ops; vm_guest = VM_GUEST_XEN; +#ifdef __amd64__ + if (xen_pv_domain()) + cpu_ops.start_all_aps = xen_pv_start_all_aps; +#endif break; case XEN_HVM_INIT_RESUME: if (error != 0) diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c index d11bc1a..22fd6a6 100644 --- a/sys/x86/xen/pv.c +++ b/sys/x86/xen/pv.c @@ -34,8 +34,11 @@ __FBSDID($FreeBSD$); #include sys/kernel.h #include sys/reboot.h #include sys/systm.h +#include sys/malloc.h #include sys/lock.h #include sys/rwlock.h +#include sys/mutex.h +#include sys/smp.h #include vm/vm.h #include vm/vm_extern.h @@ -49,9 +52,13 @@ __FBSDID($FreeBSD$); #include machine/sysarch.h #include machine/clock.h #include machine/pc/bios.h +#include machine/smp.h #include xen/xen-os.h #include xen/hypervisor.h +#include xen/pv.h + +#include xen/interface/vcpu.h /* Native initial function */ extern
[PATCH v9 15/19] xen: create a Xen nexus to use in PV/PVH
Introduce a Xen specific nexus that is going to be in charge for attaching Xen specific devices. --- sys/conf/files.amd64 |1 + sys/conf/files.i386 |1 + sys/dev/xen/console/console.c |2 +- sys/dev/xen/timer/timer.c |4 +- sys/dev/xen/xenpci/xenpci.c |4 ++ sys/x86/xen/xen_nexus.c | 82 + sys/x86/xen/xenpv.c |1 + sys/xen/xenstore/xenstore.c |6 +-- 8 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 sys/x86/xen/xen_nexus.c diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index d7c98cc..f378983 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -571,3 +571,4 @@ x86/xen/xen_intr.c optionalxen | xenhvm x86/xen/pv.c optionalxenhvm x86/xen/pvcpu_enum.c optionalxenhvm x86/xen/xenpv.coptionalxenhvm +x86/xen/xen_nexus.coptionalxenhvm diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 81142e3..02887a33 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -604,3 +604,4 @@ x86/x86/delay.c standard x86/xen/hvm.c optional xenhvm x86/xen/xen_intr.c optional xen | xenhvm x86/xen/xenpv.coptional xen | xenhvm +x86/xen/xen_nexus.coptional xen | xenhvm diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c index 899dffc..91538fe 100644 --- a/sys/dev/xen/console/console.c +++ b/sys/dev/xen/console/console.c @@ -462,4 +462,4 @@ xcons_force_flush(void) } } -DRIVER_MODULE(xc, nexus, xc_driver, xc_devclass, 0, 0); +DRIVER_MODULE(xc, xenpv, xc_driver, xc_devclass, 0, 0); diff --git a/sys/dev/xen/timer/timer.c b/sys/dev/xen/timer/timer.c index 96372ab..f16f5a5 100644 --- a/sys/dev/xen/timer/timer.c +++ b/sys/dev/xen/timer/timer.c @@ -636,5 +636,5 @@ static driver_t xentimer_driver = { sizeof(struct xentimer_softc), }; -DRIVER_MODULE(xentimer, nexus, xentimer_driver, xentimer_devclass, 0, 0); -MODULE_DEPEND(xentimer, nexus, 1, 1, 1); +DRIVER_MODULE(xentimer, xenpv, xentimer_driver, xentimer_devclass, 0, 0); +MODULE_DEPEND(xentimer, xenpv, 1, 1, 1); diff --git a/sys/dev/xen/xenpci/xenpci.c b/sys/dev/xen/xenpci/xenpci.c index dd2ad92..a27b54f 100644 --- a/sys/dev/xen/xenpci/xenpci.c +++ b/sys/dev/xen/xenpci/xenpci.c @@ -270,6 +270,10 @@ xenpci_attach(device_t dev) goto errexit; } + /* Add the xenpv device so top level Xen devices can attach */ + if (BUS_ADD_CHILD(dev, 0, xenpv, 0) == NULL) + panic(xenpci: unable to add xenpv device); + return (bus_generic_attach(dev)); errexit: diff --git a/sys/x86/xen/xen_nexus.c b/sys/x86/xen/xen_nexus.c new file mode 100644 index 000..d34e333 --- /dev/null +++ b/sys/x86/xen/xen_nexus.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013 Roger Pau Monné roger@citrix.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *notice, this list of conditions and the following disclaimer in the + *documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include sys/cdefs.h +__FBSDID($FreeBSD$); + +#include sys/param.h +#include sys/bus.h +#include sys/kernel.h +#include sys/module.h +#include sys/sysctl.h +#include sys/systm.h +#include sys/smp.h + +#include machine/nexusvar.h + +#include xen/xen-os.h + +/* + * Xen nexus(4) driver. + */ +static int +nexus_xen_probe(device_t dev) +{ + if (!xen_pv_domain()) + return (ENXIO); + + return (BUS_PROBE_DEFAULT); +} + +static int +nexus_xen_attach(device_t dev) +{ + + nexus_init_resources(); + bus_generic_probe(dev); + + /* +* Explicitly add the xenpv device here. Other top level +* Xen
[PATCH v9 14/19] xen: introduce xenpv bus and a dummy pvcpu device
Since Xen PVH guests doesn't have ACPI, we need to create a dummy bus so top level Xen devices can attach to it (instead of attaching directly to the nexus) and a pvcpu device that will be used to fill the pcpu-pc_device field. --- sys/conf/files.amd64 |1 + sys/conf/files.i386 |1 + sys/x86/xen/xenpv.c | 155 ++ 3 files changed, 157 insertions(+), 0 deletions(-) create mode 100644 sys/x86/xen/xenpv.c diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index a3491da..d7c98cc 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -570,3 +570,4 @@ x86/xen/hvm.c optionalxenhvm x86/xen/xen_intr.c optionalxen | xenhvm x86/xen/pv.c optionalxenhvm x86/xen/pvcpu_enum.c optionalxenhvm +x86/xen/xenpv.coptionalxenhvm diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 790296d..81142e3 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -603,3 +603,4 @@ x86/x86/tsc.c standard x86/x86/delay.cstandard x86/xen/hvm.c optional xenhvm x86/xen/xen_intr.c optional xen | xenhvm +x86/xen/xenpv.coptional xen | xenhvm diff --git a/sys/x86/xen/xenpv.c b/sys/x86/xen/xenpv.c new file mode 100644 index 000..41d674f --- /dev/null +++ b/sys/x86/xen/xenpv.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2013 Roger Pau Monné roger@citrix.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *notice, this list of conditions and the following disclaimer in the + *documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include sys/cdefs.h +__FBSDID($FreeBSD$); + +#include sys/param.h +#include sys/systm.h +#include sys/bus.h +#include sys/kernel.h +#include sys/module.h +#include sys/pcpu.h +#include sys/smp.h + +#include xen/xen-os.h + +static int +xenpv_probe(device_t dev) +{ + + device_set_desc(dev, Xen PV bus); + device_quiet(dev); + return (0); +} + +static int +xenpv_attach(device_t dev) +{ + device_t child; + + /* +* Let our child drivers identify any child devices that they +* can find. Once that is done attach any devices that we +* found. +*/ + bus_generic_probe(dev); + bus_generic_attach(dev); + + if (!devclass_get_device(devclass_find(isa), 0)) { + child = BUS_ADD_CHILD(dev, 0, isa, 0); + if (child == NULL) + panic(xenpv_attach isa); + device_probe_and_attach(child); + } + + return 0; +} + +static device_method_t xenpv_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, xenpv_probe), + DEVMETHOD(device_attach,xenpv_attach), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume,bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_add_child,bus_generic_add_child), + + DEVMETHOD_END +}; + +static driver_t xenpv_driver = { + xenpv, + xenpv_methods, + 1, /* no softc */ +}; +static devclass_t xenpv_devclass; + +DRIVER_MODULE(xenpv, nexus, xenpv_driver, xenpv_devclass, 0, 0); + +/* + * Dummy Xen cpu device + * + * Since there's no ACPI on PVH guests, we need to create a dummy + * CPU device in order to fill the pcpu-pc_device field. + */ + +static void +xenpvcpu_identify(driver_t *driver, device_t parent) +{ + device_t child; + int i; + + /* Only attach to PV guests, HVM guests use the ACPI CPU devices */ + if (!xen_pv_domain()) + return; + + CPU_FOREACH(i) { + child = BUS_ADD_CHILD(parent, 0,
Re: [PATCH v9 19/19] isa: allow ISA bus to attach to xenpv device
On 1/2/14, 4:43 PM, Roger Pau Monne wrote: --- sys/x86/isa/isa.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/sys/x86/isa/isa.c b/sys/x86/isa/isa.c index 1a57137..9287ff2 100644 --- a/sys/x86/isa/isa.c +++ b/sys/x86/isa/isa.c @@ -241,3 +241,6 @@ isa_release_resource(device_t bus, device_t child, int type, int rid, * On this platform, isa can also attach to the legacy bus. */ DRIVER_MODULE(isa, legacy, isa_driver, isa_devclass, 0, 0); +#ifdef XENHVM +DRIVER_MODULE(isa, xenpv, isa_driver, isa_devclass, 0, 0); +#endif read all 19 patches. I'm glad you split them up.. makes it understandable.. even by me :-) no real negative comments except a question as to whether there is any noticable performance impact on real hardware? ___ freebsd-xen@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-xen To unsubscribe, send any mail to freebsd-xen-unsubscr...@freebsd.org