Tofu: proper cleanup of device files when mcexec gets killed

Change-Id: I6cb0290f72d96682700f945b29585e132e525ac1
This commit is contained in:
Balazs Gerofi
2020-09-08 13:30:32 +09:00
committed by Masamichi Takagi
parent 1918df7765
commit e5f4a4e87d
10 changed files with 489 additions and 40 deletions

View File

@@ -778,12 +778,36 @@ out_remote_pf:
ret = 0;
break;
case SCD_MSG_CLEANUP_PROCESS:
case SCD_MSG_CLEANUP_PROCESS: {
extern int process_cleanup_before_terminate(int pid);
dkprintf("SCD_MSG_CLEANUP_PROCESS pid=%d, thread=0x%llx\n",
packet->pid, packet->arg);
pckt.msg = SCD_MSG_CLEANUP_PROCESS_RESP;
pckt.err = process_cleanup_before_terminate(packet->pid);
pckt.ref = packet->ref;
pckt.arg = packet->arg;
pckt.reply = packet->reply;
syscall_channel_send(resp_channel, &pckt);
terminate_host(packet->pid, (struct thread *)packet->arg);
ret = 0;
break;
}
case SCD_MSG_CLEANUP_FD: {
extern int process_cleanup_fd(int pid, int fd);
pckt.msg = SCD_MSG_CLEANUP_FD_RESP;
pckt.err = process_cleanup_fd(packet->pid, packet->arg);
dkprintf("SCD_MSG_CLEANUP_FD pid=%d, fd=%d -> err: %d\n",
packet->pid, packet->arg, pckt.err);
pckt.ref = packet->ref;
pckt.arg = packet->arg;
pckt.reply = packet->reply;
syscall_channel_send(resp_channel, &pckt);
ret = 0;
break;
}
case SCD_MSG_DEBUG_LOG:
dkprintf("SCD_MSG_DEBUG_LOG code=%lx\n", packet->arg);

View File

@@ -39,7 +39,8 @@
#define SCD_MSG_SEND_SIGNAL 0x7
#define SCD_MSG_SEND_SIGNAL_ACK 0x8
#define SCD_MSG_CLEANUP_PROCESS 0x9
#define SCD_MSG_GET_VDSO_INFO 0xa
#define SCD_MSG_CLEANUP_PROCESS_RESP 0xa
#define SCD_MSG_GET_VDSO_INFO 0xb
#define SCD_MSG_GET_CPU_MAPPING 0xc
#define SCD_MSG_REPLY_GET_CPU_MAPPING 0xd
@@ -84,6 +85,8 @@
#define SCD_MSG_CPU_RW_REG 0x52
#define SCD_MSG_CPU_RW_REG_RESP 0x53
#define SCD_MSG_CLEANUP_FD 0x54
#define SCD_MSG_CLEANUP_FD_RESP 0x55
#define SCD_MSG_FUTEX_WAKE 0x60

View File

@@ -1303,10 +1303,8 @@ void terminate(int rc, int sig)
if (proc->enable_tofu && proc->fd_pde_data[fd]) {
extern void tof_utofu_release_fd(struct process *proc, int fd);
if (proc->fd_path[fd]) {
dkprintf("%s: -> tof_utofu_release_fd() @ fd: %d (%s)\n",
__func__, fd, proc->fd_path[fd]);
}
dkprintf("%s: -> tof_utofu_release_fd() @ fd: %d (%s)\n",
__func__, fd, proc->fd_path[fd]);
tof_utofu_release_fd(proc, fd);
proc->fd_pde_data[fd] = NULL;
}
@@ -1487,6 +1485,67 @@ void terminate(int rc, int sig)
panic("panic");
}
int __process_cleanup_fd(struct process *proc, int fd)
{
#ifdef ENABLE_TOFU
/* Tofu? */
if (proc->enable_tofu) {
extern void tof_utofu_release_fd(struct process *proc, int fd);
dkprintf("%s: -> tof_utofu_release_fd() @ fd: %d (%s)\n",
__func__, fd, proc->fd_path[fd]);
tof_utofu_release_fd(proc, fd);
proc->fd_pde_data[fd] = NULL;
if (proc->fd_path[fd]) {
kfree(proc->fd_path[fd]);
proc->fd_path[fd] = NULL;
}
}
#endif
return 0;
}
int process_cleanup_fd(int pid, int fd)
{
struct process *proc;
struct mcs_rwlock_node_irqsave lock;
proc = find_process(pid, &lock);
if (!proc) {
/* This is normal behavior */
dkprintf("%s: PID %d couldn't be found\n", __func__, pid);
return 0;
}
__process_cleanup_fd(proc, fd);
process_unlock(proc, &lock);
return 0;
}
int process_cleanup_before_terminate(int pid)
{
struct process *proc;
struct mcs_rwlock_node_irqsave lock;
int fd;
proc = find_process(pid, &lock);
if (!proc) {
/* This is normal behavior */
return 0;
}
/* Clean up PDE file descriptors */
for (fd = 2; fd < MAX_FD_PDE; ++fd) {
__process_cleanup_fd(proc, fd);
}
process_unlock(proc, &lock);
return 0;
}
void
terminate_host(int pid, struct thread *thread)
{
@@ -4032,15 +4091,14 @@ SYSCALL_DECLARE(close)
#ifdef ENABLE_TOFU
/* Clear path and PDE data */
if (fd >= 0 && fd < MAX_FD_PDE) {
if (thread->proc->enable_tofu &&
fd >= 0 && fd < MAX_FD_PDE) {
/* Tofu? */
if (thread->proc->fd_pde_data[fd]) {
extern void tof_utofu_release_fd(struct process *proc, int fd);
if (thread->proc->fd_path[fd]) {
dkprintf("%s: -> tof_utofu_release_fd() @ fd: %d (%s)\n",
__func__, fd, thread->proc->fd_path[fd]);
}
dkprintf("%s: -> tof_utofu_release_fd() @ fd: %d (%s)\n",
__func__, fd, thread->proc->fd_path[fd]);
tof_utofu_release_fd(thread->proc, fd);
thread->proc->fd_pde_data[fd] = NULL;
}

View File

@@ -896,16 +896,18 @@ static void tof_utofu_trans_update(struct tof_utofu_cq *ucq, int stag, uintptr_t
struct tof_trans_table ent;
uint64_t atomic;
} tmp;
unsigned long flags;
tmp.ent.steering.bits.start = start >> PAGE_SHIFT;
tmp.ent.steering.bits.len = len >> PAGE_SHIFT;
tmp.ent.steering.bits.ps_code = (pgszbits == PAGE_SHIFT)? TOF_STAG_TRANS_PS_CODE_64KB:TOF_STAG_TRANS_PS_CODE_2MB;
//atomic64_set((atomic64_t *)&table[stag], tmp.atomic);
ihk_atomic64_set((ihk_atomic64_t *)&table[stag], tmp.atomic);
linux_spin_lock(&ucq->trans.mru_lock);
linux_spin_lock_irqsave(&ucq->trans.mru_lock, flags);
tof_utofu_trans_mru_delete(ucq, stag);
tof_utofu_trans_mru_insert(ucq, stag, pgszbits, mbpt);
linux_spin_unlock(&ucq->trans.mru_lock);
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, flags);
}
@@ -1009,6 +1011,7 @@ static int tof_utofu_ioctl_alloc_stag(struct tof_utofu_device *dev, unsigned lon
uint8_t pgszbits;
size_t pgsz;
int ret = -ENOTSUPP;
unsigned long irqflags;
ucq = container_of(dev, struct tof_utofu_cq, common);
if(!ucq->common.enabled){
@@ -1054,9 +1057,9 @@ static int tof_utofu_ioctl_alloc_stag(struct tof_utofu_device *dev, unsigned lon
#if 1
/* normal stag */
int stag;
linux_spin_lock(&ucq->trans.mru_lock);
linux_spin_lock_irqsave(&ucq->trans.mru_lock, irqflags);
stag = tof_utofu_trans_search(ucq, start, end, pgszbits, readonly);
linux_spin_unlock(&ucq->trans.mru_lock);
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, irqflags);
if(stag < 0){
struct tof_utofu_mbpt *mbpt = NULL;
stag = tof_utofu_reserve_stag(ucq, readonly);
@@ -1304,6 +1307,7 @@ static int tof_utofu_ioctl_free_stags(struct tof_utofu_device *dev, unsigned lon
struct tof_free_stags req;
int i, no_free_cnt = 0, ret;
int stags[1024];
unsigned long irqflags;
ucq = container_of(dev, struct tof_utofu_cq, common);
@@ -1325,9 +1329,9 @@ static int tof_utofu_ioctl_free_stags(struct tof_utofu_device *dev, unsigned lon
}
for(i = 0; i < req.num; i++){
linux_spin_lock(&ucq->trans.mru_lock);
linux_spin_lock_irqsave(&ucq->trans.mru_lock, irqflags);
ret = tof_utofu_free_stag(ucq, stags[i]);
linux_spin_unlock(&ucq->trans.mru_lock);
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, irqflags);
if(ret == 0){
stags[i] = -1;
}
@@ -1372,6 +1376,7 @@ void tof_utofu_release_cq(void *pde_data)
struct tof_utofu_cq *ucq;
int stag;
struct tof_utofu_device *dev;
unsigned long irqflags;
dev = (struct tof_utofu_device *)pde_data;
ucq = container_of(dev, struct tof_utofu_cq, common);
@@ -1383,9 +1388,9 @@ void tof_utofu_release_cq(void *pde_data)
}
for (stag = 0; stag < TOF_UTOFU_NUM_STAG(ucq->num_stag); stag++) {
linux_spin_lock(&ucq->trans.mru_lock);
linux_spin_lock_irqsave(&ucq->trans.mru_lock, irqflags);
tof_utofu_free_stag(ucq, stag);
linux_spin_unlock(&ucq->trans.mru_lock);
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, irqflags);
}
dkprintf("%s: UCQ (pde: %p) TNI %d, CQ %d\n",
@@ -1911,6 +1916,8 @@ static int tof_utofu_disable_bch(struct tof_utofu_bg *ubg){
//tof_smmu_release_ipa_bg(ubg->tni, ubg->bgid, ubg->bch.iova, TOF_ICC_BCH_DMA_ALIGN);
//put_page(ubg->bch.page);
ubg->bch.enabled = false;
smp_mb();
dkprintf("%s: tni=%d bgid=%d\n", __func__, ubg->tni, ubg->bgid);
return 0;
}
@@ -2084,11 +2091,15 @@ void tof_utofu_release_fd(struct process *proc, int fd)
return;
}
if (strstr((const char *)proc->fd_path, "cq")) {
if (strstr((const char *)proc->fd_path[fd], "cq")) {
dkprintf("%s: PID: %d, fd: %d -> release CQ\n",
__func__, proc->pid, fd);
tof_utofu_release_cq(proc->fd_pde_data[fd]);
}
else if (strstr((const char *)proc->fd_path, "bch")) {
else if (strstr((const char *)proc->fd_path[fd], "bch")) {
dkprintf("%s: PID: %d, fd: %d -> release BCH\n",
__func__, proc->pid, fd);
tof_utofu_release_bch(proc->fd_pde_data[fd]);
}
}