Merge branch 'caps_next'
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Tue, 7 Jun 2016 14:18:20 +0000 (16:18 +0200)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Tue, 7 Jun 2016 14:18:20 +0000 (16:18 +0200)
This merge changes capabilities for address ranges (e.g. RAM, PhysAddr, ...)
from power-of-two sizes given in bits to sizes given in bytes. The current
implementation restricts capabilities to be sized >= BASE_PAGE_SIZE.  In
addition, retype now can "cut out" a part of a large capability to create a
descendant without having to create descendants for the whole region.  To
ensure integrity of operations, calls to retype result in a range query on the
capability database to check for already existing, overlapping descendants of
the source capability.

Closes T191.

Signed-off-by: Simon Gerber <simon.gerber@inf.ethz.ch>

1  2 
errors/errno.fugu
platforms/Hakefile
tools/harness/barrelfish.py
usr/monitor/capops/delete.c
usr/monitor/capops/retype.c

diff --combined errors/errno.fugu
@@@ -59,11 -59,14 +59,14 @@@ errors kernel SYS_ERR_ 
      failure DEST_TYPE_INVALID   "Destination capability is of invalid type",
      failure INVALID_RETYPE      "Invalid source/destination type pair for retyping",
      failure RETYPE_MAPPING_EXPLICIT "Invalid explicit retype to mapping type",
+     failure RETYPE_INVALID_COUNT "Invalid number of new objects requested",
      failure REVOKE_FIRST        "Capability already has descendants or siblings",
      failure INVALID_SIZE_BITS   "Invalid size for new objects",
+     failure INVALID_SIZE        "Invalid size for new objects",
      failure SLOTS_INVALID       "Destination capability slots exceed capacity of CNode",
      failure SLOTS_IN_USE        "One or more destination capability slots occupied",
      failure RETYPE_CREATE       "Error while creating new capabilities in retype",
+     failure RETYPE_INVALID_OFFSET "Offset into source capability invalid for retype",
      failure NO_LOCAL_COPIES     "No copies of specified capability in local MDB",
      failure RETRY_THROUGH_MONITOR "There is a remote copy of the capability, monitor must be involved to perform a cross core agreement protocol",
      failure TYPE_NOT_CREATABLE  "Specified capability type is not creatable at runtime. Consider retyping it from another capability.",
@@@ -217,9 -220,11 +220,11 @@@ errors libbarrelfish LIB_ERR_ 
      failure MULTI_SLOT_ALLOC_INIT  "Failure in multi_slot_alloc_init()",
      failure MULTI_SLOT_ALLOC_INIT_RAW  "Failure in multi_slot_alloc_init_raw()",
      failure SINGLE_SLOT_ALLOC      "Failure in single_slot_alloc()",
+     failure RANGE_ALLOC_NOT_HEAD   "Function called on non-head range allocator",
      failure SLOT_ALLOC             "Failure in slot_alloc()",
      failure SLOT_FREE              "Failure in slot_free()",
      failure SLOT_UNALLOCATED       "slot_free() was called on an unallocated slot",
+     failure SLOT_ALLLOC_REFILL     "Failure in slot_alloc_refill()",
  
      // vspace
      failure VSPACE_CURRENT_INIT "Failure in vspace_current_init()",
@@@ -646,6 -651,7 +651,7 @@@ errors libmm MM_ERR_ 
      failure SLOT_ALLOC_INIT     "Failure initialising slot allocator",
      failure MM_INIT             "Failure in mm_init()",
      failure MM_ADD              "Failure in mm_add()",
+     failure MM_ADD_MULTI        "Failure in mm_add_multi()",
      failure MM_FREE             "Failure in mm_free()",
      failure NEW_NODE            "Failed allocating new node from slot allocator",
      failure OUT_OF_BOUNDS       "Given memory base address / size exceeds bounds of allocator",
@@@ -798,8 -804,6 +804,8 @@@ errors pci PCI_ERR_ 
  errors acpi ACPI_ERR_ {
      failure NO_MCFG_TABLE       "No MCFG Table found.",
      failure INVALID_PATH_NAME   "Invalid ACPI path name.",
 +    failure INVALID_HANDLE      "Invalid ACPI handle.",
 +    failure NO_CHILD_BRIDGE     "No matching child bridge found.",
      failure GET_RESOURCES       "Failed to execute _CRT method.",
      failure SET_IRQ             "Failed to set IRQ for device.",
      failure NO_MADT_TABLE       "No APIC found in ACPI.",
diff --combined platforms/Hakefile
@@@ -7,10 -7,10 +7,10 @@@
  -- ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
  --
  -- Hakefile for /platforms/
 --- 
 +--
  --------------------------------------------------------------------------
  
 -let bin_rcce_lu = [ "/sbin/" ++ f | f <- [ 
 +let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
                          "rcce_lu_A1",
                          "rcce_lu_A2",
                          "rcce_lu_A4",
@@@ -19,7 -19,7 +19,7 @@@
                          "rcce_lu_A32",
                          "rcce_lu_A64" ]]
  
 -    bin_rcce_bt = [ "/sbin/" ++ f | f <- [ 
 +    bin_rcce_bt = [ "/sbin/" ++ f | f <- [
                          "rcce_bt_A1",
                          "rcce_bt_A4",
                          "rcce_bt_A9",
@@@ -29,6 -29,8 +29,6 @@@
  
      tests_common = [ "/sbin/" ++ f | f <- [
                          "fputest",
 -                        "fread_test",
 -                        "fscanf_test",
                          "hellotest",
                          "idctest",
                          "memtest",
                          "nkmtest_map_unmap",
                          "nkmtest_modify_flags",
                          "schedtest",
+                         "test_retype",
                          "testerror",
                          "yield_test" ] ]
  
 -    tests_x86 = [ "/sbin/" ++ f | f <- [ 
 +    tests_x86 = [ "/sbin/" ++ f | f <- [
                          "tests/luatest",
                          "tests/numatest" ] ] ++ tests_common
  
 -    tests_x86_64 = [ "/sbin/" ++ f | f <- [ 
 +    tests_x86_64 = [ "/sbin/" ++ f | f <- [
                          "arrakis_hellotest",
 +                        "fread_test",
 +                        "fscanf_test",
                          "ata_rw28_test",
                          "bomp_cpu_bound",
                          "bomp_cpu_bound_progress",
                          "xcorecap",
                          "xcorecapserv" ] ] ++ tests_x86
  
 -    tests_x86_32 = tests_x86
 +    tests_x86_32 = [ "/sbin/" ++ f | f <- [
 +                    "fread_test",
 +                    "fscanf_test"
 +                    ] ] ++ tests_x86
  
      tests_k1om = [ "/sbin/" ++ f | f <- [
                          "tests/dma_test",
                          "tests/xeon_phi_test",
                          "tests/xphi_nameservice_test" ] ] ++ tests_x86
  
 -    bench_common = [ "/sbin/" ++ f | f <- [ 
 +    bench_common = [ "/sbin/" ++ f | f <- [
                          "channel_cost_bench",
                          "flounder_stubs_buffer_bench",
                          "flounder_stubs_empty_bench",
                          "flounder_stubs_payload_bench",
                          "xcorecapbench" ]]
  
 -    bench_x86 =  [ "/sbin/" ++ f | f <- [ 
 +    bench_x86 =  [ "/sbin/" ++ f | f <- [
                        "multihop_latency_bench",
                        "net_openport_test",
                        "perfmontest",
                        "ump_send",
                        "ump_throughput" ]]
  
 -    bench_x86_64 = bench_x86 ++ bin_rcce_bt ++ bin_rcce_lu ++ 
 -                   [ "/sbin/" ++ f | f <- [ 
 +    bench_x86_64 = bench_x86 ++ bin_rcce_bt ++ bin_rcce_lu ++
 +                   [ "/sbin/" ++ f | f <- [
                          "ahci_bench",
                          "apicdrift_bench",
                          "benchmarks/bomp_mm",
  
      bench_x86_32 = bench_x86 ++ bin_rcce_bt ++ bin_rcce_lu
  
 -    bench_k1om = [ "/sbin/" ++ f | f <- [ 
 +    bench_k1om = [ "/sbin/" ++ f | f <- [
                          "benchmarks/bomp_mm",
                          "benchmarks/dma_bench",
                          "benchmarks/xomp_share",
                          "benchmarks/xphi_xump_bench" ] ] ++ bench_x86
  
      -- Default list of modules to build/install for all enabled architectures
 -    modules_common = [ "/sbin/" ++ f | f <- [ 
 +    modules_common = [ "/sbin/" ++ f | f <- [
                            "init",
                            "chips",
                            "skb",
          "/sshd_ramfs.cpio.gz" ]
  
      -- x86_64-specific modules to build by default
 -    -- this should shrink as targets are ported and move into the generic list above 
 -    modules_x86_64  = [ "/sbin/" ++ f | f <- [ 
 +    -- this should shrink as targets are ported and move into the generic list above
 +    modules_x86_64  = [ "/sbin/" ++ f | f <- [
                             "elver",
                             "cpu",
                             "acpi",
                             "xeon_phi",
                             "xeon_phi_mgr"
                             ]] ++ modules_common
 -    
 +
      -- the following are broken in the newidc system
 -    modules_x86_64_broken  = [ "/sbin/" ++ f | f <- [ 
 +    modules_x86_64_broken  = [ "/sbin/" ++ f | f <- [
                                    "barriers",
                                    "ipi_bench",
                                    "ring_barriers",
                                    "ssf_bcast",
                                    "lamport_bcast" ]]
 -                             
 +
      -- x86-32-specific module to build by default
 -    modules_x86_32  = [ "/sbin/" ++ f | f <- [ 
 +    modules_x86_32  = [ "/sbin/" ++ f | f <- [
                             "cpu",
                             "lpc_kbd",
                             "serial",
     --
     -- Rules to build assorted platforms
     --
 -   
 +
      platform "X86_64_Basic" [ "x86_64" ]
        ([ ("x86_64", f) | f <- modules_x86_64 ]
         ++
      platform "PandaboardES" [ "armv7" ]
      ([ ("armv7", f) | f <- pandaModules ] ++ [ ("root", "/pandaboard_image") ])
      "Standard Pandaboard ES build image and modules",
 -    
 +
      platform "ARMv8-GEM5" [ "armv8" ]
      ([ ("armv8", f) | f <- armv8_gem5Modules ] ++ [ ("root", "/armv8_gem5_image") ])
      "GEM5 emulator for ARM Cortex-A series multicore processors",
      --
      -- Rules to build assorted boot images
      --
 -    
 +
      -- Build the default PandaBoard boot image
      Rule ([ In SrcTree "tools" "/tools/arm_molly/build_pandaboard_image.sh",
 -            Str "--srcdir",   NoDep SrcTree "root" "/.", 
 -            Str "--builddir", NoDep BuildTree "root" "/.", 
 +            Str "--srcdir",   NoDep SrcTree "root" "/.",
 +            Str "--builddir", NoDep BuildTree "root" "/.",
              Str "--arch armv7-a",
              Str "--menu",     In SrcTree "tools" "/hake/menu.lst.pandaboard",
              Str "--baseaddr", Str "0x82001000",
  
      -- Build the (old) PandaBoard Cortex-M3 image
      Rule ([ In SrcTree "tools" "/tools/arm_molly/build_pandaboard_image.sh",
 -            Str "--srcdir",   NoDep SrcTree "root" "/.", 
 +            Str "--srcdir",   NoDep SrcTree "root" "/.",
              Str "--builddir", NoDep BuildTree "root" "/.",
              Str "--arch armv7-m",
              Str "--menu",     In SrcTree "tools" "/hake/menu.lst.armv7-m",
  
      -- Build the ARMv7 GEM5 simulation image
      Rule ([ In SrcTree "tools" "/tools/arm_molly/build_pandaboard_image.sh",
 -            Str "--srcdir",   NoDep SrcTree "root" "/.", 
 -            Str "--builddir", NoDep BuildTree "root" "/.", 
 +            Str "--srcdir",   NoDep SrcTree "root" "/.",
 +            Str "--builddir", NoDep BuildTree "root" "/.",
              Str "--arch armv7-a",
              Str "--menu",     In SrcTree "tools" "/hake/menu.lst.arm_gem5_mc",
              Str "--baseaddr", Str "0x100000",
  
      -- Build the ARMv8 GEM5 simulation image
      Rule ([ In SrcTree "tools" "/tools/arm_molly/build_pandaboard_image.sh",
 -            Str "--srcdir",   NoDep SrcTree "root" "/.", 
 -            Str "--builddir", NoDep BuildTree "root" "/.", 
 +            Str "--srcdir",   NoDep SrcTree "root" "/.",
 +            Str "--builddir", NoDep BuildTree "root" "/.",
              Str "--arch armv8-a",
              Str "--menu",     In SrcTree "tools" "/hake/menu.lst.armv8_gem5",
              Str "--baseaddr", Str "0x100000",
      Rules [ copyFile SrcTree "root" ("/hake/menu.lst." ++ p)
                       "root" ("/platforms/x86/menu.lst." ++ p)
              | p <- [ "x86_32", "x86_64", "k1om" ] ],
 -    
 +
      -- Convenient functions for running GEM5
      boot "gem5_armv8" [ "armv8" ] [
        Str Config.gem5,
        Str "--menu", In BuildTree "root" "/platforms/x86/menu.lst.x86_64",
        Str "--arch", Str "x86_64" ]
      "Boot QEMU in 64-bit x86 mode emulating a PC",
 -    
 +
      boot "qemu_x86_32" [ "x86_32" ] [
        In SrcTree "tools" "/tools/qemu-wrapper.sh",
        Str "--menu", In BuildTree "root" "/platforms/x86/menu.lst.x86_32",
        Str "--arch", Str "x86_64",
        Str "--debug", In SrcTree "tools" "/tools/debug.gdb" ]
      "Boot QEMU under GDB in 64-bit x86 mode emulating a PC",
 -    
 +
      boot "qemu_x86_32_debug" [ "x86_32" ] [
        In SrcTree "tools" "/tools/qemu-wrapper.sh",
        Str "--menu", In BuildTree "root" "/platforms/x86/menu.lst.x86_32",
@@@ -63,11 -63,11 +63,11 @@@ class BootModules(object)
          self.del_module(name)
          self.add_module(name, args)
  
-     def get_menu_data(self, path):
+     def get_menu_data(self, path, root="(nd)"):
          assert(self.kernel[0])
          r = "timeout 0\n"
          r += "title Harness image\n"
-         r += "root (nd)\n"
+         r += "root %s\n" % root
          if self.hypervisor:
              r += "hypervisor %s\n" % os.path.join(path, self.hypervisor)
          r += "kernel %s %s\n" % (
@@@ -140,7 -140,7 +140,7 @@@ def default_bootmodules(build, machine)
  
          if machine.name == "sbrinz1" or machine.name == "sbrinz2" \
          or machine.name == "tomme1" or machine.name == "tomme2" \
 -        or is_babybel == 1 :
 +        or machine.name == "appenzeller" or is_babybel == 1 :
              # PCI allocation broken, use BIOS plan
              m.add_module("%s/sbin/pci" % a, ["auto",
                                               "skb_bridge_program=bridge_bios"] + machine.get_pci_args())
@@@ -74,13 -74,13 +74,13 @@@ send_new_ram_cap(struct capref cap
      if (!b) {
          DEBUG_CAPOPS("%s: forwarding to monitor.0\n", __FUNCTION__);
          // we're not on core 0, so forward free_monitor msg to monitor.0
-         err = mon_ram_free(&cap_data, ram.base, ram.bits);
+         err = mon_ram_free(&cap_data, ram.base, log2ceil(ram.bytes));
          assert(err_is_ok(err));
      } else {
          DEBUG_CAPOPS("%s: we are monitor.0\n", __FUNCTION__);
          // XXX: This should not be an RPC! It could stall the monitor, but
          // we trust mem_serv for the moment.
-         err = b->vtbl.free_monitor(b, cap, ram.base, ram.bits, &result);
+         err = b->vtbl.free_monitor(b, cap, ram.base, log2ceil(ram.bytes), &result);
          assert(err_is_ok(err));
          assert(err_is_ok(result));
      }
@@@ -178,18 -178,6 +178,18 @@@ delete_remote_result__send(struct inter
      errval_t err;
      struct delete_remote_result_msg_st *msg_st = (struct delete_remote_result_msg_st*)e;
      err = intermon_capops_delete_remote_result__tx(b, NOP_CONT, msg_st->status, msg_st->st);
 +
 +    if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
 +        DEBUG_CAPOPS("%s: got FLOUNDER_ERR_TX_BUSY; requeueing msg.\n", __FUNCTION__);
 +        struct intermon_state *inter_st = (struct intermon_state *)b->st;
 +        // requeue send request at front and return
 +        err = intermon_enqueue_send_at_front(b, &inter_st->queue, b->waitset,
 +                                             (struct msg_queue_elem *)e);
 +        GOTO_IF_ERR(err, handle_err);
 +        return;
 +    }
 +
 +handle_err:
      PANIC_IF_ERR(err, "failed to send delete_remote_result msg");
      free(msg_st);
  }
@@@ -25,7 -25,9 +25,9 @@@
  
  struct retype_check_st {
      enum objtype type;
-     size_t objbits;
+     size_t objsize;
+     size_t count;
+     size_t offset;
      struct domcapref src;
      struct result_closure cont;
  };
@@@ -75,18 -77,6 +77,18 @@@ retype_result__send(struct intermon_bin
      struct requested_retype_st *req_st = (struct requested_retype_st*)e;
      err = intermon_capops_retype_response__tx(b, NOP_CONT, req_st->status,
                                                req_st->request_st);
 +
 +    if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
 +        DEBUG_CAPOPS("%s: got FLOUNDER_ERR_TX_BUSY; requeueing msg.\n", __FUNCTION__);
 +        struct intermon_state *inter_st = (struct intermon_state *)b->st;
 +        // requeue send request at front and return
 +        err = intermon_enqueue_send_at_front(b, &inter_st->queue, b->waitset,
 +                                             (struct msg_queue_elem *)e);
 +        GOTO_IF_ERR(err, handle_err);
 +        return;
 +    }
 +
 +handle_err:
      PANIC_IF_ERR(err, "sending retype result message");
      free(req_st);
  }
@@@ -150,8 -140,8 +152,8 @@@ retype_request_check__rx(errval_t statu
  }
  
  void
- retype_request__rx(struct intermon_binding *b, intermon_caprep_t srcrep,
-                    uint32_t desttype, uint32_t destbits, genvaddr_t st)
+ retype_request__rx(struct intermon_binding *b, intermon_caprep_t srcrep, uint64_t offset,
+                    uint32_t desttype, uint64_t destsize, uint64_t count, genvaddr_t st)
  {
      errval_t err;
  
  
      req_st->queue_elem.cont = retype_result__send;
      req_st->check.type = desttype;
-     req_st->check.objbits = destbits;
+     req_st->check.objsize = destsize;
+     req_st->check.count = count;
+     req_st->check.offset = offset;
      req_st->check.cont = MKRESCONT(retype_request_check__rx, req_st);
      req_st->from = ((struct intermon_state*)b->st)->core_id;
      req_st->request_st = st;
@@@ -226,22 -218,12 +230,24 @@@ retype_request__send(struct intermon_bi
      errval_t err;
  
      err = intermon_capops_request_retype__tx(b, NOP_CONT, req_st->caprep,
+                                              req_st->check.offset,
                                               req_st->check.type,
-                                              req_st->check.objbits,
+                                              req_st->check.objsize,
+                                              req_st->check.count,
                                               (lvaddr_t)req_st);
  
 +
 +    if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
 +        DEBUG_CAPOPS("%s: got FLOUNDER_ERR_TX_BUSY; requeueing msg.\n", __FUNCTION__);
 +        struct intermon_state *inter_st = (struct intermon_state *)b->st;
 +        // requeue send request at front and return
 +        err = intermon_enqueue_send_at_front(b, &inter_st->queue, b->waitset,
 +                                             (struct msg_queue_elem *)e);
 +        GOTO_IF_ERR(err, handle_err);
 +        return;
 +    }
 +
 +handle_err:
      if (err_is_fail(err)) {
          retype_result__rx(err, req_st);
      }
@@@ -346,9 -328,10 +352,10 @@@ retype_check__rx(errval_t status, struc
          struct domcapref *src = &check->src;
          struct domcapref *destcn = &output->destcn;
          assert(capcmp(src->croot, destcn->croot));
-         err = monitor_create_caps(src->croot, check->type, check->objbits,
-                                   src->cptr, src->bits, destcn->cptr,
-                                   destcn->bits, output->start_slot);
+         err = monitor_create_caps(src->croot, check->type, check->objsize,
+                                   check->count, src->cptr, src->bits,
+                                   check->offset, destcn->cptr, destcn->bits,
+                                   output->start_slot);
      }
      struct result_closure cont = output->cont;
      assert(cont.handler);
@@@ -371,9 -354,9 +378,9 @@@ local_retype_check__rx(errval_t status
   */
  
  void
- capops_retype(enum objtype type, size_t objbits, struct capref croot,
+ capops_retype(enum objtype type, size_t objsize, size_t count, struct capref croot,
                capaddr_t dest_cn, uint8_t dest_bits, cslot_t dest_slot,
-               capaddr_t src, uint8_t src_bits,
+               capaddr_t src, uint8_t src_bits, gensize_t offset,
                retype_result_handler_t result_handler, void *st)
  {
      errval_t err;
          goto err_cont;
      }
  
-     err = invoke_cnode_retype(croot, src, type, objbits, dest_cn, dest_slot,
-                               dest_bits);
+     err = invoke_cnode_retype(croot, src, offset, type, objsize, count,
+                               dest_cn, dest_slot, dest_bits);
      if (err_no(err) != SYS_ERR_RETRY_THROUGH_MONITOR) {
          goto err_cont;
      }
  
          // fill in parameters
          rtp_req_st->check.type = type;
-         rtp_req_st->check.objbits = objbits;
+         rtp_req_st->check.objsize = objsize;
+         rtp_req_st->check.count = count;
+         rtp_req_st->check.offset = offset;
          rtp_req_st->check.src = (struct domcapref){
              .croot = croot,
              .cptr = src,
  
          // fill in parameters
          rtp_loc_st->check.type = type;
-         rtp_loc_st->check.objbits = objbits;
+         rtp_loc_st->check.objsize = objsize;
+         rtp_loc_st->check.count = count;
+         rtp_loc_st->check.offset = offset;
          rtp_loc_st->check.src = (struct domcapref){
              .croot = croot,
              .cptr = src,