#define ROOTCN_SLOT_SLOT_ALLOC1 8 ///< Root of slot alloc1
#define ROOTCN_SLOT_SLOT_ALLOC2 9 ///< Root of slot alloc2
#define ROOTCN_SLOT_ARGCN 10 ///< Argcn slot in root cnode
-#define ROOTCN_SLOTS_USER 11 ///< First free slot in root cnode for user
+#define ROOTCN_SLOT_BSPKCB 11 ///< BSP KCB cap to fix reverse lookup issues
+#define ROOTCN_SLOTS_USER 12 ///< First free slot in root cnode for user
/* Size of CNodes in Root CNode if not the default size */
#define SLOT_ALLOC_CNODE_BITS (DEFAULT_CNODE_BITS * 2)
/* Initialize the location to allocate phys memory from */
bsp_init_alloc_addr = glbl_core_data->start_free_ram;
+ /* allocate initial KCB */
+ kcb_current = (struct kcb *) local_phys_to_mem(bsp_alloc_phys(sizeof(*kcb_current)));
+ assert(kcb_current);
+
/* spawn init */
init_dcb = spawn_bsp_init(BSP_INIT_MODULE_PATH, bsp_alloc_phys);
} else {
+ kcb_current = (struct kcb *)
+ local_phys_to_mem((lpaddr_t) kcb_current);
+
start_ap_signal();
// if we have a kernel control block, use it
if (kcb_current && kcb_current->is_valid) {
panic("error while mapping physical memory!");
}
- kcb_current = (struct kcb *)
- local_phys_to_mem((lpaddr_t) kcb_current);
-
/*
* Also reset the global descriptor table (GDT), so we get
* segmentation again and can catch interrupts/exceptions (the IDT
glbl_core_data->mmap_length = mb->mmap_length;
glbl_core_data->mmap_addr = mb->mmap_addr;
- extern struct kcb bspkcb;
- memset(&bspkcb, 0, sizeof(bspkcb));
- kcb_current = &bspkcb;
} else { /* No multiboot info, use the core_data struct */
struct x86_core_data *core_data =
(struct x86_core_data*)(dest - BASE_PAGE_SIZE);
#include <mdb/mdb_tree.h>
#include <trace/trace.h>
-// HACK! Remove and don't reference this, kcb points here in case we're bsp
-// This should be exposed as regular cap.
-struct kcb bspkcb;
struct kcb *kcb_current;
coreid_t my_core_id;
#endif
/* Set up root cnode and the caps it contains */
- // must be static, because this CTE will be entered into the MDB!
- // don't want this to be static, as the memory backing the data section of
- // the kernel can and will disappear when we reboot a core with a
- // different kernel but want to restore the state
+ // Has to be valid after leaving this stack frame, because this CTE will
+ // be entered into the MDB!
+ // Don't want this to be part of the data section, as the memory backing
+ // the data section of the kernel can and will disappear when we reboot a
+ // core with a different kernel but want to restore the state
struct cte *rootcn = &kcb_current->init_rootcn;
mdb_init(kcb_current);
kcb_current->is_valid = true;
rootcn);
assert(err_is_ok(err));
+ // on BSP core: Add BSP KCB to rootcn
+ if (apic_is_bsp()) {
+ // cannot use caps_create_new() here, as that would zero out KCB, so
+ // we replicate the cap initialization here.
+ struct capability bspkcb_cap;
+ memset(&bspkcb_cap, 0, sizeof(struct capability));
+ bspkcb_cap.type = ObjType_KernelControlBlock;
+ bspkcb_cap.rights = CAPRIGHTS_ALLRIGHTS;
+ bspkcb_cap.u.kernelcontrolblock.kcb = kcb_current;
+ // find slot in init rootcn
+ struct cte *bspkcb = caps_locate_slot(CNODE(rootcn), ROOTCN_SLOT_BSPKCB);
+ assert(bspkcb && bspkcb->cap.type == ObjType_Null);
+ memcpy(&bspkcb->cap, &bspkcb_cap, sizeof(struct capability));
+ }
+
// Task cnode in root cnode
st->taskcn = caps_locate_slot(CNODE(rootcn), ROOTCN_SLOT_TASKCN);
err = caps_create_new(ObjType_CNode, alloc_phys(BASE_PAGE_SIZE),
return err_push(err, INIT_ERR_COPY_KERNEL_CAP);
}
+ /* Give monitor.0 the BSP KCB capability */
+ dest.cnode = si->rootcn;
+ dest.slot = ROOTCN_SLOT_BSPKCB;
+ src.cnode = cnode_root;
+ src.slot = ROOTCN_SLOT_BSPKCB;
+ err = cap_copy(dest, src);
+ if (err_is_fail(err)) {
+ return err_push(err, INIT_ERR_COPY_KERNEL_CAP);
+ }
+
/* Give monitor the perfmon capability */
dest.cnode = si->taskcn;
dest.slot = TASKCN_SLOT_PERF_MON;