powerpc fixes for 5.8 #7

A fix to the VAS code we merged this cycle, to report the proper error code to
 userspace for address translation failures. And a selftest update to match.
 
 Another fix for our pkey handling of PROT_EXEC mappings.
 
 A fix for a crash when booting a "secure VM" under an ultravisor with certain
 numbers of CPUs.
 
 Thanks to:
   Aneesh Kumar K.V, Haren Myneni, Laurent Dufour, Sandipan Das, Satheesh
   Rajendran, Thiago Jung Bauermann.
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCAAxFiEEJFGtCPCthwEv2Y/bUevqPMjhpYAFAl8S7Q8THG1wZUBlbGxl
 cm1hbi5pZC5hdQAKCRBR6+o8yOGlgA9WEAC580vTBCte54XEpRPfKLs0g/piM93z
 +rDDKFFkHrxI+EpySeg20jlDMc/3EoevLN6UNT5I2hrZ5QcNF17RPVmjRoHP0w2l
 ixy9B6Y+auFwos1yEec14ZLJ7iWsnko0SlgtWIAsn9r35hJYFtC3+ho3/XWO0lnF
 0jb31uZim4nFQvGSNwe3oZ3/rJsKwWtPZw0WznFr9GB4pMOnrspV/zx796RI9OKY
 khwm4y6pas5Duk9GUJPJjOIk4Mag4yLTXuhzJ5G5UeuUchZRxCTVcdnXEdGXeyte
 9ZJnRjbvbDjTM9qyk2lPSHv5zFHfEbglDkp2zoKX2Ie083LIcKlkwgeFvlBjhdxQ
 qwko27DXIZdmKTsSiFDODI0VlyK3ZHumCX/m2Ctg9/VmeSiYacebQjcS7DmAwQeE
 6h2bRL2TiTLRkgWiD4HOvHZZTy22pVgRcYe/pwGzMMXJW6SLQ9GUOhhar4XEYMgj
 pzn86uZRVJLf90qdUkI9sl8p/PthGlfehqHivfwgKYk/0H1AyGkChO3NB1mLiCfS
 WC+7J/lDIvtAMnC+536LqZT5l46ntt5RQ5tUcHfvn4bFoh5ndeav0Y9hXEXblyYI
 32lYj/paAmzR2kuHOzOQAa4hwy9rnKEQiGYsF1RcpMO5zdNupXl/EPY5WaKYyEx7
 p+eGalBNTf8zuw==
 =eEXz
 -----END PGP SIGNATURE-----

Merge tag 'powerpc-5.8-7' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux into master

Pull powerpc fixes from Michael Ellerman:
 "Some more powerpc fixes for 5.8:

   - A fix to the VAS code we merged this cycle, to report the proper
     error code to userspace for address translation failures. And a
     selftest update to match.

   - Another fix for our pkey handling of PROT_EXEC mappings.

   - A fix for a crash when booting a "secure VM" under an ultravisor
     with certain numbers of CPUs.

  Thanks to: Aneesh Kumar K.V, Haren Myneni, Laurent Dufour, Sandipan
  Das, Satheesh Rajendran, Thiago Jung Bauermann"

* tag 'powerpc-5.8-7' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  selftests/powerpc: Use proper error code to check fault address
  powerpc/vas: Report proper error code for address translation failure
  powerpc/pseries/svm: Fix incorrect check for shared_lppaca_size
  powerpc/book3s64/pkeys: Fix pkey_access_permitted() for execute disable pkey
This commit is contained in:
Linus Torvalds 2020-07-18 10:45:17 -07:00
commit 721db9dfb1
7 changed files with 16 additions and 12 deletions

View File

@ -213,7 +213,7 @@ request buffers are not in memory. The operating system handles the fault by
updating CSB with the following data: updating CSB with the following data:
csb.flags = CSB_V; csb.flags = CSB_V;
csb.cc = CSB_CC_TRANSLATION; csb.cc = CSB_CC_FAULT_ADDRESS;
csb.ce = CSB_CE_TERMINATION; csb.ce = CSB_CE_TERMINATION;
csb.address = fault_address; csb.address = fault_address;

View File

@ -77,6 +77,8 @@ struct coprocessor_completion_block {
#define CSB_CC_CHAIN (37) #define CSB_CC_CHAIN (37)
#define CSB_CC_SEQUENCE (38) #define CSB_CC_SEQUENCE (38)
#define CSB_CC_HW (39) #define CSB_CC_HW (39)
/* P9 DD2 NX Workbook 3.2 (Table 4-36): Address translation fault */
#define CSB_CC_FAULT_ADDRESS (250)
#define CSB_SIZE (0x10) #define CSB_SIZE (0x10)
#define CSB_ALIGN CSB_SIZE #define CSB_ALIGN CSB_SIZE

View File

@ -87,7 +87,7 @@ static void *__init alloc_shared_lppaca(unsigned long size, unsigned long align,
* This is very early in boot, so no harm done if the kernel crashes at * This is very early in boot, so no harm done if the kernel crashes at
* this point. * this point.
*/ */
BUG_ON(shared_lppaca_size >= shared_lppaca_total_size); BUG_ON(shared_lppaca_size > shared_lppaca_total_size);
return ptr; return ptr;
} }

View File

@ -354,12 +354,14 @@ static bool pkey_access_permitted(int pkey, bool write, bool execute)
u64 amr; u64 amr;
pkey_shift = pkeyshift(pkey); pkey_shift = pkeyshift(pkey);
if (execute && !(read_iamr() & (IAMR_EX_BIT << pkey_shift))) if (execute)
return true; return !(read_iamr() & (IAMR_EX_BIT << pkey_shift));
amr = read_amr(); /* Delay reading amr until absolutely needed */ amr = read_amr();
return ((!write && !(amr & (AMR_RD_BIT << pkey_shift))) || if (write)
(write && !(amr & (AMR_WR_BIT << pkey_shift)))); return !(amr & (AMR_WR_BIT << pkey_shift));
return !(amr & (AMR_RD_BIT << pkey_shift));
} }
bool arch_pte_access_permitted(u64 pte, bool write, bool execute) bool arch_pte_access_permitted(u64 pte, bool write, bool execute)

View File

@ -79,7 +79,7 @@ static void update_csb(struct vas_window *window,
csb_addr = (void __user *)be64_to_cpu(crb->csb_addr); csb_addr = (void __user *)be64_to_cpu(crb->csb_addr);
memset(&csb, 0, sizeof(csb)); memset(&csb, 0, sizeof(csb));
csb.cc = CSB_CC_TRANSLATION; csb.cc = CSB_CC_FAULT_ADDRESS;
csb.ce = CSB_CE_TERMINATION; csb.ce = CSB_CE_TERMINATION;
csb.cs = 0; csb.cs = 0;
csb.count = 0; csb.count = 0;

View File

@ -698,13 +698,13 @@ restart_nx:
switch (cc) { switch (cc) {
case ERR_NX_TRANSLATION: case ERR_NX_AT_FAULT:
/* We touched the pages ahead of time. In the most common case /* We touched the pages ahead of time. In the most common case
* we shouldn't be here. But may be some pages were paged out. * we shouldn't be here. But may be some pages were paged out.
* Kernel should have placed the faulting address to fsaddr. * Kernel should have placed the faulting address to fsaddr.
*/ */
NXPRT(fprintf(stderr, "ERR_NX_TRANSLATION %p\n", NXPRT(fprintf(stderr, "ERR_NX_AT_FAULT %p\n",
(void *)cmdp->crb.csb.fsaddr)); (void *)cmdp->crb.csb.fsaddr));
if (pgfault_retries == NX_MAX_FAULTS) { if (pgfault_retries == NX_MAX_FAULTS) {

View File

@ -306,13 +306,13 @@ int compress_file(int argc, char **argv, void *handle)
lzcounts, cmdp, handle); lzcounts, cmdp, handle);
if (cc != ERR_NX_OK && cc != ERR_NX_TPBC_GT_SPBC && if (cc != ERR_NX_OK && cc != ERR_NX_TPBC_GT_SPBC &&
cc != ERR_NX_TRANSLATION) { cc != ERR_NX_AT_FAULT) {
fprintf(stderr, "nx error: cc= %d\n", cc); fprintf(stderr, "nx error: cc= %d\n", cc);
exit(-1); exit(-1);
} }
/* Page faults are handled by the user code */ /* Page faults are handled by the user code */
if (cc == ERR_NX_TRANSLATION) { if (cc == ERR_NX_AT_FAULT) {
NXPRT(fprintf(stderr, "page fault: cc= %d, ", cc)); NXPRT(fprintf(stderr, "page fault: cc= %d, ", cc));
NXPRT(fprintf(stderr, "try= %d, fsa= %08llx\n", NXPRT(fprintf(stderr, "try= %d, fsa= %08llx\n",
fault_tries, fault_tries,