Commit 3434caec authored by Chuhong Yuan's avatar Chuhong Yuan Committed by Vasily Gorbik

s390/extmem: use refcount_t for refcount

Reference counters are preferred to use refcount_t instead of
atomic_t.
This is because the implementation of refcount_t can prevent
overflows and detect possible use-after-free.
So convert atomic_t ref counters to refcount_t.

Link: http://lkml.kernel.org/r/20190808071817.6595-1-hslester96@gmail.comSigned-off-by: default avatarChuhong Yuan <hslester96@gmail.com>
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent c4c37723
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/refcount.h>
#include <asm/diag.h> #include <asm/diag.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
...@@ -64,7 +65,7 @@ struct dcss_segment { ...@@ -64,7 +65,7 @@ struct dcss_segment {
char res_name[16]; char res_name[16];
unsigned long start_addr; unsigned long start_addr;
unsigned long end; unsigned long end;
atomic_t ref_count; refcount_t ref_count;
int do_nonshared; int do_nonshared;
unsigned int vm_segtype; unsigned int vm_segtype;
struct qrange range[6]; struct qrange range[6];
...@@ -362,7 +363,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long ...@@ -362,7 +363,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long
seg->start_addr = start_addr; seg->start_addr = start_addr;
seg->end = end_addr; seg->end = end_addr;
seg->do_nonshared = do_nonshared; seg->do_nonshared = do_nonshared;
atomic_set(&seg->ref_count, 1); refcount_set(&seg->ref_count, 1);
list_add(&seg->list, &dcss_list); list_add(&seg->list, &dcss_list);
*addr = seg->start_addr; *addr = seg->start_addr;
*end = seg->end; *end = seg->end;
...@@ -422,7 +423,7 @@ segment_load (char *name, int do_nonshared, unsigned long *addr, ...@@ -422,7 +423,7 @@ segment_load (char *name, int do_nonshared, unsigned long *addr,
rc = __segment_load (name, do_nonshared, addr, end); rc = __segment_load (name, do_nonshared, addr, end);
else { else {
if (do_nonshared == seg->do_nonshared) { if (do_nonshared == seg->do_nonshared) {
atomic_inc(&seg->ref_count); refcount_inc(&seg->ref_count);
*addr = seg->start_addr; *addr = seg->start_addr;
*end = seg->end; *end = seg->end;
rc = seg->vm_segtype; rc = seg->vm_segtype;
...@@ -468,7 +469,7 @@ segment_modify_shared (char *name, int do_nonshared) ...@@ -468,7 +469,7 @@ segment_modify_shared (char *name, int do_nonshared)
rc = 0; rc = 0;
goto out_unlock; goto out_unlock;
} }
if (atomic_read (&seg->ref_count) != 1) { if (refcount_read(&seg->ref_count) != 1) {
pr_warn("DCSS %s is in use and cannot be reloaded\n", name); pr_warn("DCSS %s is in use and cannot be reloaded\n", name);
rc = -EAGAIN; rc = -EAGAIN;
goto out_unlock; goto out_unlock;
...@@ -544,7 +545,7 @@ segment_unload(char *name) ...@@ -544,7 +545,7 @@ segment_unload(char *name)
pr_err("Unloading unknown DCSS %s failed\n", name); pr_err("Unloading unknown DCSS %s failed\n", name);
goto out_unlock; goto out_unlock;
} }
if (atomic_dec_return(&seg->ref_count) != 0) if (!refcount_dec_and_test(&seg->ref_count))
goto out_unlock; goto out_unlock;
release_resource(seg->res); release_resource(seg->res);
kfree(seg->res); kfree(seg->res);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment