eliminate virtio DMA into kernel stacks.
This commit is contained in:
parent
3092fe2c9e
commit
c61cc69413
|
@ -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);
|
||||||
|
|
|
@ -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];
|
||||||
|
|
||||||
|
|
20
kernel/vm.c
20
kernel/vm.c
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue