at master 3.4 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2 3#include <linux/virtio.h> 4#include <linux/virtio_config.h> 5#include <linux/debugfs.h> 6 7static struct dentry *virtio_debugfs_dir; 8 9static int virtio_debug_device_features_show(struct seq_file *s, void *data) 10{ 11 u64 device_features[VIRTIO_FEATURES_U64S]; 12 struct virtio_device *dev = s->private; 13 unsigned int i; 14 15 virtio_get_features(dev, device_features); 16 for (i = 0; i < VIRTIO_FEATURES_BITS; i++) { 17 if (virtio_features_test_bit(device_features, i)) 18 seq_printf(s, "%u\n", i); 19 } 20 return 0; 21} 22DEFINE_SHOW_ATTRIBUTE(virtio_debug_device_features); 23 24static int virtio_debug_filter_features_show(struct seq_file *s, void *data) 25{ 26 struct virtio_device *dev = s->private; 27 unsigned int i; 28 29 for (i = 0; i < VIRTIO_FEATURES_BITS; i++) { 30 if (virtio_features_test_bit(dev->debugfs_filter_features, i)) 31 seq_printf(s, "%u\n", i); 32 } 33 return 0; 34} 35DEFINE_SHOW_ATTRIBUTE(virtio_debug_filter_features); 36 37static int virtio_debug_filter_features_clear(void *data, u64 val) 38{ 39 struct virtio_device *dev = data; 40 41 if (val == 1) 42 virtio_features_zero(dev->debugfs_filter_features); 43 return 0; 44} 45 46DEFINE_DEBUGFS_ATTRIBUTE(virtio_debug_filter_features_clear_fops, NULL, 47 virtio_debug_filter_features_clear, "%llu\n"); 48 49static int virtio_debug_filter_feature_add(void *data, u64 val) 50{ 51 struct virtio_device *dev = data; 52 53 if (val >= VIRTIO_FEATURES_BITS) 54 return -EINVAL; 55 56 virtio_features_set_bit(dev->debugfs_filter_features, val); 57 return 0; 58} 59 60DEFINE_DEBUGFS_ATTRIBUTE(virtio_debug_filter_feature_add_fops, NULL, 61 virtio_debug_filter_feature_add, "%llu\n"); 62 63static int virtio_debug_filter_feature_del(void *data, u64 val) 64{ 65 struct virtio_device *dev = data; 66 67 if (val >= VIRTIO_FEATURES_BITS) 68 return -EINVAL; 69 70 virtio_features_clear_bit(dev->debugfs_filter_features, val); 71 return 0; 72} 73 74DEFINE_DEBUGFS_ATTRIBUTE(virtio_debug_filter_feature_del_fops, NULL, 75 virtio_debug_filter_feature_del, "%llu\n"); 76 77void virtio_debug_device_init(struct virtio_device *dev) 78{ 79 dev->debugfs_dir = debugfs_create_dir(dev_name(&dev->dev), 80 virtio_debugfs_dir); 81 debugfs_create_file("device_features", 0400, dev->debugfs_dir, dev, 82 &virtio_debug_device_features_fops); 83 debugfs_create_file("filter_features", 0400, dev->debugfs_dir, dev, 84 &virtio_debug_filter_features_fops); 85 debugfs_create_file("filter_features_clear", 0200, dev->debugfs_dir, dev, 86 &virtio_debug_filter_features_clear_fops); 87 debugfs_create_file("filter_feature_add", 0200, dev->debugfs_dir, dev, 88 &virtio_debug_filter_feature_add_fops); 89 debugfs_create_file("filter_feature_del", 0200, dev->debugfs_dir, dev, 90 &virtio_debug_filter_feature_del_fops); 91} 92EXPORT_SYMBOL_GPL(virtio_debug_device_init); 93 94void virtio_debug_device_filter_features(struct virtio_device *dev) 95{ 96 virtio_features_andnot(dev->features_array, dev->features_array, 97 dev->debugfs_filter_features); 98} 99EXPORT_SYMBOL_GPL(virtio_debug_device_filter_features); 100 101void virtio_debug_device_exit(struct virtio_device *dev) 102{ 103 debugfs_remove_recursive(dev->debugfs_dir); 104} 105EXPORT_SYMBOL_GPL(virtio_debug_device_exit); 106 107void virtio_debug_init(void) 108{ 109 virtio_debugfs_dir = debugfs_create_dir("virtio", NULL); 110} 111EXPORT_SYMBOL_GPL(virtio_debug_init); 112 113void virtio_debug_exit(void) 114{ 115 debugfs_remove_recursive(virtio_debugfs_dir); 116} 117EXPORT_SYMBOL_GPL(virtio_debug_exit);