summaryrefslogtreecommitdiffstats
path: root/drivers/misc/genwqe/card_base.h
diff options
context:
space:
mode:
authorGuilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>2017-10-20 17:27:49 -0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-10-23 11:34:42 +0200
commitde4ce2d1ad1bb3304d4107160c9551b7fd8d8ec5 (patch)
tree83bac440666d3ebb2f92c079d6310a265d3fa91e /drivers/misc/genwqe/card_base.h
parent75f98b7ab748a6f604d667d84ec46acc452fdfc1 (diff)
downloadlinux-stable-de4ce2d1ad1bb3304d4107160c9551b7fd8d8ec5.tar.gz
linux-stable-de4ce2d1ad1bb3304d4107160c9551b7fd8d8ec5.tar.bz2
linux-stable-de4ce2d1ad1bb3304d4107160c9551b7fd8d8ec5.zip
genwqe: Take R/W permissions into account when dealing with memory pages
Currently we assume userspace pages are always writable when doing memory pinning. This is not true, specially since userspace applications may allocate their memory the way they want, we have no control over it. If a read-only page is set for pinning, currently the driver fails due to get_user_pages_fast() refusing to map read-only pages as writable. This patch changes this behavior, by taking the permission flags of the pages into account in both pinning/unpinning process, as well as in the DMA data copy-back to userpace (which we shouldn't try to do blindly, since it will fail in case of read-only-pages). Signed-off-by: Frank Haverkamp <haver@linux.vnet.ibm.com> Signed-off-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/genwqe/card_base.h')
-rw-r--r--drivers/misc/genwqe/card_base.h7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h
index 5813b5f25006..3743c87f8ab9 100644
--- a/drivers/misc/genwqe/card_base.h
+++ b/drivers/misc/genwqe/card_base.h
@@ -182,6 +182,7 @@ struct dma_mapping {
struct list_head card_list; /* list of usr_maps for card */
struct list_head pin_list; /* list of pinned memory for dev */
+ int write; /* writable map? useful in unmapping */
};
static inline void genwqe_mapping_init(struct dma_mapping *m,
@@ -189,6 +190,7 @@ static inline void genwqe_mapping_init(struct dma_mapping *m,
{
memset(m, 0, sizeof(*m));
m->type = type;
+ m->write = 1; /* Assume the maps we create are R/W */
}
/**
@@ -347,6 +349,7 @@ enum genwqe_requ_state {
* @user_size: size of user-space memory area
* @page: buffer for partial pages if needed
* @page_dma_addr: dma address partial pages
+ * @write: should we write it back to userspace?
*/
struct genwqe_sgl {
dma_addr_t sgl_dma_addr;
@@ -356,6 +359,8 @@ struct genwqe_sgl {
void __user *user_addr; /* user-space base-address */
size_t user_size; /* size of memory area */
+ int write;
+
unsigned long nr_pages;
unsigned long fpage_offs;
size_t fpage_size;
@@ -369,7 +374,7 @@ struct genwqe_sgl {
};
int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
- void __user *user_addr, size_t user_size);
+ void __user *user_addr, size_t user_size, int write);
int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
dma_addr_t *dma_list);