| .. | .. |
|---|
| 9 | 9 | |
|---|
| 10 | 10 | #include <asm/hvcall.h> |
|---|
| 11 | 11 | #include <asm/paca.h> |
|---|
| 12 | +#include <asm/lppaca.h> |
|---|
| 12 | 13 | #include <asm/page.h> |
|---|
| 13 | 14 | |
|---|
| 14 | 15 | static inline long poll_pending(void) |
|---|
| .. | .. |
|---|
| 312 | 313 | |
|---|
| 313 | 314 | static inline long plpar_set_watchpoint0(unsigned long dawr0, unsigned long dawrx0) |
|---|
| 314 | 315 | { |
|---|
| 315 | | - return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR, dawr0, dawrx0); |
|---|
| 316 | + return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR0, dawr0, dawrx0); |
|---|
| 317 | +} |
|---|
| 318 | + |
|---|
| 319 | +static inline long plpar_set_watchpoint1(unsigned long dawr1, unsigned long dawrx1) |
|---|
| 320 | +{ |
|---|
| 321 | + return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR1, dawr1, dawrx1); |
|---|
| 316 | 322 | } |
|---|
| 317 | 323 | |
|---|
| 318 | 324 | static inline long plpar_signal_sys_reset(long cpu) |
|---|
| .. | .. |
|---|
| 334 | 340 | return rc; |
|---|
| 335 | 341 | } |
|---|
| 336 | 342 | |
|---|
| 343 | +/* |
|---|
| 344 | + * Wrapper to H_RPT_INVALIDATE hcall that handles return values appropriately |
|---|
| 345 | + * |
|---|
| 346 | + * - Returns H_SUCCESS on success |
|---|
| 347 | + * - For H_BUSY return value, we retry the hcall. |
|---|
| 348 | + * - For any other hcall failures, attempt a full flush once before |
|---|
| 349 | + * resorting to BUG(). |
|---|
| 350 | + * |
|---|
| 351 | + * Note: This hcall is expected to fail only very rarely. The correct |
|---|
| 352 | + * error recovery of killing the process/guest will be eventually |
|---|
| 353 | + * needed. |
|---|
| 354 | + */ |
|---|
| 355 | +static inline long pseries_rpt_invalidate(u32 pid, u64 target, u64 type, |
|---|
| 356 | + u64 page_sizes, u64 start, u64 end) |
|---|
| 357 | +{ |
|---|
| 358 | + long rc; |
|---|
| 359 | + unsigned long all; |
|---|
| 360 | + |
|---|
| 361 | + while (true) { |
|---|
| 362 | + rc = plpar_hcall_norets(H_RPT_INVALIDATE, pid, target, type, |
|---|
| 363 | + page_sizes, start, end); |
|---|
| 364 | + if (rc == H_BUSY) { |
|---|
| 365 | + cpu_relax(); |
|---|
| 366 | + continue; |
|---|
| 367 | + } else if (rc == H_SUCCESS) |
|---|
| 368 | + return rc; |
|---|
| 369 | + |
|---|
| 370 | + /* Flush request failed, try with a full flush once */ |
|---|
| 371 | + if (type & H_RPTI_TYPE_NESTED) |
|---|
| 372 | + all = H_RPTI_TYPE_NESTED | H_RPTI_TYPE_NESTED_ALL; |
|---|
| 373 | + else |
|---|
| 374 | + all = H_RPTI_TYPE_ALL; |
|---|
| 375 | +retry: |
|---|
| 376 | + rc = plpar_hcall_norets(H_RPT_INVALIDATE, pid, target, |
|---|
| 377 | + all, page_sizes, 0, -1UL); |
|---|
| 378 | + if (rc == H_BUSY) { |
|---|
| 379 | + cpu_relax(); |
|---|
| 380 | + goto retry; |
|---|
| 381 | + } else if (rc == H_SUCCESS) |
|---|
| 382 | + return rc; |
|---|
| 383 | + |
|---|
| 384 | + BUG(); |
|---|
| 385 | + } |
|---|
| 386 | +} |
|---|
| 387 | + |
|---|
| 337 | 388 | #else /* !CONFIG_PPC_PSERIES */ |
|---|
| 338 | 389 | |
|---|
| 339 | 390 | static inline long plpar_set_ciabr(unsigned long ciabr) |
|---|
| 340 | 391 | { |
|---|
| 341 | 392 | return 0; |
|---|
| 342 | 393 | } |
|---|
| 394 | + |
|---|
| 395 | +static inline long plpar_pte_read_4(unsigned long flags, unsigned long ptex, |
|---|
| 396 | + unsigned long *ptes) |
|---|
| 397 | +{ |
|---|
| 398 | + return 0; |
|---|
| 399 | +} |
|---|
| 400 | + |
|---|
| 401 | +static inline long pseries_rpt_invalidate(u32 pid, u64 target, u64 type, |
|---|
| 402 | + u64 page_sizes, u64 start, u64 end) |
|---|
| 403 | +{ |
|---|
| 404 | + return 0; |
|---|
| 405 | +} |
|---|
| 406 | + |
|---|
| 343 | 407 | #endif /* CONFIG_PPC_PSERIES */ |
|---|
| 344 | 408 | |
|---|
| 345 | 409 | #endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */ |
|---|