diag: Remove memory device entries while mhi disconnect

When mhi remove call on diag channels is issued clear memory
device table entries including buffer information to prevent
any race condition of using the buffers queued for copying
to diag userspace clients.

Change-Id: Ie311c63c5fce31e43d7c93c23f27cfe0e2e2d64f
Signed-off-by: Manoj Prabhu B <bmanoj@codeaurora.org>
tirimbino
Manoj Prabhu B 5 years ago
parent 1e8f2043da
commit 150d7530a3
  1. 43
      drivers/char/diag/diag_memorydevice.c
  2. 3
      drivers/char/diag/diag_memorydevice.h
  3. 18
      drivers/char/diag/diag_mux.c
  4. 4
      drivers/char/diag/diag_mux.h
  5. 7
      drivers/char/diag/diagfwd_bridge.c

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -153,6 +153,8 @@ void diag_md_close_device(int id)
* When we close the Memory device mode, make sure we flush the
* internal buffers in the table so that there are no stale
* entries.
* Give Write_done notifications to buffers with packets
* indicated valid length.
*/
spin_lock_irqsave(&ch->lock, flags);
for (j = 0; j < ch->num_tbl_entries; j++) {
@ -168,9 +170,37 @@ void diag_md_close_device(int id)
entry->ctx = 0;
}
spin_unlock_irqrestore(&ch->lock, flags);
diag_ws_reset(DIAG_WS_MUX);
}
void diag_md_clear_tbl_entries(int id)
{
int j;
unsigned long flags;
struct diag_md_info *ch = NULL;
struct diag_buf_tbl_t *entry = NULL;
ch = &diag_md[id];
if (!ch || !ch->md_info_inited)
return;
/*
* When we close the Memory device mode, make sure we flush the
* internal buffers in the table so that there are no stale
* entries.
*/
spin_lock_irqsave(&ch->lock, flags);
for (j = 0; j < ch->num_tbl_entries; j++) {
entry = &ch->tbl[j];
entry->buf = NULL;
entry->len = 0;
entry->ctx = 0;
}
spin_unlock_irqrestore(&ch->lock, flags);
diag_ws_reset(DIAG_WS_MUX);
}
int diag_md_write(int id, unsigned char *buf, int len, int ctx)
{
int i, peripheral, pid = 0;
@ -302,13 +332,18 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
if (!ch->md_info_inited)
continue;
for (j = 0; j < ch->num_tbl_entries && !err; j++) {
spin_lock_irqsave(&ch->lock, flags);
entry = &ch->tbl[j];
if (entry->len <= 0 || entry->buf == NULL)
if (entry->len <= 0 || entry->buf == NULL) {
spin_unlock_irqrestore(&ch->lock, flags);
continue;
}
peripheral = diag_md_get_peripheral(entry->ctx);
if (peripheral < 0)
if (peripheral < 0) {
spin_unlock_irqrestore(&ch->lock, flags);
goto drop_data;
}
spin_unlock_irqrestore(&ch->lock, flags);
session_info =
diag_md_session_get_peripheral(i, peripheral);
if (!session_info)

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2015, 2017-2019 The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2015, 2017-2020 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -41,6 +41,7 @@ void diag_md_open_all(void);
void diag_md_close_all(void);
void diag_md_open_device(int id);
void diag_md_close_device(int id);
void diag_md_clear_tbl_entries(int id);
int diag_md_register(int id, int ctx, struct diag_mux_ops *ops);
int diag_md_close_peripheral(int id, uint8_t peripheral);
int diag_md_write(int id, unsigned char *buf, int len, int ctx);

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2017, 2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2017, 2019-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -42,6 +42,7 @@ static struct diag_logger_ops usb_log_ops = {
.queue_read = diag_usb_queue_read,
.open_device = diag_usb_connect_device,
.close_device = diag_usb_disconnect_device,
.clear_tbl_entries = NULL,
.write = diag_usb_write,
.close_peripheral = NULL
};
@ -51,6 +52,7 @@ static struct diag_logger_ops md_log_ops = {
.close = diag_md_close_all,
.open_device = diag_md_open_device,
.close_device = diag_md_close_device,
.clear_tbl_entries = diag_md_clear_tbl_entries,
.queue_read = NULL,
.write = diag_md_write,
.close_peripheral = diag_md_close_peripheral,
@ -293,6 +295,20 @@ int diag_mux_close_peripheral(int proc, uint8_t peripheral)
return 0;
}
void diag_mux_close_device(int proc)
{
struct diag_logger_t *logger = NULL;
if (!diag_mux)
return;
logger = diag_mux->logger[proc];
if (logger && logger->log_ops && logger->log_ops->clear_tbl_entries)
logger->log_ops->clear_tbl_entries(proc);
}
int diag_mux_switch_logging(int proc, int *req_mode, int *peripheral_mask)
{
unsigned int new_mask = 0;

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -52,6 +52,7 @@ struct diag_logger_ops {
void (*close)(void);
void (*open_device)(int id);
void (*close_device)(int id);
void (*clear_tbl_entries)(int id);
int (*queue_read)(int id);
int (*write)(int id, unsigned char *buf, int len, int ctx);
int (*close_peripheral)(int id, uint8_t peripheral);
@ -71,6 +72,7 @@ int diag_mux_register(int proc, int ctx, struct diag_mux_ops *ops);
int diag_mux_queue_read(int proc);
int diag_mux_write(int proc, unsigned char *buf, int len, int ctx);
int diag_mux_close_peripheral(int proc, uint8_t peripheral);
void diag_mux_close_device(int proc);
int diag_mux_open_all(struct diag_logger_t *logger);
int diag_mux_close_all(void);
int diag_pcie_register_ops(int proc, int ctx, struct diag_mux_ops *ops);

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -175,6 +175,11 @@ int diag_remote_dev_open(int id)
void diag_remote_dev_close(int id)
{
if (id < 0 || id >= NUM_REMOTE_DEV)
return;
diag_mux_close_device(BRIDGE_TO_MUX(id));
}
int diag_remote_dev_read_done(int id, unsigned char *buf, int len)

Loading…
Cancel
Save