Factored out IPI sending invocations to their own cap instead of kernel cap.
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Fri, 21 Nov 2014 13:54:17 +0000 (14:54 +0100)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Fri, 21 Nov 2014 14:34:15 +0000 (15:34 +0100)
capabilities/caps.hl
if/monitor_blocking.if
include/arch/x86_32/barrelfish/invocations_arch.h
include/arch/x86_64/barrelfish/invocations_arch.h
include/barrelfish_kpi/capabilities.h
kernel/arch/x86_32/syscall.c
kernel/arch/x86_64/syscall.c
kernel/capabilities.c
usr/drivers/cpuboot/main.c
usr/drivers/cpuboot/x86boot.c
usr/monitor/monitor_rpc_server.c

index b01be0b..6ffcc4a 100644 (file)
@@ -287,3 +287,5 @@ cap KernelControlBlock from RAM {
     /* base page size for now so we can map the kcb in boot driver */
     size_bits { kcb_size };
 };
+
+cap IPI is_always_copy {};
index d8d432c..73f40c3 100644 (file)
@@ -59,8 +59,8 @@ interface monitor_blocking "The monitor to client RPC interface" {
     /* Retrieve local arch-specific core ID (e.g. APIC ID on x86)*/
     rpc get_arch_core_id(out uintptr id);
 
-    /* Scary */
-    rpc get_kernel_cap(out cap cap);
+    /* get cap that can be used to send IPIs */
+    rpc get_ipi_cap(out cap cap);
 
     rpc forward_kcb_request(in coreid destination, in cap kcb, out errval err);
 
index 25d345d..c4e914d 100644 (file)
@@ -612,23 +612,23 @@ static inline errval_t invoke_idcap_identify(struct capref idcap,
     return sysret.error;
 }
 
-static inline errval_t invoke_send_init_ipi(struct capref kernel_cap, coreid_t core_id)
+static inline errval_t invoke_send_init_ipi(struct capref ipi_cap, coreid_t core_id)
 {
-    uint8_t invoke_bits = get_cap_valid_bits(kernel_cap);
-    capaddr_t invoke_cptr = get_cap_addr(kernel_cap) >> (CPTR_BITS - invoke_bits);
+    uint8_t invoke_bits = get_cap_valid_bits(ipi_cap);
+    capaddr_t invoke_cptr = get_cap_addr(ipi_cap) >> (CPTR_BITS - invoke_bits);
 
     return
-        syscall3((invoke_bits << 16) | (KernelCmd_Init_IPI_Send << 8) | SYSCALL_INVOKE,
+        syscall3((invoke_bits << 16) | (IPICmd_Send_Init << 8) | SYSCALL_INVOKE,
                  invoke_cptr, (uintptr_t) core_id).error;
 }
 
-static inline errval_t invoke_send_start_ipi(struct capref kernel_cap, coreid_t core_id, forvaddr_t entry)
+static inline errval_t invoke_send_start_ipi(struct capref ipi_cap, coreid_t core_id, forvaddr_t entry)
 {
-    uint8_t invoke_bits = get_cap_valid_bits(kernel_cap);
-    capaddr_t invoke_cptr = get_cap_addr(kernel_cap) >> (CPTR_BITS - invoke_bits);
+    uint8_t invoke_bits = get_cap_valid_bits(ipi_cap);
+    capaddr_t invoke_cptr = get_cap_addr(ipi_cap) >> (CPTR_BITS - invoke_bits);
 
     return
-        syscall4((invoke_bits << 16) | (KernelCmd_Start_IPI_Send << 8) | SYSCALL_INVOKE,
+        syscall4((invoke_bits << 16) | (IPICmd_Send_Start << 8) | SYSCALL_INVOKE,
                  invoke_cptr, (uintptr_t) core_id, (uintptr_t) entry).error;
 
 }
@@ -641,4 +641,4 @@ static inline errval_t invoke_get_global_paddr(struct capref kernel_cap, genpadd
     }
 
     return sr.error;
-}
\ No newline at end of file
+}
index d4f7b7b..84389b9 100644 (file)
@@ -423,15 +423,15 @@ static inline errval_t invoke_idcap_identify(struct capref idcap,
     return sysret.error;
 }
 
-static inline errval_t invoke_send_init_ipi(struct capref kernel_cap, coreid_t core_id)
+static inline errval_t invoke_send_init_ipi(struct capref ipi_cap, coreid_t core_id)
 {
-    return cap_invoke2(kernel_cap, KernelCmd_Init_IPI_Send,
+    return cap_invoke2(ipi_cap, IPICmd_Send_Init,
                        core_id).error;
 }
 
-static inline errval_t invoke_send_start_ipi(struct capref kernel_cap, coreid_t core_id, forvaddr_t entry)
+static inline errval_t invoke_send_start_ipi(struct capref ipi_cap, coreid_t core_id, forvaddr_t entry)
 {
-    return cap_invoke3(kernel_cap, KernelCmd_Start_IPI_Send,
+    return cap_invoke3(ipi_cap, IPICmd_Send_Start,
                        core_id, entry).error;
 }
 
index 38839af..f19c555 100644 (file)
@@ -50,7 +50,7 @@ struct dcb;
 
 static inline bool type_is_vnode(enum objtype type)
 {
-    STATIC_ASSERT(26 == ObjType_Num, "Check VNode definitions");
+    STATIC_ASSERT(27 == ObjType_Num, "Check VNode definitions");
 
     return (type == ObjType_VNode_x86_64_pml4 ||
             type == ObjType_VNode_x86_64_pdpt ||
@@ -74,7 +74,7 @@ static inline bool type_is_vnode(enum objtype type)
 static inline size_t vnode_objbits(enum objtype type)
 {
     // This function should be emitted by hamlet or somesuch.
-    STATIC_ASSERT(26 == ObjType_Num, "Check VNode definitions");
+    STATIC_ASSERT(27 == ObjType_Num, "Check VNode definitions");
 
     if (type == ObjType_VNode_x86_64_pml4 ||
         type == ObjType_VNode_x86_64_pdpt ||
@@ -106,7 +106,7 @@ static inline size_t vnode_objbits(enum objtype type)
  */
 static inline size_t vnode_entry_bits(enum objtype type) {
     // This function should be emitted by hamlet or somesuch.
-    STATIC_ASSERT(26 == ObjType_Num, "Check VNode definitions");
+    STATIC_ASSERT(27 == ObjType_Num, "Check VNode definitions");
 
     if (type == ObjType_VNode_x86_64_pml4 ||
         type == ObjType_VNode_x86_64_pdpt ||
@@ -189,9 +189,7 @@ enum kernel_cmd {
     KernelCmd_Spawn_SCC_Core,
     KernelCmd_IPI_Register,
     KernelCmd_IPI_Delete,
-    KernelCmd_Start_IPI_Send,     ///< Send Startup IPI to a destination core
-    KernelCmd_Init_IPI_Send,      ///< Send Init IPI to a destination core
-    KernelCmd_GetGlobalPhys,      ///< Get physical address of kernel variable struct global;
+    KernelCmd_GetGlobalPhys,
     KernelCmd_Add_kcb,            ///< add extra kcb to be scheduled
     KernelCmd_Remove_kcb,         ///< remove kcb from scheduling ring
     KernelCmd_Suspend_kcb_sched,  ///< suspend/resume kcb scheduler
@@ -265,6 +263,14 @@ enum id_cmd {
 };
 
 /**
+ * IPI capability commands
+ */
+
+enum ipi_cmd {
+    IPICmd_Send_Start,     ///< Send Startup IPI to a destination core
+    IPICmd_Send_Init,      ///< Send Init IPI to a destination core
+};
+/**
  * Maximum command ordinal.
  */
 #define CAP_MAX_CMD KernelCmd_Count
index b2bdf8b..6a5d45e 100644 (file)
@@ -840,13 +840,15 @@ static invocation_handler_t invocations[ObjType_Num][CAP_MAX_CMD] = {
         [KernelCmd_IPI_Register] = kernel_ipi_register,
         [KernelCmd_IPI_Delete]   = kernel_ipi_delete,
 #endif
-        [KernelCmd_Start_IPI_Send] = kernel_send_start_ipi,
-        [KernelCmd_Init_IPI_Send] = kernel_send_init_ipi,
         [KernelCmd_GetGlobalPhys] = kernel_get_global_phys,
         [KernelCmd_Add_kcb]      = kernel_add_kcb,
         [KernelCmd_Remove_kcb]   = kernel_remove_kcb,
         [KernelCmd_Suspend_kcb_sched]   = kernel_suspend_kcb_sched
     },
+    [ObjType_IPI] = {
+        [IPICmd_Send_Start] = kernel_send_start_ipi,
+        [IPICmd_Send_Init] = kernel_send_init_ipi,
+    },
     [ObjType_IRQTable] = {
         [IRQTableCmd_Alloc] = handle_irq_table_alloc,
         [IRQTableCmd_Set] = handle_irq_table_set,
index 86e9634..d7afcd4 100644 (file)
@@ -913,13 +913,15 @@ static invocation_handler_t invocations[ObjType_Num][CAP_MAX_CMD] = {
         [KernelCmd_Sync_timer]   = monitor_handle_sync_timer,
         [KernelCmd_IPI_Register] = kernel_ipi_register,
         [KernelCmd_IPI_Delete]   = kernel_ipi_delete,
-        [KernelCmd_Start_IPI_Send] = kernel_send_start_ipi,
-        [KernelCmd_Init_IPI_Send] = kernel_send_init_ipi,
         [KernelCmd_GetGlobalPhys] = kernel_get_global_phys,
         [KernelCmd_Add_kcb]      = kernel_add_kcb,
         [KernelCmd_Remove_kcb]   = kernel_remove_kcb,
         [KernelCmd_Suspend_kcb_sched]   = kernel_suspend_kcb_sched,
     },
+    [ObjType_IPI] = {
+        [IPICmd_Send_Start] = kernel_send_start_ipi,
+        [IPICmd_Send_Init] = kernel_send_init_ipi,
+    },
     [ObjType_IRQTable] = {
         [IRQTableCmd_Alloc] = handle_irq_table_alloc,
         [IRQTableCmd_Set] = handle_irq_table_set,
index 11f79b2..ee9c32e 100644 (file)
@@ -81,7 +81,7 @@ static errval_t set_cap(struct capability *dest, struct capability *src)
 
 // If you create more capability types you need to deal with them
 // in the table below.
-STATIC_ASSERT(26 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(27 == ObjType_Num, "Knowledge of all cap types");
 
 static size_t caps_numobjs(enum objtype type, uint8_t bits, uint8_t objbits)
 {
@@ -143,6 +143,7 @@ static size_t caps_numobjs(enum objtype type, uint8_t bits, uint8_t objbits)
     case ObjType_Notify_RCK:
     case ObjType_Notify_IPI:
     case ObjType_PerfMon:
+    case ObjType_IPI:
         return 1;
 
     default:
@@ -173,7 +174,7 @@ static size_t caps_numobjs(enum objtype type, uint8_t bits, uint8_t objbits)
  */
 // If you create more capability types you need to deal with them
 // in the table below.
-STATIC_ASSERT(26 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(27 == ObjType_Num, "Knowledge of all cap types");
 
 static errval_t caps_create(enum objtype type, lpaddr_t lpaddr, uint8_t bits,
                             uint8_t objbits, size_t numobjs,
@@ -569,6 +570,7 @@ static errval_t caps_create(enum objtype type, lpaddr_t lpaddr, uint8_t bits,
         /* fall through */
 
     case ObjType_Kernel:
+    case ObjType_IPI:
     case ObjType_IRQTable:
     case ObjType_EndPoint:
     case ObjType_Notify_RCK:
index 06d4423..26bea7d 100644 (file)
@@ -15,7 +15,7 @@
 #include "coreboot.h"
 
 coreid_t my_arch_id;
-struct capref kernel_cap;
+struct capref ipi_cap;
 
 bool done = false;
 
@@ -48,12 +48,12 @@ static void setup_monitor_messaging(void)
     st->rx_vtbl.boot_core_reply = boot_core_reply;
 }
 
-static void load_kernel_cap(void)
+static void load_ipi_cap(void)
 {
     struct monitor_blocking_rpc_client *mc = get_monitor_blocking_rpc_client();
-    errval_t err = mc->vtbl.get_kernel_cap(mc, &kernel_cap);
+    errval_t err = mc->vtbl.get_ipi_cap(mc, &ipi_cap);
     if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "get_kernel_cap failed.");
+        USER_PANIC_ERR(err, "get_ipi_cap failed.");
     }
 }
 
@@ -78,7 +78,7 @@ static void initialize(void)
 
     setup_monitor_messaging();
     load_arch_id();
-    load_kernel_cap();
+    load_ipi_cap();
 }
 
 
index e51422b..b817b99 100644 (file)
@@ -48,7 +48,7 @@ extern uint64_t x86_32_init_ap_global;
 
 volatile uint64_t *ap_dispatch;
 extern coreid_t my_arch_id;
-extern struct capref kernel_cap;
+extern struct capref ipi_cap;
 extern uint64_t end;
 
 errval_t get_core_info(coreid_t core_id, archid_t* apic_id, enum cpu_type* cpu_type)
@@ -210,7 +210,7 @@ int start_aps_x86_64_start(uint8_t core_id, genvaddr_t entry)
     barrelfish_usleep(10*1000);
 #endif
 
-    err = invoke_send_init_ipi(kernel_cap, core_id);
+    err = invoke_send_init_ipi(ipi_cap, core_id);
     if (err_is_fail(err)) {
         DEBUG_ERR(err, "invoke send init ipi");
         return err;
@@ -221,7 +221,7 @@ int start_aps_x86_64_start(uint8_t core_id, genvaddr_t entry)
 #endif
 
     // x86 protocol actually would like us to do this twice
-    err = invoke_send_start_ipi(kernel_cap, core_id, entry);
+    err = invoke_send_start_ipi(ipi_cap, core_id, entry);
     if (err_is_fail(err)) {
         DEBUG_ERR(err, "invoke sipi");
         return err;
@@ -320,13 +320,13 @@ int start_aps_x86_32_start(uint8_t core_id, genvaddr_t entry)
     *ap_wait = AP_STARTING_UP;
 
     end = bench_tsc();
-    err = invoke_send_init_ipi(kernel_cap, core_id);
+    err = invoke_send_init_ipi(ipi_cap, core_id);
     if (err_is_fail(err)) {
         DEBUG_ERR(err, "invoke send init ipi");
         return err;
     }
 
-    err = invoke_send_start_ipi(kernel_cap, core_id, entry);
+    err = invoke_send_start_ipi(ipi_cap, core_id, entry);
     if (err_is_fail(err)) {
         DEBUG_ERR(err, "invoke sipi");
         return err;
index baafca1..66b9143 100644 (file)
@@ -685,15 +685,37 @@ static void get_bootinfo(struct monitor_blocking_binding *b)
 
 /* ----------------------- BOOTINFO REQUEST CODE END ----------------------- */
 
-// TODO(gz): HACK remove before coreboot goes public.
-static void get_kernel_cap(struct monitor_blocking_binding *b)
+static void get_ipi_cap(struct monitor_blocking_binding *b)
 {
     errval_t err;
 
-    err = b->tx_vtbl.get_kernel_cap_response(b, NOP_CONT, cap_kernel);
+    // XXX: We should not just hand out this cap to everyone
+    // who requests it. There is currently no way to determine
+    // if the client is a valid recipient
+
+    // get slot for ipi cap
+    struct capref ipi;
+    err = slot_alloc(&ipi);
     if (err_is_fail(err)) {
-        USER_PANIC_ERR(err, "sending kernel_cap failed.");
+        DEBUG_ERR(err, "slot alloc for ipi");
     }
+
+    // TODO: do this in a slightly saner way!
+    // fabricate an IPI cap
+    struct capability cap;
+    memset(&cap, 0, sizeof(cap));
+    cap.type = ObjType_IPI;
+    cap.rights = CAPRIGHTS_ALLRIGHTS;
+
+    // put it in the slot
+    capaddr_t caddr = get_cnode_addr(ipi);
+    uint8_t vbits = get_cnode_valid_bits(ipi);
+    size_t  slot  = ipi.slot;
+    err = invoke_monitor_create_cap((uint64_t*)&cap, caddr, vbits, slot);
+    assert(err_is_ok(err));
+
+    err = b->tx_vtbl.get_ipi_cap_response(b, NOP_CONT, ipi);
+    assert(err_is_ok(err));
 }
 
 static void forward_kcb_request(struct monitor_blocking_binding *b,
@@ -821,7 +843,7 @@ static struct monitor_blocking_rx_vtbl rx_vtbl = {
     .get_arch_core_id_call   = get_arch_core_id,
 
     .cap_set_remote_call     = cap_set_remote,
-    .get_kernel_cap_call = get_kernel_cap,
+    .get_ipi_cap_call = get_ipi_cap,
 
     .forward_kcb_request_call = forward_kcb_request,