[PATCH v10 07/20] xen: implement hook to fetch e820 memory map

2014-01-14 Thread Roger Pau Monne
---
 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 b8d6dc2..64df89a 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,
 };
 
 /*
@@ -1403,21 +1407,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++) {
@@ -1434,6 +1429,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
@@ -1451,19 +1469,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 v10 06/20] xen: implement an early timer for Xen PVH

2014-01-14 Thread Roger Pau Monne
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 343f9b8..b8d6dc2 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,
 };
 
 /*
@@ -1822,10 +1824,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 v10 03/20] xen: add and enable Xen console for PVH guests

2014-01-14 Thread Roger Pau Monne
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 33fc75d..bddf021 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2493,8 +2493,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 v10 09/20] xen: add a apic_enumerator for PVH

2014-01-14 Thread Roger Pau Monne
---
 sys/conf/files.amd64 |1 +
 sys/x86/xen/pvcpu_enum.c |  136 ++
 2 files changed, 137 insertions(+), 0 deletions(-)
 create mode 100644 sys/x86/xen/pvcpu_enum.c

diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 109a796..a3491da 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -569,3 +569,4 @@ x86/x86/delay.c standard
 x86/xen/hvm.c  optionalxenhvm
 x86/xen/xen_intr.c optionalxen | xenhvm
 x86/xen/pv.c   optionalxenhvm
+x86/xen/pvcpu_enum.c   optionalxenhvm
diff --git a/sys/x86/xen/pvcpu_enum.c b/sys/x86/xen/pvcpu_enum.c
new file mode 100644
index 000..0384886
--- /dev/null
+++ b/sys/x86/xen/pvcpu_enum.c
@@ -0,0 +1,136 @@
+/*-
+ * Copyright (c) 2003 John Baldwin j...@freebsd.org
+ * 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.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *may be used to endorse or promote products derived from this software
+ *without specific prior written permission.
+ *
+ * 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/smp.h
+#include sys/pcpu.h
+#include vm/vm.h
+#include vm/pmap.h
+
+#include machine/intr_machdep.h
+#include machine/apicvar.h
+
+#include machine/cpu.h
+#include machine/smp.h
+
+#include xen/xen-os.h
+#include xen/hypervisor.h
+
+#include xen/interface/vcpu.h
+
+static int xenpv_probe(void);
+static int xenpv_probe_cpus(void);
+static int xenpv_setup_local(void);
+static int xenpv_setup_io(void);
+
+static struct apic_enumerator xenpv_enumerator = {
+   Xen PV,
+   xenpv_probe,
+   xenpv_probe_cpus,
+   xenpv_setup_local,
+   xenpv_setup_io
+};
+
+/*
+ * This enumerator will only be registered on PVH
+ */
+static int
+xenpv_probe(void)
+{
+   return (-100);
+}
+
+/*
+ * Test each possible vCPU in order to find the number of vCPUs
+ */
+static int
+xenpv_probe_cpus(void)
+{
+#ifdef SMP
+   int i, ret;
+
+   for (i = 0; i  MAXCPU; i++) {
+   ret = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
+   if (ret = 0)
+   cpu_add((i * 2), (i == 0));
+   }
+#endif
+   return (0);
+}
+
+/*
+ * Initialize the vCPU id of the BSP
+ */
+static int
+xenpv_setup_local(void)
+{
+   PCPU_SET(vcpu_id, 0);
+   return (0);
+}
+
+/*
+ * On PVH guests there's no IO APIC
+ */
+static int
+xenpv_setup_io(void)
+{
+   return (0);
+}
+
+static void
+xenpv_register(void *dummy __unused)
+{
+   if (xen_pv_domain()) {
+   apic_register_enumerator(xenpv_enumerator);
+   }
+}
+SYSINIT(xenpv_register, SI_SUB_TUNABLES - 1, SI_ORDER_FIRST, xenpv_register, 
NULL);
+
+/*
+ * Setup per-CPU vCPU IDs
+ */
+static void
+xenpv_set_ids(void *dummy)
+{
+   struct pcpu *pc;
+   int i;
+
+   CPU_FOREACH(i) {
+   pc = pcpu_find(i);
+   pc-pc_vcpu_id = i;
+   }
+}
+SYSINIT(xenpv_set_ids, SI_SUB_CPU, SI_ORDER_MIDDLE, xenpv_set_ids, NULL);
-- 
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 v10 05/20] xen: rework xen timer so it can be used early in boot process

2014-01-14 Thread Roger Pau Monne
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 v10 08/20] xen: use the same hypercall mechanism for XEN and XENHVM

