1 #include "config.h" 2 3 extern "C" { 4 #include "mbox.h" 5 #include "mboxd_msg.h" 6 }; 7 8 #include "vpnor/mboxd_msg.hpp" 9 #include "vpnor/pnor_partition_table.hpp" 10 11 // clang-format off 12 const mboxd_mbox_handler vpnor_mbox_handlers[NUM_MBOX_CMDS] = 13 { 14 mbox_handle_reset, 15 mbox_handle_mbox_info, 16 mbox_handle_flash_info, 17 mbox_handle_read_window, 18 mbox_handle_close_window, 19 vpnor_handle_write_window, 20 mbox_handle_dirty_window, 21 mbox_handle_flush_window, 22 mbox_handle_ack, 23 mbox_handle_erase_window 24 }; 25 // clang-format on 26 27 /* XXX: Maybe this should be a method on a class? */ 28 static bool vpnor_partition_is_readonly(const pnor_partition& part) 29 { 30 return part.data.user.data[1] & PARTITION_READONLY; 31 } 32 33 int vpnor_handle_write_window(struct mbox_context* context, 34 union mbox_regs* req, struct mbox_msg* resp) 35 { 36 size_t offset = get_u16(&req->msg.args[0]); 37 offset <<= context->block_size_shift; 38 try 39 { 40 const pnor_partition& part = context->vpnor->table->partition(offset); 41 if (vpnor_partition_is_readonly(part)) 42 { 43 return -MBOX_R_WINDOW_ERROR; 44 } 45 } 46 catch (const openpower::virtual_pnor::UnmappedOffset& e) 47 { 48 /* 49 * Writes to unmapped areas are not meaningful, so deny the request. 50 * This removes the ability for a compromised host to abuse unused 51 * space if any data was to be persisted (which it isn't). 52 */ 53 return -MBOX_R_WINDOW_ERROR; 54 } 55 56 /* Defer to the default handler */ 57 return mbox_handle_write_window(context, req, resp); 58 } 59