Message ID | 20170616185104.18967.7867.stgit@tlendack-t1.amdoffice.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, 16 Jun 2017, Tom Lendacky wrote: > Currently there is a check if the address being mapped is in the ISA > range (is_ISA_range()), and if it is then phys_to_virt() is used to > perform the mapping. When SME is active, however, this will result > in the mapping having the encryption bit set when it is expected that > an ioremap() should not have the encryption bit set. So only use the > phys_to_virt() function if SME is not active This does not make sense to me. What the heck has phys_to_virt() to do with the encryption bit. Especially why would the encryption bit be set on that mapping in the first place? I'm probably missing something, but this want's some coherent explanation understandable by mere mortals both in the changelog and the code comment. Thanks, tglx
On Fri, 16 Jun 2017, Tom Lendacky wrote: > Currently there is a check if the address being mapped is in the ISA > range (is_ISA_range()), and if it is then phys_to_virt() is used to > perform the mapping. When SME is active, however, this will result > in the mapping having the encryption bit set when it is expected that > an ioremap() should not have the encryption bit set. So only use the > phys_to_virt() function if SME is not active > > Reviewed-by: Borislav Petkov <bp@suse.de> > Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> > --- > arch/x86/mm/ioremap.c | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c > index 4c1b5fd..a382ba9 100644 > --- a/arch/x86/mm/ioremap.c > +++ b/arch/x86/mm/ioremap.c > @@ -13,6 +13,7 @@ > #include <linux/slab.h> > #include <linux/vmalloc.h> > #include <linux/mmiotrace.h> > +#include <linux/mem_encrypt.h> > > #include <asm/set_memory.h> > #include <asm/e820/api.h> > @@ -106,9 +107,11 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, > } > > /* > - * Don't remap the low PCI/ISA area, it's always mapped.. > + * Don't remap the low PCI/ISA area, it's always mapped. > + * But if SME is active, skip this so that the encryption bit > + * doesn't get set. > */ > - if (is_ISA_range(phys_addr, last_addr)) > + if (is_ISA_range(phys_addr, last_addr) && !sme_active()) > return (__force void __iomem *)phys_to_virt(phys_addr); More thoughts about that. Making this conditional on !sme_active() is not the best idea. I'd rather remove that whole thing and make it unconditional so the code pathes get always exercised and any subtle wreckage is detected on a broader base and not only on that hard to access and debug SME capable machine owned by Joe User. Thanks, tglx
On 6/20/2017 3:55 PM, Thomas Gleixner wrote: > On Fri, 16 Jun 2017, Tom Lendacky wrote: > >> Currently there is a check if the address being mapped is in the ISA >> range (is_ISA_range()), and if it is then phys_to_virt() is used to >> perform the mapping. When SME is active, however, this will result >> in the mapping having the encryption bit set when it is expected that >> an ioremap() should not have the encryption bit set. So only use the >> phys_to_virt() function if SME is not active > > This does not make sense to me. What the heck has phys_to_virt() to do with > the encryption bit. Especially why would the encryption bit be set on that > mapping in the first place? The default is that all entries that get added to the pagetables have the encryption bit set unless specifically overridden. Any __va() or phys_to_virt() calls will result in a pagetable mapping that has the encryption bit set. For ioremap, the PAGE_KERNEL_IO protection is used which will not/does not have the encryption bit set. > > I'm probably missing something, but this want's some coherent explanation > understandable by mere mortals both in the changelog and the code comment. I'll add some additional info to the changelog and code. Thanks, Tom > > Thanks, > > tglx >
On 6/21/2017 2:37 AM, Thomas Gleixner wrote: > On Fri, 16 Jun 2017, Tom Lendacky wrote: >> Currently there is a check if the address being mapped is in the ISA >> range (is_ISA_range()), and if it is then phys_to_virt() is used to >> perform the mapping. When SME is active, however, this will result >> in the mapping having the encryption bit set when it is expected that >> an ioremap() should not have the encryption bit set. So only use the >> phys_to_virt() function if SME is not active >> >> Reviewed-by: Borislav Petkov <bp@suse.de> >> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> >> --- >> arch/x86/mm/ioremap.c | 7 +++++-- >> 1 file changed, 5 insertions(+), 2 deletions(-) >> >> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c >> index 4c1b5fd..a382ba9 100644 >> --- a/arch/x86/mm/ioremap.c >> +++ b/arch/x86/mm/ioremap.c >> @@ -13,6 +13,7 @@ >> #include <linux/slab.h> >> #include <linux/vmalloc.h> >> #include <linux/mmiotrace.h> >> +#include <linux/mem_encrypt.h> >> >> #include <asm/set_memory.h> >> #include <asm/e820/api.h> >> @@ -106,9 +107,11 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, >> } >> >> /* >> - * Don't remap the low PCI/ISA area, it's always mapped.. >> + * Don't remap the low PCI/ISA area, it's always mapped. >> + * But if SME is active, skip this so that the encryption bit >> + * doesn't get set. >> */ >> - if (is_ISA_range(phys_addr, last_addr)) >> + if (is_ISA_range(phys_addr, last_addr) && !sme_active()) >> return (__force void __iomem *)phys_to_virt(phys_addr); > > More thoughts about that. > > Making this conditional on !sme_active() is not the best idea. I'd rather > remove that whole thing and make it unconditional so the code pathes get > always exercised and any subtle wreckage is detected on a broader base and > not only on that hard to access and debug SME capable machine owned by Joe > User. Ok, that sounds good. I'll remove the check and usage of phys_to_virt() and update the changelog with additional detail about that. Thanks, Tom > > Thanks, > > tglx >
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 4c1b5fd..a382ba9 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -13,6 +13,7 @@ #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/mmiotrace.h> +#include <linux/mem_encrypt.h> #include <asm/set_memory.h> #include <asm/e820/api.h> @@ -106,9 +107,11 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, } /* - * Don't remap the low PCI/ISA area, it's always mapped.. + * Don't remap the low PCI/ISA area, it's always mapped. + * But if SME is active, skip this so that the encryption bit + * doesn't get set. */ - if (is_ISA_range(phys_addr, last_addr)) + if (is_ISA_range(phys_addr, last_addr) && !sme_active()) return (__force void __iomem *)phys_to_virt(phys_addr); /*