2014-01-14 Thread Roger Pau Monne
---
 sys/amd64/include/xen/hypercall.h |7 ---
 sys/i386/i386/locore.s|9 +
 sys/i386/include/xen/hypercall.h  |8 
 sys/x86/xen/hvm.c |   24 ++--
 4 files changed, 19 insertions(+), 29 deletions(-)

diff --git a/sys/amd64/include/xen/hypercall.h 
b/sys/amd64/include/xen/hypercall.h
index a1b2a5c..499fb4d 100644
--- a/sys/amd64/include/xen/hypercall.h
+++ b/sys/amd64/include/xen/hypercall.h
@@ -51,15 +51,8 @@
 #define CONFIG_XEN_COMPAT  0x030002
 #define __must_check
 
-#ifdef XEN
 #define HYPERCALL_STR(name)\
call hypercall_page + (STR(__HYPERVISOR_##name) * 32)
-#else
-#define HYPERCALL_STR(name)\
-   mov $(STR(__HYPERVISOR_##name) * 32),%%eax; \
-   add hypercall_stubs(%%rip),%%rax; \
-   call *%%rax
-#endif
 
 #define _hypercall0(type, name)\
 ({ \
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index 68cb430..bd136b1 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/locore.s
@@ -898,3 +898,12 @@ done_pde:
 #endif
 
ret
+
+#ifdef XENHVM
+/* Xen Hypercall page */
+   .text
+.p2align PAGE_SHIFT, 0x90  /* Hypercall_page needs to be PAGE aligned */
+
+NON_GPROF_ENTRY(hypercall_page)
+   .skip   0x1000, 0x90/* Fill with nops */
+#endif
diff --git a/sys/i386/include/xen/hypercall.h b/sys/i386/include/xen/hypercall.h
index edc13f4..16b5ee2 100644
--- a/sys/i386/include/xen/hypercall.h
+++ b/sys/i386/include/xen/hypercall.h
@@ -39,16 +39,8 @@
 #defineENOXENSYS   38
 #define CONFIG_XEN_COMPAT  0x030002
 
-
-#if defined(XEN)
 #define HYPERCALL_STR(name) \
 call hypercall_page + (STR(__HYPERVISOR_##name) * 32)
-#else
-#define HYPERCALL_STR(name) \
-mov hypercall_stubs,%%eax;\
-add $(STR(__HYPERVISOR_##name) * 32),%%eax; \
-call *%%eax
-#endif
 
 #define _hypercall0(type, name) \
 ({  \
diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c
index b397721..9a0411e 100644
--- a/sys/x86/xen/hvm.c
+++ b/sys/x86/xen/hvm.c
@@ -157,7 +157,7 @@ DPCPU_DEFINE(xen_intr_handle_t, 
ipi_handle[nitems(xen_ipis)]);
 
 /*-- Hypervisor Access Shared Memory Regions 
-*/
 /** Hypercall table accessed via HYPERVISOR_*_op() methods. */
-char *hypercall_stubs;
+extern char *hypercall_page;
 shared_info_t *HYPERVISOR_shared_info;
 start_info_t *HYPERVISOR_start_info;
 
@@ -559,7 +559,7 @@ xen_hvm_cpuid_base(void)
  * Allocate and fill in the hypcall page.
  */
 static int
-xen_hvm_init_hypercall_stubs(void)
+xen_hvm_init_hypercall_stubs(enum xen_hvm_init_type init_type)
 {
uint32_t base, regs[4];
int i;
@@ -568,7 +568,7 @@ xen_hvm_init_hypercall_stubs(void)
if (base == 0)
return (ENXIO);
 
-   if (hypercall_stubs == NULL) {
+   if (init_type == XEN_HVM_INIT_COLD) {
do_cpuid(base + 1, regs);
printf(XEN: Hypervisor version %d.%d detected.\n,
regs[0]  16, regs[0]  0x);
@@ -578,18 +578,9 @@ xen_hvm_init_hypercall_stubs(void)
 * Find the hypercall pages.
 */
do_cpuid(base + 2, regs);
-   
-   if (hypercall_stubs == NULL) {
-   size_t call_region_size;
-
-   call_region_size = regs[0] * PAGE_SIZE;
-   hypercall_stubs = malloc(call_region_size, M_XENHVM, M_NOWAIT);
-   if (hypercall_stubs == NULL)
-   panic(Unable to allocate Xen hypercall region);
-   }
 
for (i = 0; i  regs[0]; i++)
-   wrmsr(regs[1], vtophys(hypercall_stubs + i * PAGE_SIZE) + i);
+   wrmsr(regs[1], vtophys(hypercall_page + i * PAGE_SIZE) + i);
 
return (0);
 }
@@ -692,7 +683,12 @@ xen_hvm_init(enum xen_hvm_init_type init_type)
if (init_type == XEN_HVM_INIT_CANCELLED_SUSPEND)
return;
 
-   error = xen_hvm_init_hypercall_stubs();
+   if (xen_pv_domain()) {
+   /* hypercall page is already set in the PV case */
+   error = 0;
+   } else {
+   error = xen_hvm_init_hypercall_stubs(init_type);
+   }
 
switch (init_type) {
case XEN_HVM_INIT_COLD:
-- 
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 v10 20/20] isa: allow ISA bus to attach to xenpv device

2014-01-14 Thread Roger Pau Monne
---
 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
-- 
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 v10 19/20] xen: changes to gnttab for PVH

2014-01-14 Thread Roger Pau Monne
---
 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 v10 16/20] xen: create a Xen nexus to use in PV/PVH

2014-01-14 Thread Roger Pau Monne
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   |   64 ++-
 sys/x86/xen/xen_nexus.c   |   76 +
 sys/xen/xenstore/xenstore.c   |6 +---
 7 files changed, 85 insertions(+), 69 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..e334051 100644
--- a/sys/dev/xen/xenpci/xenpci.c
+++ b/sys/dev/xen/xenpci/xenpci.c
@@ -51,8 +51,6 @@ __FBSDID($FreeBSD$);
 
 extern void xen_intr_handle_upcall(struct trapframe *trap_frame);
 
-static device_t nexus;
-
 /*
  * This is used to find our platform device instance.
  */
@@ -188,36 +186,6 @@ xenpci_alloc_space(size_t sz, vm_paddr_t *pa)
}
 }
 
-static struct resource *
-xenpci_alloc_resource(device_t dev, device_t child, int type, int *rid,
-u_long start, u_long end, u_long count, u_int flags)
-{
-   return (BUS_ALLOC_RESOURCE(nexus, child, type, rid, start,
-   end, count, flags));
-}
-
-
-static int
-xenpci_release_resource(device_t dev, device_t child, int type, int rid,
-struct resource *r)
-{
-   return (BUS_RELEASE_RESOURCE(nexus, child, type, rid, r));
-}
-
-static int
-xenpci_activate_resource(device_t dev, device_t child, int type, int rid,
-struct resource *r)
-{
-   return (BUS_ACTIVATE_RESOURCE(nexus, child, type, rid, r));
-}
-
-static int
-xenpci_deactivate_resource(device_t dev, device_t child, int type,
-int rid, struct resource *r)
-{
-   return (BUS_DEACTIVATE_RESOURCE(nexus, child, type, rid, r));
-}
-
 /*
  * Probe - just check device ID.
  */
@@ -229,7 +197,7 @@ xenpci_probe(device_t dev)
return (ENXIO);
 
device_set_desc(dev, Xen Platform Device);
-   return (bus_generic_probe(dev));
+   return (BUS_PROBE_DEFAULT);
 }
 
 /*
@@ -239,20 +207,8 @@ static int
 xenpci_attach(device_t dev)
 {
struct xenpci_softc *scp = device_get_softc(dev);
-   devclass_t dc;
int error;
 
-   /*
-* Find and record nexus0.  Since we are not really on the
-* PCI bus, all resource operations are directed to nexus
-* instead of through our parent.
-*/
-   if ((dc = devclass_find(nexus))  == 0
-|| (nexus = devclass_get_device(dc, 0)) == 0) {
-   device_printf(dev, unable to find nexus.);
-   return (ENOENT);
-   }
-
error = xenpci_allocate_resources(dev);
if (error) {
device_printf(dev, xenpci_allocate_resources failed(%d).\n,
@@ -270,7 +226,7 @@ xenpci_attach(device_t dev)
goto errexit;
}
 
-   return (bus_generic_attach(dev));
+   return (0);
 
 errexit:
/*
@@ -309,16 +265,10 @@ xenpci_detach(device_t dev)
 }
 
 static int
-xenpci_suspend(device_t dev)
-{
-   return (bus_generic_suspend(dev));
-}
-
-static int
 xenpci_resume(device_t dev)
 {
xen_hvm_set_callback(dev);
-   return (bus_generic_resume(dev));
+   return (0);
 }
 

[PATCH v10 14/20] xen: introduce xenpv bus and a dummy pvcpu device

2014-01-14 Thread Roger Pau Monne
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  |  128 ++
 3 files changed, 130 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..e1282cf
--- /dev/null
+++ b/sys/x86/xen/xenpv.c
@@ -0,0 +1,128 @@
+/*
+ * 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 devclass_t xenpv_devclass;
+
+static void
+xenpv_identify(driver_t *driver, device_t parent)
+{
+   if (!xen_domain())
+   return;
+
+   /* Make sure there's only one xenpv device. */
+   if (devclass_get_device(xenpv_devclass, 0))
+   return;
+
+   /*
+* Use a high order number so xenpv is attached after
+* xenpci on HVM guests.
+*/
+   BUS_ADD_CHILD(parent, 200, xenpv, 0);
+}
+
+static int
+xenpv_probe(device_t dev)
+{
+
+   device_set_desc(dev, Xen PV bus);
+   device_quiet(dev);
+   return (BUS_PROBE_NOWILDCARD);
+}
+
+static int
+xenpv_attach(device_t dev)
+{
+   device_t child;
+
+   if (xen_hvm_domain()) {
+   device_t xenpci;
+   devclass_t dc;
+
+   /* Make sure xenpci has been attached */
+   dc = devclass_find(xenpci);
+   if (dc == NULL)
+   panic(unable to find xenpci devclass);
+
+   xenpci = devclass_get_device(dc, 0);
+   if (xenpci == NULL)
+   panic(unable to find xenpci device);
+
+   if (!device_is_attached(xenpci))
+   panic(trying to attach xenpv before xenpci);
+   }
+
+   /*
+* 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 */
+   

[PATCH v10 10/20] xen: add hook for AP bootstrap memory reservation

2014-01-14 Thread Roger Pau Monne
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 64df89a..3a2db30 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
 };
 
 /*
@@ -1492,7 +1495,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 v10 15/20] xen: create a PV CPU device for PVH guests

2014-01-14 Thread Roger Pau Monne
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.
---
 sys/conf/files|1 +
 sys/dev/xen/pvcpu/pvcpu.c |  101 +
 2 files changed, 102 insertions(+), 0 deletions(-)
 create mode 100644 sys/dev/xen/pvcpu/pvcpu.c

diff --git a/sys/conf/files b/sys/conf/files
index bddf021..178d5e2 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2500,6 +2500,7 @@ dev/xen/netback/netback.c optional xen | xenhvm
 dev/xen/netfront/netfront.coptional xen | xenhvm
 dev/xen/xenpci/xenpci.coptional xenpci
 dev/xen/timer/timer.c  optional xen | xenhvm
+dev/xen/pvcpu/pvcpu.c  optional xen | xenhvm
 dev/xl/if_xl.c optional xl pci
 dev/xl/xlphy.c optional xl pci
 fs/deadfs/dead_vnops.c standard
diff --git a/sys/dev/xen/pvcpu/pvcpu.c b/sys/dev/xen/pvcpu/pvcpu.c
new file mode 100644
index 000..7f3697c
--- /dev/null
+++ b/sys/dev/xen/pvcpu/pvcpu.c
@@ -0,0 +1,101 @@
+/*
+ * 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
+
+/*
+ * 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, pvcpu, i);
+   if (child == NULL)
+   panic(xenpvcpu_identify add pvcpu);
+   }
+}
+
+static int
+xenpvcpu_probe(device_t dev)
+{
+
+   device_set_desc(dev, Xen PV CPU);
+   return (BUS_PROBE_NOWILDCARD);
+}
+
+static int
+xenpvcpu_attach(device_t dev)
+{
+   struct pcpu *pc;
+   int cpu;
+
+   cpu = device_get_unit(dev);
+   pc = pcpu_find(cpu);
+   pc-pc_device = dev;
+   return (0);
+}
+
+static device_method_t xenpvcpu_methods[] = {
+   DEVMETHOD(device_identify, xenpvcpu_identify),
+   DEVMETHOD(device_probe, xenpvcpu_probe),
+   DEVMETHOD(device_attach, xenpvcpu_attach),
+
+   DEVMETHOD_END
+};
+
+static driver_t xenpvcpu_driver = {
+   pvcpu,
+   xenpvcpu_methods,
+   0,
+};
+
+devclass_t xenpvcpu_devclass;
+
+DRIVER_MODULE(xenpvcpu, xenpv, xenpvcpu_driver, xenpvcpu_devclass, 0, 0);
+MODULE_DEPEND(xenpvcpu, xenpv, 1, 1, 1);
-- 
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 v10 13/20] xen: introduce flag to disable the local apic

2014-01-14 Thread Roger Pau Monne
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 17e957d..cea0306 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 v10 17/20] xen: add shutdown hook for PVH

2014-01-14 Thread Roger Pau Monne
Add the PV shutdown hook to PVH.
---
 sys/dev/xen/control/control.c |   37 ++---
 1 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/sys/dev/xen/control/control.c b/sys/dev/xen/control/control.c
index bc0609d..78894ba 100644
--- a/sys/dev/xen/control/control.c
+++ b/sys/dev/xen/control/control.c
@@ -316,21 +316,6 @@ xctrl_suspend()
EVENTHANDLER_INVOKE(power_resume);
 }
 
-static void
-xen_pv_shutdown_final(void *arg, int howto)
-{
-   /*
-* Inform the hypervisor that shutdown is complete.
-* This is not necessary in HVM domains since Xen
-* emulates ACPI in that mode and FreeBSD's ACPI
-* support will request this transition.
-*/
-   if (howto  (RB_HALT | RB_POWEROFF))
-   HYPERVISOR_shutdown(SHUTDOWN_poweroff);
-   else
-   HYPERVISOR_shutdown(SHUTDOWN_reboot);
-}
-
 #else
 
 /* HVM mode suspension. */
@@ -440,6 +425,21 @@ xctrl_crash()
panic(Xen directed crash);
 }
 
+static void
+xen_pv_shutdown_final(void *arg, int howto)
+{
+   /*
+* Inform the hypervisor that shutdown is complete.
+* This is not necessary in HVM domains since Xen
+* emulates ACPI in that mode and FreeBSD's ACPI
+* support will request this transition.
+*/
+   if (howto  (RB_HALT | RB_POWEROFF))
+   HYPERVISOR_shutdown(SHUTDOWN_poweroff);
+   else
+   HYPERVISOR_shutdown(SHUTDOWN_reboot);
+}
+
 /*-- Event Reception 
-*/
 static void
 xctrl_on_watch_event(struct xs_watch *watch, const char **vec, unsigned int 
len)
@@ -522,10 +522,9 @@ xctrl_attach(device_t dev)
xctrl-xctrl_watch.callback_data = (uintptr_t)xctrl;
xs_register_watch(xctrl-xctrl_watch);
 
-#ifndef XENHVM
-   EVENTHANDLER_REGISTER(shutdown_final, xen_pv_shutdown_final, NULL,
- SHUTDOWN_PRI_LAST);
-#endif
+   if (xen_pv_domain())
+   EVENTHANDLER_REGISTER(shutdown_final, xen_pv_shutdown_final, 
NULL,
+ SHUTDOWN_PRI_LAST);
 
return (0);
 }
-- 
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


Re: [PATCH v10 05/20] xen: rework xen timer so it can be used early in boot process

2014-01-14 Thread Will Andrews
Looks good to me.  It appears to go with your PATCH v10 06/20, and
your commit log should note the dependency directly.

Thanks!
--Will.

On Tue, Jan 14, 2014 at 7:59 AM, Roger Pau Monne roger@citrix.com wrote:
 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-curr...@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/freebsd-current
 To unsubscribe, send any mail to freebsd-current-unsubscr...@freebsd.org
___
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 v10 11/20] xen: changes to hvm code in order to support PVH guests

2014-01-14 Thread Roger Pau Monne
On PVH we don't need to init the shared info page, or disable emulated
devices. Also, make sure PV IPIs are set before starting the APs.
---
 sys/x86/xen/hvm.c |   17 -
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c
index 9a0411e..fb1ed79 100644
--- a/sys/x86/xen/hvm.c
+++ b/sys/x86/xen/hvm.c
@@ -523,7 +523,7 @@ xen_setup_cpus(void)
 {
int i;
 
-   if (!xen_hvm_domain() || !xen_vector_callback_enabled)
+   if (!xen_vector_callback_enabled)
return;
 
 #ifdef __amd64__
@@ -712,10 +712,13 @@ xen_hvm_init(enum xen_hvm_init_type init_type)
}
 
xen_vector_callback_enabled = 0;
-   xen_domain_type = XEN_HVM_DOMAIN;
-   xen_hvm_init_shared_info_page();
xen_hvm_set_callback(NULL);
-   xen_hvm_disable_emulated_devices();
+
+   if (!xen_pv_domain()) {
+   xen_domain_type = XEN_HVM_DOMAIN;
+   xen_hvm_init_shared_info_page();
+   xen_hvm_disable_emulated_devices();
+   }
 } 
 
 void
@@ -746,6 +749,9 @@ xen_set_vcpu_id(void)
struct pcpu *pc;
int i;
 
+   if (!xen_hvm_domain())
+   return;
+
/* Set vcpu_id to acpi_id */
CPU_FOREACH(i) {
pc = pcpu_find(i);
@@ -789,7 +795,8 @@ xen_hvm_cpu_init(void)
 
 SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_sysinit, 
NULL);
 #ifdef SMP
-SYSINIT(xen_setup_cpus, SI_SUB_SMP, SI_ORDER_FIRST, xen_setup_cpus, NULL);
+/* We need to setup IPIs before APs are started */
+SYSINIT(xen_setup_cpus, SI_SUB_SMP-1, SI_ORDER_FIRST, xen_setup_cpus, NULL);
 #endif
 SYSINIT(xen_hvm_cpu_init, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_cpu_init, NULL);
 SYSINIT(xen_set_vcpu_id, SI_SUB_CPU, SI_ORDER_ANY, xen_set_vcpu_id, NULL);
-- 
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 v10 12/20] xen: add a hook to perform AP startup

2014-01-14 Thread Roger Pau Monne
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 4af4f8f..17e957d 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 3c5d5df..98dc3e0 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 

Re: [PATCH v10 14/20] xen: introduce xenpv bus and a dummy pvcpu device

2014-01-14 Thread Roger Pau Monné
On 14/01/14 16:41, Julien Grall wrote:
 On 01/14/2014 02:59 PM, Roger Pau Monne wrote:
 +static int
 +xenpv_attach(device_t dev)
 +{
 +device_t child;
 +
 +if (xen_hvm_domain()) {
 +device_t xenpci;
 +devclass_t dc;
 +
 +/* Make sure xenpci has been attached */
 +dc = devclass_find(xenpci);
 +if (dc == NULL)
 +panic(unable to find xenpci devclass);
 +
 +xenpci = devclass_get_device(dc, 0);
 +if (xenpci == NULL)
 +panic(unable to find xenpci device);
 +
 +if (!device_is_attached(xenpci))
 +panic(trying to attach xenpv before xenpci);
 +}
 
 Can you use the identify method to add the xenpci device?

I don't think so, xenpci is a pci device, it is detected and plugged by
the pci bus code.

 As I said earlier, I will reuse this code for ARM guest and this device
 is not used on this architecture.

You could move this chunk of code (the check for xenpci) to a static
inline function and make it a noop for ARM.

___
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


Re: [PATCH v10 14/20] xen: introduce xenpv bus and a dummy pvcpu device

2014-01-14 Thread Julien Grall
On 01/14/2014 04:08 PM, Roger Pau Monné wrote:
 On 14/01/14 16:41, Julien Grall wrote:
 On 01/14/2014 02:59 PM, Roger Pau Monne wrote:
 +static int
 +xenpv_attach(device_t dev)
 +{
 +   device_t child;
 +
 +   if (xen_hvm_domain()) {
 +   device_t xenpci;
 +   devclass_t dc;
 +
 +   /* Make sure xenpci has been attached */
 +   dc = devclass_find(xenpci);
 +   if (dc == NULL)
 +   panic(unable to find xenpci devclass);
 +
 +   xenpci = devclass_get_device(dc, 0);
 +   if (xenpci == NULL)
 +   panic(unable to find xenpci device);
 +
 +   if (!device_is_attached(xenpci))
 +   panic(trying to attach xenpv before xenpci);
 +   }

 Can you use the identify method to add the xenpci device?
 
 I don't think so, xenpci is a pci device, it is detected and plugged by
 the pci bus code.

Oups, I though you are trying to add the device. In this case, the check
seems pointless. In which case the xenpci couldn't exist?

-- 
Julien Grall
___
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

Re: [PATCH v10 14/20] xen: introduce xenpv bus and a dummy pvcpu device

2014-01-14 Thread Julien Grall
On 01/14/2014 04:20 PM, Roger Pau Monné wrote:
 On 14/01/14 17:14, Julien Grall wrote:
 On 01/14/2014 04:08 PM, Roger Pau Monné wrote:
 On 14/01/14 16:41, Julien Grall wrote:
 On 01/14/2014 02:59 PM, Roger Pau Monne wrote:
 +static int
 +xenpv_attach(device_t dev)
 +{
 + device_t child;
 +
 + if (xen_hvm_domain()) {
 + device_t xenpci;
 + devclass_t dc;
 +
 + /* Make sure xenpci has been attached */
 + dc = devclass_find(xenpci);
 + if (dc == NULL)
 + panic(unable to find xenpci devclass);
 +
 + xenpci = devclass_get_device(dc, 0);
 + if (xenpci == NULL)
 + panic(unable to find xenpci device);
 +
 + if (!device_is_attached(xenpci))
 + panic(trying to attach xenpv before xenpci);
 + }

 Can you use the identify method to add the xenpci device?

 I don't think so, xenpci is a pci device, it is detected and plugged by
 the pci bus code.

 Oups, I though you are trying to add the device. In this case, the check
 seems pointless. In which case the xenpci couldn't exist?
 
 It's just a belt and suspenders, if we attach the xenpv bus without
 xenpci being attached first a bunch of things are going to fail, I
 though it might be best to print a clear error message about what went
 wrong in order to help debug it.

I only see one place which could failed, and we are already protected.
It's when we are trying to allocate space from grant-table via
xenpci_alloc_space.

I think this error should be enough to understand the problem. At the
same time, it's the same things with xenstore. If grant-table
initialization has failed, an error message is just printed and FreeBSD
will likely failed later when it will try to initialized the PV disk.

-- 
Julien Grall
___
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

[RFC] Add support for Xen ARM guest on FreeBSD

2014-01-14 Thread Julien Grall
Hello,

During the last couple of months I have been working on porting FreeBSD on
Xen on ARM.

It's my first big project on FreeBSD and I'm not sure if I have cc the right
MLs and people. If not, could somebody point me to the right email address?

With this patch series I'm able to boot FreeBSD with a single VCPU on every
32 bits platform supported by Xen.

The patch series is divided in 5 parts:
* #1-#12: Clean up and bug fix with some options
* #13-#17: Update the Xen interface to Xen 4.4 and fix compilation
* #18-#32: Update Xen code to support ARM guest
* #33-#38: Update ARM code to support Xen guest
* #39-#40: Add platform code to support ARM guest

I have pushed a branch on my git based on Royger's pvh work version 10:
git clone git://xenbits.xen.org/people/julieng/freebsd.git -b xen-arm

http://xenbits.xen.org/gitweb/?p=people/julieng/freebsd.git;a=shortlog;h=refs/heads/xen-arm

If needed, I can send the patch one by one the different mailing list.

This new support brings 2 open questions (for both Xen and FreeBSD community).
When a new guest is created, the toolstack will generated a device tree which
will contains:
- The amount of memory
- The description of the platform (gic, timer, hypervisor node)
- PSCI node for SMP bringup

Until now, Xen on ARM supported only Linux-based OS. When the support of
device tree was added in Xen for guest, we chose to use Linux device tree
bindings (gic, timer,...). It seems that FreeBSD choose a different way to
implement device tree:
- strictly respect ePAR (for interrupt-parent property)
- gic bindings different (only 1 interrupt cell)

I would like to come with a common device tree specification (bindings, ...)
across every operating system. I know the Linux community is working on having
a device tree bindings out of the kernel tree. Does FreeBSD community plan to
work with Linux community for this purpose?

As specified early, the device tree can vary accross Xen version and user input
(eg the memory). I have noticed few places (mainly the timer) where the IRQs
number are harcoded.

In the long-term, it would be nice to see FreeBSD booting out-of-box (eg the
device tree is directly provided by the board firmware). I plan to add support
for Device Tree loading via Linux Boot ABI, it the way that Xen use to boot a
new guest.

The second question is related to memory attribute for page table. The early
page table setup by FreeBSD are using Write-Through memory attribute which
result to a likely random (not every time the same place) crash before the
real page table are initialized.
Replacing Write-Through by Write-Back made FreeBSD boot correctly. Even today,
I have no idea if it's a requirement from Xen or a bug (either in Xen or
FreeBSD).

The code is taking its first faltering steps, therefore the TODO is quite big:
- Try the code on x86 architecture. I did lots of rework for the event
channels code and didn't even try to compile
- Clean up event channel code
- Clean up xen control code
- Add support for Device Tree loading via Linux Boot ABI
- Fixing crashing on userspace. Could be related to the patch
series arm SMP on Cortex-A15
- Add guest SMP support
- DOM0 support?

Any help, comments, questions are welcomed.

Sincerely yours,

= Instruction to test FreeBSD on Xen on ARM ===

Xen upstream tree doesn't fully support ELF loading for ARM. You will need to
recompile the tools with the following 2 patches:
- https://patches.linaro.org/8/
- https://patches.linaro.org/7/

To compile and boot Xen on your board, you can refer to the wiki page:
http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions

The instruction to compile FreeBSD for Xen on ARM:
$ truncate -s 512 xenvm.img
$ sudo mdconfig -f xenvm.img -u0
$ sudo newfs /dev/md0
$ sudo mount /dev/md0 /mnt

$ sudo make TARGET_ARCH=armv6 kernel-toolchain
$ sudo make TARGET_ARCH=armv6 KERNCONF=XENHVM buildkernel
$ sudo make TARGET_ARCH=armv6 buildworld
$ sudo make TARGET_ARCH=armv6 DESTDIR=/mnt installworld distribution

$ echo /dev/xbd0   /   ufs rw  1   1  /mnt/etc/fstab
$ vi /mnt/etc/ttys (add the line 'xc0 /usr/libexec/getty Pc xterm on secure)

$ sudo umount /mnt
$ sudo mdconfig -d u0

Then you can copy the rootfs and the kernel to DOM 0 on your board.

To boot the a FreeBSD your will required the following configuration file
$ cat freebsd.xl
kernel=kernel
memory=64
name=freebsd
vcpus=1
autoballon=off
disk=[ 'phy:/dev/loop0,xvda,w' ]
$ losetup /dev/loop0 xenvm.img
$ xl create freebsd.xl
$ xl console freebsd

Julien Grall (40):
  xen/netfront: Don't need to include machine/intr_machdep.h
  xen/blkfront: Don't need to include machine/intr_machdep.h
  xen/control: Remove include machine/intr_machdep.h
  xen: Define xen_intr_handle_upcall in common headers
  xen: Remove 

Re: [RFC] Add support for Xen ARM guest on FreeBSD

2014-01-14 Thread Warner Losh

On Jan 14, 2014, at 2:01 PM, Julien Grall wrote:
 This new support brings 2 open questions (for both Xen and FreeBSD community).
 When a new guest is created, the toolstack will generated a device tree which
 will contains:
   - The amount of memory
   - The description of the platform (gic, timer, hypervisor node)
   - PSCI node for SMP bringup
 
 Until now, Xen on ARM supported only Linux-based OS. When the support of
 device tree was added in Xen for guest, we chose to use Linux device tree
 bindings (gic, timer,...). It seems that FreeBSD choose a different way to
 implement device tree:
   - strictly respect ePAR (for interrupt-parent property)
   - gic bindings different (only 1 interrupt cell)
 
 I would like to come with a common device tree specification (bindings, ...)
 across every operating system. I know the Linux community is working on having
 a device tree bindings out of the kernel tree. Does FreeBSD community plan to
 work with Linux community for this purpose?

We generally try to follow the common definitions for the FDT stuff. There are 
a few cases where we either lack the feature set of Linux, or where the Linux 
folks are moving quickly and changing the underlying definitions where we wait 
for the standards to mature before we implement. In some cases, where maturity 
hasn't happened, or where the bindings are overly Linux centric (which in 
theory they aren't supposed to be, but sometimes wind up that way). where we've 
not implemented things.

 As specified early, the device tree can vary accross Xen version and user 
 input
 (eg the memory). I have noticed few places (mainly the timer) where the IRQs
 number are harcoded.

These cases should be viewed as bugs in FreeBSD, I believe. One of the goals 
that has wide support, at leas tin theory, is that we can boot with an 
unaltered Linux FDT. This goal is some time in the future.

 In the long-term, it would be nice to see FreeBSD booting out-of-box (eg the
 device tree is directly provided by the board firmware). I plan to add support
 for Device Tree loading via Linux Boot ABI, it the way that Xen use to boot a
 new guest.

That would be most welcome.

 The second question is related to memory attribute for page table. The early
 page table setup by FreeBSD are using Write-Through memory attribute which
 result to a likely random (not every time the same place) crash before the
 real page table are initialized.
 Replacing Write-Through by Write-Back made FreeBSD boot correctly. Even today,
 I have no idea if it's a requirement from Xen or a bug (either in Xen or
 FreeBSD).

There were some problems with pages being setup improperly for the mutexes to 
operate properly. Have you confirmed this on a recent version of FreeBSD?

 The code is taking its first faltering steps, therefore the TODO is quite big:
   - Try the code on x86 architecture. I did lots of rework for the event
   channels code and didn't even try to compile
   - Clean up event channel code
   - Clean up xen control code
   - Add support for Device Tree loading via Linux Boot ABI
   - Fixing crashing on userspace. Could be related to the patch
   series arm SMP on Cortex-A15
   - Add guest SMP support
   - DOM0 support?
 
 Any help, comments, questions are welcomed.

I think this is great! We'd love to work with you to make this happen.

Warner

 Sincerely yours,
 
 = Instruction to test FreeBSD on Xen on ARM ===
[trimmed]
___
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