mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-26 16:18:31 +00:00
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.
This commit is contained in:
parent
aa389b4f8c
commit
97baeefd5b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=263006
@ -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 *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.
|
||||
@ -1685,6 +1694,26 @@ getmemsize(caddr_t kmdp, u_int64_t first)
|
||||
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 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();
|
||||
|
43
sys/x86/include/init.h
Normal file
43
sys/x86/include/init.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 Roger Pau Monné <roger.pau@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__ */
|
@ -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, 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_t xenstack)
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user