Commit b0490dc0 authored by Brian Kocoloski's avatar Brian Kocoloski

Update packet interface to perform xrbuf creation on the LWK side

rather than the LNX side. This ensures that physical memory allocation
is performed on the LWK side, preventing xpmem issues related to
memory revocation that the Linux kernel wants to perform
parent caadf1fd
......@@ -84,8 +84,6 @@ struct hobbes_xtap {
/* TAP device for reading/writing */
int tap_fd;
struct hobbes_vm_tap_connect_info conn_info;
};
......@@ -921,13 +919,61 @@ __handle_destroy(const char * tap_ifname)
* --- how does monitor/mwait play in?
*/
static int
__handle_lwk_disconnect(hobbes_id_t vm_enclave_id,
hobbes_id_t host_enclave_id,
const char * tap_ifname)
__send_lwk_connect(hobbes_id_t vm_enclave_id,
hobbes_id_t host_enclave_id,
const char * tap_ifname)
{
struct hobbes_xtap * xtap;
hcq_handle_t hcq = HCQ_INVALID_HANDLE;
hcq_cmd_t cmd = HCQ_INVALID_CMD;
char * ret_str = NULL;
uint32_t ret_len = 0;
int status = -1;
struct hobbes_vm_tap_connect_info info;
info.enclave_id = vm_enclave_id;
strncpy(info.tap_ifname, tap_ifname, TAP_IFNAME_LEN);
hcq = hobbes_open_enclave_cmdq(host_enclave_id);
if (hcq == HCQ_INVALID_HANDLE) {
ERROR("Could not open host enclave command queue\n");
goto out_hcq;
}
cmd = hcq_cmd_issue(
hcq,
ENCLAVE_CMD_VM_TAP_CONNECT,
sizeof(struct hobbes_vm_tap_connect_info),
&info
);
if (cmd == HCQ_INVALID_CMD) {
ERROR("Could not issue HCQ command to host enclave command queue\n");
goto out_hcq_issue;
}
status = hcq_get_ret_code(hcq, cmd);
ret_str = hcq_get_ret_data(hcq, cmd, &ret_len);
if (ret_len > 0)
ERROR("lwk_init error: %s\n", ret_str);
hcq_cmd_complete(hcq, cmd);
out_hcq_issue:
hobbes_close_enclave_cmdq(hcq);
out_hcq:
return status;
}
static int
__send_lwk_disconnect(hobbes_id_t vm_enclave_id,
hobbes_id_t host_enclave_id)
{
hcq_handle_t hcq = HCQ_INVALID_HANDLE;
hcq_cmd_t cmd = HCQ_INVALID_CMD;
......@@ -935,6 +981,44 @@ __handle_lwk_disconnect(hobbes_id_t vm_enclave_id,
uint32_t ret_len = 0;
int status = -1;
hcq = hobbes_open_enclave_cmdq(host_enclave_id);
if (hcq == HCQ_INVALID_HANDLE) {
ERROR("Could not open host enclave command queue\n");
return -1;
}
cmd = hcq_cmd_issue(
hcq,
ENCLAVE_CMD_VM_TAP_DISCONNECT,
sizeof(hobbes_id_t),
&vm_enclave_id
);
if (cmd == HCQ_INVALID_CMD) {
ERROR("Could not issue HCQ command to host enclave command queue\n");
goto out_hcq_issue;
}
status = hcq_get_ret_code(hcq, cmd);
ret_str = hcq_get_ret_data(hcq, cmd, &ret_len);
if (ret_len > 0)
ERROR("lwk_init error: %s\n", ret_str);
hcq_cmd_complete(hcq, cmd);
out_hcq_issue:
hobbes_close_enclave_cmdq(hcq);
return status;
}
static int
__handle_lwk_disconnect(hobbes_id_t vm_enclave_id,
hobbes_id_t host_enclave_id,
const char * tap_ifname)
{
struct hobbes_xtap * xtap;
int status;
/* find the xtap */
xtap = __xtap_of_iface(tap_ifname);
if (xtap == NULL) {
......@@ -942,77 +1026,64 @@ __handle_lwk_disconnect(hobbes_id_t vm_enclave_id,
return -1;
}
/* Send command queue message to teardown LWK TAP state */
status = __send_lwk_disconnect(vm_enclave_id, host_enclave_id);
if (status != 0)
return status;
/* stop watching the tap iface */
close(xtap->tap_fd);
/* forget the fds and forget the xtap (these free the handler/xtap structures) */
/* forget the fds */
__forget_fd(xtap->xrbuf_rx_poll_fd);
__forget_fd(xtap->tap_fd);
__forget_iface(tap_ifname);
/* Send command queue message */
{
hcq = hobbes_open_enclave_cmdq(host_enclave_id);
if (hcq == HCQ_INVALID_HANDLE) {
ERROR("Could not open host enclave command queue\n");
goto out_hcq;
}
cmd = hcq_cmd_issue(
hcq,
ENCLAVE_CMD_VM_TAP_DISCONNECT,
sizeof(hobbes_id_t),
&vm_enclave_id
);
if (cmd == HCQ_INVALID_CMD) {
ERROR("Could not issue HCQ command to host enclave command queue\n");
goto out_hcq_issue;
}
status = hcq_get_ret_code(hcq, cmd);
ret_str = hcq_get_ret_data(hcq, cmd, &ret_len);
/* destroy the xrbufs */
status = xrbuf_detach(xtap->xrbuf_tx);
if (status != 0)
ERROR("Could not detach xtap TX xrbuf\n");
if (ret_len > 0)
ERROR("lwk_init error: %s\n", ret_str);
status = xrbuf_detach(xtap->xrbuf_rx);
if (status != 0)
ERROR("Could not detach xtap RX xrbuf\n");
hcq_cmd_complete(hcq, cmd);
}
/* forget/delete the xtap */
__forget_iface(tap_ifname);
out_hcq_issue:
hobbes_close_enclave_cmdq(hcq);
out_hcq:
return status;
return 0;
}
static int
__handle_lwk_connect(hobbes_id_t vm_enclave_id,
hobbes_id_t host_enclave_id,
const char * tap_ifname)
{
struct hobbes_xtap * xtap;
hcq_handle_t hcq = HCQ_INVALID_HANDLE;
hcq_cmd_t cmd = HCQ_INVALID_CMD;
int status;
char xrbuf_tx_name[XEMEM_SEG_NAME_LEN] = { 0 };
char xrbuf_rx_name[XEMEM_SEG_NAME_LEN] = { 0 };
char * ret_str = NULL;
uint32_t ret_len = 0;
int status = -1;
xtap = malloc(sizeof(struct hobbes_xtap));
if (xtap == NULL) {
ERROR("Could not allocate xtap structure\n");
return -1;
}
/* Create xrbufs */
/* Send command queue connection message */
status = __send_lwk_connect(vm_enclave_id, host_enclave_id, tap_ifname);
if (status != 0) {
ERROR("Could not initialize device '%s' on LWK enclave\n",
tap_ifname);
goto out_connect;
}
/* Attach to xrbufs */
{
snprintf(xrbuf_tx_name, XEMEM_SEG_NAME_LEN - 1, "%s_tx", tap_ifname);
snprintf(xrbuf_rx_name, XEMEM_SEG_NAME_LEN - 1, "%s_rx", tap_ifname);
status = xrbuf_create(
status = xrbuf_attach(
XTAP_ITEM_SIZE,
XTAP_TX_NR_ITEMS,
xrbuf_tx_name,
......@@ -1024,7 +1095,7 @@ __handle_lwk_connect(hobbes_id_t vm_enclave_id,
goto out_xrbuf_tx;
}
status = xrbuf_create(
status = xrbuf_attach(
XTAP_ITEM_SIZE,
XTAP_RX_NR_ITEMS,
xrbuf_rx_name,
......@@ -1043,41 +1114,6 @@ __handle_lwk_connect(hobbes_id_t vm_enclave_id,
}
}
/* Send command queue message */
{
xtap->conn_info.enclave_id = vm_enclave_id;
strncpy(xtap->conn_info.tap_ifname, tap_ifname, TAP_IFNAME_LEN);
hcq = hobbes_open_enclave_cmdq(host_enclave_id);
if (hcq == HCQ_INVALID_HANDLE) {
ERROR("Could not open host enclave command queue\n");
goto out_hcq;
}
cmd = hcq_cmd_issue(
hcq,
ENCLAVE_CMD_VM_TAP_CONNECT,
sizeof(struct hobbes_vm_tap_connect_info),
&(xtap->conn_info)
);
if (cmd == HCQ_INVALID_CMD) {
ERROR("Could not issue HCQ command to host enclave command queue\n");
goto out_hcq_issue;
}
status = hcq_get_ret_code(hcq, cmd);
ret_str = hcq_get_ret_data(hcq, cmd, &ret_len);
if (ret_len > 0)
ERROR("lwk_init error: %s\n", ret_str);
hcq_cmd_complete(hcq, cmd);
/* non-zero status indicates error */
if (status != 0)
goto out_connect;
}
/* Finally, get an fd to the tap device */
xtap->tap_fd = __tap_open(tap_ifname);
if (xtap->tap_fd < 0) {
......@@ -1124,30 +1160,25 @@ out_remember_tap:
close(xtap->tap_fd);
out_tap:
out_xrbuf_rx_poll:
if (status != 0)
(void)__handle_lwk_disconnect(vm_enclave_id, host_enclave_id, tap_ifname);
out_connect:
out_hcq_issue:
hobbes_close_enclave_cmdq(hcq);
out_hcq:
if (status != 0)
xrbuf_destroy(xtap->xrbuf_rx);
xrbuf_detach(xtap->xrbuf_rx);
out_xrbuf_rx_poll:
out_xrbuf_rx:
if (status != 0)
xrbuf_destroy(xtap->xrbuf_tx);
xrbuf_detach(xtap->xrbuf_tx);
out_xrbuf_tx:
if (status != 0)
(void)__send_lwk_disconnect(vm_enclave_id, host_enclave_id);
out_connect:
if (status != 0)
free(xtap);
return status;
}
static int
__handle_lnx_connect(hobbes_id_t vm_enclave_id,
hobbes_id_t host_enclave_id,
......
......@@ -823,11 +823,9 @@ __hobbes_vm_tap_connect(hcq_handle_t hcq,
char xrbuf_tx_name[XEMEM_SEG_NAME_LEN] = { 0 };
char xrbuf_rx_name[XEMEM_SEG_NAME_LEN] = { 0 };
xemem_segid_t xrbuf_rx_segid = XEMEM_INVALID_SEGID;
struct hobbes_vm_tap_connect_info * connect_info = NULL;
struct hobbes_vm_tap_state * state = NULL;
struct v3_hobbes_tuntap_cfg tap_cfg;
state = (struct hobbes_vm_tap_state *)malloc(sizeof(struct hobbes_vm_tap_state));
if (state == NULL) {
......@@ -871,9 +869,9 @@ __hobbes_vm_tap_connect(hcq_handle_t hcq,
snprintf(xrbuf_tx_name, XEMEM_SEG_NAME_LEN, "%s_tx", connect_info->tap_ifname);
snprintf(xrbuf_rx_name, XEMEM_SEG_NAME_LEN, "%s_rx", connect_info->tap_ifname);
/* First, connect to the xrbuf created by the Linux side */
/* Create TX xrbuf */
{
status = xrbuf_attach(
status = xrbuf_create(
XTAP_ITEM_SIZE,
XTAP_TX_NR_ITEMS,
(const char *)xrbuf_tx_name,
......@@ -882,30 +880,25 @@ __hobbes_vm_tap_connect(hcq_handle_t hcq,
);
if (status != 0) {
err_str = "Could not connect to xrbuf_tx";
goto out_cmd;
err_str = "Could not create xrbuf_tx";
goto out_tx;
}
status = xrbuf_get_poll_fd(state->xrbuf_tx, &(state->xrbuf_tx_poll_fd));
if (status != 0) {
err_str = "Could not get poll_fd from xrbuf_tx";
goto out_poll;
goto out_tx_poll;
}
}
/* Connect to rxbuf via v3vee LWK tap iface */
/* Send conn ioctl to Palacios VM device */
{
xrbuf_rx_segid = xemem_lookup_segid(xrbuf_rx_name);
if (xrbuf_rx_segid == XEMEM_INVALID_SEGID) {
err_str = "Could not find segid for xrbuf_rx";
goto out_connect;
}
struct v3_hobbes_tuntap_cfg tap_cfg;
memset(&tap_cfg, 0, sizeof(struct v3_hobbes_tuntap_cfg));
strncpy(tap_cfg.dev_name, connect_info->tap_ifname, V3_TUNTAP_IFNAME_LEN);
tap_cfg.xrbuf_item_size = XTAP_ITEM_SIZE;
tap_cfg.xrbuf_max_items = XTAP_TX_NR_ITEMS;
tap_cfg.xrbuf_segid = xrbuf_rx_segid;
tap_cfg.xrbuf_max_items = XTAP_RX_NR_ITEMS;
status = __issue_vm_cmd(state->vm_id, V3_VM_TUNTAP_CONNECT, (uintptr_t)&tap_cfg);
if (status != 0) {
......@@ -913,7 +906,22 @@ __hobbes_vm_tap_connect(hcq_handle_t hcq,
goto out_connect;
}
/* Kernel returns TAP fd to monitor packet availability, and
* segid mapping the xrbuf it created
*/
state->tap_fd = tap_cfg.tap_fd;
/* export the segid */
status = xemem_export_segment(tap_cfg.xrbuf_segid,
xrbuf_rx_name,
connect_info->enclave_id,
HOBBES_INIT_APP_ID
);
if (status != 0) {
ERROR("Could not export segid\n");
goto out_export;
}
}
/* Start polling the fds */
......@@ -953,12 +961,16 @@ out_htable:
// remove_fd_handler(state->tap_fd);
out_fd:
out_export:
close(state->tap_fd);
out_connect:
out_poll:
xrbuf_detach(state->xrbuf_tx);
close(state->xrbuf_tx_poll_fd);
out_tx_poll:
xrbuf_destroy(state->xrbuf_tx);
out_tx:
out_cmd:
free(state);
......@@ -992,13 +1004,13 @@ __hobbes_vm_tap_disconnect(hcq_handle_t hcq,
/* Perform teardown */
// remove_fd_handler(state->tap_fd);
close(state->xrbuf_tx_poll_fd);
remove_fd_handler(state->xrbuf_tx_poll_fd);
close(state->tap_fd);
xrbuf_detach(state->xrbuf_tx);
xrbuf_destroy(state->xrbuf_tx);
free(state);
ret = 0;
printf("Disconnected from Palacios TAP device\n");
out:
if (err_str) ERROR("%s\n", err_str);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment