0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140 #ifdef CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE
0141 #define MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK \
0142 (MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE \
0143 | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE)
0144 #else
0145 #define MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK 0
0146 #endif
0147
0148 #ifdef CONFIG_RSEQ
0149 #define MEMBARRIER_PRIVATE_EXPEDITED_RSEQ_BITMASK \
0150 (MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ \
0151 | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ)
0152 #else
0153 #define MEMBARRIER_PRIVATE_EXPEDITED_RSEQ_BITMASK 0
0154 #endif
0155
0156 #define MEMBARRIER_CMD_BITMASK \
0157 (MEMBARRIER_CMD_GLOBAL | MEMBARRIER_CMD_GLOBAL_EXPEDITED \
0158 | MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED \
0159 | MEMBARRIER_CMD_PRIVATE_EXPEDITED \
0160 | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED \
0161 | MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK \
0162 | MEMBARRIER_PRIVATE_EXPEDITED_RSEQ_BITMASK)
0163
0164 static void ipi_mb(void *info)
0165 {
0166 smp_mb();
0167 }
0168
0169 static void ipi_sync_core(void *info)
0170 {
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 smp_mb();
0182
0183 sync_core_before_usermode();
0184 }
0185
0186 static void ipi_rseq(void *info)
0187 {
0188
0189
0190
0191
0192
0193
0194
0195 smp_mb();
0196 rseq_preempt(current);
0197 }
0198
0199 static void ipi_sync_rq_state(void *info)
0200 {
0201 struct mm_struct *mm = (struct mm_struct *) info;
0202
0203 if (current->mm != mm)
0204 return;
0205 this_cpu_write(runqueues.membarrier_state,
0206 atomic_read(&mm->membarrier_state));
0207
0208
0209
0210
0211
0212
0213 smp_mb();
0214 }
0215
0216 void membarrier_exec_mmap(struct mm_struct *mm)
0217 {
0218
0219
0220
0221
0222
0223 smp_mb();
0224 atomic_set(&mm->membarrier_state, 0);
0225
0226
0227
0228
0229 this_cpu_write(runqueues.membarrier_state, 0);
0230 }
0231
0232 void membarrier_update_current_mm(struct mm_struct *next_mm)
0233 {
0234 struct rq *rq = this_rq();
0235 int membarrier_state = 0;
0236
0237 if (next_mm)
0238 membarrier_state = atomic_read(&next_mm->membarrier_state);
0239 if (READ_ONCE(rq->membarrier_state) == membarrier_state)
0240 return;
0241 WRITE_ONCE(rq->membarrier_state, membarrier_state);
0242 }
0243
0244 static int membarrier_global_expedited(void)
0245 {
0246 int cpu;
0247 cpumask_var_t tmpmask;
0248
0249 if (num_online_cpus() == 1)
0250 return 0;
0251
0252
0253
0254
0255
0256 smp_mb();
0257
0258 if (!zalloc_cpumask_var(&tmpmask, GFP_KERNEL))
0259 return -ENOMEM;
0260
0261 cpus_read_lock();
0262 rcu_read_lock();
0263 for_each_online_cpu(cpu) {
0264 struct task_struct *p;
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274 if (cpu == raw_smp_processor_id())
0275 continue;
0276
0277 if (!(READ_ONCE(cpu_rq(cpu)->membarrier_state) &
0278 MEMBARRIER_STATE_GLOBAL_EXPEDITED))
0279 continue;
0280
0281
0282
0283
0284
0285 p = rcu_dereference(cpu_rq(cpu)->curr);
0286 if (!p->mm)
0287 continue;
0288
0289 __cpumask_set_cpu(cpu, tmpmask);
0290 }
0291 rcu_read_unlock();
0292
0293 preempt_disable();
0294 smp_call_function_many(tmpmask, ipi_mb, NULL, 1);
0295 preempt_enable();
0296
0297 free_cpumask_var(tmpmask);
0298 cpus_read_unlock();
0299
0300
0301
0302
0303
0304
0305 smp_mb();
0306 return 0;
0307 }
0308
0309 static int membarrier_private_expedited(int flags, int cpu_id)
0310 {
0311 cpumask_var_t tmpmask;
0312 struct mm_struct *mm = current->mm;
0313 smp_call_func_t ipi_func = ipi_mb;
0314
0315 if (flags == MEMBARRIER_FLAG_SYNC_CORE) {
0316 if (!IS_ENABLED(CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE))
0317 return -EINVAL;
0318 if (!(atomic_read(&mm->membarrier_state) &
0319 MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY))
0320 return -EPERM;
0321 ipi_func = ipi_sync_core;
0322 } else if (flags == MEMBARRIER_FLAG_RSEQ) {
0323 if (!IS_ENABLED(CONFIG_RSEQ))
0324 return -EINVAL;
0325 if (!(atomic_read(&mm->membarrier_state) &
0326 MEMBARRIER_STATE_PRIVATE_EXPEDITED_RSEQ_READY))
0327 return -EPERM;
0328 ipi_func = ipi_rseq;
0329 } else {
0330 WARN_ON_ONCE(flags);
0331 if (!(atomic_read(&mm->membarrier_state) &
0332 MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY))
0333 return -EPERM;
0334 }
0335
0336 if (flags != MEMBARRIER_FLAG_SYNC_CORE &&
0337 (atomic_read(&mm->mm_users) == 1 || num_online_cpus() == 1))
0338 return 0;
0339
0340
0341
0342
0343
0344 smp_mb();
0345
0346 if (cpu_id < 0 && !zalloc_cpumask_var(&tmpmask, GFP_KERNEL))
0347 return -ENOMEM;
0348
0349 cpus_read_lock();
0350
0351 if (cpu_id >= 0) {
0352 struct task_struct *p;
0353
0354 if (cpu_id >= nr_cpu_ids || !cpu_online(cpu_id))
0355 goto out;
0356 rcu_read_lock();
0357 p = rcu_dereference(cpu_rq(cpu_id)->curr);
0358 if (!p || p->mm != mm) {
0359 rcu_read_unlock();
0360 goto out;
0361 }
0362 rcu_read_unlock();
0363 } else {
0364 int cpu;
0365
0366 rcu_read_lock();
0367 for_each_online_cpu(cpu) {
0368 struct task_struct *p;
0369
0370 p = rcu_dereference(cpu_rq(cpu)->curr);
0371 if (p && p->mm == mm)
0372 __cpumask_set_cpu(cpu, tmpmask);
0373 }
0374 rcu_read_unlock();
0375 }
0376
0377 if (cpu_id >= 0) {
0378
0379
0380
0381
0382 smp_call_function_single(cpu_id, ipi_func, NULL, 1);
0383 } else {
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401 if (flags != MEMBARRIER_FLAG_SYNC_CORE) {
0402 preempt_disable();
0403 smp_call_function_many(tmpmask, ipi_func, NULL, true);
0404 preempt_enable();
0405 } else {
0406 on_each_cpu_mask(tmpmask, ipi_func, NULL, true);
0407 }
0408 }
0409
0410 out:
0411 if (cpu_id < 0)
0412 free_cpumask_var(tmpmask);
0413 cpus_read_unlock();
0414
0415
0416
0417
0418
0419
0420 smp_mb();
0421
0422 return 0;
0423 }
0424
0425 static int sync_runqueues_membarrier_state(struct mm_struct *mm)
0426 {
0427 int membarrier_state = atomic_read(&mm->membarrier_state);
0428 cpumask_var_t tmpmask;
0429 int cpu;
0430
0431 if (atomic_read(&mm->mm_users) == 1 || num_online_cpus() == 1) {
0432 this_cpu_write(runqueues.membarrier_state, membarrier_state);
0433
0434
0435
0436
0437
0438
0439
0440
0441 smp_mb();
0442 return 0;
0443 }
0444
0445 if (!zalloc_cpumask_var(&tmpmask, GFP_KERNEL))
0446 return -ENOMEM;
0447
0448
0449
0450
0451
0452
0453 synchronize_rcu();
0454
0455
0456
0457
0458
0459
0460
0461
0462 cpus_read_lock();
0463 rcu_read_lock();
0464 for_each_online_cpu(cpu) {
0465 struct rq *rq = cpu_rq(cpu);
0466 struct task_struct *p;
0467
0468 p = rcu_dereference(rq->curr);
0469 if (p && p->mm == mm)
0470 __cpumask_set_cpu(cpu, tmpmask);
0471 }
0472 rcu_read_unlock();
0473
0474 on_each_cpu_mask(tmpmask, ipi_sync_rq_state, mm, true);
0475
0476 free_cpumask_var(tmpmask);
0477 cpus_read_unlock();
0478
0479 return 0;
0480 }
0481
0482 static int membarrier_register_global_expedited(void)
0483 {
0484 struct task_struct *p = current;
0485 struct mm_struct *mm = p->mm;
0486 int ret;
0487
0488 if (atomic_read(&mm->membarrier_state) &
0489 MEMBARRIER_STATE_GLOBAL_EXPEDITED_READY)
0490 return 0;
0491 atomic_or(MEMBARRIER_STATE_GLOBAL_EXPEDITED, &mm->membarrier_state);
0492 ret = sync_runqueues_membarrier_state(mm);
0493 if (ret)
0494 return ret;
0495 atomic_or(MEMBARRIER_STATE_GLOBAL_EXPEDITED_READY,
0496 &mm->membarrier_state);
0497
0498 return 0;
0499 }
0500
0501 static int membarrier_register_private_expedited(int flags)
0502 {
0503 struct task_struct *p = current;
0504 struct mm_struct *mm = p->mm;
0505 int ready_state = MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY,
0506 set_state = MEMBARRIER_STATE_PRIVATE_EXPEDITED,
0507 ret;
0508
0509 if (flags == MEMBARRIER_FLAG_SYNC_CORE) {
0510 if (!IS_ENABLED(CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE))
0511 return -EINVAL;
0512 ready_state =
0513 MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY;
0514 } else if (flags == MEMBARRIER_FLAG_RSEQ) {
0515 if (!IS_ENABLED(CONFIG_RSEQ))
0516 return -EINVAL;
0517 ready_state =
0518 MEMBARRIER_STATE_PRIVATE_EXPEDITED_RSEQ_READY;
0519 } else {
0520 WARN_ON_ONCE(flags);
0521 }
0522
0523
0524
0525
0526
0527
0528 if ((atomic_read(&mm->membarrier_state) & ready_state) == ready_state)
0529 return 0;
0530 if (flags & MEMBARRIER_FLAG_SYNC_CORE)
0531 set_state |= MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE;
0532 if (flags & MEMBARRIER_FLAG_RSEQ)
0533 set_state |= MEMBARRIER_STATE_PRIVATE_EXPEDITED_RSEQ;
0534 atomic_or(set_state, &mm->membarrier_state);
0535 ret = sync_runqueues_membarrier_state(mm);
0536 if (ret)
0537 return ret;
0538 atomic_or(ready_state, &mm->membarrier_state);
0539
0540 return 0;
0541 }
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579 SYSCALL_DEFINE3(membarrier, int, cmd, unsigned int, flags, int, cpu_id)
0580 {
0581 switch (cmd) {
0582 case MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ:
0583 if (unlikely(flags && flags != MEMBARRIER_CMD_FLAG_CPU))
0584 return -EINVAL;
0585 break;
0586 default:
0587 if (unlikely(flags))
0588 return -EINVAL;
0589 }
0590
0591 if (!(flags & MEMBARRIER_CMD_FLAG_CPU))
0592 cpu_id = -1;
0593
0594 switch (cmd) {
0595 case MEMBARRIER_CMD_QUERY:
0596 {
0597 int cmd_mask = MEMBARRIER_CMD_BITMASK;
0598
0599 if (tick_nohz_full_enabled())
0600 cmd_mask &= ~MEMBARRIER_CMD_GLOBAL;
0601 return cmd_mask;
0602 }
0603 case MEMBARRIER_CMD_GLOBAL:
0604
0605 if (tick_nohz_full_enabled())
0606 return -EINVAL;
0607 if (num_online_cpus() > 1)
0608 synchronize_rcu();
0609 return 0;
0610 case MEMBARRIER_CMD_GLOBAL_EXPEDITED:
0611 return membarrier_global_expedited();
0612 case MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED:
0613 return membarrier_register_global_expedited();
0614 case MEMBARRIER_CMD_PRIVATE_EXPEDITED:
0615 return membarrier_private_expedited(0, cpu_id);
0616 case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED:
0617 return membarrier_register_private_expedited(0);
0618 case MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE:
0619 return membarrier_private_expedited(MEMBARRIER_FLAG_SYNC_CORE, cpu_id);
0620 case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE:
0621 return membarrier_register_private_expedited(MEMBARRIER_FLAG_SYNC_CORE);
0622 case MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ:
0623 return membarrier_private_expedited(MEMBARRIER_FLAG_RSEQ, cpu_id);
0624 case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ:
0625 return membarrier_register_private_expedited(MEMBARRIER_FLAG_RSEQ);
0626 default:
0627 return -EINVAL;
0628 }
0629 }