Skip to content

Commit

Permalink
s390/qdio: fill SBALEs with absolute addresses
Browse files Browse the repository at this point in the history
sbale->addr holds an absolute address (or for some FCP usage, an opaque
request ID), and should only be used with proper virt/phys translation.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
  • Loading branch information
Julian Wiedmann authored and Vasily Gorbik committed Feb 19, 2020
1 parent e9091ff commit 2db01da
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 20 deletions.
4 changes: 2 additions & 2 deletions arch/s390/include/asm/qdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ struct slib {
* @scount: SBAL count
* @sflags: whole SBAL flags
* @length: length
* @addr: address
* @addr: absolute data address
*/
struct qdio_buffer_element {
u8 eflags;
Expand All @@ -211,7 +211,7 @@ struct qdio_buffer_element {
u8 scount;
u8 sflags;
u32 length;
void *addr;
u64 addr;
} __attribute__ ((packed, aligned(16)));

/**
Expand Down
23 changes: 12 additions & 11 deletions drivers/s390/net/qeth_core_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1128,9 +1128,10 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
qeth_tx_complete_buf(buf, error, budget);

for (i = 0; i < queue->max_elements; ++i) {
if (buf->buffer->element[i].addr && buf->is_header[i])
kmem_cache_free(qeth_core_header_cache,
buf->buffer->element[i].addr);
void *data = phys_to_virt(buf->buffer->element[i].addr);

if (data && buf->is_header[i])
kmem_cache_free(qeth_core_header_cache, data);
buf->is_header[i] = 0;
}

Expand Down Expand Up @@ -2641,7 +2642,8 @@ static int qeth_init_input_buffer(struct qeth_card *card,
buf->pool_entry = pool_entry;
for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
buf->buffer->element[i].length = PAGE_SIZE;
buf->buffer->element[i].addr = pool_entry->elements[i];
buf->buffer->element[i].addr =
virt_to_phys(pool_entry->elements[i]);
if (i == QETH_MAX_BUFFER_ELEMENTS(card) - 1)
buf->buffer->element[i].eflags = SBAL_EFLAGS_LAST_ENTRY;
else
Expand Down Expand Up @@ -3459,9 +3461,8 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, unsigned int qdio_err,

while ((e < QDIO_MAX_ELEMENTS_PER_BUFFER) &&
buffer->element[e].addr) {
unsigned long phys_aob_addr;
unsigned long phys_aob_addr = buffer->element[e].addr;

phys_aob_addr = (unsigned long) buffer->element[e].addr;
qeth_qdio_handle_aob(card, phys_aob_addr);
++e;
}
Expand Down Expand Up @@ -3750,7 +3751,7 @@ static unsigned int __qeth_fill_buffer(struct sk_buff *skb,
elem_length = min_t(unsigned int, length,
PAGE_SIZE - offset_in_page(data));

buffer->element[element].addr = data;
buffer->element[element].addr = virt_to_phys(data);
buffer->element[element].length = elem_length;
length -= elem_length;
if (is_first_elem) {
Expand Down Expand Up @@ -3780,7 +3781,7 @@ static unsigned int __qeth_fill_buffer(struct sk_buff *skb,
elem_length = min_t(unsigned int, length,
PAGE_SIZE - offset_in_page(data));

buffer->element[element].addr = data;
buffer->element[element].addr = virt_to_phys(data);
buffer->element[element].length = elem_length;
buffer->element[element].eflags =
SBAL_EFLAGS_MIDDLE_FRAG;
Expand Down Expand Up @@ -3820,7 +3821,7 @@ static unsigned int qeth_fill_buffer(struct qeth_qdio_out_buffer *buf,
int element = buf->next_element_to_fill;
is_first_elem = false;

buffer->element[element].addr = hdr;
buffer->element[element].addr = virt_to_phys(hdr);
buffer->element[element].length = hd_len;
buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG;
/* remember to free cache-allocated qeth_hdr: */
Expand Down Expand Up @@ -5288,7 +5289,7 @@ static int qeth_extract_skb(struct qeth_card *card,
offset = 0;
}

hdr = element->addr + offset;
hdr = phys_to_virt(element->addr) + offset;
offset += sizeof(*hdr);
skb = NULL;

Expand Down Expand Up @@ -5387,7 +5388,7 @@ static int qeth_extract_skb(struct qeth_card *card,
walk_packet:
while (skb_len) {
int data_len = min(skb_len, (int)(element->length - offset));
char *data = element->addr + offset;
char *data = phys_to_virt(element->addr) + offset;

skb_len -= data_len;
offset += data_len;
Expand Down
2 changes: 1 addition & 1 deletion drivers/s390/scsi/zfcp_fsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2510,7 +2510,7 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)
for (idx = 0; idx < QDIO_MAX_ELEMENTS_PER_BUFFER; idx++) {

sbale = &sbal->element[idx];
req_id = (unsigned long) sbale->addr;
req_id = sbale->addr;
fsf_req = zfcp_reqlist_find_rm(adapter->req_list, req_id);

if (!fsf_req) {
Expand Down
6 changes: 3 additions & 3 deletions drivers/s390/scsi/zfcp_qdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
memset(pl, 0,
ZFCP_QDIO_MAX_SBALS_PER_REQ * sizeof(void *));
sbale = qdio->res_q[idx]->element;
req_id = (u64) sbale->addr;
req_id = sbale->addr;
scount = min(sbale->scount + 1,
ZFCP_QDIO_MAX_SBALS_PER_REQ + 1);
/* incl. signaling SBAL */
Expand Down Expand Up @@ -199,7 +199,7 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
q_req->sbal_number);
return -EINVAL;
}
sbale->addr = sg_virt(sg);
sbale->addr = sg_phys(sg);
sbale->length = sg->length;
}
return 0;
Expand Down Expand Up @@ -418,7 +418,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
sbale->length = 0;
sbale->eflags = SBAL_EFLAGS_LAST_ENTRY;
sbale->sflags = 0;
sbale->addr = NULL;
sbale->addr = 0;
}

if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q))
Expand Down
6 changes: 3 additions & 3 deletions drivers/s390/scsi/zfcp_qdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,14 @@ void zfcp_qdio_req_init(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
% QDIO_MAX_BUFFERS_PER_Q;

sbale = zfcp_qdio_sbale_req(qdio, q_req);
sbale->addr = (void *) req_id;
sbale->addr = req_id;
sbale->eflags = 0;
sbale->sflags = SBAL_SFLAGS0_COMMAND | sbtype;

if (unlikely(!data))
return;
sbale++;
sbale->addr = data;
sbale->addr = virt_to_phys(data);
sbale->length = len;
}

Expand All @@ -152,7 +152,7 @@ void zfcp_qdio_fill_next(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
BUG_ON(q_req->sbale_curr == qdio->max_sbale_per_sbal - 1);
q_req->sbale_curr++;
sbale = zfcp_qdio_sbale_curr(qdio, q_req);
sbale->addr = data;
sbale->addr = virt_to_phys(data);
sbale->length = len;
}

Expand Down

0 comments on commit 2db01da

Please sign in to comment.