svn commit: r263006 - in head/sys: amd64/amd64 x86/include x86/xen
Roger Pau Monné
royger at FreeBSD.org
Tue Mar 11 10:15:26 UTC 2014
Author: royger
Date: Tue Mar 11 10:15:25 2014
New Revision: 263006
URL: http://svnweb.freebsd.org/changeset/base/263006
Log:
amd64: introduce hook for custom preload metadata parsers
Add hooks to amd64 in order to have diverging implementations, since
on Xen PV the metadata is passed to the kernel in a different form.
Approbed by: gibbs
Sponsored by: Citrix Systems R&D
amd64/amd64/machdep.c:
- Define init_ops for native.
- Put native code inside of native_parse_preload_data hook.
- Call the parse_preload_data in order to fill the metadata info.
x86/include/init.h:
- Declare the init_ops struct.
x86/xen/pv.c:
- Declare xen_init_ops that contains the Xen PV implementation of
init_ops.
- Implement the parse_preload_data for Xen PVH, the info is fetched
from HYPERVISOR_start_info->cmd_line as provided by Xen.
Added:
head/sys/x86/include/init.h (contents, props changed)
Modified:
head/sys/amd64/amd64/machdep.c
head/sys/x86/xen/pv.c
Modified: head/sys/amd64/amd64/machdep.c
==============================================================================
--- head/sys/amd64/amd64/machdep.c Tue Mar 11 10:13:06 2014 (r263005)
+++ head/sys/amd64/amd64/machdep.c Tue Mar 11 10:15:25 2014 (r263006)
@@ -145,6 +145,7 @@ __FBSDID("$FreeBSD$");
#include <isa/isareg.h>
#include <isa/rtc.h>
+#include <x86/init.h>
/* Sanity check for __curthread() */
CTASSERT(offsetof(struct pcpu, pc_curthread) == 0);
@@ -165,6 +166,14 @@ static int set_fpcontext(struct thread
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.
@@ -1685,6 +1694,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)
{
@@ -1709,17 +1738,7 @@ hammer_time(u_int64_t modulep, u_int64_t
*/
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();
Added: head/sys/x86/include/init.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/x86/include/init.h Tue Mar 11 10:15:25 2014 (r263006)
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2013 Roger Pau Monné <roger.pau at 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __X86_INIT_H__
+#define __X86_INIT_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;
+
+#endif /* __X86_INIT_H__ */
Modified: head/sys/x86/xen/pv.c
==============================================================================
--- head/sys/x86/xen/pv.c Tue Mar 11 10:13:06 2014 (r263005)
+++ head/sys/x86/xen/pv.c Tue Mar 11 10:15:25 2014 (r263006)
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/rwlock.h>
#include <sys/boot.h>
+#include <sys/ctype.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -47,6 +48,8 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_pager.h>
#include <vm/vm_param.h>
+#include <x86/init.h>
+
#include <xen/xen-os.h>
#include <xen/hypervisor.h>
@@ -55,6 +58,16 @@ extern u_int64_t hammer_time(u_int64_t,
/* Xen initial function */
uint64_t hammer_time_xen(start_info_t *, uint64_t);
+/*--------------------------- Forward Declarations ---------------------------*/
+static caddr_t xen_pv_parse_preload_data(u_int64_t);
+
+/*-------------------------------- Global Data -------------------------------*/
+/* Xen init_ops implementation. */
+struct init_ops xen_init_ops = {
+ .parse_preload_data = xen_pv_parse_preload_data,
+};
+
+/*-------------------------------- Xen PV init -------------------------------*/
/*
* First function called by the Xen PVH boot sequence.
*
@@ -119,6 +132,56 @@ hammer_time_xen(start_info_t *si, uint64
}
load_cr3(((uint64_t)&PT4[0]) - KERNBASE);
+ /* Set the hooks for early functions that diverge from bare metal */
+ init_ops = xen_init_ops;
+
/* Now we can jump into the native init function */
return (hammer_time(0, physfree));
}
+
+/*-------------------------------- PV specific -------------------------------*/
+/*
+ * Functions to convert the "extra" parameters passed by Xen
+ * into FreeBSD boot options.
+ */
+static void
+xen_pv_set_env(void)
+{
+ char *cmd_line_next, *cmd_line;
+ size_t env_size;
+
+ cmd_line = HYPERVISOR_start_info->cmd_line;
+ env_size = sizeof(HYPERVISOR_start_info->cmd_line);
+
+ /* Skip leading spaces */
+ for (; isspace(*cmd_line) && (env_size != 0); cmd_line++)
+ env_size--;
+
+ /* Replace ',' with '\0' */
+ for (cmd_line_next = cmd_line; strsep(&cmd_line_next, ",") != NULL;)
+ ;
+
+ init_static_kenv(cmd_line, env_size);
+}
+
+static void
+xen_pv_set_boothowto(void)
+{
+ int i;
+
+ /* get equivalents from the environment */
+ for (i = 0; howto_names[i].ev != NULL; i++) {
+ if (getenv(howto_names[i].ev) != NULL)
+ boothowto |= howto_names[i].mask;
+ }
+}
+
+static caddr_t
+xen_pv_parse_preload_data(u_int64_t modulep)
+{
+ /* Parse the extra boot information given by Xen */
+ xen_pv_set_env();
+ xen_pv_set_boothowto();
+
+ return (NULL);
+}
More information about the svn-src-head
mailing list