Greetings, while working on a driver, I've found a bug that I'm unable to understand. I assume that I'm doing something wrong. here is my reduced c file: #include <linux/string.h> #include <linux/module.h> #include <linux/pci.h> /* modules info */ #define DEVICE_NAME "vSMP" #define DRIVER_LICENSE "GPL v2" #define DRIVER_AUTHOR "Eial Czerwacki <eial.czerwacki@xxxxxxx>" #define DRIVER_DESC "vSMP hypervisor driver" #define DRIVER_VERSION "0.1" #define PCI_DEVICE_ID_SAP_FLX_VSMP_CTL 0x1011 #define ROOT_SYFS_FOLDER "vsmp" #define DEVICE_ATTR_NAME(_name_) &dev_attr_##_name_ .attr #ifndef sysfs_emit #define sysfs_emit sprintf #endif // sysfs_emit MODULE_LICENSE(DRIVER_LICENSE); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_VERSION(DRIVER_VERSION); #define MAX_LABEL_LEN 81 struct data { char version[MAX_LABEL_LEN]; struct pci_dev *pdev; struct kobject *kobj; }; static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) { struct data *d = dev_get_drvdata(dev); return sysfs_emit(buf, "%s\n", d->version); } DEVICE_ATTR_RO(version); static int populate_version(struct data *d) { int ret_val; snprintf(d->version, sizeof(d->version) - 1, "%u.%u.%u.%u", 1,2,3,4); ret_val = sysfs_add_file_to_group(d->kobj, DEVICE_ATTR_NAME(version), NULL); if (ret_val) { dev_err(&d->pdev->dev, "Failed to create version entry, error (%d)\n", ret_val); return -EINVAL; } dev_info(&d->pdev->dev, "version is %s\n", d->version); return ret_val; } static const struct pci_device_id vsmp_pci_table[] = { { PCI_VDEVICE(SCALEMP, PCI_DEVICE_ID_SAP_FLX_VSMP_CTL), 0, }, { 0, }, /* terminate list */ }; static int vsmp_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) { struct data *d; int ret_val = 0; d = devm_kzalloc(&pci->dev, sizeof(*d), GFP_KERNEL); if (IS_ERR(d)) return PTR_ERR(d); d->pdev = pci; pci_set_drvdata(pci, d); d->kobj = kobject_create_and_add(ROOT_SYFS_FOLDER, &d->pdev->dev.kobj); if (!d->kobj) { kfree(d); dev_err(&d->pdev->dev, "Failed to create vSMP sysfs entry.\n"); return -EINVAL; } ret_val = sysfs_create_link(hypervisor_kobj, d->kobj, ROOT_SYFS_FOLDER); if (ret_val) { kobject_del(d->kobj); kfree(d); dev_err(&d->pdev->dev, "Failed to link obj to hypervisor, error (%d)\n", ret_val); return ret_val; } populate_version(d); dev_info(&d->pdev->dev, "Driver up and running\n"); return ret_val; } static void vsmp_pci_remove(struct pci_dev *pci) { struct data *d = pci_get_drvdata(pci); kobject_del(d->kobj); sysfs_remove_link(hypervisor_kobj, ROOT_SYFS_FOLDER); kfree(d); } static struct pci_driver vsmp_pci_driver = { .name = DEVICE_NAME, .id_table = vsmp_pci_table, .probe = vsmp_pci_probe, .remove = vsmp_pci_remove, }; module_pci_driver(vsmp_pci_driver); it compiles well (the kernel I use doesn't have sysfs_emit so I had to improvise) and loads well but when I cat the version file, I don't get valid data. even with printks. printing the addresses of d from the init and the d inside the show attr func returns different addresses. can anyone help me understand what I'm doing wrong? Thanks, Eial