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? */
vpnor_partition_is_readonly(const pnor_partition & part)28 static bool vpnor_partition_is_readonly(const pnor_partition& part)
29 {
30 return part.data.user.data[1] & PARTITION_READONLY;
31 }
32
vpnor_handle_write_window(struct mbox_context * context,union mbox_regs * req,struct mbox_msg * resp)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