bdev/nvme: account for 2MB straddle in queued_next_sge()
This function needs to check for SGEs that straddle a 2MB page boundary, and ensure it does not return a length that will cross that boundary. This cannot happen in practice currently with SPDK since all buffers are allocated using rte_malloc(), but an upcoming vhost-scsi target may produce SGEs from a guest VM's physical memory that span a 2MB boundary. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: I8b83c7c39c4cf33815abb22ff2ebc90941b21e28
This commit is contained in:
parent
aac30ff3f4
commit
0095e2b994
@ -639,6 +639,10 @@ queued_reset_sgl(void *ref, uint32_t sgl_offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define min(a, b) (((a)<(b))?(a):(b))
|
||||||
|
|
||||||
|
#define _2MB_OFFSET(ptr) (((uintptr_t)ptr) & (0x200000 - 1))
|
||||||
|
|
||||||
static int
|
static int
|
||||||
queued_next_sge(void *ref, void **address, uint32_t *length)
|
queued_next_sge(void *ref, void **address, uint32_t *length)
|
||||||
{
|
{
|
||||||
@ -658,6 +662,8 @@ queued_next_sge(void *ref, void **address, uint32_t *length)
|
|||||||
*length -= bio->iov_offset;
|
*length -= bio->iov_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*length = min(*length, 0x200000 - _2MB_OFFSET(*address));
|
||||||
|
|
||||||
bio->iov_offset += *length;
|
bio->iov_offset += *length;
|
||||||
if (bio->iov_offset == iov->iov_len) {
|
if (bio->iov_offset == iov->iov_len) {
|
||||||
bio->iovpos++;
|
bio->iovpos++;
|
||||||
|
Loading…
Reference in New Issue
Block a user