Skip to content

Commit 2fa3b1d

Browse files
Merge pull request #186 from bo3z/bugfix/driver-fixes
Various driver fixes and safe-guards
2 parents 0f4196d + 90f391d commit 2fa3b1d

File tree

4 files changed

+40
-7
lines changed

4 files changed

+40
-7
lines changed

driver/src/coyote_setup.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,20 @@ int setup_vfpga_devices(struct bus_driver_data *data) {
445445
device_destroy(data->vfpga_class, MKDEV(data->vfpga_major, j));
446446
cdev_del(&data->vfpga_dev[j].cdev);
447447
}
448-
if( data->en_wb) {
448+
// Unmap control register regions if they were mapped
449+
if (data->vfpga_dev[i].fpga_lTlb) {
450+
iounmap(data->vfpga_dev[i].fpga_lTlb);
451+
data->vfpga_dev[i].fpga_lTlb = NULL;
452+
}
453+
if (data->vfpga_dev[i].fpga_sTlb) {
454+
iounmap(data->vfpga_dev[i].fpga_sTlb);
455+
data->vfpga_dev[i].fpga_sTlb = NULL;
456+
}
457+
if (data->vfpga_dev[i].cnfg_regs) {
458+
iounmap(data->vfpga_dev[i].cnfg_regs);
459+
data->vfpga_dev[i].cnfg_regs = NULL;
460+
}
461+
if (data->en_wb) {
449462
set_memory_wb((uint64_t)data->vfpga_dev[i].wb_addr_virt, N_WB_PAGES);
450463
dma_free_coherent(&data->pci_dev->dev, WB_SIZE, data->vfpga_dev[i].wb_addr_virt, data->vfpga_dev[i].wb_phys_addr);
451464
}
@@ -487,6 +500,20 @@ void teardown_vfpga_devices(struct bus_driver_data *data) {
487500
device_destroy(data->vfpga_class, MKDEV(data->vfpga_major, i));
488501
cdev_del(&data->vfpga_dev[i].cdev);
489502

503+
// Unmap control register regions if they were mapped
504+
if (data->vfpga_dev[i].fpga_lTlb) {
505+
iounmap(data->vfpga_dev[i].fpga_lTlb);
506+
data->vfpga_dev[i].fpga_lTlb = NULL;
507+
}
508+
if (data->vfpga_dev[i].fpga_sTlb) {
509+
iounmap(data->vfpga_dev[i].fpga_sTlb);
510+
data->vfpga_dev[i].fpga_sTlb = NULL;
511+
}
512+
if (data->vfpga_dev[i].cnfg_regs) {
513+
iounmap(data->vfpga_dev[i].cnfg_regs);
514+
data->vfpga_dev[i].cnfg_regs = NULL;
515+
}
516+
490517
if(data->en_wb) {
491518
set_memory_wb((uint64_t)data->vfpga_dev[i].wb_addr_virt, N_WB_PAGES);
492519
dma_free_coherent(&data->pci_dev->dev, WB_SIZE, data->vfpga_dev[i].wb_addr_virt, data->vfpga_dev[i].wb_phys_addr);

driver/src/vfpga/vfpga_gup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ struct user_pages* tlb_get_user_pages(struct vfpga_dev *device, struct pf_aligne
281281

282282
user_pg->pages = vmalloc(pf_desc->n_pages * sizeof(*user_pg->pages));
283283
BUG_ON(!user_pg->pages);
284-
for (int i = 0; i < pf_desc->n_pages - 1; i++) {
284+
for (int i = 0; i < pf_desc->n_pages; i++) {
285285
user_pg->pages[i] = NULL;
286286
}
287287

driver/src/vfpga/vfpga_isr.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ irqreturn_t vfpga_isr(int irq, void *d) {
5858
case IRQ_PFAULT:
5959
// vFPGA issued page fault; issue asynchronous work via vfpga_pfault_handler to handle the page fault
6060
dbg_info("(irq=%d) page fault, vFPGA %d\n", irq, device->id);
61-
struct vfpga_irq_pfault *irq_pf = kzalloc(sizeof(struct vfpga_irq_pfault), GFP_KERNEL);
61+
struct vfpga_irq_pfault *irq_pf = kzalloc(sizeof(struct vfpga_irq_pfault), GFP_ATOMIC);
6262
BUG_ON(!irq_pf);
6363

6464
irq_pf->device = device;
@@ -67,14 +67,15 @@ irqreturn_t vfpga_isr(int irq, void *d) {
6767
INIT_WORK(&irq_pf->work_pfault, vfpga_pfault_handler);
6868

6969
if(!queue_work(device->wqueue_pfault, &irq_pf->work_pfault)) {
70-
pr_err("could not enqueue a workqueue, page fault ISR");
70+
pr_err("could not enqueue a workqueue, page fault ISR\n");
71+
kfree(irq_pf);
7172
}
7273
break;
7374

7475
case IRQ_NOTIFY:
7576
// vFPGA issued a user interrupt (notification); issue asynchronous work via vfpga_notify_handler to handle the user interrupt
7677
dbg_info("(irq=%d) notify, vFPGA %d\n", irq, device->id);
77-
struct vfpga_irq_notify *irq_not = kzalloc(sizeof(struct vfpga_irq_notify), GFP_KERNEL);
78+
struct vfpga_irq_notify *irq_not = kzalloc(sizeof(struct vfpga_irq_notify), GFP_ATOMIC);
7879
BUG_ON(!irq_not);
7980

8081
irq_not->device = device;
@@ -83,7 +84,8 @@ irqreturn_t vfpga_isr(int irq, void *d) {
8384
INIT_WORK(&irq_not->work_notify, vfpga_notify_handler);
8485

8586
if(!queue_work(device->wqueue_notify, &irq_not->work_notify)) {
86-
pr_err("could not enqueue a workqueue, notify ISR");
87+
pr_err("could not enqueue a workqueue, notify ISR\n");
88+
kfree(irq_not);
8789
}
8890
break;
8991

@@ -186,7 +188,10 @@ void vfpga_pfault_handler(struct work_struct *work) {
186188
mutex_unlock(&device->mmu_lock);
187189
dbg_info("page fault vFPGA %d handled\n", device->id);
188190
kfree(irq_pf);
191+
return;
189192

190193
err_mmu:
194+
mutex_unlock(&device->mmu_lock);
195+
kfree(irq_pf);
191196
return;
192197
}

driver/src/vfpga/vfpga_ops.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ long vfpga_dev_ioctl(struct file *file, unsigned int command, unsigned long arg)
135135
// Check if a new Coyote thread can be registered
136136
if (device->num_free_ctid_chunks == 0) {
137137
dbg_info("no free ctid chunks left for hpid %d, spid %d\n", hpid, spid);
138+
mutex_unlock(&device->pid_lock);
138139
return -ENOMEM;
139140
}
140141

@@ -663,7 +664,7 @@ int vfpga_dev_mmap(struct file *file, struct vm_area_struct *vma) {
663664

664665
// dma_mmap_coherent expects vma->pg_offs to be 0; hence MMAP_WB was changed to 0 and MMAP_CTRL to 3
665666
int ret_val = dma_mmap_coherent(
666-
&device->bd_data->pci_dev->dev, vma, (void *) device->wb_addr_virt, device->wb_phys_addr, PAGE_SIZE
667+
&device->bd_data->pci_dev->dev, vma, (void *) device->wb_addr_virt, device->wb_phys_addr, WB_SIZE
667668
);
668669

669670
if (ret_val) {

0 commit comments

Comments
 (0)