diff options
author | Roger Pau Monné <roger.pau@citrix.com> | 2015-11-03 19:34:09 +0300 |
---|---|---|
committer | Zefan Li <lizefan@huawei.com> | 2016-10-26 18:15:39 +0300 |
commit | a7bc1af57e5a08e579b165df87ba446de0f7b476 (patch) | |
tree | d44da5adcbd3a4ad01cd6f92c0388004e9722ddd | |
parent | f97ed0a98cd26a2fa7249e7bad44e84091e19b17 (diff) | |
download | linux-a7bc1af57e5a08e579b165df87ba446de0f7b476.tar.xz |
xen-blkback: only read request operation from shared ring once
commit 1f13d75ccb806260079e0679d55d9253e370ec8a upstream.
A compiler may load a switch statement value multiple times, which could
be bad when the value is in memory shared with the frontend.
When converting a non-native request to a native one, ensure that
src->operation is only loaded once by using READ_ONCE().
This is part of XSA155.
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
[lizf: Backported to 3.4:
- adjust context
- call ACCESS_ONCE instead of READ_ONCE]
Signed-off-by: Zefan Li <lizefan@huawei.com>
-rw-r--r-- | drivers/block/xen-blkback/common.h | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 933adc5a2637..47e5b6509682 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -256,8 +256,8 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, struct blkif_x86_32_request *src) { int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; - dst->operation = src->operation; - switch (src->operation) { + dst->operation = ACCESS_ONCE(src->operation); + switch (dst->operation) { case BLKIF_OP_READ: case BLKIF_OP_WRITE: case BLKIF_OP_WRITE_BARRIER: @@ -292,8 +292,8 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, struct blkif_x86_64_request *src) { int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; - dst->operation = src->operation; - switch (src->operation) { + dst->operation = ACCESS_ONCE(src->operation); + switch (dst->operation) { case BLKIF_OP_READ: case BLKIF_OP_WRITE: case BLKIF_OP_WRITE_BARRIER: |