eliminate virtio DMA into kernel stacks.

This commit is contained in:
Robert Morris 2020-10-05 06:59:33 -04:00 committed by Frans Kaashoek
parent 3092fe2c9e
commit c61cc69413
3 changed files with 11 additions and 30 deletions

View file

@ -156,7 +156,6 @@ int uartgetc(void);
// vm.c // vm.c
void kvminit(void); void kvminit(void);
void kvminithart(void); void kvminithart(void);
uint64 kvmpa(uint64);
void kvmmap(uint64, uint64, uint64, int); void kvmmap(uint64, uint64, uint64, int);
int mappages(pagetable_t, uint64, uint64, uint64, int); int mappages(pagetable_t, uint64, uint64, uint64, int);
pagetable_t uvmcreate(void); pagetable_t uvmcreate(void);

View file

@ -65,6 +65,10 @@ static struct disk {
char status; char status;
} info[NUM]; } info[NUM];
// disk command headers.
// one-for-one with descriptors, for convenience.
struct virtio_blk_req ops[NUM];
struct spinlock vdisk_lock; struct spinlock vdisk_lock;
} __attribute__ ((aligned (PGSIZE))) disk; } __attribute__ ((aligned (PGSIZE))) disk;
@ -219,19 +223,17 @@ virtio_disk_rw(struct buf *b, int write)
// format the three descriptors. // format the three descriptors.
// qemu's virtio-blk.c reads them. // qemu's virtio-blk.c reads them.
struct virtio_blk_req buf0; struct virtio_blk_req *buf0 = &disk.ops[idx[0]];
if(write) if(write)
buf0.type = VIRTIO_BLK_T_OUT; // write the disk buf0->type = VIRTIO_BLK_T_OUT; // write the disk
else else
buf0.type = VIRTIO_BLK_T_IN; // read the disk buf0->type = VIRTIO_BLK_T_IN; // read the disk
buf0.reserved = 0; buf0->reserved = 0;
buf0.sector = sector; buf0->sector = sector;
// buf0 is on a kernel stack, which is not direct mapped, disk.desc[idx[0]].addr = (uint64) buf0;
// thus the call to kvmpa(). disk.desc[idx[0]].len = sizeof(struct virtio_blk_req);
disk.desc[idx[0]].addr = (uint64) kvmpa((uint64) &buf0);
disk.desc[idx[0]].len = sizeof(buf0);
disk.desc[idx[0]].flags = VRING_DESC_F_NEXT; disk.desc[idx[0]].flags = VRING_DESC_F_NEXT;
disk.desc[idx[0]].next = idx[1]; disk.desc[idx[0]].next = idx[1];

View file

@ -121,26 +121,6 @@ kvmmap(uint64 va, uint64 pa, uint64 sz, int perm)
panic("kvmmap"); panic("kvmmap");
} }
// translate a kernel virtual address to
// a physical address. only needed for
// addresses on the stack.
// assumes va is page aligned.
uint64
kvmpa(uint64 va)
{
uint64 off = va % PGSIZE;
pte_t *pte;
uint64 pa;
pte = walk(kernel_pagetable, va, 0);
if(pte == 0)
panic("kvmpa");
if((*pte & PTE_V) == 0)
panic("kvmpa");
pa = PTE2PA(*pte);
return pa+off;
}
// Create PTEs for virtual addresses starting at va that refer to // Create PTEs for virtual addresses starting at va that refer to
// physical addresses starting at pa. va and size might not // physical addresses starting at pa. va and size might not
// be page-aligned. Returns 0 on success, -1 if walk() couldn't // be page-aligned. Returns 0 on success, -1 if walk() couldn't