Annotation of /trunk/kernel-alx/patches-4.9/0149-4.9.50-all-fixes.patch
Parent Directory | Revision Log
Revision 3034 -
(hide annotations)
(download)
Wed Dec 20 11:48:26 2017 UTC (6 years, 9 months ago) by niro
File size: 28989 byte(s)
Wed Dec 20 11:48:26 2017 UTC (6 years, 9 months ago) by niro
File size: 28989 byte(s)
-linux-4.9.50
1 | niro | 3034 | diff --git a/Makefile b/Makefile |
2 | index 1ebc553f5464..038d126a15fc 100644 | ||
3 | --- a/Makefile | ||
4 | +++ b/Makefile | ||
5 | @@ -1,6 +1,6 @@ | ||
6 | VERSION = 4 | ||
7 | PATCHLEVEL = 9 | ||
8 | -SUBLEVEL = 49 | ||
9 | +SUBLEVEL = 50 | ||
10 | EXTRAVERSION = | ||
11 | NAME = Roaring Lionus | ||
12 | |||
13 | diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c | ||
14 | index 0122ad1a6027..f7861dc83182 100644 | ||
15 | --- a/arch/arm/mm/fault.c | ||
16 | +++ b/arch/arm/mm/fault.c | ||
17 | @@ -314,8 +314,11 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | ||
18 | * signal first. We do not need to release the mmap_sem because | ||
19 | * it would already be released in __lock_page_or_retry in | ||
20 | * mm/filemap.c. */ | ||
21 | - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | ||
22 | + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) { | ||
23 | + if (!user_mode(regs)) | ||
24 | + goto no_context; | ||
25 | return 0; | ||
26 | + } | ||
27 | |||
28 | /* | ||
29 | * Major/minor page fault accounting is only done on the | ||
30 | diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | ||
31 | index 49a5d8ccae27..68e6f88bdcfe 100644 | ||
32 | --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | ||
33 | +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | ||
34 | @@ -170,6 +170,7 @@ | ||
35 | interrupt-controller; | ||
36 | reg = <0x1d00000 0x10000>, /* GICD */ | ||
37 | <0x1d40000 0x40000>; /* GICR */ | ||
38 | + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; | ||
39 | }; | ||
40 | }; | ||
41 | |||
42 | diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c | ||
43 | index d7f724b24fd7..0c84ee80e5b6 100644 | ||
44 | --- a/drivers/mtd/nand/mxc_nand.c | ||
45 | +++ b/drivers/mtd/nand/mxc_nand.c | ||
46 | @@ -877,6 +877,8 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) | ||
47 | } | ||
48 | } | ||
49 | |||
50 | +#define MXC_V1_ECCBYTES 5 | ||
51 | + | ||
52 | static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section, | ||
53 | struct mtd_oob_region *oobregion) | ||
54 | { | ||
55 | @@ -886,7 +888,7 @@ static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section, | ||
56 | return -ERANGE; | ||
57 | |||
58 | oobregion->offset = (section * 16) + 6; | ||
59 | - oobregion->length = nand_chip->ecc.bytes; | ||
60 | + oobregion->length = MXC_V1_ECCBYTES; | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | @@ -908,8 +910,7 @@ static int mxc_v1_ooblayout_free(struct mtd_info *mtd, int section, | ||
65 | oobregion->length = 4; | ||
66 | } | ||
67 | } else { | ||
68 | - oobregion->offset = ((section - 1) * 16) + | ||
69 | - nand_chip->ecc.bytes + 6; | ||
70 | + oobregion->offset = ((section - 1) * 16) + MXC_V1_ECCBYTES + 6; | ||
71 | if (section < nand_chip->ecc.steps) | ||
72 | oobregion->length = (section * 16) + 6 - | ||
73 | oobregion->offset; | ||
74 | diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c | ||
75 | index 57d483ac5765..6f0fd1512ad2 100644 | ||
76 | --- a/drivers/mtd/nand/qcom_nandc.c | ||
77 | +++ b/drivers/mtd/nand/qcom_nandc.c | ||
78 | @@ -109,7 +109,11 @@ | ||
79 | #define READ_ADDR 0 | ||
80 | |||
81 | /* NAND_DEV_CMD_VLD bits */ | ||
82 | -#define READ_START_VLD 0 | ||
83 | +#define READ_START_VLD BIT(0) | ||
84 | +#define READ_STOP_VLD BIT(1) | ||
85 | +#define WRITE_START_VLD BIT(2) | ||
86 | +#define ERASE_START_VLD BIT(3) | ||
87 | +#define SEQ_READ_START_VLD BIT(4) | ||
88 | |||
89 | /* NAND_EBI2_ECC_BUF_CFG bits */ | ||
90 | #define NUM_STEPS 0 | ||
91 | @@ -148,6 +152,10 @@ | ||
92 | #define FETCH_ID 0xb | ||
93 | #define RESET_DEVICE 0xd | ||
94 | |||
95 | +/* Default Value for NAND_DEV_CMD_VLD */ | ||
96 | +#define NAND_DEV_CMD_VLD_VAL (READ_START_VLD | WRITE_START_VLD | \ | ||
97 | + ERASE_START_VLD | SEQ_READ_START_VLD) | ||
98 | + | ||
99 | /* | ||
100 | * the NAND controller performs reads/writes with ECC in 516 byte chunks. | ||
101 | * the driver calls the chunks 'step' or 'codeword' interchangeably | ||
102 | @@ -672,8 +680,7 @@ static int nandc_param(struct qcom_nand_host *host) | ||
103 | |||
104 | /* configure CMD1 and VLD for ONFI param probing */ | ||
105 | nandc_set_reg(nandc, NAND_DEV_CMD_VLD, | ||
106 | - (nandc->vld & ~(1 << READ_START_VLD)) | ||
107 | - | 0 << READ_START_VLD); | ||
108 | + (nandc->vld & ~READ_START_VLD)); | ||
109 | nandc_set_reg(nandc, NAND_DEV_CMD1, | ||
110 | (nandc->cmd1 & ~(0xFF << READ_ADDR)) | ||
111 | | NAND_CMD_PARAM << READ_ADDR); | ||
112 | @@ -1893,7 +1900,7 @@ static int qcom_nand_host_setup(struct qcom_nand_host *host) | ||
113 | | wide_bus << WIDE_FLASH | ||
114 | | 1 << DEV0_CFG1_ECC_DISABLE; | ||
115 | |||
116 | - host->ecc_bch_cfg = host->bch_enabled << ECC_CFG_ECC_DISABLE | ||
117 | + host->ecc_bch_cfg = !host->bch_enabled << ECC_CFG_ECC_DISABLE | ||
118 | | 0 << ECC_SW_RESET | ||
119 | | host->cw_data << ECC_NUM_DATA_BYTES | ||
120 | | 1 << ECC_FORCE_CLK_OPEN | ||
121 | @@ -1972,13 +1979,14 @@ static int qcom_nandc_setup(struct qcom_nand_controller *nandc) | ||
122 | { | ||
123 | /* kill onenand */ | ||
124 | nandc_write(nandc, SFLASHC_BURST_CFG, 0); | ||
125 | + nandc_write(nandc, NAND_DEV_CMD_VLD, NAND_DEV_CMD_VLD_VAL); | ||
126 | |||
127 | /* enable ADM DMA */ | ||
128 | nandc_write(nandc, NAND_FLASH_CHIP_SELECT, DM_EN); | ||
129 | |||
130 | /* save the original values of these registers */ | ||
131 | nandc->cmd1 = nandc_read(nandc, NAND_DEV_CMD1); | ||
132 | - nandc->vld = nandc_read(nandc, NAND_DEV_CMD_VLD); | ||
133 | + nandc->vld = NAND_DEV_CMD_VLD_VAL; | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c | ||
138 | index 5a3f008d3480..eef1a68e5d95 100644 | ||
139 | --- a/drivers/nvme/host/fabrics.c | ||
140 | +++ b/drivers/nvme/host/fabrics.c | ||
141 | @@ -77,7 +77,7 @@ static struct nvmf_host *nvmf_host_default(void) | ||
142 | kref_init(&host->ref); | ||
143 | uuid_be_gen(&host->id); | ||
144 | snprintf(host->nqn, NVMF_NQN_SIZE, | ||
145 | - "nqn.2014-08.org.nvmexpress:NVMf:uuid:%pUb", &host->id); | ||
146 | + "nqn.2014-08.org.nvmexpress:uuid:%pUb", &host->id); | ||
147 | |||
148 | mutex_lock(&nvmf_hosts_mutex); | ||
149 | list_add_tail(&host->list, &nvmf_hosts); | ||
150 | diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c | ||
151 | index 74ed5aae6cea..f6e111984ce2 100644 | ||
152 | --- a/fs/btrfs/super.c | ||
153 | +++ b/fs/btrfs/super.c | ||
154 | @@ -1834,6 +1834,8 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | ||
155 | goto restore; | ||
156 | } | ||
157 | |||
158 | + btrfs_qgroup_rescan_resume(fs_info); | ||
159 | + | ||
160 | if (!fs_info->uuid_root) { | ||
161 | btrfs_info(fs_info, "creating UUID tree"); | ||
162 | ret = btrfs_create_uuid_tree(fs_info); | ||
163 | diff --git a/fs/nfs/file.c b/fs/nfs/file.c | ||
164 | index 84c1cb9237d0..1eec947c562d 100644 | ||
165 | --- a/fs/nfs/file.c | ||
166 | +++ b/fs/nfs/file.c | ||
167 | @@ -636,11 +636,11 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) | ||
168 | if (result <= 0) | ||
169 | goto out; | ||
170 | |||
171 | - result = generic_write_sync(iocb, result); | ||
172 | - if (result < 0) | ||
173 | - goto out; | ||
174 | written = result; | ||
175 | iocb->ki_pos += written; | ||
176 | + result = generic_write_sync(iocb, written); | ||
177 | + if (result < 0) | ||
178 | + goto out; | ||
179 | |||
180 | /* Return error values */ | ||
181 | if (nfs_need_check_write(file, inode)) { | ||
182 | diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h | ||
183 | index 80bcc0befb07..52ea41bce038 100644 | ||
184 | --- a/fs/nfs/internal.h | ||
185 | +++ b/fs/nfs/internal.h | ||
186 | @@ -248,7 +248,6 @@ int nfs_iocounter_wait(struct nfs_lock_context *l_ctx); | ||
187 | extern const struct nfs_pageio_ops nfs_pgio_rw_ops; | ||
188 | struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *); | ||
189 | void nfs_pgio_header_free(struct nfs_pgio_header *); | ||
190 | -void nfs_pgio_data_destroy(struct nfs_pgio_header *); | ||
191 | int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *); | ||
192 | int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr, | ||
193 | struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops, | ||
194 | diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c | ||
195 | index 142a74f3c59b..3d17fc82b9fe 100644 | ||
196 | --- a/fs/nfs/pagelist.c | ||
197 | +++ b/fs/nfs/pagelist.c | ||
198 | @@ -497,16 +497,6 @@ struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *ops) | ||
199 | } | ||
200 | EXPORT_SYMBOL_GPL(nfs_pgio_header_alloc); | ||
201 | |||
202 | -/* | ||
203 | - * nfs_pgio_header_free - Free a read or write header | ||
204 | - * @hdr: The header to free | ||
205 | - */ | ||
206 | -void nfs_pgio_header_free(struct nfs_pgio_header *hdr) | ||
207 | -{ | ||
208 | - hdr->rw_ops->rw_free_header(hdr); | ||
209 | -} | ||
210 | -EXPORT_SYMBOL_GPL(nfs_pgio_header_free); | ||
211 | - | ||
212 | /** | ||
213 | * nfs_pgio_data_destroy - make @hdr suitable for reuse | ||
214 | * | ||
215 | @@ -515,14 +505,24 @@ EXPORT_SYMBOL_GPL(nfs_pgio_header_free); | ||
216 | * | ||
217 | * @hdr: A header that has had nfs_generic_pgio called | ||
218 | */ | ||
219 | -void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr) | ||
220 | +static void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr) | ||
221 | { | ||
222 | if (hdr->args.context) | ||
223 | put_nfs_open_context(hdr->args.context); | ||
224 | if (hdr->page_array.pagevec != hdr->page_array.page_array) | ||
225 | kfree(hdr->page_array.pagevec); | ||
226 | } | ||
227 | -EXPORT_SYMBOL_GPL(nfs_pgio_data_destroy); | ||
228 | + | ||
229 | +/* | ||
230 | + * nfs_pgio_header_free - Free a read or write header | ||
231 | + * @hdr: The header to free | ||
232 | + */ | ||
233 | +void nfs_pgio_header_free(struct nfs_pgio_header *hdr) | ||
234 | +{ | ||
235 | + nfs_pgio_data_destroy(hdr); | ||
236 | + hdr->rw_ops->rw_free_header(hdr); | ||
237 | +} | ||
238 | +EXPORT_SYMBOL_GPL(nfs_pgio_header_free); | ||
239 | |||
240 | /** | ||
241 | * nfs_pgio_rpcsetup - Set up arguments for a pageio call | ||
242 | @@ -636,7 +636,6 @@ EXPORT_SYMBOL_GPL(nfs_initiate_pgio); | ||
243 | static void nfs_pgio_error(struct nfs_pgio_header *hdr) | ||
244 | { | ||
245 | set_bit(NFS_IOHDR_REDO, &hdr->flags); | ||
246 | - nfs_pgio_data_destroy(hdr); | ||
247 | hdr->completion_ops->completion(hdr); | ||
248 | } | ||
249 | |||
250 | @@ -647,7 +646,6 @@ static void nfs_pgio_error(struct nfs_pgio_header *hdr) | ||
251 | static void nfs_pgio_release(void *calldata) | ||
252 | { | ||
253 | struct nfs_pgio_header *hdr = calldata; | ||
254 | - nfs_pgio_data_destroy(hdr); | ||
255 | hdr->completion_ops->completion(hdr); | ||
256 | } | ||
257 | |||
258 | diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c | ||
259 | index 415d7e69bc5e..b7a07ba8783a 100644 | ||
260 | --- a/fs/nfs/pnfs.c | ||
261 | +++ b/fs/nfs/pnfs.c | ||
262 | @@ -2145,7 +2145,6 @@ pnfs_write_through_mds(struct nfs_pageio_descriptor *desc, | ||
263 | nfs_pageio_reset_write_mds(desc); | ||
264 | mirror->pg_recoalesce = 1; | ||
265 | } | ||
266 | - nfs_pgio_data_destroy(hdr); | ||
267 | hdr->release(hdr); | ||
268 | } | ||
269 | |||
270 | @@ -2257,7 +2256,6 @@ pnfs_read_through_mds(struct nfs_pageio_descriptor *desc, | ||
271 | nfs_pageio_reset_read_mds(desc); | ||
272 | mirror->pg_recoalesce = 1; | ||
273 | } | ||
274 | - nfs_pgio_data_destroy(hdr); | ||
275 | hdr->release(hdr); | ||
276 | } | ||
277 | |||
278 | diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h | ||
279 | index 1455b25205a8..3ebed168e508 100644 | ||
280 | --- a/fs/xfs/xfs_linux.h | ||
281 | +++ b/fs/xfs/xfs_linux.h | ||
282 | @@ -363,7 +363,14 @@ static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y) | ||
283 | #endif /* DEBUG */ | ||
284 | |||
285 | #ifdef CONFIG_XFS_RT | ||
286 | -#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) | ||
287 | + | ||
288 | +/* | ||
289 | + * make sure we ignore the inode flag if the filesystem doesn't have a | ||
290 | + * configured realtime device. | ||
291 | + */ | ||
292 | +#define XFS_IS_REALTIME_INODE(ip) \ | ||
293 | + (((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) && \ | ||
294 | + (ip)->i_mount->m_rtdev_targp) | ||
295 | #else | ||
296 | #define XFS_IS_REALTIME_INODE(ip) (0) | ||
297 | #endif | ||
298 | diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c | ||
299 | index f8c5af52a131..d3de04b12f8c 100644 | ||
300 | --- a/kernel/locking/locktorture.c | ||
301 | +++ b/kernel/locking/locktorture.c | ||
302 | @@ -780,6 +780,10 @@ static void lock_torture_cleanup(void) | ||
303 | else | ||
304 | lock_torture_print_module_parms(cxt.cur_ops, | ||
305 | "End of test: SUCCESS"); | ||
306 | + | ||
307 | + kfree(cxt.lwsa); | ||
308 | + kfree(cxt.lrsa); | ||
309 | + | ||
310 | end: | ||
311 | torture_cleanup_end(); | ||
312 | } | ||
313 | @@ -924,6 +928,8 @@ static int __init lock_torture_init(void) | ||
314 | GFP_KERNEL); | ||
315 | if (reader_tasks == NULL) { | ||
316 | VERBOSE_TOROUT_ERRSTRING("reader_tasks: Out of memory"); | ||
317 | + kfree(writer_tasks); | ||
318 | + writer_tasks = NULL; | ||
319 | firsterr = -ENOMEM; | ||
320 | goto unwind; | ||
321 | } | ||
322 | diff --git a/mm/memory.c b/mm/memory.c | ||
323 | index d064caff9d7d..1aa63e7dd790 100644 | ||
324 | --- a/mm/memory.c | ||
325 | +++ b/mm/memory.c | ||
326 | @@ -3596,6 +3596,11 @@ int handle_mm_fault(struct vm_area_struct *vma, unsigned long address, | ||
327 | /* do counter updates before entering really critical section. */ | ||
328 | check_sync_rss_stat(current); | ||
329 | |||
330 | + if (!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE, | ||
331 | + flags & FAULT_FLAG_INSTRUCTION, | ||
332 | + flags & FAULT_FLAG_REMOTE)) | ||
333 | + return VM_FAULT_SIGSEGV; | ||
334 | + | ||
335 | /* | ||
336 | * Enable the memcg OOM handling for faults triggered in user | ||
337 | * space. Kernel faults are handled more gracefully. | ||
338 | @@ -3603,11 +3608,6 @@ int handle_mm_fault(struct vm_area_struct *vma, unsigned long address, | ||
339 | if (flags & FAULT_FLAG_USER) | ||
340 | mem_cgroup_oom_enable(); | ||
341 | |||
342 | - if (!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE, | ||
343 | - flags & FAULT_FLAG_INSTRUCTION, | ||
344 | - flags & FAULT_FLAG_REMOTE)) | ||
345 | - return VM_FAULT_SIGSEGV; | ||
346 | - | ||
347 | if (unlikely(is_vm_hugetlb_page(vma))) | ||
348 | ret = hugetlb_fault(vma->vm_mm, vma, address, flags); | ||
349 | else | ||
350 | diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c | ||
351 | index 577f1c01454a..ffd09c1675d4 100644 | ||
352 | --- a/net/bluetooth/l2cap_core.c | ||
353 | +++ b/net/bluetooth/l2cap_core.c | ||
354 | @@ -58,7 +58,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | ||
355 | u8 code, u8 ident, u16 dlen, void *data); | ||
356 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, | ||
357 | void *data); | ||
358 | -static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); | ||
359 | +static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size); | ||
360 | static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err); | ||
361 | |||
362 | static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, | ||
363 | @@ -1473,7 +1473,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | ||
364 | |||
365 | set_bit(CONF_REQ_SENT, &chan->conf_state); | ||
366 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
367 | - l2cap_build_conf_req(chan, buf), buf); | ||
368 | + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); | ||
369 | chan->num_conf_req++; | ||
370 | } | ||
371 | |||
372 | @@ -2977,12 +2977,15 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, | ||
373 | return len; | ||
374 | } | ||
375 | |||
376 | -static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) | ||
377 | +static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val, size_t size) | ||
378 | { | ||
379 | struct l2cap_conf_opt *opt = *ptr; | ||
380 | |||
381 | BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val); | ||
382 | |||
383 | + if (size < L2CAP_CONF_OPT_SIZE + len) | ||
384 | + return; | ||
385 | + | ||
386 | opt->type = type; | ||
387 | opt->len = len; | ||
388 | |||
389 | @@ -3007,7 +3010,7 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) | ||
390 | *ptr += L2CAP_CONF_OPT_SIZE + len; | ||
391 | } | ||
392 | |||
393 | -static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) | ||
394 | +static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan, size_t size) | ||
395 | { | ||
396 | struct l2cap_conf_efs efs; | ||
397 | |||
398 | @@ -3035,7 +3038,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) | ||
399 | } | ||
400 | |||
401 | l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs), | ||
402 | - (unsigned long) &efs); | ||
403 | + (unsigned long) &efs, size); | ||
404 | } | ||
405 | |||
406 | static void l2cap_ack_timeout(struct work_struct *work) | ||
407 | @@ -3181,11 +3184,12 @@ static inline void l2cap_txwin_setup(struct l2cap_chan *chan) | ||
408 | chan->ack_win = chan->tx_win; | ||
409 | } | ||
410 | |||
411 | -static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | ||
412 | +static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size) | ||
413 | { | ||
414 | struct l2cap_conf_req *req = data; | ||
415 | struct l2cap_conf_rfc rfc = { .mode = chan->mode }; | ||
416 | void *ptr = req->data; | ||
417 | + void *endptr = data + data_size; | ||
418 | u16 size; | ||
419 | |||
420 | BT_DBG("chan %p", chan); | ||
421 | @@ -3210,7 +3214,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | ||
422 | |||
423 | done: | ||
424 | if (chan->imtu != L2CAP_DEFAULT_MTU) | ||
425 | - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); | ||
426 | + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr); | ||
427 | |||
428 | switch (chan->mode) { | ||
429 | case L2CAP_MODE_BASIC: | ||
430 | @@ -3229,7 +3233,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | ||
431 | rfc.max_pdu_size = 0; | ||
432 | |||
433 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | ||
434 | - (unsigned long) &rfc); | ||
435 | + (unsigned long) &rfc, endptr - ptr); | ||
436 | break; | ||
437 | |||
438 | case L2CAP_MODE_ERTM: | ||
439 | @@ -3249,21 +3253,21 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | ||
440 | L2CAP_DEFAULT_TX_WINDOW); | ||
441 | |||
442 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | ||
443 | - (unsigned long) &rfc); | ||
444 | + (unsigned long) &rfc, endptr - ptr); | ||
445 | |||
446 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) | ||
447 | - l2cap_add_opt_efs(&ptr, chan); | ||
448 | + l2cap_add_opt_efs(&ptr, chan, endptr - ptr); | ||
449 | |||
450 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
451 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, | ||
452 | - chan->tx_win); | ||
453 | + chan->tx_win, endptr - ptr); | ||
454 | |||
455 | if (chan->conn->feat_mask & L2CAP_FEAT_FCS) | ||
456 | if (chan->fcs == L2CAP_FCS_NONE || | ||
457 | test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) { | ||
458 | chan->fcs = L2CAP_FCS_NONE; | ||
459 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, | ||
460 | - chan->fcs); | ||
461 | + chan->fcs, endptr - ptr); | ||
462 | } | ||
463 | break; | ||
464 | |||
465 | @@ -3281,17 +3285,17 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | ||
466 | rfc.max_pdu_size = cpu_to_le16(size); | ||
467 | |||
468 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | ||
469 | - (unsigned long) &rfc); | ||
470 | + (unsigned long) &rfc, endptr - ptr); | ||
471 | |||
472 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) | ||
473 | - l2cap_add_opt_efs(&ptr, chan); | ||
474 | + l2cap_add_opt_efs(&ptr, chan, endptr - ptr); | ||
475 | |||
476 | if (chan->conn->feat_mask & L2CAP_FEAT_FCS) | ||
477 | if (chan->fcs == L2CAP_FCS_NONE || | ||
478 | test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) { | ||
479 | chan->fcs = L2CAP_FCS_NONE; | ||
480 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, | ||
481 | - chan->fcs); | ||
482 | + chan->fcs, endptr - ptr); | ||
483 | } | ||
484 | break; | ||
485 | } | ||
486 | @@ -3302,10 +3306,11 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | ||
487 | return ptr - data; | ||
488 | } | ||
489 | |||
490 | -static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | ||
491 | +static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data_size) | ||
492 | { | ||
493 | struct l2cap_conf_rsp *rsp = data; | ||
494 | void *ptr = rsp->data; | ||
495 | + void *endptr = data + data_size; | ||
496 | void *req = chan->conf_req; | ||
497 | int len = chan->conf_len; | ||
498 | int type, hint, olen; | ||
499 | @@ -3407,7 +3412,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | ||
500 | return -ECONNREFUSED; | ||
501 | |||
502 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | ||
503 | - (unsigned long) &rfc); | ||
504 | + (unsigned long) &rfc, endptr - ptr); | ||
505 | } | ||
506 | |||
507 | if (result == L2CAP_CONF_SUCCESS) { | ||
508 | @@ -3420,7 +3425,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | ||
509 | chan->omtu = mtu; | ||
510 | set_bit(CONF_MTU_DONE, &chan->conf_state); | ||
511 | } | ||
512 | - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); | ||
513 | + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu, endptr - ptr); | ||
514 | |||
515 | if (remote_efs) { | ||
516 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && | ||
517 | @@ -3434,7 +3439,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | ||
518 | |||
519 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, | ||
520 | sizeof(efs), | ||
521 | - (unsigned long) &efs); | ||
522 | + (unsigned long) &efs, endptr - ptr); | ||
523 | } else { | ||
524 | /* Send PENDING Conf Rsp */ | ||
525 | result = L2CAP_CONF_PENDING; | ||
526 | @@ -3467,7 +3472,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | ||
527 | set_bit(CONF_MODE_DONE, &chan->conf_state); | ||
528 | |||
529 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
530 | - sizeof(rfc), (unsigned long) &rfc); | ||
531 | + sizeof(rfc), (unsigned long) &rfc, endptr - ptr); | ||
532 | |||
533 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { | ||
534 | chan->remote_id = efs.id; | ||
535 | @@ -3481,7 +3486,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | ||
536 | le32_to_cpu(efs.sdu_itime); | ||
537 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, | ||
538 | sizeof(efs), | ||
539 | - (unsigned long) &efs); | ||
540 | + (unsigned long) &efs, endptr - ptr); | ||
541 | } | ||
542 | break; | ||
543 | |||
544 | @@ -3495,7 +3500,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | ||
545 | set_bit(CONF_MODE_DONE, &chan->conf_state); | ||
546 | |||
547 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | ||
548 | - (unsigned long) &rfc); | ||
549 | + (unsigned long) &rfc, endptr - ptr); | ||
550 | |||
551 | break; | ||
552 | |||
553 | @@ -3517,10 +3522,11 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | ||
554 | } | ||
555 | |||
556 | static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, | ||
557 | - void *data, u16 *result) | ||
558 | + void *data, size_t size, u16 *result) | ||
559 | { | ||
560 | struct l2cap_conf_req *req = data; | ||
561 | void *ptr = req->data; | ||
562 | + void *endptr = data + size; | ||
563 | int type, olen; | ||
564 | unsigned long val; | ||
565 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; | ||
566 | @@ -3538,13 +3544,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, | ||
567 | chan->imtu = L2CAP_DEFAULT_MIN_MTU; | ||
568 | } else | ||
569 | chan->imtu = val; | ||
570 | - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); | ||
571 | + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr); | ||
572 | break; | ||
573 | |||
574 | case L2CAP_CONF_FLUSH_TO: | ||
575 | chan->flush_to = val; | ||
576 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, | ||
577 | - 2, chan->flush_to); | ||
578 | + 2, chan->flush_to, endptr - ptr); | ||
579 | break; | ||
580 | |||
581 | case L2CAP_CONF_RFC: | ||
582 | @@ -3558,13 +3564,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, | ||
583 | chan->fcs = 0; | ||
584 | |||
585 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
586 | - sizeof(rfc), (unsigned long) &rfc); | ||
587 | + sizeof(rfc), (unsigned long) &rfc, endptr - ptr); | ||
588 | break; | ||
589 | |||
590 | case L2CAP_CONF_EWS: | ||
591 | chan->ack_win = min_t(u16, val, chan->ack_win); | ||
592 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, | ||
593 | - chan->tx_win); | ||
594 | + chan->tx_win, endptr - ptr); | ||
595 | break; | ||
596 | |||
597 | case L2CAP_CONF_EFS: | ||
598 | @@ -3577,7 +3583,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, | ||
599 | return -ECONNREFUSED; | ||
600 | |||
601 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), | ||
602 | - (unsigned long) &efs); | ||
603 | + (unsigned long) &efs, endptr - ptr); | ||
604 | break; | ||
605 | |||
606 | case L2CAP_CONF_FCS: | ||
607 | @@ -3682,7 +3688,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) | ||
608 | return; | ||
609 | |||
610 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
611 | - l2cap_build_conf_req(chan, buf), buf); | ||
612 | + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); | ||
613 | chan->num_conf_req++; | ||
614 | } | ||
615 | |||
616 | @@ -3890,7 +3896,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, | ||
617 | u8 buf[128]; | ||
618 | set_bit(CONF_REQ_SENT, &chan->conf_state); | ||
619 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
620 | - l2cap_build_conf_req(chan, buf), buf); | ||
621 | + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); | ||
622 | chan->num_conf_req++; | ||
623 | } | ||
624 | |||
625 | @@ -3968,7 +3974,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, | ||
626 | break; | ||
627 | |||
628 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
629 | - l2cap_build_conf_req(chan, req), req); | ||
630 | + l2cap_build_conf_req(chan, req, sizeof(req)), req); | ||
631 | chan->num_conf_req++; | ||
632 | break; | ||
633 | |||
634 | @@ -4080,7 +4086,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, | ||
635 | } | ||
636 | |||
637 | /* Complete config. */ | ||
638 | - len = l2cap_parse_conf_req(chan, rsp); | ||
639 | + len = l2cap_parse_conf_req(chan, rsp, sizeof(rsp)); | ||
640 | if (len < 0) { | ||
641 | l2cap_send_disconn_req(chan, ECONNRESET); | ||
642 | goto unlock; | ||
643 | @@ -4114,7 +4120,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, | ||
644 | if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) { | ||
645 | u8 buf[64]; | ||
646 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
647 | - l2cap_build_conf_req(chan, buf), buf); | ||
648 | + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); | ||
649 | chan->num_conf_req++; | ||
650 | } | ||
651 | |||
652 | @@ -4174,7 +4180,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, | ||
653 | char buf[64]; | ||
654 | |||
655 | len = l2cap_parse_conf_rsp(chan, rsp->data, len, | ||
656 | - buf, &result); | ||
657 | + buf, sizeof(buf), &result); | ||
658 | if (len < 0) { | ||
659 | l2cap_send_disconn_req(chan, ECONNRESET); | ||
660 | goto done; | ||
661 | @@ -4204,7 +4210,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, | ||
662 | /* throw out any old stored conf requests */ | ||
663 | result = L2CAP_CONF_SUCCESS; | ||
664 | len = l2cap_parse_conf_rsp(chan, rsp->data, len, | ||
665 | - req, &result); | ||
666 | + req, sizeof(req), &result); | ||
667 | if (len < 0) { | ||
668 | l2cap_send_disconn_req(chan, ECONNRESET); | ||
669 | goto done; | ||
670 | @@ -4781,7 +4787,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result, | ||
671 | set_bit(CONF_REQ_SENT, &chan->conf_state); | ||
672 | l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn), | ||
673 | L2CAP_CONF_REQ, | ||
674 | - l2cap_build_conf_req(chan, buf), buf); | ||
675 | + l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); | ||
676 | chan->num_conf_req++; | ||
677 | } | ||
678 | } | ||
679 | @@ -7457,7 +7463,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | ||
680 | set_bit(CONF_REQ_SENT, &chan->conf_state); | ||
681 | l2cap_send_cmd(conn, l2cap_get_ident(conn), | ||
682 | L2CAP_CONF_REQ, | ||
683 | - l2cap_build_conf_req(chan, buf), | ||
684 | + l2cap_build_conf_req(chan, buf, sizeof(buf)), | ||
685 | buf); | ||
686 | chan->num_conf_req++; | ||
687 | } | ||
688 | diff --git a/sound/isa/msnd/msnd_midi.c b/sound/isa/msnd/msnd_midi.c | ||
689 | index ffc67fd80c23..58e59cd3c95c 100644 | ||
690 | --- a/sound/isa/msnd/msnd_midi.c | ||
691 | +++ b/sound/isa/msnd/msnd_midi.c | ||
692 | @@ -120,24 +120,24 @@ void snd_msndmidi_input_read(void *mpuv) | ||
693 | unsigned long flags; | ||
694 | struct snd_msndmidi *mpu = mpuv; | ||
695 | void *pwMIDQData = mpu->dev->mappedbase + MIDQ_DATA_BUFF; | ||
696 | + u16 head, tail, size; | ||
697 | |||
698 | spin_lock_irqsave(&mpu->input_lock, flags); | ||
699 | - while (readw(mpu->dev->MIDQ + JQS_wTail) != | ||
700 | - readw(mpu->dev->MIDQ + JQS_wHead)) { | ||
701 | - u16 wTmp, val; | ||
702 | - val = readw(pwMIDQData + 2 * readw(mpu->dev->MIDQ + JQS_wHead)); | ||
703 | - | ||
704 | - if (test_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER, | ||
705 | - &mpu->mode)) | ||
706 | - snd_rawmidi_receive(mpu->substream_input, | ||
707 | - (unsigned char *)&val, 1); | ||
708 | - | ||
709 | - wTmp = readw(mpu->dev->MIDQ + JQS_wHead) + 1; | ||
710 | - if (wTmp > readw(mpu->dev->MIDQ + JQS_wSize)) | ||
711 | - writew(0, mpu->dev->MIDQ + JQS_wHead); | ||
712 | - else | ||
713 | - writew(wTmp, mpu->dev->MIDQ + JQS_wHead); | ||
714 | + head = readw(mpu->dev->MIDQ + JQS_wHead); | ||
715 | + tail = readw(mpu->dev->MIDQ + JQS_wTail); | ||
716 | + size = readw(mpu->dev->MIDQ + JQS_wSize); | ||
717 | + if (head > size || tail > size) | ||
718 | + goto out; | ||
719 | + while (head != tail) { | ||
720 | + unsigned char val = readw(pwMIDQData + 2 * head); | ||
721 | + | ||
722 | + if (test_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) | ||
723 | + snd_rawmidi_receive(mpu->substream_input, &val, 1); | ||
724 | + if (++head > size) | ||
725 | + head = 0; | ||
726 | + writew(head, mpu->dev->MIDQ + JQS_wHead); | ||
727 | } | ||
728 | + out: | ||
729 | spin_unlock_irqrestore(&mpu->input_lock, flags); | ||
730 | } | ||
731 | EXPORT_SYMBOL(snd_msndmidi_input_read); | ||
732 | diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c | ||
733 | index 4c072666115d..a31ea6c22d19 100644 | ||
734 | --- a/sound/isa/msnd/msnd_pinnacle.c | ||
735 | +++ b/sound/isa/msnd/msnd_pinnacle.c | ||
736 | @@ -170,23 +170,24 @@ static irqreturn_t snd_msnd_interrupt(int irq, void *dev_id) | ||
737 | { | ||
738 | struct snd_msnd *chip = dev_id; | ||
739 | void *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF; | ||
740 | + u16 head, tail, size; | ||
741 | |||
742 | /* Send ack to DSP */ | ||
743 | /* inb(chip->io + HP_RXL); */ | ||
744 | |||
745 | /* Evaluate queued DSP messages */ | ||
746 | - while (readw(chip->DSPQ + JQS_wTail) != readw(chip->DSPQ + JQS_wHead)) { | ||
747 | - u16 wTmp; | ||
748 | - | ||
749 | - snd_msnd_eval_dsp_msg(chip, | ||
750 | - readw(pwDSPQData + 2 * readw(chip->DSPQ + JQS_wHead))); | ||
751 | - | ||
752 | - wTmp = readw(chip->DSPQ + JQS_wHead) + 1; | ||
753 | - if (wTmp > readw(chip->DSPQ + JQS_wSize)) | ||
754 | - writew(0, chip->DSPQ + JQS_wHead); | ||
755 | - else | ||
756 | - writew(wTmp, chip->DSPQ + JQS_wHead); | ||
757 | + head = readw(chip->DSPQ + JQS_wHead); | ||
758 | + tail = readw(chip->DSPQ + JQS_wTail); | ||
759 | + size = readw(chip->DSPQ + JQS_wSize); | ||
760 | + if (head > size || tail > size) | ||
761 | + goto out; | ||
762 | + while (head != tail) { | ||
763 | + snd_msnd_eval_dsp_msg(chip, readw(pwDSPQData + 2 * head)); | ||
764 | + if (++head > size) | ||
765 | + head = 0; | ||
766 | + writew(head, chip->DSPQ + JQS_wHead); | ||
767 | } | ||
768 | + out: | ||
769 | /* Send ack to DSP */ | ||
770 | inb(chip->io + HP_RXL); | ||
771 | return IRQ_HANDLED; | ||
772 | diff --git a/tools/testing/selftests/x86/fsgsbase.c b/tools/testing/selftests/x86/fsgsbase.c | ||
773 | index 5b2b4b3c634c..9b4610c6d3fb 100644 | ||
774 | --- a/tools/testing/selftests/x86/fsgsbase.c | ||
775 | +++ b/tools/testing/selftests/x86/fsgsbase.c | ||
776 | @@ -285,9 +285,12 @@ static void *threadproc(void *ctx) | ||
777 | } | ||
778 | } | ||
779 | |||
780 | -static void set_gs_and_switch_to(unsigned long local, unsigned long remote) | ||
781 | +static void set_gs_and_switch_to(unsigned long local, | ||
782 | + unsigned short force_sel, | ||
783 | + unsigned long remote) | ||
784 | { | ||
785 | unsigned long base; | ||
786 | + unsigned short sel_pre_sched, sel_post_sched; | ||
787 | |||
788 | bool hard_zero = false; | ||
789 | if (local == HARD_ZERO) { | ||
790 | @@ -297,6 +300,8 @@ static void set_gs_and_switch_to(unsigned long local, unsigned long remote) | ||
791 | |||
792 | printf("[RUN]\tARCH_SET_GS(0x%lx)%s, then schedule to 0x%lx\n", | ||
793 | local, hard_zero ? " and clear gs" : "", remote); | ||
794 | + if (force_sel) | ||
795 | + printf("\tBefore schedule, set selector to 0x%hx\n", force_sel); | ||
796 | if (syscall(SYS_arch_prctl, ARCH_SET_GS, local) != 0) | ||
797 | err(1, "ARCH_SET_GS"); | ||
798 | if (hard_zero) | ||
799 | @@ -307,18 +312,35 @@ static void set_gs_and_switch_to(unsigned long local, unsigned long remote) | ||
800 | printf("[FAIL]\tGSBASE wasn't set as expected\n"); | ||
801 | } | ||
802 | |||
803 | + if (force_sel) { | ||
804 | + asm volatile ("mov %0, %%gs" : : "rm" (force_sel)); | ||
805 | + sel_pre_sched = force_sel; | ||
806 | + local = read_base(GS); | ||
807 | + | ||
808 | + /* | ||
809 | + * Signal delivery seems to mess up weird selectors. Put it | ||
810 | + * back. | ||
811 | + */ | ||
812 | + asm volatile ("mov %0, %%gs" : : "rm" (force_sel)); | ||
813 | + } else { | ||
814 | + asm volatile ("mov %%gs, %0" : "=rm" (sel_pre_sched)); | ||
815 | + } | ||
816 | + | ||
817 | remote_base = remote; | ||
818 | ftx = 1; | ||
819 | syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); | ||
820 | while (ftx != 0) | ||
821 | syscall(SYS_futex, &ftx, FUTEX_WAIT, 1, NULL, NULL, 0); | ||
822 | |||
823 | + asm volatile ("mov %%gs, %0" : "=rm" (sel_post_sched)); | ||
824 | base = read_base(GS); | ||
825 | - if (base == local) { | ||
826 | - printf("[OK]\tGSBASE remained 0x%lx\n", local); | ||
827 | + if (base == local && sel_pre_sched == sel_post_sched) { | ||
828 | + printf("[OK]\tGS/BASE remained 0x%hx/0x%lx\n", | ||
829 | + sel_pre_sched, local); | ||
830 | } else { | ||
831 | nerrs++; | ||
832 | - printf("[FAIL]\tGSBASE changed to 0x%lx\n", base); | ||
833 | + printf("[FAIL]\tGS/BASE changed from 0x%hx/0x%lx to 0x%hx/0x%lx\n", | ||
834 | + sel_pre_sched, local, sel_post_sched, base); | ||
835 | } | ||
836 | } | ||
837 | |||
838 | @@ -381,8 +403,15 @@ int main() | ||
839 | |||
840 | for (int local = 0; local < 4; local++) { | ||
841 | for (int remote = 0; remote < 4; remote++) { | ||
842 | - set_gs_and_switch_to(bases_with_hard_zero[local], | ||
843 | - bases_with_hard_zero[remote]); | ||
844 | + for (unsigned short s = 0; s < 5; s++) { | ||
845 | + unsigned short sel = s; | ||
846 | + if (s == 4) | ||
847 | + asm ("mov %%ss, %0" : "=rm" (sel)); | ||
848 | + set_gs_and_switch_to( | ||
849 | + bases_with_hard_zero[local], | ||
850 | + sel, | ||
851 | + bases_with_hard_zero[remote]); | ||
852 | + } | ||
853 | } | ||
854 | } | ||
855 |