cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

kcmproc.c (8873B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <linux/in.h>
      3#include <linux/inet.h>
      4#include <linux/list.h>
      5#include <linux/module.h>
      6#include <linux/net.h>
      7#include <linux/proc_fs.h>
      8#include <linux/rculist.h>
      9#include <linux/seq_file.h>
     10#include <linux/socket.h>
     11#include <net/inet_sock.h>
     12#include <net/kcm.h>
     13#include <net/net_namespace.h>
     14#include <net/netns/generic.h>
     15#include <net/tcp.h>
     16
     17#ifdef CONFIG_PROC_FS
     18static struct kcm_mux *kcm_get_first(struct seq_file *seq)
     19{
     20	struct net *net = seq_file_net(seq);
     21	struct kcm_net *knet = net_generic(net, kcm_net_id);
     22
     23	return list_first_or_null_rcu(&knet->mux_list,
     24				      struct kcm_mux, kcm_mux_list);
     25}
     26
     27static struct kcm_mux *kcm_get_next(struct kcm_mux *mux)
     28{
     29	struct kcm_net *knet = mux->knet;
     30
     31	return list_next_or_null_rcu(&knet->mux_list, &mux->kcm_mux_list,
     32				     struct kcm_mux, kcm_mux_list);
     33}
     34
     35static struct kcm_mux *kcm_get_idx(struct seq_file *seq, loff_t pos)
     36{
     37	struct net *net = seq_file_net(seq);
     38	struct kcm_net *knet = net_generic(net, kcm_net_id);
     39	struct kcm_mux *m;
     40
     41	list_for_each_entry_rcu(m, &knet->mux_list, kcm_mux_list) {
     42		if (!pos)
     43			return m;
     44		--pos;
     45	}
     46	return NULL;
     47}
     48
     49static void *kcm_seq_next(struct seq_file *seq, void *v, loff_t *pos)
     50{
     51	void *p;
     52
     53	if (v == SEQ_START_TOKEN)
     54		p = kcm_get_first(seq);
     55	else
     56		p = kcm_get_next(v);
     57	++*pos;
     58	return p;
     59}
     60
     61static void *kcm_seq_start(struct seq_file *seq, loff_t *pos)
     62	__acquires(rcu)
     63{
     64	rcu_read_lock();
     65
     66	if (!*pos)
     67		return SEQ_START_TOKEN;
     68	else
     69		return kcm_get_idx(seq, *pos - 1);
     70}
     71
     72static void kcm_seq_stop(struct seq_file *seq, void *v)
     73	__releases(rcu)
     74{
     75	rcu_read_unlock();
     76}
     77
     78struct kcm_proc_mux_state {
     79	struct seq_net_private p;
     80	int idx;
     81};
     82
     83static void kcm_format_mux_header(struct seq_file *seq)
     84{
     85	struct net *net = seq_file_net(seq);
     86	struct kcm_net *knet = net_generic(net, kcm_net_id);
     87
     88	seq_printf(seq,
     89		   "*** KCM statistics (%d MUX) ****\n",
     90		   knet->count);
     91
     92	seq_printf(seq,
     93		   "%-14s %-10s %-16s %-10s %-16s %-8s %-8s %-8s %-8s %s",
     94		   "Object",
     95		   "RX-Msgs",
     96		   "RX-Bytes",
     97		   "TX-Msgs",
     98		   "TX-Bytes",
     99		   "Recv-Q",
    100		   "Rmem",
    101		   "Send-Q",
    102		   "Smem",
    103		   "Status");
    104
    105	/* XXX: pdsts header stuff here */
    106	seq_puts(seq, "\n");
    107}
    108
    109static void kcm_format_sock(struct kcm_sock *kcm, struct seq_file *seq,
    110			    int i, int *len)
    111{
    112	seq_printf(seq,
    113		   "   kcm-%-7u %-10llu %-16llu %-10llu %-16llu %-8d %-8d %-8d %-8s ",
    114		   kcm->index,
    115		   kcm->stats.rx_msgs,
    116		   kcm->stats.rx_bytes,
    117		   kcm->stats.tx_msgs,
    118		   kcm->stats.tx_bytes,
    119		   kcm->sk.sk_receive_queue.qlen,
    120		   sk_rmem_alloc_get(&kcm->sk),
    121		   kcm->sk.sk_write_queue.qlen,
    122		   "-");
    123
    124	if (kcm->tx_psock)
    125		seq_printf(seq, "Psck-%u ", kcm->tx_psock->index);
    126
    127	if (kcm->tx_wait)
    128		seq_puts(seq, "TxWait ");
    129
    130	if (kcm->tx_wait_more)
    131		seq_puts(seq, "WMore ");
    132
    133	if (kcm->rx_wait)
    134		seq_puts(seq, "RxWait ");
    135
    136	seq_puts(seq, "\n");
    137}
    138
    139static void kcm_format_psock(struct kcm_psock *psock, struct seq_file *seq,
    140			     int i, int *len)
    141{
    142	seq_printf(seq,
    143		   "   psock-%-5u %-10llu %-16llu %-10llu %-16llu %-8d %-8d %-8d %-8d ",
    144		   psock->index,
    145		   psock->strp.stats.msgs,
    146		   psock->strp.stats.bytes,
    147		   psock->stats.tx_msgs,
    148		   psock->stats.tx_bytes,
    149		   psock->sk->sk_receive_queue.qlen,
    150		   atomic_read(&psock->sk->sk_rmem_alloc),
    151		   psock->sk->sk_write_queue.qlen,
    152		   refcount_read(&psock->sk->sk_wmem_alloc));
    153
    154	if (psock->done)
    155		seq_puts(seq, "Done ");
    156
    157	if (psock->tx_stopped)
    158		seq_puts(seq, "TxStop ");
    159
    160	if (psock->strp.stopped)
    161		seq_puts(seq, "RxStop ");
    162
    163	if (psock->tx_kcm)
    164		seq_printf(seq, "Rsvd-%d ", psock->tx_kcm->index);
    165
    166	if (!psock->strp.paused && !psock->ready_rx_msg) {
    167		if (psock->sk->sk_receive_queue.qlen) {
    168			if (psock->strp.need_bytes)
    169				seq_printf(seq, "RxWait=%u ",
    170					   psock->strp.need_bytes);
    171			else
    172				seq_printf(seq, "RxWait ");
    173		}
    174	} else  {
    175		if (psock->strp.paused)
    176			seq_puts(seq, "RxPause ");
    177
    178		if (psock->ready_rx_msg)
    179			seq_puts(seq, "RdyRx ");
    180	}
    181
    182	seq_puts(seq, "\n");
    183}
    184
    185static void
    186kcm_format_mux(struct kcm_mux *mux, loff_t idx, struct seq_file *seq)
    187{
    188	int i, len;
    189	struct kcm_sock *kcm;
    190	struct kcm_psock *psock;
    191
    192	/* mux information */
    193	seq_printf(seq,
    194		   "%-6s%-8s %-10llu %-16llu %-10llu %-16llu %-8s %-8s %-8s %-8s ",
    195		   "mux", "",
    196		   mux->stats.rx_msgs,
    197		   mux->stats.rx_bytes,
    198		   mux->stats.tx_msgs,
    199		   mux->stats.tx_bytes,
    200		   "-", "-", "-", "-");
    201
    202	seq_printf(seq, "KCMs: %d, Psocks %d\n",
    203		   mux->kcm_socks_cnt, mux->psocks_cnt);
    204
    205	/* kcm sock information */
    206	i = 0;
    207	spin_lock_bh(&mux->lock);
    208	list_for_each_entry(kcm, &mux->kcm_socks, kcm_sock_list) {
    209		kcm_format_sock(kcm, seq, i, &len);
    210		i++;
    211	}
    212	i = 0;
    213	list_for_each_entry(psock, &mux->psocks, psock_list) {
    214		kcm_format_psock(psock, seq, i, &len);
    215		i++;
    216	}
    217	spin_unlock_bh(&mux->lock);
    218}
    219
    220static int kcm_seq_show(struct seq_file *seq, void *v)
    221{
    222	struct kcm_proc_mux_state *mux_state;
    223
    224	mux_state = seq->private;
    225	if (v == SEQ_START_TOKEN) {
    226		mux_state->idx = 0;
    227		kcm_format_mux_header(seq);
    228	} else {
    229		kcm_format_mux(v, mux_state->idx, seq);
    230		mux_state->idx++;
    231	}
    232	return 0;
    233}
    234
    235static const struct seq_operations kcm_seq_ops = {
    236	.show	= kcm_seq_show,
    237	.start	= kcm_seq_start,
    238	.next	= kcm_seq_next,
    239	.stop	= kcm_seq_stop,
    240};
    241
    242static int kcm_stats_seq_show(struct seq_file *seq, void *v)
    243{
    244	struct kcm_psock_stats psock_stats;
    245	struct kcm_mux_stats mux_stats;
    246	struct strp_aggr_stats strp_stats;
    247	struct kcm_mux *mux;
    248	struct kcm_psock *psock;
    249	struct net *net = seq->private;
    250	struct kcm_net *knet = net_generic(net, kcm_net_id);
    251
    252	memset(&mux_stats, 0, sizeof(mux_stats));
    253	memset(&psock_stats, 0, sizeof(psock_stats));
    254	memset(&strp_stats, 0, sizeof(strp_stats));
    255
    256	mutex_lock(&knet->mutex);
    257
    258	aggregate_mux_stats(&knet->aggregate_mux_stats, &mux_stats);
    259	aggregate_psock_stats(&knet->aggregate_psock_stats,
    260			      &psock_stats);
    261	aggregate_strp_stats(&knet->aggregate_strp_stats,
    262			     &strp_stats);
    263
    264	list_for_each_entry(mux, &knet->mux_list, kcm_mux_list) {
    265		spin_lock_bh(&mux->lock);
    266		aggregate_mux_stats(&mux->stats, &mux_stats);
    267		aggregate_psock_stats(&mux->aggregate_psock_stats,
    268				      &psock_stats);
    269		aggregate_strp_stats(&mux->aggregate_strp_stats,
    270				     &strp_stats);
    271		list_for_each_entry(psock, &mux->psocks, psock_list) {
    272			aggregate_psock_stats(&psock->stats, &psock_stats);
    273			save_strp_stats(&psock->strp, &strp_stats);
    274		}
    275
    276		spin_unlock_bh(&mux->lock);
    277	}
    278
    279	mutex_unlock(&knet->mutex);
    280
    281	seq_printf(seq,
    282		   "%-8s %-10s %-16s %-10s %-16s %-10s %-10s %-10s %-10s %-10s\n",
    283		   "MUX",
    284		   "RX-Msgs",
    285		   "RX-Bytes",
    286		   "TX-Msgs",
    287		   "TX-Bytes",
    288		   "TX-Retries",
    289		   "Attach",
    290		   "Unattach",
    291		   "UnattchRsvd",
    292		   "RX-RdyDrops");
    293
    294	seq_printf(seq,
    295		   "%-8s %-10llu %-16llu %-10llu %-16llu %-10u %-10u %-10u %-10u %-10u\n",
    296		   "",
    297		   mux_stats.rx_msgs,
    298		   mux_stats.rx_bytes,
    299		   mux_stats.tx_msgs,
    300		   mux_stats.tx_bytes,
    301		   mux_stats.tx_retries,
    302		   mux_stats.psock_attach,
    303		   mux_stats.psock_unattach_rsvd,
    304		   mux_stats.psock_unattach,
    305		   mux_stats.rx_ready_drops);
    306
    307	seq_printf(seq,
    308		   "%-8s %-10s %-16s %-10s %-16s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s\n",
    309		   "Psock",
    310		   "RX-Msgs",
    311		   "RX-Bytes",
    312		   "TX-Msgs",
    313		   "TX-Bytes",
    314		   "Reserved",
    315		   "Unreserved",
    316		   "RX-Aborts",
    317		   "RX-Intr",
    318		   "RX-Unrecov",
    319		   "RX-MemFail",
    320		   "RX-NeedMor",
    321		   "RX-BadLen",
    322		   "RX-TooBig",
    323		   "RX-Timeout",
    324		   "TX-Aborts");
    325
    326	seq_printf(seq,
    327		   "%-8s %-10llu %-16llu %-10llu %-16llu %-10llu %-10llu %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u\n",
    328		   "",
    329		   strp_stats.msgs,
    330		   strp_stats.bytes,
    331		   psock_stats.tx_msgs,
    332		   psock_stats.tx_bytes,
    333		   psock_stats.reserved,
    334		   psock_stats.unreserved,
    335		   strp_stats.aborts,
    336		   strp_stats.interrupted,
    337		   strp_stats.unrecov_intr,
    338		   strp_stats.mem_fail,
    339		   strp_stats.need_more_hdr,
    340		   strp_stats.bad_hdr_len,
    341		   strp_stats.msg_too_big,
    342		   strp_stats.msg_timeouts,
    343		   psock_stats.tx_aborts);
    344
    345	return 0;
    346}
    347
    348static int kcm_proc_init_net(struct net *net)
    349{
    350	if (!proc_create_net_single("kcm_stats", 0444, net->proc_net,
    351			 kcm_stats_seq_show, NULL))
    352		goto out_kcm_stats;
    353
    354	if (!proc_create_net("kcm", 0444, net->proc_net, &kcm_seq_ops,
    355			sizeof(struct kcm_proc_mux_state)))
    356		goto out_kcm;
    357
    358	return 0;
    359
    360out_kcm:
    361	remove_proc_entry("kcm_stats", net->proc_net);
    362out_kcm_stats:
    363	return -ENOMEM;
    364}
    365
    366static void kcm_proc_exit_net(struct net *net)
    367{
    368	remove_proc_entry("kcm", net->proc_net);
    369	remove_proc_entry("kcm_stats", net->proc_net);
    370}
    371
    372static struct pernet_operations kcm_net_ops = {
    373	.init = kcm_proc_init_net,
    374	.exit = kcm_proc_exit_net,
    375};
    376
    377int __init kcm_proc_init(void)
    378{
    379	return register_pernet_subsys(&kcm_net_ops);
    380}
    381
    382void __exit kcm_proc_exit(void)
    383{
    384	unregister_pernet_subsys(&kcm_net_ops);
    385}
    386
    387#endif /* CONFIG_PROC_FS */